title *** RTX RUNTIME SYSTEM *** : .z80 ;set m80 for z80 ops rtxver equ 141 ;rtx version number ; ; print message & symbol at consol during assembly print_sym macro message,symbol .printx * message symbol * endm .sall ;no macro expansion list .sfcond ;no false conditional list page 56 ;************************************************************************ ;* * ;* RTX Runtime accessories for PX-8 * ;* * ;* This system is in two parts: * ;* 1) Loader to allocate user BIOS area, check CP/M revision and * ;* install the system with the correct jump table. * ;* 2) The runtime system which is relocated into user BIOS. * ;* * ;************************************************************************ ;* * ;* Revision history: * ;* V1.0 30/6/85 First version put together. * ;* V1.1 1/7/85 Initial bugs fixed. * ;* V1.2 4/7/85 User BIOS allocation changed from auto * ;* to manual (via CONFIG) to eliminate an * ;* obscure problem on machines without an * ;* external RAM disk. * ;* (V1.3) Digital clock added. * ;* V1.4 18/11/85 Terminal mode added, clock removed. * ;* * ;* v1.41 11/30/86 Prgcal code added, continuious battery, * ;* date and time added, terminal echo opt * ;* added. Battery, Printer Setup and I/O * ;* byte setup deleted. Misc format and * ;* assembly changes. evd * ;* * ;************************************************************************ ; .xlist if1 .printx ** .printx * RTX Loader * .printx ** else .printx ** .printx * Pass 2 * .printx ** endif .list title *** RTX LOADER PROGRAM *** : page ; ubsize equ 14 ctrlesc equ 0F1BAH userbios equ 0F00BH ubend equ 0EC00H ubstart equ ubend-(ubsize*256) rtxsize equ rtxend-rtxstart ; deleol equ 5 bs equ 8 lf equ 10 cls equ 12 cr equ 13 esc equ 27 term equ 255 ; .phase 00100H ; loader: ld a,(userbios) ;Check userbios size set correct cp ubsize ld de,ubmsg ;If not, say so and quit jp nz,finish ; load20: ld hl,(ctrlesc) ld de,vermsg ; ld a,h ;Check the contents of the CTRL/ESC cp 039H ;vector matches the correct value jr z,load30 ;for Rev.A (38F8H) or Rev.B (3970H) cp 038H jr z,load40 jp finish ; load30: ld a,l cp 070H jr z,load50 jp finish ; load40: ld a,l cp 0F8H jr z,load50 jp finish ; load50: ld bc,rtxsize ;Relocate RTX into user BIOS ld de,ubstart ld hl,rtxtop ldir ; ld a,(ctrlesc) ;Relocate correct system jump table into cp 070H ;user BIOS depending on version jr z,load60 ld hl,revatbl jr load70 load60: ld hl,revbtbl load70: ld de,jumptbl ld bc,revbtbl-revatbl ldir ; ld hl,(ctrlesc) ;Save existing CTRL/ESC vector ld (sbrwrk),hl ld hl,ubstart ;Set up CTRL/ESC to point to RTX ld (ctrlesc),hl ; ld de,okmsg ;And say we're done ; finish: ld c,9 jp 5 ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; revatbl: ;System call table for Rev.A ; jp 035D8H ;const jp 035FEH ;conin jp 0363FH ;conout jp 03CA7H ;rsopen jp 03C3AH ;opnprinter jp 04535H ;x63c1a jp 04391H ;advcrt jp 0300FH ;readram jp 05B4FH ;xsysscrn jp 05BB5H ;xusrscrn jp 01046H ;blkflsh jp 03CD6H ;rsiox jp 0420Dh ;timdat ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; revbtbl: ;System call table for Rev.B ; jp 03647H ;const jp 0366DH ;conin jp 036AEH ;conout jp 03D42H ;rsopen jp 03CD5H ;opnprinter jp 0459DH ;x63c1a jp 04416H ;advcrt jp 03014H ;readram jp 05B9DH ;xsysscrn jp 05C03H ;xusrscrn jp 00F67H ;blkflsh jp 03D71H ;rsiox jp 04299h ;timdat ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ubmsg: 'The user BIOS area is not set correctly.',cr,lf 'Use the CONFIG program to set ' ubsize/10+'0',ubsize mod 10 +'0',' pages ' 'of user BIOS before running RTX.',cr,lf,'$' ; vermsg: 'RTX already installed, or wrong CP/M version in use.',cr,lf,'$' ; okmsg: cls ' PX-8 Runtime Accessories System, Version ' (rtxver/100+'0'),'.' ((rtxver mod 100)/10)+'0' ((rtxver mod 100) mod 10)+'0',cr,lf ' RTX (c) 1985 AJF, Epson (UK) Ltd., PrgCal (c) 1986 EVD',cr,lf,lf ' RTX is now installed in the user BIOS area.',cr,lf ' Be sure to use the "Remove RTX from memory" option before',cr,lf ' reducing the user BIOS size.',cr,lf,'$' ; ;============================================================================== ;============================================================================== ; title *** RTX RUNTIME SYSTEM *** : page ; rtxtop: ; .dephase .phase ubstart ; ;------------------------------------------------------------------------------ ; .xlist if1 .printx ** .printx * RTX Main Menu * .printx ** endif .list subttl Main menu and entry/exit section page ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; modefg equ 0F0B8H lsfkdsp equ 0F2CFH bflshdt equ 0F335H btryfg equ 0F0D8H ypofst equ 0F0DAH ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; rtxstart: ld hl,modefg ;If MODE is system display, password etc. ld a,(hl) ;then no entry to RTX and 027H ret nz set 2,(hl) ;Else set system display flag ld a,8 ld (lsfkdsp),a ;No function key display xor a call blkflsh ;No block flash call xsysscrn ;Change from user screen to system screen ; restrt: ld hl,menumsg ;Print main menu call stout1 call hdline ; ent10: call getkey ;Get keystroke jp z,exit ;If Z set, then power off/fail cp esc jp z,exit cp '1' jr c,ent10 cp '7' jr nc,ent10 sub 030H dec a jp z,direc ;Ram disk directory dec a jp z,pcal ;prgcal dec a jp z,rs232 ;RS-232 setup dec a jp z,ramed ;RAM editor dec a jp z,terminal ;Terminal jp unhook ;else delete RTX ; exit: ld hl,extmsg ;System screen cursor on call stout1 call xusrscrn ;Change back to user screen ld a,(bflshdt) call blkflsh ;Restore block flash if any ld hl,modefg ;Clear system display flag res 2,(hl) ret ;Finish ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; menumsg: cls,esc,'2','*** RTX v' (rtxver/100+'0'),'.' ;expand version number ((rtxver mod 100)/10)+'0' ((rtxver mod 100) mod 10)+'0' ' ***',cr,lf,lf ' 1 - RAM disk directory 4 - RAM editor',cr,lf ' 2 - Programmer calculator 5 - Terminal',cr,lf ' 3 - RS-232 setup 6 - Remove RTX from memory',term ; extmsg: esc,'3',term ; ;------------------------------------------------------------------------------ ; .xlist if1 .printx ** .printx * RTX RAM Disk * .printx ** endif .list subttl RAM disk directory module page ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; sektrk equ 0F544H seksec equ 0F546H dmaadr equ 0F557H ysizeram equ 0F6A8H ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; direc: ld hl,dirmsg call stout1 call hdline call crlf ld hl,(sektrk) ;Store old track, sector and dma ld (oldtrk),hl ld hl,(dmaadr) ld (olddma),hl ld a,(seksec) ld (oldsec),a ld hl,0 ;Set track=0 ld (sektrk),hl ld hl,rambuf ;Set dma to RTX's ram buffer ld (dmaadr),hl ; ld a,(ysizeram) ;Check RAM disk size cp 64 ;If <64K, ld a,4 ;Then 4 sectors - 16 entries jr c,dir10 add a,a ;else 8 sectors - 32 entries dir10: dec a ;Start with top sector ld (seksec),a ;Store it call readram ;Direct call to RAM disk read routine ld b,4 ;4 entries in this sector, ld hl,rambuf ;starting at the bottom dir20: ld a,(hl) cp 010H ;If byte 0 less than 16 then valid file jr nc,dir40 ;else skip on push hl ld de,12 add hl,de ;Add 12 ld a,(hl) ;Check extent byte or a ;If not zero, pop hl jr nz,dir40 ;then don't display push bc push hl inc hl ld b,8 ;Display 8 characters (filename) call stout2 ld a,' ' ;Output a space call chrout ld b,3 ;Display 3 characters (type) call stout2 ld b,4 ;Output 4 spaces dir30: ld a,' ' call chrout djnz dir30 pop hl pop bc dir40: ld de,020H ;Increment HL for next FCB add hl,de djnz dir20 ;Decrement counter ld a,(seksec) or a ;Done sector 0 yet? jr nz,dir10 ;No, go round again ; ld hl,(oldtrk) ;Restore old tracks etc. ld (sektrk),hl ld hl,(olddma) ld (dmaadr),hl ld a,(oldsec) ld (seksec),a dir50: call getkey ;Wait for ESC keypress before returning jp z,exit ;to main menu cp esc jr nz,dir50 jp restrt ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; dirmsg: cls,'*** RAM Disk Directory ***',term ; ;------------------------------------------------------------------------------ ; subttl RTX PRGCAL module - 30 Nov 86 evd page .8080 ;set m80 for 8080 code .ver set 3 ;version number n.n .mon set 11 ;version date parameters .day set 30 .year set 86 asize equ 16 ;ascii buffer size .comment # px-8 programmers calculator, (c) 1986 evd ops: + add, - sub, * mul, / div, % mod, & and, | or, ^ xor stk: > roll up, < roll dwn, = swap xy, ^X clr stk, BS edit/clrx, CR enter base: \B binary, \D dec, \H hex, \O octal vers: 0.1 11/01/86 initial version 0.2 11/04/86 fixed leadin bug 0.3 11/30/86 mods for time/date disp w/rtx # .xlist ver_pr macro m,d,y,v .printx * version nmbr: v/10 * .printx * version date: m-d-y * endm if1 .printx ** .printx * PrgCal, RTX version * .printx ** ver_pr %.mon,%.day,%.year,%.ver .printx ** endif ; ; some macros for z80 ; m68 style relative ops bra macro lblnam ;branch always (jr) .z80 jr lblnam .8080 endm bcc macro lblnam ;branch carry clr (jr nc) .z80 jr nc,lblnam .8080 endm bcs macro lblnam ;branch carry set (jr c) .z80 jr c,lblnam .8080 endm bne macro lblnam ;branch not equal (jr nz) .z80 jr nz,lblnam .8080 endm beq macro lblnam ;branch equal (jr z) .z80 jr z,lblnam .8080 endm bge macro lblnam ;branch greater or equal, c=clr bcc lblnam endm bls macro lblnam ;branch less, c=set bcs lblnam endm dbnz macro lblnam ;b=b-1, branch b <> 0 .z80 djnz lblnam .8080 endm ; bit test & set ops bit.m macro bitno ;test bitno @(hl) .z80 bit bitno,(hl) .8080 endm set.m macro bitno ;set bitno @(hl) .z80 set bitno,(hl) .8080 endm ; misc ops ld. macro param1,param2 ;generalized z80 load op .z80 ld param1,param2 .8080 endm lsr macro reg ;0 -> (reg) -> carry .z80 srl reg .8080 endm ror macro reg ;same as 'rar' for any reg .z80 rr reg .8080 endm rol macro reg ;same as 'ral' for any reg .z80 rl reg .8080 endm dsub macro regpr ;hl=hl-(reg pair)-carry ora a ;clear carry .z80 sbc hl,regpr .8080 endm .list page ; ; sign on pcal: lxi h,signon call stout1 ;sign on call hdline call dspstk ;display stack & enter command loop ; ; command loop, radix lead-in & op-code routines cmdlop: lxi h,cmdlop push h ;preset return addr lxi h,inpos call stout1 ;set cursor for input call getkey ;get input jz pcalq ;power down exit cpi esc jz pcalx ;exit cpi '>' jz rup ;roll up cpi '<' jz rdwn ;roll down cpi '=' jz swapxy ;exchg x & y cpi cr jz entx ;enter cpi '\' jz leadin ;radix lead-in lxi h,oprtn-1 ;chk for op-codes mvi b,oprtn-opchr ;length clop: cmp m jz ops ;match, do it dcx h dbnz clop ;else cont cpi 'X'-64 jz stkclr ;^X to clear stack cpi bs jz bkspc ;backspace to del entry digit cpi 'a' bls isupr ;upper case or dgt now ani 05fh ;make lower upper isupr: mov b,a ;save ascii cpi '0' rc ;too small cpi ':' bls dgtin ;ok, is 0 - 9 cpi 'A' ;chk A-F rc ;no cpi 'F'+1 rnc ;no sui 7 ;ok, adj dgtin: ani 0fh ;strip ascii lhld radix ;get radix cmp l ;test rnc ;too big mov c,a ;dgt ok: (b)=ascii, (c)= binary push b ;save lxi h,sflag ;get flag addr bit.m 0 ;1=entry in progress now bne dgi1 ;cont entry set.m 0 ;mark entry now bit.m 1 ;1=lift, 0=overwrite beq dgi0 ;ovrwrt call rollup ;lift call dspstk ;and display dgi0: call xclr ;get rid of old data dgi1: pop b ;restore lda sizex ora a ;test regx size rz ;full cpi asize beq dgi2 ;empty, skip shift push b ;save data lxi b,asize-1 ;set count lxi d,regxa+2 ;set destination lxi h,regxa+3 ;set source .z80 ldir ;shift ascii left .8080 pop b ;restore dgi2: lxi h,regxb-1 ;set at lsd of ascii mov m,b ;put in new dgt mvi b,0 ;extend dgt (c) push b ;save input data ld. bc,(regxb) ;get current reg value ld. de,(radix) ;get radix call .mul ;bc= bc*de pop d ;restore input data call .add ;add in: bc= bc+de ld. (regxb),bc ;save lxi h,sizex dcr m ;adj size jmp dspx ;display & return bkspc: lda sizex cpi asize ;empty? jz xclr ;yes, clear x & return mvi a,' ' ;preset mvi b,asize ;set count lxi h,regxa+2 ;set pointer bks0: mov c,m ;get current char mov m,a ;set new mov a,c ;keep inx h ;next dbnz bks0 ;loop cpi ':' ;done: (a) is del char, (hl)= regxb bls bks1 ;is 0-9 sui 7 ;else adj bks1: ani 0fh ;strip ascii mov e,a mvi d,0 ;de= del dgt ld. bc,(regxb) ;get current call .sub ;remove digit (bc= bc-de) ld. de,(radix) call .div ;adj ld. (regxb),bc ;new val lxi h,sizex inr m ;adj for bs jmp dspx ;disp x & return leadin: lxi h,inpos ;(v0.3) call stout1 ;(v0.3) establish position mvi a,'\' ;(v0.3) call chrout ;echo '\' call ldi ;process next input (no rtn: not BDHO) shld rmadr ;set radix msg addr sta radix ;set radix jmp drpx ;then disp stack & return ldi: call getkey ;get char jz pcalq ;special exit ;(v0.3) call chrout ;echo input ani 05fh ;assure upper case cpi 'B' beq isbin ;binary cpi 'D' beq isdec ;decimal cpi 'H' beq ishex ;hex cpi 'O' beq isoct ;oct pop h ;else clear last call ret ;and rtn to cmd loop isoct: mvi a,8 ;radix lxi h,octmsg ;radix message ret isbin: mvi a,2 lxi h,binmsg ret isdec: mvi a,10 lxi h,decmsg ret ishex: mvi a,16 lxi h,hexmsg ret ops: dcr b ;adj position count mov a,b rlc ;*2 mov c,a mvi b,0 ;bc= routine position lxi h,oprtn ;base addr dad b mov a,m ;routine addr low inx h mov h,m ;high mov l,a shld opcode ;install addr in routine ld® bc,(regyb© ;geô data ld. de,(regxb) call 0 ;modified adde opcode equ $-2 ld. (regyb),bc ;setup result jmp drop ;exit w/stk drop pcalx: pop h ;clear stack jmp restrt ;and exit pcalq: pop h jmp exit ;exit after power off ; ; stack routines xclr: call clrx ;clear reg x mvi a,1 sta sflag ;mark entry in progress & overwrite jmp dspx ;disp & rtn stkclr: call clrstk ;clear stk & disp bra entx1 entx: call rollup ;roll up stack ld. (regxb),de ;overwrite x entx1: xra a bra drpx1 drop: call rolldn ;roll down stack ld. (regtb),de ;overwrite t drpx: mvi a,2 drpx1: sta sflag ;mark new entry & lift mvi a,asize sta sizex ;reset ascii length drpx2: jmp dspstk ;disp & rtn rup: call rollup bra drpx rdwn: call rolldn bra drpx swapxy: lhld regxb ;swap x & y ld. de,(regyb) shld regyb ld. (regxb),de bra drpx rollup: ld. de,(regxb) ;get regx lhld regtb shld regxb ;t -> x lhld regzb shld regtb ;z -> t lhld regyb shld regzb ;y -> z ld. (regyb),de ;x -> y ret rolldn: ld. de,(regtb) ;get regt lhld regxb shld regtb ;x -> t lhld regyb shld regxb ;y -> x lhld regzb shld regyb ;z -> y ld. (regzb),de ;t -> z ret ; ; arithmetic & logical routines .add: ;bc+de=bc, bc=de & other regs unchanged xchg dad b push h pop b xchg ret .sub: ;bc-de=bc, other regs unchanged push h push b pop h dsub de ;z80: hl=hl-(reg pair)-carry push h pop b pop h ret .mul: ;bc*de = bc w/de as 16 bit overflow, (a) used & hl unchanged push h ;save hl mvi a,16 ;bit count lxi h,0 ;clear ovrflo push h ;and result mu1: lsr d ;shift multiplier right ror e bcc mu2 ;ls bit is 0 dad b ;else adj bc mu2: ror h ;shift 32 bit answer, ovrflo first ror l xthl ror h ;then result ror l xthl dcr a ;chk bit count bne mu1 xchg ;done, de=overflow (ms 16 bits) pop b ;bc=result (ls 16 bits) pop h ;restore hl ret .div: ;bc/de = bc w/de as remainder, (a) used & hl unchanged push h lxi h,0 ;2s comp of de (0-de) dsub de ;z80: hl=hl-(reg pair)-carry xchg lxi h,0 ;initial remainder mvi a,17 ;init bit count dv0: push h ;save remainder dad d ;subtract divisor (2s comp add) bcc dv1 ;under-flow xthl ;else exchange hl with (sp) dv1: pop h ;restore remainder push psw ;save bit count rol c ;rotate left bc & hl rol b rol l rol h pop psw ;restore bit count and adj dcr a bne dv0 ;cont til zero ora a ;then clr carry ror h ;and adjust remainder ror l xchg ;put remainder in de pop h ret ;quotient in bc .mod: ; bc mod de = de call .div ;do div mov b,d ;set remanider as result mov c,e ret .and: ; bc&de=bc, only bc and (a) changed mov a,c ana e mov c,a mov a,b ana d mov b,a ret .or: ; bc|de=bc, only bc and (a) changed mov a,c ora e mov c,a mov a,b ora d mov b,a ret .xor: ; bc^de=bc, only bc and (a) changed mov a,c xra e mov c,a mov a,b xra d mov b,a ret ; ; radix conversion routine radvrt: push h ;save index (at msd of ascii buffer) call clrg0 ;clear reg push h ;save index (at lsd of ascii buffer) inx h mov c,m inx h mov b,m ;(bc)= reg data lhld radix xchg ;(de)= radix pop h ;restore buffer index rdv0: push d ;save radix divisor call .div ;bc= bc/de, de is remainder mov a,e ;(a) is remainder pop d ;restore radix ori '0' ;rem to ascii cpi ':' bls rdv1 ;is 0-9 adi 7 ;is A or more rdv1: mov m,a ;char to buffer dcx h ;adj mov a,b ora c ;complete? bne rdv0 ;no, loop pop h ;yes, restore msd index ret ; ; stack clear & display routines clrstk: lxi h,regtb ;set at binary reg call clreg ;and clear reg lxi h,regzb call clreg lxi h,regyb call clreg clrx: lxi h,regxb ;x reg entry, fall thru clreg: xra a ;clear (a) mov m,a inx h mov m,a ;clear binary part of reg lxi b,-(asize+1) dad b ;set (hl) to ascii part clrg0: mvi b,asize-1 ;set count clrg1: mvi m,' ' ;clear ascii inx h dbnz clrg1 mvi m,'0' ;last is 0 ret ;rtn (hl)= lsd of buffer dspstk: lhld rmadr ;get addr of radix message call stout1 ;print it lxi h,regta ;index at ascii reg call dspreg ;display reg lxi h,regza call dspreg dspyx: lxi h,regya ;disp x & y entry call dspreg dspx: lxi h,regxa ;disp x entry dspreg: mvi a,esc call chrout ;esc out mvi a,'=' call chrout ;lead for cursor addr mvi b,2 ;set count call dspr1 ;2 chars @(hl) out mvi a,esc call chrout mvi a,'T' call chrout ;clear to end of line call radvrt ;convert reg?b to reg?a mvi b,16 dspr1: mov a,m ;char @ reg?a call chrout ;out inx h dbnz dspr1 ret ; ; data area sizex: db asize ;ascii in reg x sflag: db 2 ; bit 0 bit 1 ;0=new entry 0=no lift radix: dw 10 ;display radix rmadr: dw decmsg ;radix message addr opchr: db '+-*/%^|&' oprtn: dw .add,.sub,.mul,.div dw .mod,.xor,.or,.and signon: db cls,'*** PrgCal ',(.ver/10+'0'),'.',(.ver mod 10+'0'),' ***',term binmsg: db esc,'=',0+32,22+32,'Bin',term octmsg: db esc,'=',0+32,22+32,'Oct',term decmsg: db esc,'=',0+32,22+32,'Dec',term hexmsg: db esc,'=',0+32,22+32,'Hex',term inpos: db esc,'=',6+32,32+32,esc,'T',term regxa: db 6+32,14+32,' 0' regxb: dw 0 ;row,col,ascii,binary regya: db 5+32,14+32,' 0' regyb: dw 0 ;row,col,ascii,binary regza: db 4+32,14+32,' 0' regzb: dw 0 ;row,col,ascii,binary regta: db 3+32,14+32,' 0' regtb: dw 0 ;row,col,ascii,binary .z80 ;back to epson code ; ;------------------------------------------------------------------------------ ; .xlist if1 .printx ** .printx * RTX RS-232 Setup * .printx ** endif .list subttl RS-232 display/setup module page ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; bitrate equ 0F6A9H wl equ bitrate+1 parity equ wl+1 stopbits equ parity+1 special equ stopbits+1 drsdat equ 0F00FH ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; rs232: ld hl,rsmsg call stout1 call hdline ; displ: ld hl,csrbr ;Position cursor call stout1 ld a,(bitrate) ;Get baud rate bit 7,a ;Convert the baud rate to a simple value 0-? jr z,rs10 sub 070H rs10: cp 13 jr c,rs11 sub 6 jr rs12 rs11: rra and 07FH rs12: sub 1 rlca rlca rlca ld l,a ld h,0 ld de,bittbl ;Display baud rate string add hl,de call stout1 ; ld hl,csrwl ;Repeat procedure for word length call stout1 ld a,(wl) add a,035H call chrout ; ld hl,csrpar ;And parity call stout1 ld a,(parity) ld hl,partbl ld de,5 or a jr z,rs20 add hl,de dec a jr z,rs20 add hl,de rs20: call stout1 ; ld hl,csrstp ;And stopbits call stout1 ld a,(stopbits) bit 1,a jr z,rs30 dec a rs30: add a,030H call chrout ; ld hl,csrxon ;And Xon/Xoff flag call stout1 ld hl,yntbl ld a,(special) bit 4,a jr z,rs40 ld de,4 add hl,de rs40: call stout1 ; ld hl,csrdft ;And set-defaults flag call stout1 ld a,(rstdft) ld hl,yntbl or a jr nz,rs50 ld de,4 add hl,de rs50: call stout1 ; rs60: call getkey ;Get user's choice and validate jp z,exit cp esc jr z,rsend cp '1' jr c,rs60 cp ':' jr c,rs70 res 5,a cp 'A' jr c,rs60 cp 'N' jr nc,rs60 sub 7 ; rs70: sub 030H ; ld hl,dattbl-1 ;Get top of data table into HL ld d,0 ld e,a add hl,de ;Add offset calculated from user's entry ld b,(hl) ;Get the value to store into B ld hl,bitrate ;Depending on the keystroke entered, cp 12 ;store the value into the appropriate jr c,rs80 ;memory area (RS-232 work or set-default inc hl ;flag) cp 14 jr c,rs80 inc hl cp 17 jr c,rs80 inc hl cp 19 jr c,rs80 inc hl cp 21 jr c,rs80 ld hl,rstdft ; rs80: ld (hl),b jp displ ;Go round again - redisplay settings ; rsend: ld a,(rstdft) ;Check reset-defaults flag or a jp z,restrt ld bc,5 ;Copy working params to default params ld de,drsdat ld hl,bitrate ldir jp restrt ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; rsmsg: cls,'*** RS-232C Setup ***' esc,'=',2+32,0+32,'bits/second :' esc,'=',3+32,0+32,'data bits :' esc,'=',4+32,0+32,'parity check :' esc,'=',5+32,0+32,'stop bits :' esc,'=',6+32,0+32,'Xon/Xoff :' esc,'=',7+32,0+32,'reset defaults :' esc,'=',2+32,26+32,'1=19200 2=9600 3=4800 5=1200 7=300 A=75/1200' esc,'=',3+32,26+32,'C=7 D=8' esc,'=',4+32,26+32,'E=none F=odd G=even' esc,'=',5+32,26+32,'H=1 I=2' esc,'=',6+32,26+32,'J=yes K=no' esc,'=',7+32,26+32,'L=yes M=no',term ; csrbr: esc,'=',2+32,17+32,term csrwl: esc,'=',3+32,17+32,term csrpar: esc,'=',4+32,17+32,term csrstp: esc,'=',5+32,17+32,term csrxon: esc,'=',6+32,17+32,term csrdft: esc,'=',7+32,17+32,term ; bittbl: '110 ',term '150 ',term '300 ',term '600 ',term '1200 ',term '2400 ',term '4800 ',term '9600 ',term '19200 ',term '1200/75',term '75/1200',term ; partbl: 'none',term 'odd ',term 'even',term ; yntbl: 'yes',term 'no ',term ; dattbl: 15,14,13,12,10,8,6,4,2,129,128,2,3,0,1,3,1,3,239,255,255,0 ; ;------------------------------------------------------------------------------ ; .xlist if1 .printx ** .printx * RTX RAM Editor * .printx ** endif .list subttl RAM editor module page ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; iselbnk equ 0ED29H ldaxx equ 0ECF9H staxx equ 0ECFFH ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ramed: ld hl,redmsg ;Menu call stout1 call hdline call crlf xor a ld (tdup),a ;disable time/date updates ld hl,00100H ;Initial address for dump/set = 0100 ld (curradr),hl ; rmed10: ld a,'-' ;Prompt call chrout rmed20: call getkey ;Key in and validate jp z,exit cp esc jp z,restrt res 5,a ;Upper case cp 'S' jp z,setmem ;S for set cp 'D' jr nz,rmed20 ; dmpmem: call chrout ;D for dump. Echo to screen ld b,4 ;Get 4 hex digits - they're stored in (curradr) call gethex jp z,abort ;If gethex returns Z set, ESC was pressed ; ld c,0 ;Select RAM bank di ;Peace and quiet required for this call iselbnk push bc ld bc,112 ;Read 112 bytes from bank 0 ld de,rambuf ld hl,(curradr) ldir pop bc call iselbnk ;Put back old bank ei ;Open the door to the outside world again ; ld hl,rambuf ;Set up some pointers & counters ld b,7 ;7 rows of 16 bytes ; dmp10: push bc ; ld a,(curradr+1) ;Output address of this row in ascii hex call binhex ld a,(curradr) call binhex ld a,':' call chrout ld a,' ' call chrout ; ld b,16 ;16 bytes push hl ; dmp20: ld a,(hl) ;Output each as ascii hex call binhex ld a,' ' ;Separate with spaces call chrout inc hl djnz dmp20 ; ld a,' ' ;output a couple of spaces call chrout call chrout ; ld b,16 ;16 bytes again, this time in true ascii pop hl ; dmp30: ld a,(hl) cp 020H ;If less than 32 then output a dot jr nc,dmp50 dmp40: ld a,'.' dmp50: cp 0A0H ;If not less than 160 then output a dot jr nc,dmp40 call chrout inc hl djnz dmp30 ; ld a,cr ;End line with CRLF call chrout ld a,lf call chrout ; push hl ld hl,(curradr) ld de,16 add hl,de ;Increment current address ld (curradr),hl pop hl ; pop bc djnz dmp10 ;Repeat for next row ; jp rmed10 ;Restart ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; setmem: call chrout ;Echo the "S" ld b,4 ;Get address call gethex jp z,abort ; set10: ld a,(curradr+1) ;Output address call binhex ld a,(curradr) call binhex ld a,':' call chrout ld a,' ' call chrout ; ld hl,(curradr) ;Output current contents ld c,0 call ldaxx ld (currbyt),a ;Store in current byte call binhex ld a,' ' call chrout ld b,2 ;Get new byte call gethex jp z,abort ld a,(currbyt) ;Store new byte in current address ld hl,(curradr) ld c,0 call staxx inc hl ;Increment address ld (curradr),hl jr set10 ;Go round again ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; abort: ld a,cr ;ESC pressed. Output CRLF call chrout ld a,lf call chrout jp rmed10 ;and restart ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; gethex: ld hl,hexwork ;This subroutine reads hex characters from the ld c,0 ;keyboard (0-9, A-F). If CR is pressed straight ; ;away it returns with (currbyt) and (curradr) hex10: push bc ;unchanged and Z=0. If ESC is pressed it push hl ;returns immediately with Z=1. If hex digits call getkey ;are entered it will not allow RETURN until the pop hl ;correct number have been entered (2 or 4). If pop bc ;2 are entered they go in (currbyt), if 4 they cp esc ;go in (curradr). BS is allowable. ret z cp bs jr z,backsp cp cr jr z,return ld d,a ld a,c cp b jr nc,hex10 ld a,d cp '0' jr c,hex10 cp ':' jp c,hex20 and 11011111B cp 'A' jr c,hex10 cp 'G' jr nc,hex10 hex20: call chrout sub 030H cp 10 jr c,hex30 sub 7 hex30: ld (hl),a inc c inc hl jr hex10 ; backsp: ld a,c or a jr z,hex10 ld a,bs call chrout ld a,deleol call chrout dec c dec hl jr hex10 ; return: ld a,c or a jr z,hex40 cp b jr nz,hex10 ld a,(hexwork) rlca rlca rlca rlca ld d,a ld a,(hexwork+1) add a,d ld (currbyt),a ld c,a ld a,b cp 2 jr z,hex40 ld a,c ld (curradr+1),a ld a,(hexwork+2) rlca rlca rlca rlca ld d,a ld a,(hexwork+3) add a,d ld (curradr),a hex40: ld a,cr call chrout ld a,lf call chrout xor a dec a ret ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; binhex: ld c,a ;This routine outputs a character as two ASCII and 11110000B ;hex characters rrca rrca rrca rrca call bh10 ld a,c and 00001111B bh10: cp 10 jr c,bh20 add a,7 bh20: add a,030H jp chrout ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; redmsg: cls,'*** RAM Editor ***',esc,'3',term ; ;------------------------------------------------------------------------------ ; .xlist if1 .printx ** .printx * RTX Terminal * .printx ** endif .list subttl Terminal emulation module page ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; combuf equ 0FB90H comlen equ 00186H rsflg equ 0F6B8H rsdat equ 0F6A9H yshfdt equ 0F0FEH ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; terminal: ld hl,tmsg1 ;Output header call stout1 call hdline xor a ld (tdup),a ;disable time/date updates ; ld a,(rsflg) ;Serial being used? bit 0,a jr z,term20 ;No ; ld hl,tmsg2 ;Error messgae call stout1 ; term10: call getkey ;Wait for ESC jp z,exit cp esc jr nz,term10 jp restrt ;And return to main menu ; term20: ld hl,tmsg3 ;Cursor on etc. call stout1 xor a ld (local),a ;disable local call getkey ;get ans jp z,exit cp esc jp z,restrt res 5,a ;make upper cp 'Y' jr nz,term21 ;assume half duplex ld (local),a ;else set local term21: ld a,cls call chrout ;clear screen to start ld hl,combuf ;Set up buffer address ld (tdata),hl ld hl,comlen ;Length of COMBUF ld (tdata+2),hl ld bc,5 ;Set up RS-232 parameters ld de,tdata+4 ld hl,rsdat ldir ; ld b,10H ;Open RS-232 ld hl,tdata call rsiox ; term30: ld b,30H ;Data waiting in buffer? ld hl,tdata call rsiox or a jr z,term40 ;No ld b,c ;Yes, get number (<=240) term35: push bc ;Loop to read data and put it onscreen ld b,50H call rsiox call chrout pop bc djnz term35 ; term40: ld a,(ypofst) ;Power switch thrown? ld b,a ld a,(btryfg) ;or low battery? or b jr nz,term45 ;Yes, bale out call const ;Output character waiting? or a jr z,term30 ;No call conin ;Yes, read it ld c,a cp esc ;ESC? jr nz,term50 ;No ld a,(yshfdt) ;SHIFT pressed? and 3 jr z,term50 ;No ; term45: ld b,20H ;Close RS-232 call rsiox jp restrt ;And exit ; term50: push bc ;save char in (c) ld b,60H ;Output char to RS-232 ld hl,tdata call rsiox pop bc ;restore ld a,(local) or a ;test local jr z,term40 ;no local echo ld a,c ;get char cp ' ' jr nc,term55 ;>space, just echo cp bs jr z,term55 ;bs, echo cp lf jr z,term55 ;lf, echo cp cr jr z,term55 ;cr, echo push af ;else save control char ld a,'^' call chrout ;output control marker pop af add a,64 ;make control printable & fall thru term55: call chrout jr term40 ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; tmsg1: cls,'*** Terminal ***',term ; tmsg2: cr,lf,lf,'Serial I/O in use by application program',term ; tmsg3: esc,'=',0+32,24+32,'SHIFT',cr,lf,lf,esc,'3' 'Local? (Y=Yes) ',term local: db 0 ;not 0 for local echo ; ;------------------------------------------------------------------------------ ; .xlist if1 .printx ** .printx * RTX Remover * .printx ** endif .list subttl Remove RTX from memory module page ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; unhook: ld hl,uhmsg1 ;Menu call stout1 call hdline unhk10: call getkey ;Y or ESC allowable jp z,exit cp esc jp z,restrt res 5,a cp 'Y' jp nz,unhk10 ld hl,(sbrwrk) ;If Y, reset CTRL/ESC hook ld (ctrlesc),hl ld hl,uhmsg2 ;And say we've done it call stout1 unhk20: call getkey ;Get a further ESC jp z,exit cp esc jr nz,unhk20 jp restrt ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; uhmsg1: cls,'*** Remove RTX ***',cr,lf,lf,lf 'Confirm removal : Y=yes',term ; uhmsg2: esc,'=',3+32,0+32 'The CTRL/ESC key has been disabled.',cr,lf 'Use CONFIG to recover the user BIOS space used by RTX.',term ; ;------------------------------------------------------------------------------ ; .xlist if1 .printx ** .printx * RTX Support * .printx ** endif .list subttl support routines page .8080 ;set m80 tddisp: lda tdup ;date/time updates allowed? ora a rz ;no push b push d push h ;save regs call dateis ;print date & time pop h pop d pop b ;restore & exit ret hdline: mvi a,255 sta tdup ;enable time/date update lxi h,escmsg call stout1 ;print 'ESC to exit' message call batcap ;print battery capacity dateis: call timeis ;print time lxi h,datpos call stout1 ;position for date lxi h,tdbfr+1 ;mon mvi b,'/' ;seperator call tdcom ;print mon call tdcom ;print day lxi h,tdbfr jmp prtbcd ;print yr & exit timeis: mvi c,0 lxi d,tdbfr call timdat ;get date/time info in buffer lxi h,timpos call stout1 ;position for time lxi h,tdbfr+3 ;hour mvi b,':' ;seperator call tdcom ;prt hr call tdcom ;prt min & fall thru for second prtbcd: mov a,m ;get bcd byte @(hl) rar rar rar rar ;get hi nybble call pbcd1 ;print it mov a,m ;re-get byte pbcd1: ani 0fh ;mask ori '0' ;make ascii jmp chrout ;and output tdcom: call prtbcd ;print bcd byte @(hl) mov a,b call chrout ;print seperator inx h ;for next byte ret batcap: lxi h,bcpmsg call stout1 ;print battery capacity msg mvi c,3 call advcrt ;get battery vltg (*4) rar ;/2 ani 07eh ;mask mov c,a mvi a,07eh ;max vltg (*2) sub c ;max-now cz bcp1 ;special case, 100% mov c,a mvi b,0 ;bc= 16 bit dif lxi h,bcptbl ;base addr dad b ;plus vltg offset mvi b,2 call stout2 ;print (b) bytes @(hl) mvi a,'%' jmp chrout ;print and exit bcp1: push psw ;save mvi a,'1' call chrout ;output lead digit pop psw ret crlf: mvi a,cr ;output crlf call chrout mvi a,lf jmp chrout escmsg: db esc,'=',0+32,30+32 ;row 0, col 30 db 'ESC to exit',term bcpmsg: db esc,'=',0+32,44+32 ;row 0, col 44 db 'Battery at ',term bcptbl: db '0090807060504030201005' datpos: db esc,'=',0+32,62+32,term ;row 0, col 62 timpos: db esc,'=',0+32,72+32,term ;row 0, col 72 tdbfr: ds 11 ;buffer for date/time info tdup: db 255 ;time/date update enable, 0=no update .z80 ;back to epson code stout1: ld a,(hl) ;This outputs a string pointed at by HL to cp 0FFH ;the console - 0FFH is the terminator. HL ret z ;is incremented. call chrout inc hl jr stout1 ; stout2: ld a,(hl) ;This outputs a string pointed at by HL to and 07FH ;the console after stripping the top bit. The call chrout ;number of characters to output are in B - inc hl ;no terminator. Its main use is when printing djnz stout2 ;the RAM disk directory. ret ; chrout: push af ;This saves all regs and outputs the A reg push bc ;to the console. push de push hl ld c,a call conout pop hl pop de pop bc pop af ret ; getkey: call const ;This gets a character from the keyboard. It or a ;will not allow auto power off or any other jr nz,gtky10 ;kind of power off, but will return with Z=1 call tddisp ;display time & date ld a,(ypofst) ;if a power fail (low bat or power-switch) or a ;occurs. Otherwise, it will return with Z=0 jr z,getkey ;and the character in A. xor a ret ; gtky10: call conin ld b,a ;Mental block I had here. How do you clear xor a ;the Z flag while not clobbering A? inc a ld a,b ret ; ;------------------------------------------------------------------------------ ; jumptbl: ;This is where the relocated jump table goes. ; const: jp $ conin: jp $ conout: jp $ rsopen: jp $ opnprinter: jp $ x63c1a: jp $ advcrt: jp $ readram: jp $ xsysscrn: jp $ xusrscrn: jp $ blkflsh: jp $ rsiox: jp $ timdat: jp $ ; ;------------------------------------------------------------------------------ ; tdata: ds 9 sbrwrk: ds 2 curradr: ds 2 currbyt: ds 2 hexwork: ds 4 flgtbl: ds 13 flag: ds 2 seq: ds 2 rstdft: ds 1 oldtrk: ds 2 oldsec: ds 1 olddma: ds 2 ; ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; rambuf: ds 128 ; ;------------------------------------------------------------------------------ ; ; rtxend: if2 .radix 16 print_sym ,%rtxstart print_sym ,%rtxend .printx ** .radix 10 endif subttl *** Macros and Symbols *** end