5 .printx Error: Z80 macro assembler (i.e. M80) required
8 ; KERMIT - (Celtic for "FREE")
10 ; This is the CP/M-80 implementation of the Columbia University
11 ; KERMIT file transfer protocol.
15 ; Copyright June 1981,1982,1983,1984,1985
18 ; Originally written by Bill Catchings of the Columbia University Center for
19 ; Computing Activities, 612 W. 115th St., New York, NY 10025.
21 ; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
22 ; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
29 ; Keep module name, edit number, and last revision date in memory.
31 family: db 'CPXCA.ASM (1) 3-DEC-2015$' ; First entry for V4.11
34 ; Assembly time message to let me know I'm building the right version.
37 .printx * Assembling Kermit-80 for AVR-CP/M *
41 SC16IS740_ADDR equ 90H ;SC16IS740 I2C address. (8bit, A0=VDD, A1=VDD)
44 VERSION_MIN equ 0304H ;Minimum AVR-CP/M firmware version required
46 ; Virtual I2C Interface
52 VI2C_BSIZ equ 66 ;largest message size including address byte (SLA)
54 ;----------------------------- ISC16IS740 UART -------------------------------
57 I2C_UART_RHR equ I2C_UART_PORT+00H ;R Receive Holding
58 I2C_UART_THR equ I2C_UART_PORT+00H ;W Transmit Holding
59 I2C_UART_IER equ I2C_UART_PORT+01H ;R/W Interrupt Enable
60 I2C_UART_FCR equ I2C_UART_PORT+02H ;W FIFO Control
61 TX_FIFO_RES equ 04H ; TX FIFO reset
62 RX_FIFO_RES equ 02H ; RX FIFO reset
63 FIFO_ENABLE equ 01H ; FIFO enable
65 I2C_UART_IIR equ I2C_UART_PORT+02H ;R Interrupt Identification
66 I2C_UART_LCR equ I2C_UART_PORT+03H ;R/W Line Control
67 DLAB equ 80H ; Devisor latch enable
68 WLS0 equ 01H ; Word Length Select Bit 0
69 WLS1 equ 02H ; Word Length Select Bit 1 for 8 bit word
70 STB equ 04H ; Stop bit count - 2 stop bits
72 I2C_UART_MCR equ I2C_UART_PORT+04H ;R/W Modem Control
73 RTS equ 02H ;RTS pin, 1 = active (low)
74 DTR equ 01H ;DTR pin (not on '740)
75 I2C_UART_LSR equ I2C_UART_PORT+05H ;R Line Status
76 TXE equ 40H ; THR and TSR empty
77 TXRDY equ 20H ; THR empty
78 RX_FE equ 08H ; Framig error
79 RX_PE equ 04H ; Parity error
80 RX_OE equ 02H ; Overrun error
81 RXRDY equ 01H ; Receved byte available
82 I2C_UART_MSR equ I2C_UART_PORT+06H ;R Modem Status
83 I2C_UART_SPR equ I2C_UART_PORT+07H ;R/W Scratchpad
84 I2C_UART_TCR equ I2C_UART_PORT+06H ;R/W Transmission Control
85 I2C_UART_TLR equ I2C_UART_PORT+07H ;R/W Trigger Level
86 I2C_UART_TXLVL equ I2C_UART_PORT+08H ;R Transmit FIFO Level
87 I2C_UART_RXLVL equ I2C_UART_PORT+09H ;R Receive FIFO Level
88 I2C_UART_EFCR equ I2C_UART_PORT+0FH ;R/W Extra Features
89 I2C_UART_DLL equ I2C_UART_PORT+00H ;R/W divisor latch LSB
90 I2C_UART_DLH equ I2C_UART_PORT+01H ;R/W divisor latch MSB
91 I2C_UART_EFR equ I2C_UART_PORT+02H ;R/W Enhanced Feature
92 I2C_UART_XON1 equ I2C_UART_PORT+04H ;R/W Xon1 word
93 I2C_UART_XON2 equ I2C_UART_PORT+05H ;R/W Xon2 word
94 I2C_UART_XOFF1 equ I2C_UART_PORT+06H ;R/W Xoff1 word
95 I2C_UART_XOFF2 equ I2C_UART_PORT+07H ;R/W Xoff2 word
98 z80 set TRUE ;This one emulates an Z80.
101 ;----------------------------------------------------------------------
103 ;----------------------------------------------------------------------
105 ; make a message table
107 ; label: mkmsgtab <msg0,msg1,msg2,...>
120 ; make a message table
122 ; label: mkmsgtab <msg0,msg1,msg2,...>
139 ;----------------------------------------------------------------------
141 ;----------------------------------------------------------------------
145 mkms_tab <'UART',,' not', ' detected',', crystal frequency: ','!'>
148 mkm_tab <?,1.8432, 3.6864, 5.5296, 7.3728, 9.216, 11.0592, 12.9024, 14.7456, 16.5888, 18.432, 20.2752, 22.1184, 23.9616>
152 db 'AVR firmware to old, at least version 3.4 neded.','$'
154 db cr,lf,'Exiting!',cr,lf,'$'
156 ;----------------------------------------------------------------------
158 ;----------------------------------------------------------------------
160 ; Print message from table
162 ; hl: message table address
163 ; first byte is number of table entries
164 ; a: number of message to print (0 based, index in table)
166 ; If index is out of range, print message #0
173 cp (hl) ; number of messages in table
194 ;----------------------------------------------------------------------
195 ; output bytes to ports
197 ; hl: tables of port,value pairs:
198 ; db n ;number of pairs
199 ; db port1,val1, port2,val2,... portn,valn
201 ; db 0 ; Terminate table
208 ld c,(hl) ;port address
215 ;----------------------------------------------------------------------
227 ;----------------------------------------------------------------------
236 ;----------------------------------------------------------------------
238 ;----------------------------------------------------------------------
242 out (c),b ;write 0 to version port
244 cp 1 ;result should be 0
245 ret nc ;exit (a != 0) if it wasn't
255 sbc a,a ;z if hl >= VERSION_MIN
258 ;----------------------------------------------------------------------
266 in a,(VI2C_CTRL) ;do: get i2c result
268 jr nz,uc_0 ;while busy
270 jr nz,uc_err ;error in transaction
307 ;----------------------------------------------------------------------
311 db (I2C_UART_SPR - I2C_UART_PORT) shl 3 ;address of scratch pad register
314 ;----------------------------------------------------------------------
317 ld hl,spt_tab ;init UART in loop back mode
318 call ioinil ; and fill tx fifo with 60 chars
320 in a,(I2C_UART_MSR) ;Clear Modem Status Register
321 in a,(I2C_UART_LSR) ;Clear Line Status Register
322 in a,(I2C_UART_RHR) ;Clear Receiver Buffers
325 ld a,2 ;start write transaction
333 in a,(43H) ;lsb seconds
337 in a,(I2C_UART_RXLVL) ;wait till all 60 char in rx fifo
346 in a,(43H) ;lsb seconds
350 spt_2: ;convert s to ms
355 sbc hl,de ;hl = elapsed time (ms) for 60 chars
373 db (spt_tab_end - ($+1))/2
374 db I2C_UART_LCR, DLAB+03H ;Set devisor latch access bit
375 db I2C_UART_DLL, low 96 ;1200 bit/s at 1.832 MHz
376 db I2C_UART_DLH, high 96 ;Out to the MSB divisor port
377 db I2C_UART_LCR, 03H ;Disable Divisor Access Latch
378 db I2C_UART_FCR, 07H ;Clear and enable fifos
379 db I2C_UART_MCR, 10H ;Enable loopback
380 db I2C_UART_IER, 0 ;Set no interrupts
381 db VI2C_ADR+0, low outbuf
382 db VI2C_ADR+1, high outbuf
386 ;----------------------------------------------------------------------
388 ;----------------------------------------------------------------------
390 sysxin: ; continuation of system initialisation from sysinit
400 ld hl,6 ;set default baud rate
418 ; ld a,07H ;Enable and clear fifos
419 ; out (I2C_UART_FCR),a ;
421 ; out (I2C_UART_LCR),a ;
425 ; system-dependent KERMIT termination processing
426 ; If we've changed anything, this is our last chance to put it back.
432 ; system-dependent processing for start of CONNECT command
437 conmsg: ; Messages printed when entering transparent (CONNECT) mode:
442 ; syscls - system-dependent close routine
443 ; called when exiting transparent session.
451 ; sysinh - help for system-dependent special functions.
452 ; called in response to <escape>?, after listing all the
453 ; system-independent escape sequences.
460 ; Additional, system-dependent help for transparent mode
461 ; (two-character escape sequences)
463 db cr,lf,'B Transmit a BREAK (0.3s)'
464 db cr,lf,'L Transmit a LONG BREAK (1.8s)'
465 db '$' ; string terminator
469 ; sysint - system dependent special functions
470 ; called when transparent escape character has been typed;
471 ; the second character of the sequence is in A (and in B).
473 ; non-skip: sequence has been processed
474 ; skip: seqence was not recognized
477 and 5FH ; convert lower case to upper, for testing...
478 cp 'B' ; send break ?
479 jr z,sendbr ; then jump to send break routine
480 cp 'L' ; long break ?
481 jr z,longbr ; then jump to long break routine
482 jp rskp ; take skip return - command not recognised
488 ld e,180 ; time for long break is 1800 ms
492 ld e,25 ; time for break is 300 ms
496 set 6,a ; Break contol bit
499 ; Now, delay for duration of hangup or break
503 ; Time's up. Put transmitter back in normal state and return.
506 res 6,a ; Break contol bit
512 ; sysflt - system-dependent filter
513 ; called with character in E.
514 ; if this character should not be printed, return with A = zero.
515 ; preserves bc, de, hl.
516 ; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
519 mov a,e ; get character for testing
523 ; mdmflt - modem filter
524 ; called with character to be sent to printer in E
525 ; with parity set as appropriate.
526 ; return with accumulator = 0 do do nothing,
527 ; <> 0 to send char in E.
529 mov a,e ; get character to test
533 ; prtflt - printer filter
534 ; called with character to be sent to printer in E
535 ; returns with a = 0 to do nothing
536 ; a <> 0 to print it.
538 ; this routine for those printer that automatically insert
539 ; a lf on cr, or cr for lf. Should this be shifted to
540 ; the system indep. stuff, in say 4.06?
543 mov a,e ; get character to test
545 IF FALSE ; strip out lf from printer stream
546 ani 7fh ; make sure it is parity less
547 cpi lf ; is it a line feed?
549 ; xra a ; yes, don't.
556 ; system-dependent processing for BYE command.
562 ; This is the system-dependent command to change the baud rate.
563 ; DE contains the two-byte value from the baud rate table; both
564 ; bytes of this value are also stored in 'speed'.
582 in a,(I2C_UART_MSR) ;Clear Modem Status Register
583 in a,(I2C_UART_LSR) ;Clear Line Status Register
584 in a,(I2C_UART_RHR) ;Clear Receiver Buffers
589 db (sysspd_tab_end - ($+1))/2
590 db I2C_UART_LCR, DLAB+03H ;Set devisor latch access bit
593 ds 1 ;1200 bit/s at 1.832 MHz
596 ds 1 ;Out to the MSB divisor port
597 db I2C_UART_LCR, 03H ;Disable Divisor Access Latch
598 db I2C_UART_FCR, 07H ;Clear and enable fifos
599 db I2C_UART_MCR, 00H ;Enable loopback
600 db I2C_UART_IER, 0 ;Set no interrupts
607 ; (Note that speed tables MUST be in alphabetical order for later
608 ; lookup procedures, and must begin with a value showing the total
609 ; number of entries. The speed help tables are just for us poor
612 ; db string length, string, divisor (2 bytes or 1 word, ab)
613 ; the data byte a is return in A and E, and b in D
614 ; only byte 'a' is the key for the table
616 spdtbl: db 15 ; Number of entries
648 sphtbl: db cr,lf,' 75 110 150 300 450 600 1200 2400'
649 db cr,lf,'4800 9600 19200 28800 38400 57600 115200$'
652 sphtbl: db cr,lf,' 110 300 600 2400 9600 28800 57600'
653 db cr,lf,' 75 150 450 1200 4800 19200 38400 115200$'
657 ; This is the system-dependent SET PORT command.
658 ; HL contains the argument from the command table.
663 prttbl EQU 0 ; SET PORT is not supported
667 ; selmdm - select modem port
668 ; selcon - select console port
669 ; selmdm is called before using inpmdm or outmdm;
670 ; selcon is called before using inpcon or outcon.
671 ; For iobyt systems, diddle the I/O byte to select console or comm port;
672 ; For the rest, does nothing.
673 ; preserves bc, de, hl.
682 ; Get character from console, or return zero.
683 ; result is returned in A. destroys bc, de, hl.
686 ld c,dconio ;Direct console I/O BDOS call.
693 ; Output character in E to the console.
694 ; destroys bc, de, hl
697 ld c,dconio ;Console output bdos call.
698 call bdos ;Output the char to the console.
703 ; outmdm - output a char from E to the modem.
704 ; the parity bit has been set as necessary.
705 ; returns nonskip; bc, de, hl preserved.
710 ld (hl),e ;save char in buffer
717 jr nc,omflush_1 ;buffer full
740 in a,(I2C_UART_TXLVL)
750 ld a,2 ;start write transaction
753 ld hl,outbuf+2 ;buffer start
755 sub c ;buffer now empty?
759 push de ;no, shift remaining chars down
760 ld d,h ;dest = buffer start
763 add hl,bc ;src = buffer start + num chars last transmitted
775 ; get character from modem; return zero if none available.
776 ; for IOBYT systems, the modem port has already been selected.
777 ; destroys bc, de, hl.
780 ld a,(inpcnt) ;any buffered chars?
782 jp m,imdrdi2c ;no, buffer empty
783 ld (inpcnt),a ;save updated buffer counter
785 ld a,(hl) ;return buffered char
787 ld (inpptr),hl ;save buffer pointer
791 in a,(I2C_UART_RXLVL) ;get rx fifo count
793 ret z ;fifo is empty, return 0
796 inc a ;+ slave address
800 ld (hl),0 ;select subaddr 0 (RHR) for next read
801 ld a,3 ;write 1 byte (subaddr.), then read fifo
803 in a,(VI2C_CTRL) ;get i2c result
805 and 11h ;transfer completed?
807 in a,(VI2C_BLEN) ;get actual transfer count
809 sub 2 ;- (slave address + char to return now)
811 ld (inpcnt),a ;save new buffer count
814 ld (inpptr),hl ;save buffer pointer
823 ; flsmdm - flush comm line.
825 ; Currently, just gets characters until none are available.
828 call inpmdm ; Try to get a character
830 jnz flsmdm ; If so, try for another
831 ret ; Receiver is drained. Return.
835 ; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
838 call bprtst ; get status
841 xra a ; assume it is ok.. this may not be necessary
845 ; outlpt - output character in E to printer
846 ; console is selected.
850 push d ; save DE in either case
851 call prtflt ; go through printer filter [30]
852 ana a ; if A = 0 do nothing,
853 jz outlp1 ; if a=0 do nothing
855 outlp1: pop d ; restore saved register pair
858 ; delchr - make delete look like a backspace. Unless delete is a printing
859 ; character, we just need to print a backspace. (we'll output clrspc
863 mvi e,bs ;get a backspace
866 ; erase the character at the current cursor position
869 mvi e,bs ;get a backspace
872 ; erase the current line
876 ; erase the whole screen, and go home. preserves b (but not c)
880 ;----------------------------------------------------------------------
882 sysver: db 'AVR-CP/M'
885 ;----------------------------------------------------------------------
904 ;----------------------------------------------------------------------
907 LINK CPXVDU.ASM ; get terminal defs etc