Now that the Apatco kit is working – at least the basic version (having trouble with the keyboard and display upgrade) – it’s time to mess around with writing code for it.
Many people swear by the now-abandoned CC65 as their compiler/assembler of choice for 6502 homebrew computers. But I’m going with Beebasm.
Although inspired by and largely aimed at the BBC Micro, and sharing many of the features of that machine’s outstanding inline assembler, Beebasm can be used for any 6502 computer.
The assembler has macros, conditional assembly (with IF statements), variables (much like BBC Basic’s assembler features), your choice of ‘$’ or ‘&’ for hex literals (don’t know why that matters to me, but it does), a lot of useful assembler directives, and even output to a BBC Micro-compatible DFS floppy disk image, if that floats your boat. (It might.)
I’ve no idea how it stacks up against CC65’s assembler features, but it’s more than enough for me right now. I’ll dig into CC65 more when I want to move to C and need a compiler.
The toolchain will be simple enough – VS Code and Beebasm. I can call Beebasm right from a VS Code terminal window. I’ll probably do this in a Bash script that will also copy the executable to a shared folder on my Nextcloud-based home cloud. That’s because I’ll need to switch to my Windows machine to actually burn the EEPROM.
Too few bits
There was one slight snag, though. If you Google for Beebasm, you’re likely to be taken to the page on the Retro Software website. That’s what I did and was glad to find a downloadable executable for the Mac. The only hitch is that an upgrade to macOS Catalina is in my near future and the executable I’d downloaded was 32-bit. Catalina spits out 32-bit programs with the contempt they deserve. So last century…
It’s easy to check if an executable is 32-bit or 64-bit. In Terminal, use ‘file’ followed by the executable name (and path if necessary). I have Beebasm in /usr/local/bin, which is in my $PATH. Having cd’d to that directory, this is what I found with file:
$ file beebasm beebasm: Mach-O executable i386
The ‘i386’ is the giveaway. That means 32-bit.
Never mind. I headed over to the Beebasm GitHub instead and downloaded the source. In Terminal I used:
git clone https://github.com/stardot/beebasm
cd beebasm/src
make code
This builds the code and drops the executable in the beebasm directory. I checked the new executable:
$ file beebasm beebasm: Mach-O 64-bit executable x86_64
Yay! Beebasm is now 64-bit.
Assemble. Burn. Rinse. Repeat.
The coding process is simple enough. Write the assembler code in VS Code. What follows is the code that Apatco supplies with the kit which I’d entered into a file called ‘bincount.asm’. When building the kit, you have to toggle it into the EEPROM in a laborious manner. The manual provides a binary listing for that, but also gives the assembler code for reference. Actually, this isn’t that code – I’ve modified it slightly to have the right syntax for Beebasm.
; Apatco demo code for 6502 breadboard computer kit. ; Modified for compiling with Beebasm assembler. ORG $E000 Out_B = $8000 ; Port B register address on VIA - not used here Out_A = $8001 ; Port A register address on VIA DDR_B = $8002 ; Port B data direction register address - not used here DDR_A = $8003 ; Port A data direction register address .start LDA #$FF ; setting data direction for port A to all outputs STA DDR_A LDA #$FF ; store 255 in memory address 1024 STA $400 .main LDA $400 ; load A with contents of addr $400 INC $400 ; increment value at $400 for next time STA Out_A ; write A to Port A register JSR delay ; pause using subroutine below JMP main ; loop forever .delay LDA #$00 LDX #$C4 ; start counter for outer loop .loopB LDY #$FF ; start counter for inner loop .loopA DEY BNE loopA ; result of DEY is not 0, so go round inner loop again DEX BNE loopB ; result of DEX is not 0, so go round outer loop again RTS .end SAVE "bincount", start, end
Note the SAVE command at the end. This tells the assembler to use the filename ‘bincount’ for the executable.
From the command line, I use:
beebasm -i bincount.asm
This assembles the code and saves the binary ‘bincount’. I could take this file and burn it to the EEPROM, but it wouldn’t run. See that ORG $E000 at the beginning? $E000 is the address of the start of the ROM in the memory map this machine uses and therefore the start address of this code. But the 6502 doesn’t know to look there for code when it first runs – it looks at $FFFC and loads whatever 16-bit address it finds there (ie, the two bytes in $FFFC and $FFFD) as the program counter. Because this is a little endian world, the byte at $FFFC is the low byte and the one at $FFFD is the high byte. We need to have the value $E000 in these two bytes, so $FFFC should be $00 and $FFFD should be $E0.
To confuse matters slightly more, when looking at the bytes in a hex editor, such as that used in the software for the MiniPro EEPROM programmer, the start address for the code you’re viewing is $0000, not $E000. So, as far as the ROM code is concerned, the addresses of the two bytes we’ve just been discussing are $1FFC (which needs to have the value $00) and $1FFD (which should be $E0). The addresses change, as far as the 6502 is concerned because of how things are memory mapped via decoding.
With the binary code in hand, I read it into the software for the MiniPro EEPROM programmer, then manually edit the bytes at $1FFC and $1FFD. Then burn the EEPROM.
It’s all simple enough, but a bit clunky and time consuming, especially when you’re bug hunting. Maybe I need to look for some kind of 6502 emulator. Any suggestions?