BASIC?
I’ve started looking at getting BASIC working on the machine. At first I thought I might need to reverse engineer an existing 8-bit BASIC from the ROM image, or write my own, but then I found something much better. These guys have reverse-engineered 7 different versions of Microsoft BASIC, creating a set of well-documented 6502 assembly source files. It’s probably nearly as good as the original source was, and you can conditionally compile Applesoft, Commodore, and other BASIC variants.
I’ve been working on this for 4 days now, and it’s going fairly well. Early on, I found that quite of few of BMOW’s instructions that are supposed to act like 6502’s aren’t quite accurate in the way they update the condition codes. Some 6502 instructions update only the negative and zero flags, others updates those plus the carry and overflow flags, and still others update additional combinations of flags. In contrast, most BMOW instructions either updated all the flags, or none. Fixing the behavior to match the 6502 required a lot of new microcode and a couple of wiring changes.
There are also quite a few 6502 instructions that I just never bothered to implement in BMOW, because I didn’t find them useful. Microsoft BASIC uses practically every possible instruction, though, so I’ve been madly implementing new instructions in microcode, updating the assembler and simulator to match.
I think it’s actually getting close to working. Running in the simulator, BASIC detects how much RAM I have, prints a copyright message, and dumps me to the BASIC prompt. But if I type something like “10 PRINT ‘Steve’ “, it spews an error that’s every possible BASIC error message concatenated together. The line that reports the number of bytes free also shows it as something like “19019.1901 bytes free”. Strangely, it actually converts the byte count to a floating point number, then calls the floating point print routine, and something’s clearly going wrong inside there. I haven’t actually tried running on the real hardware yet, but if I can get the major issues sorted out in the simulator, it should go pretty smoothly.
Read 9 comments and join the conversation9 Comments so far
Leave a reply. For customer support issues, please use the Customer Support link instead of writing comments.
There are at least a couple of articles about undocumented 6502 behavior in the old Apple Assembly Line archives:
http://www.txbobsc.com/aal/index.html
Bob S-C also published a complete, heavily commented disassembly of Applesoft BASIC (we were told that it was much better commented that Apple’s source), but that’s not part of the archive.
Oops, I didn’t look far enough:
http://www.txbobsc.com/scsc/
Cool, thanks for pointing that out. I’d actually looked at that once before, and the BASIC listing I’m using from pagetable.com is derived from Bob’s work. Despite this, I just did a quick check, and it looks like Bob’s version is more extensively-commented than the pagetable one.
I’m getting pretty warm on a working BASIC now. It prints 52776.0000 bytes free (right number, but with trailing zeroes?), and I successfully executed the immediate mode command PRINT “HELLO”. But when I enter a simple program like 10 PRINT “HELLO” followed by RUN, nothing happens.
I’ve found and fixed several more discrepancies between BMOW and 6502, and outright bugs in BMOW, some of which were pretty interesting. I’ll write more about those once I’ve got it all working.
I have a UK101, which runs a modified version of the OSI BASIC. The copyright and sign-on messages have been changed, but that’s about all! Anyway, after writing a 6502 simulator and testing it with that BASIC, I can suggest that the “floating-point” line numbers and memory sizes are most likely due to incorrect setting of the flags (as I think you’ve already found). I think the BASIC will normally work out integer values such as memory size, and then convert to floating-point for printing — not very efficient, but it works! The floating-point printing routines are quite good at supressing the decimal point and trailing zeroes in the case of an integer value.
Yup, I think you’re exactly right. I plan to look at why the trailing zeroes are appearing next. Although it’s not a big problem, it’s one that’s easy to isolate, and I’m hoping if I fix whatever is causing that problem, it’ll fix a lot of other stuff too.
When I had problems with my 6502-like CPU project and BASIC floating point numbers it was the overflow flag being incorrectly updated on ADD and SUB which caused the problems. In the end I tested the flags for edge cases for add/sub (like 127+1) with a real 6502 and compared them directly to the output of my ALU and tweaked as required.
This part “it spews an error thatโs every possible BASIC error message concatenated together” just made me think. I seem to remember the code that prints errors messages uses the MSB (0x80) ORed with the character code to signify the end of the character string. When it prints these strings it uses PLA (pulls the character from the stack) followed by BPL to detect the MSB being clear. So make sure when you PLA the processor flags are updated.
The concatenated error messages no longer occur– that was an earlier bug in my microcode that’s now fixed. Good memory about the MSB end of string marker! What else was bumped out of your brain to save room for that? ๐
At this point the only remaining problem I’m aware of is that any reference to a string literal or variable causes a crash, and I’ve traced that to a faulty/glitchy memory access at once specific location. I haven’t had time to debug it further since last Monday: been too busy and sick.
Birthdays were replaced by 6502 and C64 stuff. ๐