The Status Register as I wrote yesterday, is the onboard cpu register which stores some flags. The flags are side-effects of instructions. Normally instructions will manipulate and store the data in the accumulator, but depending on the result the CPU will set (put to 1) or reset (put to 0) some bits in this register.

The most important bits of the Status Register are:

Zero Flag

Every instructions that results in a zero, including transfers to accumulator or the x and y registers, will set this flag to 1, while any other result will set it to 0.

Carry Flag

Indicates if a mathematical instruction result in a situation where you will have to carry its most significant byte to another byte. It’s not the same as the overflow flag.

Overflow Flag

Indicates when the result of the operation sets the 7th bit. It’s a more restricted case of the Carry Flag.

Negative Flag

Indicates if the result is to be considered “negative”.

There are three other flags that are not used with branching, but they are present in the Status Register.

Decimal Flag,

Iit’s used to set the computer mathematical operations in “decimal” mode. Normally the 6510 will operate on bits with normal binary maths. If the decimal flag is set then the CPU will instead use the encoding and rules of Binary Coded Decimal, which trades off some ram (every byte coded in BCD will store only one out of 100 values instead of one out of 255, so it’s less compact) for getting more precise calculations.

Break Flag,

To be used to test if the processor returned from a BRK (break) instruction. I don’t know much about this flag yet.

Interrupt flag,

This indicates if the CPU is currently executing an interrupt sequence. Interrupts are special ways a machine has to hijack control from a central program to handle important events like input or output operations (for example, when the user presses a button or when the TV finishes rendering a screen).

How and why to test for the flags

The Zero Flag

Testing for the zero flag is useful, for example, in situations where you have to test a FOR-style loop or when you do comparisons on bytes.

BEQ

with BEQ you test on the result of the previous operation being EQUAL to zero (Z = 1)

LDX #$20

LOOP

LOOP

DEX

BEQ EXIT

JMP LOOP

EXIT

...

BNE

with BNE you test on the result of the previous operation being NOT EQUAL to zero (Z = 0)

LDX #$20

LOOP

LOOP

DEX

BNE LOOP

...

Note that a comparison between two numbers can also set the zero flag if both numbers are equal.

For BEQ:

LDX #$20

LDA #$20

STX $03FF

CMP $03FF

BEQ OK

LDA #$20

STX $03FF

CMP $03FF

BEQ OK

...

For BNE:

LDX #$20

LDA #$21

STX $03FF

CMP $03FF

BNE OK

LDA #$21

STX $03FF

CMP $03FF

BNE OK

...

The Negatifve Flag.

The Negative flag is useful, again, for countdowns, or is useful too in mathematical operations or other comparisons. You can test the Negative Flag with the following operations:

BMI

You use this to test if the result is negative (N = 1)

LDX #$20

LDA #$1F

STX $03FF

CMP $03FF

BMI OK

LDA #$1F

STX $03FF

CMP $03FF

BMI OK

...

BPL

You use this to test if the result is positive (N = 0)

LDX #$20

LDA #$21

STX $03FF

CMP $03FF

BPL OK

LDA #$21

STX $03FF

CMP $03FF

BPL OK

...

The Carry Flag.

The Carry flag is useful with mathematical calculations. With an 8 bit computer you are not limited to work on 8 bit values, but you can chain those values to represent an higher precision number spending a bit more memory. Note that the Carry flag is automatically used by several mathematical operations as well. You can also see a bit more info on the C64 Wiki.

BCS

By now you can imagine that Branch on Carry Set branches when the Carry flag is set (C = 1)

LDA #$FF

ADC #$01

BCS OK

ADC #$01

BCS OK

...

BCC

Branch on carry clear instead jumps only if the Carry flag is reset (C = 0)

LDA #$FE

ADC #$01

BCC OK

ADC #$01

BCC OK

...

The Overflow Flag

There is a more limited number of instructions that will set the overflow flag, actually there are only two mathematical instructions (ADC and SBC) that will set this (and the BIT comparison instruction, but apparently BIT is rarely used). The Overflow flag is set when a 7-bit operation makes the number overflow in the 8th bit. If you add 1 to 127, you will obtain 128, which is represented like this: 10000000. In that case the ADC will remind you that, if you are using 7-bit precision numbers, to check the overflow flag if you need to test for SIGNED numbers, but you can ignore this flag instead if you are using UNSIGNED numbers. As usual, the C64 wiki explains stuff better than me.

BVS

Branch on Overflow Set (V = 1)

LDA #$7F

ADC #$01

BVS OK

ADC #$01

BVS OK

...

BVC

Branch on Overflow Clear (or “reset”) (V = 0)

LDA #$7E

ADC #$01

BVC OK

ADC #$01

BVC OK

...

The following is the code I used to test the various snippets.

*=$0810

PREAMBLE

CLD

MAIN ; you can change the parts between MAIN and KO

LDA #$7F

ADC #$01

BVC OK

KO ; if your calculation is wrong the program should print two black @'s

LDA #$00

STA $0400

STA $0401

LDX #$00

STX $D800

STX $D801

RTS

OK ; if your calculation is correct the code should print two white A's

LDA #$01

STA $0400

STA $0401

LDX #$01

STX $D800

STX $D801

RTS

; The following is how the machine stores the SYS 2080 command on

; line 10 of the Basic interpreterPREAMBLE

CLD

MAIN ; you can change the parts between MAIN and KO

LDA #$7F

ADC #$01

BVC OK

KO ; if your calculation is wrong the program should print two black @'s

LDA #$00

STA $0400

STA $0401

LDX #$00

STX $D800

STX $D801

RTS

OK ; if your calculation is correct the code should print two white A's

LDA #$01

STA $0400

STA $0401

LDX #$01

STX $D800

STX $D801

RTS

; The following is how the machine stores the SYS 2080 command on

; 10 SYS 2064

*=$801

BYTE $0B, $08, $0A, $00, $9E, $20, $32, $30, $36, $34, $00, $00, $00

*=$801

BYTE $0B, $08, $0A, $00, $9E, $20, $32, $30, $36, $34, $00, $00, $00

## No comments:

## Post a Comment