; CP4SYS.ASM ; 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 code and data for KERMIT. ; It will be probably be broken into independent files to generate ; overlays for the various systems, one or more overlay possible ; from each file. For now, we will leave it in one piece. ; ; revision history: ; ; edit 31 April 17th, 1986 OBSchou. Bugs in PX8 kermit fixed. ; ; edit 30 24th march, 1986 by OBSchou. Sorting out torch tx and break ; problems... AGAIN ; ; edit 29, March 7th, 1986 by OBSchou. Added in code for Epson PX8 ; code written by Tony Addyman from Salford University. This is ; really two edits into one, with a final edit of a dollar in the ; help messages. ; Also add in code from an Unknown kermiteer, who added code for a ; basic Northstar (basicns) (small changes) and also wrote the ; following headers to a list of "changes" to the CP4SYS file..... ; ;> ACCESS-MATRIX ;> Note - The following differences in CP4SYS.ASM apply to the ;> implementation for the Access-Matrix computer. ;> In CP4TYP.ASM, set access to TRUE, inout to TRUE, and crt to FALSE ;> Use port J5 of the Access ;> ;> PMC MICROMATE ;> The following applies to the implementation for Personal Micro ;> Computers PMC-101 MicroMate. In CP4TYP.ASM, set mmate to TRUE, ;> inout to TRUE, and crt to TRUE (Don't know what terminal might ;> be used.) ;> ;> U.S. Micro Sales s1008 (out of business) ;> Can use the same approach as for the basic NorthStar except set ;> crt to FALSE. (s1008) ;> ;> A. C. E. DISCOVERY ;> This implementation is for the Action Computer Enterprise, Inc. ;> "Discovery" multi user computer. It uses port B on an 83U ;> user board. ;> ;> In CP4TYP.asm set disc to TRUE, inout to TRUE, and crt to TRUE ;> ; ; edit 28, January 29 1986 by OBSchou ; added code to drive a 2651 USART for one of our odd ball ; machines. (Euromicro/Ithica Intersystems VIO (?) board) ; (pci2651) Also split the HUGE cp4sys.asm file into two smaller ; ones: this one is still CP4SYS.ASM, the next one is CP4SY2.ASM ; The break is just after the BREAK and DELAY routines.. roughly 1/2 ; way through the file. ; ; edit 27, 23rd January, 1986 ; General tidy up of code and comments ; ; edit 26: 10 December by OBSchou Loughborough University. ; Edit out nested IF around screen handling code (Shame on me) ; Aslo re-inserted code for prtstr for all other machines than Torch ; as some (RM380Z is one) throws up when using direct con out. ; ; edit 25: 24 November, 1985 by ajcole @ leeds.ai ; Merged in support for the following: ; North Star Horizon without SIO-4 (horizon) ; Comart Communicator (comart) ; Cromemco TU-ART interface (cmemco) ; TVI912/920 VDUs (tvi912) ; ; Separated initialisation and speed setting for SuperBrain ports, ; Main 'brainm' and Aux 'braina' ports are now independent. ; ; EDIT 24 14 November, 1985 by OBSchou @ Loughborough. Tidied up some ; aphids wot crept in edit 22. Thanks to Brian Robertson ; for checking the code. ; ; Edit 23 9th November, 1985 by OBchou @ Loughborough. ; Moved an lxi h,0f0f in the cpt85 and advant code in sysinit. ; My crummy merging showing up. (Tut Tut) ; ; Edit 22 by OBSchou @ Loughborough. Merge in code from B Robertson ; of Aberdeen University. He writes: ; September 20, 1985 by B Robertson, Aberdeen Univ. Computing Centre. ; Add support for Research Machines 380Z, North Star Advantage, Acorn ; BBC with Z80 co-processor and APPLE II with Mountain Computers CPS ; Multifunction card. ; ; Edit 21 by OBSchou at Loughborough General tidyup of files ; ; Edit 20: add in call in sysinit to call inadr etc (for io byte init) ; as the modified prtstr requires outcon, ie the bios call. The code ; hase only been moved to be the first thing done by sysinit. ; Also added the escape sequences required for the Cifer to be set ; correctly. Comes as part of the Conf. message. ; io byte calls. Code is there, it just does not seem to be called ; ; Edit 19, 11 October, 1985 by OBSchou at Loughborough ; Added Torch and Brain to conditional IF for sysinh to write ; message sayin these can do breaks. Should have noticed, tut tut ; ; edit 18; october 9th, 1985 by OBSchou at Loughborough University. ; added in code to generate breaks on Torch range of computers ; ; edit 17: October 7th, 1985 OBSchou ; added code to set baud rate for Torch. Also fond that DOS call 9 ; (Print a string) ruins any embedded control characters. Have ; therefore written an equivalent routine as prtstr using repeated ; calls to outcon, which uses direct io (DOS call 6). This sorts ; the TORCH cursor addressing problem. ; ; ; edit 16: 4 september, 1985 by OBSchou ; Added Superbrain Breaks.. similar to cpt85xx as these two seem ; use that ever so common 8251 USART. ; ; edit 15: 14 August, 1985, by OBSchou. ; Try to sort out non-cursor posiotioning on torch.. and bug that ; kills xfers after 443 packets. (See edit 17) ; ; edit 14: 14 June 12,1985, by OBSchou at Loughborough University ; added code to automatically select rs423 port rather than cassette ; interface on the BBC Microcomputer (The BASE PROCESSOR) when ; driven from a Torchpack /Unicorn 5 etc ; ; edit 13: JUNE 11, 1985 by OB Schou, Loughbororugh University, UK ; added in code for Torch Unicorn 5 + CP/N (as in Nut) and Cifer ; 1886. This will probably cover also 26xx and 28xx series machines. ; ; edit 12: February 6, 1985 ; Add extended H89 support (by Paul Milazzo, Rice University), ; support for Northstar Horizon with Northstar CP/M and SIO-4 board ; (by Joe Smith, Colorodo School of Mines), and support for Lobo ; MAX-80 computer (from Hal Hostetler) ; ; edit 11: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809 ; ;pcc001 27-Dec-84 vjc modules: cp4sys,cp4typ ; Add conditional for Xerox 820. I thought at first I could ; live with the kaypro conditional, but it's enough of a pain ; that I added it back in. The clear-to-end-of-screen char ; is different, breaking many programs in VT52 mode, and the ; default escape char control-\2, is not at all obvious how ; to type on the 820 keyboard. If you muddle through the ; key translation table, it turns out to be control-comma. ; Rather than OR xer820 all the occurances of kpII conditionals ; I added a bbI conditional for all common code for the big ; board I based machines that is automatically turned on by ; either kpII or xer820. This will also make it easier in ; the future if another flavor of bigboard is added. ; ; edit 10: 5 December 1984 by CJC ; Add missing ENDIF (tsk, tsk) ; ; edit 9: 4 December 1984 by CJC ; Add two osborne fixes: missing crlf in outlin:, incorrect opcode in ; initialization. ; ; edit 8: 13 October 1984 by L M Jones, JCC, for New York Botanical Garden ; Add support for CPT-85xx series word processors when running CP/M-80. ; ; edit 7: 29 August 1984 by Bdale Garbee @ CMU ; Add support for Digicomp Delphi 100 and Netronics Smartvid terminal. ; ; edit 6: August 21, 1984 ; Add flsmdm, to flush comm line on startup. ; Support multiple-sector buffering (except for osborne 1). ; ; edit 5: August 19, 1984 ; Add missing RET in outlpt: (*sigh*). Also preserve DE in case ; the BIOS destroys it. Add version string (sysedt, since sysver ; was already taken). ; ; edit 4: August 8, 1984 ; Running terminal output through the BDOS didn't work so well for ; the Kaypro. Remove the special check at outcon:. ; ; edit 3: August 3, 1984 ; move "mover" to CP4SYS from CP4UTL, so we can use Z80 block move. ; define Z80 true or false when setting up the rest of the parameters. ; (I'm only defining as Z80's the ones I KNOW are Z80's, because I ; don't want to break anything by guessing wrong). Make the values ; stored by sysinit in "speed" match the 16-bit values found in the ; speed table, so we can find them later. ; ; edit 2: July 27, 1984 (CJC) ; Add break capability for Kaypro II and bbII. ; Merge Toad Hall changes: Allow assembly with LASM, add support for ; Morrow Decision I. ; ; edit 1: May, 1984 ; extracted from CPMBASE.M80 version 3.9; modifications are described ; in the accompanying .UPD file. ; ; Keep module name, edit number, and last revision date in memory. sysedt: db 'CP4SYS.ASM (31) 17-APR-86 $' ; 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 robin .printx * Assembling KERMIT-80 for the DEC VT180 * ENDIF IF brain .printx * Assembling KERMIT-80 for the Intertec Superbrain * ENDIF IF brainm ;[13] .printx * With main port selected ENDIF IF braina .printx * With Aux port ENDIF ;[13] IF vector .printx * Assembling KERMIT-80 for the Vector Graphics * ENDIF IF osi .printx * Assembling KERMIT-80 for the Ohio Scientific * ENDIF IF heath .printx * Assembling KERMIT-80 for the Heath/Zenith 89 * ENDIF IF z100 .printx * Assembling KERMIT-80 for the Heath/Zenith Z100 * ENDIF IF apple .printx * Assembling KERMIT-80 for the Apple ][ * ENDIF;apple IF apmmdm .printx * with Z80 Softcard & Micromodem II * ENDIF;apmmdm IF ap6551 .printx * with Z80 Softcard & 6551 ACIA * ENDIF;ap6551 IF apcps;[22] .printx * with Softcard & CPS Multifunction card * ENDIF;apcps IF trs80 .printx * Assembling KERMIT-80 for the TRS-80 II * ENDIF IF osbrn1 .printx * Assembling KERMIT-80 for the Osborne 1 * ENDIF IF telcon .printx * Assembling KERMIT-80 for the Telcon Zorba * ENDIF IF dmII .printx * Assembling KERMIT-80 for the DECmate II * ENDIF IF gener .printx * Assembling Generic KERMIT-80 * ENDIF IF cpm3 .printx * Assembling Generic KERMIT-80 for CP/M 3.0 * ENDIF IF kpii .printx * Assembling Kaypro II KERMIT-80 * ENDIF IF xer820 ;[pcc001] .printx * Assembling Xerox 820 KERMIT-80 * ENDIF ;[pcc001] IF bbII .printx * Assembling BigBoard II KERMIT-80 * ENDIF IF mdI .printx * Assembling for Morrow Decision I * ENDIF ;mdI [Toad Hall] IF mmdI .printx * Assembling for Morrow Micro Decision I * ENDIF ;mmdI IF mikko .printx * Assembling MikroMikko Kermit-80 * ENDIF IF delphi ;[7] .printx * Assembling Digicomp Delphi 100 Kermit-80 * ENDIF ;[7] IF cpt85xx .printx * Assembling CPT-85xx (under CompuPak CP/M) Kermit-80 * ENDIF IF norths .printx * Assembling for NorthStar Horizon with HSIO-4 board * ENDIF;norths IF comart ;[25] .printx * Assembling KERMIT-80 for the Comart Communicator * ENDIF;comart IF horizon ;[25] .printx * Assembling KERMIT-80 for the NorthStar Horizon * ENDIF;horizon IF cmemco ;[25] .printx * Assembling KERMIT-80 for the Cromemco (TU-ART) * ENDIF;cmemco IF pci2651 ;[28] .printx * assembling Kermit-80 for 2651 PCI as comms device * ENDIF ;[28] IF advant ;[22] .printx * Assembling kermit-80 for North Star Advantage * ENDIF ;[22] IF bbc ;[22] .printx * Assembling Kermit-80 for BBC with Z80 co-processor * ENDIF ;[22] IF rm380z ;[22] .printx * Assembling Kermit-80 for Research Machines 380Z * ENDIF ;[22] IF px8 ;[29] .printx * Assembling Kermit-80 for Epson PX-8 * ENDIF ;px8 [29] IF mmate ;[29] .printx * Assembling KERMIT-80 for the PMC MicroMate * ENDIF ;mmate [29] IF disc ;[29] .printx * Assembling KERMIT-80 for the A. C. E. Discovery * ENDIF ;disc [29] IF basicns ;[29] .printx * Assembling KERMIT-80 for the Northstar Horizon using printer port * ENDIF ;basicns [29] IF s1008 ;[29] .printx * Assembling KERMIT-80 for the MicroSales s1008 * ENDIF ;s1008 [29] IF access ;[29] .printx * Assembling Kermit-80 for the ACCESS-MATRIX computer * ENDIF ;access [29] IF cifer ;[13] .printx * Assembling Kermit-80 for Cifer 1886 * ENDIF IF torch .printx * Assembling Kermit-80 for Torch Unicorn 5 * ENDIF;Torch [13] IF lobo ;[hh] .printx * Assembling Kermit-80 for the Lobo MAX-80 * ENDIF;lobo [hh] ; Also tell what kind of terminal, if any, is selected IF crt .printx * generic CRT selected * ENDIF IF adm3a .printx * ADM3A selected * ENDIF IF smrtvd ;[7] .printx * Netronics Smartvid-80 selected * ENDIF ;[7] IF tvi912 .printx * TVI912/920 selected * ENDIF IF tvi925 .printx * TVI925 selected * ENDIF IF vt52 .printx * VT52 selected * ENDIF IF vt100 .printx * VT100 selected * ENDIF ;========================================================================= ; 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 ; the basics... IF robin OR gener batio EQU 056H ;I/O byte CON=BAT,LIST=CRT,READER=RDR,PUNCH=PTP defio EQU 095H ;I/O byte CON=CRT,LIST=LPT,READER=RDR,PUNCH=PTP ENDIF;robin OR gener IF gener crtio equ 01010101B ; use CRT: device ptrio equ 01010110B ; use PTR: device ttyio equ 00000000B ; use TTY: device uc1io equ 01010111B ; use UC1: device ur1io equ 01101010B ; use UR1: device ur2io equ 01111110B ; use UR2: device ENDIF;gener IF cifer ;[13] batio equ 80h ; tty: as console defio equ 81h ; crt: as console z80 equ false ; although it really is... ENDIF;cifer [13] IF robin lptio EQU 054H ;I/O byte CON=TTY,LIST=CRT,READER=PTR,PUNCH=PTP gppio EQU 057H ;I/O byte CON=UC1,LIST=CRT,READER=RDR,PUNCH=PTP ENDIF;robin IF dmII OR bbc ;[22] batio EQU 042H ;I/O byte CON=BAT,LIST=CRT,READER=RDR defio EQU 081H ;I/O byte CON=CRT,LIST=LPT,READER=RDR ENDIF;dmII IF mikko batio EQU 10110010B ; I/O byte console => serial line defio EQU 10000001B ; I/O byte console => CRT and Keyboard ENDIF;mikko ; ; Protocol parameters. Some of these can be changed with commands. ; drpsiz EQU 5EH ;Default receive packet size. (maximum is 5EH) dspsiz EQU 20H ;Default send packet size. (maximum is 5EH) dstime EQU 08H ;Default send time out interval. IF NOT (apple OR osbrn1) drtime EQU 05H ;Default receive time out interval. ENDIF;NOT (apple OR osbrn1) IF apple OR osbrn1 drtime EQU 0AH ; Use longer receive timeout on apple and osborne. ENDIF;apple OR osbrn1 dspad EQU 00H ;Default send padding. drpad EQU 00H ;Default receive padding. dspadc EQU 00H ;Default send padding char. drpadc EQU 00H ;Default receive padding char. dseol EQU CR ;Default send EOL char. dreol EQU CR ;Default receive EOL char. dsquot EQU '#' ;Default send quote char. drquot EQU '#' ;Default receive quote char. dschkt EQU '1' ;Default checksum type IF lobo ;[hh] mnport EQU 0F7E4H ;Modem data port A mnprts EQU 0F7E5H ;Modem status/conrtol port A baudrt EQU 0F7D0H ;Baud rate port A output EQU 04H ;Transmit buffer empty input EQU 01H ;Receive data available z80 EQU TRUE ;a good z80, here ENDIF;lobo ; [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 EQU 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 osi mnport EQU 0CF01H ;Modem data port mnprts EQU 0CF00H ;Modem status port output EQU 02H ;Transmitter empty input EQU 01H ;Input data available z80 EQU FALSE ;I don't know... ENDIF;osi IF vector mnport EQU 04H ;Modem data port mnprts EQU 05H ;Modem status port output EQU 01H ;Transmitter empty input EQU 02H ;Input data available z80 EQU FALSE ;I don't know... ENDIF;vector IF delphi ;[7] mnport EQU 22H ;[7] Modem data port mnprts EQU 23H ;[7] Modem status port output EQU 01H ;[7] Transmitter empty input EQU 02H ;[7] Input data available baudrt equ 29h ;[7] Baud rate port for channel 2 (default) z80 EQU true ;[7] We're using the z80 side of the dual processor ENDIF;[7] delphi IF heath ; Definitions for the 8250 ACE acerbr EQU 0 ; ACE Receiver Buffer Register offset (R/O) (DLAB = 0) acethr EQU 0 ; ACE Transmitter Holding Register offset (W/O) acedll EQU 0 ; ACE Divisor Latch (Low) (DLAB = 1) acedlh EQU 1 ; ACE Divisor Latch (High) (DLAB = 1) aceier EQU 1 ; ACE Interrupt Enable Register (DLAB = 0) aceiir EQU 2 ; ACE Interrupt Identification Register acelcr EQU 3 ; ACE Line Control Register acemcr EQU 4 ; ACE Modem Control Register acelsr EQU 5 ; ACE Line Status Register offset acemsr EQU 6 ; ACE Modem Status Register ace8bw EQU 00000011b ; 8 bit words acesb EQU 01000000b ; set break acedla EQU 10000000b ; divisor latch access acedtr EQU 00000001b ; data terminal ready aceloo EQU 00010000b ; loopback mode acedr EQU 00000001b ; data ready acethe EQU 00100000b ; transmitter holding register empty mnport EQU 330O ;Modem data port mnprts EQU mnport+acelsr ;Modem status port output EQU acethe ;Transmitter empty input EQU acedr ;Input data available z80 EQU TRUE ;H89 uses the Z80 ENDIF;heath IF z100 mnport EQU 0ECH ;Modem data port mnprts EQU 0EDH ;Modem status port output EQU 01H ;Transmitter empty input EQU 02H ;Input data available z80 EQU FALSE ;[hh] this one's an 8085. ENDIF;z100 IF trs80 ;NEEDS display definition (e.g. trs80lb or trs80pt) mnport EQU 0F4H ;Modem data port (0F5H for port B) mnprts EQU 0F6H ;Modem status port (0F7H for port B) output EQU 04H ;Transmitter empty input EQU 01H ;Input data available z80 EQU TRUE ;[hh] All TRS-80's but the CoCo ENDIF;trs80 IF apmmdm ;APPLE Slot 2 contains Micromodem II. MNPORT EQU 0E0A7H ;Communications Port. mnprts EQU 0E0A6H ;Communications Port Status. mnmodm EQU 0E0A5H ;Modem Control Port. orgmod EQU 8EH ;Modem Originate Mode. OUTPUT EQU 02H ;Output Buffer Empty. INPUT EQU 01H ;Input Register Full. apinc1 EQU 03H ;First Init Character for 6850 ACIA (Reset) apinc2 EQU 11H ;Second Init Character for ACIA (8-bits) apoffh EQU 80H ;Set if OFFHOOK AP300 EQU 1 ;300 Baud z80 EQU TRUE ;Z80 Softcard ENDIF;apmmdm IF ap6551 ;jb mnport EQU 0E088H+(10H*apslot) ;jb Communications Port. mnprts EQU 0E089H+(10H*apslot) ;jb Communications Port Status. mnprtc EQU 0E08BH+(10H*apslot) ;jb Communications Control mnprtm EQU 0E08AH+(10H*apslot) ;jb Communications Master (command) output EQU 10H ;jb Output Buffer Empty. input EQU 08H ;jb Input Register Full. mncinb EQU 18H ;jb Control Port Initialization Byte ;jb (8-bit, no parity, 1-stop, 1200 baud) mnminb EQU 0BH ;jb Master Port Initialization Byte ;jb (DTR, RTS, no interrupts) z80 EQU TRUE ;Z80 Softcard ENDIF;ap6551 IF apcps ;[22] mnport EQU 0E0FAH+(100H*apslot) ; Communications Port. mnprts EQU 0E0FBH+(100H*apslot) ; Communications Port Status. mnprtc EQU 0E0FEH+(100H*apslot) ; Communications Control output EQU 1 ; Output Buffer Empty. input EQU 2 ; Input Register Full. TxEmpty EQU 04h ; Transmitter empty flag apmod1 EQU 4EH ; Mode Byte 1 (1 stop, no parity,8-bit, 16x) ; Mode Byte 2 is speed control byte apcmd EQU 37H ; Command Byte (RTS,Error reset,RxE,DTR,TxE) z80 EQU TRUE ;Z80 Softcard ENDIF;[22] apcps IF osbrn1 ;Osborne 1 uses 6850 ACIA, but memory mapped. Derived from Apple. BAUDRT EQU 0EFC1H ;Memory location where baud rates are stored. OSTOP EQU 4000H ;Where we move OSMOVE to at startup OSPORT EQU 2A01H ;Communications Port. OSPRTS EQU 2A00H ;Communications Port Status. OUTPUT EQU 02H ;Output Buffer Empty. INPUT EQU 01H ;Input Register Full. OSBIN1 EQU 57H ;First Init Character for 6850 ACIA (Reset) ;(I would have thought 03, but prom code writes 57 there) OSBI12 EQU 55H ;Second Init Character for ACIA (8-bits, 1200) OSBI03 EQU 56H ;Second init char. for ACIA (8 bits, 300) ;(don't ask.. I don't know why SETUP writes 55 and 56 either) z80 EQU TRUE ;[hh] a z80 here, also ENDIF;osbrn1 IF telcon MNPORT EQU 20H ;Modem data port MNPRTS EQU 21H ;Modem status port OUTPUT EQU 01H ;Transmitter empty INPUT EQU 02H ;Input data available z80 EQU FALSE ;I don't know... ENDIF;telcon IF robin ;Those definitions below that are commented out are just for information ;***** NOT generally found in distributed documentation **** ;pbausl EQU 90H ;The Baud-Rate register. prntst EQU 49H ;Printer ;prndat EQU 48H contst EQU 41H ;Console ;condat EQU 40H gentst EQU 51H ;General port. ;gendat EQU 50H comtst EQU 59H ;COMM-Port ;comdat EQU 58H ;output EQU 01H ;Output ready bit. ;input EQU 02H ;Input ready bit. z80 EQU TRUE ; This one's a Z80. ENDIF;robin IF bbI mnport equ 04h ; Modem data port mnprts equ 06h ; Modem status port output equ 04h ; Transmit buffer empty input equ 01h ; Receive data available baudrt equ 00h ; Baud rate port for channel A z80 EQU TRUE ; This one's a Z80. ENDIF;bbI IF norths ;The basic Northstar Horizon BIOS does not access ports 2-5 port0d equ 02h ;Port 0 data (console) port0s equ 03h ;Port 0 status port1d equ 04h ;Port 1 data (printer) port1s equ 05h ;Port 1 status port2b equ 10h ;Port 2 baud port2i equ 11h ;Port 2 interrupt mask port2d equ 12h ;Port 2 data port2s equ 13h ;Port 2 status port3b equ 14h ;Port 3 baud port3i equ 15h ;Port 3 interrupt mask port3d equ 16h ;Port 3 data port3s equ 17h ;Port 3 status port4b equ 18h ;Port 4 baud port4i equ 19h ;Port 4 interrupt mask port4d equ 1Ah ;Port 4 data port4s equ 1Bh ;Port 4 status port5b equ 1Ch ;Port 5 baud port5i equ 1Dh ;Port 5 interrupt mask port5d equ 1Eh ;Port 5 data port5s equ 1Fh ;Port 5 status NS19K2 EQU 00H ;19.2 kilobaud NS9600 EQU 01H ;9600 baud NS4800 EQU 02H ;4800 baud NS2400 EQU 03H ;2400 baud NS1200 EQU 04H ;1200 baud NS0600 EQU 05H ; 600 baud NS0300 EQU 06H ; 300 baud NS0110 EQU 07H ; 110 baud ;; Set to use port 5 at 1200 baud ***** mnport equ port5d ;Data port mnprts equ port5s ;Status port baudrt equ port5b ;Baud rate port baudini equ ns1200 ;Initial baud rate output EQU 1 ;Bit of UART status for transmitter ready input EQU 2 ;Bit of UART status for receiver ready z80 EQU TRUE ;This one's a Z80. ENDIF;norths IF basicns ;[29] mnport equ 04h ;printer port data mnprts equ 05h ; printer port status output equ 1 ;transmitter ready input equ 2 ;receiver ready z80 equ FALSE ; not important ENDIF ;basicns [29] IF s1008 ;[29] mnport equ 00 ;printer port data mnprts equ 01 ;printer port status output equ 4 ;transmitter ready input equ 2 ;receiver ready z80 equ FALSE ;not important ENDIF;s1008 [29] IF mmate ;[29] mnport EQU 89H ;MODEM data port mnprts EQU 8BH ;MODEM status/control port output EQU 04H ;Transmit buffer empty, ready to send input EQU 01H ;Receive data available baudrt EQU 93H ;MODEM baud rate port ;NOTE - also used for console z80 EQU TRUE ENDIF;mmate [29] IF disc ;[29] mnport EQU 05 ;Discovery 83U port B data mnprts EQU 04 ;Discovery 83U port B status/command output EQU 04 ;Transmit buffer empty input EQU 01 ;Receiver ready z80 EQU TRUE ENDIF;disc [29] IF comart ;[25] mnport EQU 002H ;Modem data port mnprts EQU 003H ;Modem status port output EQU 01H ;Transmitter empty input EQU 02H ;Input data available TxEmpty EQU 04h ;Transmitter empty ;Note: Needs terminal definition (vt100, vt52, tvi925, adm3a or crt above) z80 EQU TRUE ;This one's a Z80. ENDIF;comart IF horizon ;[25] mnport EQU 004H ;Modem data port mnprts EQU 005H ;Modem status port output EQU 01H ;Transmitter empty input EQU 02H ;Input data available TxEmpty EQU 04h ;Transmitter empty ;Note: Needs terminal definition (vt100, vt52, tvi925, adm3a or crt above) z80 EQU TRUE ;This one's a Z80. ENDIF;horizon IF cmemco ;[25] tuart EQU 020H ;TU-ART address mnport EQU tuart+1 ;Modem data port mnprts EQU tuart ;Modem status port output EQU 080H ;Transmitter empty input EQU 040H ;Input data available baudrt EQU tuart ;Baud rate port ;Note: Needs terminal definition (vt100, vt52, tvi925, adm3a or crt above) z80 EQU TRUE ;This one's a Z80. ENDIF;cmemco 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 equ true ; For Ithica intersystems it is cpuspd equ 40 ; and running at four megs ENDIF ;[28] IF bbII mnport equ 80h ; Modem data port (SIO channel A) mnprts equ 81h ; Modem status port output equ 04h ; Transmit buffer empty input equ 01h ; Receive data available baudrt equ 89h ; Baud rate port for channel A z80 EQU TRUE ; This one's a Z80. ENDIF;bbII IF cpt85xx baudrt EQU 4Ch ; Baud rate generater (National MM5307) mnport EQU 4Bh ; Comm port data register (Intel 8251) mnprts EQU 4Ah ; Comm port command/status register output EQU 01h ; Transmitter buffer empty flag input EQU 02h ; Reciver buffer full flag TxEmpty EQU 04h ; Transmitter empty flag z80 EQU FALSE ; It's really an 8080 [or 8085 ... same thing] ENDIF;cpt85xx IF mmdI ;Morrow MicroDecision - the single-board one mnport EQU 0FEH ;Morrow Printer UART data port mnprts EQU 0FFH ;Morrow Printer UART command/status output EQU 01H ;Output ready bit. input EQU 02H ;Input ready bit. ;Note: Needs terminal definition (vt100, vt52, tvi925, adm3a or crt above) z80 EQU FALSE ;I don't know... ENDIF;mmdI IF advant ;[22] slot EQU 1 ;SIO card slot mnport EQU (6-slot)*16 ;Modem data port mnprts EQU mnport+1 ;Modem status port baudrt EQU mnport+8 ;Baud rate register output EQU 01H ;Transmitter buffer empty input EQU 02H ;Input data available TxEmpty EQU 04h ;Transmitter empty flag z80 EQU TRUE ENDIF;[22] advant IF bbc ;[22] osbyte EQU 0FFF4H ; OS entry point osword EQU 0FFF1H ; " " " term EQU 0FFC8H ;Terminal mode OS entry z80 EQU TRUE ENDIF;[22] bbc IF rm380z ;[22] mnport EQU 0E8H ;Modem data port mnprts EQU 0E9H ;Modem status port output EQU 01H ;Transmitter buffer empty input EQU 02H ;Input data available TxEmpty EQU 04h ;Transmitter empty flag z80 EQU TRUE ENDIF;[22] rm380z IF px8 ; [29] z80 EQU TRUE mnprts EQU 0dh ; used in sending a break ENDIF ;px8 [29] IF mdI ;Morrow Decision I - the big sucker mnport equ 48H ; Modem data port. mnprts equ 4DH ; Modem status port. output equ 20H ; Transmitter empty. input equ 1 ; Input data available. mbase equ 48H ; Base address of Multi I/O port ; selector area. grpsel equ 4FH ; Group select port. rbr equ 48H ; Read Data Buffer. group equ 1 ; Multi I/O Group byte for serial ports. congrp equ 1 ; Serial Port 1 for console mdmgrp equ 3 ; Serial Port 3 for modem. ; Following are needed for baud rate changes...[Toad Hall] dlm equ 49H ; Baud Rate Divisor (Most Sig Bit) dll equ 48H ; Baud Rate Divisor (Least Sig Bit) ier equ 49H ; Interrupt Enable Register lcr equ 4BH ; Line Control Register lsr equ 4DH ; Line Status Register msr equ 4EH ; Modem Status Register dlab equ 80H ; Divisor Latch Access Bit wls0 equ 1 ; Word Length Select Bit 0 wls1 equ 2 ; Word Length Select Bit 1 for 8 bit word stb equ 4 ; Stop bit count - 2 stop bits imask equ 0 ; Interrupt mask (all disabled) z80 EQU TRUE ; This one's a Z80. ENDIF ;mdI NOTE: needs terminal definition. [Toad Hall] IF mikko sioac EQU 0FF12H ;SIO channel A register(s) address sioo3 EQU 01000001B ;SIO Write Reg. 3 original setup (?) ;RX 7 bits,synch mode bits 0,RX enable sion3 EQU 11001111B ;SIO Write Reg. 3 KERMIT setup ;RX 8 bits,synch mode bits 0,RX enable sioo4 EQU 01001111B ;SIO Write Reg. 4 original setup (?) ;X16 clock,8 bit synch(ignored), ;2stop bits,par even(on) sion4 EQU 01000100B ;SIO Write Reg. 4 KERMIT setup ;X16 clock,8 bit synch(ignored), ;1stop bit,par off sioo5 EQU 10101010B ;SIO Write Reg. 5 original setup (?) ;DTR,TX 7 bits,TX enable,RTS sion5 EQU 11101010B ;SIO Write Reg. 5 KERMIT setup ;DTR,TX 8 bits,TX enable,RTS txclk EQU 0FF30H ;Baud rate generator (CTC) for transmitter rxclk EQU 0FF31H ;Baud rate generator (CTC) for receiver chmask EQU 0F1F2H ;Mask byte address for SIO ch. A reception z80 EQU TRUE ;It's got a SIO and a CTC, it must be a Z80 ENDIF;mikko IF torch ;[13] z80 equ TRUE baudini equ 404h ; 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 access ;[29] mnport EQU 40H ;Modem data port A mnprts EQU 42H ;Modem status/conrtol port A output EQU 04H ;Transmit buffer empty input EQU 01H ;Receive data available z80 EQU TRUE ;a good z80, here ENDIF;access [29] IF robin OR dmII z80 EQU TRUE ; This one's a Z80 ENDIF;robin OR dmII IF gener OR cpm3 ; To be truly generic, we must assume 8080. z80 EQU FALSE ENDIF;gener OR cpm3 IF brain OR osi OR apple OR telcon OR xer820 OR cifer OR torch;[13] defesc EQU ']'-100O ;The default escape character. ENDIF;brain OR osi OR apple OR telcon OR xer820 OR cifer OR torch IF vector defesc EQU '~' ;Vector can't type ']'. ENDIF;vector IF robin OR dmII OR mikko OR heath OR z100 OR osbrn1 OR kpII OR lobo defesc EQU '\'-100O ;The default is Control \ -- it's easier B.E. ENDIF;robin OR dmII OR mikko OR heath OR z100 OR osbrn1 OR kpII OR lobo IF crt OR vt100 OR vt52 OR tvi912 OR tvi925 OR adm3a OR smrtvd OR cpt85xx defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) ENDIF;crt OR vt100 OR vt52 OR tvi912 OR tvi925 OR adm3a OR smrtvd OR cpt85xx IF advant OR bbc OR rm380z OR px8 OR access OR S1008 ;[22] [29] defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) ENDIF ;[22] advant OR bbc OR rm380z OR px8 OR access OR s1008[29] IF trs80 defesc EQU '_'-100O ;CTRL-_ (Down-arrow on TRS-80 keyboard) ENDIF;trs80 ; Select initial setting for VT-52 emulation flag. IF crt ; If dumb or unknown console, vtval EQU 0FFH ; we can't support VT52 emulation ENDIF;crt IF heath OR z100 OR telcon OR vt52 ; If console looks like (or is) VT52 vtval EQU 0 ; we don't need VT52 emulation ENDIF;heath OR z100 OR telcon OR vt52 IF robin OR dmII OR vt100 ; If console looks like VT100 vtval EQU 0 ; we probably don't want VT52 emulation ENDIF;robin OR dmII OR vt100 ; Select initial setting for VT-52 emulation flag. IF access ; Console can emulate VT-52 [29] vtval EQU 1 ENDIF;access [29] ; If none of the above, default to VT52-EMULATION ON. IF NOT (crt OR heath OR z100 OR telcon OR vt52 OR robin OR dmII OR vt100) vtval EQU 1 ENDIF;NOT (crt OR heath OR z100 OR telcon OR vt52 OR robin OR dmII OR vt100) ; Set the fuzzy timeout value. Range is 1 (VERY short) through 0ffffH to zero ; (maximum). The actual duration is a function of the loop length and the ; processor speed. For now, we'll make it zero for everybody, but feel free ; to change it for your system. fuzval EQU 0 ; ; System-dependent initialization ; Called once at program start. sysinit: ; ; [13] Had to move this call to here, as the prtstr routine needs this ; before the config message is sent out. It has only been moved. ; IF iobyt ; (actually, we ought to do this for everybody) call iniadr ;Initialize the BIOS addresses mvi c,gtiob ;Get current I/O byte call bdos ;From CP/M sta coniob ;Remember where console is ENDIF ;iobyte [13] mvi c,getvnm ; get the BDOS version number (e.g. 22H, 31H) call bdos mov a,l sta bdosvr ; and store it away for future reference ; lxi d,cfgmsg ; "configured for " call prtstr lxi d,sysver ; get configuration we're configured for call prtstr ; print it. ; ; If we're set up to do special terminal handling, say what kind ; of terminal we expect... (unless it's the generic 'crt') IF adm3a OR tvi912 OR tvi925 OR vt52 OR vt100 OR smrtvd OR access;[7] [29] lxi d,witmsg ; " with " call prtstr lxi d,ttytyp ; terminal type call prtstr ENDIF;adm3a OR tvi912 OR tvi925 OR vt52 OR vt100 OR smrtvd OR access;[7] [29] call prcrlf ; print CR/LF ; ; now, to work... ; IF NOT osbrn1 ; locate large buffer for multi-sector I/O ; What we want to do here is find the ccp. Space between ovlend and the ccp ; is available for buffering, except we don't want to use more than maxsec ; buffers (if we use too many, the remote end could time out while we're ; writing to disk). maxsec is system-dependent, but for now we'll just ; use 8Kbytes. If you get retransmissions and other protocol errors after ; transferring the first maxsec sectors, lower maxsec. ; I'm excluding the Osborne 1 for now because it needs code up at 4000H, ; so we'd have to start the buffer after that. maxsec EQU (8*1024)/bufsiz ; 8K / number of bytes per sector lxi h,ovlend ; get start of buffer shld bufadr ; store in linkage section mvi a,maxsec ; get size of buffer, in sectors sta bufsec ; store that, too. ENDIF;NOT osbrn1 IF osbrn1 lxi d,ostop ;where we're moving it to lxi h,osmove ;what we're moving mvi b,osmct ;How many bytes we're moving call mover lda baudrt ; Find out what speed is current ani 1 mvi a,osbi03 ; assume 300 baud jz osstr1 mvi a,osbi12 ; nope, it's 1200. osstr1: sta speed ; save initial speed sta speed+1 ; as 16 bits, to match speed table entries mov d,a mov e,a ; get initial speed in DE call sysspd ;set up parity etc. ENDIF;osbrn1 IF bbI OR bbII lxi d,siotbl ; Load the address of the status able mvi c,siolen ; Length of status table siolup: ;Loop back here for each command byte ldax d ; Load the first byte into A inx d ; Index the pointer out mnprts ; Send it to the status port dcr c ; Decrement the byte counter jnz siolup ; Jump back for more commands ENDIF;bbI or bbII IF cpt85xx mvi a,80h ; Send UART reset [force idle] by setting out baudrt ; bit 7 of baud rate I/O port lxi H,0f0fh ; Clear reset and default to 9600 baud [23] ENDIF ;[22] cpt85xx ; ; [22] Have diced code for advant and cpt85xx together ;************************************************************************** ; mvi a,0Fh ; Clear reset bit and default to 9600 baud ; out baudrt ; mvi a,4Eh ; Set UART mode to async 16x clock, 8 data ; out mnprts ; bits, no parity, and 1 stop bit ; mvi a,37h ; Set command to Tx enable, DTR on, Rx enable, ; out mnprts ; break off, error reset, and RTS on ;ENDIF;cpt85xx ;************************************************************************** IF advant ;[22] mvi a,40h out mnprts ; Reset USART lxi h,7070h ; Default to 1200 baud ENDIF;[22] advant IF cpt85xx OR advant ;[22] both Intel 8251 shld speed ; store current speed xchg call sysspd ; set default baud rate mvi a,4Eh ; Set UART mode to async 16x clock, 8 data out mnprts ; bits, no parity, and 1 stop bit mvi a,37h ; Set command to Tx enable, DTR on, Rx enable, out mnprts ; break off, error reset, and RTS on ENDIF;[22] cpt85xx OR advant IF bbc ;[22] lxi d,modstr ; Set MODE 3 call prtstr mvi a,1 ; Set terminal mode on call term mvi a,0F2H ; Read current transmit speed lxi h,0FF00H ; .. 3 lsb of ULA register call osbyte ; FX242,0,255 mov a,l ani 7 ; Mask of 3 lsb xri 7 ; Stored as 2's complement inr a sta speed ; Store 16 bit value sta speed+1 mov e,a ; Ensure RX and TX speeds are the same call sysspd ENDIF;[22] bbc IF rm380z ;[22] mvi e,11h ;Output ctrl-Q to clear autopaging call outcon ENDIF;[22] rm380z IF lobo ;[hh] lxi d,siotbl ;[hh] address of status table mvi c,siolen ;[hh] length of the table siolup: ;[hh] loop here for each command byte ldax d ;[hh] load first byte into A inx d ;[hh] index pointer to next bute sta mnprts ;[hh] send it to status port A sta mnprts+2 ;[hh] and to status port B dcr c ;[hh] decrement the counter jnz siolup ;[hh] loop back for more commands mvi a,05H ;[hh] value for 300 baud sta baudrt ;[hh] starting default for port A sta baudrt+4 ;[hh] and for port B sta speed ;[hh] tell program they're set mvi a,0E4H ;[hh] value for port A sta port ;[hh] tell program we've set this, too mvi a,0D0H ;[hh] port A baud rate value sta port+1 ;[hh] save this as well, for consistancy ENDIF ;lobo IF mikko lxi d,mintbl ;Address of KERMIT Reg values (what) mvi c,minlen ;Length of table (how many) lxi h,sioac ;Send data to ch. A SIO registers (to where) call movmik mvi a,0FFH ;Set ch. A mask to use all bits sta chmask ENDIF;mikko 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 mdI lxi h,96 ;Default 1200 baud modem port speed shld speed ;Store as modem port speed call sysspd ;Initialize the port ENDIF;mdI [Toad Hall] IF ap6551 lda mnprtc ; read control port ani 0fH ; extract low order nybble sta speed ; store as comm line speed sta speed+1 ; (16 bits, to match speed table entries) mvi a,mnminb ;jb initialization routine sta mnprts ;jb sta mnprtm ;jb initialize master (command) port mvi a,mncinb ;jb sta mnprtc ;jb initialize control port ENDIF;ap6551 IF apcps ;[22] lxi h,3737h ;Default 1200 baud shld speed ;Store as port speed xchg call sysspd ;Initialise the port ENDIF;[22] apcps IF cifer ;[13] lxi d,ciferi call prtstr ENDIF ;cifer [13] IF torch ;[13] push h push d lxi d,baudini ; initial buad rate of form ?0?h mvi a,7 ; osbyte call 7 = receive rate push d call osbyt1 pop d ; now do transmit rate mvi a,8 ; osbyte call 8 call osbyt1 lxi h,f31 ; enable rs423 call osbyte lxi h,f22 ; select keyboard, enable rs423 call osbyte lxi h,f52 ; fx 5,2 to select printer is serial port [30] call osbyte ; [30] lxi h,f60 ; fx 6,0 to send LF to line [30] call osbyte ; [30] pop d pop h jmp over ; [ for debugging use ] [30] ; ;[30] This is not used, but it may be used later, depending on the Current ;version of the CCCP. Leave it in for now ; add in code to dump 6502 code to the base processor (6502 based machine) ; to generate breaks. Code works ok, from BBC, but how about is triggered ; from this end of the Tube (Reg. Trade. Mrk) lxi h,840h ; gonna stuff the beebs RAM at 840h mvi b,codeln ; (Sound buffer) for code length lxi d,bbccode poklop: ldax d ; get data push h push d push b ; save in case tx to tube messs these call poke pop b pop d pop h inx h inx d dcr b ; adjust pointers jnz poklop ; send all bytes ; lxi h,0840h ; now read em back, to make sure it is there lxi d,tspace mvi b,codeln peklop: push h push d push b call peek pop b pop d pop h stax d ; save byte in torch space inx h inx d dcr b jnz peklop ; loop until all is done jmp over call tx ; send function 6 => write 40 bytes db 6 call tx ; address is 0840h, so send 083eh db 3eh ; as lo high combination call tx db 08h ; hi bits of target address lxi h,bbccode ; bbc code to send mvi b,40 ; cout is forty tbrkinit: ; Torch break code initialisation... mov a,m sta tbrki1 ; little impure code... push h push b ; just in case call tx tbrki1: db 0 ; fill this in pop b pop h inx h dcr b ; count less one jnz tbrkinit ; loop til done jmp over ;.. the 6502 code bbccode: db 0a9h,09ch ;.BREAK LDA #&9c get original 6850 regs db 0afh,0ffh ; LDY #&FF by osbyte call db 0a2h,00h ; LDX #0 db 20h,0f4h,0ffh ; JSR OSBYTE db 8ah ; TXA save returned byte db 48h ; PHA on the stack db 0a2h,0dch ; LDX #220 Swiped this from BBC db 0a0h,0dch ; LDY #220 Kermit, Lancaster Uni. db 0a9h,77h ;.LOOP LDA #77 (If it works, use it) db 8dh,08h,0feh ;.LOOP STA &FE08 reset 6850 regs db 88h ; DEY counter db 0d0h,0fah ; BNE LOOP db 0cah ; DEX db 0d0h,0f7h ; BNE LOOP loads of loops db 68h ; PLA get original x back db 0aah ; TAX to x reg db 0a9h,09ch ; LDA #&9c Osbyte to restore it db 0a0h,00h ; LDY #0 (reg AND Y) EXOR X db 20h,0f4h,0ffh ; JSR OSBYTE db 060h ; RTS hopefully back across ; the tube to torch db ' ' ; 20 spaces db ' ' ; any left over wont be sent codeln equ $-bbccode tspace: db ' ' ; fill space with muck db ' ' ; to make sure peeks and pokes work over: ; just a label ENDIF ;torch [13] 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] IF norths mvi a,baudini ;Get initial speed out baudrt sta speed ;save for status display sta speed+1 ENDIF;norths IF comart OR horizon ;[25] ; The PD8251/PD8251A is reset by three successive 00 Hex or two ; successive 80 Hex command instructions followed by a software ; reset command instruction (40 Hex). mvi a,80h ; Send UART reset out mnprts mvi a,80h out mnprts mvi a,40h out mnprts mvi a,4Eh ; Set UART mode to async 16x clock, 8 data out mnprts ; bits, no parity, and 1 stop bit mvi a,37h ; Set command to Tx enable, DTR on, Rx enable, out mnprts ; break off, error reset, and RTS on ENDIF;comart OR horizon IF cmemco ;[25] mvi a,01h ; Reset TU-ART out tuart+2 mvi a,90h ; Set default baud rate (2400), and 1 stop bit out tuart sta speed ; save for status display sta speed+1 ENDIF;cmemco IF delphi ;[7] ; ; shove the default baud rate (1200) in to the Delphi port address ; for the baud rate generator on port 2, the default port; save this ; value so we can tell what speed is selected. ; mvi a,07h ;[7] get value for 1200 baud out baudrt ;[7] set it for port 2 sta speed ;[7] save for status display sta speed+1 ENDIF;[7] delphi IF px8 ; [29] lda 0f6a9h ; get baud rate value set by CONFIG sta px8blk+4 ; put into parameter block mov h, a ; initialise global speed indicator mov l, a shld speed lhld 6 ; base of CP/M ; buffer starts at ovlend+8192, immediately after sector buffer ; We must also allow (800h) for the CCP as Kermit exits with a RET lxi d, ovlend+8192+800h ; calc buffer length ora a ; clear carry db 0edh, 52h ; sbc hl, de shld px8blk+2 call rsopen ENDIF ; px8 [29] IF disc ;[29] ;Initialization sequence for Discovery 83U port B ;Sets port to 9600 baud, 8 data bits, 1 stop bit, no parity mvi a,12 ;Register 12 out mnprts mvi a,11 ;Low byte of time constant for 9600 out mnprts mvi a,13 ;Register 13 out mnprts mvi a,0 ;High byte of time constant for 9600 out mnprts mvi a,14 ;Register 14 out mnprts mvi a,3 ;Enable baud rate generator out mnprts mvi a,11 ;Register 11 out mnprts mvi a,52h ;No Xtal, tclk=rclk=/trxc out=br gen out mnprts mvi a,4 ;Register 4 out mnprts mvi a,44h ;16x clock, 1 stop, no parity out mnprts mvi a,3 ;Register 3 out mnprts mvi a,71h ;rx 8 bit/ch, autoenable, rx enable out mnprts mvi a,5 ;Register 5 out mnprts mvi a,0eah ;tx 8 bit/ch, tx enable, rts out mnprts ENDIF;disc [29] IF heath ; ; System dependent startup for H89 ; call mdmofl ; keep the line safe from garbage ; First, tell Kermit the modem port's current speed in mnport+acelcr ori acedla out mnport+acelcr ; access the ACE's divisor latch in mnport+acedll ; get the low byte sta speed in mnport+acedlh ; and the high byte sta speed+1 ; Now set up the port for Kermit mvi a,ace8bw ; 8 data bits, 1 stop bit, no parity out mnport+acelcr in mnport+acemcr ori acedtr ; raise DTR (just in case) out mnport+acemcr call mdmonl ; and put the ACE back on line ret ; Take the ACE off line before modifying its state mdmofl: in mnport+aceier ; save the ACE's interrupt state sta iersav xra a out mnport+aceier ; and disable ACE interrupts in mnport+acemcr ; now put the ACE in loopback mode ori aceloo out mnport+acemcr ret ; Put the ACE back on line mdmonl: in mnport ; flush left-over garbage in the receive buffer mvi a,7 ; wait about 2 300-baud character times call delay in mnport ; and flush more garbage in mnport+acemcr ; take the ACE out of loopback mode ani 0FFH-aceloo out mnport+acemcr lda iersav out mnport+aceier ; and restore the ACE's interrupt state ret iersav: ds 1 ENDIF;heath ret ; return from system-dependent routine bdosvr: ds 1 ; space to save the BDOS version number IF iobyt ; This one is hopefully the last "improvement" in view of GENERIC ;Kermit. It uses for Character-I/O the BIOS-routines ( instead of the ;"normal" BDOS routines. What does it give us (hopefully) : More speed, ;higher chance of success ( I/O byte implemented in BIOS [if at all]), ;but no "extra" device handling - that's done by BDOS. ; ; How do we "get" the call-adresses? Location 0 has a JMP Warm-Boot ;in CP/M which points into the second location of the BIOS JMP-Vector. The ;next three locations of the JMP-Vector point to the CONSTAT,CONIN,CONOUT ;BIOS-routines. CONOUT wants the character in C. ; ;- Bernie Eiben iniadr: lhld 1 ;get BIOS Warmstart-address lxi d,3 ;next adress is CONSTAT in BIOS dad d shld bconst+1 ;stuff it into the call-instruction lxi d,3 ;next adress is CONIN in BIOS dad d shld bconin+1 ; lxi d,3 ;next adress is CONOUT in BIOS dad d shld bcnout+1 lxi d,3 ;next address is LIST in BIOS dad d shld blsout+1 ret ;And return bconst: jmp $-$ ;Call BIOS directly (filled in by iniadr) bconin: jmp $-$ ;Call BIOS directly (filled in by iniadr) bcnout: jmp $-$ ;Call BIOS directly (filled in by iniadr) blsout: jmp $-$ ; .... ENDIF;iobyt IF mikko ;currently for MIKROMIKKO only ; copy command block into memory-mapped SIO. movmik: di ;disable interrupts movmk1: ldax d ;Get a register value mov m,a ;Output it inx d ;Next value dcr c ;Decrement counter jnz movmk1 ;Repeat until done ei ret ENDIF;mikko IF osbrn1 osmove: osflag equ 0EF08H ;Osborne 1 Bank-2 flag ; ; return modem status in A ; OSLDST EQU ostop-osmove+$ DI OUT 0 LDA osprts ;Read the status port OUT 1 EI ret ; ; set modem status from A ; OSSTST equ ostop-osmove+$ DI OUT 0 STA osprts ;Write the control port jmp osstex ; ; read character from modem into A ; OSLDDA equ ostop-osmove+$ DI OUT 0 LDA osport OUT 1 EI ret ; ; output character in A to modem ; OSSTDA equ ostop-osmove+$ DI OUT 0 STA osport osstex equ ostop-osmove+$ OUT 1 mvi a,1 sta osflag EI ret osmct equ $-osmove ENDIF;osbrn1 IF bbI OR bbII OR lobo ; List of commands to set up SIO channel A for asynchronous operation. siotbl: DB 18H ; Channel reset DB 18H ; another, in case register 0 wasn't selected DB 04H ; Select register 4 DB 44H ; 1 stop bit, clock*16 DB 01H ; Select register 1 DB 00H ; No interrupts enabled DB 03H ; Select register 3 DB 0C1H ; Rx enable, 8 bit Rx character DB 05H ; Select register 5 DB 0EAH ; Tx enable, 8 bit Tx character, ; raise DTR and RTS siolen equ $-siotbl ; length of command list ENDIF;bbI or bbII OR lobo IF mikko ; command list to set SIO chip back to normal state miotbl: db 3 ;reg. 3 db sioo3 db 5 ;reg. 5 db sioo5 db 4 ;reg. 4 db sioo4 db 0 ;reselect reg. 0 miolen equ $-miotbl ;MikroMikko SIO table length (original values) ; command list to set up SIO chip for operation with Kermit mintbl: db 3 ;reg. 3 db sion3 db 5 ;reg. 5 db sion5 db 4 ;reg. 4 db sion4 db 0 ;reselect reg. 0 minlen equ $-mintbl ;MikroMikko SIO table length (KERMIT values) ENDIF;mikko IF bbc ;[22] modstr: db 16h,03h,'$' ; String to put screen into MODE 3 ENDIF IF px8 ; [29] rsget: mvi b, 50h jmp rsiox rsinst: mvi b, 30h jmp rsiox rsput: mvi b, 60h jmp rsiox rsoutst:mvi b, 40h jmp rsiox rserst: mvi b, 90h jmp rsiox rsopen: lxi h, px8blk ; copy px8blk to px8prm lxi d, px8prm lxi b, 9 call mover mvi b, 10h ; open code jmp rsiox rsclose:mvi b, 20h ; close code rsiox: lxi h, px8prm lxi d, 51h ; offset into BIOS jump table push h lhld 1 ; start of BIOS dad d xthl ; entry point on stack, px8prm addr in hl ret ; jump indirect px8prm: dw 0, 0 db 0, 0, 0, 0, 0 ; the param area is overwritten in rsopen px8blk: dw ovlend+8192 ; buffer address dw 0 ; buffer size - overwritten db 0 ; baud rate - overwritten db 3 ; 8 bits/char db 0 ; no parity, it is done internally db 1 ; 1 stop bit db 0cfh ; special bits - activate xon/xoff ; The documentation suggests that the xon/xoff bit is bit 4, i.e the pattern ; should be 0efh, but the top bit is omitted from the diagram. I will try ; clearing both bit 4 and bit 5. ENDIF ; px8 [29] ; ; system-dependent termination processing ; If we've changed anything, this is our last chance to put it back. sysexit: IF mikko lxi d,miotbl ;Load the adress of original reg values mvi c,miolen ;Length of table lxi h,sioac ;Send data to ch A SIO registers call movmik mvi a,07FH ;Set ch A mask to use just 7 bits sta chmask ENDIF;mikko IF cpt85xx mvi a,80h ; Reset (force idle) the 8251 UART via bit 7 out baudrt ; of the baud rate generater port mvi a,00h ; and turn off the baud rate generater out baudrt ENDIF;cpt85xx IF bbc ;[22] mvi a,0 ; Turn off terminal mode call term ENDIF;[22] bbc IF px8 ;[29] call rsclose ENDIF ;px8 [29] ret ; ; system-dependent processing for start of CONNECT command ; syscon: IF apmmdm call ckdial ;See if dialing is required. jmp kermit ;Go to command loop if aborted. ENDIF;apmmdm IF robin OR trs80 OR cpt85xx ;For Robin/TRS80/CPT-85xx, add some more info lxi d,conmsg ; about obscure key combinations call prtstr ENDIF;robin OR trs80 OR cpt85xx IF osbrn1 ;*** This is Software dependent *** lhld 1 ;Modify back-arrow code to DELETE mvi l,0 ;Get BIOS-start address lxi d,85H ;Adress for key-code = XX85H dad d mov e,m ;Get it in DE inx h mov d,m xchg ;Memory pointer to HL mvi m,del ;modify the code ENDIF;osbrn1 ret conmsg: ; Messages printed when entering transparent (CONNECT) mode: IF robin ; for Robin, control-S key is hidden db ' (Type Left Arrow to send CTRL-S)',cr,lf,'$' ENDIF;robin IF trs80 ; for TRS-80, the preferred escape key is hidden db ' (Control-_ is the Down-Arrow key on the TRS-80 keyboard)' db cr,lf,'$' ENDIF;trs80 IF cpt85xx ; for CPT-85xx, some graphics map "funny" to keyboard in CP/M db ' (Use CODE + SHIFT + 1/2 key to generate a Control-\)' db cr,lf,'$' ENDIF;cpt85xx IF apmmdm ;This code was mostly taken from ; APMODEM.ASM V2.1 ; Based on MODEM.ASM by Ward Christensen ; Modified for the Apple ][ by Gordon Banks 1-Jan-81 ; Micromodem ][ dialer option by Dav Holle 2-Feb-81 ; Code modified for KERMIT by Scott Robinson 14-Oct-82 ; ;Come here to see if we need to dial a number. ; ckdial: lda mnport ;access the data port lda mnprts ;check status ani 4 ;do we already have carrier? jz rskp ;Yes, just continue xra a ;Hangup Phone for starters sta mnmodm lxi b,1000 ;Delay for a second call delay mvi a,8FH ;orgmod+ap300+apoffh sta holdd ;storing mode for after dialing mvi A,8DH ;Go Offhook to start dialing sequence sta mnmodm mvi a,apinc1 ;Init ACIA sta mnport mvi a,apinc2 ;Set ACIA bits per character sta mnport lxi b,2500 ;wait 2.5 seconds for dial tone call delay lxi d,dialms ;Ask the user for the number call prtstr ; gtdial: mvi c,conin ;Get a character call bdos push psw ;save it cpi 30H ;is it big enough to dial? jc dialed ;no cpi 3AH ;is it too big to dial? jnc dialed ;yes ani 0FH ;ok, it's a digit, get its value jnz dialnz ;dial nonzero digits as-is mvi A,10 ;dial zero as ten ; dialnz: mov e,a ;count pulses in E-reg dopuls: mvi a,0DH ;put it on-hook sta mnmodm lxi b,61 ;61-millisec pulse call delay mvi a,8DH ;take it off-hook again... sta mnmodm lxi b,39 ;39-millisec delay between pulses call delay dcr e ;any more pulses to do? jnz dopuls ;yep, do 'em lxi b,600 ;delay 600 msecs between digits call delay ; dialed: pop psw ;get back the char cpi cr ;do we have a CR (done dialing)? jnz gtdial ;no, keep on dialin' lxi d,dialm2 call prtstr tictoc: mvi c,dconio ;Direct console input. mvi e,0FFH call bdos ora a ;Have a charcter? jnz nodial ;If so we abort lda mnport ;access the data port lda mnprts ;get modem status ani 4 ;carrier? jnz tictoc ;No ; lda holdd ;get the old modem control byte sta mnmodm ;turn our carrier on lxi d,dialm3 call prtstr jmp rskp nodial: xra a ;Hangup the modem. sta mnmodm ret ;Return to abort the command. ; holdd: db 0 ;Modem setup code dialms: DB 'Number to Dial: $' dialm2: DB CR,LF,'Awaiting Carrier....(any key aborts)$' dialm3: DB cr,lf,'Connected.',CR,LF,'$' ; ;DELAY wait for the number of millisecs in B,C ; delay:, push b ;save B,C push d ;save D,E inr b ;bump B for later DCR ; delay1: mvi e,126 ;delay count for 1 millisec (Apple Z80 ;clock=2.041MHz) ; delay2: dcr e ;count jnz delay2 ;down ; dcr c ;more millisecs? jnz delay1 ;yes dcr b ;no - more in hi byte? jnz delay1 ;yes pop d ;no, restore D,E pop b ; restore B,C ret ENDIF;apmmdm ; ; syscls - system-dependent close routine ; called when exiting transparent session. ; syscls: IF osbrn1 lhld 1 ;Modify back-arrow code to BACKSPACE mvi l,0 ;Get BIOS address lxi d,85H ;Address for key-code =XX85H dad d mov e,m ;Get it in DE inx h mov d,m xchg ;Address to HL mvi m,bs ;Modify code ENDIF;osbrn1 ret ; ; sysinh - help for system-dependent special functions. ; called in response to ?, after listing all the ; system-independent escape sequences. ; sysinh: IF apmmdm OR robin OR dmII OR bbII OR bbI OR cpt85xx OR heath OR lobo OR torch OR brain ;[16] [18] lxi d,inhlps ; we got options... call prtstr ; print them. ENDIF;apmmdm OR robin OR dmII OR bbII OR bbI OR cpt85xx OR heath OR lobo OR torch OR brain [16] [18] IF advant OR apcps OR bbc OR rm380z OR comart OR horizon ;[22] [25] [29] some more lxi d,inhlps ; we got options... call prtstr ; print them. ENDIF;[22] advant OR apcps OR bbc OR rm380z OR comart OR horizon [29] IF px8 OR pci2651 OR access OR mmate OR disc ;[28] [29] and more... lxi d,inhlps ; we got options... call prtstr ; print them. ENDIF ;px8 OR pci2651 OR access OR mmate OR disc [28] [29] 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 robin OR dmII OR bbII OR bbI OR cpt85xx OR heath OR lobo db cr,lf,'B Transmit a BREAK' ENDIF;robin OR dmII OR bbII OR bbI OR cpt85xx OR heath OR lobo IF advant OR apcps OR bbc OR rm380z OR comart OR horizon ; [22] [25] ... some more db cr,lf,'B Transmit a BREAK' ENDIF;[22] advant OR apcps OR bbc OR rm380z OR comart OR horizon IF pci2651 OR brain OR torch OR px8 OR access OR mmate ;[28] [29] Breaks also for... db cr,lf,'B Transmit a BREAK' ENDIF ;pci2651 OR brain OR torch OR px8 OR access OR mmate [28] [29] IF disc ;[29] db cr,lf,'B Transmit a 300ms BREAK' db cr,lf,'L Transmit a 5 second BREAK' ENDIF;disc [29] IF apmmdm OR heath OR lobo db cr,lf,'D Drop the line' ENDIF;apmmdm OR heath OR lobo 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... IF apmmdm cpi 'D' ;Disconnect Modem? jnz intc00 ;No. xra a ;Yes, hangup the modem sta mnmodm ret ; command has been executed intc00: ENDIF;apmmdm IF heath cpi 'D' ; drop line? jnz intc00 ; no: try next function character mdmdrp: in mnport+acemcr ; (we also get here from sysbye) ani 0FFH-acedtr out mnport+acemcr ; yes: drop DTR mvi a,50 ; for half a second call delay in mnport+acemcr ori acedtr out mnport+acemcr ; and then restore it ret intc00: ENDIF;heath ; [19] have added superbrain and torch to the list IF robin OR dmII OR bbI OR bbII OR cpt85xx OR heath OR lobo OR brain cpi 'B' ; send break? jz sendbr ; yes, go do it. return nonskip when through. ENDIF;robin OR dmII OR bbI OR bbII OR cpt85xx OR heath OR lobo OR brain IF advant OR apcps OR bbc OR rm380z OR comart OR horizon ; [22] [25] ... some more cpi 'B' ; send break? jz sendbr ; yes, go do it. return nonskip when through. ENDIF;[22] advant OR apcps OR bbc OR rm380z OR comart OR horizon IF pci2651 OR torch OR px8 OR access OR mmate ;[28] [29] and anothers cpi 'B' ; send break? jz sendbr ; yes, go do it. return nonskip when through. ENDIF ;pci2651 OR torch OR px8 OR access OR mmate [28] [29] IF lobo ;[hh] cpi 'D' ;[hh] disconnect? jz discon ;[hh] yes, go do it. nonskip return when done. ENDIF ;lobo IF disc ;[29] cpi 'B' ;Send short break? jz sendbr cpi 'L' ;Send long break? jz sendlbr ENDIF;disc [29] jmp rskp ; take skip return - command not recognized. IF robin ;Definitions & code to send a BREAK (ungenerically, no other way). comctl equ 59h ;VT180 communications port crtctl equ 41h ;VT180 crt port ;VT180 serial port command bits txe equ 1 ;transmit enable dtr equ 2 ;dtr on rxe equ 4 ;rx enable sndbrk equ 8 rerr equ 10h ;reset error rts equ 20h ;RTS on reset equ 40h ;port reset ;Send a break to the communications port. ; sendbr: lxi h,38500 ;250 ms(?) lda prtadr ;Get address of selected port mov c,a ;Into C mvi a,sndbrk+dtr ; OUT C,A ;Want to send to port addressed by C db 0EDH,079H ;Op code for above instruction sndbr1: dcx h ;timing loop... mov a,l ora h jnz sndbr1 ;...until over lda prtadr ;Get the address for the port mov c,a ;Into C mvi a,txe+dtr+rxe+rerr+rts ;enable tr/rc, dtr, reset error ; out c,a ;Z-80 only instruction db 0EDH,079H ;Op code for above instruction out contst ;reset ports ret ENDIF;robin IF dmII ;[jd] this added to send break on DECmate ; DECmate command codes for 6120 I/O processor oboff equ 3fh ; offset of outbyt routine for 6120 prtctl equ 02h ; port control brdat equ 06h ; data to tell 6120 to send a break brdur equ 30 ; duration, 30 = 300 ms. sendbr: lxi b,(brdat * 100h) + prtctl ; c/prtctl, b/brdat call outbyt lxi b,brdur*100h ; b/duration, c/0 ; fall through into outbyt outbyt: lhld 1 ; get warm boot address lxi d,oboff ; offset of outbyt routine dad d ; compute address pchl ; branch there (a callret) ENDIF;dmII IF bbI OR bbII OR access OR mmate ;[cjc] send break on Kaypro and bbII [29] ; Officially, a "break" is 300 milliseconds of "space" (idle line is ; "mark"). (or maybe 200 milliseconds; I forget.) The timing isn't ; usually that critical, but we'll make an attempt, at least. Sending ; too long a break can cause some modems to hang up. sendbr: ; First, make sure the transmitter is really empty. (The SIO sets ; "transmitter buffer empty" when it can accept another character; ; the previous character is still being shifted onto the line. ; Another status bit, "all done", is set to indicate that the ; transmitter is really idle. sndbr1: mvi a,1 ; select Read Register 1 out mnprts in mnprts ; read the contents ani 1 ; test "all done" flag jz sndbr1 ; loop until it's nonzero. ; ; Next, set the "send break" bit to start the transmitter spacing. mvi a,5 ; select Write Register 5 out mnprts mvi a,0FAH ; Tx enable, 8 bit Tx character, Send Break, out mnprts ; DTR and RTS on. ; ; Now, delay for 30 hundredths of a second mvi a,30 ; delay count call delay ; ; Time's up. Put transmitter back in normal state (data byte is the ; same as the one in siotbl: for Write Register 5) and return. mvi a,5 ; select Write Register 5 out mnprts mvi a,0EAH ; Tx enable, 8 bit Tx character, out mnprts ; DTR and RTS on. ret ; done. ENDIF;bbI OR bbII OR access OR mmate [29] IF lobo ;[hh] This routine sends a break tone or disconnects a modem ; (those that respond to it) by setting the DTR line low ; for 300 ms. ; sendbr: mvi a,05H ;[hh] write register 5 call outctl ;[hh] send it to control port mvi a,0FAH ;[hh] value to send break tone jmp sndbr1 ;[hh] ; discon: mvi a,05H ;[hh] write register 5 call outctl ;[hh] send it to the control port mvi a,06AH ;[hh] DTR off and break tone on sndbr1: call outctl ;[hh] send to control port mvi a,30 ;[hh] delay count for 300 ms. call delay ;[hh] wait a while... mvi a,05H ;[hh] write register 5 call outctl ;[hh] get it's attention mvi a,0EAH ;[hh] normal 8 bits, DTR on, RTS on, etc. call outctl ;[hh] restore SIO ret ; outctl: sta mnprts ;[hh] ret ENDIF ;lobo IF cpt85xx OR advant OR rm380z OR brain OR comart OR horizon ;[lmj] [22] [25] 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;cpt85xx OR advant OR rm380z OR brain OR comart OR horizon IF px8 ; [29] sendbr: mvi a, 3fh ; set break bit out mnprts mvi a, 25 call delay ; wait 250 msec mvi a, 37h ; clear break bit out mnprts ret ENDIF ; px8 [29] IF bbc ;[22] sendbr: ; ; Ensure that the transmitter has finished sending buffered chars sndbr1: mvi a,96h ; get ACIA status mvi l,8 call osbyte ; *FX150,8 mov a,h ani 2 ; everything sent? jz sndbr1 ; no, wait a bit more ; ; Disable centisecond clock (system VIA) which interferes with break lxi h,0FE4Eh ; system VIA interrupt enable register mvi a,40H ; disable timer 1 call wrtiom ; write to I/O processor memory ; ; Begin sending a break by setting bit in ACIA control register mvi a,9Ch lxi h,9F60h ; Set Rxint, Txint, Break, RTS call osbyte ; *FX 156,96,159 ; ; Wait for 250 milliseconds (using hundredths second delay routine) mvi a,25 call delay ; ; Resume normal operation by returning old control byte mvi a,9Ch mvi h,0 ;Set TxEna, DTR, RxEna, ErrRst, RTS call osbyte ; *FX 156,oldvalue,0 ; ; Enable centisecond clock (system VIA) lxi h,0FE4Eh ; system VIA interrupt enable register mvi a,0C0H ; enable timer 1 call wrtiom ; write to I/O processor memory ; ret ;done ; ; Routine to write byte in A to I/O processor memory address ; given by HL wrtiom: shld parblk ; store address to parameter block sta parblk+4 ; store data lxi h,parblk ; load hl with address of param block mvi a,6 ; write I/O processor memory call osword ; go do it ret ; parblk: DS 5 ; reserve space for parameter block ENDIF;bbc [22] IF apcps ;[22] sendbr: ; ; Ensure that the transmitter has finished sending buffered chars sndbr1: lda mnprts ; get UART status ani TxEmpty ; everything sent? jz sndbr1 ; no, wait a bit more ; ; Unmask command register mvi a,80h sta mnprtc ; ; Begin sending a break by setting bit in UART command register mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS sta 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 sta mnprts ; ; Remask command register mvi a,0 sta mnprtc ; ret ;done ENDIF;[22] apcps IF torch ; [18] [27] [30] ; Send a break. The Torch computer has to dump some 6502 code to the "Base ; processor " (A BBC computer), then do a call subroutine ACROSS THE TUBE ; (ie then run that routine in the processor itself) Use the sound buffer ; area in the Beeb, at address 0840h. How does one return from the routine ; in the base processor??? ; ; [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 push d push b mvi a,0e8h lxi d,0 ; turn interrupts off call osbyt1 push psw ; mvi a,9ch ; OSBYTE call 9c is read/write 6850 cntl prt lxi d,00ffh ; d= 6502 X reg, e= 6502 Y reg call osbyt1 ; returned new val. = (old value AND Y)XOR X lda xx ; get returned value push psw ; save it for return ; mvi a,9ch ; now send break lxi d,7700h ;[30] call osbyt1 ; mvi a,30 call delay ; do a delay ; ; now clear rx register ; mvi a,96h ; do a read sheila address 08h mvi d,08 mvi e,0 call osbyt1 ; read sheila 08h = 6850 rx reg ; ; restore 6850 regs... ; pop psw ; restore previous cntl reg mov d,a mvi e,0 mvi a,9ch ; write previous value to 6850 call osbyt1 ; ; and Beebs interrupt mask ; pop psw ; get interrupt mask mov d,a mvi e,0 mvi a,0e8h call osbyt1 ; restore interrupts mask ; pop b pop d pop h ret ; its raining again, so exit ENDIF ; torch [18] 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 ENDIF ;pci2651 [28] IF heath ; ; Send BREAK on H89 ; sendbr: in mnport+acelcr ori acesb out mnport+acelcr ; set ACE break condition mvi a,30 call delay ; wait 300 milliseconds in mnport+acelcr ani 0FFH-acesb out mnport+acelcr ; and clear ACE break condition ret ENDIF;heath IF disc ;[29] ; This is almost an exact copy of the bbI sendbr routine. ; Modifications to include a long break have been made. ; ; Officially, a "break" is 300 milliseconds of "space" (idle line is ; "mark"). (or maybe 200 milliseconds; I forget.) The timing isn't ; usually that critical, but we'll make an attempt, at least. Sending ; too long a break can cause some modems to hang up. sendlbr: push d ;save d, this may not be necessary, but safe mvi d,17 ;do short break 17 times (approx. 5 sec.) jmp sndbr1 sendbr: push d mvi d,1 ;On short break, do only once ; First, make sure the transmitter is really empty. (The SIO sets ; "transmitter buffer empty" when it can accept another character; ; the previous character is still being shifted onto the line. ; Another status bit, "all done", is set to indicate that the ; transmitter is really idle. sndbr1: mvi a,1 ; select Read Register 1 out mnprts in mnprts ; read the contents ani 1 ; test "all done" flag jz sndbr1 ; loop until it's nonzero. ; ; Next, set the "send break" bit to start the transmitter spacing. mvi a,5 ; select Write Register 5 out mnprts mvi a,0FAH ; Tx enable, 8 bit Tx character, Send Break, out mnprts ; DTR and RTS on. ; ; Now, delay for 30*d hundredths of a second sendbr2: mvi a,30 ; delay count call delay ; The following has been added to allow doing .03 delay d times dcr d ; decrement # of times to do loop jnz sendbr2 ; if not done, do again pop d ; reload d ; ; Time's up. Put transmitter back in normal state (data byte is the ; same as the one in siotbl: for Write Register 5) and return. mvi a,5 ; select Write Register 5 out mnprts mvi a,0EAH ; Tx enable, 8 bit Tx character, out mnprts ; DTR and RTS on. ret ; done. ENDIF ;disc [29] IF bbI OR bbII OR cpt85xx OR heath OR lobo OR brain OR torch OR mmate OR disc;[16] [18] ; ;[cjc] Delay routine. Called with time (hundredths of seconds) in A. ; The inner loop delays 1001 T-states, assuming no wait states are ; inserted; this is repeated CPUSPD times, for a total delay of just ; over 0.01 second. (CPUSPD should be set to the system clock rate, ; in units of 100KHz: for an unmodified Kaypro II, that's 25 for ; 2.5 MHz. Some enterprising soul could determine whether or not the ; Kaypro actually inserts a wait state on instruction fetch (a common ; practice); if so, the magic number at delay2 needs to be decreased. ; (We also neglect to consider time spent at interrupt level). ; ; called by: sendbr ; destroys BC delay: mvi c,cpuspd ; Number of times to wait 1000 T-states to ; make .01 second delay delay2: mvi b,70 ; Number of times to execute inner loop to ; make 1000 T-state delay delay3: dcr b ; 4 T-states (* 70 * cpuspd) jnz delay3 ; 10 T-states (* 70 * cpuspd) dcr c ; 4 T-states (* cpuspd) jnz delay2 ; 10 T-states (* cpuspd) ; total delay: ((14 * 70) + 14) * cpuspd ; = 1001 * cpuspd dcr a ; 4 T-states jnz delay ; 10 T-states ret ; grand total: ((1001 * cpuspd) + 14) * a ENDIF;bbI OR bbII or cpt85xx OR heath OR lobo OR brain OR torch OR mmate OR disc [29] IF apcps OR bbc OR advant OR rm380z OR comart OR horizon OR pci2651 OR px8;[16] [18] [28] [29].... ; ;[cjc] Delay routine. Called with time (hundredths of seconds) in A. ; The inner loop delays 1001 T-states, assuming no wait states are ; inserted; this is repeated CPUSPD times, for a total delay of just ; over 0.01 second. (CPUSPD should be set to the system clock rate, ; in units of 100KHz: for an unmodified Kaypro II, that's 25 for ; 2.5 MHz. Some enterprising soul could determine whether or not the ; Kaypro actually inserts a wait state on instruction fetch (a common ; practice); if so, the magic number at delay2 needs to be decreased. ; (We also neglect to consider time spent at interrupt level). ; ; called by: sendbr ; destroys BC delay: mvi c,cpuspd ; Number of times to wait 1000 T-states to ; make .01 second delay delay2: mvi b,70 ; Number of times to execute inner loop to ; make 1000 T-state delay delay3: dcr b ; 4 T-states (* 70 * cpuspd) jnz delay3 ; 10 T-states (* 70 * cpuspd) dcr c ; 4 T-states (* cpuspd) jnz delay2 ; 10 T-states (* cpuspd) ; total delay: ((14 * 70) + 14) * cpuspd ; = 1001 * cpuspd dcr a ; 4 T-states jnz delay ; 10 T-states ret ; grand total: ((1001 * cpuspd) + 14) * a ENDIF;apcps OR bbc OR advent OR rm380 OR comart OR horizon OR pci2651 OR px8 [16] [18] [28] [29] ; IF access ;[29] .. ran out of room.. again ;[cjc] Delay routine. Called with time (hundredths of seconds) in A. ; The inner loop delays 1001 T-states, assuming no wait states are ; inserted; this is repeated CPUSPD times, for a total delay of just ; over 0.01 second. (CPUSPD should be set to the system clock rate, ; in units of 100KHz: for an unmodified Kaypro II, that's 25 for ; 2.5 MHz. Some enterprising soul could determine whether or not the ; Kaypro actually inserts a wait state on instruction fetch (a common ; practice); if so, the magic number at delay2 needs to be decreased. ; (We also neglect to consider time spent at interrupt level). ; ; called by: sendbr ; destroys BC delay: mvi c,cpuspd ; Number of times to wait 1000 T-states to ; make .01 second delay delay2: mvi b,70 ; Number of times to execute inner loop to ; make 1000 T-state delay delay3: dcr b ; 4 T-states (* 70 * cpuspd) jnz delay3 ; 10 T-states (* 70 * cpuspd) dcr c ; 4 T-states (* cpuspd) jnz delay2 ; 10 T-states (* cpuspd) ; total delay: ((14 * 70) + 14) * cpuspd ; = 1001 * cpuspd dcr a ; 4 T-states jnz delay ; 10 T-states ret ; grand total: ((1001 * cpuspd) + 14) * a ENDIF;access [29] ; Had to break the whopping CP4SYS.ASM file onto two.. Sorry folks ;IF lasm ; LINK CP4SY2 ;ENDIF ; lasm ; Asked to string the two files back together again. Those who ; want to use two files should remove the semicolons in the above IF...ENDIF ; Call the next file CP4SY2.ASM ; CP4SY2.ASM ; 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 is the second part of the CP4SYS.ASM file, as it got too big. ; ; This file contains the system-dependent code and data for KERMIT. ; It will be probably be broken into independent files to generate ; overlays for the various systems, one or more overlay possible ; from each file. For now, we will leave it in one piece. ; ; revision history: (Please keep as CP4SYS file: these two really should be ; one, but that would be too big.) ; ; edit 31 April 7th, 1986 OBSchou. Bugs in PX8 kermit fixed. ; ; edit 30 24th march, 1986 by OBSchou. Sorting out torch tx and break ; problems... AGAIN ; ; edit 29, March 7th, 1986 by OBSchou. Added in code for Epson PX8 ; code written by Tony Addyman from Salford University. This is ; really two edits into one, with a final edit of a dollar in the ; help messages. ; Also add in code from an Unknown kermiteer, who added code for a ; basic Northstar (basicns) (small changes) and also wrote the ; following headers to a list of "changes" to the CP4SYS file..... ; ;> ACCESS-MATRIX ;> Note - The following differences in CP4SYS.ASM apply to the ;> implementation for the Access-Matrix computer. ;> In CP4TYP.ASM, set access to TRUE, inout to TRUE, and crt to FALSE ;> Use port J5 of the Access ;> ;> PMC MICROMATE ;> The following applies to the implementation for Personal Micro ;> Computers PMC-101 MicroMate. In CP4TYP.ASM, set mmate to TRUE, ;> inout to TRUE, and crt to TRUE (Don't know what terminal might ;> be used.) ;> ;> U.S. Micro Sales s1008 (out of business) ;> Can use the same approach as for the basic NorthStar except set ;> crt to FALSE. (s1008) ;> ;> A. C. E. DISCOVERY ;> This implementation is for the Action Computer Enterprise, Inc. ;> "Discovery" multi user computer. It uses port B on an 83U ;> user board. ;> ;> In CP4TYP.asm set disc to TRUE, inout to TRUE, and crt to TRUE ;> ; ; edit 28, January 29 1986 by OBSchou ; added code to drive a 2651 USART for one of our odd ball ; machines. (Euromicro/Ithica Intersystems VIO (?) board) ; (pci2651) Also split the HUGE cp4sys.asm file into two smaller ; ones: this one is still CP4SYS.ASM, the next one is CP4SY2.ASM ; The break is just after the BREAK and DELAY routines.. roughly 1/2 ; way through the file. ; ; ; ; 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 IF mikko cpi 'O'-100O ;Control-O's lock keyboard rnz ; if not control-O, it's ok. xra a ; don't allow control-O out. ENDIF;mikko IF advant ;[22] cpi 'D'-100O ;Control-D's reset video rnz ; if not control-D, it's ok. xra a ; don't allow control-D out. ENDIF;[22] advant 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: IF apmmdm xra a ;Hangup our end, too. sta mnmodm ENDIF;apmmdm IF heath call mdmdrp ; Sleazy but effective ENDIF;heath IF lobo ;[hh] call discon ;[hh] force modem to hang up ENDIF;lobo 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 px8 ; [29] push d call rsclose ; baud rate can only be set on opening rs232 pop d mov a, e sta px8blk+4 ; set param block call rsopen ; to set rate ret ENDIF ; px8 [29] ; Set the speed for the Osborne I IF osbrn1 mvi a,osbin1 ;Reset the ACIA call osstst ;Write the control port osbs1: inr c ;Waiting loop jnz osbs1 mov a,e ; get the specified speed jmp osstst ;Write the control reg. ENDIF;osbrn1 ; Set the speed for bigboard II IF bbII di ; don't let anything between the data bytes mvi a,01000111b ; get the command byte (load time constant) out baudrt ; output it to CTC mov a,e ; Get the parsed value. out baudrt ; Tell the baud rate generator. ei ; end of critical section ret ENDIF;bbII ;[hh] set the speed for a lobo MAX-80 IF lobo mov a,e ;[hh] get the parsed value setbd: sta baudrt ;[hh] and send it to the baud rate port ret ;[hh] ENDIF;lobo ; Set the speed for bigboard I or the delphi or the CPT-85xx or Northstar ; or Cromemco (TU-ART) IF bbI OR delphi OR cpt85xx OR norths OR cmemco OR advant OR mmate ;[22] [29] mov a,e ; get the parsed value out baudrt ; Tell the baud rate generator. ret ENDIF;bbI OR delphi OR cpt85xx OR norths OR cmemco OR advant OR mmate [22] [29] ;[22] Set the speed for Acorn BBC IF bbc mov l,e mvi a,7 ;Set receive baud rate call osbyte ;*FX7,?e mov l,e mvi a,8 ;Set transmit baud rate call osbyte ;*FX8,?e ret ENDIF;[22] bbc ;[22] Set speed for RM 380Z IF rm380z mvi a,4 ;device type (SI/O4) in A rst 6 ; EMT db 29h ; SETLST ret ENDIF;[22] rm380z ; Set the speed for MicroMikko. DE is baud rate multiplier IF mikko di lxi h,txclk mov m,d ;LSB first (swapped in memory) mov m,e ;MSB last lxi h,rxclk mov m,d mov m,e mvi b,0 ;"modifier" for 1 stop bit mvi a,2 ;Test MSB of speed >2 (110 bps or less) cmp e jp miksp1 mvi b,00001000B ;"modifier" for 2 stop bits miksp1: mvi a,4 ;Select SIO Reg 4 lxi h,sioac mov m,a mvi a,sion4 ;Get values ora b ;Add modifier mov m,a ;Set value (stop bits) ei ret ENDIF;mikko ; Set the speed for Apple with 6551 ACIA IF ap6551 lda mnprtc ;jb read control port ani 0F0H ;jb zap low order nybble ora e ;jb put rate in low order nybble sta mnprtc ;jb send to control port ret ENDIF;ap6551 ; Set the speed for Apple with CPS Multifunction card IF apcps ;[22] mvi a,80h sta mnprtc lda mnprts ;read command register to reset 2651 mvi a,apmod1 ;first mode byte sta mnport mvi a,4 ;waste some time before sending second byte spdwt: dcr a ; 4 T-states jnz spdwt ; 10 T-states mov a,e ;second mode byte is speed byte sta mnport mvi a,apcmd ;command byte sta mnprts xra a sta mnprtc ret ENDIF;[22] apcps ; Set the speed for the Decision I IF mdI call selmdm ;Let's be absolutely sure, huh? mvi a,dlab+wls1+wls0+stb ;Set data latch access bit out lcr ;Out to Line Control Register lhld speed ;Load baudrate multiplier xchg mov a,d ;Get low order byte for baud rate out dlm ;Out to the MSB divisor port mov a,e ;...and the high order byte out dll ;Out to the LSB divisor port mvi a,wls1+wls0+stb ;Enable Divisor Access Latch out lcr ;Out to ACE Line Control Register xra a ;Clear A out ier ;Set no interrupts out lsr ;Clear status in msr ;Clear Modem Status Register in lsr ;Clear Line Status Register in rbr ;Clear Receiver Buffers in rbr ret ENDIF ;mdI [Toad Hall] IF heath ; ; Set speed for H89 ; call mdmofl ; keep the line safe from garbage in mnport+acelcr ori acedla out mnport+acelcr ; access the ACE's divisor latch mov a,e ; low byte of speed is in E out mnport+acedll ; set the low byte mov a,d ; high byte of speed is in D out mnport+acedlh ; set the high byte in mnport+acelcr ani 0FFH-acedla out mnport+acelcr ; de-access the ACE's divisor latch call mdmonl ; and put the ACE back on line ret ENDIF;heath If torch ; Set speed for Torch [14] push psw ; save for a rainy day push d ; it may be monsoon mvi a,rxrate ; set up for osbyte call to set rx rate call osbyt1 ; similar call to osbyte, which is near io stuff pop d ; it is raining mvi a,txrate ; set up for tx rate to be set call osbyt1 pop psw ; its pouring ret ; and now, all rates should be different rxrate equ 7h ; osbyte or fx call 7 is set rx rate txrate equ 8h ; osbyte or fx call 8 is set tx rate ENDIF ;torch [14] 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] IF access ;[29] mov a,e ;Get the parsed time constant ;The following code is derived from the Access initialization code sta savspd ;Save the time constant mvi a,14h ;Code for 'monitor' to set channel A baudrate call monitor lda savspd ;Get the time constant call monitor ; and send it to the CRT ret savspd: ds 1 monitor: ;Routine to do CRT functions out 90h ;Output the data to the CRT mvi a,1 ;Set DRDY true out 23h mon1: in 0a0h ;Wait for CACK* true rlc jc mon1 in 80h ;Read the input data latch push psw ;Save the input data xra a ;Set DRDY false out 23h mon2: in 0a0h ;Wait for CACK* false rlc jc mon2 pop psw sta 0ee02h ;Save the input data ret ENDIF;access [29] IF disc ;[29] ; Assuming that parsing of value from speed table puts low order ; byte of time constant in the e register and high byte in d. mvi a,12 ;Register 12 out mnprts mov a,e ;Low order byte of time constant out mnprts mvi a,13 ;Register 13 out mnprts mov a,d ;High order byte of time constant out mnprts mvi a,14 ;Register 14 out mnprts mvi a,3 ;Enable baud rate generator out mnprts mvi a,11 ;Register 11 out mnprts mvi a,52h ;no Xtal, tclk=rclk=/trxc out=br gen out mnprts ret ENDIF;disc [29] ; 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 bbI OR brain OR delphi OR lobo ;[hh] 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;bbI OR brain OR delphi OR lobo ;[hh] IF bbII spdtbl: db 8 ; 8 entries db 04h,'1200$', 20h,20h db 05h,'19200$', 02h,02h db 04h,'2400$', 10h,10h db 03h,'300$', 80h,80h db 05h,'38400$', 01h,01h db 04h,'4800$', 08h,08h db 03h,'600$', 40h,40h db 04h,'9600$', 04h,04h sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600 19200 38400$' ENDIF;bbII IF cpt85xx spdtbl: db 15 ; 15 entries db 03,'110$', 03h,03h db 04,'1200$', 09h,09h db 05,'134.5$', 04h,04h db 03,'150$', 05h,05h db 04,'1800$', 0Ah,0Ah db 04,'2400$', 0Bh,0Bh db 03,'300$', 06h,06h db 04,'3600$', 0Ch,0Ch db 04,'4800$', 0Dh,0Dh db 02,'50$', 01h,01h db 03,'600$', 07h,07h db 04,'7200$', 0Eh,0Eh db 02,'75$', 02h,02h db 03,'900$', 08h,08h db 04,'9600$', 0Fh,0Fh sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 900' db cr,lf,' 1200 1800 2400 3600 4800 7200 9600$' ENDIF;cpt85xx IF advant ;[22] spdtbl: db 6 ; 6 entries db 04,'1200$', 70h,70h db 04,'2400$', 78h,78h db 03,'300$', 40h,40h db 04,'4800$', 7Ch,7Ch db 03,'600$', 60h,60h db 04,'9600$', 7Eh,7Eh sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$' ENDIF;[22] advant IF bbc ;[22] spdtbl: db 8 ; 8 entries db 04,'1200$', 04h,04h db 03,'150$', 02h,02h db 05,'19200$', 08h,08h db 04,'2400$', 05h,05h db 03,'300$', 03h,03h db 04,'4800$', 06h,06h db 02,'75$', 01h,01h db 04,'9600$', 07h,07h sphtbl: db cr,lf,' 75 150 300 1200 2400 4800 9600 19200$' ENDIF;[22] bbc IF rm380z ;[22] spdtbl: db 7 ; 7 entries db 03,'110$', 00h,00h db 04,'1200$', 03h,03h db 04,'2400$', 04h,04h db 03,'300$', 01h,01h db 04,'4800$', 05h,05h db 03,'600$', 02h,02h db 04,'9600$', 06h,06h sphtbl: db cr,lf,' 110 300 600 1200 2400 4800 9600$' ENDIF;[22] rm380z IF px8 ; [29] spdtbl: db 9 ; 9 entries db 03,'110$', 02h,02h db 04,'1200$', 0ah,0ah db 03,'150$', 04h,04h db 05,'19200$', 0fh,0fh db 04,'2400$', 0ch,0ch db 03,'300$', 06h,06h db 04,'4800$', 0dh,0dh db 03,'600$', 08h,08h db 04,'9600$', 0eh,0eh sphtbl: db cr, lf db ' 100 150 300 600 1200 2400 4800 9600 19200$' ENDIF ; px8 [29] IF mikko spdtbl: db 9h ;9 entries db 03h,'110$' dw 0369h db 04h,'1200$' dw 0050h db 03h,'150$' dw 0280h db 04h,'2400$' dw 0028h db 03h,'300$' dw 0140h db 04h,'4800$' dw 0014h db 03h,'600$' dw 00A0H db 02h,'75$' dw 0500h db 04h,'9600$' dw 000ah sphtbl: db cr,lf,' 75 110 150 300 600 1200 2400 4800 9600$' ENDIF;mikko IF osbrn1 spdtbl: db 02h ;2 entries db 04h,'1200$', OSBI12,OSBI12 db 03h,'300$', OSBI03,OSBI03 sphtbl: db cr,lf,' 300',cr,lf,' 1200$' ENDIF;osbrn1 IF ap6551 ;jb spdtbl: db 0DH ;jb 13 entries db 03H,'110$', 03H,03H ;jb db 04H,'1200$', 08H,08H ;jb db 05H,'134.5$', 04H,04H ;jb db 03H,'150$', 05H,05H ;jb db 04H,'1800$', 09H,09H ;jb db 05H,'19200$', 0FH,0FH ;jb db 04H,'2400$', 0AH,0AH ;jb db 03H,'300$', 06H,06H ;jb db 04H,'3600$', 0BH,0BH ;jb db 04H,'4800$', 0CH,0CH ;jb db 03H,'600$', 07H,07H ;jb db 04H,'7200$', 0DH,0DH ;jb db 04H,'9600$', 0EH,0EH ;jb sphtbl: db cr,lf,' 110 134.5 150 300 600 1200 1800' db cr,lf,' 2400 3600 4800 7200 9600 19200$' ENDIF;ap6551 IF apcps ;[22] spdtbl: db 10H ; 16 entries db 03H,'110$', 32h,32h db 04H,'1200$', 37h,37h db 05H,'134.5$', 33h,33h db 03H,'150$', 34h,34h db 04H,'1800$', 38h,38h db 05H,'19200$', 3fh,3fh db 04H,'2000$', 39h,39h db 04H,'2400$', 3ah,3ah db 03H,'300$', 35h,35h db 04H,'3600$', 3bh,3bh db 04H,'4800$', 3ch,3ch db 02H,'50$', 30h,30h db 03H,'600$', 36h,36h db 04H,'7200$', 3dh,3dh db 02H,'75$', 31h,31h db 04H,'9600$', 3eh,3eh 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;[22] apcps IF mdI spdtbl: db 0dh ; 13 entries db 03h, '110$' dw 1047 db 04h, '1200$' dw 96 db 03h, '150$' dw 768 db 05h,'19200$' dw 6 db 04h, '2400$' dw 48 db 03h, '300$' dw 384 db 05h,'38400$' dw 3 db 03h, '450$' dw 288 db 04h, '4800$' dw 24 db 05h,'56000$' dw 2 db 03h, '600$' dw 192 db 02h, '75$' dw 1536 db 04h, '9600$' dw 12 sphtbl: db cr,lf,' 75 110 150 300 450 600 1200' db cr,lf,' 2400 4800 9600 19200 38400 56000$' ;(Lord knows what you'll be communicating with at 56000 baud, but the ;Multi-I/O board literature says it'll do it, so what the heck.... ;might as well throw it in here just to show off...sure hope the ;port don't melt...) ENDIF ;mdI [Toad Hall] IF heath ; ; Speed selection table for H89 (OK, so I got a little carried away...) ; spdtbl: db 19 ; 19 entries db 3,'110$' dw 1047 db 4,'1200$' dw 96 db 5,'134.5$' dw 857 db 4,'1800$' dw 64 db 5,'19200$' dw 6 db 3,'200$' dw 576 db 4,'2400$' dw 48 db 3,'300$' dw 384 db 4,'3600$' dw 32 db 5,'38400$' dw 3 db 3,'450$' dw 256 db 4,'4800$' dw 24 db 2,'50$' dw 2304 db 5,'56000$' dw 2 db 3,'600$' dw 192 db 4,'7200$' dw 16 db 2,'75$' dw 1536 db 3,'900$' dw 128 db 4,'9600$' dw 12 sphtbl: db cr,lf db ' 50 75 110 134.5 200 300 450 600 900 1200' db cr,lf,' 1800 2400 3600 4800 7200 9600 19200 38400 56000$' ENDIF;heath IF norths spdtbl: db 8 ; 8 entries db 3,'110$', 07H,07H db 4,'1200$', 04H,04H db 5,'19200$', 00H,00H db 4,'2400$', 03H,03H db 3,'300$', 06H,06H db 4,'4800$', 02H,02H db 3,'600$', 05H,05H db 4,'9600$', 01H,01H sphtbl: db cr,lf db ' 110 300 600 12000 2400 4800 9600 19200$' ENDIF;norths IF cmemco ;[25] spdtbl: db 7 ; 7 entries db 3,'110$', 01H,01H db 4,'1200$', 88H,88H db 3,'150$', 82H,82H db 4,'2400$', 90H,90H db 3,'300$', 84H,84H db 4,'4800$', 0A0H,0A0H db 4,'9600$', 0C0H,0C0H sphtbl: db cr,lf db ' 110 150 300 1200 2400 4800 9600$' ENDIF;cmemco IF cifer ;[17] spdtbl equ 0 ; for the time being.. lets get it working sphtbl equ 0 ; ditto ENDIF;cifer 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] IF pci2651 spdtbl: db 16 ; sixteen entries for PCI db 3,'110$', 2,2 db 4,'1200$', 7,7 db 3,'134$', 3,3 db 3,'150$', 4,4 db 4,'1800$', 8,8 db 5,'19200$', 15,15 db 4,'2000$', 9,9 db 4,'2400$', 10,10 db 3,'300$', 5,5 db 4,'3600$', 11,11 db 4,'4800$', 12,12 db 2,'50$', 0,0 db 3,'600$', 6,6 db 4,'7200$', 13,13 db 2,'75$', 1,1 db 4,'9600$', 14,14 sphtbl: db ' 50 75 110 134 150 300 600 1200 ' db cr,lf,'1800 2000 2400 3600 4800 7200 9600 19200$' ENDIF ;pci2651 [28] IF access ;Similar to bbI with different values [29] spdtbl: db 6h ;6 entries db 04h,'1200$', 28h,28h db 04h,'2400$', 14h,14h db 03h,'300$', 0a0h,0a0h db 04h,'4800$', 0ah,0ah db 03h,'600$', 50h,50h db 04h,'9600$', 5,5 sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$' ENDIF;access [29] IF mmate ;[29] spdtbl: db 10h ;16 entries db 03h,'110$', 0e2h,0e2h db 04h,'1200$', 0e7h,0e7h db 05h,'134.5$', 0e3h,0e3h db 03h,'150$', 0e4h,0e4h db 04h,'1800$', 0e8h,0e8h db 05h,'19200$', 0efh,0efh db 04h,'2000$', 0e9h,0e9h db 04h,'2400$', 0eah,0eah db 03h,'300$', 0e5h,0e5h db 04h,'3600$', 0ebh,0ebh db 04h,'4800$', 0ech,0ech db 02h,'50$', 0e0h,0e0h db 03h,'600$', 0e6h,0e6h db 04h,'7200$', 0edh,0edh db 02h,'75$', 0e1h,0e1h db 04h,'9600$', 0eeh,0eeh 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;mmate [29] IF disc ;[29] ; Similar to mikko table but with different time constant values spdtbl: db 9h ;9 entries db 03h,'110$' dw 1134 db 04h,'1200$' dw 102h db 03h,'150$' dw 831 db 04h,'2400$' dw 50 db 03h,'300$' dw 415 db 04h,'4800$' dw 24 db 03h,'600$' dw 206 db 02h,'75$' dw 1665 db 04h,'9600$' dw 11 sphtbl: db cr,lf,' 75 110 150 300 600 1200 2400 4800 9600$' ENDIF;disc [29] ; 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] IF robin OR gener OR dmII OR vector OR z100 OR trs80 OR telcon spdtbl equ 0 ; SET BAUD not supported. sphtbl equ 0 ENDIF;robin OR gener OR dmII OR vector OR z100 OR trs80 OR telcon ; IF mmdI OR osi OR cpm3 OR apmmdm OR comart OR horizon OR basicns OR S1008 ; [29] spdtbl EQU 0 ;[hh] SET BAUD not supported. sphtbl EQU 0 ;[hh] ran out of room above... ENDIF;mmdI OR osi OR cpm3 OR apmmdm OR comart OR horizon OR basicns OR S1008 [29] ; ; This is the system-dependent SET PORT command. ; HL contains the argument from the command table. sysprt: IF lobo ;[hh] mov a,e ;[hh] get the data port value and store at sta outmd3+1 ;[hh] the two places we use... sta inpmd2+1 ;[hh] MNPORT in the overlay sta port ;[hh] inform program of the change in ports inr a ;[hh] status port = data port + 1 in the Lobo sta outmd1+1 ;[hh] store it at the three places... sta inpmd1+1 ;[hh] we use MNPRTS... sta outctl+1 ;[hh] in the overlay mov a,d ;[hh] now get the baud rate port value sta getbd+1 ;[hh] store it in the two places we use... sta setbd+1 ;[hh] BAUDRT in the overlay sta port+1 ;[hh] don't need to, but keeps it consistant getbd: lda baudrt ;[hh] get baud rate value from port sta speed ;[hh] tell STAT. baud rate for each port ;[hh] is independant of the other ENDIF ;lobo 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 IF iobyt AND robin inx h ;Point at next entry mov a,m ;Get the hardware address for the port sta prtadr ;Store it ENDIF;iobyt AND robin ret ; ; Port tables for Lobo MAX-80 IF lobo ;[hh] ; help text prhtbl: db cr,lf,'RS-232 port A or B$' ; ; command table prttbl: db 02H ;[hh] two entries db 01H,'A$',0E4H,0D0H db 01H,'B$',0E6H,0D4H ENDIF ;lobo ; ; 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 ; ; Port tables for DECmate II or MicroMikko or Acorn BBC ; IF dmII OR mikko OR bbc ;[22] ; help text prhtbl: db cr,lf,'COMMUNICATIONS port$' ; command table prttbl: db 01H ;Only one port known at this point db 0EH,'COMMUNICATIONS$' dw comptb ;address of info ; port entry table ; table entries are: ; db iobyte-value, BDOS output function, reserved comptb: db batio,punout,0 ENDIF;[22] dmII OR mikko OR bbc ; ; Port tables for Robin ; IF robin ; help text prhtbl: db cr,lf,'COMMUNICATIONS port' db cr,lf,'GENERAL purpose port' db cr,lf,'PRINTER port$' ; command table prttbl: db 03H ;Three entries db 0EH,'COMMUNICATIONS$' dw comptb db 07H,'GENERAL$' dw gppptb db 07H,'PRINTER$' dw prnptb ; port entry table ; table entries are: ; db iobyte-value, BDOS output function, hardware port address ; (control/status) ; ;At present, the hardware port address is only used for sending a break. comptb: db batio,punout,comtst gppptb: db gppio,conout,gentst prnptb: db lptio,conout,prntst prtadr: db comtst ;space for current hardware port address ENDIF;robin IF cifer ; no ports yet... prttbl db 0 prhtbl db 0 ; ENDIF; cifer 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 OR lobo) ;[hh] prttbl equ 0 ; SET PORT is not supported prhtbl equ 0 ENDIF;NOT iobyt OR lobo ; ; Set up screen display for file transfer ; called with kermit version in DE ; sysscr: push d ; save version for a bit lxi d,outlin ; clear screen, position cursor call prtstr ; do it pop d ; get Kermit's version IF NOT (osi OR crt) ; got cursor control? call prtstr ; print it mvi e,'[' ; open bracket call outcon ; print it (close bracket is in outln2) lxi d,sysver ; get name and version of system module call prtstr lxi d,outln2 ; yes, print field names call prtstr lda dbgflg ; is debugging enabled? ora a rz ; finished if no debugging lxi d,outln3 ; set up debugging fields call prtstr ENDIF;NOT (osi OR crt) ret ; Calculate free space for current drive ; returns value in HL sysspc: lda bdosvr ;cpm3's alloc vect may be in another bank cpi 30H ;cpm3 or later? jm cp2spc ;no: use cp/m 2 algorithm lda fcb ;If no drive, get ora a ; logged in drive jz dir180 dcr a ;FCB drive A=1 normalize to be A=0 jmp dir18a dir180: mvi c,rddrv call bdos dir18a: mov e,a ;drive in e mvi c,getfs ;get free space BDOS funct call bdos ;returns free recs (3 bytes in buff..buff+2) mvi b,3 ;conv recs to K by 3 bit shift dir18b: xra a ;clear carry mvi c,3 ;for 3 bytes lxi h,buff+3 ;point to addr + 1 dir18c: dcx h ;point to less sig. byte mov a,m ;get byte rar ;carry -> A -> carry mov m,a ;put back byte dcr c ;for all bytes (carry not mod) jnz dir18c dcr b ;shift 1 bit 3 times jnz dir18b mov e,m ;get least sig byte inx h mov d,m ;get most sig byte xchg ;get K free in HL ret ; the rest are CP/M 2.2 systems, so use the alloc vector cp2spc: mvi c,getalv ;Address of CP/M Allocation Vector call bdos xchg ;Get its length lhld bmax inx h lxi b,0 ;Initialize Block count to zero dir19: push d ;Save allocation address ldax d mvi e,8 ;set to process 8 blocks dir20: ral ;Test bit jc dir20a inx b dir20a: mov d,a ;Save bits dcx h mov a,l ora h jz dir21 ;Quit if out of blocks mov a,d ;Restore bits dcr e ;count down 8 bits jnz dir20 ;do another bit pop d ;Bump to next count of Allocation Vector inx d jmp dir19 ;process it dir21: pop d ;Clear Allocation vector from stack mov l,c ;Copy block to 'HL' mov h,b lda bshiftf ;Get Block Shift Factor sui 3 ;Convert from records to thousands rz ;Skip shifts if 1K blocks dir22: dad h ;Multiply blocks by 'K per Block' dcr a jnz dir22 ret ; ; 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 IF mdI lda group ori mdmgrp ;Mask modem serial port out grpsel ENDIF;mdI [Toad Hall] ret selcon: IF iobyt lda coniob ;Set up for output to go to the console port sta iobyte ;Switch directly ENDIF;iobyt IF mdI lda group ori congrp ;Mask console serial port (1) out grpsel ENDIF;mdI [Toad Hall] 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 rm380z ;[22] mov a,e cpi cr ;cr produces cr + lf jnz outcn1 mvi e,'N'-100O ;Control-N produces cr only outcn1: ;continue ENDIF;[22] rm380z 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 osi OR apple OR lobo ;[hh] push h outmd1: lxi h,mnprts ;address of the port status register outmd2: mov a,m ; get port status in A ani output ;Loop till ready. jz outmd2 outmd3: lxi h,mnport ;address of port data register mov m,e ; write the character pop h ret ENDIF;osi OR apple OR lobo IF osbrn1 call osldst ;Read the status port ani output ;Loop till ready. jz outmdm mov a,e jmp osstda ;Write to the data port ENDIF;osbrn1 IF px8 ; [29] push h push b push d outmd1: call rsoutst ; get the output status ora a jz outmd1 ; check if output enabled pop d mov c, e ; char in C push d call rsput pop d pop b pop h ret ENDIF; px8 [29] IF inout 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 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 cpm3 push h push b mvi c,auxout ;Output to the aux output device call bdos pop b pop h ret ENDIF;cpm3 IF torch ;[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... mov a,e ; get the byte to ssend [30] sta outda1 ; little impure code [30] call tx db 01 ; send to printer call tx outda1: db 0 ; filled in by above [30] ret outda2: mov a,e ; get the byte to be sent s-l-o-w-l-y sta txd ; store for third parameter push h lxi h,txds ; load for txdata via osbyte call osbyte pop h ret instat: push h ;get serial port status lxi h,rxrs ; load rxrdy string call osbyte pop h lda xx ana a ; if zero, then nothing jz notry jmp rdy outstat:push h ;get serial port status (tx) lxi h,txrs ; load string for tx ready string call osbyte pop h lda xx ; get reply byte from base proc. cpi 5 ; 5 spaces left? jm notry rdy: mvi a,0ffh ; ready for data ana a ret notry: xra a ret 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 cpm3 mvi c,auxist call bdos ;is char at auxin? ora a ;something there? rz ;no mvi c,auxin call bdos ;read char from auxin ENDIF;cpm3 IF osi OR apple OR lobo ;[hh] inpmd1: lda mnprts ;Get the port status into A. ani input ;See if the input ready bit is on. rz ;If not then return. inpmd2: lda mnport ;If so, get the char. ENDIF;osi OR apple IF osbrn1 call osldst ;Read the status port ani input ;Something there? rz ;Nope call osldda ;Read the data port ENDIF;osbrn1 IF inout ;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 IF px8 ; [29] call rserst ; check error status ani 64h ; this assumes 'not open' cannot occur jnz inpmd1 ; error has occurred! call rsinst ; any chars outstanding? ora a rz ; exit if none call rsget ; get char in A ret ; return the 'no char outstanding' indication on error inpmd1: mvi a, 0 ENDIF; px8 [29] IF torch ;[13] torch input indat: push h lxi h,rxds call osbyte pop h lda yy ani 7fh ret ; rx data in a ENDIF ;torch [13] 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. ; ; 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 lxi h,f51 ; fx 5,1 (parallel port selected for printer) call osbyte ; lxi h,f610 ; map out lf as these are usually added ; call osbyte ; by the printer, alas. pop d push d ; restore de regs 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] lxi h,f52 ;fx 5,2 call osbyte lxi h,f60 ;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 NOT (robin OR dmII OR vt100 OR osi OR crt OR vector OR cifer OR torch ) 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;NOT (robin OR dmII OR vt100 OR osi OR crt OR vector OR cifer OR torch) ; ; IF cifer ; [14] cifer does it colums then rows.. swap b and c 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 (' '-1) ; space is column one mov e,a push h call outcon ; output row pop h mov a,h ; [obs] get row adi (' '-1) ; space is row one mov e,a jmp outcon ; output it and return ENDIF; cifer [14] ; ; csrpos for ANSI terminals ; IF robin OR dmII OR vt100 csrpos: push b ; save coordinates lxi d,curldn ; get cursor leadin sequence call prtstr ; print it pop h ; peek at coordinates push h ; then save away again mov l,h ; l = row mvi h,0 ; hl = row call nout ; output in decimal mvi e,';' ; follow with semicolon call outcon ; print it pop h ; restore column mvi h,0 ; hl = column call nout mvi e,'H' ; terminate with 'move cursor' command jmp outcon ; output it and return ENDIF;robin OR dmII OR vt100 ; ; csrpos for the Vector General. It's weird. ; IF vector csrpos: dcr b ; vector uses zero-based addressing? dcr c push b ; save coordinates mvi e,esc ; print an escape call outcon pop d ; peek at coordinates push d call outcon ; output column pop d mov e,d ; get row jmp outcon ; output and return ENDIF;vector ;[13] torch stuff follows IF torch ; This assumes no smartvdu functions.. and relies on BBC screen functions. ; Has bias of -1 on column/row coords. Column first. ; NOTE -- must use torch unique prtstr as cntl chars are trapped ; by the output routine. csrpos: push b ; save coordinates mvi e,1fh ; get cursor leadin sequence call outcon ; print it pop h ; restore coordinates mov a,l ; get column adi 0ffh ; a zero is first (add minus 1) mov e,a push h call outcon ; output column pop h mov a,h ; get row adi 0ffh ; zero is first row mov e,a jmp outcon ; output row ENDIF ;torch [13] IF osi OR crt ; systems without cursor positioning csrpos: ret ; dummy routine referenced by linkage section ENDIF;osi OR crt ; ; position to various fields: ; for the Kermits with cursor positioning, the display looks like this: ; 5 10 15 20 25 30 35 ; +----|----|----|----|----|----|----|... ; 1 | ; 2 | Kermit-80 v4.0 [system] ; 3 | ; 4 |Number of packets: ____ ; 5 |Number of retries: ____ ; 6 |File name: ____________ ; 7 |... ; 8 |... ; 9 |RPack: ___(if debugging)... ; 10 | ; 11 |SPack: ___(if debugging)... ; 12 | ; 13 |Kermit-80 A:> (when finished) ; ; For the PX-8, the display looks like: ; 5 10 15 20 25 30 35 40 45 50 55 ; +----|----|----|----|----|----|----|----|----|----|----|----|---- ; 1 |Kermit-80 v4.05 [Epson PX-8] Number of retries: ____ ; 2 |Number of packets: ____ File name: ________.___ ; 3 |... ; 4 |... ; 5 |RPack: ___ (if debugging)... ; 6 | ; 7 |SPack: ___ (if debugging)... ; 8 | ; 9 |Kermit-80 A:> (when finished) ; IF NOT px8 ; [29] nppos EQU 4*100h+20 rtpos EQU 5*100h+20 fnpos EQU 6*100h+12 errlin EQU 7 stlin EQU 8 rplin EQU 9 splin EQU 11 prplin EQU 13 ENDIF ; NOT px8 IF px8 nppos EQU 2*100h+20 rtpos EQU 1*100h+59 fnpos EQU 2*100h+51 errlin EQU 3 stlin EQU 4 rplin EQU 5 splin EQU 7 prplin EQU 9 ENDIF ; px8 [29] IF NOT (osi OR crt OR torch) ;[26] see also torch version below scrnp: lxi b,nppos jmp csrpos scrnrt: lxi b,rtpos jmp csrpos scrfln: lxi b,fnpos call csrpos clreol: lxi d,tk jmp prtstr screrr: lxi b,errlin*100H+1 call csrpos jmp clreol scrst: lxi b,stlin*100H+1 call csrpos jmp clreol rppos: lxi b,rplin*100H+8 call csrpos jmp clreol sppos: lxi b,splin*100H+8 call csrpos jmp clreol ; [29] Modify scrend to make the cursor line conditional on use of debugging ; This means that in most cases the entire file transfer will fit on PX-8 lcd scrend: lda dbgflg ora a jz scr1nd lxi b,prplin*100H+1 ; debugging in use [29] jmp scr2nd scr1nd: lxi b,rplin*100H+1 ; no debugging scr2nd: call csrpos clreos: lxi d,tj jmp prtstr ; [29] and nop out the rest for now... ; ;scrend: lxi b,prplin*100H+1 ; call csrpos ;clreos: lxi d,tj ; jmp prtstr ENDIF;NOT (osi OR crt OR torch) [26] IF torch ;[26] Torch version different, naturally, so duplicate ; the above code and add in querks. scrnp: lxi b,nppos jmp csrpos scrnrt: lxi b,rtpos jmp csrpos scrfln: lxi b,fnpos call csrpos clreol: lxi d,spac15 ; No clear to end of line, so fudge it... call prtstr ; by writing a load of spaces.. lxi b,fnpos ; and re-position the cursor again jmp prtstr lxi d,tk jmp prtstr screrr: lxi b,errlin*100H+1 call csrpos jmp clreol scrst: lxi b,stlin*100H+1 call csrpos jmp clreol rppos: lxi b,rplin*100H+8 call csrpos jmp clreol sppos: lxi b,splin*100H+8 call csrpos jmp clreol scrend: lxi b,prplin*100H+1 call csrpos clreos: lxi d,tj jmp prtstr ENDIF;torch [26] IF osi OR crt ; no cursor control scrnp: mvi e,' ' jmp outcon scrnrt: mvi e,' ' call outcon mvi e,'%' jmp outcon scrfln: screrr: scrst: scrend: jmp prcrlf ;Print CR/LF [Toad Hall] rppos: lxi d,prpack jmp prtstr sppos: lxi d,pspack jmp prtstr ENDIF;osi OR crt ; ; 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 bbI OR vector OR apple OR osbrn1 OR lobo lxi d,delstr jmp prtstr ENDIF;bbI OR vector OR apple OR osbrn1 OR lobo IF advant OR bbc OR rm380z ;[22] ret ENDIF;[22] advant OR bbc OR rm380z IF NOT (bbI OR vector OR apple OR osbrn1 OR torch OR advant OR bbc OR rm380z);[22] mvi e,bs ;get a backspace jmp outcon ENDIF;NOT (bbI OR vector OR apple OR osbrn1 OR torch OR advant OR bbc OR rm380z [22] ; 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 ; Some frequently-used routines (duplicates of those in CP4MIT): ; prcrlf - output a CR/LF ; prtstr - output string in DE ; rskp - return, skipping over error return prcrlf: lxi d,crlf ;[26] re-inserted prtstr for normal machines as some belly-ache at ; Torch code below (ie DOS function 9 emulation). Save regs just in case prtstr: IF NOT (torch OR px8) ;ie any machine that can send ctrl chrs via dos call 9 push b mvi c,9 ; Dos call 9 (print a string) call bdos pop b ret ; all done for good machines ENDIF ;NOT torch [26] OR px8 [31] IF (torch OR px8) ; Now for the not-so-good machine(s) ; [17] added this to avoid prtstr.. emulate function 9 call. ; ; Modified print string as the CP/N (for Nut) system traps control ; characters in a function 9 call.. rot its cotton socks. push h push d push b prtst1: ldax d inx d cpi '$' ; if a dollar then end of string jz prtst2 push d mov e,a call outcon ; send it to the screen pop d jmp prtst1 prtst2: pop b pop d pop h ret ; regs restored.. just in case ENDIF ;torch [17] [26] OR px8 [31] rskp: pop h ; Get the return address inx h ; Increment by three inx h inx h pchl ; Copy block of data ; source in HL, destination in DE, byte count in BC ; called by: cp4sys, mfname ; mover: IF NOT z80 ; 8080's have to do it the hard way mov a,m stax d inx h inx d dcx b mov a,b ora c jnz mover ENDIF;NOT z80 IF z80 db 0EDh,0B0h ; Z80 LDIR instruction ENDIF;z80 ret IF torch ;[13] ; OSBYTE call from Torch to BBC Base Processor. ; ; Two entries, one for call if (hl) points to three bytes which are ; Osbyte type ; X register byte (Parameter 2) ; Y register byte (Parameter 3) ; ; second entry where ; A register has osbyte type ; D register has equivalent X regiter of Beeb (Parameter 2) ; E register has equivalent Y register of 6502 (parametr 3) ; ; Both have reply parameters equivaletnt to the Beeb 6502 processors X and Y ; registers as xx and yy address locations below. ; ; A little impure code never hurt anyone... ; tx equ 0ffc3h ; tx routine to talk to base board proc. rx equ 0ffc6h ; rx ditto osbyt1: sta p1 ; accumulator to p1 (Type of osbyte) mov a,d ; get ls bits of input parameter sta p2 ; second parameter from d mov a,e ; sta p3 ; third parameter from e jmp osbytx ; now do funny torch call that calls an osbyte osbyte: mov a,m sta p1 inx h mov a,m sta p2 inx h mov a,m sta p3 osbytx: call tx ;set it for user function db 15 call tx ; select function is osbyte db 15 call tx ; now do call to osbyte proper p1: db 0 call tx p2: db 0 call tx ; three params there, p3: db 0 call rx sta xx ; stor return value call rx sta yy ; and second returned value ret txrs: db 128,253,0 ; string for txstatus txds: db 138,2 txd: db 0 ; place data to be sent rxrs: db 128,254,0 ; get rx status string rxds: db 145,1,0 xx: db 0 yy: db 0 ; returned data from osbyte call rs423m: db 204,0,0 rs423n: db 205,0,0 f31: db 3,0,1 ; enable 423. uses xx=(xx AND Y) EOR X f22: db 2,2,0 f51: db 5,1,0 ; fx 5,1 sets printer to parallel port [30] f52: db 5,2,0 ; 432 as printer => faster tx to line [30] f60: db 6,0,0 ; allow line feed chars [30] f610: db 6,10,0 ; add strip line feeds from prinetr stream [30] prinuse:db 0 ; 0=> fast tx, <>0 => slow tx to serial pt. [30] ENDIF ;torch [13] IF Torch ;[27] ;Peek and Poke routines for the Torch systems.. Needed to check if TX empty ; ; PEEK - On entry, has address to be snooped at in HL ; - On return, has the data at that address in tha A register ; ; POKE - On entry, has the address to be poked in HL, and the data in A ; - Nothing returned. ; ; Assume all other registers and flags corrupted ; ; peek: mvi a,peekb ; byte for tx routine to peek ram sta ppbyte ; save it in impure code call peekpoke ; do common code call rx ; and get peeked byte back in accumulator ret poke: sta pbyte ; save byte to be poked mvi a,pokeb ; byte for tx routne to poke to ram sta ppbyte ; save it in impure code call peekpoke ;call common routine call tx ; interprocessor tx routine pbyte: db 0 ; byte to be poked placed here ret ; and return peekpoke: ; common routine for peek-ing and ; poke-ing to the base processor memory map. mov a,l ; get the taget address to this routine sta lobyte mov a,h ; ditto high address byte sta hibyte call tx ; call the interprocessor send routine ppbyte: db 0 ; this byte to be filled by the peek or poke routine call tx ; now send address lobyte: db 0 ; low address byte to be sent call tx hibyte: db 0 ; high address byte ret ; now do either a peek (rx) or poke (tx) ; peekb equ 0dh ; byte to initiate a peek pokeb equ 0eh ; byte to initiate a poke ENDIF ;torch [27] ; ; Miscellaneous messages ; crlf: db cr,lf,'$' cfgmsg: db 'configured for $' IF adm3a OR tvi912 OR tvi925 OR vt52 OR vt100 OR smrtvd OR access; [7] [29] witmsg: db ' with $' ENDIF;adm3a OR tvi912 OR tvi925 OR vt52 OR vt100 OR smrtvd OR access [7] [29] ;**************************Terminal tables**************************** IF NOT (osi OR crt) AND NOT px8 ; [29] got cursor control? outln2: db ']',cr,lf,cr,lf,'Number of packets:' db cr,lf,'Number of retries:' db cr,lf,'File name:$' ENDIF;NOT (osi OR crt) AND NOT px8 [29] IF px8 ; [29] outln2: db '] Number of retries:', cr, lf db 'Number of packets: File name:$' ENDIF ; px8 [29] IF NOT (osi OR crt) ; [29] outln3: db cr,lf,cr,lf ; debugging messages db cr,lf,'Rpack:' db cr,lf ; Blank line in case of long packet db cr,lf,'Spack:$' ENDIF ; NOT (osi OR crt) [29] IF lobo ;[hh] sysver: db 'Lobo MAX-80$' outlin: db esc,'*',cr,lf,tab,tab,'$' erascr: db esc,'*$' ;[hh] clear screen and home cursor eralin: db cr,esc,'R$' ;[hh] clear line curldn: db esc,'=$' ;[hh] cursor lead-in string delstr: db bs,' ',bs,bs,'$' ;[hh] ??adjust for echoing delete ttab: ;[hh] table start location ta: db 0BH,'$',0,0 ;[hh] cursor up tb: db 0AH,'$',0,0 ;[hh] cursor down tc: db 0CH,'$',0,0 ;[hh] cursor right td: db 08H,'$',0,0 ;[hh] cursor left te: db esc,'*$',0 ;[hh] clear display (homes cursor) tf: db '$',0,0,0 ;[hh] (can't) enter graphics mode tg: db '$',0,0,0 ;[hh] (can't) exit graphics mode th: db 01EH,'$',0,0 ;[hh] home cursor ti: db esc,'E$',0 ;[hh] reverse linefeed (insert line) tj: db esc,'Y$',0 ;[hh] clear to end of screen tk: db esc,'T$',0 ;[hh] clear to end of line ENDIF ;lobo 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 px8 ; [29] sysver: db 'Epson PX-8$' outlin: db esc,'*$' erascr: db esc,'*$' ; clear screen and home eralin: db cr,esc,'T$' ; clear line curldn: db esc,'=$' ; cursor lead in ttab: ; table start location ta: db 30,'$',0,0 ; cursor up tb: db 31,'$',0,0 ; cursor down tc: db 28,'$',0,0 ; cursor right td: db 29,'$',0,0 ; cursor left te: db esc,'*$',0 ; clear display tf: db '$',0,0,0 ; can't enter graphics graphics mode tg: db '$',0,0,0 ; can't exit graphics mode th: db 11,'$',0,0 ; home cursor ti: db 30,'$',0,0 ; reverse linefeed tj: db esc,'Y$',0 ; erase to end of screen tk: db esc,'T$',0 ; erase to end of line ENDIF ; px8 [29] IF osbrn1 sysver: db 'Osborne 1$' outlin: db 1AH,cr,lf,tab,'$' ;(Clear screen, home cursor) erascr: db 1AH,'$' ;Clear screen and go home. eralin: db cr,esc,'T$' ;Clear line. delstr: db bs,bs,'$' ; Adjust for delete curldn: db esc,'=$' ;Cursor lead-in ttab: ;Table start location. ta: db ('K'-100O),'$',0,0 ;Cursor up. tb: db 12O,'$',0,0 ;Cursor down. tc: db ('L'-100O),'$',0,0 ;Cursor right. td: db bs,'$',0,0 ;Cursor left. te: db subt,'$',0,0 ;Clear screen. tf: db '$',0,0,0 ;(can't) Enter graphics mode tg: db '$',0,0,0 ;(can't) Exit graphics mode th: db ('^'-100O),'$',0,0 ;Cursor home. ti: db ('K'-100O),'$',0,0 ;Reverse linefeed. tj: db esc,'T$',0 ;(can't) Clear to end of screen. tk: db esc,'T$',0 ;Clear to end of line. ENDIF;osbrn1 IF apple sysver: db 'Apple II CP/M$' outlin: db ('^'-100O),esc,'Y',cr,lf,' $' erascr: db ('^'-100O),esc,'Y$' ;Clear screen and go home. eralin: db cr,esc,'T$' ;Clear line. delstr: db bs,bs,'$' ; Adjust for delete curldn: db esc,'=$' ;Cursor lead-in 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 ('^'-100O),'$',0,0 ;Cursor home. ti: db ('K'-100O),'$',0,0 ;Reverse linefeed. tj: db esc,'Y$',0 ;Clear to end of screen. tk: db esc,'T$',0 ;Clear to end of line. ENDIF;apple IF vector sysver: db 'Vector Graphics$' outlin: db ('D'-100O),cr,lf,tab,tab,'$' erascr: db ('D'-100O),'$' ;Clear screen and go home. eralin: db cr,('Q'-100O),'$' ;Clear line. delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character ttab: ;Table start location. ta: db ('U'-100O),'$',0,0 ;Cursor up. tb: db 12O,'$',0,0 ;Cursor down. tc: db ('Z'-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 ('B'-100O),'$',0,0 ;Cursor home. ti: db ('U'-100O),'$',0,0 ;Reverse linefeed. tj: db ('P'-100O),'$',0,0 ;Clear to end of screen. tk: db ('Q'-100O),'$',0,0 ;Clear to end of line. ENDIF;vector IF telcon sysver: db 'Telcon Zorba$' ENDIF;telcon IF heath sysver: db 'Heath/Zenith 89$' ENDIF;heath IF z100 sysver: db 'Heath/Zenith Z-100 CP/M$' ENDIF;z100 IF vt52 ; DEC VT52 ttytyp: db 'VT52$' ENDIF;vt52 IF heath OR z100 OR telcon OR vt52 outlin: db esc,'H',esc,'J',cr,lf,tab,tab,'$' erascr: db esc,'H',esc,'J$' ;Clear screen and go home. eralin: db cr,esc,'K$' ;Clear line. curldn: db esc,'Y$' ;cursor leadin ttab: ;Table start location. ta: db esc,'A$',0 ;Cursor up. tb: db esc,'B$',0 ;Cursor down. tc: db esc,'C$',0 ;Cursor right. td: db esc,'D$',0 ;Cursor left te: db esc,'E$',0 ;Clear display tf: db esc,'F$',0 ;Enter Graphics Mode tg: db esc,'G$',0 ;Exit Graphics mode th: db esc,'H$',0 ;Cursor home. ti: db esc,'I$',0 ;Reverse linefeed. tj: db esc,'J$',0 ;Clear to end of screen. tk: db esc,'K$',0 ;Clear to end of line. ENDIF;heath OR z100 OR telcon OR vt52 IF trs80lb sysver: db 'TRS-80 II Lifeboat CP/M$' outlin: db esc,':',cr,lf,tab,tab,'$' erascr: db esc,':$' ;Clear screen and go home. eralin: db cr,esc,'T$' ;Clear line. curldn: db esc,'=$' ;Cursor lead-in ttab: ;Table start location. ta: db 0BH,'$',0,0 ;Cursor up. tb: db 0AH,'$',0,0 ;Cursor down. tc: db 0CH,'$',0,0 ;Cursor right. td: db bs,'$',0,0 ;Cursor left te: db esc,':$',0 ;Clear display 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 linefeed. tj: db esc,'Y$',0 ;Clear to end of screen. tk: db esc,'T$',0 ;Clear to end of line. ENDIF;trs80lb IF trs80pt sysver: db 'TRS-80 II P+T CP/M$' outlin: db 0CH,cr,lf,tab,tab,'$' erascr: db 0CH,'$' ;Clear screen and go home. eralin: db cr,01H,'$' ;Clear line. curldn: db esc,'Y$' ;Cursor lead-in ttab: ;Table start location ;Must be 4 bytes each ta: db 1EH,'$',0,0 ;Cursor up. tb: db 1FH,'$',0,0 ;Cursor down. tc: db 1DH,'$',0,0 ;Cursor right. td: db 1CH,'$',0,0 ;Cursor left te: db 0CH,'$',0,0 ;Clear display tf: db 11H,'$',0,0 ;Enter Graphics Mode tg: db 14H,'$',0,0 ;Exit Graphics mode th: db 06H,'$',0,0 ;Cursor home. ti: db 1EH,'$',0,0 ;Reverse linefeed. tj: db 02H,'$',0,0 ;Clear to end of screen. tk: db 01H,'$',0,0 ;Clear to end of line. ENDIF;trs80pt IF robin sysver: db 'VT180 "Robin"$' ENDIF;robin IF dmII sysver: db 'DECmate II CP/M-80$' ENDIF;dmII IF vt100 ttytyp: db 'VT100$' ENDIF;vt100 IF norths sysver: db 'Northstar Horizon$' ENDIF;norths IF basicns ;[29] sysver: db 'Northstar using printer port$' ttytyp: db 0 ENDIF ;basicns [29] IF comart ;[25] sysver: db 'Comart Communicator$' ENDIF;comart IF horizon ;[25] sysver: db 'Northstar Horizon$' ENDIF;horizon IF cmemco ;[25] sysver: db 'Cromemco (TU-ART)$' ENDIF;cmemco IF robin OR dmII or vt100 ; Note that we cannot support Graphics Mode or the H19 erase-screen command ; (E), because the sequences are more than three bytes. outlin: db esc,3CH,esc,'[H',esc,'[J',cr,lf,tab,tab,'$' erascr: db esc,'[H',esc,'[J$' ;Clear screen and go home. eralin: db cr,esc,'[K$' ;Clear line. curldn: db esc,'[$' ; Cursor leadin ttab: ta: db esc,'[A$' ; Cursor up. tb: db esc,'[B$' ; Cursor down. tc: db esc,'[C$' ; Cursor right. td: db esc,'[D$' ; Cursor left te: db '$',0,0,0 ; (can't) Clear display tf: db '$',0,0,0 ; (don't) Enter Graphics Mode tg: db '$',0,0,0 ; (don't) Exit Graphics mode th: db esc,'[H$' ; Cursor home. ti: db esc,'M$',0 ; Reverse linefeed. tj: db esc,'[J$' ; Clear to end of screen. tk: db esc,'[K$' ; Clear to end of line. ENDIF;robin OR dmII or vt100 IF kpii sysver: db 'Kaypro II$' outlin: db subt,cr,lf,tab,tab,'$' erascr: db subt,'$' ;Clear screen and home. eralin: db cr,18H,'$' ;Clear line. curldn: db esc,'=$' ;Cursor lead-in delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character ttab: ;Table start location. ta: db 0BH,'$',0,0 ;Cursor up. tb: db 0AH,'$',0,0 ;Cursor down. tc: db 0CH,'$',0,0 ;Cursor right. td: db bs,'$',0,0 ;Cursor left te: db subt,'$',0,0 ;Clear display tf: db esc,'G$',0 ; Enter Graphics Mode (select Greek) tg: db esc,'A$',0 ; Exit Graphics mode (select ASCII) th: db 1EH,'$',0,0 ; Cursor home. [UTK016] ti: db esc,'E','$',0 ; Reverse linefeed. (insert line) tj: db 'W'-100O,'$',0,0 ; Clear to end of screen. tk: db 'X'-100O,'$',0,0 ; Clear to end of line. ENDIF ; kpii IF xer820 sysver: db 'Xerox 820$' outlin: db subt,cr,lf,tab,tab,'$' erascr: db subt,'$' ;Clear screen and home. eralin: db cr,18H,'$' ;Clear line. curldn: db esc,'=$' ;Cursor lead-in delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character ttab: ;Table start location. ta: db 0BH,'$',0,0 ;Cursor up. tb: db 0AH,'$',0,0 ;Cursor down. tc: db 0CH,'$',0,0 ;Cursor right. td: db bs,'$',0,0 ;Cursor left te: db subt,'$',0,0 ;Clear display tf: db '$',0,0,0 ; Enter Graphics Mode (can't) tg: db '$',0,0,0 ; Exit Graphics mode (can't) th: db 1EH,'$',0,0 ; Cursor home. [UTK016] ti: db 0BH,'$',0,0 ; Reverse linefeed. (cursor up) tj: db 11H,'$',0,0 ; Clear to end of screen. tk: db 18H,'$',0,0 ; Clear to end of line. ENDIF ; xer820 IF mikko sysver: db 'MikroMikko$' outlin: db subt,cr,lf,tab,'$' erascr: db subt,'$' ;Clear screen and go home. eralin: db cr,1CH,'$' ;Clear line. curldn: db esc,'=$' ;cursor leadin ttab: ;Table start location. ta: db 0BH,'$',0,0 ;Cursor up. tb: db 0AH,'$',0,0 ;Cursor down. tc: db 0CH,'$',0,0 ;Cursor right. td: db bs,'$',0,0 ;Cursor left te: db subt,'$',0,0 ;Clear display 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 '$',0,0,0 ;(can't) Reverse linefeed. tj: db 1cH,'$',0,0 ;Clear to end of screen. tk: db 1cH,'$',0,0 ;Clear to end of line. ENDIF;mikko IF cifer ;[13] ttytyp: db 'Cifer 1886$' sysver: db ' Cifer 1886 $' ; outlin: db esc,'J',cr,lf,tab,tab,'$' eralin: db esc,'^K$' ;Clear to end of line. erascr: db esc,'J$' ;Clear screen and go home. curldn: db esc,'P$' ;Cursor lead-in ttab: ;Table start location. ta: db esc,'A$',0 ;Cursor up. tb: db esc,'@$',0 ;Cursor down. tc: db esc,'C$',0 ;Cursor right. td: db esc,'D$',0 ;Cursor left. te: db esc,'J',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 esc,'H$',0 ;Cursor home. ti: db esc,'@$',0 ;reverse linfeed tj: db esc,'B$',0 ;Clear to end of screen tk: db esc,'K$',0 ;Clear to end of line. ; ; Setup string for the Cifer.. called as a prtstr param. from sysinit ciferi: db esc,'/' ;Setup cifer for on line db esc,'*[' ; direct mode on db esc,'%' ; protocol on host line on db esc,'*~x' ; protocol is xon/xoff db esc,'*(' ; protocol out on host is xon/xoff db '$' ; all done ENDIF;cifer [13] IF torch AND NOT crt ;[13] ttytyp: db 'Torch Unicorn 5$' sysver: db 'Torch Unicorn 5$' outlin: db 0ch,cr,lf,tab,tab,'$' eralin: db '$' ;Clear to end of line. erascr: db 0ch,'$' ;Clear screen and go home. curldn: db 1fh,'$' ;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;torch [13] IF advant ;[22] sysver: db 'North Star Advantage$' outlin: db 04H,cr,lf,tab,'$' erascr: db 04H,'$' ;Clear screen and go home. eralin: db cr,0EH,'$' ;Clear line. curldn: db esc,'=$' ;cursor leadin ttab: ;Table start location. ta: db 0BH,'$',0,0 ;Cursor up. tb: db 0AH,'$',0,0 ;Cursor down. tc: db 0CH,'$',0,0 ;Cursor right. td: db bs,'$',0,0 ;Cursor left te: db 04H,'$',0,0 ;Clear display tf: db 12H,'$',0,0 ;Enter Graphics Mode tg: db 13H,'$',0,0 ;Exit Graphics mode th: db 1EH,'$',0,0 ;Cursor home. ti: db 0BH,'$',0,0 ;Reverse linefeed. tj: db 0FH,'$',0,0 ;Clear to end of screen. tk: db 0EH,'$',0,0 ;Clear to end of line. ENDIF;[22] advant IF bbc ;[22] sysver: db 'BBC (Z80)$' outlin: db 0CH,esc,'=',21H,30H,'$' erascr: db 0CH,'$' ;Clear screen and go home. eralin: db cr,esc,'@$' ;Clear line. curldn: db esc,'=$' ;cursor leadin ttab: ;Table start location. ta: db 0BH,'$',0,0 ;Cursor up. tb: db 0AH,'$',0,0 ;Cursor down. tc: db tab,'$',0,0 ;Cursor right. td: db bs,'$',0,0 ;Cursor left te: db 0CH,'$',0,0 ;Clear display 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 '$',0,0,0 ;(can't) Reverse linefeed. tj: db esc,'?$',0,0 ;Clear to end of screen. tk: db esc,'@$',0,0 ;Clear to end of line. ENDIF;[22] bbc IF rm380z ;[22] sysver: db 'Research Machines 380Z$' outlin: db 1FH,cr,tab,'$' erascr: db 1FH,'$' ;Clear screen and go home. eralin: db 0EH,19H,'$' ;Clear line. curldn: db 16H,'$' ;cursor leadin ttab: ;Table start location. ta: db 0BH,'$',0,0 ;Cursor up. tb: db 0AH,'$',0,0 ;Cursor down. tc: db 18H,'$',0,0 ;Cursor right. td: db bs,'$',0,0 ;Cursor left te: db 1FH,'$',0,0 ;Clear display tf: db '$',0,0,0 ;(can't) Enter Graphics Mode tg: db '$',0,0,0 ;(can't) Exit Graphics mode th: db 1DH,'$',0,0 ;Cursor home. ti: db '$',0,0,0 ;(can't) Reverse linefeed. tj: db 1EH,'$',0,0 ;Clear to end of screen. tk: db 19H,'$',0,0 ;Clear to end of line. ENDIF;[22] rm380z IF gener or cpm3 sysver: db 'Generic CP/M-80$' ENDIF;gener or cpm3 IF bbII sysver: db 'Big Board II$' ENDIF;bbII IF cpt85xx sysver: db 'CPT-85xx under CompuPak CP/M$' ENDIF;cpt85xx IF mdI sysver: db 'Morrow Decision I$' ENDIF;mdI [Toad Hall] IF mmdI sysver: db 'MicroDecision I$' ENDIF;mmdI IF osi sysver: db 'Ohio Scientific$' ENDIF;osi IF pci2651 ;[28] sysver: db 'LUT M/C 3 Standard 8 inch system$' ENDIF ;pci2651 [28] IF mmate ;[29] sysver: db 'PMC Micromate using port I/O$' ENDIF;mmate [29] IF disc ;[29] sysver: db 'Discovery using 83U board port B$' ENDIF ;disc [29] IF access ;[29] sysver: db 'Actrix CP/M$' ENDIF ; access [29] IF s1008 ;[29] sysver: db 'U. S. MicroSales using printer port' ENDIF ;s1008 [29] IF (access OR s1008) ;[29] Should this not be with terminals..... ttytyp: db 'Soroc IQ-120$' outlin: db 1EH,esc,'Y',cr,lf,tab,tab,'$' erascr: db 1EH,esc,'Y$' ;clear screen and home cursor eralin: db cr,esc,'T$' ;clear line curldn: db esc,'=$' ;cursor lead-in string delstr: db bs,' ',bs,bs,'$' ;??adjust for echoing delete ttab: ;table start location ta: db 0BH,'$',0 ;cursor up tb: db 0AH,'$',0 ;cursor down tc: db 0CH,'$',0 ;cursor right td: db 08H,'$',0 ;cursor left te: db esc,'*$',0 ;clear display (homes cursor) tf: db esc,')$',0 ;enter inverse video mode tg: db esc,'($',0 ;exit inverse video mode th: db 01EH,'$',0 ;home cursor ti: db 0BH,'$',0 ;reverse linefeed (insert line) tj: db esc,'Y$',0 ;clear to end of screen tk: db esc,'T$',0 ;clear to end of line ENDIF;access [29] IF osi OR crt outlin: db cr,lf,'Starting ...$' erascr equ crlf ;"Home & clear" (best we can do). eralin: db '^U',cr,lf,'$' ;Clear line. prpack: db cr,lf,'RPack: $' pspack: db cr,lf,'SPack: $' ttab equ 0 ; no VT52 table ENDIF;osi OR crt IF tvi912 ttytyp: db 'TVI912/920$' outlin: db 'Z'-64,0,0,cr,lf,'$' erascr: db 'Z'-64,0,0,'$' ;Clear screen and home eralin: db esc,'Y$',0 ;Clear to end of sreen curldn: db cr,esc,'=$' ;Cursor lead-in ttab: ;Table start location ;(MUST be 4 bytes each) ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top tb: db 'J'-64,'$',0,0 ;Cursor down, stop at bottom tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right td: db 'H'-64,'$',0,0 ;Cursor left, stop at left te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls) 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 esc,'j$',0 ;Reverse linefeed, scroll tj: db esc,'Y$',0 ;Clear to end of sreen tk: db esc,'T$',0 ;Clear to end of line ENDIF;tvi912 ; IF tvi925 ;(incidentally, works fine for Freedom 100 also [Toad Hall]) ;adm3a entry and tvi925 entry separated to remove warning message. ttytyp: db 'TVI925$' outlin: db 'Z'-64,0,0,cr,lf,'$' erascr: db 'Z'-64,0,0,'$' ;Clear screen and home eralin: db esc,'Y$',0 ;Clear to end of sreen curldn: db cr,esc,'=$' ;Cursor lead-in ttab: ;Table start location ;(MUST be 4 bytes each) ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top tb: db 'V'-64,'$',0,0 ;Cursor down, stop at bottom tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right td: db 'H'-64,'$',0,0 ;Cursor left, stop at left te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls) 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 esc,'j$',0 ;Reverse linefeed, scroll tj: db esc,'Y$',0 ;Clear to end of sreen tk: db esc,'T$',0 ;Clear to end of line ENDIF;tvi925 ; IF adm3a ttytyp: db 'ADM3A$' outlin: db 'Z'-64,0,0,cr,lf,'$' erascr: db 'Z'-64,0,0,'$' ;Clear screen and home eralin: db esc,'Y$',0 ;Clear to end of sreen curldn: db cr,esc,'=$' ;Cursor lead-in ttab: ;Table start location ;(MUST be 4 bytes each) ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top tb: db 'J'-64,'$',0,0 ;Cursor down CTRL-J tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right td: db 'H'-64,'$',0,0 ;Cursor left, stop at left te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls) 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 'K'-64,'$',0,0 ;Reverse linefeed tj: db '$',0,0,0 ;(can't) Clear to end of screen tk: db '$',0,0,0 ;(can't) Clear to end of line ENDIF;adm3a IF delphi ; [7] new system sysver: db 'Digicomp Delphi 100$' endif;delphi IF smrtvd ; [7] new terminal ttytyp: db 'Smartvid-80$' outlin: db esc,'+',cr,lf,tab,tab,'$' eralin: db cr,esc,'T$' ;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 ('K'-100O),'$',0,0 ;Cursor up. tb: db 12O,'$',0,0 ;Cursor down. tc: db ('A'-100O),'$',0,0 ;Cursor right. td: db ('H'-100O),'$',0,0 ;Cursor left. te: db ('L'-100O),'$',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 ('Z'-100O),'$',0,0 ;Cursor home. ti: db ('K'-100O),'$',0,0 ;Reverse linefeed. tj: db esc,'Y$',0 ;Clear to end of screen. tk: db esc,'T$',0 ;Clear to end of line. ENDIF;smrtvd IF (torch AND crt) sysver: db 'Torch Unicorn 5 without crt addressing$' ENDIF ovlend equ $ ; End of overlay END