home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
sigm
/
sigmv068.ark
/
PLINK65.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
24KB
|
1,158 lines
; PLINK.ASM ver 6.5
; (revised 6/26/81)
;
;PLINK is a CP/M transient command which allows the user to
;establish a communications link with a remote computer.
;
;This program currently supports the following modems or computers
;via conditional assembly:
;
; 1. PMMI modem
; 2. Any serial I/O board (TUART included)
; 3. TRS-80 model 1
; 4. TRS-80 model 2
; 5. Heath H8/H89 with 8250 uart at port 330Q
; 6. D.C.Hayes 80-103A or Micromodem 100
; 7. MITS 2SI/O board, ports 10h &11h = console, 12h & 13h = modem
; 8. Intel SBC or National BLC multi-bus boards using 8251 USART
;
;Originally written by L.E. Hughes (EDCAM) in July, 1977. Many
;modifications have been made since this time, as shown in the
;following summary.
;
;Fixes/updates (in reverse order to minimize reading time):
;
; June 26, 1981. Added message when exiting if last buffer was
; not saved. Ted Shapin.
;
;June 14, 1981, by Keith Petersen, W8SDZ. Changed port
;equate to 'equ' instead of 'set'. ASM doesn't like 'set'
;when later conditionals are based on a label defined that
;way.
;
;June 7, 1981, by Tom Jorgenson (CP-MIG). Changed CP/M
;origin from being via SETs to referenced to BASE, added
;TRUE/FALSE rather than numeric values (for readability),
;changed ^Q function to ^W (write) because some systems
;(notably Micronet) use ^S/^Q to suspend/resume output,
;changed page 0 references in TRS routines to use
;BASE equate properly, changed PORT equates to default
;to TRUE, reinserted Heath equates, and cleaned up code
;in several places.
;
;June 7, 1981, by Keith Petersen, W8SDZ. Fixed problem with
;equates which prevented assembly by 'ASM' when TUART option
;was selected.
;
;June 6, 1981, by Keith Petersen, W8SDZ. Added version number,
;cleaned up file.
;
;May 12, 1981, by T. Shapin. Added code for 8251 USART on Intel
;SBC or National BLC multibus board with modified CP/M origin.
;Added prompt to signon. Added toggle to ^Y to save or ignore
;incoming text. Added ^C abort on file name response.
;
;November 10, 1980, by Kelly Smith. Added conditional assembly
;switch for MITS 2SI/O board, using "standard" MITS ports 10 and
;11 hex for the console, and 12 and 13 hex for the modem.
;
;October 18, 1980, by Keith Petersen, W8SDZ.
;
;Heath equates added by Tom Jorgenson.
;
;TRS-80 model 1 mods by Steve Vinokuroff, Vancouver CBBS.
;
;Optional trigger characters by Steve Vinokuroff.
;
;TRS-80 mods by Dennis Breckenridge, Burnaby CBBS.
;
;D.C.Hayes mods by Bruce Ratoff, Iselin New Jersey Remote CP/M.
;
;NOTE: If you add improvements or otherwise update
;this program, please modem a copy of the new file
;to "TECHNICAL CBBS" in Dearborn, Michigan - phone
;313-846-6127 (110, 300, 450 or 600 baud). Use the
;filename PLINKXX.NEW.
;
;PLINK currently supports two way transfer of text files between
;the CP/M disk and the remote computer. The following control
;codes may be initiated from the console keyboard:
;
;Control-E Exit PLINK to CP/M "warm-boot".
;
;Control-T Transmit ASCII file to remote system, asks for
; drive (A, B, etc.) and filename.typ.
;
;Control-C Aborts transmission of file to remote system.
;
;Control-Y Switches between saving and ignoring
; incoming ASCII data in RAM buffer,
; for later transfer to disk.
;
;Control-W Writes RAM buffer to disk, and asks for drive
; and filename.typ.
;
;Del (delete) Backspace when in command mode (e.g. ^T or ^W).
;
;Control-U Aborts current line when in command mode.
;
;(Note: all other control codes are passed to modem output, and
;may be interpreted by the remote system as various control
;functions.)
;
;TRUE/FALSE definitions
;
FALSE equ 0
TRUE equ NOT FALSE
;
;Conditional assembly switches <<-- set for your system
;(select only one as true) - (NOTE: use TUART for other
;serial ports not defined).
;
MITSIO equ FALSE ;true, if MITS 2SI/O board
H84 equ FALSE ;true, if you have H8/H8-4 or H89
TUART equ FALSE ;true, if Cromenco TUART or OTHER SERIAL
PMMI equ TRUE ;true, if PMMI (set INITREQ true only
;if orig mode and parity is required)
DCH equ FALSE ;true, if D.C.Hayes
TRS1 equ FALSE ;true, if TRS-80 model 1
TRSPT equ FALSE ;true, if TRS-80 model 2
;using pickles & trout CP/M 2.x
MULTI equ FALSE ;true, if SBC or BLC 8251 USART
;
INITREQ equ FALSE ;true, if port initialization required
;
IF NOT TRSPT
PORT equ TRUE ;true, on most systems
ENDIF
;
IF TRSPT
PORT equ FALSE ;this is the oddball
ENDIF
;
;bdos entry point and function codes
;
base equ 0 ;<<-- set to offset of CP/M for your
;system, standard systems are 0, some
;'alternate' systems are 4200H
;
bdos equ base+5
resdsk equ 13 ;reset disk system
offc equ 15 ;open file
cffc equ 16 ;close file
dffc equ 19 ;delete file
rrfc equ 20 ;read record
wrfc equ 21 ;write record
mffc equ 22 ;make file
;
;TRS80 pickles and trout sio calls
;offset by -3 that is add 3 to all calls
;
setsio equ 30h ;set up z80 sio
siotst equ 33h ;read sio status
sioinp equ 36h ;input a char
sioout equ 39h ;output a char
;
IF MULTI
mods equ 0DDH ;modem control
mtbe equ 1 ;bit to test for send
mrda equ 2 ;bit to test for receive
mxor equ 3 ;mask to make MTBE and MRDA 'low true'
modd equ 0DCH ;modem data port
ENDIF
;
;default fcb and field definitions
;
fcb equ base+5ch
fn equ 1 ;file name field (rel)
ft equ 9 ;file type field (rel)
ex equ 12 ;file extent field (rel)
nr equ 32 ;next record field (rel)
dbuf equ base+80h ;default disk buffer address
;
;ascii control characters
;
cr equ 0dh ;carriage return
lf equ 0ah ;line feed
del equ 7fh ;delete (rubout)
bell equ 07h ;bell signal
tab equ 09h ;horizontal tab
xon equ 11h ;x-on character
null equ 00h ;null char
;
;the following "trigger" equate is set to "lf" (linefeed)
;by default. an optional trigger char may be passed via fcb1
;
; ie: PLINK B will set trigger to "bell"
;
;the following options are allowed
;
; 1. B = bell 07h
; 2. X = xon 11h
; 3. U = upload no trigger check at all
;
;any other ascii character may be passed through fcb1
;
;
trigger equ LF ;default value
;
;
;warning character for low memory
;
wrnsig equ BELL ;if you have one, put 'BELL' here
;...else put '*' here.
;
;modem i/o port addresses
;
IF MITSIO
modd equ 13h ;modem data port
mods equ 12h ;modem status port
modrset equ 03h ;6850 ACIA reset
modinit equ 11h ;8 data, no parity, 2 stop
ENDIF
;
IF H84
modd equ 330Q ;modem data port
mods equ 335Q ;modem status port
ENDIF
;
IF PMMI
modd equ 0c1h ;modem data port
mods equ 0c0h ;modem status port
modinit equ 29h ;initialize byte originate,
;7 data, even parity, 1 stop
ENDIF
;
IF DCH
modd equ 90h ;modem data port
mods equ 91h ;modem status port
modinit equ 05h ;7 data, even parity, 1 stop
ENDIF
;
IF TRS1
modd equ 0ebh ;TRS80 mod 1 rs232 data port
mods equ 0eah ; and the rs232 status port
ENDIF
;
IF TUART
modd equ 0d6h ;<<--modify for yours
mods equ 0d7h ;<<--modify for yours
ENDIF
;
;modem status port bit definitions
;
IF H84
mtbe equ 40Q ;modem THRE transmit ready bit
mrda equ 01Q ;modem RDA rec'd data bit
mxor equ 41Q ;mask to make mtbe and mrda 'negative logic'
ENDIF
;
IF PMMI
mtbe equ 01h ;modem trans. buffer ready flag
mrda equ 02h ;modem receive data avail. flag
mxor equ 03h ;mask to make mtbe and mrda "low true"
ENDIF
;
IF DCH or MITSIO
mtbe equ 02h ;modem trans. buffer ready flag
mrda equ 01h ;modem receive data avail. flag
mxor equ 03h
ENDIF
;
IF TRS1
mtbe equ 40h ;TRS80 mod1 rs232 buffer ready
mrda equ 80h ;modem receive data avail.
mxor equ 0c0h
ENDIF
;
IF TUART ;<<--or any other serial i/o
mtbe equ 1 ;<<--modify for yours
mrda equ 2 ;<<--modify for yours
mxor equ 3 ;<<--modify for yours
ENDIF
;
; **main program**
;
org base+100h
;
link: lxi sp,stack+64 ;create local stack
lhld base+1 ;point to CP/M jmp table
lxi d,3 ;get ready to add 3
dad d ;point to con status jmp
shld citcal+1 ;modify call adrs
dad d ;point to con in jmp
shld rccal+1 ;modify call adrs
dad d ;point to con out jmp
shld wccal+1 ;modify call adrs
lda fcb+1 ;see if optional trigger char
cpi 20h ;blank.. ?
jz skp ;..blank so use default "lf"
cpi 'B' ;bell wanted
jz trgbel
cpi 'X' ;xon wanted
jz trgxon
cpi 'U' ;uploading no checking for trigger
jz trgupl
;
settrg sta overly+1 ;store the character as is then
jmp skp
;
trgbel mvi a,bell
jmp settrg
;
trgxon mvi a,xon
jmp settrg
;
trgupl xra a ;zero out jump
sta overl1+1 ;change check for c/r to null
sta overl2+1 ;and send linefeeds as well
jmp skp
;
skp: equ $
;
IF MITSIO
mvi a,modrset
out mods
mvi a,modinit
out mods
ENDIF
;
IF H84
mvi a,80h ;set dlab bit in 8250 uart
out 0dbh ;8250 at port d8h (330q)
nop ! nop ! nop
nop ! nop
mvi a,01h ;msb of baud rate divisor
out 0d9h ;...to uart
nop ! nop ! nop
nop ! nop
mvi a,80h ;lsb of baud rate divisor
out 0d8h ;...to uart
nop ! nop ! nop
nop ! nop
mvi a,03h ;8 bits, 1 stop bit, no parity, dlab reset
out 0dbh ;...to uart
nop ! nop ! nop
nop ! nop
mvi a,0 ;reset control register
out 0dch ;...to uart
jmp cont
ENDIF
;
IF INITREQ and (NOT H84) and (NOT MITSIO)
mvi a,modinit
out mods ;initialize modem port
ENDIF
;
IF INITREQ and TUART
mvi a,80h ;dsr on bit 7 parl port b
out 54h
ENDIF
;
IF TRSPT ;must set up serial channel
reset: lxi h,initr ;store return address
push h
lhld 1
lxi d,setsio ;sio setup routine
dad d
push h ;store on stack
mvi c,00h ;no parity chan-a
mvi d,0e6h ;8 bits ,1 stop
mvi e,3 ;300 baud
mvi l,00h ;disable ext/ack sio functions
mvi h,'S'-40h ;control s (x-on)
ret ;trough setup prog
;
initr nop ;do it to it
ENDIF
;
IF TRS1 ;init for TRS80 mod1 rs232
out 0e8h ;reset rs232
in 0e9h ;read the switches
ani 0f8h
ori 5
out 0eah ;set dsr and cts
mvi a,55h ;300 baud
out 0e9h
ENDIF
;
IF PORT
in modd ;clear modem uart read buffers
in modd
ENDIF
;
IF MULTI ;initialize 8251
xra a
out mods
out mods
out mods
mvi a,40h
out mods
mvi a,0cfh ;300 baud (this depends on strapping)
out mods
mvi a,37h
out mods
ENDIF
;
cont: xra a ;clear char buffers
sta inch
sta outch
sta flag ;clear text save flag
lxi h,tbuf ;set ptr to tbuf
shld ptr
lxi h,0 ;size = 0
shld size
lxi h,linkms ;print sign-on message
call wcs
;
;main loop
;
link3: call citest ;jump if no data from console
jz link4
call rcc ;else read console data
cpi 20h
cc pcc ;call pcc if control char
jc link4 ;jump if pcc handled char
ori 80h ;else set valid data bit
sta inch ;and store in input char buffer
;
link4: lda outch ;jump if no data for console
ora a
jp link5
ani 7fh ;else discard valid data bit
call wcc ;send char to console
xra a ;then clear output char buffer
sta outch
;
link5: call mitest ;jump if no data from modem
jz link6
call rmc2 ;else read modem data
call save ;save char in text buffer if flag on
ori 80h ;set data valid bit
sta outch ;store in output char buffer
;
link6: call motest ;jump if modem xmit buffer busy
jz link7
lda inch ;jump if no data for modem
ora a
jp link7
ani 7fh ;discard valid data bit
;
IF PORT
out modd ;output char to modem
ENDIF
;
IF TRSPT
push b ;store registers
push h
push d
call wmc ;send char
pop d
pop h
pop b
ENDIF
;
xra a ;...then clear input char buffer
sta inch
;
link7: jmp link3 ;end of main loop
;
linkms: db cr,lf,'PLINK ver 6.5'
db cr,lf,cr,lf
db '[^T]ransmit, [^Y]ank, [^W]rite, [^E]xit, [^C]ancel'
db cr,lf,'Ready',cr,lf,lf,0
;
;pcc - process control character
;
pcc: cpi 'E'-40h ;jump out if ctrl e
jnz pcc1
push h
lhld size ; check for something in text buffer
mov a,l ; and give warning
ora h
jz pccex ; before exit
lxi h,ays ;print 'do you want to save...
call wcs
pop h
call rcc ;get answer
call wcc ;echo it
ani 5fh ;make upper case
cpi 'Y' ;yes?
cz wtb ; write out buffer
jmp pccex ;exit
; call wccr ;crlf
; stc ;tell plink to ignore this character
;
IF TRSPT
pop psw ;gobble up call address
jmp reset ;re-initialize sio
ENDIF
;
IF PORT
ret
ENDIF
;
pcc1: cpi 'T'-40h ;jump if not control-t
jnz pcc2
call stf ;transmit text file to modem
stc ;tell plink to ignore this character
ret
;
pcc2: cpi 'Y'-40h ;jump if not control-y
jnz pcc3
lda flag
dcr a ;was it zero?
jnz pcc2a ;yes
sta flag ;no, was 1, now 0
lxi h,pcmnix ;print ignore incoming stuff
jmp pcc2b
;
pcc2a: mvi a,1 ;turn on text save flag
sta flag
lxi h,pccmr ;print 'saving incoming text in memory'
;
pcc2b: call wcs
stc ;tell plink to ignore this character
ret
;
pcc3: cpi 'W'-40h ;jump if not control-W
jnz pcc4
xra a ;turn off text save flag
sta flag
call wtb ;write text buffer to disk
stc
ret
;
pcc4: stc ;let plink handle all other cont. codes
cmc
ret
;
pccex: lxi h,disms ;print 'modem not disconnected'
call wcs
jmp base ;exit to warm boot
;
ays: db cr,lf,'Do you want to save the stuff in'
db cr,lf,'the buffer before exit to CP/M (Y or N)? ',0
;
IF PMMI or DCH
disms: db cr,lf,'Don''t forget - the modem '
db 'is not disconnected',cr,lf
db 'use "MODEM D" to disconnect',0
ENDIF
;
IF (NOT PMMI) and (NOT DCH)
disms: db cr,lf,'+++ Exit to CP/M +++',cr,lf,0
ENDIF
;
pccmr: db cr,lf,'Saving incoming text in memory',cr,lf,0
pcmnix: db cr,lf,'Ignoring incoming text',cr,lf,0
;
;stf - send text file (to modem)
;
stf: call gfn ;get name of disk file to send
jc stf6 ;jump if file name error
call open ;try to open specified file
cpi 255 ;jump if file not found
jz stf7
;
stf1: call read ;read next record into dbuf
cpi 1 ;jump if end-of-file
jz stf5
lxi h,dbuf ;point to disk buffer
mvi c,128
;
stf2: mov a,m ;fetch next char from dbuf
inx h
cpi 'Z'-40h ;jump if end-of-file character
jz stf5
;
overl2 cpi lf ;ignore line feeds
jz stf4
call wmc ;write character to modem
call wcc ;write character to console
;
overl1 cpi cr ;jump if not carriage return
jnz stf4
;
stf3: call citest ;check console data ready
jz stf3a ;no data there
call rcc ;get console character
cpi 'C'-40h ;control c aborts it
jz stf8
;
stf3a: call mitest ;wait for next modem character
jz stf3
call rmc2 ;check modem for trigger char.
;
overly cpi trigger
jnz stf3
call wccr ;send crlf to console
;
stf4: dcr c ;loop thru rest of dbuf
jnz stf2
jmp stf1 ;go get next record from disk
;
stf5: lxi h,stfsm ;print 'file send complete'
call wcs
ret
;
stf6: lxi h,stfs1 ;print 'file name error'
call wcs
ret
;
stf7: lxi h,stfs2 ;print 'file not found'
call wcs
ret
;
stf8: lxi h,stfsa ;print 'file send aborted'
call wcs
ret
;
stfsm: db 'File send complete',cr,lf,0
stfs1: db 'File name error or abort',cr,lf,0
stfs2: db 'File not found',cr,lf,0
stfsa: db cr,lf,'File send aborted',cr,lf,0
;
;save - save char in text buffer if flag on
;
; entry conditions
; a - character to save
;
save: push psw
lda flag
ora a
jnz save1
pop psw
ret
;
save1: pop psw
cpi del ;rubout (del) ?
rz ;yes, ignore it
cpi 20h ;test for control characters
jnc save2 ;jump if not control char.
cpi cr ;allow cr to be saved
jz save2
cpi lf ;allow lf to be saved
jz save2
cpi tab ;allow tab to be saved
jz save2
ret ;ignore all other control chars.
;
save2: push h
lhld size ;size = size + 1
inx h
shld size
lhld ptr
mov m,a
inx h
shld ptr
push psw
lda base+7 ;get system size
sui 1 ;so we dont crash CP/M
cmp h ;are we out of room?
jz saveab ;yes, abort
sui 4 ;leave some room (1k)
cmp h
mvi a,wrnsig ;signal console running out of space
cc wcc
pop psw
pop h
ret
;
;saveab - ran out of room, issue message and flow
; through to disk save routine
;
savend: db bell,cr,lf,'Aborting - no room left',0
;
saveab: lxi sp,stack+64 ;reinitialize stack
lxi h,savend ;print 'aborting - no room left'
call wcs
lxi h,link ;set up return address
push h ;leave it on the stack
;
;wtb - write text buffer to disk
;
wtb: lhld size ;jump if text buffer empty
mov a,l
ora h
jz wtb5
mvi c,resdsk ;reset in case read-only
call bdos
call gfn ;get file name
jc wtb6 ;jump if file name error
call delt ;delete old file, if any
call make ;make new file
lhld size ;de = tbuf size
xchg
lxi h,dbuf ;top of stack points to dbuf
push h
lxi h,tbuf ;hl points to tbuf
;
wtb1: mvi c,128 ;disk buffer size
;
wtb2: mov a,m ;fetch next byte of tbuf
inx h
xthl
mov m,a ;store in dbuf
inx h
xthl
dcx d ;size = size - 1
mov a,d ;exit loop if size = 0
ora e
jz wtb3
dcr c ;loop until dbuf full
jnz wtb2
call write ;write full dbuf to disk
xthl ;top of stack points to dbuf
lxi h,dbuf
xthl
jmp wtb1 ;loop until end of tbuf
;
wtb3: pop h ;hl points to current place in dbuf
;
wtb4: mvi m,'Z'-40h ;store eof code
inx h
dcr c ;loop thru rest of dbuf
jnz wtb4
call write ;write last sector to disk
call close ;clean up act and go home
lxi h,tbuf ;clear text buffer
shld ptr
lxi h,0
shld size
lxi h,wtbsm ;print 'buffer saved on disk'
call wcs
ret
;
wtb5: lxi h,wtbs1 ;print 'text buffer empty'
call wcs
ret
;
wtb6: lxi h,wtbs2 ;print 'file name error'
call wcs
ret
;
wtbsm: db cr,lf,'Buffer saved on disk',cr,lf
db 'Memory save cancelled',cr,lf,0
wtbs1: db 'Text buffer empty',cr,lf,0
wtbs2: db 'File name error or abort',cr,lf,0
;
;wcs - write console string
;
; entry conditions
; hl - points to string (term by zero byte)
;
wcs: mov a,m
inx h
ora a
rz
call wcc
jmp wcs
;
;wccr - write console carriage return (and line feed)
;
wccr: mvi a,cr
call wcc
mvi a,lf
;
;wcc - write console character
;
; entry conditions:
; a - character to write
;
wcc: push psw
push b
push d
push h
mov c,a ;get character for cbios
wccal: call $-$ ;modified by init.
pop h
pop d
pop b
pop psw
ret
;
;rcs - read console string (with echo)
;
; exit conditions
; b - number of characters read (<255)
; hl - points to last char stored (cr)
;
rcs: lxi h,ibuf
mvi b,0
;
rcs1: call rcc ;read next char from console
cpi del ;jump if not del
jnz rcs2
inr b ;ignore del if ibuf already empty
dcr b
jz rcs1
dcx h ;else discard last char
mov a,m ;echo discarded char to console
call wcc
dcr b ;decrement count
jmp rcs1 ; and loop
;
rcs2: cpi 'U'-40h ;jump if not control u
jnz rcs3
call wccr ;else abort current line
jmp rcs ; and start over
;
rcs3: call wcc ;echo char to console
mov m,a ;store char in ibuf
inr b ;increment count
cpi cr ;jump if carriage return
jz rcs4
inx h ;else advance pointer
jmp rcs1 ; and loop
;
rcs4: mvi a,lf ;issue line feed and return
call wcc
ret
;
;rcc - read console character
;
; exit conditions
; a - character read
;
rcc: push b
push d
push h
rccal: call $-$ ;modified by init.
pop h
pop d
pop b
ret
;
;wmc - write modem character
;
; entry conditions
; a - character to write
;
;
IF PORT
wmc: push psw
;
wmcl: in mods
xri mxor
ani mtbe
jnz wmcl
pop psw
ani 7fh ;strip parity bit
out modd
ret
ENDIF
;
IF TRSPT
wmc: push h
push d
push psw
;
wmcl: call motest ;test status
jz wmcl ;loop till tx empty
pop psw ;restore char
ani 7fh ;strip parity
push b ;store b
mov c,a ;put char into c
mvi b,00h ;channel a
lxi h,wmcre ;store return address
push h
lhld base+1 ;get base address
lxi d,sioout
dad d
pchl ;jump to it
;
wmcre: pop b ;restore it
pop d
pop h
ret
ENDIF
;
;rmc - read modem character
;
; exit conditions:
; a - character read
;
;
IF PORT
rmc: in mods
xri mxor
ani mrda
jnz rmc
;
rmc2: in modd
ani 7fh
ret
ENDIF
;
IF TRSPT
rmc: call mitest ;char available
jz rmc ;loop if not ready
;
rmc2: push b ;store b
push d
push h
mvi b,00h ;channel a
lxi h,rmcre ;return address
push h
lhld 1
lxi d,sioinp
dad d
pchl
;
rmcre: pop h
pop d
pop b
ani 7fh ;strip parity
ret
ENDIF
;
;gfn - get file name
;
gfn: lxi h,gfnsd ;print 'which drive?'
call wcs
call rcc ;get answer from console
call wcc ;echo it to console
ani 5fh ;make upper case
cpi 'C'-40h ;^C means abort
jz gfn6
sui 'A'-1
jc gfn ;require alphabetic
jz gfn
cpi 17 ;allow 16 drives (as in CP/M 2.x)
jnc gfn
sta fcb
;
gfnb: lxi h,gfns1 ;print 'filename? '
call wcs
call rcs ;read response into ibuf
lxi h,fcb+fn ;blank fill fn and ft fields
mvi c,11
;
gfn1: mvi m,' '
inx h
dcr c
jnz gfn1
lxi h,ibuf ;point to input buffer
lxi d,fcb+fn ;scan off fn field
mvi c,9
;
gfn2: mov a,m ;fetch next char from ibuf
inx h
cpi 61h ;if lc, convert to uc
jc gfn2a
sui 20h
;
gfn2a: cpi cr ;jump if end of line
jz gfn5
cpi '.' ;jump if end of name
jz gfn3
stax d ;else store char in fn field
inx d
dcr c ;loop if 8 or less chars so far
jnz gfn2
jmp gfn6 ;else take error exit
;
gfn3: lxi d,fcb+ft ;scan off ft field
mvi c,4
;
gfn4: mov a,m ;fetch next char from ibuf
inx h
cpi 61h ;if lc, convert to uc
jc gfn4a
sui 20h
;
gfn4a: cpi cr ;jump if end of line
jz gfn5
stax d ;else store char in ft field
inx d
dcr c ;loop if 3 or less chars so far
jnz gfn4
jmp gfn6 ;else take error exit
;
gfn5: xra a
sta fcb+ex ;set extent number to zero
sta fcb+nr ;set record number to zero
stc ;clear error flag and return
cmc
ret
;
gfn6: stc ;set error flag and return
ret
;
gfnsd: db cr,lf,'Which drive? ',0
gfns1: db cr,lf,'Filename? ',0
;
;open - open disk file
;
open: push h
push d
push b
lxi d,fcb
mvi c,offc
call bdos
pop b
pop d
pop h
ret
;
;read - read record from disk file
;
read: push h
push d
push b
lxi d,fcb
mvi c,rrfc
call bdos
pop b
pop d
pop h
ret
;
;close - close disk file
;
close: push h
push d
push b
lxi d,fcb
mvi c,cffc
call bdos
pop b
pop d
pop h
ret
;
;delt - delete disk file
;
delt: push h
push d
push b
lxi d,fcb
mvi c,dffc
call bdos
pop b
pop d
pop h
ret
;
;write - write record to disk
;
write: push h
push d
push b
lxi d,fcb
mvi c,wrfc
call bdos
pop b
pop d
pop h
ret
;
;make - make new disk file
;
make: push h
push d
push b
lxi d,fcb
mvi c,mffc
call bdos
pop b
pop d
pop h
ret
;
;citest - check console input status
;
citest: push b
push d
push h
citcal: call $-$ ;modified by init.
ora a ;set zero flag
pop h
pop d
pop b
ret ;zero flag carries answer
;
;mitest - check modem input status
;
IF PORT
mitest: in mods ;get modem uart status
xri mxor ;invert high-true bits
ani mrda ;any data available?
mvi a,0
jnz mitst1
cma
;
mitst1: ora a
ret ;zero flag carries answer
ENDIF
;
IF TRSPT
;
mitest: push b
push h
push d
mvi b,00 ;channel a
lxi h,mitstr
push h
lhld base+1
lxi d,siotst
dad d
pchl
;
mitstr: pop d
pop h
ani 01 ;tx empty
pop b
ret ;zero flag holds the answer
ENDIF
;
;motest - check modem output status
;
IF PORT
motest: in mods ;get modem uart status
xri mxor ;invert high-true bits
ani mtbe ;uart ready for character?
mvi a,0
jnz motst1 ;zero flag carries answer
cma
;
motst1: ora a ;set zero flag if ready
ret
ENDIF
;
IF TRSPT
motest: push b
push h
push d
mvi b,00 ;channel a
lxi h,motstr
push h
lhld 1
lxi d,siotst
dad d
pchl
;
motstr: ani 02 ;buffer empty
pop d
pop h
pop b
ret
ENDIF
;
;data area
;
inch: ds 1 ;input char buffer (to cyber)
outch: ds 1 ;output char buffer (from ciber)
stack: ds 80 ;local stack
ibuf: ds 256 ;input buffer
;
;text buffer
;
flag: ds 1 ;text save flag
ptr: ds 2 ;text buffer pointer
size: ds 2 ;text buffer size
tbuf: equ $ ;start of text buffer
;
end