Code_ The Hidden Language of Computer Hardware and Software - Charles Petzold [132]
ByteToAscii: PUSH PSW ; Save accumulator
RRC ; Rotate A right 4 times...
RRC
RRC
RRC ; ...to get high-order nibble
CALL NibbleToAscii ; Convert to ASCII code
MOV B,A ; Move result to register B
POP PSW ; Get original A back
AND A,0Fh ; Get low-order nibble
CALL NibbleToAscii ; Convert to ASCII code
MOV C,A ; Move result to register C
RET
These subroutines now let you display a byte in hexadecimal on the video display. If you want to convert to decimal, it's a bit more work. The process is actually quite similar to the way a person converts hexadecimal to decimal—by several divisions by 10.
Remember that you're not actually entering these assembly-language programs into memory. Instead, you're probably writing them on paper and then converting them to machine code that you then enter into memory. This "hand assembling" is something that we'll continue doing until Chapter 24.
Although the control panel doesn't require a lot of hardware, what it also lacks is ease of use. The control panel has to be the absolute worst form of input and output ever devised. It's downright embarrassing that we're clever enough to build our own computer from scratch, yet we're still keying in numbers in 0s and 1s. The first priority has to be to get rid of the control panel.
The key, of course, is the keyboard. We've constructed the computer keyboard so that every time a key is pressed, an interrupt to the microprocessor occurs. The interrupt controller chip that we've used in our computer causes the microprocessor to respond to this interrupt by executing a RST (Restart) instruction. Let's suppose that this is a RST 1 instruction. This instruction causes the microprocessor to save the current program counter on the stack and to jump to address 0008h. Beginning at that address, you'll enter some code (using the control panel) that we'll call the keyboard handler.
To get this all working right, you'll need some code that's executed when the microprocessor is reset. This is called initialization code. The initialization code first sets the stack pointer so that the stack is located in a valid area of memory. The code then sets every byte in the video display memory to the hexadecimal value 20h, which is the ASCII space character. This procedure gets rid of all the random characters on the screen. The initialization code uses the OUT (Output) instruction to set the position of the cursor—the underline on the video display that shows you where the next character you type will be entered—to the first column of the first row. The next instruction is EI to enable interrupts so that the microprocessor can respond to the keyboard interrupt. That instruction is followed by a HLT to halt the microprocessor.
And that's it for the initialization code. From now on, the computer will mostly be in a halted state resulting from executing the HLT instruction. The only event that can nudge the computer from the halted state is a Reset from the control panel or an interrupt from the keyboard.
The keyboard handler is much longer than the initialization code. Here's where all the really useful stuff takes place.
Whenever a key is pressed on the keyboard, the interrupt signal causes the microprocessor to jump from the HLT statement at the end of the initialization code to the keyboard handler. The keyboard handler uses the IN (Input) instruction to determine the key that has been pressed. The keyboard handler then does something based on which key has been pressed (that is, the keyboard handler processes each key) and then executes a RET (Return) instruction to go back to the HLT statement to await another keyboard interrupt.
If the pressed key is a letter or a number or a punctuation mark, the keyboard handler uses the keyboard scan code, taking into account whether the Shift key is up or down, to determine the appropriate ASCII code. It then writes this ASCII code into the video display memory at the cursor position. This procedure is called