Programs can now list and share vectors.
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
; A loaded program that is interrupted by the console rather than asking it for anything.
|
||||
;
|
||||
; Until the loadable program format could carry vectors, this could not be written. A
|
||||
; handler has to be an address in the vector table, and a program that is not the one the
|
||||
; machine booted from had no way to say what its vectors were, so interrupts belonged to
|
||||
; boot images and every loaded program had to poll. Snake polls for exactly that reason.
|
||||
;
|
||||
; What this shows is the whole path: the assembler writes the vectors into the file, the
|
||||
; system installs them when the program is run, the console raises its line, the handler
|
||||
; runs, and the system takes the vectors back out again when the program gives the machine
|
||||
; back. Nothing in the waiting loop below looks at the console at all.
|
||||
;
|
||||
; The vector is named by port, because a device interrupts on the port it is plugged into
|
||||
; and the console is on port 0x00.
|
||||
|
||||
#Include services.asm
|
||||
|
||||
#Program
|
||||
|
||||
#Base 0x2000
|
||||
|
||||
start:
|
||||
CIF ; Nothing arrives until there is something to catch it.
|
||||
|
||||
; Set rather than trusted to be zero. Running a program a second time does not load it
|
||||
; again, so its Data Segment is exactly as the last run left it - and the last thing the
|
||||
; last run did was set this.
|
||||
RSTA
|
||||
SETD.0 Stopping
|
||||
STA.0
|
||||
|
||||
SETD.0 Banner
|
||||
CALL printString
|
||||
CALL newLine
|
||||
|
||||
; Key mode and interrupt on input, in one write, since the two control bits are
|
||||
; independent of each other.
|
||||
INIA 0x03
|
||||
OUTA 0x02
|
||||
SIF
|
||||
|
||||
wait:
|
||||
; This loop is the point. It never touches the console, so every character that appears
|
||||
; below was put there by something that interrupted it.
|
||||
SETD.3 Stopping
|
||||
LDA.3
|
||||
RSTB
|
||||
OR
|
||||
BRQ wait
|
||||
|
||||
CALL newLine
|
||||
RSTA
|
||||
OUTA 0x02 ; Line mode and no interrupts, the way it was found.
|
||||
SETD.0 DoneText
|
||||
CALL printString
|
||||
CALL newLine
|
||||
SWI osExit
|
||||
|
||||
; Entered because the console had something to say. Never called.
|
||||
keyHandler:
|
||||
INA 0x01
|
||||
INIB 0x01 ; READY: is there a byte, as opposed to the end of input?
|
||||
AND
|
||||
BRQ keyNoByte
|
||||
INA 0x00
|
||||
|
||||
INIB 0x71 ; q, which is how this program is stopped.
|
||||
XOR
|
||||
BRQ keyStop
|
||||
|
||||
OUTA 0x00 ; Nothing echoes in key mode, so the handler does it.
|
||||
RETI
|
||||
|
||||
keyNoByte:
|
||||
; The end of input raises the line once as well, so a program driven entirely by
|
||||
; interrupts is told when nothing more is coming instead of waiting for ever.
|
||||
keyStop:
|
||||
SETD.3 Stopping
|
||||
INIA 0x01
|
||||
STA.3
|
||||
RETI
|
||||
|
||||
#Data
|
||||
|
||||
#Base 0x1000
|
||||
|
||||
Banner:
|
||||
"keys, by interrupt. q stops."
|
||||
DoneText:
|
||||
"the console has been handed back"
|
||||
|
||||
; The only thing the handler and the loop it interrupts have to say to each other.
|
||||
Stopping:
|
||||
0x00
|
||||
|
||||
#Vectors
|
||||
|
||||
Boot start
|
||||
Device 0x00 keyHandler
|
||||
|
||||
#Include console.asm
|
||||
@@ -9,13 +9,15 @@
|
||||
; console holds the next key until it is asked, so nothing typed between frames is lost,
|
||||
; and a script of moves plays back one move to a frame.
|
||||
;
|
||||
; WHY IT POLLS RATHER THAN INTERRUPTS. The console can raise an interrupt line when a byte
|
||||
; arrives, which is the better shape for a game: the loop would never look at the console
|
||||
; at all. A loaded program cannot use it. Installing a handler means putting an address in
|
||||
; the vector table, and the loadable program format carries only code and data - a program
|
||||
; that is not the one the machine booted from has no way to say what its vectors are. So
|
||||
; interrupts belong to boot images for now, and this asks once a frame, which is what the
|
||||
; machines this one is pretending to be did anyway.
|
||||
; WHY IT POLLS RATHER THAN INTERRUPTS. When this was written a loaded program could not be
|
||||
; interrupted at all: installing a handler means putting an address in the vector table,
|
||||
; and the loadable format carried only code and data, so a program that was not the one the
|
||||
; machine booted from had no way to say what its vectors were. That is no longer true - the
|
||||
; format carries them now, and Keys.asm is the program that shows it.
|
||||
;
|
||||
; This still polls, and now by choice. Asking once a frame is what the machines this one is
|
||||
; pretending to be actually did, it is the shape a game with a frame loop wants anyway, and
|
||||
; having one of each in the same Apps directory is worth more than having two the same.
|
||||
;
|
||||
; THE BOARD IS A PAGE, and that is the whole trick this program turns on. Sixteen by
|
||||
; sixteen is 256 squares, so a square number is a byte, and the board is aligned so that
|
||||
|
||||
Reference in New Issue
Block a user