title 'Core Board Monitor' ; ;**************************************************************** ; ; 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 11-08-87 ;**************************************************************** ; name 'cmon' public cmon extrn init,ini$led extrn coe,cie,cst extrn clkrd,clkwr ; Real time clock routines extrn crlf,phacc,space,ptxt,space2 extrn makasc,delay,bell extrn caps,pdde,phde,clrwdt ; ; A-D equates ; extrn ini$ad,rd$ad,scan$ad ; ; LCD Equates ; extrn ini$lcd,hom$lcd,cur$lcd extrn put$lcd,str$lcd extrn pmu$lcd,clr$lcd extrn eol$lcd,xyi$lcd ; ; ioram board code for reading and writing to mass memory i/o driven boards ; extrn in$ioram,rd$ioram,wr$ioram public cur$dma,cur$sec ; public ?time ; Base of time parameter table public ksec,kmin,khrs public kdow,kdom,kmth public kyrs ; extrn ext$ldr ; maclib z80 maclib core ; ; ilhlp equ false ; Inline help ; cpos1 equ 01bh ; Cursor positioning lead in code cpos2 equ '=' offset equ 020h ; Offset for vdu cursor positioioning cscrn equ 01ah ; Clear screen code ; ;++++++++++++++++++++++++++++++++ ; ; Start of program ; ;++++++++++++++++++++++++++++++++ ; cmon: jmp start$mon ; Leap over interrupt table ; ; Restart 1 address. org 8 ret ; 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 ; simpply increments the value written to a port. ;------------------------------------------------ ; int$ctc2: push psw lda int$cnt inr a sta int$cnt out @gp1a ; Send to a data port ; 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 call init call ini$led ; Initialize led drivers ; ; Initialize any LCD and ioram boards here ; call in$ioram call ini$lcd ; Initialize LCD lxi d,20 call delay call clrwdt lxi d,signon1 ; -> text to lcd print call str$lcd ; Print string to LCD ; ; Setup the interrupt output 8255 for all outputs ; mvi a,080h out @gp1md ; ; 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 ; im2 ; Interrupt mode 2 ei ; ;+--------------------------------+ ;| Actual monitor start | ;+--------------------------------+ ; amon: ; Start off 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 ; ;---------------------------------------------------------------- ; Simulate a little Dinos' interaction ;---------------------------------------------------------------- ; dinos: call clr$lcd ; Clear the lcd and home cursor lxi d,din$msg call pmu$lcd ; Print the LCD message ; dinos$new: lxi d,din$prompt call pmu$lcd ; Print the prompt call eol$lcd ; Clear to end of line ; ; Fetch characters from the console till ESC to end or CR for again. ; mvi b,0 ; No Characters entered lxi h,din$buf ; -> dinos character buffer ; dinos$loop: call cie ; Fetch a byte cpi esc jz dinos$end cpi 'X' and 01fh jz dinos$erase ; cpi cr jz dinos$next ; cpi lf jz dinos$next ; cpi 08 ; Backspace ? jnz dinos$save ; If not, save the character ; ; It is a backspace, check for the start of the line and if so ; ignore the attempt. It not, then do the backspace. ; mov a,b ora a jz dinos$loop ; ; Not end of input. We can erase something. dcr b dcx h ; Decrement character buffer pointer ; ; mvi a,8 ; Re-load the backspace call put$lcd mvi a,' ' call put$lcd mvi a,8 call put$lcd jmp dinos$loop ; dinos$erase: call bell jmp dinos$new ; dinos$save: mov c,a ; Save char here mov a,b ; Check for end of line/over run cpi 9 ; All characters done ? jrnz dinos$save$ok ; End of buffer. call bell jmp dinos$loop ; dinos$save$ok mov a,c ; Get the char back mov m,a ; Save to buffer call put$lcd ; Send to the LCD inx h ; Save character inr b jmp dinos$loop ; ; ---- Process another caller ---- ; dinos$next: mov a,b ora a ; Test for no input entered jz dinos$new ; lxi d,3 ; Bottom line call cur$lcd call eol$lcd ; Clear the bottom line call xyi$lcd db 05,03,'Thank You For Calling : ',0 ; lxi h,din$buf dinos$next$loop: mov a,m call put$lcd inx h djnz dinos$next$loop ; lxi d,2000 call delay jmp dinos$new ; dinos$end: call clr$lcd lxi d,bye$din call pmu$lcd ret ; ; ; ---- Messages ---- ; ; 1 2 3 4 ; din$msg: db 00,00,'---- Dial-A-Dinos Pizza Order Taker ----',0 db 00,01,' By SME Systems P/L Ph. 874-3666 ',0 db 00,02,' 22 Queen Street Mitcham Vic. ',0 din$prompt: db 00,03,'Enter Customer Telephone No. :',0 db 0ffh ; ; 01234567890123456789012345678901234567890' bye$din: db 00,00,'---- LCD / Dinos Demonstration Over ----',0 db 00,01,' Written by Richard Holmes',0 db 00,02,' For SME Systems P/L',0 db 00,03,' 11/08/1987',0 db 0ffh ; ;******************************************************* ; 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' db 0dh,0ah,'D = Display memory D 5000' db 0dh,0ah,'E = Examine memory E 5000' db 0dh,0ah,'F = Fill memory F 5000 5010 FF' db 0dh,0ah,'G = Goto and execute memory G 100' db 0dh,0ah,'H = Hex sum and difference H 4000 5000' db 0dh,0ah,'I = Input from a port I 68' db 0dh,0ah,'I = Multiple input from a port I 88 n' db 0dh,0ah,'K = Read clock K' 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' db 0dh,0ah,'M = Move memory M 5000 5010 6000' db 0dh,0ah,'O = Output to a port O 88 55' db 0dh,0ah,'O = Multiple port output O 88 55 n' db 0dh,0ah,'P = Examine a port P 88' db 0dh,0ah,'P = Port map P ^' db 0dh,0ah,'Q = Quit this program Q' db 0dh,0ah,'S = Substitute memory S 5000' db 0dh,0ah,'T = Test memory T 5000 6000' db 0dh,0ah,'U = Write console to ram U 5000...^Z' db 0dh,0ah,'V = Verify memory V 4000 5000 5001' 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: lxi b,1 ; Default count lda opcnt ; How many operands cpi 2 ; 2 ? jrc porti1 ; Skip if less lbcd opr2 ; Get operand 2 (no.Displays) porti1: push b lda opr1 mov c,a ; Load port no. call pracc ; Display port no.+ space inp a call pracc ; Go display value pop b call chkabrt ; See if abort pressed call crlf ; New line dcx b mov a,b ora c ; Does B = C = 0 ???? jrnz porti1 ; Count - 1 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 jrnz mtest2 ; Loop if not finished lhld opr1 ; Get back start address mtest3: mov a,l 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 jrnz 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 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 ; ;**************************************************************** ; ; I/O ram board reads, writes, display and CRC are done ; with the read and write command via; ; ; R bb cc ss sz ds ; W bb cc ss sz ds ; ^ ^ ^ ^ ^ ; | | | | +-- System memory address to use ; | | | +----- Size in bytes ; | | +-------- I/O memory address in the chip ; | +----------- Chip number 0..7 ; +-------------- Board number 0..3 ; ;**************************************************************** ; ; Read the I/O RAM board to system memory. ; ;**************************************************************** ; io$rd: lda opcnt cpi 2 jrnz iord2 ; Error if not 5 ; Load registers now lhld opr1 shld cur$sec lhld opr2 shld cur$dma jmp rd$ioram ; Read the board ; iord2: lhld opr1 shld cur$sec lhld opr2 shld cur$dma call rd$ioram ; Read board call cst jrz iord2 ; Loop till a key press call cie ret ; ;**************************************************************** ; ; Write to the I/O RAM board from system memory. ; ;**************************************************************** ; io$wr: lda opcnt cpi 2 jrnz iowr2 ; Error if not 5 ; Load registers now lhld opr1 shld cur$sec lhld opr2 shld cur$dma jmp wr$ioram ; Write to the board ; iowr2: lhld opr1 shld cur$sec lhld opr2 shld cur$dma call wr$ioram ; Write to the board call cst jrz iowr2 call cie ret ; ;**************************************************************** ; Display the contents of an ioram device. The user must enter ; the command X bb cc mm which is board, chip, memory address ; which will be dispplayed onto the screen. ;**************************************************************** ; io$dsp: lda opcnt cpi 1 jnz erdisp ; Error if <>3 ; Now use the ioram routine to display memrory ; with DE = board/chip, HL = address lhld opr1 shld cur$sec lxi h,sector shld cur$dma ; Sector buffer dsp$next: call rd$ioram ; Read the sector lxi h,sector ; -> data area ; ; Now display it. ; next$page: lxi d,sec$msg call ptxt lded cur$sec call phde ; call crlf ; One line to separate mvi c,8 ; 8 lines to display next$line: ; Jump here to display a line mvi b,16 ; 16 bytes per line push h ; Preserve ; ; call crlf mvi a,8 sub c ; A = 8 - line number add a add a add a add a call phacc ; Address within sector = line times 16 call space2 ; ; Now display the line ; ds$bin: call clrwdt ; Stop the watchdog mov a,m ; Fetch a byte from sector buffer call phacc call space ; Separator mov a,b cpi 9 ; Middle ? jrnz bin$nxt mvi a,'-' call coe call space ; Display next binary byte bin$nxt: inx h ; -> next ioram byte djnz ds$bin ; ; Display in ASCII now ; call space2 ; pop h ; Restores sector address mvi b,16 ds$asc: call clrwdt mov a,m call makasc call coe inx h djnz ds$asc ; Do all line ; Any more lines ???? dcr c mov a,c ora a jnz next$line ; Done. ; ; Look for users options ; call cie cpi esc jz warm ; Space, cr, lf = next sector cpi ' ' jrz nxt$sec cpi cr jrz nxt$sec cpi lf jrz nxt$sec cpi '+' jrz next$sec$k cpi '-' jrz last$sec$k jmp warm ; ; last$sec$k: ora a lhld cur$sec lxi d,8 dsbc d shld cur$sec jmp dsp$next ; next$sec$k: lhld cur$sec lxi d,8 dad d shld cur$sec jmp dsp$next ; ; Select the next sector to read and display ; nxt$sec: lhld cur$sec inx h shld cur$sec jmp dsp$next ; sec$msg: db cr,lf,'Sector : $' ; ;**************************************************************** ; Fill the IORAM board with the 16 bit sector number. ;**************************************************************** ; io$fill: lxi h,sector shld cur$dma ; lxi b,2048 ; 2048 sectors = 25k k. lxi h,0 ; Sector number shld cur$sec ; io$fill$loop: call clrwdt push b ; If bits 0..6 C = 0 then 128 records written. Indicate. Clear dog. mov a,c ani 1fh ora a jnz ifl1 mvi a,'.' call coe call clrwdt ; ; Fill sector ; ifl1: lhld cur$sec ; Sector number mov a,l sta sector sta sector + 2 mov a,h sta sector + 1 ; Now fill with low address lxi h,sector + 2 lxi d,sector + 3 lxi b,125 ; Bytes to copy ldir ; Copy. ; Write to board. call wr$ioram pop b ; Bump the numbers lhld cur$sec inx h shld cur$sec dcx b mov a,b ; Do all 2048 sectors ora c jnz io$fill$loop ; ret ; ;**************************************************************** ; Display the A-D converter ;**************************************************************** ; ad$disp: call ini$ad call rd$ad xchg call pdde ret ; ;**************************************************************** ; Verify all the sectors in an IORAM board. ;**************************************************************** ; io$verf: lxi h,sector shld cur$dma ; lxi b,2048 ; 2048 sectors = 25k k. lxi h,0 ; Sector number shld cur$sec ; io$verf$loop: call clrwdt push b ; If C = 0 then 128 records checked. Indicate. Clear dog. mov a,c ani 01fh ora a jnz ivl1 mvi a,'.' call coe call clrwdt ; ; Read sector ivl1: call rd$ioram ; Verify sector is prefixed by record number and is homogenous. lhld cur$sec ; DE = HL if ok lda sector cmp l jnz verf$err ; Error if not = ; Check high address lda sector + 1 cmp h jnz verf$err ; Now check all other bytes mov a,l ; A = low address = byte to check for mvi b,126 lxi h,sector + 2 svl: cmp m jnz verf$err inx h ; -> next sector number djnz svl ; ; -- See if any more to do. ; verf$next: pop b ; See if a user abort call cst jz vnb call cie cpi esc rz ; Exit with an escape ; Bump the numbers vnb: lhld cur$sec inx h shld cur$sec dcx b mov a,b ; Do all 2048 sectors ora c jnz io$verf$loop ; ret ; verf$err: lxi d,ve$msg call ptxt lded cur$sec call phde ; Display sector jmp verf$next ; Verify next byte ; ve$msg db cr,lf,'Verify Error at $' ; ; ;**************************************************************** ; 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 ; ;---------------------------------------------------------------- ; Write a string of text, 80 characters long to the LCD ;---------------------------------------------------------------- ; lcd$wr: call ini$lcd ; Initialize the lcd lxi d,20 call delay call clrwdt ; mvi b,40 ; 16 characters on top line mvi a,'0' lcd$l1: call put$lcd inr a push psw lxi d,1 call delay pop psw djnz lcd$l1 ; ; Do second row ; lxi d,1 ; X = 0, Y = 1 call cur$lcd ; mvi b,40 ; 40 characters on top line mvi a,'A' lcd$l2: call put$lcd lxi d,1 push psw call delay pop psw inr a djnz lcd$l2 ; call hom$lcd ; Cursor to top lh corner ret ; ;**************************************************************** ;* 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 ; ;************************************************ ;* Table of routines for indirect jump * ;************************************************ ; jmptbl: dw adump ; A Ascii display of memory dw ad$disp ; B Display A-D converter dw scan$ad ; C Scan the A-D converter 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 lcd$wr ; J LCD write dw clock ; K read/write clock dw locat ; L locate string dw move ; M move memory dw dinos ; N dw portout ; O output to a port dw port ; P examine port dw quit ; Q quit this monitor dw io$rd ; R = read I/O ram board 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 io$wr ; W = write to I/O ram dw io$dsp ; X display ioram contents dw io$fill ; Y Fill IORAM with data dw io$verf ; Z Verify ioram data ; signon: db cr,lf signon1: db 'CORE BOARD Monitor' db cr,lf,0 signon2: db cr,lf db 'M>' db 0 ; dseg ; din$buf ds 10 ; ; ; ds 128 stack: ds 10 stcktop ds 10 ; dump$lst ds 2 cur$dma db 00,00 ; DMA address for ioram work cur$sec db 00,00 sector ds 128 ; 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 ;