Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic command PRINT not yet available? #33

Open
dirkwhoffmann opened this issue Oct 11, 2019 · 29 comments
Open

Basic command PRINT not yet available? #33

dirkwhoffmann opened this issue Oct 11, 2019 · 29 comments

Comments

@dirkwhoffmann
Copy link

I've added support for the open-roms in VirtualC64. At the moment they are listed as "unknown or patched" Roms.

Bildschirmfoto 2019-10-11 um 16 27 50

After that, I tried to write a simple program:

Bildschirmfoto 2019-10-11 um 16 21 53

I didn't use the open-roms before, so I want to make sure that I am not doing something stupid here. Is it true that the PRINT command is not supported yet?

@FeralChild64
Copy link
Collaborator

FeralChild64 commented Oct 11, 2019

That's true, PRINT is not yet implemented. But at least LOAD from IEC is, and we even have a DOS Wedge :) Kernal is quite complete (although there is still a lot to do), but BASIC... barely anything works. See https://github.com/MEGA65/open-roms/blob/master/STATUS.md - Features Missing chapter.

If you want to recognize Open ROMs in your emulator:

  • Kernal contains an identification byte at $FF80 - for Open ROMs you'll currently find $F0 there, I hope there won't be any conflict with any other ROM and we won't have to change it
  • BASIC contains identifier at $A004, for Open ROMs you'll currently find MEGABAS2 string there (probably due to historical reasons... but I think it'll stay this way).
  • [edit] character ROM does not have any way to identify it, but it definitely won't change often

