Intellec8/MOD 80 Monitor (1/2)
From
Mr. Emmanuel Roche, France@21:1/5 to
All on Tue Aug 31 23:26:45 2021
; MOD80MON.ASM
; ------------
;
; Intellec8/MOD 80 Monitor, Version 3.0, 14 April 1975
; Intel 98-0007C
;
; (Retyped by Emmanuel ROCHE.)
;
; Copyright (C) 1973, 1974, 1975
; Intel Corporation
; 3065 Bowers Avenue
; Santa Clara, California 95051
;
; <legal command> ::= <assign I/O command>
; <BNPF punch command>
; <compare command>
; <display memory command>
; <endfile command>
; <fill memory command>
; <program execute command>
; <hexadecimal arithmetic command>
; <load BNPF command>
; <move memory command>
; <leader command>
; <program command>
; <read hexadecimal file command>
; <substitute memory command>
; <transfer command>
; <write hexadecimal record command>
; <register modify command>
;
; <assign I/O command> ::= A<logical device>=<physical device>
;
; <BNPF punch command> ::= B<number>,<number>
;
; <compare command> ::= C<number>
;
; <display memory command> ::= D<number>,<number>
;
; <endfile command> ::= E<number>
;
; <fill memory command> ::= F<number>,<number>,<number>
;
; <program execute command> ::= G<number>,<number>,<number>
;
; <hexadecimal arithmetic command> ::= H<number>,<number>
;
; <load BNPF command> ::= L<number>,<number>
;
; <move memory command> ::= M<number>,<number>,<number>
;
; <leader command> ::= N
;
; <program command> ::= P<number>,<number>,<number>
;
; <read hexadecimal file command> ::= R<number>
;
; <substitute memory command> ::= S<number>
;
; <transfer command> ::= T<numbr>
;
; <write hexadecimal record command> ::= W<number>,<number>
;
; <register modify command> ::= X<register identifier>
;
; <logical device> ::= console|reader|list|punch
;
; <physical device> ::= CRT|TTY|PTR|PTP|BATCH|1|2
;
; <register identifier> ::= A|B|C|D|E|F|H|L|M|P|S
;
; <number> ::= <hex digit>
; <number><hex digit>
;
; <hex digit> ::= 0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F
;
; System signs on with <CR><LF><.>
ver EQU 30 ; Version 3.0
TITLE ' Intellec8/Mod 80 Monitor, Version 3.0, 14 April 1975 '
; I/O device ouput Command port 1 (TTC) bit values
;
; Bit Rest Mnemonic Description
; --- ---- -------- -----------
; 0 0 RBIT TTY reader go/no go
; 1 0 PCMD PTP go/no go
; 2 0 RCMD PTR go/no go
; 3 1 DSB PROM enable/disable, DSB=1
; 4 0 Data in T/C
; 5 0 Data out T/C
; 6 0 PBIT 1702 PROM prog. go/no go
; 7 0 PBITA 1702A PROM prog. go/no go
; I/O device input Status port 1 (TTS) bit values
;
; Bit Rest Mnemonic Description
; --- ---- -------- -----------
; 0 1 TTYDA If TTYDA=0 input is ready
; 1 1 Overrun error
; 2 0 TTYBE If TTYBE=0 output is ready
; 3 1 Framing error
; 4 1 Parity error
; 5 0 PTRDA If PTRDA=1 PTR has char.
; 6 1 PRDY If PRDY=1 PTP is ready
; 7 Unassigned
; I/O device input Status port 5 (CRTS) bit values
;
; Bit Rest Mnemonic Description
; --- ---- -------- -----------
; 0 1 CRTDA If CRTDA=0 input is ready
; 1 1 Overrun error
; 2 0 CRTBE If CRTBE=0 output is ready
; 3 1 Framing error
; 4 1 Parity error
; 5 Unassigned
; 6 Unassigned
; 7 Unassigned
; I/O command constants
;
RBIT EQU 1
PCMD EQU 2
RCMD EQU 4
DSB EQU 8
PBITA EQU 80H
; TTY I/O constants
;
TTI EQU 0 ; TTY Input data port
TTO EQU 0 ; TTY Output data port
TTS EQU 1 ; TTY input Status port
TTC EQU 1 ; TTY ouput Command port
TTYGO EQU RBIT OR DSB ; Start TTY reader
TTYNO EQU DSB ; Stop TTY reader
TTYDA EQU 1 ; Data Available
TTYBE EQU 4 ; Transmit Buffer Empty
; CRT I/O constants
;
CRTI EQU 4 ; CRT Input data port
CRTO EQU 4 ; CRT Output data port
CRTS EQU 5 ; CRT input Status port
CRTDA EQU 1 ; Data Available
CRTBE EQU 4 ; Transmit Buffer Empty
; PTR I/O constants
;
PTRI EQU 3 ; PTR Input data port (not inverted)
PTRS EQU TTS ; PTR input Status port
PTRC EQU TTC ; PTR Output command port
PTRGO EQU RCMD OR DSB ; Start reader
PTRNO EQU TTYNO ; Stop reader
PTRDA EQU 20H ; PTR Data Available
; PTP I/O constants
;
PTPO EQU 3 ; PTP Output data port
PTPS EQU TTS ; PTP input Status port
PTPC EQU TTC ; PTP output Command port
PRDY EQU 40H ; Punch ReaDY status
PTPGO EQU PCMD OR DSB ; Start punch
PTPNO EQU TTYNO ; Stop punch
; PROM programmer I/O constants
;
PAD EQU 2 ; PROM ADdress output port
PDO EQU PTPO ; PROM Data Output port
PDI EQU 2 ; PROM Data Input port
PROMC EQU TTC ; Programming pulse output port
PROGO EQU PBITA ; Start programming
PRONO EQU 0 ; Stop programming
ENB EQU 0 ; ENaBle programmer
; Conditional assembly switches
;
false EQU 0
true EQU NOT false
debug EQU false ; Debug mode -
; Modify certain code sections,
; so that Version 2.0 may be
; debugged by Version 1.0.
; Global constants
;
TOUT EQU 250 ; 250 ms. counter for reader TimeOUT
LDLY EQU 20 ; Counter for 20 ms. DeLaY
IF debug
DLY EQU 111 ; Counter for 1.0 ms. delay in RAM
ENDIF
IF NOT debug
DLY EQU 84 ; Counter for 1.0 ms. delay in PROM
ENDIF
; ASCII characters used
;
CR EQU 0DH ; Carriage Return
LF EQU 0AH ; Line Feed
space EQU 20H ; ' '
dollar EQU 24H ; '$' PROM error flag
star EQU 2AH ; '*'
comma EQU 2CH ; ','
dash EQU 2DH ; '-'
dot EQU 2EH ; '.'
zero EQU 30H ; '0'
colon EQU 3AH ; ':' HEX file 1st char
equal EQU 3DH ; '='
upA EQU 41H ; 'A'
upB EQU 42H ; 'B'
upF EQU 46H ; 'F'
upN EQU 4EH ; 'N'
upP EQU 50H ; 'P'
upX EQU 58H ; 'X'
; Macro definition
;
fetch MACRO value ;; Fetch the address
lxi h,value ;; of a value
dad sp ;; in the stack.
ENDM
; I/O status byte masks and values
;
CMSK EQU 11111100B ; Mask for Console I/O
RMSK EQU 11110011B ; Mask for Reader input
PMSK EQU 11001111B ; Mask for Punch output
LMSK EQU 00111111B ; Mask for List output
CTTY EQU 00000000B ; Console I/O = TTY
CCRT EQU 00000001B ; Console I/O = CRT
BATCH EQU 00000010B ; Batch mode -
; input = reader, output = list.
CUSE EQU 00000011B ; User-defined console I/O
RTTY EQU 00000000B ; Reader = TTY
RPTR EQU 00000100B ; Reader = PTR
RUSE1 EQU 00001000B ; User-defined Reader (1)
RUSE2 EQU 00001100B ; User-defined Reader (2)
PTTY EQU 00000000B ; Punch = TTY
PPTP EQU 00010000B ; Punch = PTP
PUSE1 EQU 00100000B ; User-defined Punch (1)
PUSE2 EQU 00110000B ; User-defined Punch (2)
LTTY EQU 00000000B ; List = TTY
LCRT EQU 01000000B ; List = CRT
LUSE1 EQU 10000000B ; List = LPT
LUSE2 EQU 11000000B ; User-defined List
; User-defined device entry points
;
CILOC EQU 3700H ; User Console Input
COLOC EQU 3703H ; User Console Output
R1LOC EQU 3706H ; User Reader (1)
R2LOC EQU 3709H ; User Reader (2)
P1LOC EQU 370CH ; User Punch (1)
P2LOC EQU 370FH ; User Punch (2)
L1LOC EQU 3712H ; User List (1)
L2LOC EQU 3715H ; User List (2)
CSLOC EQU 3718H ; User Console Status
IF debug
ORG 800H ; Locate in RAM for debug
ENDIF
IF NOT debug
ORG 3800H ; Locate in top 8 ROMs in 16K
ENDIF
;--------------------------------
; Branch table for I/O system
jmp begin ; Reset entry point
jmp ci ; Console Input
jmp ri ; Reader Input
jmp co ; Console Output
jmp po ; Punch Output
jmp lo ; List Output
jmp csts ; Console input STatuS
jmp iochk ; I/O system status
jmp ioset ; Set I/O configuration
jmp memck ; Compute size of memory
;--------------------------------
; Pointers to RAM
;
RS1 EQU 8 ; Restart 1 logic
; Status byte for I/O system
IF NOT debug
iobyt EQU 3 ; Use location 0003H
ENDIF
IF debug
iobyt EQU 4 ; Use location 0004H
ENDIF
init EQU 000000B ; Initially,
; ------00 Console = TTY,
; ----00-- Reader = TTY,
; --00---- Punch = TTY,
; 00------ List = TTY.
vers db cr, lf, '8080 V'
IF NOT debug
db ver/10+'0','.',ver MOD 10+'0'
ENDIF
IF debug
db 'X.X'
ENDIF
Lver EQU $-vers ; Length of sign-on message
;--------------------------------
; Program entry point
;
; Compute the top of RAM memory available in this system,
; and locate the user register save area, exit template,
; and monitor stack at the top of RAM.
begin: lxi h,iobyt ; Point HL at IOBYT
mvi m,init ; Initial value of I/O
mvi l,0ffh ; Find end of memory
bg0: dcr h
mov a,m ; Fetch contents of memory
cma ; Invert it
mov m,a ; Attempt to write into memory
cmp m ; Is location Read/Write?
cma ; Invert again
mov m,a ; Write data back
jnz bg0 ; Yes: continue
inx h ; No: point to first non-RAM location
IF debug
mvi h,2 ; Set stack at 200H for debug
ENDIF
mvi b,endx-exit ; Move exit template to RAM
lxi d,endx
bg1: dcx d
ldax d
dcx h
mov m,a
dcr b
jnz bg1
sphl ; Set stack
lxi h,0100H
push h
mvi h,00h
push h ; Push registers on stack
push h
push h
IF NOT debug ; If in debug mode, don't set traps
mvi a,jmp
sta rs1
lxi h,restart ; Set up Restart 1 for breakpoint
shld rs1+1 ; logic.
ENDIF
; Type sign-on
;
lxi h,vers ; Address of message
mvi d,Lver ; Length of message
ver0: mov c,m
inx h
call co
dcr d
jnz ver0
; Main command loop
;
; This loop is the starting point of all command sequences.
; In this code, interrupts are enabled, all I/O devices are
; initialized, a Carriage Return and Line Feed are typed,
; along with the prompt character, '.'. When a character is
; entered from the console keyboard, it is checked for validity,
; then a branch to the proper processing routine is computed.
start: ei ; Enable interrupts
mvi a,ttyno ; Reset TTY, PTR, PTP,
out ttc ; and PROM programmer.
call crlf ; Type <CR>,<LF>
mvi c,dot
call co ; Output a period
call ti ; Get a character
sui upA ; Test for A-X
jm start ; LT A, error
cpi upX-upA+1
jp Ler ; GT X, error
add a ; * 2
lxi h,tbl ; Address of table
add l
mov l,a ; Compute table address, put in HL
mov a,m ; Get LSB of address
inx h ; Point to next address
mov h,m ; Get MSB of address
mov l,a ; LSB to A
mvi c,02h ; C is set for 2-param commands
pchl ; Branch to routine
; Command branch table
;
; This table contains the addresses of the entry points of
; all the command processing routines. Note that an entry to
; 'LER' is an error condition, i.e., no command corresponding
; to that character exists.
tbl: dw assign ; A - assign I/O units
dw bnpf ; B - punch BNPF
dw comp ; C - compare PROM with memory
dw disp ; D - display RAM memory
dw eof ; E - endfile a HEX file
dw fill ; F - fill memory
dw goto ; G - go to memory address
dw hexn ; H - hexadecimal sum and difference
dw Ler ; I -
dw Ler ; J -
dw Ler ; K -
dw Load ; L - load BNPF tape
dw move ; M - move memory
dw null ; N - punch NULLs for leader
dw Ler ; O -
dw prog ; P - program a 1702A PROM
dw Ler ; Q -
dw read ; R - read HEX file
dw subs ; S - substitute memory
dw tran ; T - transfera PROM to memory
dw Ler ; U -
dw Ler ; V -
dw write ; W - write HEX file
dw x ; X - examine and modify registers
;--------------------------------
; Process I/O device assignments commands
;--------------------------------
; This routine maps symbolic device identifiers to bits
; in the I/O status byte (IOBYT) to allow for console
; modification of system I/O configuration.
assign: call ti ; Get logical device character
lxi h,Ltbl ; Address of master table
mvi c,04h ; Maximum of 4 entries
as0: cmp m ; Test for identifying character
inx h
jz as1 ; Found it
inx h ; Point to next entry
inx h
inx h
dcr c ; Decrement loop count
jnz as0 ; Try next entry
jmp Ler ; No match: error
as1: mov b,m ; Get select bit mask
inx h
mov e,m ; Get physical device table
inx h
mov d,m
xchg
as2: call ti ; Scan until '=' is found
cpi equal
jnz as2
as3: call ti ; Deblank
cpi space
jz as3
mvi c,04h ; Set table length
as4: ; Index through physical unit table
cmp m ; Compare device char. with legal values
inx h
jz as5 ; Return with HL -> device select bits
inx h
dcr c
jnz as4 ; Continue lookup
jmp Ler ; Error return
as5: call ti
cpi cr
jnz as5 ; Loop until CR encountered
mov c,m ; Get device select bits
lxi h,iobyt ; Get I/O status
mov a,m
ana b ; Clear field
ora c ; Set new status
mov m,a ; Return to memory
jmp start
;--------------------------------
; Punch a BNPF tape
;
; This routine expects 2 hexadecimal parameter to
; be entered from the keyboard, and interprets them
; as the bounds of a memory area to be punched on
; the assigned punch device in BNPF format. The tape
; produced is formatted with 4 BNPF 8-bit words per
; line, with a reference address in decimal preceding
; each line.
bnpf: call expr ; Get 2 addresses
call crlf
call lead
pop d ; Get high address
pop h ; Get low address
bn0: push h
push d
call peol ; Punch CR,LF
mvi b,space ; Zero suppression character
lxi d,10000 ; Punch address in decimal
call digit
lxi d,1000
call digit
lxi d,100
call digit
mvi e,10
call digit
mvi e,1
mvi b,zero ; Force at least 1 zero
call digit
mvi c,space
call po
pop d
pop h
bn1: call encode ; Encode a memory byte into BNPF
call hilo
jc null ; All done, punch trailer and return
mov a,l
ani 03h ; Punch CR,LF,Address on multiple of 4
jnz bn1
jmp bn0
;--------------------------------
; Compare PROM with memory
;
; This routine expects 1 hexadecimal parameter which
; it interprets as a memory address. The routine
; compares the PROM in the Front Panel socket with a
; 256-byte area of memory pointed to be the input parameter.
; All differences between the PROM and the memory are
; are displayed in the following format:
;
; <mem address> <mem contents> <corresponding PROM contents>
comp: dcr c
call expr ; Get one address
pop h ; Load HL
mvi e,00h ; Count/PROM address
cm0: mvi a,enb
out promc ; Enable PROM programmer
mov a,e ; Set PROM address
cma ; Invert address
out pad
call delay ; Wait for imm6-76 board to latch data
in pdi ; Get PROM data
cma
cmp m ; Compare with memory
jz cm1 ; Compare
push psw
call crlf
call Ladr ; Print memory address
call blk
mov a,m
call Lbyte ; Print RAM data
call blk
pop psw ; Retrieve data
call Lbyte ; Print PROM data
cm1: inx h
inr e ; Adjust PROM address
jnz cm0
jmp start
;--------------------------------
; Display memory in hex on console device
;
; This routine expects 2 hexadecimal parameters specifying
; the bounds of a memory area to be displayed on the
; console device. The memory area is displayed 16 bytes
; per line, with the memory address of the first byte
; printed for reference. All lines are blocked into integral
; multiples of 16 for clarity, so that the first and last
; lines may be less than 16 bytes, in order to synchronize
; the display.
disp: call expr ; Get 2 addresses
pop d ; Get high address
pop h ; Get low address
di0: call crlf
call Ladr ; Print memory address
di1: call blk ; Print space
mov a,m
call Lbyte ; Print data
call hilo ; Test for completion
jc start
mov a,l
ani 00001111B ; Print CR,LF,Address on multiple of 16
jnz di1
jmp di0
;--------------------------------
; End of file command
;
; This routine produces a termination record which properly
; completes a HEX file created by 'W' commands. It
; expects 1 hexadecimal parameter which is encoded in the
; termination record in the load address field, and specifies
; the entry point of the file created. A subsequent 'R' command
; will load the file created and transfer control to the
; entry point specified if it is non-zero.
eof: dcr c ; Get 1 parameter
call expr
call peol ; Punch CR,LF
mvi c,colon
call po ; Punch HEX file 1st char.
xra a ; Clear checksum
mov d,a
call pbyte ; Output record length
pop h
call padr ; Punch execution address
mvi a,01h ; Record type 1
call pbyte
xra a
sub d ; Output checksum
call pbyte
jmp null ; Punch trailer and return
;--------------------------------
; Fill RAM memory block with constant
;
; The routine expects 3 hexadecimal parameters. The
; first and second (16 bits) are interpreted as the bounds
; of a memory area to be initialized to a constant value.
; The third parameter (8 bits) is that value.
fill: inr c ; Get 3 parameters
call expr
pop b ; Get data in C
pop d ; Get high address
pop h ; Get low address
fi0: mov m,c ; Store constant in memory
call hilo ; Test for completion
jnc fi0 ; Continue looping
jmp start
;--------------------------------
; Go to <address>, optionally set breakpoints
;
; The G command is used for transferring control from
; the Monitor to a user program. It has several modes
; of operation.
;
; If one hexadecimal parameter is entered, it is interpreted
; as the entry point of the user program and a transfer to
; that location is executed.
;
; If additional (up to 2) parameters are entered, these
; are considered 'breakpoints', i.e., locations where
; control is to be returned to the Monitor, if they are
; encountered.
;
; If the first parameter is not entered, the stored value
; of the user's Program Counter (register P) is used as
; the user program entry point.
goto: call pchk ; Get a character
jc go3 ; CR entered: exit
jz go0 ; Don't modify PC
call exp ; Get new PC value
pop d
fetch Ploc
mov m,d ; Store modified PC in RAM
dcx h
mov m,e
mov a,b ; Retrieve delimiter character
cpi cr
jz go3 ; No traps to be set
go0: mvi d,02h ; Set maximum of 2 traps
fetch Tloc
go1: push h ; Save address of trap area
mvi c,01h
call expr ; Get a trap address
mov e,b ; Save delimiter character
pop b ; Get address in BC
pop h
mov a,b
ora c
jz go2 ; Don't allow a trap at 0
mov m,c ; Put trap address away
inx h
mov m,b
inx h
ldax b ; Fetch opcode
mov m,a ; Put in trap area
inx h
mvi a,RST ; Restart 1
stax b ; Set trap in memory
go2: mov a,e ; Test delimiter character
cpi cr
jz go3 ; All done
dcr d
jnz go1 ; Go get newt trap
go3: call crlf
fetch 8
pchl ; Take the branch
;--------------------------------
; Compute hexadecimal sum and difference
;
; This routine expects 2 hexadecimal parameters.
; It computes the sum and difference of the 2 values
; and displays them on the console device as follows:
;
; <p1+p2> <p1-p2>
hexn: call expr ; Get 2 numbers
pop d
pop h
call crlf
push h
dad d ; Compute HL+DE
call Ladr ; Display sum
call blk ; Type a space
pop h
mov a,l ; Compute HL-DE
sub e
mov l,a
mov a,h
sbb d
mov h,a
call Ladr ; Display difference
jmp start
;--------------------------------
; Load a BNPF tape into RAM memory
;
; This routine expects 2 hexadecimal parameters, and
; interprets them as bounds of a memory area to be
; loaded by BNPF data to be read from the reader.
; It is assumed that enough data is available in the
; tape to be read to satisfy the memory bounds entered.
; If end of tape is encountered before the memory bounds
; are satisfied, this routine will terminate on an error
; condition (see RIX), but all data read before the end
; of tape was encountered will be loaded.
Load: call expr ; Get 2 addresses
call crlf
pop d ; Get high address
pop h ; Get low address
Lo0: call decode ; Convert BNPF, store in memory
call hilo ; Test for completion
jnc Lo0 ; Keep going
jmp start
;--------------------------------
; Move a block of memory
;
; This routine expects 3 hexadecimal parameters from the
; console. The first and second parameters are the bounds of
; the memory area to be moved, the third parameter is the
; starting address of the destination area.
move: inr c ; Get 3 addresses
call expr
pop b ; Destination
pop d ; Source end
pop h ; Source begin
mv0: mov a,m ; Get a data byte
stax b ; Store at destination
inx b ; Move destination pointer
call hilo ; Test for completion
jnc mv0
jmp start
;--------------------------------
; Punch leader or trailer
;
; This routine punches 60 NULL ASCII characters on the
; device assigned as the punch. It is branched to by
; the 'B' and 'E' commands, as well as being invoked
; by the 'N' command.
null: call lead
jmp start
;--------------------------------
; Program a 1702A PROM with fast algorithm
; (20.46 to 409.6 seconds)
;
; This routine expects 3 hexadecimal parameters from the
; console. The first and second are the bounds of a
; memory area to be reproduced in the 1702A PROM in the
; Front Panel socket. The third parameter is the address
; in the PROM (8 bits) where the duplication is to commence.
; The algorithm used in this routine takes advantage of the
; fact that most PROMs may be programmed in a small fraction
; of the time that it would take under worst case conditions,
; therefore greatly reducing programming time for most PROMs.
; The wide variation in times quoted is due to the allowable
; range between best and worst case programming times.
prog: inr c
call expr ; HL = top after return
call crlf
pop b ; C <- PROM address
pop d ; High address
pop h ; Low address
pr0: mvi a,enb
out promc ; Enable PROM programmer
mov a,c
out 0ffh ; Display address
cma
out pad ; PROM address
in pdi
cma
cmp m
jz pr4 ; Don't have to program the loc
mvi b,-16 ; Set max tries = 16
pr1: call pgrm ; Pulse and delay 16 ms.
in pdi ; Read value
cma
cmp m ; Compare with desired
jz pr2 ; Got it, now pulse 4*N more times
inr b ; Increment count
jnz pr1 ; Keep going
push b ; Error out
mvi c,dollar
call co ; Print error flag
call blk
pop b ; Restore PROM address in C
mov a,c
call Lbyte ; Display it
jmp Ler ; Error exit
pr2: mov a,b ; Move count residue to A
adi 17 ; Actual count of tries required
add a ; Count = count * 2
add a ; Count = count * 4
mov b,a
pr3: ; Overprogram 4*N times
call pgrm
dcr b
jnz pr3
pr4: inr c ; Increment PROM address
call hilo
jnc pr0 ; Continue
jmp start ; All done
;--------------------------------
; Read HEX file routine
;
; This routine reads a HEX file from the assigned reader
; device and loads it into memory. One hexadecimal
; parameter is expected. This parameter is a bias address
; to be added to the memory address of each data byte
; encountered. In this way, HEX files may be loaded into
; memory in areas others than that for which they were
; assembled or compiled. All records read are checksummed
; and compared against the checksum in the record. If a
; checksum error (or tape read error) occurs, the routine
; takes an error exit. Normal loading is terminated when
; a record of length 0 is encountered. This is interpreted
; as an end-of-file record, and the load address field of
; that record is taken to be the entry point of the program
; (if it is non-zero).
read: dcr c ; Get 1 address
call expr
red0: pop h ; Get bias address
push h
call rix
mvi b,colon
sub b
jnz red0 ; Scan to record mark
mov d,a ; Clear checksum
call byte
jz red2 ; Zero record length, all done
mov e,a ; E <- record length
call byte ; Get MSB of load address
push psw ; Save it
call byte ; Get LSB of load address
pop b ; Retrieve MSB, put in B
mov c,a
dad b ; Bias address + load address -> HL
call byte ; Record type
red1: call byte ; Read data
mov m,a ; Put in memory
inx h
dcr e
jnz red1 ; Loop until done
call byte ; Read checksum
jnz Ler ; Checksum error
jmp red0 ; Get another record
red2: call byte ; Get MSB of transfer address
mov h,a
call byte
mov l,a
ora h
jz red3 ; If transfer address=0, return to KB
pchl
red3: pop h
jmp start
;--------------------------------
; Substitute memory contents routine
;
; This routine expects 1 parameter from the console,
; followed by a space. The parameter is interpreted
; as a memory location, and the routine will display
; the contents of that location, followed by a dash (-).
; To modify memory, type in the new data followed by
; a space or a Carriage Return. If no modification of
; the location is required, type only a space or
; Carriage Return. If a space was last typed, the next
; memory location will be displayed and modification
; of it is allowed. If a Carriage Return was entered,
; the command is terminated.
subs: dcr c
call expr ; Get 1 address
call p2c
jc Ler
pop h
su0: mov a,m
call Lbyte ; Display data
mvi c,dash
call co
call pchk
jc start ; CR entered, return to command mode
jz su1 ; Space entered, space by
push h ; Save memory address
call exp ; Get new value
pop d ; E = value
pop h ; Restore memory address
mov m,e ; Store new value
mov a,b ; Test delimiter
cpi cr
jz start ; CR entered after last substitution
su1: inx h
jmp su0
;--------------------------------
; Transfer contents of a PROM to memory
;
; This routine expects 1 hexadecimal parameter which is
; interpreted as the location in memory where a copy of
; the PROM in the Front Panel socket is to be stored.
; This copy is always 256 bytes in length.
tran: dcr c
call expr ; Get 1 address
pop h ; HL = mem adr
mvi e,00h ; Count/PROM address
tr0: mvi a,enb
out promc ; Enable PROM programmer
mov a,e
cma ; Invert address
out pad ; Set PROM address
call delay ; Wait for imm6-76 board to latch data
in pdi ; Get PROM data
cma
mov m,a ; Put in memory
inx h ; Bump memory pointer
inr e ; Bump PROM pointer
jnz tr0 ; Get another byte
jmp start
;--------------------------------
; Write HEX file routine
;
; This routine expects 2 hexadecimal parameters which are
; interpreted as the bounds of a memory area to be encoded
; into HEX file format, and punched on the assigned punch
; device.
write: call expr ; Get 2 addresses
call crlf
pop d ; Get high address
pop h ; Get low address
wri0: mov a,l
adi 16
mov c,a
mov a,h
aci 00h
mov b,a
mov a,e
sub c
mov c,a
mov a,d
sbb b
jc wri1 ; Record length = 16
mvi a,16
jmp wri2
wri1: mov a,c ; Last record
adi 17
wri2: ora a
jz start
push d ; Save high address
mov e,a ; E = length
mvi d,00h ; Clear checksum
call peol ; Punch CR,LF
mvi c,colon
call po
mov a,e
call pbyte ; Punch length
call padr ; Punch address
xra a
call pbyte ; Punch record type
wri3: mov a,m
inx h
call pbyte ; Punch data
dcr e ; Decrement length
jnz wri3 ; Continue looping
xra a
sub d
call pbyte ; Punch checksum
pop d ; Restore high address
jmp wri0
;--------------------------------
; Examine and modify CPU registers
;
; This routine allows the operator to examine and/or
; modify the contents of the user program's registers.
; The register values were stored as a result of a
; previous breakpoint, and will be restored to the
; user program during a subsequent 'G' command.
x: call ti ; Get register identifier
lxi h,actbl ; Point to access table
cpi cr
jz x6 ; Full register display
x0: cmp m
jz x1
push psw ; Save the character
mov a,m
ora a ; Test for end of table
jm Ler
inx h
inx h
inx h
pop psw
jmp x0
x1: call blk
x2: inx h
mov a,m ; Displacement
xchg ; Save HL in DE (HL = pointer to ACTBL)
mov l,a
mvi h,00H
dad sp
xchg ; Restore HL
inx h
mov b,m ; Precision
inx h ; Point at next register identifier
ldax d ; 8/16-bit display and modification
call Lbyte ; MSB of 16-bit reg., all of 8-bit reg.
dcr b
jz x3 ; 8-bit display
dcx d
ldax d
call Lbyte ; LSB of 16-bit reg.
x3: inr b
mvi c,dash
call co
call pchk ; Skip if null entry
jc start ; CR entered, return to command mode
jz x5
push h ; Save pointer to ACTBL
push b ; Save precision
call exp ; Get new reg value
pop h
pop psw ; A = precision
push b ; B = delimiter char
push psw ; A = precision
mov a,l
stax d ; Store LSB in register area
pop b ; Retrieve precision
dcr b
jz x4 ; 8 bits only
inx d
mov a,h
stax d ; Store MSB in register area
x4: pop b ; Retrieve delimiter char
pop h
x5: mov a,m ; Test for end of table
ora a
jm start
mov a,b ; Test delimiter
cpi cr
jz start
jmp x2
x6: ; Full register display
call crlf
x7: call blk ; Output a space
mov a,m ; Get the character
inx h ; Point at displacement
ora a ; Set condition codes
jm start ; All done
mov c,a
call co ; Print character
mvi c,equal
call co ; Print equal sign
mov a,m ; Fetch displacement
inx h ; Point at precision
xchg ; Save HL in DE
mov l,a
mvi h,00h
dad sp ; Compute address of value
xchg ; HL = current table address
; DE = memory address
mov b,m ; Fetch precision
inx h ; Point to next display
ldax d ; Get LSB of data
call Lbyte ; Display it
dcr b
jz x7 ; 8-bit precision, all done
dcx d ; Point to MSB of 16-bit value
ldax d ; Fetch it
call Lbyte ; Display it
jmp x7 ; Continue
;--------------------------------
; Error exit
;
; This abnormal exit is executed for all Monitor error
; conditions. The Stack Pointer value is recomputed
; because of the unknown state of the processor
; as the result of a command or data error.
Ler: call MemSiz ; Compute top of memory
lxi d,-8
dad d
sphl ; Reset Stack Pointer on error return
mvi c,star
call co
jmp start
;--------------------------------
; Subroutines
;--------------------------------
; Print a blank
blk: mvi c,space
; - - - - - - - - - - - - - - - -
; Externally-referenced routine
;
; Console Output code, value expected in C
; A, Flags, C modified
; Stack usage: 2 bytes
co: lda iobyt ; Get status byte
ani LOW NOT Cmsk ; Get console bits
jnz co0 ; Test for CRT
TTYout: in tts ; Console = TTY
ani ttybe
jnz TTYout ; Loop until ready
mov a,c
cma
out tto ; Output character
ret ; Return
co0: cpi ccrt ; Console = CRT?
jnz co1 ; Test for batch
CRTout: in crts ; Console = CRT
ani crtbe
jnz CRTout ; Loop until ready
mov a,c
cma
out crto
ret
co1: cpi batch
jz lo ; Batch mode, output = list
jmp coloc ; Branch to user console output
;--------------------------------
; Read 2 ASCII characters, decode into 8 bits binary
byte: call rix ; Read char from tape
call nibble ; Convert ASCII to hex
rlc ; Shift 4 places
rlc
rlc
rlc
mov c,a
call rix
call nibble ; Get lower nibble
ora c
mov c,a
add d ; Update checksum
mov d,a
mov a,c
ret ; Return
;--------------------------------
; Externally-referenced routine
;
; Console Input code, value returned in A
; A, Flags modified
; Stack usage: 2 bytes
ci: lda iobyt ; Get status byte
ani LOW NOT Cmsk ; Get console bits
jnz ci1 ; Test for CRT
ttyin: in tts ; TTY Status port
ani ttyda ; Check for Data Available
jnz ttyin
in tti ; Read the character
ci0: cma
ret ; Return
ci1: cpi ccrt ; Console = CRT?
jnz ci2 ; Test for batch
crtin: in crts ; CRT Status port
ani crtda ; Check for Data Available
jnz crtin ; Not ready: continue looping
in crti ; Read the character
jmp ci0
ci2: cpi batch
jz ri ; Batch mode, input = Reader
jmp ciloc ; Console = user device
;--------------------------------
; Convert 4-bit value to ASCII character
; Input = 0-0FH
; Output = 30H-39H, 41H-46H (0-9, A-F)
conv: adi 10010000B ; Set up A so that A-F cause Carry
daa
aci 01000000B ; Add in Carry and adjust upper nibble
daa
mov c,a
ret ; Return
;--------------------------------
; Type Carriage Return and Line Feed on console
crlf: mvi c,cr ; <CR>
call co
mvi c,lf ; <LF>
jmp co
;--------------------------------
; Externally-referenced routine
;
; Console input STatuS code
; A, Flags modified
; Stack usage: 2 bytes
csts: lda iobyt ; Get status byte
ani LOW NOT Cmsk ; Console = TTY?
jnz cs0 ; Console = CRT
in tts ; Get TTY Status
jmp cs1
cs0: cpi ccrt
jnz cs3
in crts ; Get CRT Status
cs1: ani ttyda
mvi a,false ; Return FALSE if no Data Available
cs2: rnz
cma
ret ; Return
cs3: cpi batch
mvi a,true
jz cs2
jmp CSloc
;--------------------------------
; Read BNPF tape record, build byte, store in memory.
; If error, abort command.
decode: call rix ; Read tape
cpi upB ; Scan for 'B'
jnz decode
mvi m,01h ; Initialize memory
dc0: call rix ; Get data
cpi upN ; Check for 'N'
jnz dc2 ; No: check for 'P'
; Carry = 0
dc1: mov a,m ; Shift in data bit
ral
mov m,a
jnc dc0 ; If Carry is set, 8-bits read
call rix ; Test for required 'F'
cpi upF
jnz Ler
ret ; Return
dc2: adi -upP
jnz Ler ; Error
jmp dc1 ; Carry is set
;--------------------------------
; 1.0 ms. delay
delay: push b
mvi b,dly
dl0: dcr b
jnz dl0
pop b
ret ; Return
;--------------------------------
[continued in next message]
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)