home *** CD-ROM | disk | FTP | other *** search
- title 'Core Board Monitor - EXEC Version'
- ;****************************************************************
- ;
- ; Dicko's Universal Monitor Program.
- ;
- ; This version has been tricked up for CORE BOARD.
- ; Notables are:
- ;
- ; Written by Richard Holmes 24-05-86
- ; Last update by Richard Holmes 24-01-89
- ;
- ; Make it run any program located at 02000h 24/01/1989
- ;****************************************************************
- ;
- name 'ExecMon'
- public cmon
- ; Exec Equates.
- extrn exec
- ;
- extrn bel$cnt ; Bell down counter
- ;
- extrn con$out, con$inp, con$ist
- extrn prn$out
- ;
- public ?time ; Base of time parameter table
- public ksec,kmin,khrs
- public kdow,kdom,kmth
- public kyrs
- ;
- extrn ext$ldr
- ;
- maclib z80
- maclib core
- maclib exec
- ;
- ;
- ilhlp equ false ; Inline help
- ;
- cpos1 equ 01bh ; Cursor positioning lead in code
- cpos2 equ '='
- offset equ 020h ; Offset for vdu cursor positioning
- cscrn equ 01ah ; Clear screen code
- ;
- pgm$base equ 02000h
- ;
- ;++++++++++++++++++++++++++++++++
- ;
- ; Start of program
- ;
- ;++++++++++++++++++++++++++++++++
- ;
- cmon:
- jmp start$mon ; Leap over interrupt table
- ;
- ; Restart 1 address.
- org 8
- jmp exec
- ; Restart 2 address.
- org 16 ; Restart 2 address
- ;
- int$tbl:
- dw int$ctc0
- dw int$ctc1
- dw int$ctc2
- dw int$ctc3
- ;
- db 'Copyright (C) 1986 Richard C Holmes'
- ;
- ;++++++++++++++++++++++++++++++++
- ; Power fail detect handler
- ;++++++++++++++++++++++++++++++++
- ;
- org 066h ; NMI location
- ;
- xra a
- out 046h ; Turn OFF the memory
- ; Stop any IORAM boards
- out 04eh ; Clear control port to ioram
-
- hlt ; HALT the processor
- ;
- ;++++++++++++++++++++++++++++++++
- ; ---- Interrupt drivers ----
- ;++++++++++++++++++++++++++++++++
- ;
- int$ctc0:
- int$ctc1:
- ei
- reti
- ;
- ;----------------------------------------------------------------
- ; ---- Real time clock ----
- ;
- ; Port 30h will tell of the clock interrupt that occured and
- ; reset the source of interrupts.
- ;----------------------------------------------------------------
- ;
- int$ctc3:
- push psw
- in 030h ; Read clock int. status to reset interrupt
- mvi a,'K' ; Indicate a clock output
- call coe
- pop psw
- ei
- reti
- ;
- ;----------------------------------------------------------------
- ; This is the 1ms periodic interrupt handler. It will decrement the
- ; prescaler till it hits ZERO then reload, decrement the bell timer
- ; and then when this hits 0, turn OFF the buzzer. This is good for
- ; implimenting an interrupt driven buzzer.
- ;----------------------------------------------------------------
- ;
- int$ctc2:
- push psw
- ;
- lda prescale
- dcr a
- sta prescale
- jnz skip$int2
- ; At 0. Reload the prescaler
- mvi a,10
- sta prescale
- ;
- ; Save other used registers
- push h
- ; See if the bell counter is greater than 0.
- lhld bel$cnt
- mov a,l
- ora h
- jz end$int2 ; Exit if < 1. Dead now.
- ;
- ; Greater than 0. Hmm.
- dcx h
- shld bel$cnt
- mov a,l
- ora h ; Hit 0 now ????
- jnz end$int2 ; Non zero and skip
- ; Stop the bell
- xra a
- out @buz ; Turns off bell
- ;
- ;
- end$int2:
- pop h
- skip$int2:
- pop psw
- ei
- reti
- ;
- ;
- ;****************************************************************
- ;* Start of the main program here *
- ;* Setups and initializations *
- ;****************************************************************
- ;
- start$mon:
- lxi sp,stack
- ;
- mvi a,080h ; Port C outputs, A&B outputs
- out 047h
- mvi a,040h
- out 046h
- ;
- ; Initialize EXEC System
- mvi c,0
- rst 1
- ;
- ; Setup interrupts on the CTC
- ; Load vector
- ; Load down counter
- ;
- di
- xra a
- sta int$cnt ; Clear an interrupt counter
- ;
- lxi h,int$tbl ; HL -> interrupt vectors
- mov a,l
- out @ctc0 ; Bit 0 = 0 means a vector
- ;
- mov a,h ; Get high table address
- stai
- ;
- ; Clear the interrupt out line from the clock.
- ;
- xra a
- out 31h ; Stop interrupts from the clock
- in 30h ; Clear any pending.
- sta dump$lst
- sta dump$lst + 1
- ;
- ; Select a 1 count on the CTC from the clock. Any other count will hang
- ; because the interrupt out line is only cleared when the 30h port is read.
- ;
- mvi a,0D5h ; Counter mode, interrupts, tc follows
- out @ctc3
- ;
- mvi a,1 ; Trigger on a 1 count.
- out @ctc3 ; Last CTC
- ;
- in 030h ; Clear any interrupt pending again.
- ;
- ; Setup a periodic interrupt for CTC 2
- ;
- mvi a,085h ; Interrupt enable, Timer, 16 prescale
- out @ctc2
- mvi a,0fdh ; This gives accurate 1khz interrupt
- out @ctc2
- mvi a,10
- sta prescale
- ;
- im2 ; Interrupt mode 2
- ei
- ;
- ;+--------------------------------+
- ;| Actual monitor start |
- ;+--------------------------------+
- ;
- amon: ; Start off
- ;
- lda pgm$base
- cpi 0ffh
- jnz pgm$base ; Run any program at 2000h.
- ;
- amon1:
- lxi d,signon ; Go print the message
- call ptxt
- ;
- ; Warm1 is the restart address after all routines are finished.
- ;
- warm:
- Lxi sp,stack ; Re-set the stack
- lxi d,signon2
- call ptxt ; Print the M> message
- call echo ; Get character and echo it
- ;
- cpi cr
- jrz warm
- cpi lf
- jrz warm
- cpi ' '
- jrz warm
- cpi '@'
- jz code$load
- ;
-
- cpi esc
- jrz warm
- mov c,a
- push b ; Save character
- call space ; Space across 1
- call gaddr ; Get operands
- pop b
- mov a,c ; Restore first command
- lxi h,warm ; Save address of re-entry
- push h ; On stack
- lded opr1 ; Operand 1
- lxiy stcktop ; Set iy to stack top
- ;
- ;****************************************************************
- ;* Check key against table *
- ;****************************************************************
- ;
- if ilhlp ; If help is allowed, check for it
- cpi '?'
- jz help
- endif
- ;
- sui 'A'
- jrc erdisp ; Incorrect command
- cpi 'Z'-'A'+1 ; Only A to Z allowed.
- jrnc erdisp
- add a ; *2
- push d ; Save it
- mov e,a
- mvi d,0 ; Index into table
- lxi h,jmptbl ; Table of routines
- dad d ; Point to it
- mov e,m
- inx h
- mov d,m
- xchg
- pop d ; Restore
- push h ; Load stack with routine address
- lhld opr2
- ret ; To the routine
- ;
- code$load:
- call ext$ldr
- jmp warm
- ;
- ;****************************************************************
- ;* Display a ? for an error prompt *
- ;****************************************************************
- ;
- erdisp:
- mvi a,'?' ; ? = illegal data
- call coe
- jmp warm ; Re-enter monitor
- ;
- ;*******************************************************
- ; Inline help screen. Pressing a '?' displays this lot *
- ;*******************************************************
- ;
- help:
- if ilhlp
- ;
- lxi d,help$text
- call ptxt
- jmp warm
- help$text:
- db 0dh,0ah,'A = Ascii Dump of memory A 5000<cr>'
- db 0dh,0ah,'D = Display memory D 5000<cr>'
- db 0dh,0ah,'E = Examine memory E 5000<cr>'
- db 0dh,0ah,'F = Fill memory F 5000 5010 FF<cr>'
- db 0dh,0ah,'G = Goto and execute memory G 100<cr>'
- db 0dh,0ah,'H = Hex sum and difference H 4000 5000<cr>'
- db 0dh,0ah,'I = Input from a port I 68<cr>'
- db 0dh,0ah,'I = Multiple input from a port I 88 n<cr>'
- db 0dh,0ah,'K = Read clock K<cr>'
- db 0dh,0ah,'K y m d w m h s Set Clock'
- db 0dh,0ah,'L = Locate a string of bytes L 0 100 1 2 3 4 5<cr>'
- db 0dh,0ah,'M = Move memory M 5000 5010 6000<cr>'
- db 0dh,0ah,'O = Output to a port O 88 55<cr>'
- db 0dh,0ah,'O = Multiple port output O 88 55 n<cr>'
- db 0dh,0ah,'P = Examine a port P 88<cr>'
- db 0dh,0ah,'P = Port map P ^<cr>'
- db 0dh,0ah,'Q = Quit this program Q<cr>'
- db 0dh,0ah,'S = Substitute memory S 5000<cr>'
- db 0dh,0ah,'T = Test memory T 5000 6000<cr>'
- db 0dh,0ah,'U = Write console to ram U 5000<cr>...^Z'
- db 0dh,0ah,'V = Verify memory V 4000 5000 5001<cr>'
- db 03
- endif
- ret
- ;
- ;****************************************************************
- ; Display memory as if it were a page of text. Hex data is not *
- ; displayed, it is converted into a '.' to be comaptible with *
- ; the dump command. *
- ;****************************************************************
- ;
- adump:
- lda opcnt
- ora a
- jz erdisp ; No operands cause an error
- cpi 1 ; 1 operand gives a screen full
- jrz scrnful
- ; Display from start to a finish. Start is in de, finish in hl
- call rngchk ; Check end is after the start
- lhld opr2 ; Re-load ending address if ok.
- adump1:
- push h ; Save ending address
- ldax d ; Get the character
- call makasc ; make it ascii into C
- call coe
- inx d ; Bump memory source address
- ora a ; Clear carry
- dsbc d ; Subtract current address from end
- pop h ; Restore the ending address
- jrnz adump1 ; When equal, next page is asked for
- ;
- ; Here we read the console for an escape or a space
- adwait: ; Wait for a legitimate ascii dump command
- call cie
- cpi esc
- jz warm
- cpi ' ' ; next K ?
- jrz adump2
- cpi '^' ; Previous K ?
- jrz adump3
- cpi '?' ; Do you want to know the address ??
- jrnz adwait ; If not this then keep on waiting
- call prhl ; Print the current ending address
- jr adwait ; Wait on Norelle, all things come....
- ;
- adump2: ; Add the standard screen display amount to the end address
- lxi b,1024 ; Dsiplay the next 1k
- dad b ; End address is now 1k on
- call crlf
- jr adump1
- ;
- adump3: ; Display the previous k to the one on the screen
- ora a ; Clear carry
- lxi b,2048 ; A sort of double back up is required
- dsbc b ; HL & DE point to 2 k back
- push h
- pop d ; Copy end into start
- jr adump2 ; Load the new end address
- ;
- ; Here the user entered only one operand so he wants a standard screenfull
- scrnful:
- push d
- pop h ; Copy start address into end
- jr adump2
- ;
- ;****************************************************************
- ; Execute a program at an optional address *
- ;****************************************************************
- ;
- go: lda opcnt ; See if operands entered
- ana a
- jrz go1 ; Use last given address
- sded temp8
- go1:
- lhld temp8
- pchl ; Start execution at the address
- ;
- ;****************************************************************
- ;* Block move memory routine *
- ;****************************************************************
- ;
- move: call rngchk ; See that end > start
- mov b,h
- mov c,l ; Bc = count of bytes
- xchg
- lded opr3 ; Get destination
- ora a
- dsbc d ; Check no everlay
- jrnc move2 ; Skip if likely
- lhld opr3 ; Get back dest
- dad b ; Add to byte count
- dcx h ; Less 1
- mov d,h
- mov e,l ; Copy to de
- lhld opr2 ; Get end
- lddr ; Fill backwards
- ret
- ;
- move2: lhld opr1 ; Forward block move
- ldir
- move1: ret
- ;
- ;****************************************************************
- ;* This is the hexadecimal calculator *
- ;****************************************************************
- ;
- hexad:
- push h
- dad d ; Add opr1 and opr2
- mvi a,'+' ; Display sum
- call coe
- call prhl ; Display contents hl
- call space ; Space
- pop h ; Restore opr2
- xchg ; Swap opr1 and opr2
- ora a ; Clear flags
- dsbc d ; Subtract other way
- mvi a,'-'
- call coe ; Display difference
- jmp prhl
- ;
- ;****************************************************************
- ;* Exam port contents *
- ;* cmd => i pp (x) where x means forever *
- ;****************************************************************
- ;
- portin:
- ;****************************************************************
- ;* Exam port contents *
- ;* cmd => i pp (x) where x means forever *
- ;****************************************************************
- ;
- portin:
- ; Get the port number into C
- lda opr1
- mov c,a ; Save port number
- ;
- mvi b,0 ; Upper low to read internal/external
- inp a ; Read port
- cma
- mov e,a ; Ensure impossible value in E 1st time
- mvi d,0 ; Load count before a CR,LF
- ;
- lxi h,1 ; Default count into HL
- lda opcnt ; How many operands
- ; Specified opcode count ?
- cpi 2 ; 2 ?
- jrc porti1 ; Skip if less
- lhld opr2 ; Get operand 2 (no.Displays)
- ;
- ; First time round we need a heading
- porti1:
- call crlf
- mov a,c
- call phacc ; Display port no.+ space
- call space
- mvi a,'-'
- call coe
- ;
- ;----------------------------------------------------------------
- ; Port input loop. Wait for a port change then display it. If
- ; decremented number of displays required = 0 then exit.
- ;
- ; -- Use registers as --
- ; HL = count of items printed total
- ; D = count of items printed on a line 0..7
- ; E = the previous port image
- ; C = port number
- ;----------------------------------------------------------------
- ;
- portin$loop:
- call clrwdt ; Clear watchdog
- mvi b,0
- inp a
- ;
- cmp e
- jrz porti3
- ;
- ; Else if not equal, display the new value
- ;
- mov e,a ; Save new value port image
- call space
- mov a,e
- call phacc ; Go display value
- inr d ; One more displayed
- mov a,d
- cpi 8
- jrnz porti2
- ; End of line, cr/lf and port address
- mvi d,0
- call crlf
- mov a,c ; Port number
- call phacc ; Display port no.+ space
- call space
- mvi a,'-'
- call coe
- ;
- ; Decrement the HL count and if 0 then exit.
- porti2:
- dcx h
- mov a,l
- ora h ; Does H = L = 0 ????
- rz ; Exit if end
- ;
- ; If port is same as previous image then come to this routine
- ; and check for an escape key.
- ;
- porti3:
- call cst
- jrz portin$loop
- call cie
- cpi esc
- jrnz portin$loop
- ret
- ;
- ;****************************************************************
- ;* Output a value to a port *
- ;* cmd => o pp (xx) (yy) *
- ;* xx= data yy = optional count, 0 = forever *
- ;****************************************************************
- ;
- portout:
- lda opr2 ; Get data
- mov d,a ; Into d
- ;
- lxi b,1 ; Default count = 1
- lda opcnt ; See how many operands
- cpi 3
- jrc pout1 ; Skip if < 3
- lbcd opr3 ; Get loop count
- pout1:
- push b
- lda opr1 ; Get port no.
- mov c,a ; To c
- outp d ; Send data in D to port in A
- pop b
- call chkabrt ; See if abort wanted
- dcx b
- mov a,c
- ora b
- jrnz pout1 ; Counter - 1
- ret
- ;
- ;****************************************************************
- ;* Fill memory with data *
- ;* cmd => f ssss ffff dd *
- ;****************************************************************
- ;
- fill: lda opr3 ; Get data to fill with
- push h ; Save hl
- call rngchk ; Check de < hl
- pop h
- fill1: stax d ; Save data
- push h
- ora a ; Clear flags leave acc.
- dsbc d ; See if address match
- pop h ; Restore end address
- inx d ; Next location
- jrnz fill1 ; Skip if no match
- ret
- ;
- ;****************************************************************
- ;* Locate a string in memory *
- ;* cmd => l ssss ffff b1 b2 b3... B5 *
- ;****************************************************************
- ;
- locat:
- call rngchk ; Make sure end > start
- lda opcnt ; How many operands
- sui 3 ; Subtract 3
- jc erdisp ; Error 3 minimum
- mov b,a ; Save difference
- inr a ; Add 1
- sta opcnt ; Save operand count
- lxi h,opr4-1
- lxi d,opr4
- locat1: ldax d ; Get data
- mov m,a ; Save it
- inx h ; Next location
- inx d
- inx d
- djnz locat1 ; Loop till all operands crushed
- locat2: lda opcnt
- mov b,a ; Save opcount
- lhld opr1 ; Get start address
- lxi d,opr3
- locat3: ldax d ; Get operand
- cmp m ; Compare to memory
- jrnz locat4 ; Skip if no match
- inx h ; Next memory location
- inx d ; Next operand
- djnz locat3 ; Opcount - 1
- lhld opr1
- call prhl ; Memory address
- call crlf ; New line
- call chkabrt ; See if abort wanted
- locat4: lhld opr2 ; Get end address
- lded opr1 ; Get start address
- ora a
- dsbc d ; Compare them
- rz ; If same, exit
- inx d ; Next location
- sded opr1 ; Update start address
- jr locat2 ; Loop around
- ;
- ;****************************************************************
- ;* Verify 2 blocks of memory *
- ;* cmd => v ssss ffff ssss *
- ;****************************************************************
- ;
- verify:
- call rngchk ; Check start and end address
- push h ; Save difference
- pop b ; Count into bc
- xchg ; Swap start and end
- lded opr3 ; Get destination block
- verif1: ldax d ; Byte from dest
- cci ; Block compare with increment
- inx d ; Next locat for test
- jrnz verif2 ; If no match skip
- rpo ; End of compare, exit
- jr verif1 ; Loop
- ;
- verif2: push psw ; No match
- push b
- push d ; Save all regs
- dcx h ; Go back one location
- call prhl ; Display pointer
- mov a,m ; Get contents
- inx h ; Increment pointer
- call pracc ; Print value
- pop d
- push d
- push h
- xchg ; Get dest block
- dcx h ; Back one
- call prhl ; Print pointer
- mov a,m ; Get data
- call phacc ; Display it also
- call crlf ; New line
- pop h
- pop d
- pop b
- pop psw ; Restore regs
- rpo
- call chkabrt ; Test for abort key
- jr verif1 ; Then loop
- ;
- ;****************************************************************
- ;* Test memory for errors *
- ;* cmd => t ssss ffff *
- ;****************************************************************
- ;
- mtest:
- xchg ; Swap start and end
- inx d ; De = start+1
- mvi b,0 ; Count = 256
- mtest1: lhld opr1 ; Get start address
- mtest2: mov a,l
- xra h ; Compare to h
- xra b ; Then count
- mov m,a ; Save in memory (auto change)
- inx h ; Next location
- push h ; Save pointer
- ora a ; Clear flags
- dsbc d ; Start - dest
- pop h ; Restore pointer
- jnz mtest2 ; Loop if not finished
- ;
- call clrwdt
- call clrwdt
- lhld opr1 ; Get back start address
- mtest3:
- mov a,l
- out @wdt
- xra h
- xra b ; Reconstruct data to test
- cmp m
- cnz mtest4 ; If no match, display error
- inx h ; Next loc
- push h ; Save it
- ora a
- dsbc d ; See if end of test
- pop h
- jnz mtest3 ; Skip if not
- inr b ; Bit count done
- call chkabrt ; See if abort wanted
- mvi a,'P' ; Indicate 1 pass
- call coe
- call clrwdt
- call clrwdt
- jr mtest1 ; Loop to restart
- ;
- mtest4: push psw ; Save test byte
- call clrwdt
- call prhl ; Print address
- pop psw
- call pracc ; Print test byte
- mov a,m ; Get invalid data
- call pracc ; Print it also
- jmp crlf ; Display crlf, then return
- ;
- ;****************************************************************
- ;* Dump memory contents *
- ;* cmd => d ssss *
- ;****************************************************************
- ;
- dump:
- lda opcnt ; Get count
- ora a
- jrz dump$again ; Dump from previous use address
- ;
- cpi 1 ; See if < 2
- jnz erdisp ; One operand = start address ONLY
- lded opr1 ; Get the start address
- sded dump$lst ; Save dump start address for next time
- dump$again:
- lded dump$lst
- ;
- ; 16 lines to dispplay
- dsp$mem:
- call crlf
- mvi b,16 ; Lines to display
- dsp$mem$loop:
- call dsp$line
- call crlf
- djnz dsp$mem$loop
- ;
- call cie
- cpi 01bh
- rz
- cpi cr
- jrz dsp$mem ; Display the next page a CR
- cpi ' '
- jrz dsp$mem ; Display next page if a space
- cpi lf
- jrz dsp$mem ; Next page if a lf
- cpi '+'
- jrz next$k
- cpi '-'
- jrz lst$k
- ret
- ;
- next$k:
- lxi h,1024 ; 1k
- dad d
- xchg
- jr dsp$mem
- ;
- lst$k:
- xchg
- lxi d,1024
- ora a
- dsbc d
- xchg
- jr dsp$mem
- ;
- ;------------------------------------
- ; ---- Display a line of memory ----
- ;------------------------------------
- ;
- dsp$line:
- push b ; Save external counters
- ; Now the address from DE
- call phde ; Print as hex
- call space
- ;
- push d ; Save the address also
- mvi b,16 ; 16 bytes
- dl1:
- ldax d
- inx d
- call phacc ; Print as hex
- inx h
- call space ; Separator
- ; Middle ?
- mov a,b
- cpi 9
- jnz dl11
- mvi a,'-'
- call coe
- call space
- dl11:
- call clrwdt ; Stop the dog
- djnz dl1
- ;
- call space2
- pop d ; Restore the memory address
- mvi b,16
- dl2:
- ldax d
- inx d
- call makasc
- call coe
- call clrwdt
- djnz dl2
- ;
- pop b ; Restore counters
- ret
- ;
- ;****************************************************************
- ;* Examine / alter memory locations *
- ;* cmd => e llll (xx) *
- ;****************************************************************
- ;
- exmem:
- xchg ; Hl gets start
- exmem1: call prhl ; Display pointer
- mov a,m ; Get byte
- call phacc ; Print hex value
- mvi a,'-'
- call coe ; Then marker
- push h
- call gaddr ; Get data from user
- pop h
- lda opcnt ; Get bytes entered
- ani 3
- jrz exmem3 ; If none, skip
- lda opr1 ; Get data
- mov m,a ; Copy to memory
- inx h ; Next location
- lda lastchr
- cpi 00dh ; Was it a carriage ret ?
- jrz exmem1 ; Skip if so
- exmem2: dcx h ; Restore pointer
- jr exmem1 ; Loop
- ;
- exmem3: lda lastchr ; Get back last char
- cpi '^' ; Was it an up-carrot
- jrz exmem2 ; If so, stay on this location
- inx h ; Else next location
- jr exmem1 ; Loop around
- ;
- ;****************************************************************
- ;* Port examine / modify command *
- ;* cmd => p pp *
- ;****************************************************************
- ;
- port: ; See if display whole port space
- lda lastchr ; Get the character
- cpi '^' ; Carrot causes whole page
- jrz pmap
- cpi '&'
- jrnz porta
- ; Do a repeated port map display with cursor positioning. An escape ends it.
- cport:
- mvi a,cscrn ; Erase screen code
- call coe
- cport1:
- ; DO a cursor position to line 5 column 1
- mvi a,cpos1 ; First cursor position code
- call coe
- mvi a,cpos2 ; Second cursor position code
- call coe
- mvi a,3+offset ; Row + offset first
- call coe
- mvi a,1+offset ; Column next
- call coe
- call pmap ; Display the port map
- jr cport1
- ;
- pmap:
- ; This section causes the whole port address space to be displayed
- mvi e,16 ; Number of 16 port lines
- mvi c,00 ; Start at port 00
- pm1:
- mvi b,16 ; 16 ports per line displayed
- mov l,c ; Get start port #
- mvi h,00
- push b
- call crlf ; Space apart
- call prhl2 ; Print port #
- pop b
- pm2:
- inp a ; Get the port from (c)
- push b ; Save the counters
- call pracc ; Print a port & a space
- call prsep ; Check if we need a line separator
- call chkabrt ; Detect if we need to quit-a-motto
- pop b
- inr c ; Next port next time
- djnz pm2
- ; Detect if all lines have been sent to screen ( = all ports done)
- dcr e ; Decrement line counter
- mov a,e
- ora a ; End of the lines ?
- jrnz pm1
- ret
- ;
- porta:
- lda opr1 ; Get port no
- mov c,a ; Into c
- port1: mov a,c ; Get back port no
- call pracc ; Display it
- inp a ; Get contents
- call pracc ; Print also
- push b
- call gaddr ; See if data to be altered
- pop b
- lda lastchr ; Get character entered
- mov h,a
- lda opcnt ; Get opcount
- ana a
- jrz port3 ; If none, skip
- lda opr1
- outp a ; Send data out
- mvi a,'^' ; Test for carrot
- cmp h
- jrz port1 ; Skip if so
- port2: inr c ; Next port number
- jr port1 ; Loop
- ;
- port3: mvi a,'^'
- cmp h
- jrnz port2 ; Skip if not carrot
- dcr c ; Port no.- 1
- jr port1
- ;
- ;****************************************************************
- ;
- ; Quit the monitor *
- ; *
- ;****************************************************************
- ;
- quit:
- lhld usr$stk
- sphl
- ret
- ;
- ;****************************************************************
- ; Enter a string into memory at opr1 till an escape. *
- ;****************************************************************
- ;
- string:
- lda opcnt
- cpi 1
- jnz warm ; Only one operand allowed
- xchg ; Put the destination address in hl
- ; Do a crlf then enter text till a control Z
- lxi d,00 ; Set up a character counter
- string1:
- call cie ; Get a character
- cpi 01ah ; Control Z
- jrz string2 ; End of the command.
- cpi esc
- cnz coe ; No echo of control codes.
- mov m,a ; Put into memory
- inx h
- inx d ; Bump pointers
- jr string1
- string2: ; Here when the user has had enough and entered a control Z
- call crlf
- xchg ; Put character counter into hl
- mvi a,'>'
- call coe
- call prhl ; Print the number of characters
- jmp warm ; Process next command
- ;
- ;****************************************************************
- ;* Clock routines to set and clear the clock registers *
- ;****************************************************************
- ;
- clock:
- lxi h,?time ; Clock string
- lda opcnt
- ora a ; See if set/display
- jrz readit
- ;
- writit:
- cpi 6 ; Should be 7 operands (0-6)
- jc erdisp ; Error not enough
- lda opr1
- sta kdom ; Day of month
- lda opr2
- sta kmth ; Month number
- lda opr3
- sta kyrs ; Year number
- lda opr4
- sta kdow ; Day of week
- ;
- lda opr5
- sta khrs ; Hours
- lda opr6
- sta kmin ; Minutes
- lda opr7
- sta ksec ; Seconds
- lxi d,?time
- jmp clkwr ; Go write clock from ?time
- ;
- readit:
- lxi d,?time
- call clkrd ; Go read clock string
- call crlf ; Select next line
- ; Dat in format dd/mm/yy
- lda kdom ; Day of month
- call phacc ; Print date
- mvi a,'/'
- call coe
- lda kmth ; Month
- call phacc
- mvi a,'/'
- call coe
- lda kyrs
- call phacc
- mvi a,' '
- call coe
- call coe
- ; Now time in format hh:mm:ss
- lda khrs ; Seconds
- call phacc
- mvi a,':'
- call coe
- lda kmin
- call phacc
- mvi a,':'
- call coe
- lda ksec
- call phacc
- jmp crlf
- ;
- ;
- chkabrt: ; Detect if the user wanted to quit or not
- call cst ; See if abort pressed
- rz ; Return if no character pending
- call cie ; Get the character, conin handles esc
- cpi esc
- jz warm
- cpi '.'
- jz warm
- ret
- ;
- ;****************************************************************
- ;* See if de less than hl *
- ;****************************************************************
- ;
- rngchk:
- ora a ; Clear flags
- dsbc d
- jc erdisp
- inx h
- ret
- ;
- pracc:
- call phacc
- jmp space
- ;
- ;
- makhex:
- sui '0' ; Remove ascii bias
- cpi 10 ; If 0 - 9, return
- rm
- sui 7 ; Else make a - f = 10 - 15
- ret
- ;
- valnum:
- cpi '0'
- jrc valbad ; Check = '0' - '9'
- cpi '9'+1
- jrc valnok
- cpi 'A'-1 ; Check = 'A' - 'F'
- jrc valbad
- cpi 'G'
- jrnc valbad
- valnok:
- xra a ; Set zero flag for good exit
- ret
- ;
- valbad:
- xra a ; Set acc = 1
- inr a
- ret
- ;
- ;****************************************************************
- ;* Checks for end of numeric entry *
- ;****************************************************************
- ;
- valdm: cpi ' ' ; valid delim
- rz
- cpi '^' ; Alternate code for cr (*)
- jrz valdm1
- cpi '&' ; This is allowed for cont' commands
- jrz valdm1
- cpi cr ; End of command
- rnz ; Exit if not a one of these
- ;
- valdm1:
- call crlf ; Issue a carriage return
- xra a ; Set zero flag = valid delim
- ret
- ;
- ghex:
- lxi h,00
- mov b,l
- ghex1:
- call echo
- inr b
- call valdm
- rz
- call valnum
- rnz
- mov a,c
- call makhex
- dad h
- dad h
- dad h
- dad h
- add l ; add in lower digit
- mov l,a ; put back in
- jr ghex1
- ;
- echo: call cie
- ani 07fh
- cpi 'a' ; Ensure in upper case
- jrc noconv
- cpi 'z'+1
- jrnc noconv
- ani 05fh
- noconv:
- mov c,a ; save
- cpi esc
- jnz coe
- ret
- ;
- ;****************************************************************
- ;* Collect up to 9 bytes of numeric data *
- ;* separated by spaces if entered *
- ;****************************************************************
- ;
- gaddr:
- xra a
- lxi h,opr1
- push h
- popix
- mov m,a
- lxi b,13
- lxi d,opr1+1
- ldir ; Clear 13 bytes of ram
- sta opcnt
- ;
- ;
- gaddr1:
- call ghex
- jnz erdisp
- mov a,c
- sta lastchr
- cpi ' '
- jrz gaddr2
- dcr b
- rz
- ;
- ;
- gaddr2:
- stx l,000h
- stx h,001h
- lda opcnt
- inr a
- sta opcnt
- inxix
- inxix
- mov a,c
- cpi ' '
- jrz gaddr1
- ret
- ;
- prhl:
- mov a,h
- call phacc
- mov a,l
- jmp pracc
- ;
- prhl2: ; Print contents of hl and also extra spaces
- call prhl
- jr prsep2 ; Send an additional space
- ;
- prsep: ; If b = 8 then print a '- ' else return
- mov a,b
- cpi 9 ; Already done 8 characters ??
- rnz ; Return if not at exact match
- mvi a,'-'
- call coe
- prsep2:
- jmp space ; Print a space
- ;
- ;****************************************************************
- ;* Printer output routine *
- ;****************************************************************
- ;
- poe:
- ret
- ;
- ;
- ; Small I/O Deiver interfaces
- ;
- phde:
- push b
- mvi c,19 ; HEX DE Print code
- rst 1
- pop b
- ret
- ;
- pdde:
- push b
- mvi c,20 ; Decimal DE Print code
- rst 1
- pop b
- ret
- ;
- phacc:
- push b
- mvi c,17 ; HEX Psw Print code
- rst 1
- pop b
- ret
- ;
- ptxt:
- ldax d
- ora a
- rz
- cpi '$'
- rz
- call coe
- inx d
- jr ptxt
- ;
- ;
- bell:
- mvi a,7
- jmp coe
- ;
- space2:
- call space
- space:
- mvi a,' '
- jmp coe
- ;
- crlf:
- mvi a,cr
- call coe
- mvi a,lf
- jmp coe
- ;
- caps:
- push b
- mvi c,55 ; CAPS code
- rst 1
- pop b
- ret
- ;
- ClrWdt:
- push b
- push psw
- mvi c,40 ; Watchdog clear
- rst 1
- pop psw
- pop b
- ret
- ;
- makasc:
- ani 07fh ; Make in the range
- cpi 020h ; Lower than a space is illegal
- jrc noasc ; Not ascii
- cpi 07bh ; Higher than upper case is illegal too
- rc ; return with ascii character in C
- noasc: mvi A,02eh ; Replace with a '.'
- ret
- ;
- coe:
- jmp con$out
- cie:
- jmp con$inp
- cst:
- jmp con$ist
- ;
- clkrd:
- push b
- mvi c,get$clk
- rst 1
- pop b
- ret
- ;
- ;
- ;
- clkwr: ; Real time clock routines
- push b
- mvi c,put$clk
- rst 1
- pop b
- ret
- ;
- ;************************************************
- ;* Table of routines for indirect jump *
- ;************************************************
- ;
- jmptbl:
- dw adump ; A Ascii display of memory
- dw erdisp ; B
- dw erdisp ; C
- dw dump ; D display memory
- dw exmem ; E examine memory
- dw fill ; F fill memory
- dw go ; G go to program
- dw hexad ; H hex sum and difference
- dw portin ; I input from port
- dw erdisp ; J
- dw clock ; K read/write clock
- dw locat ; L locate string
- dw move ; M move memory
- dw erdisp ; N
- dw portout ; O output to a port
- dw port ; P examine port
- dw quit ; Q quit this monitor
- dw erdisp ; R
- dw exmem ; S Substitute memory duplicate
- dw mtest ; T test ram
- dw string ; U Use console for writing to ram
- dw verify ; V verify ram
- dw erdisp ; W
- dw erdisp ; X
- dw erdisp ; Y
- dw erdisp ; Z
- ;
- signon:
- db cr,lf
- signon1:
- db 'ExecMon - CORE BOARD Monitor With EXEC Processor 25/10/88'
- db cr,lf,0
- signon2:
- db cr,lf
- db 'M>'
- db 0
- ;
- dseg
- ;
- prescale:
- ds 1 ; 1mS interrupt prescaler
- ;
- ;
- ds 128
- stack:
-
- ds 10
- stcktop
- ds 10
- ;
- dump$lst ds 2
- ;
- int$cnt db 00,00 ; Interrupt counter
- opcnt db 00
- lastchr db 00
- opr1 db 00,00
- opr2 db 00,00
- opr3 db 00,00
- opr4 db 00,00
- opr5 db 00,00
- opr6 db 00,00
- opr7 db 00,00
- temp2 db 00,00
- temp6 db 00,00
- temp8 db 00,00
- ?time:
- ksec: db 00 ; Seconds
- kmin: db 00 ; Minutes
- khrs: db 00 ; Hours
- kdow: db 00 ; Day of week
- kdom: db 00 ; Day of month
- kmth: db 00 ; Month number
- kyrs: db 00 ; Years
- ;
- usr$stk db 00,00
- ;
- end
-
-
- ;