173 lines
3.9 KiB
NASM
173 lines
3.9 KiB
NASM
; The fence.
|
|
;
|
|
; A guarded range is a fence rather than a wall. Any program may raise one and any
|
|
; program may lower it, so nobody is ever told no. What it stops is walking into
|
|
; something by accident, which is the failure that costs an afternoon: without it, code
|
|
; that gets walked over is found much later, when the wreckage is finally executed and
|
|
; the evidence is long gone.
|
|
;
|
|
; The handler reads the controller's destination registers to say where the refused write
|
|
; was aimed. That is the whole point of catching it at the instruction that did it: the
|
|
; address is still sitting there to be read.
|
|
;
|
|
; The addresses here are absolute rather than labels, so that this says the same thing no
|
|
; matter what else ends up in the Data Segment. Data Memory is 64K and this program uses
|
|
; a hundred bytes of it, so 0x0200 is empty ground.
|
|
;
|
|
; Correct output is:
|
|
; outside ok a write just below the fence went through
|
|
; caught 0200 a write inside it was refused, and the handler says where
|
|
; caught 01FC a blit that merely clipped it was refused whole
|
|
; read ok reading inside the fence is allowed: it guards writing
|
|
; lowered ok after GuardOff the same write goes through
|
|
; fenced 05 the bank table shows bank 1 present and fenced
|
|
|
|
#Include print.asm
|
|
|
|
#Program
|
|
|
|
start:
|
|
; Fence off 0x0200 to 0x020F in Data Memory.
|
|
INIA 0d1
|
|
OUTA 0xEB ; GuardBank = 1
|
|
INIA 0x02
|
|
OUTA 0xEC
|
|
RSTA
|
|
OUTA 0xED ; GuardStart = 0x0200
|
|
INIA 0x02
|
|
OUTA 0xEE
|
|
INIA 0x0F
|
|
OUTA 0xEF ; GuardEnd = 0x020F
|
|
INIA 0x10
|
|
OUTA 0xE8 ; GuardOn
|
|
|
|
; Just below the fence is ordinary ground.
|
|
INIA 0x01
|
|
OUTA 0xE4
|
|
INIA 0xFF
|
|
OUTA 0xE5 ; Dest = 0x01FF
|
|
INIA 0d1
|
|
OUTA 0xE3 ; DestBank = 1
|
|
INIA 0x41
|
|
OUTA 0xE9
|
|
SETD.0 OutsideOk
|
|
CALL say
|
|
|
|
; Inside it is not.
|
|
INIA 0x02
|
|
OUTA 0xE4
|
|
RSTA
|
|
OUTA 0xE5 ; Dest = 0x0200
|
|
INIA 0x42
|
|
OUTA 0xE9 ; Refused.
|
|
|
|
; A blit from 0x01FC for eight bytes runs to 0x0203, so it clips the fence. It is
|
|
; refused whole rather than doing the four bytes that would have fitted.
|
|
INIA 0x01
|
|
OUTA 0xE4
|
|
INIA 0xFC
|
|
OUTA 0xE5 ; Dest = 0x01FC
|
|
INIA 0d1
|
|
OUTA 0xE0
|
|
RSTA
|
|
OUTA 0xE1
|
|
OUTA 0xE2 ; Source = bank 1, 0x0000
|
|
OUTA 0xE6
|
|
INIA 0d8
|
|
OUTA 0xE7 ; Length = 8
|
|
INIA 0x01
|
|
OUTA 0xE8 ; Refused.
|
|
|
|
; Reading inside a fence is allowed. A debugger has to be able to see what is being
|
|
; protected.
|
|
INIA 0d1
|
|
OUTA 0xE0
|
|
INIA 0x02
|
|
OUTA 0xE1
|
|
RSTA
|
|
OUTA 0xE2 ; Source = 0x0200
|
|
INA 0xE9
|
|
SETD.0 ReadOk
|
|
CALL say
|
|
|
|
; Lower it, and the write that was refused goes through.
|
|
INIA 0x11
|
|
OUTA 0xE8 ; GuardOff
|
|
INIA 0x02
|
|
OUTA 0xE4
|
|
RSTA
|
|
OUTA 0xE5
|
|
INIA 0x43
|
|
OUTA 0xE9
|
|
SETD.0 LoweredOk
|
|
CALL say
|
|
|
|
; Raise it again, and read the flags back out of the bank table, where a fence is
|
|
; published along with everything else about a bank.
|
|
INIA 0x10
|
|
OUTA 0xE8
|
|
INIA 0d2
|
|
OUTA 0xE0
|
|
RSTA
|
|
OUTA 0xE1
|
|
INIA 0d8
|
|
OUTA 0xE2 ; Bank 1's record begins at 8.
|
|
SETD.0 Fenced
|
|
CALL printString
|
|
CALL blankSpace
|
|
INA 0xE9
|
|
CALL printByteHex
|
|
CALL lineFeed
|
|
HALT
|
|
|
|
; Says where the refused write was aimed, by reading the controller's own registers.
|
|
guardHandler:
|
|
SETD.0 Caught
|
|
CALL printString
|
|
CALL blankSpace
|
|
INA 0xE4 ; DestHigh
|
|
CALL printByteHex
|
|
INA 0xE5 ; DestLow
|
|
CALL printByteHex
|
|
CALL lineFeed
|
|
|
|
; Step past the refused instruction. Every write here is an opcode and a port.
|
|
MVSD.0
|
|
DPUP.0 0d14
|
|
LDA.0
|
|
CCF
|
|
INIB 0d2
|
|
ADD
|
|
MVQA
|
|
STA.0
|
|
BRC stepCarried
|
|
RETI
|
|
stepCarried:
|
|
DPDN.0 0d01
|
|
LDA.0
|
|
INCA
|
|
STA.0
|
|
RETI
|
|
|
|
say:
|
|
CALL printString
|
|
CALL lineFeed
|
|
RET
|
|
|
|
#Data
|
|
|
|
OutsideOk:
|
|
"outside ok"
|
|
Caught:
|
|
"caught"
|
|
ReadOk:
|
|
"read ok"
|
|
LoweredOk:
|
|
"lowered ok"
|
|
Fenced:
|
|
"fenced"
|
|
|
|
#Vectors
|
|
|
|
GuardViolation guardHandler
|