So I started to learn 6502 assembly language. It is not my first assembler to dabble with: I’ve been doing some small exercises in Mips assembler (largest program was a merge sort algorithm). But – oh boy – was I about to face some serious issues.
Data size
8-bit computers surprisingly deal with data in bytes. The registers are byte sized along with the other stuff. So what does it mean? Basically you can freely do stuff with numbers between 0-255, but after that it gets a bit more complicated. Now, 255 is awfully small number if you are about to, for example, multiply a number with another (not to mention the floating point numbers or the BCD format of which I may dabble with later). Even more so if you have been used to use variables like 32 bit integers without thinking it much. Which brings us to the
Instruction set
Oh dear, the instruction set is very small and lacks such novelty things like multiplication. And there is (to my knowledge) no available kernel routine for that (perhaps one could use the Basic multiplication routine?). So it pretty much looks like one has to do all the boring things first. Maybe my coworker is kind enough to let me to put his “print number” and multiplication routines in this blog at some point.
Registers
You have three of them: accumulator, X and Y and thats about it. Be prepared to swap things around quite a bit. There is also the program stack of which we will have closer look after this set of blogs.
Memory
Where the processor and registers work in 8 bit chunks, the memory address is a 16 bit number. Actually, a wrapped around one so if you want to point to the location $0c00 then you put the low byte first: $oo $0c. With all the other things this just nicely adds up to the initial confusion.
It is also quite hard to start programming a system that relies in the use of various memory locations (or routines residing in certain memory addresses) while you only know a handful of the system addresses.
Something good too!
But in the end I have to admire the simplicity, elegance and openness of the system. No wonder it has been the favorite of many modders and DIY dudes all around the world. And even though the first steps has been as comfortable as sitting on the ant’s nest with no pants on, I have some unexplained need to continue with learning and trying out various silly things with the assembler.
Anyway, here is the full source code of the assembler routine: sfoc2. It is a plain text file, the “doc” suffix is because of the file filter of WordPress. I’ll (try to) dissect the code in the following posts.
The random number generator
Lets start with random numbers instead of doing my own “linear congruential random number” generation routine I just copied one I found from the Compute’s book “Machine language routines for Commodore 64/128 “. The name of the routine is RNDDBYT:
RDINIT ; init rnd from the sound chip
LDA #$FF
STA FREHI3
LDA #%10000000
STA VCREG3
STA SIGVOL
RTS
RNDBYT
LDA RANDOM ; get random number
RTS
The RDINIT routine is called just once to set up the random number generator.
- First the number 255 is put to the accumulator and then stored to FREHI3 ($D40F, 54287) which is the high byte of frequency control for voice 3 in SID changing the voice’s wave frequency to very high.
- Then the number 128 (8th bit) is loaded to accumulator and it is used to set the voice 3 waveform type to noise (VCREG3, see for example the Commodore 64 user’s guide for more information).
- And finally the same 128 is used to set up the volume of voice 3 making it inaudible. The maximum volume is 15 so I guess making the number go over the limit will turn volume off?
The RNDBYT routine just copies the value from the “third oscillator’s waveform” whatever that means (probably it is the current value of the voice 3 waveform and since it is rabidly changing noise it will work as random number generator).
Funnily enough the routine RDBYRG in the same book gets the random number in given range (0-255) by reading the oscillator waveform until it gets the number within the given range!! This is almost as good as Bogosort.
Next time we will be back, the blog will talk about getting a random location from screen.
Filed under: Commodore64