title IOPACK terminal i/o package ; ; ; equates for assembly ; INCLUDE RSOPT.INC entry actcur,altmsg,blkadd,blkflg entry chkinp,chrout,ckinpb,clears,clrline entry constat,couch,ctoend,ctoen0 entry delay,dsplay,dspmsg,endcur,getif entry inchr,initio,inputc,joc entry msgend,msgrsp,mult,mycur,nmscnl,nxline,nxtcur,ourwid entry poscur,printc,putreq,readbf,rqptr0,smycur,waitif,wtline IF KANJI entry knjtst entry knjchr,knjflg entry chk2nd entry knjout ENDIF ; USER ext hite ;# lines on screen ext wid ;# columns on screen ext clead1 ;cursor position lead in sequence ext clead2 ;cursor position between line nd column ext ctrail ;cursor positon trailing sequence ext cb4lfg ;cursor positon, column before line flag ext linoff ;offset to add to line ext coloff ;offset to add to column ext ivon ;inverse video on sequence ext ivoff ;inverse video off sequence ext delcus ;delay after cursor positioning ext delmis ;miscellaneous delay ext ucrpos ;user cursor position ext ascur ;ascii cursor positioning ext rstflg ;MP/M flag ext cnvkey ;keystroke conversion routine ext inisub,trmini ;init ext unisub,trmuni ;terminate ext memapv,memadr ;memory mapped ext eraeol ;erase to end of line ext uselst ;use last byte of screen ext hibcur,crbliv,hibiv IF KANJI ext rdrst ;H/W specific reader status routine ext knjcpm ;Flag set to 0ffH if running under KANJI CP/M ext sjispr ;Flag set to 0ffH if printer accepts SHIFT JIS ext knjon ;Escape sequence to put CRT into KANJI mode ext konprt ;Escape sequence to put PRINTER into KANJI mode ext knjoff ;Escape sequence to put CRT into ANK mode ext kofprt ;Escape sequence to put PRINTER into ANK mode ENDIF ; OTHER ext ourbyte ;substitution string ext addbase ;add message file base ext indptr ;convert to message pointer ext cmpde IF KANJI IF REDIT ;Only REDIT has use of this printer routine. ext imdos ;Routine used to do PRINTER output ext prtflg ;Flag set when output directed to PRINTER ENDIF ENDIF nx equ 1 ;flag indirect message ml equ 2 ;flag second type indirect message al equ 3 ;flag for answer list follows cx equ 4 ;flag to chain message in another module ul equ 5 ;flag for insert a line of underline pc equ 6 ;flag to restore cursor to this position after dsplay bell equ 7 st equ 8 ;skip to line number following ct equ 9 ;clear to line number following ctrlc equ 3 ctrlh equ 8 ctlz equ 1AH lf equ 0AH cr equ 0DH fs equ 1CH ;field separator rub equ 7fH inputl equ 40H ;input buffer length IF HILITE remvid equ 7FH ;true for HIGHLIGHTING invbit equ 080H ENDIF IF ATEBIT remvid equ 0FFH ;true for 8 BIT CHAR SET invbit equ 0 ENDIF ; ; equates for MP/M calls ; bdos equ 5 diriof equ 6 gtstat equ 0FEH gtchar equ 0FFH page 60 ; ; init addresses, screen images and BIOS addresses ; HL = free space pointer, returned updated by amount used ; initio: push b push d push h ;save free space ptr on top of stack if KEYS call openit ;open keystore capture file ENDIF call getwid sta ourwid lda hibcur sta hibcrf ;set internal hi bit for cursor flag lda hite sta nmscnl ;set number of screen lines to display mov b,a lhld memadr ;set screen addresses for memory mapped shld simage shld rimage call chkmap jnz init1 ;jif memory mapped pop h ;free space ptr shld simage ;alloacte space for screen image mvi c,0 call pntscn shld rimage ;allocate space for request image call ptrscn shld rlflag ;allocate space for request line changed table lda hite mov e,a mvi d,0 dad d push h ;save updated ptr to return lda clead1 lxi h,clead2 add m lxi h,ctrail add m adi 2 sta cpscnt ;cursor position string count init1: lxi d,3 lhld 1 ;get ptr to BIOS start dad d shld conrdy dad d shld conin dad d shld conout ;fall through serial number check IF KANJI dad d dad d dad d ; bios READER input routine Address shld reader ENDIF call inisub ;init with user sub lxi h,trmini call strout ;and user string call delaym ;misc delay call clears ;clear screen pop h pop d pop b ret page ; ; clear screen and screen image ; clears: push h push d push b mvi a,0FFH sta curbyte ;say no internal cursor for memory mapped lhld hite lda ourwid mov h,a xchg mov h,e ;hite dcr h mvi l,0 call poscur ;position cursor at screen end mov b,d ;wid lhld simage shld scnadd clear1: call clear4 ;clear line in screen image (leaving D=0) call chkmap jnz clear2 ;jif memory mapped call clear4 ;clear a line for requested image push h lhld rlflag ;request line flag table dad d ;point byte in table dcx h mov m,d ;clear request change flag pop h mvi c,cr call outc mvi c,lf call outc ;clear line on screen clear2: dcr e jnz clear1 lda hibcrf ora a cnz revidv ;set high bit on so erascr can turn it off lxi h,0 call poscur shld mycur pop b pop d pop h ret ; clear4: mov d,b clear5: mvi m,' ' ;clear sreen image inx h dcr d jnz clear5 ret page ; ; position cursor ; poscur: push h push d push b lda hibcrf ora a jnz pscurv ;jif use hi bit for cursor push h mov e,h ;line mov d,l ;column lda ucrpos ora a jnz pscur4 ;jif user wants to do it lhld actcur ;cursor line and column mov a,e cmp h jnz pscur1 ;jif changed lines mov a,d sub l ;# bytes to move cursor jz pscur3 ;nothing to do mov b,a lda cpscnt cmp b jc pscur1 ;faster to reposition cursor lhld scnadd call sout1 ;output the string jmp pscur3 ; pscur1: lxi h,clead1 call strout ;lead in sequence lhld linoff ;line offset in l, column offset in h dad d mov c,l ;line mov d,h ;column lda cb4lfg ora a jz pscur2 ;jif line before column mov c,h ;column mov d,l ;line pscur2: call pscur7 ;send line (or column if switched) lxi h,clead2 call strout ;in between sequence mov c,d ;column (or line if switched) call pscur7 lxi h,ctrail call strout ;send trailing sequence pscur5: lda delcus call delay ;wait appropriate amount of time pscur3: pop h call setcur pscur6: pop b pop d pop h ret ; ; set registers for ucrpos ; D = column, E = line ; pscur4: push d lxi h,0 mov b,e ;get line mvi c,0 call ptscn0 ;get number of bytes to line start mov e,d ;column mov d,c ;clear D mov b,h ;put number of bytes to line start in BC mov c,l dad d xchg ;number of bytes to position in DE pop h ;line/column in HL call ucrpos jmp pscur5 ; ; send cursor line/column number in C ; DE must be preserved ; pscur7: lhld ascur ;L = 0 or number of acsii digits expected dcr l jm outc ;jif not ascii mov a,c ;line/column number to output mvi h,0 ;extent to 16 bits lxi b,powers dad b ;point last power to use pscur8: mvi c,'0'-1 pscur9: inr c ;get digit here sub m jnc pscur9 add m ;restore mov b,a ;save remainder call outc ;output character mov a,m dcx h ;point next power dcr a ;set Z if end mov a,b ;restore remainder jnz pscur8 ret ; powers: db 1,10,100 ; ; position cursor for memory mapped ; pscurv: call erascr ;erase current cursor call setcur ;set new position mov a,m ;save video at new postion sta curbyte xri invbit mov m,a ;turn on iv for cursor postion jmp pscur6 ; ; set actcur and scnadd ; setcur: shld actcur mov b,h mov c,l call pntscn shld scnadd ;set address in screen ret ; ; positon cursor at screen end for exit ; endcur: lhld ourwid lda hite dcr a mov h,a call poscur call extpos ;restore external cursor positioning call exterm if KEYCAP call closit endif ret ; ; put request into rimage ; DE = address ; ACC = byte ; ptreqa: push b mov c,a xchg call putreq xchg mov a,c pop b ret ; ; put request into rimage ; HL = address ; C = byte ; putreq: lda curbyte inr a jz ptreq1 ;jif not using the high bit for cursor push d xchg lhld scnadd call cmpde ;set z if at cursor position xchg pop d jnz ptreq1 ;jif not at cursor position mov a,c xri invbit mov m,a ret ; ptreq1: call chkmap ;set NZ if mapped jz ptreq2 lda hibiv ora a ;set Z if memory mapped and no inverse video jnz ptreq2 mov a,c ani remvid ;get rid of possible high bit(unless ATEBIT) mov m,a ret ; ptreq2: mov m,c ret page ; ; get screen width ; getwid: lda uselst lxi h,memapv ora m ;set nz to use full screen if mem mapped or USELST lda wid rnz dcr a ret ; ; check mapped ; chkmap: lda memapv ora a ret ; ; exit stuff ; exterm: call unisub ;user's exit sub lxi h,trmuni call strout ;user's exit string delaym: lda delmis ;miscellaneous delay ; ; delay, nunber of ms in ACC ; delay: inr a delay1: dcr a rz call waitf2 jmp delay1 ; ; restore external cursor ; extpos: xra a sta hibcrf ;clear high bit on cursor flag ; ; erase internal cursor ; erascr: lda curbyte cpi 0FFH cnz revidv ret page ; ; reverse state of inverse video ; revid: lda hibiv ora a jnz revidv ;jif use high bit for inverse video lda ivflag ora a jmp ckvid1 ; ; reverse video for memory mapped ; revidv: push h lhld scnadd mov a,m xri invbit mov m,a pop h ret ; ; check inverse video and reverse if it needs it ; ckvid: IF ATEBIT ; (or KANJI) ret ;can't use hi-bit for inverse if ATEBIT ENDIF lda ivflag xra c rp ;ok if both on or both off ; note that clear screen and cursor position ; sequence as well as a cr will turn video off xra c ;restore flag and test ckvid1: jz vidon ;turn it on vidoff: xra a sta ivflag ;off sequnce turns flag off first push h lxi h,ivoff mov a,m ora a jnz vdoff1 lxi h,ivon vdoff1: call chgvid pop h ret ; vidon: push h lxi h,ivon call chgvid pop h mvi a,0FFH sta ivflag ;on sequnce turns flag on last ret ; chgvid: push b call strout ;send off sequence call delaym ;wait pop b ret ; ; output character control string sequence ; ptr in HL ; strout: mov b,m ;count inr b sout0: dcr b rz inx h sout1: mov c,m call outc ;call bios to output the character jmp sout0 ; ; print character in c ; this causes immediate print at mycur, not just a buffer stuff ; it is used only for input character echo ; printc: push h call prntc1 ;display character only if changed pop h ret ; prntc1: lhld mycur call chrout ;put character into request image rc ;not accepted call chkmap jnz movcur ;jif memory mapped call poscur ;position cursor to location before chrout call ; ; output character in C ; joc: call outc ;output the character push h lxi h,actcur inr m ;bump cursor position lhld scnadd mov m,c inx h shld scnadd pop h ret ; movcur: push h lhld mycur call poscur pop h ret page ; ; put character in C into request image ; set cy if character not accepted ; chrout: push h call chrou1 pop h ret ; chrou1: mov a,c cpi cr jz chrou2 cpi ' ' rc ;non-printing lda ourwid dcr a lxi h,mycur cmp m rc ;off screen call reqptr ;get address in rimage call putreq ;put C into request image w/o damaging cursor nxtcur: push h lxi h,mycur inr m lda ourwid cmp m cz nxline pop h xra a ;clear cy ret ; ; next line for outputting cr ; chrou2: call ctoend nxline: lhld mycur inr h xra a ;clear cy mov l,a smycur: shld mycur ret ; ; call BIOS to output character in C ; outc: push h push b push d outc1: call ckvid ;if inverse video needs switching, switch it mov a,c ;some BIOS's need this IF KANJI call KNJOUT ; special routine to handle KANJI otput ; Nb. RET's to CALLer of OUTC in some cases mov a,c ; restore original character ; NOTE: chg'd PUSH/POP order to match imdos rtn's order ENDIF call couch ;BIOS output if not KEYRES call tryinp ;put any waiting input into buffer ENDIF pop d pop b pop h ret page ; ; clear to end of line ; ctoend: push h lhld mycur call ctoehl pop h ret ; ; clear to end of line from position in HL ; ctoehl: push d push b mov d,h mov e,l call rqptr0 ;get request image pointer and set rlflag call ctoen0 ;clear to end line, col in E, rimage ptr in HL xchg shld mycur pop b pop d ret ; ; clear to end of line ; HL = pointer in rimage ; E = col of first byte to clear ; ctoen0: lda ourwid mov b,a ;screen width mvi c,' ' ctoen1: mov a,e ;current cmp b rnc call putreq inx h inr e jmp ctoen1 ret ; ; get request image pointer and set rlflag ; reqptr: lhld mycur rqptr0: push d push b mov a,h call setrlf ;set rlflag unless memory mapped mov b,h mov c,l call ptrscn pop b pop d ret ; ; set rlflag for line number in ACC unless memory mapped ; setrlf: push h push b mov c,a call chkmap jnz strlf1 lhld rlflag mvi b,0 dad b mvi m,80H ;set request flag strlf1: pop b pop h ret page ; ; display message and get responce ; ; HL = message pointer ; B = line number of start ; C = byte to match in responce if nz ; ; restores old cursor position when done ; msgrsp: push h push h lhld mycur xthl msgrs1: call chkinp ;set NZ if input waiting cz msgrs2 ;display message and clear to end of line call inputc ;get responce call msgrs3 ;set nz if nogood jnz msgrs1 ;jif no good mov c,a ;return in C pop h shld mycur ;restore cursor pop h ret ; ; display message at line start ; msgrs2: push h ;save in case responce is no good since dsplay changes push b mvi c,0 call dsplay ;display message at line b pop b pop h ret ; ; set nz if C register is nz and ACC is different ; msgrs3: inr c dcr c ;see if want a special responce rz ;jif any will do cmp c ret ; ; display message at mycur ; dspmsg: push h push b push h lhld mycur mov b,h mov c,l pop h call dsplay pop b pop h ret ; ; display message and clear to end of line ; ; HL = indirect message pointer, returned pointing to message end ; B = line ; C = column ; ; dsplay: push d call indptr ;convert indirect message pointer push h ;save message pointer lxi h,0 shld rescur ;restore cursor to this position if NZ mov h,b mov l,c shld curcol ;set line and column call chkalt ;set NZ if alternate output cz rqptr0 ;get request image pointer unless alternate output xchg ;put rimage pointer in DE pop h mvi b,0 ;starting byte count call dspms1 ;display the message push h ;save pointer to message end lhld curcol shld msgend lhld rescur mov a,h ora l jnz dsply1 ;jif to restore cursor from RESCUR instead lhld curcol shld mycur call chkalt cz ctoend ;clear rest of line unless alternate I/O dsply1: mov b,h ;return in BC as well mov c,l shld mycur ;restore cursor pop h pop d ret ; ; put message on alternate device ; ; HL = message pointer ; DE = address of routine to put a byte ; C = a column, not > screen width ; altmsg: xchg shld altadd ;set output address xchg call dsplay mvi a,0FFH sta altadd+1 ;turn off alternate output ret ; ; set NZ if alternate output ; chkalt: push h lhld altadd inr h ;set Z if altadd = FF00-FFFF pop h ret ; ; put the byte ; altadd equ $+1 putalt: jmp 0FFFFH ;address filled in by putmsg page ; ; display message at HL ; DE = where to put if displaying on terminal ; B = byte count if NZ ; CURCOL = line and column, routine must update ; ; message terminated by zero ; message may contain all sorts of flag bytes ; such as: ; nx chain to next message, adding message file base ; ml count terminated message, length follows ; al answer list follows ; cx chain to next message without adding message file base ; ul insert a line of underlines ; pc restore cursor to here when you're done ; st skip to line, line number follows ; ct clear to line number following ; ; field separator(1Ch) will be displayed as a comma(2Ch) ; dspms1: mov a,m ;get message byte ani remvid ;test for 0/*) = terminators rz IF KANA IF KANJI cpi 7FH ;can't use 80H since it is valid 2nd byte of Kanji ELSE cpi 80h ENDIF rz ENDIF mov a,m inx h cpi al ;answer list flag rz cpi nx cz dspms2 ;another message address follows cpi cx cz dspms3 ;another message follow, but in another module cpi ml cz dspms4 ;count terminated cpi ul cz dspm10 ;insert a line of underlines cpi st cz dspm12 ;skip to cursor line cpi pc cz dspm14 ;save cursor to restore cpi ct cz dspm15 ;clear to cpi cr jz dspms5 cpi fs jz dspm17 ;replace field separator with comma cpi ' ' jc dspms1 ;ignore other non-printing dspms5: call dspms6 ;put byte in ACC mov a,b ora a jz dspms1 ;jif not count terminated dcr b jnz dspms1 xra a ret ; ; nx, cx ; dspms2: ora a ;set NZ for nx dspms3: ; Z set for cx push d ;save rimage pointer mov e,m ;get next message pointer inx h mov d,m inx h xthl ;save to continue xchg cnz addbase ;add message file base for nx call dspms1 ;display message pop h ;and continue xra a ;to go back to dspms1 ret ; ; ml ; dspms4: mov b,m ;get length inx h xra a ;to go back to dspms1 ret ; ; put byte in ACC ; dspms6: call chkalt jnz putalt ;alternate I/O cpi cr jz dspms9 ;jif cr dspms7: call ptreqa ;put character into terminal request image dspm7a: inx d ;request image pointer push h lxi h,curcol inr m ;bump column lda ourwid sub m jnz dspms8 mov m,a ;clear column inx h inr m ;new line mov a,m ;line number call setrlf ;set rlflag xra a ;return Z set if new line dspms8: pop h ret ; ; do cr ; dspms9: mvi a,' ' call dspms7 ;put byte in ACC, returning Z set if new line jnz dspms9 ;do while col <> 0 ret ; ; ul = do underline ; dspm10: lda curcol ora a cnz dspms9 ;if not at line start, do new line dspm11: mvi a,'=' call dspms7 jnz dspm11 xra a ;to go back to dspms1 ret ; ; st = skip to line number ; dspm13: call dspms9 ;do cr dspm12: lda curline ;get current line number cmp m ;set CY if line to go to is higher jc dspm13 ;skip to next line inx h ;point next byte xra a ;to go back to dspms1 ret ; ; rc = save current cursor position to restore later ; dspm14: push h lhld curcol shld rescur pop h xra a ;to go back to dspms1 ret ; ; ct = clear to line ; dspm16: call dspm7a ;skip byte jnz dspm13 ;do while not at line end dspm15: lda curline ;get current line number cmp m ;set CY if line to go to is higher jc dspm13 ;skip to next line inx h ;point next byte xra a ;to go back to dspms1 ret ; ; replace field separator with comma ; dspm17: mvi a,',' ;ACC = comma jmp dspms5 ;display it page ; ; read into buffer from terminal ; ; HL = pointer to buffer, count in first byte ; returns number of bytes entered in second byte ; data starting at third byte ; readbf: push h push d push b mov b,m ;buffer length inx h push h inx h mvi e,0 ;number of characters entered readb1: call inputc ;get a charcter ani remvid cpi rub jnz readb0 mvi a,ctrlh readb0: cpi ' ' ;printing? jc readb3 IF KANJI push psw lda knjflg ora a ;Kanji character ? jz readb7 ;no - an 8-bit character, skip down lda knjchr+1 ;yes - load first byte of Kanji character mov m,a ;save in buffer inx h ;increment buffer pointer mov c,a call printc ;echo first byte of Kanji lda knjchr ;load 2nd byte of Kanji character mov m,a ;save in buffer inx h mov c,a call printc ;echo 2nd byte of Kanji inr e ;increment byte count dcr b ;buffer = length-1 pop psw jmp readb6 ;skip down readb7: pop psw ENDIF mov c,a call printc ;echo mov m,c inx h IF KANJI readb6: ENDIF inr e dcr b jnz readb1 readb2: pop h mov m,e ;count pop b pop d pop h ret ; ; control charcter ; readb3: cpi ctrlc jnz readb5 mov m,a inr e dcr b jz readb2 inx h mvi m,0 jmp readb2 ; readb5: cpi cr mvi m,0 jz readb2 call readb4 jmp readb1 ; ; process control h ; readb4: cpi ctrlh rnz ;ignore all others mov a,e ora a rz push h IF KANJI dcr a ;set offset in buffer dcx h ;go back to previous byte call chk2nd ;is it the 2nd byte of a Kanji? jnc redb41 ;jif not lxi h,mycur ;address current cursor position dcr m ;set cursor back to 2nd byte of Kanji mvi c,' ' ;load a space character call printc ;overwrite 2nd byte with a space (cursor updated) dcr m ;set cursor back again pop h ;restore buffer address dcx h ;back to 2nd byte of kanji push h ;and save it again inr b ;increment buffer length dcr e ;decrement input count redb41: ENDIF lxi h,mycur dcr m ;backspace mvi c,' ' call printc dcr m ;backspace pop h dcx h inr b dcr e ret page ; ; clear number of lines in ACC ; starting line number in B ; clrlin: push h mov h,b clrln1: mvi l,0 push psw call ctoehl ;clear to end of line pop psw inr h dcr a jnz clrln1 pop h ret page ; ; input character without echo and by the way, display any lines that are ; flagged if there's no character waiting ; inputc: call ckinpb ;check input ready cz ckline ;display output requests until input is received jnz getif ;get if there call movcur ;move cursor to mycur if not KEYRES lda blkflg ora a jnz input2 ;jif to blink between mycur and blkadd ENDIF call testiv cp getinp ;just get character if no blink (avoid hogging MP/M) input1: call getif IF KANJI push b mov b,a ; Save current content of A lda knjflg ora a ; did we just input a Kanji character? mov a,b pop b ; Restore content of A jz input3 lda knjchr+1 ; If YES, load 1st byte of KANJI into A input3: ora a ENDIF rnz ;character is input call blink ;blink if on or next to inverse video jmp input1 ; ; blink between mycur and blkadd while awaiting input ; input2: call getif rnz push h call blinkb ;blink between pop h jmp input2 ; ; set minus if on or next to inverse video ; testiv: IF HILITE lda crbliv ora a rz ;don't have to blink next to inverse video push h push b lda actcur mov c,a lhld scnadd ;point current position inr c mov b,m call chkmap jz tstiv3 lda curbyte mov b,a tstiv3: lda ourwid cmp c mov a,b jz tstiv0 ;skip if at line end inx h ora m dcx h tstiv0: dcr c jz tstiv1 ;skip if at line beginning dcx h ora m tstiv1: ora a pop b pop h ret ELSE xra a ret ENDIF page ; ; blink cursor in place ; blink: call blink1 blink1: call revid ;reverse state of inverse video blink2: push b mvi b,2 blink3: xra a call waitif jnz blink0 ;character ready dcr b jnz blink3 blink0: pop b ret ; ; blink cursor between mycur and blkadd ; blinkb: mvi a,80H call waitif rnz ;already have input lhld blkadd call blink4 lhld mycur blink4: call poscur call blink2 ;wait ret ; ; wait unless character is ready ; ; count in ACC ; waitif: call waitf2 rnz dcr a jnz waitif ret ; waitf2: push b mov c,a xra a waitf3: dcr a jnz waitf3 call chkinp mov a,c pop b ret ; ; bump pointer for wrap around buffer ; bumptr: push psw inx h mov a,m cpi 0FFH ;test if buffer end jnz bumpte lxi h,inputb bumpte: pop psw ret page ; ; get character into ACC if one is waiting ; else return Z flag set ; getif: call chkinp ;if any input waiting, stuff buffer rz push h lhld loadp mvi m,0 ;say we got it IF KANJI push psw ;save character lda knjin1 ;Kanji character ? sta knjflg ;reflect flag to Kanji flag for multiple entry cases ora a jz getif1 ;no - skip down call bumptr ;yes bump pointer mvi m,0 ;say we got it xra a ;initialise flag sta knjin1 getif1: pop psw ;restore character ENDIF call bumptr ;bump ptr shld loadp pop h ora a ret ; ; set nz if input waiting ; chkinp: call tryinp ckinpb: push h lhld loadp mov a,m IF KANJI call knjtst ; check if current byte (in A) is kanji byte jnc ckinpc ; If NOT Kanji, skip down mvi a,0ffH ; ELSE set KNJIN1 flag sta knjin1 ; + do the rest... mov a,m ; restore character sta knjchr+1 ; save Kanji hi-byte call bumptr ; bump pointer mov a,m ; sta knjchr ; save Kanji lo-byte lda knjchr+1 ; ensure we have 1st byte of Kanji in ACC on return ckinpc: ENDIF pop h ora a ret ; ; get input ; getinp: call ckinpb ;don't bother waiting if character already there rnz push h push d push b if KEYRES ;for replay from log file lda suppbf ;suppress buffer flag ora a jnz getin0 ;jif suppressed call restit jmp getin1 ;put character ELSE jmp getin0 ENDIF ; ; if console ready, put character into buffer ; returns character in ACC ; tryinp: push h push d push b call constat IF KANJI jz tryknj ; try Kanji tablet after CONsole try01: ;check console status getin0: call constat ;input ? jz tryin2 ;no check reader call inchr ;get input call knjtst ; Check if byte in A is in Kanji Range jnc try01a ;no - 8-bit character skip down sta knjchr+1 ;save hi-byte Kanji call inchr ;read second Kanji byte ani remvid ; jz tryin1 sta knjchr ;save Kanji lo-byte jmp bpknj1 ;exit to Kanji store routine try01a: ani remvid ;remove the high order bit (for 7-bit char sets) jnz try04 jmp tryin1 ;---------------------------------------------------------------- ; TRYKNJ -- Check Reader (Kanji Tablet) Status ; If RDY read Kanji code into KNJCHR ; tryknj: call rdrst ;check reader status ora a ;Kanji input ? jz tryin1 ;no - jif not ready jmp tryin3 ;yes - get input tryin2: call rdrst ora a jz try01 ;loop for 'conin' equivalent tryin3: call rdrin ;get input from Kanji tablet ani 7fH ;strip Kanji hi-bit jz tryin1 sta knjchr+1 ;save hi-byte of Kanji character ;---------------- ; Timout for 2nd byte of Kanji from Tablet controlled here... ; mvi b,80 ;counter for timeout loop (80 ms delay) tryin4: lda rdrrdy ;timer loop for second Kanji byte ora a ;check for second Kanji byte jnz tryin5 ;success, second byte ready - skip down mvi a,1 ;units for delay in msec call delaya ;snooze dcr b ;decrement counter jnz tryin4 ;not timed out - skip up pop b ;timed out - no second byte jmp tryin2 ;discard first byte and try again tryin5: xra a sta rdrrdy ;reset reader ready flag call rdrin ;(Kanji characters are two bytes) ani 7fH jz tryin1 sta knjchr ;save lo-byte of Kanji character ; ; push h ;JIS 1 to Shift JIS conversion lhld knjchr ; input JIS-1 code in HL call PCONV ; returns Shift JIS code back in HL bmpknj: shld knjchr ;save shift JIS Kanji character pop h bpknj1: lhld storep ;current pointer lda knjchr+1 mov m,a ;save hi-byte Kanji call bumptr ;increment current store pointer for first Kanji byte lda knjchr mov m,a ;save lo-byte Kanji call bumptr ;increment current store pointer for second Kanji byte shld storep ;update current store pointer jmp tryin1 ;exit try04: ELSE jz tryin1 ;jif not ready getin0: call inchr getin1: ora a jz tryin1 ENDIF IF XLATSP cpi 0A0H ;test if KANA space jnz getin2 ;j if not - skip translation mvi a,' ' ;replace with ASCII space getin2: ENDIF lhld storep ;current store pointer mov m,a ;store in buffer call bumptr ;bump pointer shld storep ;new store pointer tryin1: pop b pop d pop h ret page ; ; BIOS I/O ; consta: lda rstflg ora a ;set NZ if MP/M jnz mpmsta conrdy equ $+1 call 0 ;check console ready in BIOS ora a ret ; inchr: lda rstflg ora a ;set NZ if MP/M jnz mpmchr conin equ $+1 call 0 ;get input conin1: call cnvkey if KEYCAP jmp saveit endif if KEYRES cpi ctlz lxi h,suppbf jz conin2 ;toggle suppbf on ctlz inr m dcr m rnz ;ok if input from console xra a ;else ignore endif ret ; conout equ $+1 couch: call 0 ret IF KANJI ; ; Input from Reader Device ; reader equ $+1 rdrin: call 0 ret ENDIF ; ; MP/M I/O ; mpmsta: mvi e,gtstat mpmcll: mvi c,diriof call bdos ora a ret ; mpmchr: mvi e,gtchar call mpmcll jmp conin1 ; ; display all output requests while awaiting input ; returns ACC nz if input found ; ckline: mvi a,0FFH jmp cklin0 ; ; display all output requests ; wtline: xra a cklin0: sta cklinf call chkmap jnz ckinpb ;memory mapped (nothing to do) push h push d push b lhld rlflag lxi b,0 ;line number cklin1: mov a,m ora a cm cklin2 ;jif need to display a line jnz cklini ;aborted with input mvi m,0 inx h inr b lda hite cmp b jnz cklin1 cklini: pop b pop d pop h ret ; cklin2: push h push b call ptrscn xchg ;request image call pntscn ;screen image call ckeol ;locate erase to end of line sta eolcol ;column to do erase to end of line on cklin3: ldax d IF KANJI call knjtst ;is this the first byte of a Kanji? jnc ckln31 ;jif not cmp m ;is it same as what is on the screen? jnz ckln31 ;jif not - need to display it inx d ;bump rimage pointer inx h ;bump siamge pointer inr c ;increment current column number ldax d ;get 2nd byte of Kanji cmp m ;is it same as what is on the screen? jz ckln31 ;jif yes - no need to display it dcx d ;unbump rimage pointer dcx h ;unbump siamge pointer dcr c ;decrement current column number mov a,m ;get simage byte dcr a ;ensure that it won't match one in rimage ckln31: ENDIF cmp m cnz cklin6 ;display string jnz cklin4 ;jif to interrupt with input inx d inx h inr c lda ourwid dcr a cmp c jnc cklin3 xra a cklin4: pop b pop h ret ; ; locate any erase to end of line ; ckeol: lda eraeol dcr a rm ;since hardware not present push h push d lda ourwid mov l,a mvi h,0 xchg dad d ;point end of line ckeol1: dcx h mov a,m cpi ' ' jnz ckeol2 inr d dcr e jnz ckeol1 ckeol2: mov a,d sui 4 jc ckeol3 ;not worth it mov a,e ckeol3: pop d pop h ret ; ; display string starting at DE until matches string at HL ; cklin6: push h mov h,b mov l,c call poscur ;position cursor pop h IF KANJI xra a sta knj1st ;clear 1st byte of Kanji flag cklin7: lda knj1st ;was previous byte 1st of a Kanji character? ora a jz ckln71 ;jif not xra a ;else sta knj1st ;clear flag jmp ckln74 ;and jump to display 2nd byte of Kanji ckln71: ldax d ;get rimage byte call knjtst ;is it in the Kanji range? jnc ckln72 ;jif not lda ourwid ;else get screen width dcr a ;minus 1 cmp c ;are we at the 2nd last column on the screen? mvi a,' ' ;will replace 1st byte of Kanji with a space if so jz ckln75 ;jif at 2nd last column - not room for Kanji so space sta knj1st ;else set flag to say 1st byte of Kanji character jmp ckln73 ;jump to display 1st byte of Kanji ckln72: cmp m ;is byte already on screen? rz ;return if so - no need to display it ckln73: lda eolcol ;get eol column number inr c ;increment current column number cmp c ;are we at eol column? jc ctoenh ;jif time for erase to end of line dcr c ;decrement current column number again ckln74: ldax d ;get rimage byte ckln75: inr c ;increment current column number ELSE cklin7: ldax d cmp m rz lda eolcol inr c cmp c jc ctoenh ;time for erase to end of line ldax d ENDIF push b mov c,a call joc ;output character pop b call ckinpb ;set flag nz if input waiting IF KANJI push psw ;save ACC and flags jz ckln76 ;jif no input waiting lda knj1st ;need to check if in middle of Kanji output ora a jz ckln76 ;jif not pop psw ;get flags xra a ;ensure Z set to ignore waiting input push psw ;reset flags ckln76: pop psw ENDIF cnz cklin8 ;if input waiting, clear nz if unconditional display rnz ;input waiting and we want to stop if so inx h inx d lda ourwid cmp c jnz cklin7 ret ; cklin8: lda cklinf ora a ret ; ; do erase to end of line ; ctoenh: mov l,a ;eolcol mov c,a mov h,b call poscur call pntscn ctoen3: mvi m,' ' inx h inr c lda ourwid cmp c jnz ctoen3 lxi h,eraeol call strout call delaym call chkinp ;check for input ready now cnz cklin8 mvi c,0FEH ret ; cklinf: ds 1 ;nz to abort on input waiting eolcol: ds 1 ;column to do erase to end of line on page ; ; point to screen image ; BC = cursor position ; ptrscn: lhld rimage jmp ptscn0 ; pntscn: lhld simage ptscn0: push d push b push psw lda ourwid push h call mult ;DE = ACC*B+C pop h dad d ;add offset pop psw pop b pop d ret ; ; multiply DE=A*B+C ; mult: mov l,a xra a mov h,a ;HL = # columns in screen mov d,a mov e,c ;DE = # columns in cursor position mov a,b ;number of lines ptscn1: rar jnc ptscn2 ;jif multiply bit is off xchg dad d xchg ;add power to total ptscn2: dad h ;shift HL left ora a ;test for done jnz ptscn1 ret page IF KANJI ; ;Kanji delay counter. Delay ACC milliseconds ; delaya: inr a delayl: dcr a rz ;rif number of milliseconds done push psw ;save millisecond counter ;delay 1ms or more xra a ;init counter for 256 inner loops nop ;patch space - use mvi a,xx for other counts delil: dcr a ;2.5 microseconds on 8080 push psw call rdrst ;check reader status ora a jnz delix ;yes - skip down pop psw ;no - continue delay nop jnz delil ;5.0 microseconds on 8080 - 7.5 microseconds jmp delix1 ;per loop times 256 = 1.920 ms on 8080 delix: mvi a,1 ;set reader ready flag sta rdrrdy pop psw delix1: pop psw jmp delayl ;loop on outer loop ; ; ; check if byte in ACC is the first byte of a Kanji char. If it is ; return with CY set. ; knjtst: cpi 80H ;is char < Kanji S-JIS 1 range? cmc rnc ;return if so - ASCII cpi 0A0H ;is char in Kanji S-JIS 1 range? rc ;return if so - KANJI cpi 0E0H ;is char < KANJI S-JIS 2 range? cmc rnc ;return if so - KATAKANA cpi 0FDH ;is char in KANJI S-JIS 2 range? ret ;CY set if KANJI PAGE ;--------------------------------------------------------------- ; CHK2ND -- CHECK IF 2ND BYTE OF KANJI ; This routine checks if the byte pointed to by HL is the 2nd byte ; of a KANJI character. The values required for this routine are: ; HL pointer to byte to be checked ; A offset from start of string (e.g., current line) ; ; Returns CY set to 1 if byte is 2nd byte of KANJI ; chk2nd: push b push h mvi b,0 ; reset counter mov c,a ; offset to byte into C ora a jz ck2nd2 ; jif at beginning of string (can't be 2nd byte of knj) mov a,m cpi 40H ; 2nd byte of Kanji cannot be < 40H jc ck2nd2 ; If it is < 40, return w/o CY set ck2nd1: dcx h ; point to previous byte mov a,m ; get byte into A (for KNJTST) call knjtst ; check if this byte is within KANJI range jnc ck2nd2 ; jif NOT IN Kanji range (1st byte must've been an ANK) inr b dcr c ; 1 byte closer to the beginning of string jnz ck2nd1 ; loop till AT beginning of string ck2nd2: mov a,b ; move counter into A rar ; check if odd or even bytes traversed (CY=1 if odd) pop h pop b ret ; CY=1 if byte pointed to by HL was 2nd byte of KANJI PAGE ;---------------------------------------------------------------- ; KANJI OUTPUT HANDLED HERE, including... ; Shift-Jis to Jis conversion for Non-Kanji CP/M terminals & printers. ; ; This is part of the output character routine in IOPACK ; to convert shift JIS Kanji into standard JIS code (for non KANJI ; CP/M's) and output the converted KANJI code. In addition, ; it handles the outputting of ESCAPE SEQUENCES to control screen ; and printer image (for non-KANJI CP/M's). ; Major variables used: ; KNJCPM In user area. If non-zero, it indicates ; machine is running under KANJI CP/M, and ; no processing will be undertaken by this ; routine. If zero, the machine is running ; non-kanji CP/M, and this routine will be ; executed. ; KNJON String in user area for the ESCAPE SEQUENCE ; to turn the terminal to KANJI ON mode. ; KNJOFF String in user area for the ESCAPE SEQUENCE ; to turn the terminal to ANK (KANJI OFF) mode. ; ; Major routines called: ; ZITKNJ Checks whether byte in A is in range of 1st ; byte of KANJI. If K2MASK mask is 0, this ; always returns false. ; ONKNJ This sends the ESCAPE SEQUENCE to turn the ; CRT (or PRINTER) to KANJI ON mode. The string ; is sent only when a transition occurs from ANK ; to KANJI. ; OFFKNJ This sends the ESCAPE SEQUENCE to turn the ; CRT (or PRINTER) to ANK mode. The string is ; sent only when a transition occurs from ; SJ2JIS KANJI to ANK. Converts 2 byte Shift JIS ; into 2 byte standard JIS. ;---------------------------------------------------------------- ; KNJOUT: lda K2MASK ; If this mask is 0 this means the byte in C ora a ; is the 2nd byte of Kanji and 1st byte is jnz NOT2nd ; stashed in KBYTE1 process these mov a,c sta KNJCH2 ; take this byte and store it w/1st byte mvi a,0ffh sta K2MASK ; set K2MASK mask back to all 1's call OUTKNJ ; OUTPUT KANJI 2byte pair... ret ;---------------- NOT2nd: mov a,c call ZITKNJ ; Have we come by 1st byte of KANJI? ; NB. KNJFLG is NOT set most of the time ; so MUST check this for every char. jnc OUTC1a ; No.. skip down sta KNJCH2+1 ; Yes.. It is 1st byte KNJ. Stash it away. xra a ; Toggle mask byte for sta K2MASK ; ZITKNJ so 2nd byte isnt tagged as KNJ inx sp inx sp ; (skip output... return to caller of OUTC or IMDOS) pop d pop b ; (also clear off the stack for OUTC or IMDOS) pop h ret ; Wait till 2nd byte to output stuff. ;---------------- ; OUTKNJ: ; output Kanji and escape sequences here. The logic below for sending ; escape sequences and converting to JIS is as follows: ; Let x :: PRFLAG Flag says output is to PRINTER ; Let y :: SJISPR Flag says CP/M printer driver accepts Shift-JIS ; Let x :: KNJCPM Flag says program is running under KANJI CP/M ; Let s :: 1 if OUTPUTTING ESCAPE SEQUENCE and CODE CVT, ; 0 if not ; ; x y z s ; ----------------- ; | 0 | 0 | 0 | 1 | ; ----------------- ; | 0 | 0 | 1 | 0 | ; ----------------- ; | 0 | 1 | 0 | 1 | ; ----------------- ; | 0 | 1 | 1 | 0 | ; ----------------- ; | 1 | 0 | 0 | 1 | ; ----------------- ; | 1 | 0 | 1 | 1 | ; ----------------- ; | 1 | 1 | 0 | x | ; ----------------- ; | 1 | 1 | 1 | 0 | ; ----------------- ; lda KNJCPM ; check if running under KANJI CP/M ora a cz ONKNJ ; Don't do anything for KANJI CP/M IF REDIT jz OUTKJ0 ; Output KANJI-ON ESC SEQ for Non KNJ CP/M lda PRTFLG ; cma ; if PRINTING and PRINTER not lxi h,SJISPR ; handled by KANJI CP/M then do our ora m ; own code conversion and ESCAPE SEQUENCE cz ONKNJ ; outputting to PRINTER OUTKJ0: ENDIF lhld KNJCH2 cz SJ2JIS ; Don't do anything for KANJI CP/M ; Convert to standard JIS for Non KNJ CP/M IF REDIT lda PRTFLG ora a ; Is output directed to PRINTER? jz OUTKJ1 ; mov e,h ; ** push h ; ** mvi c,05 ; ** call bdos ; ** These 6 lines for PRINTER output pop h ; ** mov e,l ; ** jmp OUTKJ2 OUTKJ1: ENDIF mov c,h ; @@ These 5 lines for CRT output push h ; @@ call COUCH ; @@ Output 1st byte of KANJI code pop h ; @@ mov c,l ; @@ OUTKJ2: OUTC1a: lda KNJCPM ; If not running under Kanji CP/M... ora a cz OFFKNJ ; Turn off KANJI MODE on CRT if necessary IF REDIT jz OUTKJ9 lda PRTFLG ; cma ; if PRINTING and PRINTER not lxi h,SJISPR ; handled by KANJI CP/M then do our ora m ; own ESCAPE SEQUENCE cz OFFKNJ ; outputting to PRINTER OUTKJ9: ENDIF ret PAGE ;---------------------------------------------------------------- ; ONKNJ -- This routine sends an ESCAPE SEQUENCE to switch the CRT ; into the KANJI ON mode, when necessary (i.e., when a ; transition occurs between ANK characters and KANJI). ; The point at which to issue is determined by KNJCRT, ; a flag indicating which mode the CRT is currently in. ; If KNJCRT is zero then the CRT is switched to KANJI and ; KNJCRT is set non-zero. Also it sets CNTBYT, a counter ; which is used to count down the number of characters ; before any KANJI off ESCAPE SEQUENCE can be issued. (See ; OFFKNJ routine) ONKNJ: PUSH PSW PUSH H ; *** Save Registers *** PUSH B ; EVERYTIME ONKANJI IS CALLED SET CNTBYT TO 2+ length of esq seq. ; CNTBYT IS DCR'D IN OFFKNJ. WHEN IT REACHES 0, KNJOFF SEQ ; IS ACTUALLY OUTPUT TO CRT MVI A,2 ; KANJI BYTE1 INDICATOR. STA CNTBYT LDA KNJCRT ORA A ; NO NEED TO TURN KANJI ON IF ALREADY ON JNZ ONK2 CMA ; TURN ON A KANJI FLAG STA KNJCRT ; IF REDIT lda PRTFLG ; Check if output directed to PRINTER ora a jz ONK0 lxi h,KONPRT ; ** This is the string for PRINTER OUTPUT jmp ONK1 ONK0: ENDIF LXI H,KNJON ; @@ This is the String for CRT OUTPUT ONK1: LDA CNTBYT ADD M ; ADD # OF CHARS IN KNJON ESQ SEQ STA CNTBYT ; THIS IS # OF TIMES WE CAN SKIP ON/OFF SEQ CALL STRCRT ; OUTPUT KANJI SEQUENCE (ADDR IN HL) ONK2: POP B POP H ; *** Restore Registers *** POP PSW RET PAGE ;---------------------------------------------------------------- ; OFFKNJ - This routine is used to switch the CRT into the ANK mode ; when necessary, i.e., when a transition occurs from a KANJI ; character to an ANK. The output the ESCAPE SEQUENCE for ; this operation is governed by the variable CNTBYT which ; counts down the number of bytes to let by before this ; routine can be allowed to output. In order to localize ; the output of all characters to the JOC routine we must ; call JOC recursively, which means this routine may be ; called, for instance, while it is outputting its ESCAPE ; SEQUENCE. This counter assures that during such operations ; such confusion will not occur. ; The routine finally outputs the ESCAPE SEQUENCE when CNTBYT ; is dcr'd to 0. However, to avoid outputting redundant ESCAPE ; sequences, it will only output when CNTBYT reaches 0 and NOT ; when CNTBYT IS 0. OFFKNJ: PUSH PSW PUSH B ; *** Save Registers *** PUSH H ; BYTETYPE IS DCR'D ONCE EACH TIME THIS ROUTINE CALLED TILL IT ; REACHES 0. LDA CNTBYT ORA A JZ OFFK2 ; RETurn if CNTBYT IS 0 DCR A STA CNTBYT JNZ OFFK2 ; RETurn if CNTBYT wasnt 1 before DCR STA KNJCRT ; TURN OFF KANJI FLAG (A=0 FROM ABOVE) IF REDIT lda PRTFLG ora a ; Check if output directed to PRINTER jz OFFK0 lxi h,KOFPRT ; ** This string is for PRINTER OUTPUT jmp OFFK1 OFFK0: ENDIF LXI H,KNJOFF ; @@ This string is for CRT OUTPUT OFFK1: CALL STRCRT ; OUTPUT KNJOFF ESC SEQ (ADDR IN HL) OFFK2: POP H POP B ; *** Restore Registers *** POP PSW RET PAGE ;---------------------------------------------------------------- ; PCONV -- ROUTINE TO CONVERT FROM JIS TO Shift-JIS ; ; INPUT: JIS CODE IN REGISTER: HL ; OUTPUT: Shift-JIS CODE IN REGISTER: HL ; ; Clobber Register A ; PCONV: mov a,h cpi 21H ;compare Kanji hi-byte (if HL = 2121H) jnz pconv5 ; (then area VI') mov a,l cpi 21H ; (HL = 2020H) jnz pconv5 ; (else code is) mvi a,20H sta knjchr ; (in another area) sta knjchr+1 ret pconv5: mov a,l adi 1fH ; L:=L+1FH mov l,a mov a,h rar ; H:=H DIV 2 mov h,a jc pconv0 ; if H MOD 2=0 dcr a ; then H:=H-1 mov h,a mov a,l adi 5EH ; L:=L+5EH mov l,a pconv0: mov a,l cpi 7FH ; (if L >= 7FH) jc pconv1 ; (then L:=L+1) inr l pconv1: mov a,h cpi 2EH ; (if H < 2FH) jnc pconv2 ; (then H:=H+71H) adi 71H mov h,a ret pconv2: adi 0B1H ; (else H:=H+B1H) mov h,a ret page ;---------------------------------------------------------------- ; SJ2JIS -- ROUTINE TO CONVERT FROM SHIFT JIS TO JIS ; ; INPUT: SHIFT JIS CODE IN REGISTER: HL ; OUTPUT: JIS CODE IN REGISTER: HL ; ; CLOBBERS REGISTER A SJ2JIS: MOV A,H CPI 80H ; IF HI = 80H RZ ; THEN GAIJI (NOT HANDLED HERE) CPI 0A0H ; ELSE JNC OSJ1 ; IF HI < A0H SUI 070H ; THEN HI = HI - 70H MOV H,A JMP OSJ2 ; OSJ1: CPI 0F0H ; ELSE RNC ; IF HI < F0H SUI 0B0H ; THEN HI = HI - B0H MOV H,A ; ELSE GAIJI OSJ2: MOV A,L ; IF LO <= 80H ORA A ; THEN JP OSJ3 ; LO = LO - 1 DCR L OSJ3: MOV A,H ADD H ; HI = HI * 2 MOV H,A MOV A,L CPI 9EH ; IF LO >= 9EH JC OSJ4 ; THEN SUI 5EH ; LO = LO - 5EH MOV L,A JMP OSJ5 ; OSJ4: DCR H ; ELSE HI = HI - 1 OSJ5: MOV A,L SUI 01FH ; LO = LO - 1FH MOV L,A RET PAGE ;---------------------------------------------------------------- ; ZITKNJ -- Checks whether current character is first byte of ; KANJI. To avoid false detection on 2nd byte, K2MASK ; is used-- if K2MASK is 0 then no detection occurs. ; Input: A Contains the byte to be checked ; Output: CY Flag set if 1st byte KANJI detected ; Cleared otherwise ZITKNJ: PUSH PSW PUSH H ; SAVE PSW SO WE DONT CHANGE ANY OTHER FLAG LXI H,K2MASK ANA M ; IF K2MASK IS 0 THIS'LL INHIBIT KANJI POP H ; DETECTION. K2MASK CLEARED ONLY WHEN ; ZITKNJ IN RECURSIVE CODE CPI 081H JC NOTKNJ ; ASCII CHARS (00-7F) JUMP HERE CPI 0FDH JNC NOTKNJ ; SPECIAL FCNS (FD-FF) JUMP HERE CPI 0A0H JC ISKNJ ; 1ST HALF OF JIS CHAR (81-9F) JUMP HERE CPI 0E0H JC NOTKNJ ; KANA CHARACTERS (A0-DF) JUMP HERE ISKNJ: POP PSW ; PRESERVE ALL OTHER FLAGS STC RET ; ALL KANJI (81-9F) & (E0-FC) EXIT HERE NOTKNJ: POP PSW ; PRESERVE ALL OTHER FLAGS STC CMC ; RESET CY FLAG RET ; ASCII/KANA/SPCLFCNS EXIT HERE PAGE ;---------------------------------------------------------------- ; STRCRT -- SUBROUTINE TO OUTPUT STRING TO CRT ; HL ADDRESS OF BYTE COUNT ; STRING FOLLOWS BYTE COUNT STRCRT: PUSH PSW ; SAVE REGISTERS PUSH B PUSH D MOV A,M ; GET STRING LENGTH MOV b,A ; COPY OF COUNT IN b ORA A ; CHECK IF LEN = 0 OUTLUP: JZ ENDSEQ ; EXIT HERE IF COUNT IS 0 INX H ; MOVE PTR TO NEXT CHAR IN STRING IF REDIT lda PRTFLG ora a ; Check if output directed to PRINTER jz OUTLP1 mov e,m ; ** These 3 lines for PRINTER OUTPUT mvi c,5 ; ** call IMDOS ; ** jmp OUTLP2 OUTLP1: ENDIF MOV c,M ; @@ These 2 lines for CRT OUTPUT CALL OUTC ; @@ GET A BYTE, OUTPUT THE CHAR TO CRT OUTLP2: DCR b ; DECREMENT CHAR COUNT JMP OUTLUP ENDSEQ: POP D POP B POP PSW ; RESTORE REGISTERS RET PAGE ;---------------------------------------------------------------- ; DATA AREA ; KNJCRT: db 0 ; Flag is non-zero if CRT in KANJI mode ; 0 if CRT in ANK mode CNTBYT: db 0 ; Counter used by OFFKNJ routine to tell ; when it is appropriate to output ESC SEQ K2MASK: db 0ffh ; Mask used in ZITKNJ to control detection of ; 1st byte of KANJI. 0 value means no detection ; will occur (as during 2nd byte of kanji) KNJCH2: dw 0 ; Holds KANJI byte pair for output purposes ; Used in KNJOUT. ENDIF page ; ; data area ; nmscnl: ds 1 ;number of form lines in screen (and DEFLD flag) ivflag: db 0 ;if high bit on, inverse video is on hibcrf: db 0 ;if non-zero, set high bit for cursor ourwid: ds 1 ;number of usable bytes on screen cpscnt: ds 1 ;number bytes to output in cursor position string scnadd: ds 2 ;current address in simage curbyt: db 0FFH ;byte at scnadd (for memory mapped) curcol: ds 2 ;screen address for dsplay curline equ curcol+1 rescur: ds 2 ;restore cursor from here if NZ actcur: dw 0FFFFH ;actual cursor position mycur: dw 0FFFFH ;current cursor position for output requests msgend: dw 0 ;cursor position at message end blkflg: db 0 ;if nz, cursor will blink between blkadd and mycur blkadd: dw 0FFFFH ;cursor blink address simage: ds 2 ;points screen image rimage: ds 2 ;points request image rlflag: ds 2 ;points request line flag loadp: dw inputb ;load position from input buffer storep: dw inputb ;store positon IF KANJI knjchr: dw 0 ;current Kanji character input knjflg: db 0 ;say Kanji character in current input position knjin1: db 0 ;current position in input buffer contains Kanji rdrrdy: db 0 ;reader status flag knjhld: db 0 ;console temp Kanji hold buffer knjprt: db 0 ;used to correctly redisplay a Kanji character knjfrm: db 0 ;indicate that we are displaying lines form the form knj1st: db 0 ;flag to say(in CKLIN7) current byte is 1st of Kanji ENDIF inputb: dw 0,0,0,0 ;input buffer dw 0,0,0,0 dw 0,0,0,0 dw 0,0,0,0 dw 0,0,0,0 dw 0,0,0,0 dw 0,0,0,0 dw 0,0,0,0 db 0FFH ;marks buffer end IF KANJI db 0FFH ; needs two end-of-buffer markers for Kanji ENDIF if KEYS ;for keystroke capture/restore only ext imdos ext curdsk ext curdma ext namptr ;name pointer in FIRST.MAC ; ; equates ; bdos equ 5 openf equ 15 closef equ 16 readf equ 20 writef equ 21 makef equ 22 setdmf equ 26 endif if KEYCAP ; ; open file ; openit: push h push d push b lxi h,namptr lxi d,ourfcb+1 mvi b,6 open1: mov a,m stax d ;copy name into FCB from first inx h inx d dcr b jnz open1 lxi d,ourfcb lda curdsk inr a stax d mvi c,openf call imdos cpi 0FFH mvi c,makef cz imdos mvi a,80H sta bufcnt pop b pop d pop h ret ; ; entry with character in ACC to save in file ; saveit: push h push d push b push psw ;save character in ACC lhld bufptr mov m,a inx h shld bufptr lxi h,bufcnt dcr m cz writbf pop psw pop b pop d pop h ret ; ; write buffer ; writbf: mvi m,80H writb1: lhld curdma push h ;save current dma address lxi h,ourbuf shld bufptr ;reset buffer pointer call setdma lxi d,ourfcb mvi c,writef call imdos pop h call setdma ret ; ; close file ; closit: push h push d push b lda bufcnt lhld bufptr clos1: mvi m,0 inx h dcr a jnz clos1 call writb1 lxi d,ourfcb mvi c,closef call imdos pop b pop d pop h ret endif if KEYRES ; ; open file ; openit: push h push d push b lxi h,namptr lxi d,ourfcb+1 mvi b,6 open1: mov a,m stax d ;copy name into FCB from first inx h inx d dcr b jnz open1 lxi d,ourfcb lda curdsk inr a stax d mvi c,openf call imdos cpi 0FFH mvi a,1 sta bufcnt pop b pop d pop h ret ; conin2: lxi h,suppbf mov a,m cma ;toggle mov m,a inr a ;set Z if now suppressed rz ; ; get next character from keystroke file ; restit: lxi h,bufcnt dcr m cz readb jz conin2 ;toggle suppbf to 0FFH and return zero lhld bufptr mov a,m inx h shld bufptr ani 7FH jz restit ;skip zeros ret ; ; read buffer, return Z set if end file ; readb: mvi m,80H lhld curdma push h ;save current dma address lxi h,ourbuf shld bufptr ;reset buffer pointer call setdma lxi d,ourfcb mvi c,readf call imdos dcr a ;set Z if eof pop h push psw call setdma ;restore DMA pop psw ret endif if KEYS ; setdma: xchg mvi c,setdmf call imdos ret ; suppbf: db 0 ;suppresses file buffer if NZ bufptr: dw ourbuf bufcnt: ds 1 ourbuf: ds 80H ourfcb: db 0,'REDIT LOG',0,0,0,0 ds 16 db 0 endif end