comment ~ - SIUX - Siux Monitor Program entry: ............ siux.asm version: .......... 1.0 started: .......... 1998-11-01 last edit date: ... 2004-01-16 assembler used: ... Zilog Zmasm Mikael Pontén Pons Data ~ ; constants include "sys.inc" ; system equates include "macros.inc" ; instruction macros pgm: equ 0 ; start of program org pgm ; restart RESET - start of monitor ; system default is extended, long word mode setc xm ; enter extended mode setc lw ; set long word mode jp rstreset db 0 ; fill ; restart RIN - get input mrin: scal zin ret c jr mrin ; STMON - initialize monitor ; NB! The address of STMON is equated in sys.inc jp strtb ; STMON: ; restart 10 - not used rstrt10: jp rst10j ; vector through ram db [5]0 ; fill ; restart scal - subroutine call scal: ex (sp),hl ; only works in long word mode inc hl ex (sp),hl push hl,af jp scalb ; restart BRKPT - breakpoint mbrkpt: ex.lw (sp),hl dec hl ; dec pc on stack jp breakpt db 0 ; restart PRS - output a string ; NB! The address of dret is equated in sys.inc mprs: ex (sp),hl prs1: ld a,(hl) inc hl or a ; end of string? jr nz,prs2 ; nz=no ex (sp),hl ret ; dret: ; restart ROUT - output a character mrout: push hl jp aout ; more of restart PRS prs2: rst ROUT ; output a character jr prs1 db 0 ; fill ; restart 38 - not used rstrt38: jp rst38j ; vector through ram ; get input bin: push hl ld hl,(kblink) bin1: scal zin jr c,bin3 ld a,(sysflg) bit BRZBL,a ; restart requested? jr nz,bin2 ; yes sub hl,(one) ; dec count to stay here jr nc,bin1 bin2: ccf bin3: pop hl ret ; zkbd - keyboard routine ; entry: hl reserved ; exit: a char if key pressed else 0 ; cy set to 1 if key pressed ; keyboard info in kbdbuf: ; byte 1: ascii character or zero if special function key (reg. al) ; byte 2: scan code (reg. ah) ; byte 3: bios keyboard flags, 40:17 (reg. al) ; byte 4: bios keyboard flags, 40:18 (reg. ah) kbd: push hl ld a,PCSKBD ; zkbd on pc ld hl,kbdbuf call rdepp ld a,(hl) inc hl or (hl) ; key pressed? dec hl ld a,(hl) ; ascii char (?) pop hl scf ret nz ; yes ccf ; no key pressed ret ; nmi restart org 66h rnmi: jp nmij ; zblink - blink until input blink: call rdch ; get char at cursor to buffer ld (blinkf),a ; save in blinkf ld a,(curchr) ; get cursor char call wrch ; put cursor on screen call bin push af ; save char ld a,(blinkf) ; restore char at cursor call wrch xor a ; clear blink flag ld (blinkf),a pop af ; restore input char ret c ; character so return call bin ; scan kbd jr nc,blink ; no char so repeat ret ; zcrt - crt routine crt: or a ; ignore null or lf ret z push af cp LF call nz,do_crt pop af ret do_crt: cp BLANK ; control character? jp nc,wrcht ; no ld hl,crttab ld bc,crttab$ cpdr ; control character? jp nz,wrcht ; no, output to pc ld hl,crtcmd add hl,bc add hl,bc add hl,bc ld c,(hl) inc hl ld.w hl,(hl) jp (hl) ; = ok, hlz = 0 & bc lt 255 ; crt control command table crttabe: db FF,BS,CUL,CH,ESC,CR,CCR,CUU,CUD,CSL,CSR,CUR,CE,CUWL,CUWR,PGUP,PGDN,PRVC,NXTC,VPU,VPD crttab$: equ $-crttabe crttab: equ $-1 ; code key crtcmd: db PCCS,low scmdc,high scmdc ; FF ctrl/l db 0,low do_bs,high do_bs ; BS backspace db PCCUL,low scmdc,high scmdc ; CUL left arrow db 0,low cpos,high cpos ; CH home db PCESC,low scmdc,high scmdc ; ESC Esc db PCCRLF,low do_cr,high do_cr ; CR enter db PCCRLF,low do_ccr,high do_ccr ; CCR ctrl/x db PCCUU,low scmdc,high scmdc ; CUU up arrow db PCCUD,low scmdc,high scmdc ; CUD down arrow db PCCSL,low scmdc,high scmdc ; CSL delete db 0,low do_csr,high do_csr ; CSR insert db PCCUR,low scmdc,high scmdc ; CUR right arrow db PCEND,low scmdc,high scmdc ; CE end db PCWL,low scmdc,high scmdc ; CUWL ctrl/left arrow db PCWR,low scmdc,high scmdc ; CUWR ctrl/right arrow db 0,low do_pgup,high do_pgup ; PGUP page up db 0,low do_pgdn,high do_pgdn ; PGDN page down db 0,low do_prvc,high do_prvc ; PRVC ctrl/insert db 0,low do_nxtc,high do_nxtc ; NXTC ctrl/delete db 0,low do_vpu,high do_vpu ; VPU ctrl/< used by macros; use ctrl/pgup for manual operation db 0,low do_vpd,high do_vpd ; VPD ctrl/9 used by macros; use ctrl/pgdn for manual operation do_bs: call rdcp ; read cursor pos ld a,l or a ; at start of line? ret z ; yes ld a,BS call wrcht ; output bs to pc ld a,(sysflg) rra ; insert mode? ret c ; yes ld a,BLANK ; remove any char at the new pos jp wrch do_pgup: ld hl,kbdbuf+2 bit 2,(hl) ; if ctrl then inc video page jr z,crt1 ; no, cursor to top of screen do_vpu: call rdvp inc a jp wrvp crt1: call rdcp ; read cursor pos ld h,0 ; row = 0 jp wrcp ; write cursor pos do_pgdn: ld hl,kbdbuf+2 bit 2,(hl) ; if ctrl then dec video page jr z,crt2 ; no, cursor to bottom of screen do_vpd: call rdvp dec a jp wrvp crt2: call rdcp ; get cursor pos ld h,24 ; row = 24 jp wrcp do_prvc: xor a ; ctrl/ins ld bc,0 ld hl,(cblptr) push hl sub hl,(cbstart) sub hl,(one) pop hl ret c dec hl dec hl cpdr inc hl inc hl ld (cblptr),hl ld a,PCSAZ jp wrepp do_nxtc: xor a ; ctrl/del ld bc,0 ld hl,(cblptr) push hl sub hl,(cbptr) sub hl,(one) pop hl ret c cpir push hl sub hl,(cbptr) sub hl,(one) pop hl ld (cblptr),hl ld a,PCESC jp c,scmd ld a,PCSAZ jp wrepp do_ccr: call rdcp ld (temp),hl call cpos call rdcp sub hl,(temp) sub hl,(one) ; was hl at left pos? ret c ; yes do_cr: call scmdc ld a,(sysflg) rra ; insert mode? ret nc ; no do_csr: ld hl,sysflg ld a,1 xor (hl) ld (hl),a rra ; insert mode now? ld a,(imcurchr) ; insert mode cursor char jr c,crt3 ; yes ld a,(ncurchr) ; normal cursor char crt3: ld (curchr),a ld a,PCION jp c,scmd ld a,PCIOFF jp scmd ; zcrtb - write line, buffered crt routine ; This routine has limited support of control characters. wrln: push af ld hl,(robptr) ; buffer pointer ld de,hl cp BLANK ; control character? jr nc,wrln3 ; no, save in buffer cp CR ; cr? jr z,wrln6 ; yes, write to pc cp BS ; backspace? jr nz,wrln2 ; no wrln1: dec hl ld de,hl sub hl,(robstart) ; still in buffer? jr c,wrln5 ; no jr wrln4 wrln2: cp CUL ; cursor left? jr z,wrln1 ; yes jr wrln5 wrln3: inc hl ; make room for the terminating 0 sub hl,(robend) ; reached end of buffer? jr nc,wrln5 ; yes ld (de),a inc de wrln4: ex de,hl ld (robptr),hl wrln5: pop af ret wrln6: ld (hl),0 ; asciiz string ld hl,sysflg res BWRLN,(hl) ld hl,(robstart) ; reset buffer pointer ld (robptr),hl ld a,PCSAZ ; write asciiz to pc call wrepp ld a,PCCRLF ; do cr + lf call scmd pop af ret ; zcpos - set cursor to start of line cpos: ld a,PCCH call scmd ld hl,clin ret ; zwrcht - write a character to the pc ; entry: a character to write ; the cursor is moved on the pc wrcht: push hl ld hl,crtbuf ld (hl),a ld a,PCWC ; write character call wrepp pop hl ret ; zrdch - read a character at the cursor pos ; exit: a character ; crtbuf[0] has a copy of the character rdch: push hl ld hl,crtbuf ; work buffer ld a,PCGCC ; getcurchar call rdepp ld a,(hl) pop hl ret ; zwrch - write a character at the cursor pos ; entry: a character to write wrch: push hl ld hl,crtbuf ; work buffer ld (hl),a ld a,PCPCC ; putcurchar call wrepp pop hl ret ; zrdcp - read cursor position ; exit: hl h row, l column ; hlz 0 ; crtbuf[0] is the column ; crtbuf[1] is the row rdcp: ld hl,crtbuf ; work buffer ld a,PCRDCP ; read cursor position call rdepp ld hl,(crtbuf) ret ; zwrcp - write cursor position ; entry: hl h row, l column to write ; crtbuf[0, 1] are updated wrcp: push hl ld (crtbuf),hl ; work buffer ld hl,crtbuf ld a,PCWRCP ; define cursor position call wrepp pop hl ret ; zrdvp - read video page ; exit: a current video page rdvp: push hl ld hl,crtbuf ; work buffer ld a,PCRDVP ; read video page call rdepp ld a,(hl) pop hl ret ; zwrvp - write video page ; entry: a video page to write wrvp: push hl ld hl,crtbuf ld (hl),a ld a,PCWRVP ; write video page call wrepp pop hl ret ; zload - load file from pc ; entry: hl pointing to buffer ; exit: hl unchanged load: ld a,PCLF ; load file ; zrdepp - read data from epp ; entry: a command code to the pc ; hl points to data buffer ; exit: a cleared ; epprdptr is one past the last byte rdepp: push sr,hl,bc di ld bc,opcode ; opcode reg out (c),a inc c ; pcctrl reg out (c),1 ; set interrupt bit ld c,status ; status reg rdepp1: in a,(c) ; read status jr z,rdepp1 ; z = no requests => wait jp p,rdepp2 ; p = intrq => pc is ready ina a,(eppdata) ; read byte ld (hl),a inc hl jr rdepp1 rdepp2: ld (epprdptr),hl pop bc,hl,sr xor a ret ; zwrepp - write data to epp ; entry: a opcode for the pc ; hl points to data buffer ; exit: a cleared wrepp: push sr,hl,de,bc di ld bc,opcode ; opcode reg out (c),a inc c ; pcctrl reg out (c),1 ; set interrupt bit ld c,status ; status reg wrepp1: ld a,(hl) inc hl wrepp2: in e,(c) ; read status jr z,wrepp2 ; no requests => wait jp p,wrepp3 ; p = intrq => pc is ready outa (eppdata),a ; write byte jr wrepp1 wrepp3: pop bc,de,hl,sr xor a ret ; zscmd - send command to pc, no data transfer ; entry: a command to the pc ; exit: a cleared scmdc: ld a,c scmd: push sr,bc di ld bc,opcode ; opcode out (c),a inc c ; pcctrl out (c),1 ; set interrupt bit ld c,status ; status reg scmd1: in a,(c) ; read status jr z,scmd1 ; no requests => wait jp p,scmd2 ; p = intrq => pc is ready jr scmd1 scmd2: pop bc,sr xor a ret ; M - modify command modify: scal zargs mod1: ld (arg1),hl scal zsp2 scal ztbcd5 ld a,(hl) scal zb2hex Printc BLANK,CUL,CUL,CUL call inls ; get input line scal znum ; get address jr c,mod9 ld a,(hl) or a jr z,mod9 inc hl ld hl,(hl) ld b,0 mod2: push hl ; get each entry scal znum ld a,(hl) or a jr z,mod4 inc hl ; put into memory ld a,(hl) ; hl = numn+1 = numv pop hl mod3: ld (hl),a inc b inc hl push hl mod4: pop hl ld a,(de) cp '.' ret z cp ',' jr nz,mod5 inc de ld a,(de) inc de jr mod3 mod5: ld a,b ; inc if none or a jr nz,mod6 inc hl mod6: ld a,(de) cp ':' ; if : go back jr nz,mod7 dec hl dec hl jr mod1 mod7: cp '/' ; if / set to value jr nz,mod8 inc de scal znum jr c,mod9 ld hl,(numv) jr mod1 mod8: or a jr z,mod1 cp BLANK jr z,mod2 mod9: scal zerrm jr modify ; routine to get input line, store breakpoint byte etc inls: call brsto ; zinlin - normal start of routine ; exit: de start of input line, clin inlin: push hl inlin1: scal zblink ; get input character ld hl,sysflg bit BRZBL,(hl) ; just restart zblink? res BRZBL,(hl) jr nz,inlin1 ; yes, macro probably active now rst ROUT cp CR jr nz,inlin1 call rdcp ; read cursor pos push hl dec h ; previous line call wrcp ; write cursor pos ld a,PCRCL ; read the cursor line ld hl,clin ; to clin push hl call rdepp pop de,hl ; set de to start of input call wrcp ; put cursor back call storecl ; utlity to recall command lines pop hl ret ; storecl - save the commandline ; entry: de points to start of commandline (clin) ; exit: bc,de unchanged storecl: push bc ld (temp),de ; clin ld hl,80 ld b,l add hl,de storecl1: dec hl ; find end of line ld a,(hl) cp BLANK jr nz,storecl3 djnz storecl1 storecl2: pop bc ; empty line ret storecl3: inc hl sub hl,(temp) ; pos on line - clin cpw 5 ; less than 5 characters? jr c,storecl2 ; yes, don't save too short lines ld bc,hl ; # bytes in input storecl4: ld hl,(cbptr) ; insertion point add hl,bc inc hl ; asciiz string sub hl,(cbend) ; space enough? jr c,storecl5 ; yes push de,bc ; commandline, size of input str ld bc,0 ; remove oldest string in buffer xor a ld hl,(cbstart) cpir ld (temp),hl ld hl,(cbptr) sub hl,(temp) ld bc,hl ; # bytes to move down ld hl,(temp) ld de,(cbstart) ldir ld (cbptr),de pop bc,de jr storecl4 ; try again storecl5: push de ld hl,(cbptr) ; insertion point ex de,hl ldir xor a ; make asciiz ld (de),a inc de ld (cbptr),de ld (cblptr),de pop de,bc ret ; store breakpoint byte & set conflg to 0 brsto: xor a ld (conflg),a ld hl,(brkadr) ld a,(hl) ld (brkval),a ret ; T command - display memory ; the routine starts at showmem ; controls: ; pgdn or cr - next page ; pgup - next page backward ; space - update ; esc - exit ; left arrow - step one byte backward ; right arrow - step one byte forward ; up arrow - step one line backward ; down arrow - step one line forward show1: call crlf ; go to next line pop bc ld (temp),de sub hl,(temp) add hl,(temp) ; reached end address? ret nc ; yes, exit ld a,b or c ; done all lines? jp nz,show11 ; no, one more show2: rst RIN ; wait for input cp ESC ; escape? ret z ; yes, exit push af,hl ld a,(argn) cp 3 ; line count given? jr nc,show3 ; yes, must scroll ld hl,0 ; top left = 0,0 call wrcp show3: pop hl,af cp PGDN ; page down? jr z,showmem ; yes, one more page cp CR ; cr? jr z,showmem ; yes, one more page cp BLANK ; space? jr z,show8 ; yes, update cp PGUP ; reverse? jr nz,show5 ; no push de ld hl,(arg4) ; # extra byte/line ld de,16 ; + default 16 byte/line add hl,de ex de,hl ld a,(argn) ld hl,24 ; default lines cp 3 ; arg3 given? jr c,show4 ; no ld hl,(arg3) ; lines/page show4: multuw de ld (temp),hl ; # bytes to reverse ld hl,iy sub hl,(temp) pop de ; end address jr showmem ; one more page backwards show5: ld.iw bc,-1 ; one step backward cp CUL ; left arrow? jr z,show7 ; yes cp CUR ; right arrow? jr z,show6 ; yes, one step forward ld hl,(arg4) ; # extra byte/line ld bc,16 ; + default 16 byte/line add hl,bc ld (temp),hl ld hl,0 sub hl,(temp) ld bc,hl ; -x lines backward cp CUU ; up arrow? jr z,show7 ; yes cp CUD ; down arrow jr nz,show2 ; no, accept nothing else show6: ld (temp),bc ; turn backward to forward ld hl,0 sub hl,(temp) ld bc,hl show7: add iy,bc show8: ld hl,iy showmem: ld a,(argn) ld bc,24 ; default lines cp 3 ; arg3 given? jr c,show9 ; no ld bc,(arg3) ; # lines show9: ld.iw de,-1 cp 2 jr c,show10 ld de,(arg2) show10: ld iy,hl ; memory to display show11: dec bc push bc,hl ld hl,sysflg ; use write line set BWRLN,(hl) pop hl call space call tbcd5 ; output address call space ld a,(arg4) ; output 16+arg4 bytes add a,16 ld b,a ; x bytes to display push hl,bc show12: ld a,(hl) call b2hex ; display hex ld a,b cp 9 ld a,BLANK jr nz,show13 ld a,'-' show13: rst ROUT inc hl djnz show12 call sp2 ; 2 blanks up to ascii-field pop bc,hl show14: ld a,(hl) cp BLANK ; writable character? jr nc,show15 ; yes ld a,'.' ; do a dot instead show15: rst ROUT inc hl djnz show14 jp show1 ; zsp2 - output 2 spaces sp2: call space jr space ; ztbcd5 - output 32 bit hl then a space tbcd5: swap hl call outhl swap hl ; ztbcd3 - output 16 bit hl then a space tbcd3: call outhl ; zspace - output a space space: ld a,BLANK rst ROUT ret ; zerrm - output error message errm: Printt "Error" ; zcrlf - output cr crlf: ld a,CR rst ROUT ret ; output low 16 bits hl outhl: ld a,h call b2hex ld a,l ; zb2hex - output a b2hex: push af rra rra rra rra call b1hex pop af ; zb1hex - output low half a b1hex: and 0fh add a,90h daa adc a,40h daa rst ROUT ret ; znum - read in hex value ; entry: de input line ; exit: numn number of input characters ; numv value num: ld a,(de) ; ignore blanks cp BLANK inc de jr z,num dec de ld hl,0 ld (numv),hl ; numv & mumn = 0 ld hl,numn ld (hl),0 num1: ld a,(de) ; get character or a ; check for end ret z cp BLANK ret z cp "," ret z sub a,'0' ; convert from ascii ret c ; if < 0, invalid cp 10 jr c,num2 res 5,a ; make upper case sub a,'A'-'0'-10 ; 7 cp 10 ; if < 10, invalid ret c cp 16 ; if > 16, invalid jr c,num2 scf ret num2: inc de ; valid. point to next inc (hl) ; inc (numn) push bc,hl ld b,4 num3: inc hl ; put value in numv, rld ; rotating prev contents djnz num3 pop hl,bc jr z,num1 ; z = less than 8 digits dec de ; point to ninth digit scf ; error ret ; zrlin - recieve hex arguments on a line rlin: xor a ld (argn),a ld bc,arg1 rl2: scal znum ; get value ret c ; c = invalid hex number ld a,(hl) or a ; any digits in last val? ret z ; no inc hl ; copy to arg1/10 push de ld de,bc ldiw ld bc,de pop de ld hl,argn inc (hl) ; one more argument ld a,(hl) cp 11 ; too many args? jr c,rl2 ; no scf ret ; monitor initialization strtb: call brres ; restore breakpoint byte xor a ld.ib (cmdbuf),a ld (clin+80),a ld hl,port0 ; clear monitor wrk ld de,port0+4 ld bc,one-port0-4 ldw (hl),0 ldirw ldctl hl,sr ; initialize sr for E command ld (rsr),hl ld hl,initt ; set wrk from table ld bc,initte-initt ldirw ld de,kblink ; set cursor blink speed ldiw ld de,curchr ; default cursor characters ld a,(hl) ld (de),a inc de ldi ldi ld hl,staba ; copy scal table to ram ld de,sctb+4*'A' ld bc,staba$-staba ldirw xor a ; send a dummy command so the call scmd ; next won't be lost, i.e. hang waiting for the pc to respond xor a ; select video page 0 call wrvp Printc FF ; clear the screen ret ; workspace initialization table align 4 initt: equ $ dl 1 ; 1 useful constants dl 2 ; 2 dl 3 ; 3 dl 4 ; 4 dl 5 ; 5 dl 6 ; 6 dl 7 ; 7 dl 8 ; 8 dl 9 ; 9 dl 10 ; 10 icbptr: dl cmdbuf+1 ; insertion pointer icblptr: dl cmdbuf+1 ; list pointer icbstart: dl cmdbuf+1 ; start of command line buffer icmdbufe: dl cmdbufe ; end of command line buffer irobptr: dl wrlnbuf ; insertion pointer irobstart: dl wrlnbuf ; start of buffer irobend: dl wrlnbufe ; end of buffer istab: dl sctb ; subroutine table istabo: dl sctb ; ordinary subroutine table iout: dl outt1 ; output table ioutb: dl outt2 ; output table 2 iin: dl int1 ; input table align 4 iuout: jp.iw dret ; user jumps align 4 iuin: jp.iw dret align 4 inmi: jp.iw trap ; nmi jump align 4 ibrk: jp.iw trap ; break jump align 4 irst10: jp.iw dret ; rst 10 jump align 4 irst38: jp.iw dret ; rst 38 jump align 4 initte: equ $ iblink: dl 0d00h ; blink speed icurchr: db '_' ; normal cursor character iimcurchr: db 0feh ; insert mode cursor char ; continue rst RESET rstreset: ld hl,inittab ; initialize Z80380 registers rstr1: ld c,(hl) ; get register addr inc hl inc c ; reached end of table? jr z,rstr2 ; yes dec c otim ; write the data to this reg jr rstr1 rstr2: ld.ib sp,monstk call STMON jr mret ; initialization data table for Z80380 on-chip registers ; table format: register address, then value for the register inittab: db LMCS0 ; ps 88, lmcs db 0F0H ; 0 - fff db LMCS1 db 0FFH db UMCS0 ; ps 89, umcs db 1 ; activate refresh db UMCS1 db 0 ; 0 - 00ff.ffff, refresh aktiv db LMWR ; ps 91 db 0 db UMWR db 1 ; ps 91, kan ej vara noll db RFWR ; ps 96 db 0 db RFSHR0 ; ps 95 db 0 db RFSHR2 db 84H db MSMER ; ps 94 db 0C1H ; 0a1h db IOCR0 ; ps 85 db 2 db SMCR ; ps 97 db 4 db -1 ; end of table ; zmret - user return, reset stacks mret: ld.ib sp,monstk ld.iw hl,STACK ; set user stack ld (rsp),hl Text "-- SIUX --" call brres ; main monitor loop, get line and obey parse: call inls ld bc,argx ; if command is blank and previous command is not S, ignore ld a,(de) cp BLANK jr nz,pa2 ld a,(bc) cp 'S' jr nz,parse pa2: cp 'A' ; check and store jr c,perr cp 'Z'+1 jr nc,pext ld (bc),a ld (argc),a inc de ; point to next character scal zrlin ; get args ld (clinp),de jr nc,pend ld a,(argc) cp 'L' ; l command? jr z,pend ; yes, allow error perr: scal zerrm jr parse pend: scal zargs scal zscalj jr parse pext: ld hl,pexttab ld bc,pexttab$ cpdr ; command letter? jr nz,perr ; no ld (argc),a ld (argx),a inc de ; point to next character push bc scal zrlin ; get args ld (clinp),de pop bc jr c,perr ld hl,pextcmd add hl,bc add hl,bc add hl,bc add hl,bc ld hl,(hl) push parse,hl ; return to parse scal zargs ret ; do the command ; extended command table pexttabe: .ascii "oq" pexttab$: equ $-pexttabe pexttab: equ $-1 pextcmd: dl ow ; o output word dl qw ; q query word ; restore breakpoint byte brres: ld hl,(brkadr) sub hl,(one) ret c inc hl ld a,(brkval) ld (hl),a ret ; J - jump to address command jump: jp (hl) ; E - execute command exec: push hl call brsto ; store breakpoint byte sub hl,(one) ; breakpoint set? jr c,exec1 ; no inc hl ld (hl),RST20 ; insert restart, rst20=E7 exec1: pop hl ld a,(argn) ; if no address entered or a ; use stored user pc jr z,exec2 ; z = no address ld (rpc),hl ; user pc is new address exec2: ld sp,rix ; point to register ix pop ix,iy,bc,de,hl,af,sr ; restore regs ld.lw sp,(rsp) ; restore user sp push.lw hl ; put user pc on ld.lw hl,(rpc) ; top of stack ex.lw (sp),hl ret ; exec program ; do rest of rst brkpt breakpt: ex.lw (sp),hl jp brkj ; come here after nmi or breakpoint ; nb! don't use any rsts until system is fully restored trap: push.lw sr setc lw push af,hl,de,bc,iy,ix call brres ; restore breakpoint ld hl,0 add hl,sp ; stack has: pc sr af hl de bc iy ix ld.ib sp,monstk ; set monitor stack ld de,rix ; copy user regs (8) from user ld bc,32 ; stack to register save area ldirw ; incs sp to original val ld (rsp),hl ; store user sp ld hl,(ostab) ; reset stab if modified ld (stab),hl ; by user program ld hl,0 ; clear uschan for ld (uschan),hl ; same reason call pregs jp parse ; P - output registers pregs: ld hl,(sdentry) push hl sub hl,(one) ; any debugger active? ret nc ; yes, go to it pop hl ld a,CR ; put cursor at start of line rst ROUT ld de,rsp+4 Printt "SP " call printreg Printt "PC " call printreg Printt "SR " call printreg scal zcrlf Printt "AF " call printreg Printt "HL " call printreg Printt "DE " call printreg scal zcrlf Printt "BC " call printreg Printt "IY " call printreg Printt "IX " call printreg scal zcrlf Printt "I " ld hl,i ; reg i scal ztbcd5 scal zspace Printt "R " ld a,r ; reg r scal zb2hex scal zsp2 ld a,(raf) ; reg f ld de,estr-1 ld b,8 pregs1: inc de rla push af ld a,(de) jr nc,pregs2 rst ROUT pregs2: pop af djnz pregs1 scal zcrlf ret ; print register printreg: dec de dec de dec de dec de ld hl,(de) ; reg value scal ztbcd5 ld hl,(hl) ; value at reg address ld a,h ld h,l ld l,a swap hl ld a,h ld h,l ld l,a scal ztbcd5 ; memory data scal zsp2 ret ; string for flags estr: db "SZ",0,"H",0,"PNC" ; zargs - get first 3 arguments args: ld hl,(arg1) args2: ld de,(arg2) args3: ld bc,(arg3) ret ; I - intelligent copy command icopy: ld (temp),de sub hl,(temp) ; arg1 >= arg2? add hl,de jr nc,copy ; yes, do ldir dec bc ex de,hl add hl,bc ex de,hl add hl,bc inc bc lddr ret ; C - copy command copy: ldir ret ; A - arithmetic command arith: scal zspace push hl add hl,de ; sum scal ztbcd5 ; a+b pop hl ; difference push hl ld (temp),de sub hl,(temp) scal ztbcd5 ; a-b pop hl push hl multuw de scal ztbcd5 ; a*b pop hl divuw de scal ztbcd3 ; a/b Printc BS,'.' swap hl scal ztbcd3 scal zcrlf ret ; O - output command, byte ob: ld bc,hl out (c),e ret ; o - output command, word ow: ld bc,hl outw (c),de ret ; Q - query command, byte qb: scal zspace ld bc,hl in a,(c) scal zb2hex scal zcrlf ret ; q - query command, word qw: scal zspace ld bc,hl inw hl,(c) scal ztbcd3 scal zcrlf ret ; L - download a file to ram ; p1: [drive:]filename[.ext] (dos syntax) ; current drive if no drive is given ; extension go is assumed if no ext given ; p2: load address (hex) ; example: L test e00000 loadf: ld hl,clin ; must parse the cmnd line myself load1: inc hl ld a,(hl) ; skip blanks up to filename cp BLANK jr z,load1 push hl ; filename starts here load2: inc hl ; go past the filename ld a,(hl) cp BLANK jr nz,load2 ld (hl),0 ; end the filname with 0 inc hl ex de,hl ; de = command line scal znum ; get load address jr nc,load3 ; ok pop hl scal zerrm ret load3: ld hl,temp ldw.iw (hl),206f672eh ; " og." ld a,PCDE ; define default extension scal zwrepp pop hl ld a,PCFN ; send filename to pc scal zwrepp ld hl,(numv) ; load address scal zload ; load the file ret ; subroutine call restart scalb: push de ld hl,(uschan) push hl sub hl,(one) ; another scal handler? ld hl,(sp+16) dec hl ; point hl to routine number ret nc ; yes, go to it pop de scal2: ld e,(hl) ; get routine number scal3: ld hl,(stab) ld a,e cp 'A' ; second scal table? jr nc,scal4 ; nc=no ld hl,(usctab) ; routines 0 - 40h scal4: ld de,0 ld e,a add hl,de add hl,de add hl,de add hl,de ld hl,(hl) pop de,af ex (sp),hl ; fake jump to routine ret ; zscalj - subroutine for call routine at argc scalj: push hl,af,de ld hl,argc jr scal2 ; zscali - subroutine for call routine in e scali: push hl,af,de jr scal3 ; zsscv - set scal vector ; entry: hl new jump vector address ; call is followed by routine number as db ; exit: hl previous jump vector address ; de,bc junk sscv: ex (sp),hl ; get routine number ld c,(hl) inc hl ex (sp),hl ld de,0 ; clear de ld e,c ld bc,hl ld hl,(stab) ; calculate addr in add hl,de ; scal table add hl,de add hl,de add hl,de ld de,(hl) ; read old ld (hl),bc ; save new ex de,hl ; put old vector in hl ret ; zjump - execute jump table ; entry: a jump vector number ; jump vectors follow call as dd ; exit: jumps to selected routine with all ; registers unchanged jumpt: ex (sp),hl ; point to jump table push de,af ; save ld de,0 ld e,a ; calculate vector addr add hl,de add hl,de add hl,de add hl,de ld hl,(hl) ; get vector pop af,de ex (sp),hl ret ; go there ; B - breakpoint command mbreak: ld (brkadr),hl ; store breakpoint addr ret ; U - user i/o command up: ld hl,intu scal znim ld hl,outtu scal znom ret ; N - command, make in and out normal normal: scal znnim ; znnom - restore normal output table nnom: ld hl,outt1 ; znom - set new output table nom: push hl ld hl,(outta) ex (sp),hl ld (outta),hl pop hl ret ; znnim - restore normal input table nnim: ld hl,int1 ; znim - set new input table nim: push hl ld hl,(inta) ex (sp),hl ld (inta),hl pop hl ret ; zin - execute input table in: push hl ld hl,inta jr ioate ; execute output table aout: ld hl,sysflg bit BCWRLN,(hl) ; do writeline continously? jr nz,aout1 ; yes bit BWRLN,(hl) ; writeline for a single line? ld hl,outta jr z,ioate ; no aout1: ld hl,outtb ; execute input or output table ioate: push de,bc ; get start of table ld de,(hl) ioate1: push af ; get routine number ld a,(de) inc de or a ; end of table? jr z,ioate2 ; z=yes ld l,a pop af push de ; call routine or a ld e,l call scali pop de jr nc,ioate1 ; nc = continue push af ioate2: pop af,bc,de,hl ret ; output tables outtu: db zuout outt1: db zcrt,0 outt2: db zcrtb,0 ; input tables intu: db zuin int1: db zkbd,0 ; Z - boot the Z380 system boot: ld hl,bootfile ld de,clin+1 ld bc,bootfile$-bootfile ldir scal 'L' ; load the file xor a ; make sure exec does a coldstart ld (first),a jp.ib SIUXMAIN ; go to siuxmain bootfile: .asciz "exec.go fe0000" bootfile$: equ $ ; subroutine table, starts with A align 4 staba: dl arith ; A dl mbreak ; B dl copy ; C dl errm ; D dl exec ; E dl errm ; F dl errm ; G dl errm ; H dl icopy ; I dl jump ; J dl errm ; K dl loadf ; L dl modify ; M dl normal ; N dl ob ; O dl pregs ; P dl qb ; Q dl errm ; R dl errm ; S dl showmem ; T dl up ; U dl errm ; V dl errm ; W dl errm ; X dl errm ; Y dl boot ; Z dl mret ; 5B dl scalj ; 5C dl jumpt ; 5D dl scali ; 5E dl sscv ; 5F dl args ; 60 dl kbd ; 61 dl in ; 62 dl inlin ; 63 dl num ; 64 dl crt ; 65 dl tbcd3 ; 66 dl tbcd5 ; 67 dl b2hex ; 68 dl space ; 69 dl crlf ; 6A dl errm ; 6B dl sp2 ; 6C dl cpos ; 6D dl blink ; 6E dl nom ; 6F dl nim ; 70 dl b1hex ; 71 dl uoutj ; 72 dl uinj ; 73 dl nnom ; 74 dl nnim ; 75 dl rlin ; 76 dl rdepp ; 77 dl wrepp ; 78 dl rdch ; 79 dl wrch ; 7A dl wrcht ; 7B dl scmd ; 7C dl rdcp ; 7D dl wrcp ; 7E dl rdvp ; 7F dl wrvp ; 80 dl load ; 81 dl wrln ; 82 staba$: equ $ align 16 ; do not remove $end: equ $ end