658 lines
14 KiB
Plaintext
658 lines
14 KiB
Plaintext
; odds.z - code that has no place else to live
|
|
|
|
.incl "c:termcap"
|
|
.incl "c:vars"
|
|
|
|
.var slow 86 ; should we slow down outgoing string
|
|
|
|
.extern prompt ; print an inline prompt then get a buffer
|
|
prompt: ; full of data from the keyboard
|
|
ld a,(prmpfl) ; see if we're in a chat script or not
|
|
or a
|
|
jr z,nochat ; no - do normal input
|
|
push ix
|
|
pop hl ; get string address to hl
|
|
ld de,ipbuf
|
|
ld bc,116 ; reasonable amount to copy
|
|
ldir ; move it over, and we're done
|
|
skipze: pop hl ; get string address - we have to skip over it
|
|
skiplp: inc hl ; this relies on a non-empty string
|
|
ld a,(hl)
|
|
or a
|
|
jr nz,skiplp ; skip till we reach the end
|
|
jp (hl) ; and return to address in hl
|
|
nochat: call dim ; set dim mode
|
|
ld hl,crlfms
|
|
call prtslp ; send a newline
|
|
pop hl
|
|
call prtslp ; print the prompt
|
|
push hl
|
|
ld de,ipbuf - 2 ; point at where we'll read info
|
|
ld a,e
|
|
ld (de),a ; set count
|
|
ld c,buffin
|
|
call bdos ; read a line
|
|
ld hl,ipbuf - 1
|
|
ld e,(hl) ; get count actually input
|
|
ld d,h
|
|
add hl,de
|
|
inc hl ; turn into a buffer pointer
|
|
ld (hl),d ; and zero terminate input data
|
|
|
|
.extern crlf ; just print a newline
|
|
crlf:
|
|
call ilprt
|
|
crlfms: db '\r\n'
|
|
zero: db 0
|
|
ret
|
|
|
|
.extern ilprt
|
|
ilprt: call dim ; in line print - start by going dim
|
|
pop hl ; get string address
|
|
call prtslp ; out it goes
|
|
push hl ; restore return address - fall into bright
|
|
|
|
.extern bright
|
|
bright: ld a,(tcbits)
|
|
and b_brite ; do we have a bright string?
|
|
ret z
|
|
ld hl,bflag ; currently bright?
|
|
ld a,(hl)
|
|
dec a
|
|
ret nz ; yes, don't resend
|
|
ld (hl),a
|
|
ld hl,brites ; get address of bright string
|
|
jr prtslx ; and send it
|
|
|
|
.extern dim
|
|
dim: ld a,(tcbits)
|
|
and b_dim ; do we have a dim string?
|
|
ret z
|
|
ld hl,bflag ; currently dim?
|
|
ld a,(hl)
|
|
or a
|
|
ret nz ; yes, don't resend
|
|
inc (hl)
|
|
ld hl,dims ; get address of dim string
|
|
jr prtslx
|
|
|
|
.extern dellin
|
|
dellin:
|
|
ld hl,dlstr ; get address of dellin string
|
|
jr prtslx ; and send it
|
|
|
|
.extern inslin
|
|
inslin:
|
|
ld hl,ilstr ; get address of inslin string
|
|
jr prtslx ; and send it
|
|
|
|
.extern cleol
|
|
cleol:
|
|
ld hl,ceol ; get address of cleol string
|
|
jr prtslx ; and send it
|
|
|
|
.extern cleos
|
|
cleos:
|
|
ld hl,ceos ; get address of cleos string
|
|
jr prtslx ; and send it
|
|
|
|
.extern clear
|
|
clear: ld hl,clrs ; get address of clear string
|
|
|
|
prtslx: ld a,h
|
|
ld (optype),a
|
|
call prtslp
|
|
xor a
|
|
ld (optype),a
|
|
ret
|
|
|
|
.extern prtslp
|
|
prtslp:
|
|
call clrpcp
|
|
|
|
.extern prtsl1
|
|
prtsl1:
|
|
ld a,(hl)
|
|
or a
|
|
ret z
|
|
inc hl
|
|
push hl
|
|
call tabexp
|
|
pop hl
|
|
; for ^X to can a long directory, add a 'ret c' here
|
|
jr prtsl1
|
|
|
|
.extern tabexp
|
|
tabexp:
|
|
cp '\n'
|
|
jr nz,nonl
|
|
ld a,79
|
|
ld (pos),a
|
|
ld a,'\n'
|
|
nonl: cp '\r'
|
|
jr nz,nocr
|
|
ld a,0xff
|
|
ld (pos),a
|
|
ld a,'\r'
|
|
nocr: cp '\t'
|
|
jr z,tablp
|
|
call prtopc
|
|
jr chk80
|
|
tablp: ld a,' '
|
|
call prtopc
|
|
ld a,(pos)
|
|
and 7
|
|
jr nz,tablp
|
|
chk80: ld hl,pos
|
|
ld a,(hl)
|
|
xor 80
|
|
call z,newlin
|
|
ret
|
|
|
|
prtopc: ld c,a
|
|
ld a,(optype)
|
|
or a
|
|
ld a,c
|
|
jp nz,scrout
|
|
ld hl,mode
|
|
ld e,(hl)
|
|
push hl
|
|
push de
|
|
ld (hl),lf_bit
|
|
call opchar
|
|
pop de
|
|
pop hl
|
|
ld (hl),e
|
|
ld hl,pos
|
|
inc (hl)
|
|
ret
|
|
|
|
newlin: ld (hl),a ; set char count back to zero
|
|
inc hl ; point at line count
|
|
inc (hl) ; bump that too
|
|
ld a,(hl)
|
|
xor 23 ; 23 lines?
|
|
ret nz ; return if not
|
|
ld a,(pagerf)
|
|
or a
|
|
ret z ; and return if not paging
|
|
dec (hl) ; set back to 22 in case we get a return
|
|
ld hl,mmsg
|
|
.dseg
|
|
mmsg: db '[more]\0'
|
|
.cseg
|
|
call prtsl1 ; print more message
|
|
call kbdin ; get a character
|
|
ld hl,cmstr
|
|
.dseg
|
|
cmstr: db '\r \r\0'
|
|
.cseg
|
|
cp (hl) ; return?
|
|
jr z,clrmor ; yes - just remove '[more]', linec is set
|
|
xor 'x' & 0x1f
|
|
jr z,retcx ; special exit on a ^X
|
|
xor a
|
|
ld (linec),a ; else clear linc for a full page
|
|
clrmor: jp prtsl1 ; and remove the more message
|
|
|
|
retcx: call prtsl1 ; come here after a ^X - we remove the message
|
|
scf ; and return carry to flag the exit
|
|
ret
|
|
|
|
.extern clrpsp
|
|
clrpsp:
|
|
db 0x3e ; makes a ld a,xx
|
|
|
|
.extern clrpcp
|
|
clrpcp:
|
|
xor a
|
|
ld (pagerf),a
|
|
push hl
|
|
ld hl,0
|
|
ld (pos),hl
|
|
pop hl
|
|
ret
|
|
|
|
.extern mtprt ; a call to this is followed by inline coords.
|
|
mtprt: ; and a string to be printed at the coords
|
|
pop hl
|
|
ld e,(hl)
|
|
inc hl
|
|
ld d,(hl) ; get moveto coordinates
|
|
inc hl
|
|
push hl ; save address of string
|
|
ex de,hl ; coords to hl
|
|
call moveto ; move to wherever
|
|
pop hl ; restore string to hl
|
|
call prtslp ; print it
|
|
jp (hl) ; and return
|
|
|
|
.extern decob ; print number in l, by zeroing h
|
|
decob:
|
|
ld h,0 ; clear h and fall through
|
|
|
|
.extern decout ; print number in hl in decimal
|
|
decout:
|
|
push de ; save running total
|
|
push bc ; save char count
|
|
ld bc,-10
|
|
ld de,-1
|
|
decou2: add hl,bc
|
|
inc de
|
|
jr c,decou2 ; divide hl by 10
|
|
sbc hl,bc ; reset because of overflow
|
|
ex de,hl ; remainder to e, answer to hl
|
|
ld a,h
|
|
or l
|
|
pop bc ; restore char count for next call
|
|
call nz,decout ; answer non-zero: print recursively
|
|
ld a,e ; get remainder
|
|
add a,'0'
|
|
ld c,a
|
|
push bc
|
|
call scrout ; print to screen as a digit
|
|
pop bc
|
|
dec b ; keep count of printed chars in b
|
|
pop de ; restore total
|
|
ret
|
|
|
|
.extern break
|
|
break:
|
|
call tenth ; wait a while before beginning
|
|
call sbreak ; start the break
|
|
call tenth3 ; idle for 3/10 of a second
|
|
jp ebreak ; finish off by ending the break
|
|
|
|
.extern hangup
|
|
hangup:
|
|
ld hl,#dtroff
|
|
ld a,(hl)
|
|
cp 0xc9 ; return at dtroff => no code
|
|
jr z,strhup ; so send a string instead
|
|
call dtroff ; drop dtr - should make modem hang up
|
|
call tenth3
|
|
call tenth3 ; wait a (long) while
|
|
jp dtron ; dtr back on
|
|
strhup: ld ix,hangup - slow
|
|
inc hl
|
|
ld b,(hl) ; get the string length
|
|
inc hl
|
|
jp sendcs ; and out it goes
|
|
|
|
tenth3: call tenth
|
|
call tenth
|
|
|
|
.extern tenth ; delay for 1/10 of a second, but continue to
|
|
tenth: ; save incoming chars
|
|
ld de,100
|
|
call setspd ; get speed constant to hl
|
|
tnthlp: ld b,60
|
|
tnthl1: djnz tnthl1 ; idle a while
|
|
push hl
|
|
call savrng ; check incoming chars, but only as far as
|
|
pop hl ; the ring buffer
|
|
dec hl ; count main timer
|
|
ld a,h
|
|
or l
|
|
jr nz,tnthlp
|
|
ret
|
|
|
|
.extern tnthip ; delay for 1/10 of a second, but continue to
|
|
tnthip: ; check the modem for incoming chars
|
|
ld de,100
|
|
|
|
.extern msip ; delay for de msec, but continue to
|
|
msip: ; check the modem for incoming chars
|
|
ld a,d
|
|
or e ; anything in de?
|
|
ret z ; nope - return right now
|
|
call setspd ; get speed constant to hl
|
|
msil: ld b,60
|
|
msl2: djnz msl2 ; idle a while
|
|
push hl
|
|
call lstmod ; process incoming chars and printer output
|
|
pop hl
|
|
dec hl ; count main timer
|
|
ld a,h
|
|
or l
|
|
jr nz,msil
|
|
ret
|
|
|
|
.extern setspd ; take 1MHz value in de, get correct value in
|
|
setspd: ; hl based on cpu speed
|
|
ld hl,0
|
|
ld a,(speed)
|
|
ld b,a ; get cpu speed to b
|
|
spdok: add hl,de ; multiply de by b
|
|
djnz spdok
|
|
ret
|
|
|
|
.extern help
|
|
help:
|
|
call crlf ; start off with a new line
|
|
call dim ; and dim
|
|
call presc ; print the escape character
|
|
or a ; test the flag
|
|
ld c,' '
|
|
call z,scrout ; print a space if no '^'
|
|
call ilprt ; and finish off
|
|
db ' - Transmit escape character\t '
|
|
db '? - Print this help\r\n'
|
|
db '. - Send a break\t\t\t'
|
|
db ', - Hang up modem\r\n'
|
|
db 'B - Change baud rate and mode\t\t'
|
|
db 'C - Open an input catch file\r\n'
|
|
db 'D - Display local directory\t\t'
|
|
db 'E - Toggle remote echo\r\n'
|
|
db 'H - Toggle half duplex\t\t'
|
|
db 'I - Print settings information\r\n'
|
|
db 'J - Junk control characters\t\t'
|
|
db 'K - Load a function key\r\n'
|
|
db 'L - Toggle linefeed transmit for \'P\'\t'
|
|
db 'M - Toggle bit 7 mask\r\n'
|
|
db 'N - Select new default drive / user\t'
|
|
db 'O - Toggle output to printer\r\n'
|
|
db 'P - Print a file to remote\t\t'
|
|
db 'Q - Quit\r\n'
|
|
db 'R - Receive a file using protocol\t'
|
|
db 'S - Send a file using protocol\r\n'
|
|
db 'T - Type a local file\t\t\t'
|
|
db 'U - Invoke user function\r\n'
|
|
db 'V - Toggle VT100 Emulation\t\t'
|
|
db 'W - Toggle split window mode\r\n'
|
|
db 'X - Activate a chat script\t\t'
|
|
db 'Y - Put catch file on hold\r\n'
|
|
db 'Z - Close catch file\t\t\t'
|
|
db '0-9 - Send function key string\r\n'
|
|
db 0
|
|
ret
|
|
|
|
.extern info ; print current settings
|
|
info:
|
|
call ilprt
|
|
db '\r\nEscape character:\t\0'
|
|
call dim
|
|
call presc ; print the escape character
|
|
call ilprt
|
|
db '\r\nCurrent drive / user:\t\0'
|
|
call dim
|
|
ld hl,(curusr) ; get the current drive & user
|
|
ld a,h
|
|
add a,'A' ; convert drive to a letter
|
|
ld c,a
|
|
push hl
|
|
call scrout ; print the drive
|
|
pop hl
|
|
call decob ; and print the user in l
|
|
call ilprt
|
|
db ':\r\n\0'
|
|
ld a,(rate)
|
|
cp ' '
|
|
jr z,norate
|
|
call ilprt
|
|
db 'Baud rate:\t\t\0'
|
|
call dim
|
|
ld hl,rate
|
|
call prtslp
|
|
norate: ld a,(modsav)
|
|
cp ' '
|
|
jr z,nomode
|
|
call ilprt
|
|
db 'Communication Mode:\t\0'
|
|
call dim
|
|
ld hl,modsav
|
|
call prtslp
|
|
nomode: call ilprt
|
|
db '^S delay:\t\t\0'
|
|
call dim
|
|
ld hl,(csdely) ; get the delay count
|
|
call decob ; out it goes
|
|
call ilprt
|
|
db ' second(s)\r\nHalf duplex:\t\t\0'
|
|
ld a,(hflg)
|
|
call onoff ; say whether HDX is on or off
|
|
call ilprt
|
|
db 'Local echo:\t\t\0'
|
|
ld a,(eflg)
|
|
call onoff ; say what local echo is up to
|
|
call ilprt
|
|
db 'Control char. discard:\t\0'
|
|
ld a,(jflg)
|
|
call onoff ; say what local echo is up to
|
|
call ilprt
|
|
db 'Linefeed in \'P\':\t\0'
|
|
ld a,(lflg)
|
|
call onoff ; line feed in print
|
|
call ilprt
|
|
db 'Character delay:\t\0'
|
|
call dim
|
|
ld hl,(chd) ; get the character delay
|
|
call decob ; out it goes
|
|
call ilprt
|
|
db ' msec. \0'
|
|
ld a,(ecflg)
|
|
or a
|
|
jr z,noeci
|
|
call ilprt
|
|
db '\techo check\0'
|
|
noeci: call ilprt
|
|
db '\r\nNew line delay:\t\t\0'
|
|
call dim
|
|
ld hl,(nld) ; new line delay is a word
|
|
call decout
|
|
call ilprt
|
|
db ' msec. \0'
|
|
ld a,(lfecho)
|
|
or a
|
|
jr z,nolfe
|
|
push af
|
|
call ilprt
|
|
db '\tnewline echo: \'\0'
|
|
call dim
|
|
pop af
|
|
ld c,a
|
|
call scrout
|
|
ld c,'\''
|
|
call scrout
|
|
nolfe: call ilprt
|
|
db '\r\nBit 7 masking:\t\t\0'
|
|
ld a,(bmask)
|
|
inc a
|
|
call onoff ; say what bit 7 masking is up to
|
|
call ilprt
|
|
db 'VT100 emulation:\t\0'
|
|
ld a,(vflg)
|
|
call onoff ; and vt100 emulation
|
|
call ilprt
|
|
db 'Printer output:\t\t\0'
|
|
ld a,(oflg)
|
|
call onoff ; and printer output
|
|
ld a,(cflg)
|
|
or a
|
|
jr nz,isctch ; catch file active?
|
|
call ilprt ; if not then say so
|
|
db 'Not catching\r\n\0'
|
|
ret
|
|
isctch: call ilprt
|
|
db 'Current catch file:\t\0'
|
|
call dim
|
|
ld hl,cfcb
|
|
call prtfl ; otherwise print the filename
|
|
ld a,(cflg)
|
|
dec a
|
|
jp z,crlf ; if active we're done
|
|
call ilprt ; else say it's on hold
|
|
db ' (on hold)\r\n\0'
|
|
ret
|
|
|
|
onoff: or a ; is the flag active
|
|
jr z,proff ; jump if not
|
|
call ilprt
|
|
db 'on\r\n\0' ; say it's on
|
|
ret
|
|
proff: call ilprt
|
|
db 'off\r\n\0' ; or say it's off
|
|
ret
|
|
|
|
.extern presc
|
|
presc:
|
|
ld b,0
|
|
ld a,(escval) ; get the escape character
|
|
cp ' '
|
|
jr c,prthat ; it's a control char - print the ^
|
|
cp 0x7f
|
|
jr nz,nohat ; also do that for deletes
|
|
prthat: ld c,'^'
|
|
push af ; save the escape val
|
|
call scrout ; print the ^
|
|
pop af
|
|
ld b,64 ; flag we printed the ^
|
|
xor b ; and "uncontrollify" the char
|
|
nohat: ld c,a
|
|
push bc ; save flag
|
|
call scrout ; print the char
|
|
pop af ; flag back to a
|
|
ret
|
|
|
|
.extern quit
|
|
quit:
|
|
call cclose ; close catch file if open
|
|
ld hl,23 * 256 ; blh corner of screen
|
|
call moveto ; go there
|
|
call exit ; call custom unwind code
|
|
rst 0 ; exit to cp/m
|
|
|
|
.extern conin ; get char from function key or keyboard
|
|
conin:
|
|
ld a,(fkdely) ; check if we need to delay
|
|
or a
|
|
call nz,tnthip ; idle a while if we do
|
|
ld hl,(fkptr)
|
|
ld a,(hl) ; get the next char
|
|
inc hl
|
|
ld (fkptr),hl ; save revised pointer
|
|
ret ; char is in a
|
|
|
|
.extern ctls
|
|
ctls:
|
|
ld a,(lxoff) ; get local xon / xoff status
|
|
or a
|
|
ld a,(cschr)
|
|
call nz,modopc ; send the xoff if needed
|
|
ld a,(csdely)
|
|
or a
|
|
ret z ; if it's zero, return right now
|
|
ld b,a ; get the delay value
|
|
add a,a
|
|
add a,a
|
|
add a,b
|
|
add a,a ; * 10
|
|
ld b,a ; to b
|
|
waitlp: push bc
|
|
call tenth ; wait a while
|
|
pop bc
|
|
djnz waitlp
|
|
ret
|
|
|
|
.extern gotxon ; flag that an xon was sent from the kbd,
|
|
gotxon: ; so we don't re-send
|
|
ld (lxoff),a ; set the local xoff flag
|
|
ret
|
|
|
|
.extern gotxof ; flag that an xof was sent: this just clears
|
|
gotxof: ; the flag set in gotxon
|
|
ld hl,lxoff
|
|
ld (hl),0
|
|
ret
|
|
|
|
.extern areabp ; areabp used in chat scripts: point at first
|
|
areabp: ; non-white in text of a '!' command
|
|
ld hl,area - 1 ; point at chat parse area and fall into byp
|
|
|
|
.extern incbyp
|
|
incbyp: ; inc hl, and then byp
|
|
inc hl
|
|
|
|
.extern byp ; step over spaces in string pointed to by hl
|
|
byp:
|
|
ld a,(hl)
|
|
cp ' '
|
|
ret nz ; return on the first char that is NOT a space
|
|
inc hl
|
|
jr byp
|
|
|
|
.extern ldfnk ; this will prompt and then use the string
|
|
ldfnk: ; to program one of the 10 function keys
|
|
ld hl,zero ; point the readback pointer at a zero
|
|
ld (fkptr),hl ; in case we change the string under it
|
|
call prompt
|
|
db 'Key value: \0' ; get the string
|
|
ld hl,ipbuf
|
|
call byp ; strip spaces
|
|
or a
|
|
ret z ; skip if nothing to do
|
|
cp '\e'
|
|
ret z ; or if an escape typed
|
|
ld c,0 ; clear c (will become slow/fast flag)
|
|
sub '0'
|
|
cp 10
|
|
jr c,fast ; 0-9: is a fast, key index in a
|
|
ld c,a ; non-digit: save a non-zero in c
|
|
inc hl
|
|
ld a,(hl) ; get the next character
|
|
sub '0' ; and turn it into an index
|
|
fast: cp 10
|
|
jr c,fnkok ; check it's ok
|
|
call ilprt ; complain and return if not
|
|
db 'Invalid function key number\r\n\0'
|
|
ret
|
|
fnkok: inc hl ; point at string to be parsed
|
|
push hl ; save input string address
|
|
add a,a
|
|
add a,a
|
|
add a,a
|
|
add a,a ; turn index into table offset
|
|
ld e,a
|
|
ld d,0 ; goes in de
|
|
ld hl,fktbl
|
|
add hl,de ; get table entry address
|
|
ld (hl),c ; save speed flag
|
|
inc hl
|
|
ex de,hl ; string target address to de
|
|
pop hl ; text back to hl
|
|
ld bc,14 << 8 ; 14 chars, zero byte delimits
|
|
jp parst ; go parse the string, and we're done
|
|
|
|
.extern cbios ; call the entry point in the bios witn number
|
|
cbios: ; in a, saving ix and iy as we go
|
|
push ix
|
|
push iy
|
|
call #bios
|
|
pop iy
|
|
pop iy
|
|
ret
|
|
|
|
#bios: ; offset is in a
|
|
ld hl,(1) ; get the warm boot value to hl
|
|
ld l,a ; modify with function number
|
|
jp (hl) ; go do the code
|
|
|
|
.dseg
|
|
optype: db 0
|
|
bflag: db 0
|
|
.extern lxoff
|
|
lxoff: db 1
|
|
.extern prmpfl
|
|
prmpfl: db 0
|
|
.extern fkptr
|
|
fkptr: dw zero
|
|
|
|
.useg
|
|
pos: ds 1
|
|
linec: ds 1
|
|
pagerf: ds 1
|
|
.extern fkdely
|
|
fkdely: ds 1
|
|
.extern fktbl
|
|
fktbl: ds 16 * 10
|
|
|