My first BASIC program running. Output to the terminal – input done via the USB keyboard connected to the PiTrex – some things do go well together!
I have spent quite some time today with GSBasic – but I haven’t come as far as I wanted. My goal would have been to put something on the vectrex screen, only a text, or a line… or something. But it didn’t go quite as well as the last two days (also, I was tired and slept two times for 1/2 hour in front of my computer…).
As you can see in the image above, the first BASIC program is running, but not vectrex specific yet. I started today with above “test” and basic BASIC is working good. After that I stated porting the first files from the
directory – but that was not quite as easy. Every now and than I had to fix small things. I don’t know what compiler Bob uses, but mine seems to be minusculy more exact. It whined about some pure virtual destructors… had a test for some “unsigned” value which could be -1 (and thus 2^32 -1 -> a really BIG number) and stuff like that.
Also since now the “vectrex” stuff is also included there are quite a few things which I cannot (and do not have to) port. Like accessing the dual port RAM, or the communication setup with the Vectrex, interrupts and semaphores and such.
Also I realize, that some stuff will NOT work straight out of the box, since Bob uses the Vectrex BIOS. E.g. the music routines, explosions, the music itself… etc. In order for this to work in the end seemlessly, I will have to implement those functions (or similar ones) within the PiTrex environment – but I will do that right at the “end” – as of now I will put stubs in place.
Also some functionality I will not be able to map 100%. Bob implemented a feature to run Vectrex assembler code from the BASIC code. THAT I will not implement (actually I do wonder if anyone ever used that… besides myself that is – I used that to implement Lightpen support to Vectrex32 BASIC… a long time ago…)
Most files I have ported, but the largest “chunk” – namely “BASICBuiltInFunctions.cpp” (which includes all Vectrex BASIC functions) is still missing – and today I will not look further.
The plan is to also start slowly with this one, only 3 or four functions… and than convert one after another.
Getting the first function to work will be the hardest part. For that to actually work, the complete “chain” must be implemented, not only the pure functionality of the function, but the changes to the system, so that it will not be compiled to vectrex code that is copied to the DUAL RAM, but to some sort of code that I can run from my PiTrex game round. I am not yet sure how I will do that, since I am not 100% certain what Bob actually does.
If it is “just” interpreted, than I’ll probably also go with that. If the code is kept with the vectrex and only “refreshed” when needed, than I have to take another approach. I might enhance my internal pipeline feature to add similar persistent data/constructs – but that will be seen another day.
After playing around with the above mentioned files, I went a step back and looked again at “Executive.cpp” file. That is the one that actually “runs” the BASIC.
For 1-2 hours I tweaked mostly my own code to be compatible but also at one or two places that “Executive.cpp” file. Now it is behaving with the PiTrex pretty much the same as with the PIC32.
You can run BASIC programs, load BASIC programs – it supports the “autorun.bas” feature and so on. One crux was, that my fgetc() was not 100% compatible with the version Bob used/expected. I changed the oswrapper internally to function exactly the same. (EOL, EOF responses, “blocking” fgetc() calls…).
The fgetc() function now “knows” whether a USB keyboard is connected – and if called for stdin (Filepointer == 0), than it gets (USB-) keyboard inputs. The user only has once to setup the keyboard with a simple “v_initKeyboard();” – and everything else is done in the background. fgetc() even works without IRQMode and even without a waitRecal().
Another function that was missing: “feof(FILE *f)” – this checks whether a file has reached its end (hence eof…). Seems easy going, and once you studied (again) the baremetal file handler, everything is nice and easy… but believe it or not, that thing took me the better part of 1/2 hour to figure out:
int __feof(FILE *_f)
FF_WRAP *f = (FF_WRAP *)_f;
return 0 == f->file.obj.objsize – f->file.fptr;
Anyway… so much for today – sadly still no vectrex screenshot :-)!