mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 16:34:07 +00:00
903 lines
19 KiB
NASM
903 lines
19 KiB
NASM
title 'CP/M Bdos Interface, Bdos, Version 3.0 Nov, 1982'
|
|
;*****************************************************************
|
|
;*****************************************************************
|
|
;** **
|
|
;** B a s i c D i s k O p e r a t i n g S y s t e m **
|
|
;** **
|
|
;** C o n s o l e P o r t i o n **
|
|
;** **
|
|
;*****************************************************************
|
|
;*****************************************************************
|
|
;
|
|
; November 1982
|
|
;
|
|
;
|
|
; Console handlers
|
|
;
|
|
conin:
|
|
;read console character to A
|
|
lxi h,kbchar! mov a,m! mvi m,0! ora a! rnz
|
|
;no previous keyboard character ready
|
|
jmp coninf ;get character externally
|
|
;ret
|
|
;
|
|
conech:
|
|
LXI H,STA$RET! PUSH H
|
|
CONECH0:
|
|
;read character with echo
|
|
call conin! call echoc! JC CONECH1 ;echo character?
|
|
;character must be echoed before return
|
|
push psw! mov c,a! call tabout! pop psw
|
|
RET
|
|
CONECH1:
|
|
CALL TEST$CTLS$MODE! RNZ
|
|
CPI CTLS! JNZ CONECH2
|
|
CALL CONBRK2! JMP CONECH0
|
|
CONECH2:
|
|
CPI CTLQ! JZ CONECH0
|
|
CPI CTLP! JZ CONECH0
|
|
RET
|
|
;
|
|
echoc:
|
|
;echo character if graphic
|
|
;cr, lf, tab, or backspace
|
|
cpi cr! rz ;carriage return?
|
|
cpi lf! rz ;line feed?
|
|
cpi tab! rz ;tab?
|
|
cpi ctlh! rz ;backspace?
|
|
cpi ' '! ret ;carry set if not graphic
|
|
;
|
|
CONSTX:
|
|
LDA KBCHAR! ORA A! JNZ CONB1
|
|
CALL CONSTF! ANI 1! RET
|
|
;
|
|
if BANKED
|
|
|
|
SET$CTLS$MODE:
|
|
;SET CTLS STATUS OR INPUT FLAG FOR QUEUE MANAGER
|
|
LXI H,QFLAG! MVI M,40H! XTHL! PCHL
|
|
|
|
endif
|
|
;
|
|
TEST$CTLS$MODE:
|
|
;RETURN WITH Z FLAG RESET IF CTL-S CTL-Q CHECKING DISABLED
|
|
MOV B,A! LDA CONMODE! ANI 2! MOV A,B! RET
|
|
;
|
|
conbrk: ;check for character ready
|
|
CALL TEST$CTLS$MODE! JNZ CONSTX
|
|
lda kbchar! ora a! jnz CONBRK1 ;skip if active kbchar
|
|
;no active kbchar, check external break
|
|
;DOES BIOS HAVE TYPE AHEAD?
|
|
if BANKED
|
|
LDA TYPE$AHEAD! INR A! JZ CONSTX ;YES
|
|
endif
|
|
;CONBRKX CALLED BY CONOUT
|
|
|
|
CONBRKX:
|
|
;HAS CTL-S INTERCEPT BEEN DISABLED?
|
|
CALL TEST$CTLS$MODE! RNZ ;YES
|
|
;DOES KBCHAR CONTAIN CTL-S?
|
|
LDA KBCHAR! CPI CTLS! JZ CONBRK1 ;YES
|
|
if BANKED
|
|
CALL SET$CTLS$MODE
|
|
endif
|
|
;IS A CHARACTER READY FOR INPUT?
|
|
call constf
|
|
if BANKED
|
|
POP H! MVI M,0
|
|
endif
|
|
ani 1! rz ;NO
|
|
;character ready, read it
|
|
if BANKED
|
|
CALL SET$CTLS$MODE
|
|
endif
|
|
call coninf
|
|
if BANKED
|
|
POP H! MVI M,0
|
|
endif
|
|
CONBRK1:
|
|
cpi ctls! jnz conb0 ;check stop screen function
|
|
;DOES KBCHAR CONTAIN A CTL-S?
|
|
LXI H,KBCHAR! CMP M! JNZ CONBRK2 ;NO
|
|
MVI M,0 ; KBCHAR = 0
|
|
;found ctls, read next character
|
|
CONBRK2:
|
|
|
|
if BANKED
|
|
CALL SET$CTLS$MODE
|
|
endif
|
|
call coninf ;to A
|
|
if BANKED
|
|
POP H! MVI M,0
|
|
endif
|
|
cpi ctlc! JNZ CONBRK3
|
|
LDA CONMODE! ANI 08H! JZ REBOOTX
|
|
XRA A
|
|
CONBRK3:
|
|
SUI CTLQ! RZ ; RETURN WITH A = ZERO IF CTLQ
|
|
INR A! CALL CONB3! JMP CONBRK2
|
|
conb0:
|
|
LXI H,KBCHAR
|
|
|
|
MOV B,A
|
|
;IS CONMODE(1) TRUE?
|
|
LDA CONMODE! RAR! JNC $+7 ;NO
|
|
;DOES KBCHAR = CTLC?
|
|
MVI A,CTLC! CMP M! RZ ;YES - RETURN
|
|
MOV A,B
|
|
|
|
CPI CTLQ! JZ CONB2
|
|
CPI CTLP! JZ CONB2
|
|
;character in accum, save it
|
|
MOV M,A
|
|
conb1:
|
|
;return with true set in accumulator
|
|
mvi a,1! ret
|
|
CONB2:
|
|
XRA A! MOV M,A! RET
|
|
CONB3:
|
|
CZ TOGGLE$LISTCP
|
|
MVI C,7! CNZ CONOUTF
|
|
RET
|
|
;
|
|
TOGGLE$LISTCP:
|
|
; IS PRINTER ECHO DISABLED?
|
|
LDA CONMODE! ANI 14H! JNZ TOGGLE$L1 ;YES
|
|
LXI H,LISTCP! MVI A,1! XRA M! ANI 1
|
|
MOV M,A! RET
|
|
TOGGLE$L1:
|
|
XRA A! RET
|
|
;
|
|
QCONOUTF:
|
|
;DOES FX = INPUT?
|
|
LDA FX! DCR A! JZ CONOUTF ;YES
|
|
;IS ESCAPE SEQUENCE DECODING IN EFFECT?
|
|
MOV A,B! ANI 8! JNZ SCONOUTF ;YES
|
|
JMP CONOUTF
|
|
;
|
|
conout:
|
|
;compute character position/write console char from C
|
|
;compcol = true if computing column position
|
|
lda compcol! ora a! jnz compout
|
|
;write the character, then compute the column
|
|
;write console character from C
|
|
;B ~= 0 -> ESCAPE SEQUENCE DECODING
|
|
LDA CONMODE! ANI 14H! MOV B,A
|
|
push b
|
|
;CALL CONBRKX FOR OUTPUT FUNCTIONS ONLY
|
|
LDA FX! DCR A! CNZ CONBRKX
|
|
pop b! push b ;recall/save character
|
|
call QCONOUTF ;externally, to console
|
|
pop b
|
|
;SKIP ECHO WHEN CONMODE & 14H ~= 0
|
|
MOV A,B! ORA A! JNZ COMPOUT
|
|
push b ;recall/save character
|
|
;may be copying to the list device
|
|
lda listcp! ora a! cnz listf ;to printer, if so
|
|
pop b ;recall the character
|
|
compout:
|
|
mov a,c ;recall the character
|
|
;and compute column position
|
|
lxi h,column ;A = char, HL = .column
|
|
cpi rubout! rz ;no column change if nulls
|
|
inr m ;column = column + 1
|
|
cpi ' '! rnc ;return if graphic
|
|
;not graphic, reset column position
|
|
dcr m ;column = column - 1
|
|
mov a,m! ora a! rz ;return if at zero
|
|
;not at zero, may be backspace or end line
|
|
mov a,c ;character back to A
|
|
cpi ctlh! jnz notbacksp
|
|
;backspace character
|
|
dcr m ;column = column - 1
|
|
ret
|
|
notbacksp:
|
|
;not a backspace character, eol?
|
|
cpi cr! rnz ;return if not
|
|
;end of line, column = 0
|
|
mvi m,0 ;column = 0
|
|
ret
|
|
;
|
|
ctlout:
|
|
;send C character with possible preceding up-arrow
|
|
mov a,c! call echoc ;cy if not graphic (or special case)
|
|
jnc tabout ;skip if graphic, tab, cr, lf, or ctlh
|
|
;send preceding up arrow
|
|
push psw! mvi c,ctl! call conout ;up arrow
|
|
pop psw! ori 40h ;becomes graphic letter
|
|
mov c,a ;ready to print
|
|
if BANKED
|
|
call chk$column! rz
|
|
endif
|
|
;(drop through to tabout)
|
|
;
|
|
tabout:
|
|
;IS FX AN INPUT FUNCTION?
|
|
LDA FX! DCR A! JZ TABOUT1 ;YES - ALWAYS EXPAND TABS FOR ECHO
|
|
;HAS TAB EXPANSION BEEN DISABLED OR
|
|
;ESCAPE SEQUENCE DECODING BEEN ENABLED?
|
|
LDA CONMODE! ANI 14H! JNZ CONOUT ;YES
|
|
TABOUT1:
|
|
;expand tabs to console
|
|
mov a,c! cpi tab! jnz conout ;direct to conout if not
|
|
;tab encountered, move to next tab position
|
|
tab0:
|
|
|
|
if BANKED
|
|
lda fx! cpi 1! jnz tab1
|
|
call chk$column! rz
|
|
tab1:
|
|
endif
|
|
|
|
mvi c,' '! call conout ;another blank
|
|
lda column! ani 111b ;column mod 8 = 0 ?
|
|
jnz tab0 ;back for another if not
|
|
ret
|
|
;
|
|
;
|
|
backup:
|
|
;back-up one screen position
|
|
call pctlh
|
|
|
|
if BANKED
|
|
lda comchr! cpi ctla! rz
|
|
endif
|
|
|
|
mvi c,' '! call conoutf
|
|
; (drop through to pctlh) ;
|
|
pctlh:
|
|
;send ctlh to console without affecting column count
|
|
mvi c,ctlh! jmp conoutf
|
|
;ret
|
|
;
|
|
crlfp:
|
|
;print #, cr, lf for ctlx, ctlu, ctlr functions
|
|
;then move to strtcol (starting column)
|
|
mvi c,'#'! call conout
|
|
call crlf
|
|
;column = 0, move to position strtcol
|
|
crlfp0:
|
|
lda column! lxi h,strtcol
|
|
cmp m! rnc ;stop when column reaches strtcol
|
|
mvi c,' '! call conout ;print blank
|
|
jmp crlfp0
|
|
;;
|
|
;
|
|
crlf:
|
|
;carriage return line feed sequence
|
|
mvi c,cr! call conout! mvi c,lf! jmp conout
|
|
;ret
|
|
;
|
|
print:
|
|
;print message until M(BC) = '$'
|
|
LXI H,OUTDELIM
|
|
ldax b! CMP M! rz ;stop on $
|
|
;more to print
|
|
inx b! push b! mov c,a ;char to C
|
|
call tabout ;another character printed
|
|
pop b! jmp print
|
|
;
|
|
QCONIN:
|
|
|
|
if BANKED
|
|
lhld apos! mov a,m! sta ctla$sw
|
|
endif
|
|
;IS BUFFER ADDRESS = 0?
|
|
LHLD CONBUFFADD! MOV A,L! ORA H! JZ CONIN ;YES
|
|
;IS CHARACTER IN BUFFER < 5?
|
|
|
|
if BANKED
|
|
call qconinx ; mov a,m with bank 1 switched in
|
|
else
|
|
MOV A,M
|
|
endif
|
|
|
|
INX H
|
|
ORA A! JNZ QCONIN1 ; NO
|
|
LXI H,0
|
|
QCONIN1:
|
|
SHLD CONBUFFADD! SHLD CONBUFFLEN! RNZ ; NO
|
|
JMP CONIN
|
|
|
|
if BANKED
|
|
|
|
chk$column:
|
|
lda conwidth! mov e,a! lda column! cmp e! ret
|
|
;
|
|
expand:
|
|
xchg! lhld apos! xchg
|
|
expand1:
|
|
ldax d! ora a! rz
|
|
inx d! inx h! mov m,a! inr b! jmp expand1
|
|
;
|
|
copy$xbuff:
|
|
mov a,b! ora a! rz
|
|
push b! mov c,b! push h! xchg! inx d
|
|
lxi h,xbuff
|
|
call move
|
|
mvi m,0! shld xpos
|
|
pop h! pop b! ret
|
|
;
|
|
copy$cbuff:
|
|
lda ccpflgs+1! ral! rnc
|
|
lxi h,xbuff! lxi d,cbuff! inr c! jnz copy$cbuff1
|
|
xchg! mov a,b! ora a! rz
|
|
sta cbuff$len
|
|
push d! lxi b,copy$cbuff2! push b
|
|
mov b,a
|
|
copy$cbuff1:
|
|
inr b! mov c,b! jmp move
|
|
copy$cbuff2:
|
|
pop h! dcx h! mvi m,0! ret
|
|
;
|
|
save$col:
|
|
lda column! sta save$column! ret
|
|
;
|
|
clear$right:
|
|
lda column! lxi h,ctla$column! cmp m! rnc
|
|
mvi c,20h! call conout! jmp clear$right
|
|
;
|
|
reverse:
|
|
lda save$column! lxi h,column! cmp m! rnc
|
|
mvi c,ctlh! call conout! jmp reverse
|
|
;
|
|
chk$buffer$size:
|
|
push b! push h
|
|
lhld apos! mvi e,0
|
|
cbs1:
|
|
mov a,m! ora a! jz cbs2
|
|
inr e! inx h! jmp cbs1
|
|
cbs2:
|
|
mov a,b! add e! cmp c
|
|
push a! mvi c,7! cnc conoutf
|
|
pop a! pop h! pop b! rc
|
|
pop d! pop d! jmp readnx
|
|
;
|
|
refresh:
|
|
lda ctla$sw! ora a! rz
|
|
lda comchr! cpi ctla! rz
|
|
cpi ctlf! rz
|
|
cpi ctlw! rz
|
|
refresh0:
|
|
push h! push b
|
|
call save$col
|
|
lhld apos
|
|
refresh1:
|
|
mov a,m! ora a! jz refresh2
|
|
mov c,a! call chk$column! jc refresh05
|
|
mov a,e! sta column! jmp refresh2
|
|
refresh05:
|
|
push h! call ctlout
|
|
pop h! inx h! jmp refresh1
|
|
refresh2:
|
|
lda column! sta new$ctla$col
|
|
refresh3:
|
|
call clear$right
|
|
call reverse
|
|
lda new$ctla$col! sta ctla$column
|
|
pop b! pop h! ret
|
|
;
|
|
init$apos:
|
|
lxi h,aposi! shld apos
|
|
xra a! sta ctla$sw
|
|
ret
|
|
;
|
|
init$xpos:
|
|
lxi h,xbuff! shld xpos! ret
|
|
;
|
|
set$ctla$column:
|
|
lxi h,ctla$sw! mov a,m! ora a! rnz
|
|
inr m! lda column! sta ctla$column! ret
|
|
;
|
|
readi:
|
|
call chk$column! cnc crlf
|
|
lda cbuff$len! mov b,a
|
|
mvi c,0! call copy$cbuff
|
|
else
|
|
|
|
readi:
|
|
MOV A,D! ORA E! JNZ READ
|
|
LHLD DMAAD! SHLD INFO
|
|
INX H! INX H! SHLD CONBUFFADD
|
|
endif
|
|
|
|
read: ;read to info address (max length, current length, buffer)
|
|
|
|
if BANKED
|
|
call init$xpos
|
|
call init$apos
|
|
readx:
|
|
call refresh
|
|
xra a! sta ctlw$sw
|
|
readx1:
|
|
|
|
endif
|
|
|
|
MVI A,1! STA FX
|
|
lda column! sta strtcol ;save start for ctl-x, ctl-h
|
|
lhld info! mov c,m! inx h! push h
|
|
XRA A! MOV B,A! STA SAVEPOS
|
|
CMP C! JNZ $+4
|
|
INR C
|
|
;B = current buffer length,
|
|
;C = maximum buffer length,
|
|
;HL= next to fill - 1
|
|
readnx:
|
|
;read next character, BC, HL active
|
|
push b! push h ;blen, cmax, HL saved
|
|
readn0:
|
|
|
|
if BANKED
|
|
lda ctlw$sw! ora a! cz qconin
|
|
nxtline:
|
|
sta comchr
|
|
else
|
|
CALL QCONIN ;next char in A
|
|
endif
|
|
|
|
;ani 7fh ;mask parity bit
|
|
pop h! pop b ;reactivate counters
|
|
cpi cr! jz readen ;end of line?
|
|
cpi lf! jz readen ;also end of line
|
|
|
|
if BANKED
|
|
cpi ctlf! jnz not$ctlf
|
|
do$ctlf:
|
|
call chk$column! dcr e! cmp e! jnc readnx
|
|
do$ctlf0:
|
|
xchg! lhld apos! mov a,m! ora a! jz ctlw$l15
|
|
inx h! shld apos! xchg! jmp notr
|
|
not$ctlf:
|
|
cpi ctlw! jnz not$ctlw
|
|
do$ctlw:
|
|
xchg! lhld apos! mov a,m! ora a! jz ctlw$l1
|
|
xchg! call chk$column! dcr e! cmp e! xchg! jc ctlw$l0
|
|
xchg! call refresh0! xchg! jmp ctlw$l13
|
|
ctlw$l0:
|
|
lhld apos! mov a,m
|
|
inx h! shld apos! jmp ctlw$l3
|
|
ctlw$l1:
|
|
lxi h,ctla$sw! mov a,m! mvi m,0
|
|
ora a! jz ctlw$l2
|
|
ctlw$l13:
|
|
lxi h,ctlw$sw! mvi m,0
|
|
ctlw$l15:
|
|
xchg! jmp readnx
|
|
ctlw$l2:
|
|
lda ctlw$sw! ora a! jnz ctlw$l25
|
|
mov a,b! ora a! jnz ctlw$l15
|
|
call init$xpos
|
|
ctlw$l25:
|
|
lhld xpos! mov a,m! ora a
|
|
sta ctlw$sw! jz ctlw$l15
|
|
inx h! shld xpos
|
|
ctlw$l3:
|
|
lxi h,ctlw$sw! mvi m,ctlw
|
|
xchg! jmp notr
|
|
not$ctlw:
|
|
cpi ctla! jnz not$ctla
|
|
do$ctla:
|
|
;do we have any characters to back over?
|
|
lda strtcol! mov d,a! lda column! cmp d
|
|
jz readnx
|
|
sta compcol ;COL > 0
|
|
mov a,b! ora a! jz linelen
|
|
;characters remain in buffer, backup one
|
|
dcr b ;remove one character
|
|
;compcol > 0 marks repeat as length compute
|
|
;backup one position in xbuff
|
|
push h
|
|
call set$ctla$column
|
|
pop d
|
|
lhld apos! dcx h
|
|
shld apos! ldax d! mov m,a! xchg! jmp linelen
|
|
not$ctla:
|
|
cpi ctlb! jnz not$ctlb
|
|
do$ctlb:
|
|
lda save$pos! cmp b! jnz ctlb$l0
|
|
mvi a,ctlw! sta ctla$sw
|
|
sta comchr! jmp do$ctlw
|
|
ctlb$l0:
|
|
xchg! lhld apos! inr b
|
|
ctlb$l1:
|
|
dcr b! lda save$pos! cmp b! jz ctlb$l2
|
|
dcx h! ldax d! mov m,a! dcx d! jmp ctlb$l1
|
|
ctlb$l2:
|
|
shld apos
|
|
push b! push d
|
|
call set$ctla$column
|
|
ctlb$l3:
|
|
lda column! mov b,a
|
|
lda strtcol! cmp b! jz read$n0
|
|
mvi c,ctlh! call conout! jmp ctlb$l3
|
|
not$ctlb:
|
|
cpi ctlk! jnz not$ctlk
|
|
xchg! lxi h,aposi! shld apos
|
|
xchg! call refresh
|
|
jmp readnx
|
|
not$ctlk:
|
|
cpi ctlg! jnz not$ctlg
|
|
lda ctla$sw! ora a! jz readnx
|
|
jmp do$ctlf0
|
|
not$ctlg:
|
|
endif
|
|
|
|
cpi ctlh! jnz noth ;backspace?
|
|
LDA CTLH$ACT! INR A! JZ DO$RUBOUT
|
|
DO$CTLH:
|
|
;do we have any characters to back over?
|
|
LDA STRTCOL! MOV D,A! LDA COLUMN! CMP D
|
|
jz readnx
|
|
STA COMPCOL ;COL > 0
|
|
MOV A,B! ORA A! JZ $+4
|
|
;characters remain in buffer, backup one
|
|
dcr b ;remove one character
|
|
;compcol > 0 marks repeat as length compute
|
|
jmp linelen ;uses same code as repeat
|
|
noth:
|
|
;not a backspace
|
|
cpi rubout! jnz notrub ;rubout char?
|
|
LDA RUBOUT$ACT! INR A! JZ DO$CTLH
|
|
DO$RUBOUT:
|
|
if BANKED
|
|
mvi a,rubout! sta comchr
|
|
lda ctla$sw! ora a! jnz do$ctlh
|
|
endif
|
|
;rubout encountered, rubout if possible
|
|
mov a,b! ora a! jz readnx ;skip if len=0
|
|
;buffer has characters, resend last char
|
|
mov a,m! dcr b! dcx h ;A = last char
|
|
;blen=blen-1, next to fill - 1 decremented
|
|
jmp rdech1 ;act like this is an echo
|
|
notrub:
|
|
;not a rubout character, check end line
|
|
cpi ctle! jnz note ;physical end line?
|
|
;yes, save active counters and force eol
|
|
push b! MOV A,B! STA SAVE$POS
|
|
push h
|
|
if BANKED
|
|
lda ctla$sw! ora a! cnz clear$right
|
|
endif
|
|
call crlf
|
|
if BANKED
|
|
call refresh
|
|
endif
|
|
xra a! sta strtcol ;start position = 00
|
|
jmp readn0 ;for another character
|
|
note:
|
|
;not end of line, list toggle?
|
|
cpi ctlp! jnz notp ;skip if not ctlp
|
|
;list toggle - change parity
|
|
push h ;save next to fill - 1
|
|
PUSH B
|
|
XRA A! CALL CONB3
|
|
POP B
|
|
pop h! jmp readnx ;for another char
|
|
notp:
|
|
;not a ctlp, line delete?
|
|
cpi ctlx! jnz notx
|
|
pop h ;discard start position
|
|
;loop while column > strtcol
|
|
backx:
|
|
lda strtcol! lxi h,column
|
|
if BANKED
|
|
cmp m! jc backx1
|
|
lhld apos! mov a,m! ora a! jnz readx
|
|
jmp read
|
|
backx1:
|
|
else
|
|
cmp m! jnc read ;start again
|
|
endif
|
|
dcr m ;column = column - 1
|
|
call backup ;one position
|
|
jmp backx
|
|
notx:
|
|
;not a control x, control u?
|
|
;not control-X, control-U?
|
|
cpi ctlu! jnz notu ;skip if not
|
|
if BANKED
|
|
xthl! call copy$xbuff! xthl
|
|
endif
|
|
;delete line (ctlu)
|
|
do$ctlu:
|
|
call crlfp ;physical eol
|
|
pop h ;discard starting position
|
|
jmp read ;to start all over
|
|
notu:
|
|
;not line delete, repeat line?
|
|
cpi ctlr! jnz notr
|
|
XRA A! STA SAVEPOS
|
|
if BANKED
|
|
xchg! call init$apos! xchg
|
|
mov a,b! ora a! jz do$ctlu
|
|
xchg! lhld apos! inr b
|
|
ctlr$l1:
|
|
dcr b! jz ctlr$l2
|
|
dcx h! ldax d! mov m,a! dcx d
|
|
jmp ctlr$l1
|
|
ctlr$l2:
|
|
shld apos! push b! push d
|
|
call crlfp! mvi a,ctlw! sta ctlw$sw
|
|
sta ctla$sw! jmp readn0
|
|
endif
|
|
linelen:
|
|
;repeat line, or compute line len (ctlh)
|
|
;if compcol > 0
|
|
push b! call crlfp ;save line length
|
|
pop b! pop h! push h! push b
|
|
;bcur, cmax active, beginning buff at HL
|
|
rep0:
|
|
mov a,b! ora a! jz rep1 ;count len to 00
|
|
inx h! mov c,m ;next to print
|
|
DCR B
|
|
POP D! PUSH D! MOV A,D! SUB B! MOV D,A
|
|
push b! push h ;count length down
|
|
LDA SAVEPOS! CMP D! CC CTLOUT
|
|
pop h! pop b ;recall remaining count
|
|
jmp rep0 ;for the next character
|
|
rep1:
|
|
;end of repeat, recall lengths
|
|
;original BC still remains pushed
|
|
push h ;save next to fill
|
|
lda compcol! ora a ;>0 if computing length
|
|
jz readn0 ;for another char if so
|
|
;column position computed for ctlh
|
|
lxi h,column! sub m ;diff > 0
|
|
sta compcol ;count down below
|
|
;move back compcol-column spaces
|
|
backsp:
|
|
;move back one more space
|
|
call backup ;one space
|
|
lxi h,compcol! dcr m
|
|
jnz backsp
|
|
if BANKED
|
|
call refresh
|
|
endif
|
|
jmp readn0 ;for next character
|
|
notr:
|
|
;not a ctlr, place into buffer
|
|
;IS BUFFER FULL?
|
|
PUSH A
|
|
MOV A,B! CMP C! JC RDECH0 ;NO
|
|
;DISCARD CHARACTER AND RING BELL
|
|
POP A! PUSH B! PUSH H
|
|
MVI C,7! CALL CONOUTF! JMP READN0
|
|
RDECH0:
|
|
|
|
if BANKED
|
|
lda comchr! cpi ctlg! jz rdech05
|
|
lda ctla$sw! ora a! cnz chk$buffer$size
|
|
rdech05:
|
|
endif
|
|
|
|
POP A
|
|
inx h! mov m,a ;character filled to mem
|
|
inr b ;blen = blen + 1
|
|
rdech1:
|
|
;look for a random control character
|
|
push b! push h ;active values saved
|
|
mov c,a ;ready to print
|
|
if BANKED
|
|
call save$col
|
|
endif
|
|
call ctlout ;may be up-arrow C
|
|
pop h! pop b
|
|
if BANKED
|
|
lda comchr! cpi ctlg! jz do$ctlh
|
|
cpi rubout! jz rdech2
|
|
call refresh
|
|
rdech2:
|
|
endif
|
|
LDA CONMODE! ANI 08H! JNZ NOTC
|
|
mov a,m ;recall char
|
|
cpi ctlc ;set flags for reboot test
|
|
mov a,b ;move length to A
|
|
jnz notc ;skip if not a control c
|
|
cpi 1 ;control C, must be length 1
|
|
jz REBOOTX ;reboot if blen = 1
|
|
;length not one, so skip reboot
|
|
notc:
|
|
;not reboot, are we at end of buffer?
|
|
if BANKED
|
|
cmp c! jnc buffer$full
|
|
else
|
|
jmp readnx ;go for another if not
|
|
endif
|
|
|
|
if BANKED
|
|
push b! push h
|
|
call chk$column! jc readn0
|
|
lda ctla$sw! ora a! jz do$new$line
|
|
lda comchr! cpi ctlw! jz back$one
|
|
cpi ctlf! jz back$one
|
|
|
|
do$newline:
|
|
mvi a,ctle! jmp nxtline
|
|
|
|
back$one:
|
|
;back up to previous character
|
|
pop h! pop b
|
|
dcr b! xchg
|
|
lhld apos! dcx h! shld apos
|
|
ldax d! mov m,a! xchg! dcx h
|
|
push b! push h! call reverse
|
|
;disable ctlb or ctlw
|
|
xra a! sta ctlw$sw! jmp readn0
|
|
|
|
buffer$full:
|
|
xra a! sta ctlw$sw! jmp readnx
|
|
endif
|
|
readen:
|
|
;end of read operation, store blen
|
|
if BANKED
|
|
call expand
|
|
endif
|
|
pop h! mov m,b ;M(current len) = B
|
|
if BANKED
|
|
push b
|
|
call copy$xbuff
|
|
pop b
|
|
mvi c,0ffh! call copy$cbuff
|
|
endif
|
|
LXI H,0! SHLD CONBUFFADD
|
|
mvi c,cr! jmp conout ;return carriage
|
|
;ret
|
|
;
|
|
func1 equ CONECH
|
|
;return console character with echo
|
|
;
|
|
func2: equ tabout
|
|
;write console character with tab expansion
|
|
;
|
|
func3:
|
|
;return reader character
|
|
call readerf
|
|
jmp sta$ret
|
|
;
|
|
;func4: equated to punchf
|
|
;write punch character
|
|
;
|
|
;func5: equated to listf
|
|
;write list character
|
|
;write to list device
|
|
;
|
|
func6:
|
|
;direct console i/o - read if 0ffh
|
|
mov a,c! inr a! jz dirinp ;0ffh => 00h, means input mode
|
|
inr a! JZ DIRSTAT ;0feh => direct STATUS function
|
|
INR A! JZ DIRINP1 ;0fdh => direct input, no status
|
|
JMP CONOUTF
|
|
DIRSTAT:
|
|
;0feH in C for status
|
|
CALL CONSTX! JNZ LRET$EQ$FF! JMP STA$RET
|
|
dirinp:
|
|
CALL CONSTX ;status check
|
|
ora a! RZ ;skip, return 00 if not ready
|
|
;character is ready, get it
|
|
dirinp1:
|
|
call CONIN ;to A
|
|
jmp sta$ret
|
|
;
|
|
func7:
|
|
call auxinstf
|
|
jmp sta$ret
|
|
;
|
|
func8:
|
|
call auxoutstf
|
|
jmp sta$ret
|
|
;
|
|
func9:
|
|
;write line until $ encountered
|
|
xchg ;was lhld info
|
|
mov c,l! mov b,h ;BC=string address
|
|
jmp print ;out to console
|
|
|
|
func10 equ readi
|
|
;read a buffered console line
|
|
|
|
func11:
|
|
;IS CONMODE(1) TRUE?
|
|
LDA CONMODE! RAR! JNC NORMAL$STATUS ;NO
|
|
;CTL-C ONLY STATUS CHECK
|
|
if BANKED
|
|
LXI H,QFLAG! MVI M,80H! PUSH H
|
|
endif
|
|
LXI H,CTLC$STAT$RET! PUSH H
|
|
;DOES KBCHAR = CTL-C?
|
|
LDA KBCHAR! CPI CTLC! JZ CONB1 ;YES
|
|
;IS THERE A READY CHARACTER?
|
|
CALL CONSTF! ORA A! RZ ;NO
|
|
;IS THE READY CHARACTER A CTL-C?
|
|
CALL CONINF! CPI CTLC! JZ CONB0 ;YES
|
|
STA KBCHAR! XRA A! RET
|
|
|
|
CTLC$STAT$RET:
|
|
|
|
if BANKED
|
|
CALL STA$RET
|
|
POP H! MVI M,0! RET
|
|
else
|
|
JMP STA$RET
|
|
endif
|
|
|
|
NORMAL$STATUS:
|
|
;check console status
|
|
call conbrk
|
|
;(drop through to sta$ret)
|
|
sta$ret:
|
|
;store the A register to aret
|
|
sta aret
|
|
func$ret: ;
|
|
ret ;jmp goback (pop stack for non cp/m functions)
|
|
;
|
|
setlret1:
|
|
;set lret = 1
|
|
mvi a,1! jmp sta$ret ;
|
|
;
|
|
FUNC109: ;GET/SET CONSOLE MODE
|
|
;DOES DE = 0FFFFH?
|
|
MOV A,D! ANA E! INR A
|
|
LHLD CONMODE! JZ STHL$RET ;YES - RETURN CONSOLE MODE
|
|
XCHG! SHLD CONMODE! RET ;NO - SET CONSOLE MODE
|
|
;
|
|
FUNC110: ;GET/SET FUNCTION 9 DELIMITER
|
|
LXI H,OUT$DELIM
|
|
;DOES DE = 0FFFFH?
|
|
MOV A,D! ANA E! INR A
|
|
MOV A,M! JZ STA$RET ;YES - RETURN DELIMITER
|
|
MOV M,E! RET ;NO - SET DELIMITER
|
|
;
|
|
FUNC111: ;PRINT BLOCK TO CONSOLE
|
|
FUNC112: ;LIST BLOCK
|
|
XCHG! MOV E,M! INX H! MOV D,M! INX H
|
|
MOV C,M! INX H! MOV B,M! XCHG
|
|
;HL = ADDR OF STRING
|
|
;BC = LENGTH OF STRING
|
|
BLK$OUT:
|
|
MOV A,B! ORA C! RZ
|
|
PUSH B! PUSH H! MOV C,M
|
|
LDA FX! CPI 111! JZ BLK$OUT1
|
|
CALL LISTF! JMP BLK$OUT2
|
|
BLK$OUT1:
|
|
CALL TABOUT
|
|
BLK$OUT2:
|
|
POP H! INX H! POP B! DCX B
|
|
JMP BLK$OUT
|
|
|
|
SCONOUTF EQU CONOUTF
|
|
|
|
;
|
|
; data areas
|
|
;
|
|
compcol:db 0 ;true if computing column position
|
|
strtcol:db 0 ;starting column position after read
|
|
|
|
if not BANKED
|
|
|
|
kbchar: db 0 ;initial key char = 00
|
|
|
|
endif
|
|
|
|
SAVEPOS:DB 0 ;POSITION IN BUFFER CORRESPONDING TO
|
|
;BEGINNING OF LINE
|
|
if BANKED
|
|
|
|
comchr: db 0
|
|
cbuff$len: db 0
|
|
cbuff: ds 256
|
|
db 0
|
|
xbuff: db 0
|
|
ds 354
|
|
aposi: db 0
|
|
xpos: dw 0
|
|
apos: dw 0
|
|
ctla$sw: db 0
|
|
ctlw$sw: db 0
|
|
save$column: db 0
|
|
ctla$column: db 0
|
|
new$ctla$col: db 0
|
|
|
|
endif
|
|
|
|
; end of BDOS Console module
|