BTW, in my development branch (https://github.com/FeralChild64/open-roms/tree/master/bin) you'll find a version which should be much more compatible (I did some fixes just few days ago, they are just not merged yet to the official master).

@dirkwhoffmann
Copy link
Author

If you want to recognize Open ROMs in your emulator:

Right now, VirtualC64 can only detect the file type by comparing the beginning of a file with a fingerprint. Adding fingerprints is easy, so the Roms from your dev branch are now recognised, too. It starts up without any problems:

Bildschirmfoto 2019-10-11 um 18 10 40

I tried to play Fort Apokalypse and Giana Sisters which both habe issues. Internation Karate works fine though 👍:

Bildschirmfoto 2019-10-11 um 18 10 20

@gardners
Copy link
Collaborator

gardners commented Oct 11, 2019 via email

@gardners
Copy link
Collaborator

gardners commented Oct 11, 2019 via email

@dirkwhoffmann
Copy link
Author

We should really have a version number encoded in there somewhere

At the moment, VirtualC64 scans a Rom file in two phases (one phase is carried out by the emulator and the other one by the GUI):

First, both the file size and the header signature are checked (first three to five bytes). Every file that passes this test can be added as a Rom. Thus, patched Roms can be added, too (if they match the original Rom in the first three to five bytes).

When the Rom preference panel opens up, the GUI computes a fingerprint (simple FNV 1A checksum) for each of the four installed Roms and compares them against an internal database. The database consists of a list of fingerprints and a name mapping:

struct Rom {

    static let missing                 = 0x0000000000000000 as UInt64

    // Basic Roms
    static let basic_commodore         = 0x20765FEA67A8762D as UInt64
    static let basic_mega65_generic    = 0xF5E925DCABE2D3F0 as UInt64

    ....
}
let knownBasicRoms: [UInt64: String] = [

    Rom.missing:                 "This 8 KB Rom contains Commodore's Basic interpreter.",
    Rom.basic_commodore:         "Commodore 64 Basic V2",
    Rom.basic_mega65_generic:    "M.E.G.A. C64 OpenROM"
]

For a proof of concept, I've already added fingerprints for the Roms in Feralchild's dev branch. They are now recognised and displayed to the user like this:

Bildschirmfoto 2019-10-12 um 10 23 44

Once there are officially released and versioned OpenRoms, I can add a fingerprint for each of them and display the correct version number. It'll be hard for me to grab the version number from a distinct place in the Rom, because it would require a lot of internal emulator changes. All Rom recognition stuff is based on fingerprints.

Once the Roms are stable, it's also possible to bundle the Roms with the emulator and add a button in the Rom preferences like this:

Bildschirmfoto 2019-10-12 um 10 44 56

Hitting this button could install all three OpenRoms automatically.

@gardners
Copy link
Collaborator

gardners commented Oct 12, 2019 via email

@dirkwhoffmann
Copy link
Author

Hi Paul,

Would it help if we had some well-known URL with ROMs

I think that's a good idea. If there is a stable URL where the latest OpenRoms can be downloaded from, emulator authors can integrate some smart auto-grabbing feature into their products.

In the long run, I think I can integrate such functionality into VirtualC64. However, I don't think I will have enough time to do this in the short term. I am in the process of implementing an Amiga emulator (called vAmiga) and have only little time left to spend on VirtualC64 at the moment.

What I can easily do is integrate a help button called "Learn more about OpenRoms" that will redirect the user to one of your websites. I think a lot of people would love to try OpenRoms if they knew that they exist. I didn't know about their existence until Detlef Hastik sent me a mail with some background information about the MEGA65 project.

@FeralChild64
Copy link
Collaborator

Regarding versioning - I already though about this. According to Mapping the C64, there is a couple of unused bytes at $E4B7, reserved for system patches - so it's unlikely anyone touches this area. My idea:


  • = $E4B7

.byte #<error_rom_version_mismatch
.byte #>error_rom_version_mismatch

  • = $E4B9

.text "DEVEL SNAPSHOT" // revision string
.byte $00
.byte $xx // configuration file ID

...

error_rom_version_mismatch: // floating routine
// display our own version of bluescreen


BASIC should know the expected Kernal version, check it during the startup, and jump to 'error_rom_version_mismatch' if there is a mismatch. I don't have any good idea yet where to put the revision string in BASIC ROMs... maybe in the area the keywords or error strings normally reside? We are using different format nevertheless.

By default the revision string should be something generic (like "DEVEL SNAPSHOT") - I create snapshot binaries sometimes quite often, I don't really want to version them. We can have a policy to reject bug reports from such versions.

When doing a release, we should have a script which does some simple replacement, like:

DEVEL SNAPSHOT -> RELEASE 191030

In the future it might be something else like 'VERSION 1.0000'. Or COMMIT 31D181A. Or whatever else we decide. Important: every single startup banner should display the revision string.

I've already added fingerprints for the Roms in Feralchild's dev branch

Not a good idea, I do builds rather frequently :)


Regarding compatibility - I don't do much compatibility tests yet, there is a couple of things that should be done first to prevent me from wasting time. The most important still unhandled one: keyboard scanning routine. The current one (from Codebase 64) has some really nice ideas, but... it needs additional memory, it utilizes quite a lot of bytes it considers free (and game developers might consider them free, too...). And trying to extend it to support, for example, C128 numeric keypad (or C65/MEGA65 additional keys) would require even more bytes in RAM. We really need some more compatible routine (won't be as advanced, though), I've already started working on one.

BTW. Emulator-branded ROM releases are a possibility too :)

@gardners
Copy link
Collaborator

gardners commented Oct 12, 2019 via email

@gardners
Copy link
Collaborator

gardners commented Oct 12, 2019 via email

@FeralChild64
Copy link
Collaborator

I don't mean feature flags - they wouldn't be practical, for example you can already freely specify SID chip addresses - so that Kernal knows what to silence after RUN/STOP+RESTORE. And I'm going to provide configure options for function keys (and SHIFT + RUN/STOP) strings, which would make a bitfield even more unsuitable.

I mean - 0 for generic ROM, 1 for MEGA65 ROM, etc. And yes, the keyboard routine will be selectable during the compile time.

@gardners
Copy link
Collaborator

gardners commented Oct 12, 2019 via email

@FeralChild64
Copy link
Collaborator

