Using The Assembler Language 06

By Roy Warner

Originally published in EUG #08

In EUG #7, a suitably contrite editor explained away CMX in lieu of CPX. No doubt everyone spotted this as the deliberate mistake or two-ish. The editor is "clearly destined for bigger and better things" say The Sunday Times. [I've been offered a job with "Total Disaster Monthly" - Will]

If a printer is available, a listing of the FINAL part five, otherwise LOAD the program and LIST 209,210.

These lines are there the up count takes place. 'temp' is the name given to the zero page address &70 (PROCconstants). The first PLA and STA at line 205 took the low byte of the program counter and stored it in 'temp', the second PLA and STA put the high byte of the program counter in 'temp+1'.

High and low bytes? As discussed before, the Electron is an eight bit machine. This is set by various data transfer channels and the 6502 processor. Eight bits in binary gives values of zero to 255. Accordingly any value greater than 256 has to be stored in TWO bytes. Low is 0 to 255 and high is also 0 to 255, but it records the number of times the low bytes has reached 256. Try it, type PRINT &0101 and you should get 257. i.e. 256+1. PRINT &0201, gives twice 256=512 plus one for the low byte =513. Great stuff. So, 513 DIV 256 produces the high byte 2 and 513 MOD 256 produces the high byte 2 and 513 MOD 256 the low byte 1. Try that!

Each time through the print loop, providing the value in the accumulator is not &FF, the program runs onto line 209 and the low greater than zero, the program branches back to 207 (.prt1) and repeats. If the value in 'temp' is 255 the INCtemp command forces a wrap round to zero and the BNE test fails, the program runs onto 210 where 'temp+1' is incremented. 'temp+1' is tested for equality with BNEprt1 and the loop continues.

What if 'temp+1' is zero??? If it is then you have a mightly peculiar Electron. User RAM starts at PAGE which always has a high byte greater than &00. The highest address the Electron can deal with is &FFFF. &FF in the accumulator causes an exit from the loop, so 'temp+1' can never be zero. However, should the EQUB&FF loop controller be forgotten, the result is twice thrice times undefined because your merry little Electron will indulge in some dumb insolence and endeavour to print the screen memory, sideways page and operating system so fast that you will not know what happened! One very crashed computer, normally requiring a power off, power on reset.

Lines 209,210 may be looked upon as a REPEAT UNTIL loop - repeat until &FF is in the accumulator. In the original print loop, the variable data was a constant value indexed to the value in X. In the current print loop the indexing register Y is a constant zero, but the value in 'temp' up-counts so as to read the string "my string" into the accumulator.

The next two listings [In the Utilities Directory under U.7USING1 and U.7USING2 - Will] contain something like FOR:NEXT loops - but execute much faster. There are other ways of looping that are cleaner and prettier, but those would involve addition, which is best dealt with another time.

Each routine introduces another assembler command, BCC - Branch Carry Clear. There is, for want of a better definition, a companion command - BCS Branch Carry Set.

There must be a method of recording these decision-making commands, and there is, the processor register, consisting of eight bits known as flags. As these are arguably the most important flags, the name is the flags register.

A flag is normally a single bit and if the value is zero, the status is clear, but if the value is 1, it is set.

From the left, bit 7 is the sign bit, and if set indicates that the value of a result will be negative. Next is bit 6 - the overflow bit - that the accumulator uses in arithmetic calculations, and which may also be used by the programmer. Bit 5 is not used. Bit 4 is the break bit, used by the processor to record if an interrupt to the program is a BREAK or merely a hardware interrupt, say a printer calling for more data. Bit 3 is the decimal bit. If set then the processor works in binary coded decimal, and if clear it works in binary. Bit 2 is the interrupt bit. The programmer uses this to stop interrupts would be masked out, BASIC deselected, and Sideways RAM selected. The interrupt bit would then be cleared to zero and interrupts may occur again. The next two are the Z bit and the Carry bit.

Four of these flags are used to control branch instructions. They are bits 7, 6, 1 and zero, namely:- N or sign bit; V or overflow bit; Z or zero bit; C or carry bit. BMI and BPL branch on MInus or PLus, test the N bit. BCC and BCS test the carry bit. BEQ and BNE test the Z bit. BVS or BVC test the overflow bit.

The carry is very important in arithmetic, but for now let's look at it as a branch instruction. In our routine we tested the accumulator with CMP # i.e. LDAtemp:CMP#4. This results in the value 4 being deducted from the value of the accumulator. The result is sunk or not recorded but flags are set. Z is set by equality, and reset or zeroed if the result is other than equal. N is set if negative, and reset if positive. C is set if the content of the accumulator is the greater value, and reset if otherwise.

So, in situations where the counter is incremented by more than one and BNE or BEQ can fail, we use CMP #Number_Funer to force a branch. BCC works when the number is greater than the accumulator value, and BCS when the accumulator value is equal to, or greater than the number.

Next time we shall take a look at post-indexed addressing and the reversed colour text window. The print routine will progress from VDU codes so EQUB28:EQUB5:EQUB20:EQUB30:EQUB12 should give you the example shown on page 113 of the User Guide. VDU 26 clears text windows, and page 107 of the User Guide will put you on the track of the reverse colour with VDU 17.