home *** CD-ROM | disk | FTP | other *** search
- ; 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
-