INMC 80 News |
October–December 1981 · Issue 5 |
Page 44 of 71 |
---|
Now the STACK works like this. When a program is initialized, (that’s the run up to the start of the program proper), it’s normal to set the SP to the top address that the STACK will occupy. With the Nascom monitors, this is normally set to 1000H for you by the Execute command, but this may be inconvenient, and anyway it’s good practice to initialize the SP yourself, as you may one day play with other computers which aren’t so obliging, and which leave the SP any old place. So for the sake of argument, we initialize the SP to 1000H, the first time we use the STACK by executing a CALL or a PUSH instruction (there are some others that use the STACK, but these two are the most common), the SP is first decremented by one. So in this instance it will point to 0FFFH. It then places the high byte of the two byte data in memory At The Location Pointed To By The SP. The SP is the automatically decremented again, and it places the low byte At The Location Pointed TO BY THE SP. The SP is now pointing at address 0FFEH. Next time something is put on the STACK, the first thing the SP will do is to decrement by one, to point at 0FFDH. The reverse is true on a RET or POP instruction. The SP will already be at the point where the last byte was deposited in memory, so it will restore that data first without incrementing, then it will increment and restore the high byte, and last it will increment again to point at the low byte of the next data to be restored. See how the stack management is both automatic and orderly. The SP is always left pointing to the low byte of the previous data, or, looking the other way, one byte above the next data. When putting stuff on the STACK, the SP is decremented first, when getting stuff off the STACK, the SP is incremented last.
The STACK is an orderly ‘LAST IN FIRST OUT’ (LIFO) file, the last thing you put on the STACK is the first off the STACK. This normally works well, and under normal circumstances, you should never end up in the position where the data you wish to retrieve is not the next off the STACK. If you do have this sort of problem, then it is best to rethink your program, as manipulating the STACK with the INC SP and DEC SP commands is best left to experts. Unless of course, you are the masochistic type who goes looking for headaches.
One important instruction involved in this version of the B2HEX routine is the DAA. Now, the routine uses DAA because of it’s properties, and not because it is the logical instruction to use. In other words, it’s a trick. How this particular use of the DAA was discovered, I don’t know. But it proves the case for knowing exactly HOW and instruction work as opposed to the superficial knowledge of what it does. This is what it does and how it does it. The DAA instruction is primarily intended for use with ‘packed Binary Coded Decimal’ arithmetic. That’s where each nibble represents a separate decimal number, and when we add another packed BCD number to it, an adjustment has to made after the addition in case the low nibble overflowed (in decimal) and the carry has to be subsequently added to the high nibble. Don’t forget the addition would have been performed in binary, as the Z80 normally doesn’t know anything about packed BCD arithmetic. But, one thing the Z80 does provide is what is known as the ‘Half Carry flag’ which indicates this very ‘Half Carry’ overflow condition during the various addition or subtraction commands. As far as I know, the DAA instruction is the only instruction to MAKE USE OF the ‘Half Carry’ flag. If the high nibble overflows, the DAA instruction causes the C flag to be set to indicate that there was an overflow.
Now, back to B2HEX. First, lets examine the need for this particular routine. A lot of the monitor commands require the the contents of a register to be printed out on the screen. For starters, the Tab command uses it to display the contents of the memory locations, the Memory command uses it for the same purpose. Less directly, the Single Step, Arithmetic, Breakpoint, Print registers, Query ports, Read and Write routines all use it for the purpose of displaying HEX characters in either single or double byte form. So you see, this routine is used an awful lot. Now, why ‘Binary to HEX’, well, we discussed
Page 44 of 71 |
---|