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
/
KERMIT
/
CP411SRC.ARK
/
cpxtor.asm
< prev
next >
Wrap
Assembly Source File
|
1991-04-23
|
41KB
|
1,230 lines
IF NOT lasm
.printx * CPXTOR.ASM *
ENDIF ;NOT lasm
; KERMIT - (Celtic for "FREE")
;
; This is the CP/M-80 implementation of the Columbia University
; KERMIT file transfer protocol.
;
; Version 4.0
;
; Copyright June 1981,1982,1983,1984,1985
; Columbia University
;
; Originally written by Bill Catchings of the Columbia University Center for
; Computing Activities, 612 W. 115th St., New York, NY 10025.
;
; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
; others.
;
; This file contains the system dependent part for Torch, Superbrains,
; PCI2651 (Loughborough 8" Standard CP/M system) and Cifer computers.
;
; This is the first attempt to break the huge CPXSYS.ASM file
; into smaller system dependent files. To start with I will bunch
; several micros to one class.
;
; Please name system dependent files in the form CPXxxx.ASM where
; xxx is a three letter abbrev. for the system you are adding.
;
; revision history:
;
;edit 5, 10-Jan-1991 by MF. Removed references to assembly switch ker09.
; edit 4, 21 July, 1987 by OBSchou. Removed routines no in CPXCOM.ASM
;
; edit 3, 8 April, 1987 by OBSchou. Moved the VDU declarations for the
; Torch, superbrain and Cifer from CPXVDU.ASM. Also added code to
; see if the MCP/CCCP ROM versions on the Torch is less or grater than
; 1. Less than 1 => poor screen control. Finally adjusted the
; positioning of the filename to cope with a user number and drive
; in the filename field
;
;
; edit 2, 20 March, 1987 by C.J.MILES@UK.AC.UMRCC. Added support for
; NCR Decision Mate V (2651 USART)
;
; edit 1, 22 April, 1986, OBSchou. Start on splitting off individual
; systems from this huge file. It is done using the LINK facility
; LASM. We link to a collection of systems under CPXxxx.ASM.
; I have started with the systems I know, the Torch, Cifer and
; pci2651. These will all be held under CPXTOR.ASM
;
;
; Keep module name, edit number, and last revision date in memory.
family: db 'CPXTOR.ASM (5) 10-Jan-1991 $'
;
; Assembly time message to let me know I'm building the right version.
; LASM generates an 'S' error along with the message, which is messy, but
; better than trying to put everything inside a IF m80 OR mac80 conditional,
; because LASM doesn't like nested IF's, either.
IF ncrdmv
.printx * Assembling KERMIT-80 for the N.C.R. Decision Mate V *
ENDIF
IF brain
.printx * Assembling KERMIT-80 for the Intertec Superbrain *
ENDIF
IF brainm
.printx * With main port selected
ENDIF
IF braina
.printx * With Aux port
ENDIF
IF pci2651 ;
.printx * assembling Kermit-80 for 2651 PCI as comms device *
ENDIF
IF torch
.printx * Assembling Kermit-80 for Torch Unicorn 5 *
ENDIF
; *******This should be in the original CPXSYS.ASM file
;
;=========================================================================
; I/O Byte assignments (2-bit fields for 4 devices at loc 3)
;
;bits 6+7 LIST field
; 0 LIST is Teletype device (TTY:)
; 1 LIST is CRT device (CRT:)
; 2 LIST is Lineprinter (LPT:)
; 3 LIST is user defined (UL1:)
;
;bits 4+5 PUNCH field
; 0 PUNCH is Teletype device (TTY:)
; 1 PUNCH is high speed punch (PUN:)
; 2 PUNCH is user defined #1 (UP1:)
; 3 PUNCH is user defined #2 (UP2:)
;
;bits 2+3 READER field
; 0 READER is Teletype device (TTY:)
; 1 READER is high speed reader (RDR:)
; 2 READER is user defined #1 (UR1:)
; 3 READER is user defined #2 (UR2:)
;
;bits 0+1 CONSOLE field
; 0 CONSOLE is console printer (TTY:)
; 1 CONSOLE is CRT device (CRT:)
; 2 CONSOLE is in Batch-mode (BAT:);READER = Input,
; LIST = Output
; 3 CONSOLE is user defined (UC1:)
;
;=========================================================================
iobyte EQU 03H ;Location of I/O byte
; [13] modifed to use either main or aux port. Should really
; be selected by set port, but this is urgent, so no frills
IF brain
baudst EQU 60H ;
baudrt EQU 0EF00H ;Memory location where baud rates are stored.
output EQU 01H ;Transmitter ready
input EQU 02H ;Input data available
TxEmpty EQU 04h ;Transmitter empty
z80 SET TRUE ;I don't know...
ENDIF;brain
IF brainm ; Superbrain and main ports
mnport EQU 58H ;Modem data port
mnprts EQU 59H ;Modem status port
ENDIF ;brainm
IF braina ; Superbrain and aux port
mnport EQU 40H ;Modem data port
mnprts EQU 41H ;Modem status port
ENDIF ;braina [13]
IF ncrdmv
iobase equ 70h ; base address of PCI device
modrx equ 70h ; Rx data port
mnprts equ 71h ; status port
mnmodr equ 72h ; mode register read
mncmdr equ 73h ; command register read
modtx equ 74h ; Tx data port
mnmodw equ 76h ; mode register write
mncmdw equ 77h ; command register write
txrdy equ 1
output equ txrdy
rxrdy equ 2
input equ rxrdy
baudini equ 0ah ; initial baud to 2400
z80 SET true
cpuspd SET 40
ENDIF
IF pci2651 ;[28]
iobase equ 04h ; base address of PCI device
mnport equ iobase ; rx and tx data ports
mnprts equ iobase+1 ; status port
mnmode equ iobase+2 ; mode port
mncmd equ iobase+3 ; PCI command port
txrdy equ 1 ; tx ready bit set if free
output equ txrdy
rxrdy equ 2 ; RX ready bit
input equ rxrdy
baudini equ 7 ; 7 => 1200 baud by default
z80 SET true ; For Ithica intersystems it is
cpuspd SET 40 ; and running at four megs
ENDIF ;[28]
IF torch ;[13]
z80 SET TRUE
; [32] baudini removed as now read current baud rate
; settings from base processor.
;baudini equ 707h ; Initial Baud rate = 1200 baud
; Entry to be of form x0xh where x is
; the value x in the FX 7,x and FX 8,x
; funtion calls. 4= 1200 baud, 7 = 9600
; 2 = 300 baud.
ENDIF
IF brain OR torch
defesc EQU ']'-100O ;The default escape character.
ENDIF;brain OR torch
; If none of the above, default to VT52-EMULATION ON.
IF NOT crt
vtval EQU 1
ENDIF;NOT crt
sysxin:
IF brainm ;[25]
lda baudrt ; fetch current baud rate
ani 0F0H ; extract left nibble
rrc ; shift right 4 places
rrc
rrc
rrc
sta speed ; store as comm port speed
sta speed+1 ; (16 bits, to match speed table entries)
ENDIF;brainm
IF braina ;[25]
lda baudrt ; fetch current baud rate
ani 00FH ; extract right nibble
sta speed ; store as comm port speed
sta speed+1 ; (16 bits, to match speed table entries)
ENDIF;braina
IF torch ; [13] [32]
push h
mvi a,0f2h ; nick code from BBC initialisation
lxi h,0ff00h
call osbyte ; Read current speed setting
mov a,l
ani 7
xri 7 ; Store as two's complement
inr a
sta speed
sta speed+1
mov e,a
call sysspd ; Make sure they are both the same!
mvi a,15 ; Flush all internal buffers [32]
mvi l,0
; call osbyte
mvi a,3
lxi h,0100h ; *FX 3,0,1 Enable RS423
call osbyte
mvi a,2 ; Select keyboard, Enable RS423 input
mvi l,2
call osbyte
mvi a,5 ; Select serial printer [32]
mvi l,2
call osbyte ; [30]
mvi a,6 ; Must be able to send LF [30]
mvi l,0
call osbyte ; [30]
mvi a,202 ; FX 202,255 set lower case on
mvi l,255
call osbyte
pop h
; Now see what version of MCP CCP roms. Assume >1, else copy a few of the
; older Torch VDU declares over the new ones.
;
; lda 0ffffh ; Address 0ffffh has single byte Version no.
; push psw ; save for a rainy day
; ani 0F0h ; get ms digit of MCP version
; rra ; move right 4 places
; rra
; rra
; rra
; ani 0fh
; adi 30h ; make it a number
; sta mcpver
; pop psw ; its raining...
; push psw ; ... its pouring...
; ani 0fh ; get ls digit
; adi 30h ; make it ascii number
; sta mcpver+2
; pop psw ; restore psw
; cpi 10h ; Version 1.00 or less?
; jp init2 ; yes, so skip next bit
; lxi h,ooutli ; from old string table
; lxi d,ttab ; to new ttab
; lxi b,60 ; 60 bytes to move
; call mover
init2:
IF ncrdmv
mvi a,00 ; clear out command register
out mncmdw
mvi a,4eh ; 1 stop bit, 8 data bits, / by 16 counter
out mnmodw
mvi a,70h+baudini ; baud rate and select internal rate gen.
out mnmodw
mvi a,27h ; enable tx and rx, RTS and DTR low
out mncmdw
ENDIF ; ncrdmv
IF pci2651 ;[28]
in mncmd ; clearw command reg counter
mvi a,4eh ; 1 stop bit, 8 data bits, / by 16 counter
out mnmode
mvi a,30h+baudini ; baud rate and select internal rate gen.
out mnmode
mvi a,27h ; enable tx and rx, RTS and DTR low
out mncmd
ENDIF ; pci2651 [28]
ret ; return from system-dependent routine
;
;
; system-dependent termination processing
; If we've changed anything, this is our last chance to put it back.
sysexit:
ret
;
; system-dependent processing for start of CONNECT command
;
syscon:
ret
conmsg: ; Messages printed when entering transparent (CONNECT) mode:
;
;
; syscls - system-dependent close routine
; called when exiting transparent session.
;
syscls:
ret
;
;
; sysinh - help for system-dependent special functions.
; called in response to <escape>?, after listing all the
; system-independent escape sequences.
;
sysinh:
IF torch OR brain OR pci2651 OR ncrdmv
lxi d,inhlps ; we got options...
call prtstr ; print them.
ENDIF;torch OR brain OR pci2651 OR ncrdmv
ret
;additional, system-dependent help for transparent mode
; (two-character escape sequences)
inhlps:
; [16] [18] have added super brain and Torch to the list of Breaking machines.
IF pci2651 OR brain OR torch OR ncrdmv
db cr,lf,'B Transmit a BREAK'
ENDIF ;pci2651 OR brain OR torch OR ncrdmv
IF torch ; added this simply to debug the escape cokebottle D for the apple
db cr,lf,'D Disconnect the modem (Test purposes only)'
ENDIF;Torch
db '$' ;[hh] table terminator
;
; sysint - system dependent special functions
; called when transparent escape character has been typed;
; the second character of the sequence is in A (and in B).
; returns:
; non-skip: sequence has been processed
; skip: sequence was not recognized
sysint: ani 137O ; convert lower case to upper, for testing...
; [19] have added superbrain and torch to the list
IF brain OR pci2651 OR torch OR ncrdmv
cpi 'B' ; send break?
jz sendbr ; yes, go do it. return nonskip when through.
ENDIF ;brain OR pci2651 OR torch OR ncrdmv
IF Torch; added bit for doing a D...
cpi 'D' ;drop the line...
jz dropln
ENDIF ;torch
jmp rskp ; take skip return - command not recognized.
IF torch
dropln: lxi d,dropm ; tell user line is dropped..
call prtstr
xra a ; destroy A
ret
dropm: db bell,cr,lf,'Testing line dropped ',cr,lf,bell
db '$'
ENDIF ;torch and dropping them there lines..
;
IF brain
sendbr:
;
; Ensure that the transmitter has finished sending buffered chars
sndbr1: in mnprts ; get UART status
ani TxEmpty ; everything sent?
jz sndbr1 ; no, wait a bit more
;
; Begin sending a break by setting bit in UART command register
mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS
out mnprts
;
; Wait for 250 milliseconds (using hundredths second delay routine)
mvi a,25
call delay
;
; Resume normal operation by clearing the SendBreak command bit
mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS
out mnprts
;
ret ;done
ENDIF;brain
IF torch ; [18] [27] [30] [32]
; Send a break.
;
; [30] Dumping of 6502 code not yet used, but may be for later versions of
; the Torch CCCP Rom in the BBC. This works, so I leave it for now.
sendbr:
push h ;save for a monsoon
mvi a,0e8h
lxi h,0 ; turn interrupts off
call osbyte
push h
;
mvi a,9ch ; OSBYTE call 9c is read/write 6850 cntl prt
lxi h,0077h ; H = 6502 Y reg, L = 6502 X reg
call osbyte ; returned new val. = (old value AND Y)XOR X
push h ; save it for return
;
mvi a,30
call delay ; do a delay
;
; now clear rx register
;
mvi a,96h ; do a read sheila address 08h
mvi l,8
mvi h,0
call osbyte ; read sheila 08h = 6850 rx reg
;
; restore 6850 regs...
;
pop h ; restore previous cntl reg
; old x reg in l, so leave it there
; mov l,h
mvi h,0
mvi a,9ch ; write previous value to 6850
call osbyte
;
; and Beebs interrupt mask
;
pop h ; get interrupt mask
; Once again, old X in L so leave it alone
; mov l,h
mvi h,0
mvi a,0e8h
call osbyte ; restore interrupts mask
;
pop h
ret ; its raining again, so exit
ENDIF ; torch [18] [32]
IF ncrdmv
sendbr: in mnprts ; get status
ani 04h ; make sure shift register is empty
jz sendbr
mvi a,2fh ; force a break
out mncmdw
mvi a,100 ; set delay period
call delay
mvi a,27h ; restore command register
out mncmdw
ret
ENDIF ; ncrdmv
IF pci2651 ;[28]
sendbr: in mnprts
ani 04h ; make sure shift reg is clear
jz sendbr
mvi a,2fh ; set foe a break
out mncmd
mvi a,100 ; wait a bit
call delay
mvi a,27h ; restore mode
out mncmd
ret
ENDIF ;pci2651 [28]
;
; sysflt - system-dependent filter
; called with character in E.
; if this character should not be printed, return with A = zero.
; preserves bc, de, hl.
; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
sysflt:
mov a,e ; get character for testing
ret
; mdmflt - modem filter [30]
; called with character to be sent to printer in E
; with parity set as appropriate.
; return with accumulator = 0 do do nothing,
; <> 0 to send char in E.
mdmflt:
mov a,e ;[30] get character to test
IF torch ;[30] map del to bs,space,bs
ani 7fh ; strip parity
cpi 7fh ; is it the delete character
rnz ; no, then a <> 0 so print it
mvi e,bs ; else load a backspace
call outmdm ; little recursion...
mvi e,' ' ; then a space
call outmdm ; backspace, space, now another...
mvi e,bs ; backspace
call outmdm ;
xra a ; clear a => on return do nowt.
ENDIF ;torch [30]
ret
; prtflt - printer filter [30]
; called with character to be sent to printer in E
; returns with a = 0 to do nothing
; a <> 0 to print it.
;
; this routine for those printer that automatically insert
; a lf on cr, or cr for lf. Should this be shifted to
; the system indep. stuff, in say 4.06?
prtflt:
mov a,e ; [30] get character to test
IF torch ; strip out lf from printer stream
ani 7fh ; make sure it is parity less
cpi lf ; is it a line feed?
rnz ; no, print it
; xra a ; yes, don't.
ENDIF ;torch [30]
ret
;
;
; system-dependent processing for BYE command.
; for apmmdm, heath, and lobo, hang up the phone.
sysbye:
ret
;
; This is the system-dependent command to change the baud rate.
; DE contains the two-byte value from the baud rate table; this
; value is also stored in 'speed'.
sysspd:
; Set the speed for the Brain (Main Port)
IF brainm ;[25]
lda baudrt ;Get the present baud rates.
ani 0fH ;turn off the left
mov d,a ;Set it aside.
mov a,e ;Get the new baud rate.
rlc ;Shift left 4 places.
rlc
rlc
rlc
ora d ; combine with the old baud rate
sta baudrt ;Store the new baud rates.
out baudst ;Set the baud rates.
ret
ENDIF;brainm
; Set the speed for the Brain (Aux Port)
IF braina ;[25]
lda baudrt ;Get the present baud rates.
ani 0f0H ;turn off the right
ora e ; combine with the new baud rate
sta baudrt ;Store the new baud rates.
out baudst ;Set the baud rates.
ret
ENDIF;braina
If torch ; Set speed for Torch [14] [32]
mvi a,7 ; Osbyte call to set rx rate
mov l,e
call osbyte ;
mvi a,8 ; set up for tx rate to be set
mov l,e
call osbyte
ret ; and now, all rates should be different
ENDIF ;torch [14] [32]
IF ncrdmv ; Set baud rate for NCR Decision Mate V
mvi a,00 ; clear command register
out mncmdw
mvi a,4eh ; set for 1 stop, 8 data bits
out mnmodw ; save in mode 1 port
mvi a,70h ; set bits for rate etc..
add e ; add baud rate (bits 0 - 3)
out mnmodw ; set mode port 2
mvi a,27h ; set tx/rx ready, RTS CTS active
out mncmdw
ret
ENDIF ; ncrdmv
IF pci2651 ; Set baud for PCI [28]
in mncmd ; Clear register counter
mvi a,4eh ; set for 1 stop, 8 data bits
out mnmode ; save in mode 1 port
mvi a,30h ; set bits for rate etc..
add e ; add baud rate (bits 0 - 3)
out mnmode ; set mode port 2
mvi a,27h ; set tx/rx ready, RTS CTS active
out mncmd
ret
ENDIF ;pci2651 [28]
;
; Speed tables
; (Note that speed tables MUST be in alphabetical order for later
; lookup procedures, and must begin with a value showing the total
; number of entries. The speed help tables are just for us poor
; humans.
; db string length,string,divisor (2 identical bytes or 1 word)
; [Toad Hall]
IF brain OR pci2651 OR ncrdmv
spdtbl: db 10h ;16 entries
db 03h,'110$', 02h,02h
db 04h,'1200$', 07h,07h
db 05h,'134.5$', 03h,03h
db 03h,'150$', 04h,04h
db 04h,'1800$', 08h,08h
db 05h,'19200$', 0fh,0fh
db 04h,'2000$', 09h,09h
db 04h,'2400$', 0ah,0ah
db 03h,'300$', 05h,05h
db 04h,'3600$', 0bh,0bh
db 04h,'4800$', 0ch,0ch
db 02h,'50$', 00h,00h
db 03h,'600$', 06h,06h
db 04h,'7200$', 0dh,0dh
db 02h,'75$', 01h,01h
db 04h,'9600$', 0eh,0eh
sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
ENDIF;brain OR pci2651 OR ncrdmv
IF torch ;[17]
spdtbl: db 8 ; 8 entries
db 4,'1200$', 4,4
db 3,'150$', 2,2
db 5,'19200$', 8,8
db 4,'2400$', 5,5
db 3,'300$', 3,3
db 4,'4800$', 6,6
db 2,'75$', 1,1
db 4,'9600$', 7,7
sphtbl: db cr,lf,' 75 150 300 1200 2400 4800 9600 19200$'
ENDIF;torch [17]
; The following conditionals were once a huge if not statement. There
; wasn't enough room to add the lobo to the list, so it had to be broken
; into 2, which you can't do with an if not. I redid it as two ifs and
; applied them to those that wouldn't set baud. [Hal Hostetler]
;
; This is the system-dependent SET PORT command.
; HL contains the argument from the command table.
sysprt:
IF iobyt
mov a,m ;Get the I/O byte
sta prtiob ;Save the desired IO byte for this port
inx h ;Point at next entry
mov a,m ;Get the output function
sta prtfun ;Save it
ENDIF;iobyt
ret
;
;
;
; Port tables for GENERIC CPM 2.2
IF gener
; help text
prhtbl: db cr,lf,'CRT device'
db cr,lf,'PTR device'
db cr,lf,'TTY device'
db cr,lf,'UC1 device'
db cr,lf,'UR1 device'
db cr,lf,'UR2 device$'
; command table
prttbl: db 06H ;Six devices to choose from
db 03H,'CRT$'
dw crtptb
db 03H,'PTR$'
dw ptrptb
db 03H,'TTY$'
dw ttyptb
db 03H,'UC1$'
dw uc1ptb
db 03H,'UR1$'
dw ur1ptb
db 03H,'UR2$'
dw ur2ptb
; port entry table
; table entries are:
; db iobyte-value, BDOS output function, reserved
crtptb: db crtio,conout,0
ptrptb: db ptrio,punout,0
ttyptb: db ttyio,conout,0
uc1ptb: db uc1io,conout,0
ur1ptb: db ur1io,punout,0
ur2ptb: db ur2io,punout,0
ENDIF;gener
;
;
IF iobyt
prtfun: db punout ;Function to use for output to comm port
prtiob: db batio ;I/O byte to use for communicating
coniob: db defio ;I/O byte to use for console
ENDIF;iobyt
IF NOT iobyt
prttbl equ 0 ; SET PORT is not supported
prhtbl equ 0
ENDIF;NOT iobyt
;
;
; selmdm - select modem port
; selcon - select console port
; selmdm is called before using inpmdm or outmdm;
; selcon is called before using inpcon or outcon.
; For iobyt systems, diddle the I/O byte to select console or comm port;
; For Decision I, switches Multi I/O board to console or modem serial
; port. [Toad Hall]
; For the rest, does nothing.
; preserves bc, de, hl.
selmdm:
IF iobyt
lda prtiob ;Set up for output to go to the comm port
sta iobyte ;Switch byte directly
ENDIF;iobyt
ret
selcon:
IF iobyt
lda coniob ;Set up for output to go to the console port
sta iobyte ;Switch directly
ENDIF;iobyt
ret
;
; Get character from console, or return zero.
; result is returned in A. destroys bc, de, hl.
;
inpcon:
IF NOT iobyt
mvi c,dconio ;Direct console I/O BDOS call.
mvi e,0FFH ;Input.
call BDOS
ENDIF;NOT iobyt
IF iobyt
call bconst ;Get the status
ora a ;Anything there?
rz ;No, forget it
call bconin ;Yes, get the character
ENDIF;iobyt
ret
;
;
; Output character in E to the console.
; destroys bc, de, hl
;
outcon:
IF NOT iobyt
mvi c,dconio ;Console output bdos call.
call bdos ;Output the char to the console.
ENDIF;NOT iobyt
IF iobyt
mov c,e ;Character
call bcnout ;to Console
ENDIF;iobyt
ret
;
;
; outmdm - output a char from E to the modem.
; the parity bit has been set as necessary.
; returns nonskip; bc, de, hl preserved.
outmdm:
IF inout AND NOT ncrdmv
in mnprts ;Get the output done flag.
ani output ;Is it set?
jz outmdm ;If not, loop until it is.
mov a,e
out mnport ;Output it.
ret
ENDIF;inout AND NOT ncrdmv
IF inout AND ncrdmv
in mnprts ;Get the output done flag
ani output ;Set ?
jz outmdm ;Loop until it is
mov a,e
out modtx ;output char
ret
ENDIF;inout AND ncrdmv
IF iobyt
;**** Note that we enter from outpkt with the I/O byte already set up for
; output to go to the comm port
push h
push b
lda prtfun ;Get the output function
mov c,a ;Into C
call bdos ;And output the character
pop b
pop h
ret
ENDIF;iobyt
IF torch ; [32] [13] Torch stuff. Requires some bit bashing
; via the BBC host computer (io computer)
; see also decription of osbyte later on
outdat:
lda prinuse ; get the printer in use flag
ana a ; if set, then must use traditional osbyte,
jnz outda2 ; else...
push b
push h ; Preserve registers [32]
call tx
db 1 ; MCP send to printer command
mov c,e ; Byte to send is in E [32]
call txbyte
pop h
pop b
ret
outda2: ; Preserve registers [32]
push h
mvi a,138 ; Osbyte insert byte into buffer
mvi l,2
mov h,e ; get the byte to be sent s-l-o-w-l-y
call osbyte
pop h ; Restore registers and exit
ret
ENDIF ;[13]
;
;
; get character from modem; return zero if none available.
; for IOBYT systems, the modem port has already been selected.
; destroys bc, de, hl.
inpmdm:
IF iobyt
call bconst ;Is Char at COMM-Port?
ora a ;something there?
rz ; return if nothing there
call bconin ; data present. read data.
ENDIF;iobyt
IF inout AND NOT ncrdmv
;Note: modem port should already be selected for mdI. [Toad Hall]
in mnprts ;Get the port status into A.
ani input ;See if the input ready bit is on.
rz ;If not then return.
in mnport ;If so, get the char.
ENDIF;inout AND NOT ncrdmv
IF inout AND ncrdmv
in mnprts ;Get input port status
ani input ;Mask input RDY bit
rz ;return if no char
in modrx ;get the char
ENDIF;inout AND ncrdmv
IF torch ; [32] [13] torch input
indat:
push h
mvi a,128
lxi h,0fffeh ; Read buffer status
call osbyte
mov a,h ; HL has number of characters
ora l ; in the buffer
jz indatq ; None, so skip fetch
mvi a,145 ; Get character from input buffer [32]
lxi h,1
call osbyte ; Result returned in 'Y', rather H
mov a,h
indatq:
pop h
ani 7fh
ret ; rx data in A
ENDIF ;torch [13] [32]
ret ; return with character in A
;
; flsmdm - flush comm line.
; Modem is selected.
; Currently, just gets characters until none are available.
flsmdm: call inpmdm ; Try to get a character
ora a ; Got one?
jnz flsmdm ; If so, try for another
ret ; Receiver is drained. Return.
;
;
; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
lptstat:
IF torch
mvi a,80h ; read chars remaining in printer buffer
mvi l,252 ; do osbyte 80H, X=252 (printer buffer)
mvi h,0ffh
call osbyte
mov a,h
cpi 10 ; 10 characters left?
mvi a,0 ; if pos, yes r better
rp
mvi a,0ffh
ret
ENDIF ;torch
IF torch
mvi a,5 ; got to select the real printer (par. port)
mvi l,1 ; ie FX 5,1
call osbyte
ENDIF ;torch
IF iobyte ;[33]
call bprtst ; get status
ENDIF ;iobyte[33]
IF torch
push psw
mvi a,5 ; restore serial line = printer
mvi l,2 ; ie FX 5,2
call osbyte
pop psw ; return with code in a
ENDIF ;torch
IF NOT iobyte ;[33]
xra a ; assume it is ok.. this may not be necessary
ENDIF ;iobyte [33]
ret
;
;
; outlpt - output character in E to printer
; console is selected.
; preserves de.
outlpt:
push d ; save DE in either case
call prtflt ; go through printer filter [30]
ana a ; if A = 0 do nothing,
jz outlp1 ; [30] if a=0 do nothing
IF torch ;[30] Must set printer routed to par port
mvi a,5 ; fx 5,1 (parallel port selected for printer)
mvi l,1 ; Modified for new osbyte form [32]
call osbyte
ENDIF ;torch [30]
IF NOT iobyt
mvi c,lstout
call bdos ;Char to printer
ENDIF;NOT iobyt
IF iobyt
mov c,e
call blsout
ENDIF;iobyt
IF torch ; re-route printer to serial port => faster tx bytes to line [30]
mvi a,5 ; Modified for new Osbyte form [32]
mvi l,2 ;fx 5,2
call osbyte
mvi a,6
mvi l,0 ;fx 6,0
call osbyte
ENDIF ;torch [30]
outlp1: pop d ; restore saved register pair
ret
;
;
; Screen manipulation routines
; csrpos - move to row B, column C
;
; csrpos for terminals that use a leadin sequence followed
; by (row + 31.) and (column + 31.)
;
IF brain
csrpos: push b ; save coordinates
lxi d,curldn ; get cursor leadin sequence
call prtstr ; print it
pop h ; restore coordinates
mov a,h ; get row
adi (' '-1) ; space is row one
mov e,a
push h
call outcon ; output row
pop h
mov a,l ; get column
adi (' '-1) ; space is column one
mov e,a
jmp outcon ; output it and return
ENDIF;brain
;
;
IF torch
csrpos: push b ; save coordinates
lxi d,curldn ; get cursor leadin sequence
call prtstr ; print it
pop h ; restore coordinates
mov a,l ; [obs] get column
adi 0ffh ; NULL is column one
mov e,a
push h
call outcon ; output row
pop h
mov a,h ; [obs] get row
adi 0ffh ; NULL (ie decrement) is row one
mov e,a
jmp outcon ; output it and return
ENDIF;torch
;
;
; delchr - make delete look like a backspace. Unless delete is a printing
; character, we just need to print a backspace. (we'll output clrspc
; afterwards)
; For Kaypro and Vector General, delete puts a blotch on the screen.
; For Apple and Osborne 1, delete moves but doesn't print.
delchr:
IF NOT torch ;[22]
mvi e,bs ;get a backspace
jmp outcon
ENDIF;NOT torch
; erase the character at the current cursor position
clrspc: mvi e,' '
call outcon
mvi e,bs ;get a backspace
jmp outcon
; erase the current line
clrlin: lxi d,eralin
jmp prtstr
; erase the whole screen, and go home. preserves b (but not c)
clrtop: lxi d,erascr
jmp prtstr
IF torch ;[13]
;
; OSBYTE call from Torch to BBC Base Processor.
;
; A register has osbyte type
; H register has equivalent Y register of 6502
; L register has equivalent X register of 6502
;
; Results (X and Y) are returned in HL respectively
;
;
usrimm equ 0ffc0h ; MCP user function [32]
tx equ 0ffc3h ; tx routine to talk to base board proc.
rx equ 0ffc6h ; rx ditto
txbyte equ 0ffc9h ; send C to base processor [32]
osbyte: ; Osbyte rewritten [32]
push b ; Keep these
mov b,a ; Local copy - use in a moment
call usrimm ; MCP osbyte function
db 15
mov c,b ; Osbyte function
call txbyte
mov c,l ; 6502 X register
call txbyte
mov c,h ; 6502 Y register
call txbyte
call rx ; fetch results
mov l,a ; X returned
sta xx ; save just in case...
call rx
mov h,a ; Y returned
sta yy
mov a,b ; return A as called
pop b
ret
xx: db 0
yy: db 0 ; temporary space
prinuse:db 0 ; 0=> fast tx, <>0 => slow tx to serial pt. [30]
ENDIF ;torch [13]
IF pci2651 ; whatever version
sysver: db 'Ithaca Intersystems S100$'
ENDIF ;pci2651
IF ncrdmv ; whatever version
sysver: db 'NCR DecisionMate V$'
ENDIF ;ncrdmv
IF torch ; whatever version
ttytyp:
sysver: db 'Torch Unicorn 5 '
db '$' ; stop here for now, otherwise say..
db ' MCP version '
db '1.00 $' ; or whatever...
ENDIF ;torch
; Assume MCP - CCCP ROMS greater than 1
;mcpver: db 'x.x $'
;outlin: db esc,'*',cr,lf,tab,'$'
;eralin: db cr,esc,'&$' ;Clear to end of line.
;erascr: db esc,'*$' ;Clear screen and go home.
;curldn: db esc,'=$' ;Cursor lead-in
;ttab: ;Table start location.
;ta:
db esc,'!$',0 ;Cursor up.
;tb: db 0ah,'$',0,0 ;Cursor down.
;tc: db esc,'+$',0 ;Cursor right.
;td: db 08h,'$',0,0 ;Cursor left.
;te: db esc,'*$',0 ;Clear screen and home cursor
;tf: db '$',0,0,0 ;(can't) Enter Graphics mode
;tg: db '$',0,0,0 ;(can't) Exit Graphics mode
;th: db esc,'>$',0 ;Cursor home.
;ti: db '$',0,0,0 ;(Can't) reverse linefeed
;tj: db esc,'%$',0 ; Clear to end of screen
;tk: db esc,'&$',0 ; Clear to end of line.
;Older message for MCP - CCCP verstion less than 1
;ooutli: db 0ch,cr,lf,tab,tab,'$';
;oerali: db '$',0,0,0 ;Clear to end of line.
;oerasc: db 0ch,'$',0 ;Clear screen and go home.
;ocurld: db 1fh,'$',0 ;Cursor lead-in
;ottab: ;Table start location.
; db 0bh,'$',0,0 ;Cursor up.
; db 0ah,'$',0,0 ;Cursor down.
; db 09h,'$',0,0 ;Cursor right.
; db 08h,'$',0,0 ;Cursor left.
; db 0ch,'$',0,0 ;Clear screen and home cursor
; db '$',0,0,0 ;(can't) Enter Graphics mode
; db '$',0,0,0 ;(can't) Exit Graphics mode
; db 1eh,'$',0,0 ;Cursor home.
; db 0bh,'$',0,0 ;reverse linfeed
; db '$',0,0,0 ;(Can't) Clear to end of screen
; db '$',0,0,0 ;(Can't) Clear to end of line.
;
;Specials
;spac15: db ' '
; db bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,'$';
;spac80: db cr
; db ' '
; db ' '
; db bs,cr,'$' ;80 spaces, bs and then back to line start
;
IF torch ; Should be IF ker08 AND torch...
db '$' ; to terminate the ID string
outlin: db 0ch,cr,lf,tab,tab,'$'
eralin: db '$',0,0,0 ;Clear to end of line.
erascr: db 0ch,'$',0 ;Clear screen and go home.
curldn: db 1fh,'$',0 ;Cursor lead-in
ttab: ;Table start location.
ta: db 0bh,'$',0,0 ;Cursor up.
tb: db 0ah,'$',0,0 ;Cursor down.
tc: db 09h,'$',0,0 ;Cursor right.
td: db 08h,'$',0,0 ;Cursor left.
te: db 0ch,'$',0,0 ;Clear screen and home cursor
tf: db '$',0,0,0 ;(can't) Enter Graphics mode
tg: db '$',0,0,0 ;(can't) Exit Graphics mode
th: db 1eh,'$',0,0 ;Cursor home.
ti: db 0bh,'$',0,0 ;reverse linfeed
tj: db '$',0,0,0 ;(Can't) Clear to end of screen
tk: db '$',0,0,0 ;(Can't) Clear to end of line.
;Specials
spac15: db ' '
db bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,'$';
spac80: db cr
db ' '
db ' '
db bs,cr,'$' ;80 spaces, bs and then back to line start
ENDIF;ker08 AND torch [13]
IF brain
sysver: db 'Intertec SuperBrain$'
outlin: db ('A'-100O),esc,'~k',cr,lf,tab,tab,'$'
erascr: db ('A'-100O),esc,'~k$' ;Clear screen and go home.
eralin: db cr,esc,'~K$' ;Clear line.
curldn: db esc,'Y$' ; leadin for cursor positioning
ttab: ;Table start location.
ta: db ('K'-100O),'$',0,0 ;Cursor up.
tb: db 12O,'$',0,0 ;Cursor down.
tc: db ('F'-100O),'$',0,0 ;Cursor right.
td: db '$',0,0,0 ;(can't) Cursor left
te: db '$',0,0,0 ;(can't) Clear display
tf: db '$',0,0,0 ;(can't) Enter graphics mode
tg: db '$',0,0,0 ;(can't) Exit graphics mode
th: db ('A'-100O),'$',0,0 ;Cursor home.
ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.
tj: db esc,'~k$',0 ;Clear to end of screen.
tk: db esc,'~K$',0 ;Clear to end of line.
ENDIF;brain
IF lasm and not termin ; we dont want CPXVDU
ovlend equ $ ;Overlay end - start buffer
end
ENDIF ;lasm and not termin
IF lasm; we want a terminal
LINK CPXVDU.ASM
ENDIF ;lasm