Right now just a number. Initial proposal (panic screen takes some space in Kernal - doesn't have to be compiled in, you can choose to just reset the machine instead):

Both areas are unused in original ROMs (filled with $AA). I have reserved 16 bytes for a version string (mainly to know how to arrange startup banners), we don't have to use everything in the future. Fortunately, BASIC cold start init routine resides in high ROM area (above $E000) - this way if someone by mistake uses original BASIC ROM with our Kernal it will be detected too.

screenshot1
screenshot2
screenshot3

@FeralChild64
Copy link
Collaborator

From now on, all the ROMs I release will have version number embedded in them. We can change the versioning scheme later, for now this is:

DEV - development snapshot
191019 - year/month/day
FC - means FeralChild, taken from environment variable (make updatebin tells which variable to set if it isn't set yet)
1 - first snapshot this day

I still want do a couple of things before the merge request.

If anyone is interested, generic and Ultimate 64 builds have new keyboard scanning routine enabled (Mega 65 still has old). Shorter, configurable (features might be disabled to save space), should be more compatible. Handles repeat countdown in slightly different way (once DELAY is down to 0 char is output, KOUNT is only used for the next repeats - can be fixed, but would require some more ROM space, but I don't think this is a problem). I tweaked timing a little, original repeat was always too slow for me.
Price to pay: there is no rollover support (it really needs data to be passed between scans) - maybe I'll add some VERY limited rollover in the future by changing how LSTX is handled.
Scanning C128 keys in C64 mode probably needs some fixes (I don't fully understand behaviour I see under VICE x128 emulator).

screenshot4

@gardners
Copy link
Collaborator

gardners commented Oct 19, 2019 via email

@FeralChild64
Copy link
Collaborator

I'll think about it, but I would like to first understand what is the problem with C128 keyboard reading... BTW, it would be helpful if you could answer to this post: https://www.forum64.de/index.php?thread/93387-scanning-the-keyboard-questions/

@dirkwhoffmann
Copy link
Author

Sorry I've been so quiet for a long time, but I was working hard on vAmiga. Recently, I started to back port stuff from vAmiga to VirtualC64. The old version of VirtualC64 was quite limited w.r.t. recognizing Roms. I.e., I was only able to compare checksums agains a database which made it difficult to recognize the MEGA65 OpenROMs. The next version of VirtualC64 will be more flexible since the Rom recognition code will be part of the C++ emulator and no longer be part of the Swift GUI.

The next version of VirtualC64 will have a resigned Rom panel which resembles the Rom panel as it looks in vAmiga:

Bildschirmfoto 2020-07-16 um 15 01 27

By pushing „Install OpenRoms“, the three MEGA65 OpenRoms get installed (they will ship as part of the emulator).

Bildschirmfoto 2020-07-16 um 15 01 59

Of course, I also want to allow the user to drag in the latest OpenROMs by hand. And this directly leads to my question: How can I detect an OpenROM (header signature?) and how can I detect the version number? If I remember correctly, the old OpenROMs didn’t have a version number at a fixed location and you were discussing a proper identification scheme. Did you agree on a scheme in the meantime? The next version of VirtualC64 will be very flexible which means that I can grab the number from wherever it is.

Please continue with the great work! It’s awesome to have a free Rom replacement for the C64.

BTW, I just noticed that Basic has a PRINT statement now 😎:

Bildschirmfoto 2020-07-16 um 13 12 49

@FeralChild64
Copy link
Collaborator

Yes, the PRINT is there - but it is really basic, can only print constant strings (I'm currently working on string variables - there is surprisingly large number of cases which should be handled if we want them to work efficiently), floats and integers are not handled yet at all, the comma does not do what it does in the original ROMs, and the syntax checking is too strict (original ROM is more tolerant). Current implementation was just to allow me to do some tests (BTW, the BASIC is already extended a little - https://github.com/MEGA65/open-roms/blob/master/doc/Extended-BASIC.md

Regarding the ROM identification - I think it should be safe for now to use these 2 places to identify KERNAL and BASIC:

I'm not planning to change them unless some compatibility problem is discovered - and you never know: one of the guys helping with Ultimate 64 project is experimenting with more Kernal banks, one of the ideas was to use some magic sequence of memory access to switch the banks (so don't be surprised if someday you'll see a 16 KB Kernal ROM image for the U64).

There is also a MEGABAS2 string as a BASIC identifier, but I think it will be changed eventually for non-Mega65 builds (so that extended Ultimate 64 BASIC can be easily distinguished).

Versioning scheme will probably change in the future, I just don't dare to declare current ROMs anything like v0.1 yet. The numbers you see in the officially released versions are:

YYMMDD.(id of developer who did the release, FC = FeralChild).(#release this day).

Last, but not least - the ROMs are currently bundled with alternative chargen from Retrofan (https://github.com/MEGA65/open-roms/blob/master/bin/chargen_pxlfont_2.3.rom) - IMHO it is much nicer.

@FeralChild64
Copy link
Collaborator

This is how it looks like on my development branch (assigning a new value to variable does not fully work yet):

image

@dirkwhoffmann
Copy link
Author

Regarding the ROM identification - I think it should be safe for now to use these 2 places to identify KERNAL and BASIC:

Yes, that works. The identification strings are now displayed in the Rom panel 😎:

Bildschirmfoto 2020-07-16 um 22 12 09

@FeralChild64
Copy link
Collaborator

If you want to be really user friendly, you could also warn the user if BASIC/Kernal replacement versions do not match (both revision string and CONFIG_ID byte must match, otherwise you will get a "bluescreen").

@gardners
Copy link
Collaborator

This is all fantastic work, folks! It would be great to push out a blog post talking about the progress on both. Would either of you like to help write it? The screenshots above are probably sufficient for image content.

Paul

@FeralChild64
Copy link
Collaborator

I'll try to write a new blog post (really a lot has happened since my previous one) - but I would like to finish at least the string variables first. For now even my shiny Θ(n) garbage collector is crashing.

@dirkwhoffmann
Copy link
Author

garbage collector is crashing

The C64 gets a garbage collector 😮. Very cool.

you could also warn the user if BASIC/Kernal replacement versions do not match

Nice idea. Now, the emulator refuses to power up in that case:

Bildschirmfoto 2020-07-17 um 17 56 47

If you need different images for the blog post, let me know...

@Kroc
Copy link

Kroc commented Jul 17, 2020

These screenshots look lovely! I think it's about time a screenshot was added to the README so user can get an immediate idea of what the project means in a practical sense.

@FeralChild64
Copy link
Collaborator

FeralChild64 commented Jul 17, 2020

@ dirkwhoffmann - All the CBM 8-bit machines (sans ones without BASIC interpreter) have a garbage collector, but on pre-264 series (like the C64) it's very slow, Θ(n^2). Not a problem for VIC-20 with 3583 basic bytes free, but for C64 with 38911 bytes free it is IMHO unsuitable (even more unsuitable for OpenROMs, which can give the user significantly more BASIC memory, but with slower access). But the faster algorithm has a price: for each string stored outside of BASIC text (including strings from arrays) we need 2 more bytes, for the back-pointer, telling us where the variable descriptor is located.

On the other hand, C64 reserves 7 bytes for each string variable metadata (name, length, address), despite only 5 are needed - for slightly better performance (same amount of bytes for every variable type). For now I 'm following this convention, but I think I'll change it too, so that we won't waste bytes here - I'm just not sure how much it will hurt compatibility in the future.

@Kroc - good idea, I'll put some.

@gardners
Copy link
Collaborator

We can also start a book in the mega65-user-guide repo (or using the same LaTeX template) documenting the OpenROMs.

@FeralChild64
Copy link
Collaborator

Well, for now I'm just do all the documentation in markdown - I just don't have time for everything.

@gardners
Copy link
Collaborator

Totally reasonable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants