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 ?, 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: ,,, and 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