home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol078
/
talk1-5.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
23KB
|
1,039 lines
.title 'Program to microcommunicate with other computer systems'
.sbttl ' Version of 10-Jul-81'
.ident talk
.entry start
.if1,[ .prntx 'TALK v1.5 - CP/M to host file transfer program']
;
; Simple program that can send and receive characters
; from the CP/M console or floppy disk to another
; computer/ acoustic modem/ or terminal that is connected
; to a Z80 SIO or DART (serial asynchronous interface).
;
; It is my first attempt at writing a program using
; interrupts so that I can fully utilise my hardware's
; capabilities. (I have a Godbout DISK 1 DMA floppy disk
; controller, Wire-wrapped 4 MHz IEEE 696 Z80 CPU with
; 2x Z80 SIO's, Z80 CTC and Z80 PIO allowing use of Mode 2
; vectored interrupts, 64Kbytes RAM and a Fulcrum VIO-X2
; intelligent video board).
;
; Sorry the source is in TDL Macro assembly language and
; requires Phoenix Software Associates PASM or TDL/Xitan
; Macroassembler to assemble. Conversion to ASM should
; be straight forward, though you lose all the nice
; features of this assembler.
;
; Author: Anthony Nicholson
;
; Address: 54 Carnley Avenue,
; New Lambton, NSW, 2305,
; Australia.
;
; Phone: 049-526017
;
; Date written: 20-Dec-1981
;
; Modification history:
;
; * Rev 5 10-Jul-1982
; Tidy up and add Z80 processor check
; for submission to 'Public Domain'.
;
; * Rev 4 13-Jun-1982
; Add log file feature and change
; abort character to ^^ (so I can
; communicate with a VAX-11/780 which
; uses ^Y).
;
; * Rev 3 21-Mar-1982
; Add delay to SENDFILE to allow
; host computer to catch up when
; using fast (2400baud) transmission,
; and echo what is sent for testing
; (This was found to be necessary when
; TALKing to a timesharing host PDP-11/70
; which required time to process its
; input buffer).
;
; * Rev 2 07-Mar-1982
; Implement file send to host.
;
; * Rev 1 27-Jan-1982
; Fix GETFCB filename scan. Also
; add conditional assembly for use
; with the Ferguson Big Board and
; for testing using my hardware.
;
; * Rev 0 20-Dec-1981
; Initial version for my hardware.
;
;
;
; C P / M D E F I N I T I O N S
;
bdos == 5 ;CP/M entry address
base == 0 ;CP/M base re-entry address
;
conwr$ == 2 ;Console write
dirio$ == 6 ;Direct console i/o
print$ == 9 ;Print string
rdbuf$ == 10 ;Read console buffer
openf$ == 15 ;Open file
close$ == 16 ;Close file
delet$ == 19 ;Delete file
readf$ == 20 ;Read file
write$ == 21 ;Write file
creat$ == 22 ;Create file
sdma$ == 26 ;Set DMA address
;
; G E T B U F F E R S I Z E
;
bufsiz =\ 'File blocking buffer size (must be multiple of 128)'
.ifn bufsiz @ 128,[
.error '?ILLEGAL BUFFER SIZE'
]
;
; C O N T R O L C H A R A C T E R S
;
; Command characters to
ctrld == 04h ; - download file
ctrle == 05h ; - send file
ctrlf == 06h ; - log file
ctrlq == 11h ; - XON to host
ctrls == 13h ; - XOFF to host
ctrly == 1eh ; - Abort (really ^^)
ctrlz == 1ah ; - EOF char
;
lf == 0ah
cr == 0dh
;
noparity== 07fh ;parity bit mask
;
false == 0
true == # false
.opsyn .ife,.ifnot
.opsyn .ifn,.if
;
testing =\ 'Version required (TEST=1, Bigboard=0) '
;
baudc =\ 'Baud rate for Z80 SIO <Default=300> '
;
opt.delay=\ 'Is a delay required after sending a line (Yes=1, No=0) '
;
.ifnot testing,[
;
; Ferguson BIG BOARD equates
;
bauda == 0ch ;Baud rate generator
; Value output to baud
; rate generator is
; determined below with
; a default of 300baud.
;For other baud rates,
; extend the conditional
; making sure to match
; all parentheses.
.ife baudc-2400,[
baudr == 1010b
]
[.ife baudc-1200,[
baudr == 1000b
]
[.ife baudc-600,[
baudr == 0110b
]
[
baudr == 0101b
]
]
]
delcnt == 2*1000 ;delay count for 2MHz Z80
siobc == 07h ;Uses Z80 SIO channel B
siobd == 05h ; at ports 05 & 07h
intvec == 0ff00h ; and its associated interrupt
rx.v == intvec+4; vectors for rx char
rxe.v == intvec+6; and rx char error
]
.if testing,[
;
; Test equates using my hardware
;
intvec: .word ierror ;I need to set up an
.word ierror ; interrupt vector table
.word ierror ; for the Z80 SIO
.word ierror
.word ierror
.word ierror
.word ierror
.word ierror
;
ierror: lxi d,imsg ; This routine will
call prints ;handle anything funny
hlt ;that may occur by HALTing!!!
jmpr ierror
;
imsg: .ascii [cr][lf]'?SPURIOUS INTERRUPT$'
;
rx.v == intvec+4;vector assignment for SIO
rxe.v == intvec+6; channel B
ctcb == 11h ;CTC controls the baud rate
.ife baudc-2400,[
baudr == 00011000b
]
[.ife baudc-1200,[
baudr == 00110000b
]
[.ife baudc-600,[
baudr == 01100000b
]
[
baudr == 11000000b
]
]
]
siobd == 01h ;data register of SIO
siobc == 03h ;control register of SIO
delcnt == 4*1000 ;delay count for 4MHz Z80
]
;
; B E G I N P R O G R A M ' T A L K '
;
start: mvi a,7fH ;Identify processor
add a ; cause overflow
jpe Z80 ; conclusive proof of Z80
lxi d,z80msg;Give them the bad news
call prints
jmp base ;Return to CP/M
;
z80msg: .ascii '?TALK - This program requires a Z80 processor$'
;
z80: lxi d,signon ;print("TALK V1.n")
call prints
call rxecho
call inisio ;initialise SIO
;
next1: call getch ;get a character
ora a ; from console.
jrnz proc1 ;if we get one then off we go...
call prxch ;otherwise print any character
jmp next1 ; we got down the line.
;
proc1: cpi ctrld ;if ch="^D" then
jrz ..6 ; transfer file to CP/M
cpi ctrlf ;else if ch="^F" then
jrnz ..2 ; do log file function
mvi a,true ; by setting log flag
sta log.flag
lxi d,logmsg; and getting prompt
jmpr ..7 ; message ready.
;
..6: lxi d,filmsg
;
..7: call prints ; print "filename ?"
call inputl ; get filename
lxi d,newlin
call prints
lxi h,conbuf+2
lxi d,fcb
call getfcb ; set up file control
; block
jrz ..1 ;if not ok then
..0: lxi d,fnerrm ; print "filename error"
call prints
jmpr ..8 ;else
;
..1: call getfile ; transfer file
;
..8: mvi a,false ;when done, reset
sta log.flag; log flag
jmp next1
..2:
cpi ctrly ;if ch="^Y" then
jrnz ..3
lxi d,byemsg; print "exiting..."
call prints
call close ; close files and
call rxdint ; disable host rx interrupts
jmp base ;Return to CP/M
..3:
cpi ctrle ;if ch="^E" then
jrnz ..4
lxi d,sndmsg; print "filename to send?"
call prints
call inputl ; get filename
lxi d,newlin
call prints
lxi h,conbuf+2
lxi d,fcb
call getfcb
jrz ..5
lxi d,fnerrm; print "filename error"
call prints
jmp next1
..5: call sendfile
jmp next1
..4:
call send ;send character to host
jmp next1
;
signon:
.ascii 'TALK V1.5 Program to talk to host computer via serial data line'[cr][lf]
.if testing,[ .ascii 'TESTING VERSION'[cr][lf]]
.ascii 'Command characters are:'[cr][lf][cr][lf]
.ascii ' ^^ abort current process (returns to CP/M)'[cr][lf]
.ascii ' ^D prompt for CP/M filename to receive characters'[cr][lf]
.ascii ' from host and initiate the transfer (by'[cr][lf]
.ascii ' sending a <return> to host) (^F logfile)'[cr][lf]
.ascii ' ^E prompt for CP/M filename to send to host'[cr][lf]
.ascii ' and initiate the transfer (assumes host is'[cr][lf]
.ascii ' ready to receive characters)'[cr][lf]
.ascii ' ^Z when in file transfer mode causes the'[cr][lf]
.ascii ' current operation to terminate'[cr][lf][cr][lf]
.ascii 'You are now talking to the host...'[cr][lf]'$'
;
filmsg: .ascii [cr][lf]'filename to receive?$'
;
newlin: .ascii [cr][lf]'$'
;
fnerrm: .ascii [cr][lf]'filename error, ignoring input...'[cr][lf]'$'
;
byemsg: .ascii [cr][lf]'exiting...$'
;
sndmsg: .ascii [cr][lf]'filename to send?$'
;
logmsg: .ascii [cr][lf]'log filename?$'
;
;-----------------------
;
; S U B R O U T I N E S
;
;-----------------------
;
; getch - get a character from console
;
; exit: character -> a
;
getch: mvi c,dirio$
mvi e,0ffh
bdose: push b
push d
push h
call bdos
pop h
pop d
pop b
ret
;-----------------------
;
; prints - print ascii string on console
;
; entry: de -> address of string
;
prints: mvi c,print$
jmp bdose
;
; inputl - input line from console
;
; flushes buffer with spaces
;
inputl: mvi b,cbfsiz;initialise console
lxi h,conbuf; input buffer CONBUF
mov m,b ; and fill with spaces
inx h
xra a
mov m,a
inx h
..0: mvi m,' '
inx h
djnz ..0
mvi c,rdbuf$ ;read chars into buffer
lxi d,conbuf
jmp bdose
;-----------------------
;
; getfcb - build a CP/M filename from input string
;
; entry: HL -> ascii filename string
; DE -> FCB
; exit: z flag <- 0 if error (A<>0)
; 1 if ok (A=0)
;
getfcb: xra a ;Set result status=OK
sta ..okfl ; and get File Control Block
push d
mov b,m ;first char might be
inx h ; drivename
mov a,m ;if this is a ":" then we
cpi ':' ; have a drivename
jrnz ..nodv
mov a,b
call ..cpan ;check alphanumeric drive name
inx h ; point past colon
ani 7 ; mask drive A to H
jmpr ..stdv
;
..nodv:
dcx h ;no drivename so
xra a ; set to default drive
..stdv:
stax d ;store drivename
inx d ; in first byte of FCB
mvi b,8 ;get filename (8 chars)
call ..name
mov a,m
cpi '.' ;check optional '.'
jrnz ..ext
inx h
..ext: mvi b,3 ;get extension (3 chars)
call ..name
mvi b,24 ;clear rest of FCB
xra a
..crst: stax d
inx d
djnz ..crst
lda ..okfl ;Get return status
ana a ; set flag bits
pop d ; and return
ret
;
..okfl: .byte 0
;
..cpan: cpi ' ' ;if space or '.' then
jrz ..cnok ; return z bit reset.
cpi '.'
jrz ..cnok
cpi 'Z'+1 ;convert lower case
jrc ..0 ; alpha to upper case
sui 020h
..0: cpi '0' ;check for numeric
jrc ..cper
cpi '9'+1
jrc ..cok
cpi 'A' ;check for alpha
jrc ..cper
cpi 'Z'+1
jrnc ..cper
..cok: cmp a ;return with z flag
ret ; set if alphanumeric
..cper: push psw ;not alphanumeric
mvi a,0ffh ; so set flag to
sta ..okfl ; signify error
pop psw
..cnok: ori 0ffh ;reset zero flag
ret
;
..name: mov a,m ;get char from buffer
call ..cpan ; and check it
jrnz ..nr ;if error change to ' '
inx h
stax d ;put it to FCB (we
inx d ; don't check errors
djnz ..name ; 'til end)
ret
..nr: mvi a,' '
stax d
inx d
djnz ..nr
ret
;-----------------------
;
; send - send character to host
;
; entry: A <- character
;
send:
push psw ;output the character
..wait: in siobc ; to sio channel B
ani 00000100b; when the TxRDY bit
jrz ..wait ; is set
pop psw
out siobd
ret
;-----------------------
;
; conout - output character to console
;
; entry: A <- character
;
conout: mov e,a
mvi c,conwr$
jmp bdose
;-----------------------
;
; inisio - initialise Z80 SIO for interrupt
; input from host
;
inisio:
di
lxi h,intvec;set the interrupt
mov a,h ; vector on the cpu
stai ; and store the low
mov a,l ; byte in sio control
sta ivec ; data area
lxi h,init$t;point to i/o init table
..1: mov b,m ; get # bytes,
inx h
mov c,m ; i/o port
inx h
outir ; and output
bit 7,m
jrz ..1
lxi h,rxdvr ; interrupt vectors
shld rx.v ; Rx channel B
lxi h,rxerra
shld rxe.v ; Rx error channel B
im2 ;make sure its mode 2
ei ; interrupts
ret
;
; init$t - Z80 SIO and baud rate initialise
; data for Ferguson BIG BOARD
;
init$t:
.ifnot testing,[
.byte 1 ;Baud rate for
.byte bauda ; channel B on the
.byte baudr ; Big board.
]
.if testing,[
.byte 2
.byte ctcb ;My system uses a Z80 CTC
.byte 01000111b; as a clock for the Z80 SIO
.byte baudr
]
.byte 12 ;SIO channel B
.byte siobc
.byte 0,00011000b ;channel B reset
.byte 4,01000100b ;16x clock, 1 stopbit, no parity
.byte 1,00011100b ;Rx interrupt enable
.byte 3,11000001b ;8bits / Rx character, Rx enable
.byte 5,11101010b ;8bits / Tx character, DTR, RTS, Tx enable
.byte 2
ivec: .byte 0 ;interrupt vector
.byte -1 ;end of table marker
;-----------------------
;
; rxinten - set flag so characters received
; from host are buffered
;
rxinten:
mvi a,true
sta buf.active
jmp sendq
;-----------------------
;
; rxecho - set flag so characters received
; from host are echoed
;
rxecho: mvi a,false
sta buf.active
sendq: mvi a,ctrlq ;send ^Q to host
jmp send
;-----------------------
;
; rxdint - disable host receive
; character interrupts
;
rxdint: mvi a,1 ;turn off so that
out siobc ; when we return to
mvi a,00000000b; CP/M we won't
out siobc ; bomb out (RXDVR is
ret ; overlayed)
;-----------------------
;
; prxch - print the last received character
; from the host
;
prxch: di ;let's not get any
lda rxchar ; interruptions while
mov c,a ; we talk a copy of
xra a ; the last character
sta rxchar ; received and clear
ei ; it
mov a,c ;has a character been
ora a ; received ?
rz ;no
jmp conout ;yes, print it so he
; can see that something
; is happening.
;-----------------------
;
; rxdvr - receive host character interrupt
; driver.
;
rxdvr:
push psw ;save registers
push b
push d
push h
rxdvr2: lda buf.active;check for buffered
ora a ; mode
jrnz rxbufi ;yes
in siobd ;no, just get the
ani noparity; character and save
sta rxchar ; it
jmpr retdvr
rxbufi:
lhld free.ptr;buffered mode.
in siobd ;get character
ani noparity; mask parity bit
mov m,a ; and store
sta rxchar
inx h ;bump pointer
shld free.ptr; and store.
lda buf.sub ;get end of buffer
ora a ; address depending
lxi d,buf2 ; on buffer subscript
jrz ..a
lxi d,bufend
..a: mov a,h ;is the current buffer
cmp d ; full (ie: is free.ptr
jrnz ..ret ; now pointing past
mov a,l ; current buffer) ?
cmp e
jrnz ..ret ;no.
..full:
lda buf.sub ;swap buffer pointers
ana a ; to other buffer
jrz ..0 ; (using buffer
lxi h,buf1 ; subscript)
mvi a,0
jmpr ..1
..0: lxi h,buf2
mvi a,1
..1: sta buf.sub ;record new buffer
shld buf.ptr ; pointers
shld free.ptr
mvi a,true ;signal that write
sta buf.rdy ; buffer is ready
..ret: lda rxchar ;if character from
cpi ctrlz ; host was a "^Z"
jrnz retdvr ; then also set the
mvi a,true ; end of file flag
sta eof.flag
retdvr: pop h ;restore registers
pop d
pop b
pop psw
ei ; and return
reti
;
rxchar: .byte 0
;
;-----------------------
;
; rxerra - receive host character error
; interrupt driver.
;
rxerra:
push psw ;if by some means
push b ; a parity or
push d ; framing error is
push h ; detected then
mvi a,00010000b
out siobc
mvi a,00110000b; error reset
out siobc
jmp rxdvr2 ; and process character
;-----------------------
;
; getfile - get a CP/M file from host computer
;
; entry: FCB is file to get
;
getfile:
lxi h,buf1 ;initialise buffer pointers
shld free.ptr; and subscripts for
shld buf.ptr ; transfer.
shld write.ptr
mvi a,0
sta buf.sub
sta wr.sub
mvi a,false ;clear done.flag, eof.flag,
sta done.flag; buf.rdy indicator and
sta eof.flag; err.flag
sta buf.rdy
sta err.flag
call make ;open file
rnz ; abort if error
call rxinten ;enable receive buffer interrupts
lda log.flag;if log file operation
ana a ; then skip sending a <CR>
jrnz ..1
mvi a,cr ;send <CR>
call send
..1: lda buf.rdy ;if buf.ready.flag set then
ana a
jrz ..2
mvi a,false
sta buf.rdy
call stopsend; stop host from sending
call write ; write to file
mvi a,ctrlq ; send host resume
call send
jmpr ..3
..2:
lda eof.flag;else if end.of.file then
ora a
jrz ..3
call stopsend; stop host from sending
call puteofch; and put an end of file mark
; in the buffer.
call write
call close
mvi a,true ; set done.flag
sta done.flag
..3:
lda done.flag
ora a ;if done.flag set then
jrnz getexit; exit
lda err.flag;if err.flag set then
ora a ; abort
jrnz ..4
call prxch
call getch ;get char (if any) from
ana a ; console. Skip the
jrz ..1 ; tests if nothing typed
cpi ctrly ;test character and abort
jrz ..4 ; if ^Y is struck
cpi ctrlz
jrz ..9
push psw
lda log.flag;if log file active
ana a ; then we want to send
jrnz ..8 ; characters typed
pop psw
jmpr ..1
..8: pop psw
call send
jmpr ..1
..9: mvi a,true
sta eof.flag
jmpr ..1
..4:
call rxecho
lxi d,sabmsg; print "file transfer aborted"
call prints ; and return
ret
getexit:
call rxecho ;disable host buffer Rx
lxi d,sdnmsg;print "file transferred"
call prints ; and return
ret
;
sabmsg: .ascii [cr][lf]'file transfer aborted'[cr][lf]'$'
;
sdnmsg: .ascii [cr][lf]'file transferred from host'[cr][lf]'$'
;
;-----------------------
;
; sendfile - send CP/M file to host
;
sendfile:
call open ;open file
rnz ; and return if error
lxi d,senmsg;print "sending file
call prints ; to host"
mvi a,cr ;send a <CR> to
call send ; host
..rdlp: mvi c,readf$;read next sector from
lxi d,fcb ; file to RBUF
call bdose
ora a ;CP/M end of file?
jrnz ..eof ;yes
xra a ;no, clear newline
sta crflag ; flag so we only send
; a <CR> for each <CR><LF>
lxi h,rbuf ;set address and
mvi b,128 ; number of bytes
..slp: lda crflag ;was last char a <CR>?
ora a
jrz ..sn ;no
xra a ;yes, reset flag
sta crflag
.if opt.delay,[
push h ;delay 250ms to allow
lxi h,250 ; host to process the
call delay ; last line.
pop h
]
mov a,m ;get next character
inx h
cpi lf ;ignore next linefeed
jrz ..keep
jmpr ..sn2
..sn: mov a,m ;get next char from
inx h ; read buffer
..sn2: cpi cr ;if it's a <CR> then
jrnz ..sn1 ; set flag
sta crflag
..sn1: call send ; and send it to host
.if testing,[
push h ;echo what we send
push d ; to the console.
push b
push psw
call conout
pop psw
pop b
pop d
pop h
]
cpi ctrlz ;was it a ^Z?
jrz ..eof ;yes
..keep: djnz ..slp ;no, keep sending...
call getch ;check for ^Y from
cpi ctrly ; console
jrnz ..rdlp ; none, so keep going
lxi d,sabmsg;print "file transfer
call prints ; aborted"
call close
ret
..eof: call close ;close input file
lxi d,fstmsg;print "file sent
call prints ; to host successfully"
ret
;
senmsg: .ascii [cr][lf]'Sending file to host...'[cr][lf]'$'
;
fstmsg: .ascii [cr][lf]'File sent to host successfully'[cr][lf]'$'
;
;-----------------------
;
; make - create new CP/M file
;
make: lxi d,fcb ;delete any old
mvi c,delet$; file
call bdose
lxi d,fcb ; and open a new
mvi c,creat$; one
call bdose
cpi 0ffh ;any errors ?
jrz ..0 ;yes
mvi a,false ;no, return status
ora a ; OK
ret
..0: lxi d,opnmsg;error, print "open failure"
call prints
mvi a,true ;and return with status
ora a ; not OK
ret
;
opnmsg: .ascii [cr][lf]'?CP/M file create failure'[cr][lf]'$'
;
;-----------------------
;
; open - open file (which must already exist)
;
open: mvi c,sdma$ ;set buffer address
lxi d,rbuf ; for reads
call bdose
mvi c,openf$
lxi d,fcb
call bdose
cpi 0ffh ;find it?
jrz ..opnf
xra a
ret
..opnf: lxi d,opfmsg;no, print "can't find
call prints ; file"
mvi a,0ffh
ora a
ret
;
opfmsg: .ascii [cr][lf]"?Can't find CP/M file"[cr][lf]'$'
;
;-----------------------
;
; close - close file
;
close:
lxi d,fcb
mvi c,close$
jmp bdose
;-----------------------
;
; stopsend - stop host from sending
;
stopsend:
mvi a,ctrls ;send ^S
call send
..0:
lhld free.ptr; copy free.ptr
shld sav.ptr
lxi h,1000 ; delay 1 second
call delay
lhld sav.ptr ; if free.pointer
lded free.ptr; hasn't moved then
ana a ; return, else
dsbc d ; keep waiting
jrnz ..0
ret
;
sav.ptr:.blkb 2
;
;-----------------------
;
; write - write buffer to CP/M disk file
;
write:
lda eof.flag;if not end.of.file then
ora a ; write out a whole buffer
jrz ..3
lded write.ptr; otherwise calculate
lhld free.ptr; the number of sectors
ora a ; = ((free.ptr - write.ptr)*2/256)+1
dsbc d
dad h
mov a,h
inr a
jmpr ..2
;
..3: mvi a,numsec;set number of sectors
..2: sta ..nsec ; to write.
..wnxt:
lded write.ptr;set disk buffer
mvi c,sdma$ ; address
call bdose
lxi d,fcb ;write next sector
mvi c,write$
call bdose
ana a ;abort if write error
jrnz ..err ; status returned.
lhld write.ptr;point to next logical
lxi b,128 ; sector
dad b
shld write.ptr
lda ..nsec ;repeat until all sectors
dcr a ; have been written
sta ..nsec
jrnz ..wnxt
lda wr.sub ;swap write.ptr and
ora a ; wr.sub to the
jrz ..4 ; other buffer so
lxi h,buf1 ; we write it next
mvi a,0 ; time.
jmpr ..5
..4: lxi h,buf2
mvi a,1
..5: sta wr.sub
shld write.ptr
ret
..err: lxi d,wremsg;print "write error"
call prints
call close ;close CP/M file
mvi a,true ; and set error flag
sta err.flag
ret
;
..nsec: .byte 0
;
wremsg: .ascii [cr][lf]'?CRITICAL ERROR - Disk full'[cr][lf]'$'
;
;-----------------------
;
; puteofch - Put an end-of-file marker (^Z)
; at the end of the current buffer.
;
puteofch:
di
lhld free.ptr
mvi m,ctrlz
inx h
shld free.ptr
ei
ret
;-----------------------
;
; delay - delay the millisecond count
; passed in the HL register pair
;
delay: mvi a,delcnt/26
..0: dcx h
inx h
dcr a
jnz ..0
dcx h
mov a,l
ora h
jnz delay
ret
;
; G L O B A L F L A G S
;
done.flag:
.byte 0 ;set when transfer complete
eof.flag:
.byte 0 ;set when ^Z received from host
buf.rdy:
.byte 0 ;set when rx buffer full
err.flag:
.byte 0 ;set if a fatal error occurs
buf.active:
.byte 0 ;set when buffer i/o is active
crflag: .byte 0 ;set to filter <LF> from sent file
log.flag:
.byte 0 ;set to store characters received
; in a log file.
;
; B U F F E R P O I N T E R S
;
free.ptr: ;points to next free byte to
; receive a character from
.word buf1 ; the host.
buf.ptr: ;points to start of current
.word buf1 ; receive buffer.
write.ptr: ;points to start of the next
.word buf1 ; buffer to write to disk.
buf.sub: ;subscript into buffer
.byte 0 ;( 0=buf1, 1=buf2 )
wr.sub: .byte 0
;
; fcb - CP/M file control block
;
fcb: .blkb 36
;
; B U F F E R S
;
;
; conbuf - console input buffer
;
cbfsiz = 64
conbuf: .byte cbfsiz
nchrs: .byte 0
.blkb cbfsiz
;
numsec == bufsiz/128
;
buf1: .blkb bufsiz
buf2: .blkb bufsiz
bufend:
;
rbuf: .blkb 128 ;CP/M file read buffer
;
.end start