162 lines
3.9 KiB
NASM
162 lines
3.9 KiB
NASM
; Tests interrupt on input: the console asking for attention instead of being asked.
|
|
;
|
|
; The control port has two bits and they are independent of one another. Bit 0 puts the
|
|
; console in key mode; bit 1 says to put the interrupt line up when a byte arrives. The
|
|
; console is on port 0x00, so that is the vector a key comes through - a device raises its
|
|
; line on its base port, and the status and control ports belong to the same device as the
|
|
; data port.
|
|
;
|
|
; The main program does nothing at all but wait to be told it is finished. It never looks
|
|
; at the console, which is the whole point: every byte is dealt with by the handler.
|
|
;
|
|
; What the status bits mean:
|
|
; bit 0 READY reading the data port will not have to wait
|
|
; bit 1 ENDED input has run out for good
|
|
; bit 2 KEYMODE the console is in key mode
|
|
; bit 3 INTERRUPTS the console is set to raise its line when a byte arrives
|
|
;
|
|
; This runs with input from a file rather than a terminal, so key mode has no terminal to
|
|
; put into another state and nothing here depends on one. A pipe with bytes in it is a
|
|
; console with keys waiting as far as the console is concerned.
|
|
|
|
#Include console.asm
|
|
|
|
#Program
|
|
|
|
start:
|
|
CIF ; Nothing gets through until there is something to catch it.
|
|
|
|
SETD.0 Banner
|
|
CALL printString
|
|
CALL newLine
|
|
|
|
; Key mode and interrupt on input, asked for in one write. Neither bit depends on the
|
|
; other, so there is no order to get wrong.
|
|
INIA 0x03
|
|
OUTA 0x02
|
|
SETD.0 AskedLabel
|
|
CALL printString
|
|
CALL showStatus
|
|
|
|
SETD.0 ArrivedLabel
|
|
CALL printString
|
|
CALL newLine
|
|
|
|
SIF ; From here a byte arriving runs keyHandler.
|
|
|
|
waitLoop:
|
|
; Waiting without looking. Nothing in this loop touches the console, so every byte that
|
|
; comes out below was put there by something that interrupted this.
|
|
SETD.3 Finished
|
|
LDA.3
|
|
RSTB
|
|
OR ; Q is the flag, so this is a test for zero.
|
|
BRQ waitLoop
|
|
|
|
CALL newLine
|
|
RSTA
|
|
OUTA 0x02 ; Line mode and no interrupts, the way it was found.
|
|
SETD.0 DoneLabel
|
|
CALL printString
|
|
CALL showStatus
|
|
HALT
|
|
|
|
; Entered because the console had something to say. It is never called.
|
|
;
|
|
; DP3 is used freely here: an interrupt saves all four Data Pointers and RETI puts them
|
|
; back, so a handler cannot disturb what it interrupted no matter what it touches.
|
|
keyHandler:
|
|
INA 0x01
|
|
INIB 0x02 ; ENDED
|
|
AND
|
|
BNQ keyEnded
|
|
INA 0x00 ; The byte this interrupt was about.
|
|
OUTA 0x00 ; Nothing echoes in key mode, so the program does it.
|
|
RETI
|
|
|
|
keyEnded:
|
|
; The end of input raises the line once, so a program driven entirely by interrupts
|
|
; still finds out that nothing more is coming. Without it this would wait forever for a
|
|
; key that cannot arrive.
|
|
SETD.3 Finished
|
|
INIA 0x01
|
|
STA.3
|
|
RETI
|
|
|
|
; Prints the status byte as hex and then names the bits that are up, so a change in the
|
|
; output says which bit moved rather than only that the number is different.
|
|
showStatus:
|
|
INA 0x01
|
|
PSHA
|
|
CALL printByteHex
|
|
INIA 0x20
|
|
OUTA 0x00
|
|
POPA
|
|
PSHA
|
|
|
|
INIB 0x01
|
|
AND
|
|
BRQ showNotReady
|
|
SETD.0 ReadyWord
|
|
CALL printString
|
|
showNotReady:
|
|
POPA
|
|
PSHA
|
|
|
|
INIB 0x02
|
|
AND
|
|
BRQ showNotEnded
|
|
SETD.0 EndedWord
|
|
CALL printString
|
|
showNotEnded:
|
|
POPA
|
|
PSHA
|
|
|
|
INIB 0x04
|
|
AND
|
|
BRQ showNotKeys
|
|
SETD.0 KeysWord
|
|
CALL printString
|
|
showNotKeys:
|
|
POPA
|
|
|
|
INIB 0x08
|
|
AND
|
|
BRQ showNotInterrupts
|
|
SETD.0 InterruptsWord
|
|
CALL printString
|
|
showNotInterrupts:
|
|
CALL newLine
|
|
RET
|
|
|
|
#Data
|
|
|
|
Banner:
|
|
"console input interrupts"
|
|
|
|
AskedLabel:
|
|
"asked for: "
|
|
ArrivedLabel:
|
|
"what arrived:"
|
|
DoneLabel:
|
|
"at the end: "
|
|
|
|
ReadyWord:
|
|
"ready "
|
|
EndedWord:
|
|
"ended "
|
|
KeysWord:
|
|
"keys "
|
|
InterruptsWord:
|
|
"interrupts "
|
|
|
|
; Set by the handler when the console says there will be no more bytes. It is the only
|
|
; thing the handler and the program it interrupts have to say to each other.
|
|
Finished:
|
|
0x00
|
|
|
|
#Vectors
|
|
|
|
Boot start
|
|
Device 0x00 keyHandler
|