Update Q1 2022
I will try to keep this section of the hackaday site going with short updates for any interested folks. The most recent update is about the real-time clock.
I wasn't that bothered about adding a realtime clock until I had got to being 'almost complete' with the FAT16 handling. After using the filesystem for a while it becomes obvious that one needs the timestamp on files. I decided to use a period part from the day, the Dallas DS12887 which was found on most PCs in the early-mid 80s. The problem is that these units have a built-in battery and they eventually die.. the solution I learnt from research is that some clever folks found that one can cut away the packaging to expose hidden pins that give access to the battery power terminals - and then hack on a button battery such as a CR2032!
The actual biggest pain is the CPU interface - the DS12887 is not directly compatible with the 6502 bus signals, but again after a lot of research, I managed to find the right configuration.
Then came the low level software - OS routines to get and set the time (plus checking if the clock it ok on boot up). After that I could code the filesystem timestamp handling - both to set and get the time. It's actually a bit of a pain on an 8 bit only CPU!
This now means I have a lot of power when I need it - for example being able to run off interrupts. I am quite pleased with how I ended up slotting this in to the interpreter. The interpreter stores all keywords as tokens to speed up execution and tokens are identified by bit 7 being set in the code. This means 128 tokens maximum - which is fine for BASIC, but as there are at least 56 mnemonics in the 6502, I wouldn't be able to treat them as normal tokens.
My solution was that the inline assembler is a kind of sub-interpreter, invoked by the main interpreter whenever it encounters a '.' (dot) symbol as the first non-whitespace character. At that point the in-line assembler does the decoding etc. So 128 token limit side-stepped.
My other problem is how to treat labels and variables. I decided fundamentally to use the same variable name space as the main code - which is handy because variables can be set in BASIC and then used by the assembler. This makes for a potentially very powerful macro assembler.
My final problem was resolving address locations. Some addressing modes of the 6502 are ambiguous such as zero page and absolute - no way to tell which addressing mode you want until the address is known. But if that address was coming from a variable which could be a forward reference and hence has not been declared yet then what to do? The solution is to do one pass where you assume everything unknown is zero page, then a second pass with forward references filled. This may result in some zero page modes becoming absolute - which takes an extra byte. If this happens then all the forward references are now wrong, until they are reached and the value updated! The solution is to do a third and final pass which uses the correct values.
Hence the reason this is a 3-pass assembler.
What can I do with this that was not possible in BASIC? Well aside from the obvious massive speed increase, it would be impossible to do effects like this, which rely on handling interrupts and micro-second precision to change video memory settings.
(Nov 2018) - Enhanced memory map and decoding - 128K RAM and 64K ROM
I'll copy the notes from my schematic by way of an explanation..
My computer uses 16K ROM and 48K ROM (minus addresses mapped to IO), but I have 64K EEPROM and 128K SRAM chips on the breadboard. The 65c02 can only address 64K through its 16 bit address bus, so the route I will go down is memory banking - the ability to switch out different parts of the total...Read more »