Understanding 6502 assembly on the Commodore 64 - (12) Recap and Beginning Registers

Throughout our program, we have used relatively easy math to allow us to achieve our goals, this has primarily been accomplished with four operations. INX, INY, DEX, DEY.  This is the simplest form of addition and subtraction on the 6502, and its easy to understand.  You might have noticed as well that so far we have not only avoided writing code to NMI's or IRQ's, we have shown complete disregard for our status registers, a most important part of our processor.






There are a never ending supply of instructions on 6502 programming available.  Ive found that learning 6502 by complex demo coding is like teaching someone about building engines, by giving them a car.  On the other side of the coin, books, such as those by Jim Butterfield are fantastic for learning the 6502, but you are going to start way back in the basics.  This leaves us with 2 choices.

Instant Gratification :              Nothing Learned
Slooooooow Gratification :     Much learned, little to enjoy

Many people have reached out to me, having in fact realized that I have taken small bits of the most basic of each item covered, to bring about the first 11 chapters of this instruction.   Everything here was only in the books first 3 chapters, just done a bit more fun.

From our book we covered

Chapter 1: With regard to loading and storing data in memory areas, manually to achieve an immediate response from the computer. Changing the text color of the screen, we took it a bit further to create HELLO 64 on the screen.  We went even further and Hand jammed a sprite right into memory.

As we continued, because the project was more ambitious than in the book, we covered some DEV tools to continue the lesson on modern hardware and had to quickly tough on storage areas within memory for our sprite.  The simple program in the book was small enough to fit in location $033C, our was not.  Through the 6th post we still managed to stay within chapter one of the book as we typed the program in.   We learned the most basic OPCODES, loaded our program into memory, and executed it.


OPCODES:                 LDA     LDX     LDY     STA     STX     STY
Monitor Commands:   M  X

Chapter 2: Covering basic I/O we learned about sub routines within the kernel, this introduced a JSR $FFD2 which we used to clear the screen.  You will notice the we actually didn't cover BRK, as I had no use yet to drop to a monitor, as we have ben writing our code on a cross platform tool, instead employing RTS to ultimately bring us back to basic.

We covered basic loops also found in chapter 2, we used it to load our sprite into memory.  The book used the loop to write HELLO onto the screen, we were a bit more ambitious.


MEM LOCATION:  *=$C000  
DATA TYPE:           .byte  
OPCODES:              JSR     RTS      INX


Chapter 3:   This is where we currently reside, our loop required to load the sprite has brought us to the most basic operation that tests a condition.  We wanted to run this loop until X=$40 and then had the program branch back to the loop until it equaled $40.  Such that

X=0
While X != $40

DO SOMETHING

X=X+1
NEXT X
RETURN

We used two instructions here CPX and BNE, The first ComPared X to $40, the second said that if it isn't $40, Branch Not Equal back to the beginning of the loop.  But this is machine language, how does instruction BNE decide an outcome based on instruction CPX?  This is where the register begins


We've seen this each time the monitor starts.  It can be invoked at any time by pressing the R key.  Right now we are only interested with the values off to the right, Please note that in TFC3 the ON condition is a * and the off condition is a.

Our display shows ON OFF ON ON OFF OFF OFF ON or 10110001,  to explain or CPX and BNE relation we will be focusing only on the Z flag

Lets write a small program where Jim puts it in $033C, we will use the assemble command, it may look strange below, but after the first line the memory addresses are auto incremented, you need only the code

A 033C LDX #$05
             CPX #06
             BRK         (hit return twice after this)

G 033C                  (immediately executes program at address $033C)

BRK (BREAK), our new OPCODE will halt the program and fall back to the monitor, which conveniently shows the registers every time it falls back


1: Z IS OFF
2: We load the value $05 into X     LDX $05
3: We compare X to $06                 CPX $06
4: BRK and look at Z
5: Z is OFF






A 033C LDX #$06

             CPX #06
             BRK         (hit return twice after this)

G 033C                  (immediately executes program at address $033C

1: We load the value $06 into X     LDX $06
2: We compare X to $06                 CPX $06
3: BRK and look at Z
3: Z is ON



Z is on because CPX value matched the value of that which was in X.  BNE doesn't care about what is in X and it doesn't care about CPX.  All it cares about is the value of Z.  Its inverse cousin BEQ, Branch Equal tests for the exact opposite condition, Branching is Z=0.   This comparison may also be used not just for X but for Y if need be. The instruction is CPY, ComPare Y. A will do it as well using the CMP.

Its worth pointing out, as you have probably noticed that CPX, CPY, CMP effect more than just the Z register.  It actually effects N Z and C, but thats for another chapter.  our focus is strictly on BNE.



OPCODES:                     BRK     BNE     CPX     CPY     CMP     BNE     BEQ
Monitor Commands:       R   G   A


NEXT----->
Understanding 6502 assembly on the Commodore 64 - (13) Watching the 6502 Think


Table of contents


No comments:

Post a Comment