home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
QTERM
/
QT43SRC.LBR
/
TERMIO.ZY
/
TERMIO.ZY
Wrap
Text File
|
2000-06-30
|
10KB
|
512 lines
; termio.z - subroutines for doing the terminal i/o part of qterm
.incl "c:termcap"
.incl "c:vars"
.macro table byte,addr
dw addr
db byte
.endm
.extern procch
procch: call kbdcc ; get a char if it's waiting
or a
jr z,lstmod ; skip if no character
cp 'x' & 0x1f ; ctl x?
jp z,canscr ; quit if so
ld e,a ; save char in e
ld a,(escval) ; get the escape value
ld hl,pccs
inc (hl)
dec (hl) ; what state?
jr z,pccs0 ; state zero - look for escape
dec (hl) ; reset to 0
cp e ; escape twice?
jr z,pccop ; yes - send one to modem
ld a,e ; get char back
cp ',' ; was it a ','?
call z,hangup ; hang up if so
cp '.' ; or a '.'
call z,break ; do a break
jr lstmod
; This is here for branch length reasons
.extern modop
modop: ; send a character to the modem, respecting
; half duplex etc.
push af
call modopc ; send it to the modem first
pop hl
ld a,(wflg) ; window mode?
or a
ld a,h ; get character back
jr z,nowin
push hl
call winsnd ; go give it to window input code
pop af ; char back
cp '\r'
ret nz ; returns get special processing
ld a,(eflg) ; echo mode?
or a
ret z ; return if not
ld a,'\n' ; throw a linefeed into the system
jr modop
nowin: ld a,(hflg) ; half duplex?
or a
ret z
ld a,h ; get character again
cp '\r'
jr nz,ipchar ; pass non-return chars straight in
ld a,(eflg) ; echo mode too?
or a
ld a,h ; get the '\r' back
jr z,ipchar ; no echo mode, don't expand it
call ipchar ; go send return to receive code
ld a,'\n'
jr ipmchr ; throw a newline into system as well
pccs0: cp e ; did we see an escape?
jr z,setesc ; yes, set the flag
ld a,e
pccop: call modop ; send char to modem
db 0x3e ; ld a,xx opcode
setesc: inc (hl)
.extern lstmod
lstmod:
call wrtscn ; keep the printer going and check if a
; character is waiting at the modem port.
ret c ; return if nothing arrived
ld hl,ecval ; echo check needed?
dec (hl)
inc (hl)
jr z,noec ; jump if not
cp (hl) ; did we match?
jr nz,noec ; no - leave value in place
ld (hl),1 ; reset to say we got it
noec: ld hl,bmask
and (hl) ; mask if 7 bit mode
scf
ret z ; return on nulls as well
ld hl,cscqfl
inc (hl)
dec (hl) ; ^S ^Q spotting enabled?
jr z,nocscq
bit 0,(hl)
jr nz,nocs ; waiting for a ^Q?
cp 's' & 0x1f ; ^S ?
jr nz,nocscq ; nope, check status now
set 0,(hl) ; flag that a ^S arrived
scf
ret
nocs: cp 'q' & 0x1f ; was it a ^Q
jr z,wascq
cp 's' & 0x1f ; also let a second ^S toggle
jr nz,nocscq ; not yet - pass this character
wascq: res 0,(hl) ; clear the flag
scf
ret
nocscq: ld hl,eflg
inc (hl)
dec (hl) ; echo mode?
zipch: jr z,ipchar ; no, hand straight to input code
cp '\r' ; return?
jr nz,ipmchr ; no, echo and hand to input code
call ipmchr ; otherwise process,
ld a,'\n' ; and send a newline into the system as well
ipmchr: push af
call modopc ; send character to modem to echo it
pop af
.extern ipchar ; needed for sendcs in chat
ipchar: ld c,a ; save char in c
ld a,(jflg)
or a ; junking control characters?
ld a,c
call nz,limitb ; if so it gets tested
ret c ; and thrown if bad
push af ; save the character
call opchar
pop af
call oplst ; output to printer
or a ; clear the carry
ld hl,cflg
bit 0,(hl) ; catch mode enabled
ret z ; no - return
ld hl,(cptr)
ld (hl),a ; save char away
inc hl
ld (cptr),hl ; update pointer
ld de,(endcbf)
or a
sbc hl,de ; buffer full?
scf
ccf ; clear carry w/o affecting zero
ret nz ; no - keep going
push af
call flushc ; go flush data in catch buffer
call ctlq
pop af
ret
.extern savrng
savrng: ; get a char and save in ring buffer
call modist ; char available?
ret z ; no.
call modin ; get it
ld de,(ringpw) ; pick up indices
ld hl,(ringpr)
inc de ; move write index
res 2,d
or a
sbc hl,de ; buffer full?
ret z ; return if so
ld (ringpw),de ; save revised index
ld hl,ring
add hl,de
ld (hl),a
ret
wrtscn: call wrtlst ; keep printer output rolling
call savrng ; get any incoming characters
ld de,(ringpr)
ld hl,(ringpw)
xor a
sbc hl,de ; anything in the ring?
scf
ret z ; nope
inc de
res 2,d
ld (ringpr),de ; save new index
ld hl,ring
add hl,de ; index into buffer
ld a,(hl) ; get the char
ret ; and return it
.extern oplst ; put a character in the list ring buffer
oplst:
ld hl,oflg ; are we saving?
bit 0,(hl)
ret z ; return if not
push bc ; save bc
ld hl,(lstpr)
ld de,(lstpw) ; get the list ring buffer indices
inc de ; move the write pointer
res 2,d ; wrap if it hits 1K
or a
sbc hl,de ; check for buffer full
jr nz,notful
push af ; save the character
call ctls ; send an xoff and wait for things to cool
mtloop: call wrtlst ; write a character if we can
jr nc,mtloop ; keep writing if we're not done
call ctlq ; OK - you can wake up again
pop af ; restore char again
notful: ld hl,(lstpw)
inc hl
res 2,h
ld (lstpw),hl ; save the revised write pointer
ld de,lstbuf ; address the list buffer
add hl,de
ld (hl),a ; and save the character
pop bc ; get bc back.
ret
wrtlst: ld de,(lstpr) ; see if we can send a character to the lst
ld hl,(lstpw) ; get the ring buffer indices
or a
sbc hl,de ; anything in the buffer
scf ; set carry to say we're done
ret z ; nope - nothing to do
push de
ld a,0x2d
call cbios ; call to list status
pop de ; get read pointer back
or a
ret z ; can't write - return now
ld hl,lstbuf
add hl,de ; index into buffer
inc de
res 2,d ; wrap if over 1K
ld (lstpr),de ; save new index
ld c,(hl)
.extern lstout
lstout: ld a,0x0f
call cbios
or a ; clear the carry
ret
.extern ctlq
ctlq:
ld a,(lxoff) ; get local xon / xoff status
or a
ret z ; send nothing if xoff sent from keyboard
ld a,(cqchr)
.extern modopc
modopc: push af ; save character on stack
modopl: call modost ; check if we can send
jr z,modopl ; can't send - loop back
pop af ; char back to a
jp modout ; and away it goes
.extern limitb
limitb: ; like limitc, but includes backspace
cp '\b'
ret z
.extern limitc
limitc:
cp 0x7f ; del or greater
ccf
ret c ; are invalid
.extern iswa
iswa:
cp ' ' ; space to '~'
ret nc ; are valid
cp '\r'
ret z ; return is valid
cp '\n'
ret z ; newline also
cp '\t'
ret z ; and tab
scf ; rest are bad
ret
.var #where 0
.var #bot 1
.var #top 2
.var #col 6
.var #row 7
.var #lff 8
nocndo: call ilprt ; and finish the message
db '\r\nW ignored - insufficient terminal capabilities\r\n\0'
ret
wend: ld hl,23 << 8
jp moveto
.extern witog
witog: ld a,(tcbits) ; check what terminal abilities we have
cpl
and b_delln | b_insln
ld (wtflag),a ; save window type value
jr z,cando ; got insert and delete - away we go
ld a,(tcbits)
and b_cleol ; alternatively check for clear to end-of-line
jr z,nocndo ; missing it as well - can't do this
cando: ld hl,wflg
call togflg ; toggle the flag first of all
jr z,wend ; disabled - so return & do nothing
dec (hl) ; temporarily turn mode back off so prompt
push hl ; works right
call prompt
db 'Window size (b / s)? \0'
pop hl
inc (hl) ; turn flag back on
ld hl,ipbuf
call byp
or 0x20
xor 's' ; did they say 's'?
; we could probably optimise this even more, only two numbers actually change
ld hl,sdat ; get small window data
jr z,gotdat ; jump if so
ld hl,bdat ; otherwise large window data
gotdat: ld de,wrdat
ld bc,6
ldir ; go install it
ld h,d
ld l,e
inc de
ld c,5
ld (hl),b ; clear the rest of the information
ldir
ld a,(wtflag)
or a ; what sort of windowing
jr nz,setrol ; rolling w/ clear to eol
ld hl,(rbot) ; normal - get bottom row
ld a,(sbot) ; and the other
jr wsetsc ; and install them
setrol: ld hl,(rtop) ; get top row
ld a,(stop) ; and the other
wsetsc: ld (srow),a ; save send window current row
ld a,l
ld (rrow),a ; and receive window
ld (where),a ; and set where so we'll do a moveto
call clear
ld hl,(rtop - 1) ; get top of receive window
dec h ; - 1 to move up a line
ld l,0 ; and the first positon
call moveto ; go there
call dim ; dim mode
ld bc,[80 << 8] + '-'
dashes: push bc
call scrout ; spit out 80 dashes
pop bc
djnz dashes
jp bright ; set bright mode and we're done
istab: ld c,' '
call opwc
ld a,(iy + #col)
and 7
jr nz,istab
ret
trybs: cp '\b'
jr nz,trytab
ld a,(iy + #col)
or a
ret z
dec (iy + #col)
call opbs
ld c,' '
call scrout
opbs: ld c,'\b'
jp scrout
trytab: cp '\t'
jr z,istab
nobs: cp '~' + 1
ret nc
cp ' '
ret c
opwc: push hl
call scrout
pop hl
ld (iy + #lff),0
inc (iy + #col)
ld a,(iy + #col)
xor 80
jr z,scrl
ret
.extern winrec
winrec: ld iy,wrdat
jr winpc
winsnd: ld iy,wsdat
ld c,a
winpc: ld hl,where
ld a,(iy + #where)
cp (hl)
jr z,posok
ld (hl),a
push hl
push bc
ld l,(iy + #col)
ld h,(iy + #row)
call moveto
pop bc
pop hl
posok: ld a,c
cp '\n'
jr z,scrl
cp '\r'
jr nz,trybs
scrl: xor a
cp (iy + #lff)
ret nz
ld (iy + #col),a
ld (hl),h
ld (iy + #lff),h
ld a,(wtflag)
or a
jr nz,roll
ld a,(iy + #top)
ld h,(iy + #bot)
ld l,22
; rollit - scroll a region on the screen - this is made external so the VT100
; code can get at it
.extern rollit
rollit: or a
push hl
jr nz,dell
ld hl,23 << 8
call moveto
ld c,'\n'
call scrout
jr dontop
dell: ld l,0
ld h,a
call moveto
call dellin
dontop: pop hl
ld a,h
cp l
ret z
ld l,0
call moveto
jp inslin
roll: ld a,(iy + #row)
call incrow
ld (iy + #row),a
call incrow
ld h,a
ld l,0
call moveto
jp cleol
incrow: cp (iy + #bot)
jr z,reload
inc a
ret
reload: ld a,(iy + #top)
ret
.dseg
.extern pccs
pccs: db 0
ringpr: dw 0
ringpw: dw 0
lstpr: dw 0
lstpw: dw 0
.useg
ring: ds 1024
lstbuf: ds 1024
wrdat:
rwhere: ds 1
rbot: ds 1
rtop: ds 1
wsdat:
swhere: ds 1
sbot: ds 1
stop: ds 1
rcol: ds 1
rrow: ds 1
rlff: ds 1
scol: ds 1
srow: ds 1
slff: ds 1
.extern where
where: ds 1
wtflag: ds 1
.dseg
sdat: db 0,22,12
db 1,10,0
bdat: db 0,22,5
db 1,3,0