]>
Commit | Line | Data |
---|---|---|
b0db0839 L |
1 | IF NOT lasm\r |
2 | .printx * CPXAC.ASM *\r | |
3 | ENDIF ;NOT lasm\r | |
49a5f062 L |
4 | IF lasm\r |
5 | .printx Error: Z80 macro assembler (i.e. M80) required\r | |
6 | END\r | |
7 | ENDIF ;lasm\r | |
b0db0839 L |
8 | ; KERMIT - (Celtic for "FREE")\r |
9 | ;\r | |
10 | ; This is the CP/M-80 implementation of the Columbia University\r | |
11 | ; KERMIT file transfer protocol.\r | |
12 | ;\r | |
13 | ; Version 4.0\r | |
14 | ;\r | |
15 | ; Copyright June 1981,1982,1983,1984,1985\r | |
16 | ; Columbia University\r | |
17 | ;\r | |
18 | ; Originally written by Bill Catchings of the Columbia University Center for\r | |
19 | ; Computing Activities, 612 W. 115th St., New York, NY 10025.\r | |
20 | ;\r | |
21 | ; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,\r | |
22 | ; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many\r | |
23 | ; others.\r | |
24 | ;\r | |
25 | ;\r | |
26 | ;\r | |
27 | \r | |
28 | ;\r | |
29 | ; Keep module name, edit number, and last revision date in memory.\r | |
30 | ;\r | |
49a5f062 | 31 | family: db 'CPXCA.ASM (1) 3-DEC-2015$' ; First entry for V4.11\r |
b0db0839 L |
32 | \r |
33 | ;\r | |
34 | ; Assembly time message to let me know I'm building the right version.\r | |
35 | ;\r | |
36 | \r | |
37 | .printx * Assembling Kermit-80 for AVR-CP/M *\r | |
38 | \r | |
39 | \r | |
40 | \r | |
41 | SC16IS740_ADDR equ 90H ;SC16IS740 I2C address. (8bit, A0=VDD, A1=VDD)\r | |
42 | OUTSIZE equ 64\r | |
43 | \r | |
49a5f062 L |
44 | VERSION_MIN equ 0304H ;Minimum AVR-CP/M firmware version required\r |
45 | \r | |
b0db0839 L |
46 | ; Virtual I2C Interface\r |
47 | \r | |
48 | VI2C_STAT equ 05h\r | |
49 | VI2C_CTRL equ 05h\r | |
50 | VI2C_BLEN equ 06h\r | |
51 | VI2C_ADR equ 07h\r | |
52 | VI2C_BSIZ equ 66 ;largest message size including address byte (SLA)\r | |
53 | \r | |
54 | ;----------------------------- ISC16IS740 UART -------------------------------\r | |
55 | I2C_UART_PORT equ 50H\r | |
56 | \r | |
57 | I2C_UART_RHR equ I2C_UART_PORT+00H ;R Receive Holding\r | |
58 | I2C_UART_THR equ I2C_UART_PORT+00H ;W Transmit Holding\r | |
59 | I2C_UART_IER equ I2C_UART_PORT+01H ;R/W Interrupt Enable\r | |
60 | I2C_UART_FCR equ I2C_UART_PORT+02H ;W FIFO Control\r | |
61 | TX_FIFO_RES equ 04H ; TX FIFO reset\r | |
62 | RX_FIFO_RES equ 02H ; RX FIFO reset\r | |
63 | FIFO_ENABLE equ 01H ; FIFO enable\r | |
64 | \r | |
65 | I2C_UART_IIR equ I2C_UART_PORT+02H ;R Interrupt Identification\r | |
66 | I2C_UART_LCR equ I2C_UART_PORT+03H ;R/W Line Control\r | |
67 | DLAB equ 80H ; Devisor latch enable\r | |
68 | WLS0 equ 01H ; Word Length Select Bit 0\r | |
69 | WLS1 equ 02H ; Word Length Select Bit 1 for 8 bit word\r | |
70 | STB equ 04H ; Stop bit count - 2 stop bits\r | |
71 | \r | |
72 | I2C_UART_MCR equ I2C_UART_PORT+04H ;R/W Modem Control\r | |
73 | RTS equ 02H ;RTS pin, 1 = active (low)\r | |
74 | DTR equ 01H ;DTR pin (not on '740)\r | |
75 | I2C_UART_LSR equ I2C_UART_PORT+05H ;R Line Status\r | |
76 | TXE equ 40H ; THR and TSR empty\r | |
77 | TXRDY equ 20H ; THR empty\r | |
78 | RX_FE equ 08H ; Framig error\r | |
79 | RX_PE equ 04H ; Parity error\r | |
80 | RX_OE equ 02H ; Overrun error\r | |
81 | RXRDY equ 01H ; Receved byte available\r | |
82 | I2C_UART_MSR equ I2C_UART_PORT+06H ;R Modem Status\r | |
83 | I2C_UART_SPR equ I2C_UART_PORT+07H ;R/W Scratchpad\r | |
84 | I2C_UART_TCR equ I2C_UART_PORT+06H ;R/W Transmission Control\r | |
85 | I2C_UART_TLR equ I2C_UART_PORT+07H ;R/W Trigger Level\r | |
86 | I2C_UART_TXLVL equ I2C_UART_PORT+08H ;R Transmit FIFO Level\r | |
87 | I2C_UART_RXLVL equ I2C_UART_PORT+09H ;R Receive FIFO Level\r | |
88 | I2C_UART_EFCR equ I2C_UART_PORT+0FH ;R/W Extra Features\r | |
89 | I2C_UART_DLL equ I2C_UART_PORT+00H ;R/W divisor latch LSB\r | |
90 | I2C_UART_DLH equ I2C_UART_PORT+01H ;R/W divisor latch MSB\r | |
91 | I2C_UART_EFR equ I2C_UART_PORT+02H ;R/W Enhanced Feature\r | |
92 | I2C_UART_XON1 equ I2C_UART_PORT+04H ;R/W Xon1 word\r | |
93 | I2C_UART_XON2 equ I2C_UART_PORT+05H ;R/W Xon2 word\r | |
94 | I2C_UART_XOFF1 equ I2C_UART_PORT+06H ;R/W Xoff1 word\r | |
95 | I2C_UART_XOFF2 equ I2C_UART_PORT+07H ;R/W Xoff2 word\r | |
96 | \r | |
97 | \r | |
b0db0839 L |
98 | z80 set TRUE ;This one emulates an Z80.\r |
99 | \r | |
b0db0839 | 100 | .z80\r |
49a5f062 L |
101 | ;----------------------------------------------------------------------\r |
102 | ; Macros\r | |
103 | ;----------------------------------------------------------------------\r | |
104 | \r | |
105 | ; make a message table\r | |
106 | ; usage:\r | |
107 | ; label: mkmsgtab <msg0,msg1,msg2,...>\r | |
108 | \r | |
109 | mkm_tab macro x\r | |
110 | n?msg defl 0\r | |
111 | irp y,<x>\r | |
112 | n?msg defl n?msg+1\r | |
113 | endm\r | |
114 | db n?msg\r | |
115 | irp y,<x>\r | |
116 | db '&y','$'\r | |
117 | endm\r | |
118 | endm\r | |
119 | \r | |
120 | ; make a message table\r | |
121 | ; usage:\r | |
122 | ; label: mkmsgtab <msg0,msg1,msg2,...>\r | |
123 | \r | |
124 | mkms_tab macro x\r | |
125 | n?msg defl 0\r | |
126 | irp y,<x>\r | |
127 | n?msg defl n?msg+1\r | |
128 | endm\r | |
129 | db n?msg\r | |
130 | irp y,<x>\r | |
131 | ifnb <y>\r | |
132 | db y,'$'\r | |
133 | else\r | |
134 | db '$'\r | |
135 | endif\r | |
136 | endm\r | |
137 | endm\r | |
138 | \r | |
139 | ;----------------------------------------------------------------------\r | |
140 | ; Messages\r | |
141 | ;----------------------------------------------------------------------\r | |
142 | \r | |
143 | umsg_tab:\r | |
144 | ; 0 1 2 3 4 5\r | |
145 | mkms_tab <'UART',,' not', ' detected',', crystal frequency: ','!'>\r | |
146 | \r | |
147 | fmsg_tab:\r | |
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>\r | |
149 | fdim_msg:\r | |
150 | db ' MHz.',cr,lf,'$'\r | |
151 | fw_msg:\r | |
152 | db 'AVR firmware to old, at least version 3.4 neded.','$'\r | |
153 | exit_msg:\r | |
154 | db cr,lf,'Exiting!',cr,lf,'$'\r | |
155 | \r | |
156 | ;----------------------------------------------------------------------\r | |
157 | ; Utilities\r | |
158 | ;----------------------------------------------------------------------\r | |
159 | \r | |
160 | ; Print message from table\r | |
161 | ;\r | |
162 | ; hl: message table address\r | |
163 | ; first byte is number of table entries\r | |
164 | ; a: number of message to print (0 based, index in table)\r | |
165 | ;\r | |
166 | ; If index is out of range, print message #0\r | |
167 | \r | |
168 | pdecoded:\r | |
169 | push bc\r | |
170 | push de\r | |
171 | push hl\r | |
172 | ld bc,0\r | |
173 | cp (hl) ; number of messages in table\r | |
174 | jr c,pdc_1\r | |
175 | ld a,c\r | |
176 | pdc_1:\r | |
177 | inc hl\r | |
178 | ld e,a\r | |
179 | ld a,'$'\r | |
180 | inc e\r | |
181 | jr pdc_2\r | |
182 | pdc_nxt_str:\r | |
183 | cpir\r | |
184 | pdc_2:\r | |
185 | dec e\r | |
186 | jr nz,pdc_nxt_str\r | |
187 | ex de,hl\r | |
188 | call prtstr\r | |
189 | pop hl\r | |
190 | pop de\r | |
191 | pop bc\r | |
192 | ret\r | |
193 | \r | |
194 | ;----------------------------------------------------------------------\r | |
195 | ; output bytes to ports\r | |
196 | ;\r | |
197 | ; hl: tables of port,value pairs:\r | |
198 | ; db n ;number of pairs\r | |
199 | ; db port1,val1, port2,val2,... portn,valn\r | |
200 | ; ...\r | |
201 | ; db 0 ; Terminate table\r | |
202 | \r | |
203 | ioinil:\r | |
204 | push bc\r | |
205 | ld b,(hl) ;count\r | |
206 | inc hl\r | |
207 | io1_lp:\r | |
208 | ld c,(hl) ;port address\r | |
209 | inc hl\r | |
210 | outi\r | |
211 | jr nz,io1_lp\r | |
212 | pop bc\r | |
213 | ret\r | |
214 | \r | |
215 | ;----------------------------------------------------------------------\r | |
216 | \r | |
217 | vi2c_setup_chk:\r | |
218 | ld hl,chkbuf\r | |
219 | vi2c_setup:\r | |
220 | out (VI2C_BLEN),a\r | |
221 | ld a,h\r | |
222 | out (VI2C_ADR+1),a\r | |
223 | ld a,l\r | |
224 | out (VI2C_ADR+0),a\r | |
225 | ret\r | |
226 | \r | |
227 | ;----------------------------------------------------------------------\r | |
228 | \r | |
229 | prspeedmsg:\r | |
230 | ld hl,fmsg_tab\r | |
231 | call pdecoded\r | |
232 | ld de,fdim_msg\r | |
233 | call prtstr\r | |
234 | ret\r | |
235 | \r | |
236 | ;----------------------------------------------------------------------\r | |
237 | ;\r | |
238 | ;----------------------------------------------------------------------\r | |
239 | \r | |
240 | fw_check:\r | |
241 | ld bc,000CH ;\r | |
242 | out (c),b ;write 0 to version port\r | |
243 | in a,(c)\r | |
244 | cp 1 ;result should be 0\r | |
245 | ret nc ;exit (a != 0) if it wasn't\r | |
246 | inc b\r | |
247 | out (c),b\r | |
248 | in h,(c) ;get MAJOR\r | |
249 | inc b\r | |
250 | out (c),b\r | |
251 | in l,(c) ;get MINOR\r | |
252 | ld de,VERSION_MIN\r | |
253 | xor a ;clear carry\r | |
254 | sbc hl,de\r | |
255 | sbc a,a ;z if hl >= VERSION_MIN\r | |
256 | ret\r | |
257 | \r | |
258 | ;----------------------------------------------------------------------\r | |
259 | \r | |
260 | uart_check:\r | |
261 | ld a,3 ;2 byte + SLA\r | |
262 | call vi2c_setup_chk\r | |
263 | ld a,2 ;write cmd\r | |
264 | out (VI2C_CTRL),a\r | |
265 | uc_0:\r | |
266 | in a,(VI2C_CTRL) ;do: get i2c result\r | |
267 | bit 7,a ;\r | |
268 | jr nz,uc_0 ;while busy\r | |
269 | cp 0FH\r | |
270 | jr nz,uc_err ;error in transaction\r | |
271 | in a,(VI2C_BLEN)\r | |
272 | cp 3\r | |
273 | jr nz,uc_err\r | |
274 | \r | |
275 | inc hl\r | |
276 | inc hl\r | |
277 | in a,(I2C_UART_SPR)\r | |
278 | cp (hl)\r | |
279 | jr nz,uc_err\r | |
280 | ld (hl),42H\r | |
281 | ld a,2\r | |
282 | out (VI2C_CTRL),a\r | |
283 | in a,(I2C_UART_SPR)\r | |
284 | cp (hl)\r | |
285 | jr nz,uc_err\r | |
286 | xor a\r | |
287 | jr uc_1\r | |
288 | uc_err:\r | |
289 | ld a,1\r | |
290 | uc_1:\r | |
291 | ld c,a\r | |
292 | ld hl,umsg_tab\r | |
293 | xor a\r | |
294 | call pdecoded\r | |
295 | ld a,1\r | |
296 | add a,c\r | |
297 | call pdecoded\r | |
298 | ld a,3\r | |
299 | call pdecoded\r | |
300 | ld a,4\r | |
301 | add a,c\r | |
302 | call pdecoded\r | |
303 | ld a,c\r | |
304 | or a\r | |
305 | ret\r | |
306 | \r | |
307 | ;----------------------------------------------------------------------\r | |
308 | \r | |
309 | chkbuf:\r | |
310 | db SC16IS740_ADDR\r | |
311 | db (I2C_UART_SPR - I2C_UART_PORT) shl 3 ;address of scratch pad register\r | |
312 | db 5AH\r | |
313 | \r | |
314 | ;----------------------------------------------------------------------\r | |
315 | \r | |
316 | speedtest:\r | |
317 | ld hl,spt_tab ;init UART in loop back mode\r | |
318 | call ioinil ; and fill tx fifo with 60 chars\r | |
319 | \r | |
320 | in a,(I2C_UART_MSR) ;Clear Modem Status Register\r | |
321 | in a,(I2C_UART_LSR) ;Clear Line Status Register\r | |
322 | in a,(I2C_UART_RHR) ;Clear Receiver Buffers\r | |
323 | in a,(I2C_UART_RHR)\r | |
324 | \r | |
325 | ld a,2 ;start write transaction\r | |
326 | out (VI2C_CTRL),a\r | |
327 | \r | |
328 | ; get time stamp\r | |
329 | in a,(41H) ;lsb ms\r | |
330 | ld e,a\r | |
331 | in a,(42H) ;msb ms\r | |
332 | ld d,a\r | |
333 | in a,(43H) ;lsb seconds\r | |
334 | ld c,a\r | |
335 | \r | |
336 | spt_1:\r | |
337 | in a,(I2C_UART_RXLVL) ;wait till all 60 char in rx fifo\r | |
338 | cp 60\r | |
339 | jr nz,spt_1\r | |
340 | \r | |
341 | ; get 2nd time stamp\r | |
342 | in a,(41H) ;lsb ms\r | |
343 | ld l,a\r | |
344 | in a,(42H) ;msb ms\r | |
345 | ld h,a\r | |
346 | in a,(43H) ;lsb seconds\r | |
347 | sub c ;seconds diff\r | |
348 | jr z,spt_3\r | |
349 | ld bc,1000\r | |
350 | spt_2: ;convert s to ms\r | |
351 | add hl,bc\r | |
352 | dec a\r | |
353 | jr nz,spt_2\r | |
354 | spt_3:\r | |
355 | sbc hl,de ;hl = elapsed time (ms) for 60 chars\r | |
356 | ld d,h\r | |
357 | ld e,l\r | |
358 | inc hl\r | |
359 | srl h\r | |
360 | rr l\r | |
361 | ld bc,500\r | |
362 | add hl,bc\r | |
363 | \r | |
364 | xor a ;clear carry\r | |
365 | spt_4:\r | |
366 | inc a\r | |
367 | sbc hl,de\r | |
368 | jr nc,spt_4\r | |
369 | dec a\r | |
370 | ret\r | |
371 | \r | |
372 | spt_tab:\r | |
373 | db (spt_tab_end - ($+1))/2\r | |
374 | db I2C_UART_LCR, DLAB+03H ;Set devisor latch access bit\r | |
375 | db I2C_UART_DLL, low 96 ;1200 bit/s at 1.832 MHz\r | |
376 | db I2C_UART_DLH, high 96 ;Out to the MSB divisor port\r | |
377 | db I2C_UART_LCR, 03H ;Disable Divisor Access Latch\r | |
378 | db I2C_UART_FCR, 07H ;Clear and enable fifos\r | |
379 | db I2C_UART_MCR, 10H ;Enable loopback\r | |
380 | db I2C_UART_IER, 0 ;Set no interrupts\r | |
381 | db VI2C_ADR+0, low outbuf\r | |
382 | db VI2C_ADR+1, high outbuf\r | |
383 | db VI2C_BLEN, 60+2\r | |
384 | spt_tab_end:\r | |
385 | \r | |
386 | ;----------------------------------------------------------------------\r | |
387 | ;\r | |
388 | ;----------------------------------------------------------------------\r | |
b0db0839 L |
389 | \r |
390 | sysxin: ; continuation of system initialisation from sysinit\r | |
391 | \r | |
49a5f062 L |
392 | call fw_check\r |
393 | jr nz,si_exit_f\r | |
394 | call uart_check\r | |
395 | jr nz,si_exit\r | |
b0db0839 | 396 | call speedtest\r |
49a5f062 | 397 | ld (clk_div),a\r |
b0db0839 L |
398 | call prspeedmsg\r |
399 | \r | |
400 | ld hl,6 ;set default baud rate\r | |
401 | ld (speed),hl\r | |
402 | ex de,hl\r | |
403 | call sysspd\r | |
404 | \r | |
405 | ld a,RTS+DTR\r | |
406 | out (I2C_UART_MCR),a\r | |
407 | ret\r | |
408 | \r | |
49a5f062 L |
409 | si_exit_f:\r |
410 | ld de,fw_msg\r | |
b0db0839 | 411 | call prtstr\r |
49a5f062 L |
412 | si_exit:\r |
413 | ld de,exit_msg\r | |
b0db0839 | 414 | call prtstr\r |
49a5f062 | 415 | jp 0\r |
b0db0839 L |
416 | \r |
417 | \r | |
49a5f062 L |
418 | ; ld a,07H ;Enable and clear fifos\r |
419 | ; out (I2C_UART_FCR),a ;\r | |
420 | ; ld a,03H ;8N1\r | |
421 | ; out (I2C_UART_LCR),a ;\r | |
b0db0839 L |
422 | \r |
423 | \r | |
424 | ;\r | |
425 | ; system-dependent KERMIT termination processing\r | |
426 | ; If we've changed anything, this is our last chance to put it back.\r | |
427 | ;\r | |
428 | sysexit:\r | |
429 | ret\r | |
430 | \r | |
431 | ;\r | |
432 | ; system-dependent processing for start of CONNECT command\r | |
433 | ;\r | |
434 | syscon:\r | |
435 | ret\r | |
436 | \r | |
437 | conmsg: ; Messages printed when entering transparent (CONNECT) mode:\r | |
438 | \r | |
439 | db '$'\r | |
440 | \r | |
441 | ;\r | |
442 | ; syscls - system-dependent close routine\r | |
443 | ; called when exiting transparent session.\r | |
444 | ;\r | |
445 | syscls:\r | |
446 | ret\r | |
447 | \r | |
448 | .8080\r | |
449 | \r | |
450 | ;\r | |
451 | ; sysinh - help for system-dependent special functions.\r | |
452 | ; called in response to <escape>?, after listing all the\r | |
453 | ; system-independent escape sequences.\r | |
454 | ;\r | |
455 | sysinh:\r | |
456 | lxi d, inhlps\r | |
457 | call prtstr\r | |
458 | ret\r | |
459 | \r | |
460 | ; Additional, system-dependent help for transparent mode\r | |
461 | ; (two-character escape sequences)\r | |
462 | inhlps:\r | |
463 | db cr,lf,'B Transmit a BREAK (0.3s)'\r | |
464 | db cr,lf,'L Transmit a LONG BREAK (1.8s)'\r | |
465 | db '$' ; string terminator\r | |
466 | \r | |
467 | .z80\r | |
468 | ;\r | |
469 | ; sysint - system dependent special functions\r | |
470 | ; called when transparent escape character has been typed;\r | |
471 | ; the second character of the sequence is in A (and in B).\r | |
472 | ; returns:\r | |
473 | ; non-skip: sequence has been processed\r | |
474 | ; skip: seqence was not recognized\r | |
475 | ;\r | |
476 | sysint:\r | |
477 | and 5FH ; convert lower case to upper, for testing...\r | |
478 | cp 'B' ; send break ?\r | |
479 | jr z,sendbr ; then jump to send break routine\r | |
480 | cp 'L' ; long break ?\r | |
481 | jr z,longbr ; then jump to long break routine\r | |
482 | jp rskp ; take skip return - command not recognised\r | |
483 | \r | |
484 | ;\r | |
485 | ; Break routines\r | |
486 | ;\r | |
487 | longbr:\r | |
488 | ld e,180 ; time for long break is 1800 ms\r | |
489 | jr setbit\r | |
490 | \r | |
491 | sendbr:\r | |
492 | ld e,25 ; time for break is 300 ms\r | |
493 | \r | |
494 | setbit:\r | |
495 | in a,(I2C_UART_LCR)\r | |
496 | set 6,a ; Break contol bit\r | |
497 | out (I2C_UART_LCR),a\r | |
498 | ;\r | |
499 | ; Now, delay for duration of hangup or break\r | |
500 | ld a,e ; delay count\r | |
501 | call delay\r | |
502 | ;\r | |
503 | ; Time's up. Put transmitter back in normal state and return.\r | |
504 | \r | |
505 | in a,(I2C_UART_LCR)\r | |
506 | res 6,a ; Break contol bit\r | |
507 | out (I2C_UART_LCR),a\r | |
508 | ret ; done.\r | |
509 | \r | |
510 | .8080\r | |
511 | ;\r | |
512 | ; sysflt - system-dependent filter\r | |
513 | ; called with character in E.\r | |
514 | ; if this character should not be printed, return with A = zero.\r | |
515 | ; preserves bc, de, hl.\r | |
516 | ; note: <xon>,<xoff>,<del>, and <nul> are always discarded.\r | |
517 | ;\r | |
518 | sysflt:\r | |
519 | mov a,e ; get character for testing\r | |
520 | ret\r | |
521 | \r | |
522 | ;\r | |
523 | ; mdmflt - modem filter\r | |
524 | ; called with character to be sent to printer in E\r | |
525 | ; with parity set as appropriate.\r | |
526 | ; return with accumulator = 0 do do nothing,\r | |
527 | ; <> 0 to send char in E.\r | |
528 | mdmflt:\r | |
529 | mov a,e ; get character to test\r | |
530 | ret\r | |
531 | \r | |
532 | ;\r | |
533 | ; prtflt - printer filter\r | |
534 | ; called with character to be sent to printer in E\r | |
535 | ; returns with a = 0 to do nothing\r | |
536 | ; a <> 0 to print it.\r | |
537 | ;\r | |
538 | ; this routine for those printer that automatically insert\r | |
539 | ; a lf on cr, or cr for lf. Should this be shifted to\r | |
540 | ; the system indep. stuff, in say 4.06?\r | |
541 | ;\r | |
542 | prtflt:\r | |
543 | mov a,e ; get character to test\r | |
544 | \r | |
545 | IF FALSE ; strip out lf from printer stream\r | |
546 | ani 7fh ; make sure it is parity less\r | |
547 | cpi lf ; is it a line feed?\r | |
548 | rnz ; no, print it\r | |
549 | ; xra a ; yes, don't.\r | |
550 | \r | |
551 | ENDIF\r | |
552 | \r | |
553 | ret\r | |
554 | \r | |
555 | ;\r | |
556 | ; system-dependent processing for BYE command.\r | |
557 | ;\r | |
558 | sysbye:\r | |
559 | ret\r | |
560 | \r | |
561 | ;\r | |
562 | ; This is the system-dependent command to change the baud rate.\r | |
563 | ; DE contains the two-byte value from the baud rate table; both\r | |
564 | ; bytes of this value are also stored in 'speed'.\r | |
565 | ;\r | |
566 | .z80\r | |
567 | sysspd:\r | |
568 | ld hl,0\r | |
569 | ld a,(clk_div)\r | |
570 | ld b,a\r | |
571 | sysspd_1:\r | |
572 | add hl,de\r | |
573 | djnz sysspd_1\r | |
574 | ld a,l\r | |
575 | ld (sysspd_dll),a\r | |
576 | ld a,h\r | |
577 | ld (sysspd_dlh),a\r | |
578 | \r | |
579 | ld hl,sysspd_tab\r | |
580 | call ioinil\r | |
581 | \r | |
582 | in a,(I2C_UART_MSR) ;Clear Modem Status Register\r | |
583 | in a,(I2C_UART_LSR) ;Clear Line Status Register\r | |
584 | in a,(I2C_UART_RHR) ;Clear Receiver Buffers\r | |
585 | in a,(I2C_UART_RHR)\r | |
586 | ret\r | |
587 | \r | |
588 | sysspd_tab:\r | |
589 | db (sysspd_tab_end - ($+1))/2\r | |
590 | db I2C_UART_LCR, DLAB+03H ;Set devisor latch access bit\r | |
591 | db I2C_UART_DLL\r | |
592 | sysspd_dll:\r | |
593 | ds 1 ;1200 bit/s at 1.832 MHz\r | |
594 | db I2C_UART_DLH\r | |
595 | sysspd_dlh:\r | |
596 | ds 1 ;Out to the MSB divisor port\r | |
597 | db I2C_UART_LCR, 03H ;Disable Divisor Access Latch\r | |
598 | db I2C_UART_FCR, 07H ;Clear and enable fifos\r | |
599 | db I2C_UART_MCR, 00H ;Enable loopback\r | |
600 | db I2C_UART_IER, 0 ;Set no interrupts\r | |
601 | sysspd_tab_end:\r | |
602 | \r | |
603 | \r | |
604 | \r | |
605 | ;\r | |
606 | ; Speed tables\r | |
607 | ; (Note that speed tables MUST be in alphabetical order for later\r | |
608 | ; lookup procedures, and must begin with a value showing the total\r | |
609 | ; number of entries. The speed help tables are just for us poor\r | |
610 | ; humans.\r | |
611 | ;\r | |
612 | ; db string length, string, divisor (2 bytes or 1 word, ab)\r | |
613 | ; the data byte a is return in A and E, and b in D\r | |
614 | ; only byte 'a' is the key for the table\r | |
615 | \r | |
616 | spdtbl: db 15 ; Number of entries\r | |
617 | db 3,'110$'\r | |
618 | dw 1047\r | |
619 | db 6,'115200$'\r | |
620 | dw 1\r | |
621 | db 4,'1200$'\r | |
622 | dw 96\r | |
623 | db 3,'150$'\r | |
624 | dw 768\r | |
625 | db 5,'19200$'\r | |
626 | dw 6\r | |
627 | db 4,'2400$'\r | |
628 | dw 48\r | |
629 | db 5,'28800$'\r | |
630 | dw 5\r | |
631 | db 3,'300$'\r | |
632 | dw 384\r | |
633 | db 5,'38400$'\r | |
634 | dw 3\r | |
635 | db 3,'450$'\r | |
49a5f062 | 636 | dw 256\r |
b0db0839 L |
637 | db 4,'4800$'\r |
638 | dw 24\r | |
639 | db 5,'57600$'\r | |
640 | dw 2\r | |
641 | db 3,'600$'\r | |
642 | dw 192\r | |
643 | db 2,'75$'\r | |
644 | dw 1536\r | |
645 | db 4,'9600$'\r | |
646 | dw 12\r | |
647 | IF 0\r | |
648 | sphtbl: db cr,lf,' 75 110 150 300 450 600 1200 2400'\r | |
649 | db cr,lf,'4800 9600 19200 28800 38400 57600 115200$'\r | |
650 | ENDIF\r | |
651 | \r | |
652 | sphtbl: db cr,lf,' 110 300 600 2400 9600 28800 57600'\r | |
653 | db cr,lf,' 75 150 450 1200 4800 19200 38400 115200$'\r | |
654 | \r | |
655 | \r | |
b0db0839 L |
656 | ;\r |
657 | ; This is the system-dependent SET PORT command.\r | |
658 | ; HL contains the argument from the command table.\r | |
659 | ;\r | |
660 | sysprt:\r | |
661 | ret\r | |
662 | \r | |
663 | prttbl EQU 0 ; SET PORT is not supported\r | |
664 | prhtbl EQU 0\r | |
665 | \r | |
666 | ;\r | |
667 | ; selmdm - select modem port\r | |
668 | ; selcon - select console port\r | |
669 | ; selmdm is called before using inpmdm or outmdm;\r | |
670 | ; selcon is called before using inpcon or outcon.\r | |
671 | ; For iobyt systems, diddle the I/O byte to select console or comm port;\r | |
672 | ; For the rest, does nothing.\r | |
673 | ; preserves bc, de, hl.\r | |
674 | ;\r | |
675 | selmdm:\r | |
676 | ret\r | |
677 | \r | |
678 | selcon:\r | |
b0db0839 | 679 | jr omflush\r |
b0db0839 L |
680 | \r |
681 | ;\r | |
682 | ; Get character from console, or return zero.\r | |
683 | ; result is returned in A. destroys bc, de, hl.\r | |
684 | ;\r | |
685 | inpcon:\r | |
686 | ld c,dconio ;Direct console I/O BDOS call.\r | |
687 | ld e,0FFH ;Input.\r | |
688 | call BDOS\r | |
689 | \r | |
690 | ret\r | |
691 | \r | |
692 | ;\r | |
693 | ; Output character in E to the console.\r | |
694 | ; destroys bc, de, hl\r | |
695 | ;\r | |
696 | outcon:\r | |
697 | ld c,dconio ;Console output bdos call.\r | |
698 | call bdos ;Output the char to the console.\r | |
699 | \r | |
700 | ret\r | |
701 | \r | |
702 | ;\r | |
703 | ; outmdm - output a char from E to the modem.\r | |
704 | ; the parity bit has been set as necessary.\r | |
705 | ; returns nonskip; bc, de, hl preserved.\r | |
706 | ;\r | |
707 | outmdm:\r | |
b0db0839 L |
708 | push hl\r |
709 | ld hl,(outptr)\r | |
7813a2e4 | 710 | ld (hl),e ;save char in buffer\r |
b0db0839 L |
711 | inc hl\r |
712 | ld (outptr),hl\r | |
713 | ld a,(outcnt)\r | |
714 | inc a\r | |
715 | ld (outcnt),a\r | |
716 | cp OUTSIZE\r | |
717 | jr nc,omflush_1 ;buffer full\r | |
718 | pop hl\r | |
719 | ret\r | |
720 | \r | |
721 | omflush:\r | |
722 | ld a,(outcnt)\r | |
723 | or a\r | |
724 | ret z\r | |
725 | \r | |
726 | scf\r | |
727 | push hl\r | |
728 | omflush_1:\r | |
729 | push bc\r | |
730 | ld c,a ;outcnt\r | |
731 | ld b,a\r | |
732 | jr c,$+4\r | |
733 | ld b,1\r | |
734 | ld hl,outbuf\r | |
735 | ld a,h\r | |
736 | out (VI2C_ADR+1),a\r | |
737 | ld a,l\r | |
738 | out (VI2C_ADR+0),a\r | |
739 | omf_0:\r | |
740 | in a,(I2C_UART_TXLVL)\r | |
741 | cp b\r | |
742 | jr c,omf_0\r | |
743 | cp c\r | |
744 | jr nc,omf_2\r | |
745 | ld c,a\r | |
746 | omf_2:\r | |
747 | ld a,c\r | |
748 | add a,2\r | |
749 | out (VI2C_BLEN),a\r | |
750 | ld a,2 ;start write transaction\r | |
751 | out (VI2C_CTRL),a\r | |
752 | \r | |
7813a2e4 | 753 | ld hl,outbuf+2 ;buffer start\r |
b0db0839 | 754 | ld a,(outcnt)\r |
7813a2e4 | 755 | sub c ;buffer now empty?\r |
b0db0839 L |
756 | ld (outcnt),a\r |
757 | jr z,omfex\r | |
758 | \r | |
7813a2e4 L |
759 | push de ;no, shift remaining chars down\r |
760 | ld d,h ;dest = buffer start\r | |
b0db0839 L |
761 | ld e,l\r |
762 | ld b,0\r | |
7813a2e4 | 763 | add hl,bc ;src = buffer start + num chars last transmitted\r |
b0db0839 L |
764 | ld c,a\r |
765 | ldir\r | |
7813a2e4 | 766 | ex de,hl\r |
b0db0839 L |
767 | pop de\r |
768 | omfex:\r | |
7813a2e4 | 769 | ld (outptr),hl\r |
b0db0839 L |
770 | pop bc\r |
771 | pop hl\r | |
772 | ret\r | |
49a5f062 | 773 | \r |
b0db0839 L |
774 | ;\r |
775 | ; get character from modem; return zero if none available.\r | |
776 | ; for IOBYT systems, the modem port has already been selected.\r | |
777 | ; destroys bc, de, hl.\r | |
778 | ;\r | |
779 | inpmdm:\r | |
49a5f062 | 780 | ld a,(inpcnt) ;any buffered chars?\r |
b0db0839 | 781 | dec a\r |
49a5f062 L |
782 | jp m,imdrdi2c ;no, buffer empty\r |
783 | ld (inpcnt),a ;save updated buffer counter\r | |
b0db0839 | 784 | ld hl,(inpptr)\r |
49a5f062 | 785 | ld a,(hl) ;return buffered char\r |
b0db0839 | 786 | inc hl\r |
49a5f062 | 787 | ld (inpptr),hl ;save buffer pointer\r |
b0db0839 L |
788 | ret\r |
789 | \r | |
790 | imdrdi2c:\r | |
791 | in a,(I2C_UART_RXLVL) ;get rx fifo count\r | |
792 | or a\r | |
793 | ret z ;fifo is empty, return 0\r | |
794 | \r | |
795 | ; prepare fifo read\r | |
796 | inc a ;+ slave address\r | |
b0db0839 | 797 | ld hl,inbuf\r |
49a5f062 | 798 | call vi2c_setup\r |
b0db0839 L |
799 | inc hl\r |
800 | ld (hl),0 ;select subaddr 0 (RHR) for next read\r | |
801 | ld a,3 ;write 1 byte (subaddr.), then read fifo\r | |
49a5f062 | 802 | out (VI2C_CTRL),a\r |
b0db0839 L |
803 | in a,(VI2C_CTRL) ;get i2c result\r |
804 | xor 01h\r | |
805 | and 11h ;transfer completed?\r | |
806 | jr nz,imrdex\r | |
807 | in a,(VI2C_BLEN) ;get actual transfer count\r | |
808 | \r | |
809 | sub 2 ;- (slave address + char to return now)\r | |
810 | jr c,imrdex\r | |
811 | ld (inpcnt),a ;save new buffer count\r | |
812 | ld a,(hl)\r | |
813 | inc hl\r | |
49a5f062 | 814 | ld (inpptr),hl ;save buffer pointer\r |
b0db0839 L |
815 | ret\r |
816 | \r | |
817 | imrdex:\r | |
818 | xor a\r | |
819 | ret\r | |
b0db0839 L |
820 | \r |
821 | .8080\r | |
b0db0839 L |
822 | ;\r |
823 | ; flsmdm - flush comm line.\r | |
824 | ; Modem is selected.\r | |
825 | ; Currently, just gets characters until none are available.\r | |
826 | ;\r | |
827 | flsmdm:\r | |
828 | call inpmdm ; Try to get a character\r | |
829 | ora a ; Got one?\r | |
830 | jnz flsmdm ; If so, try for another\r | |
831 | ret ; Receiver is drained. Return.\r | |
832 | \r | |
833 | \r | |
834 | ;\r | |
835 | ; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.\r | |
836 | lptstat:\r | |
837 | IF iobyte ;[33]\r | |
838 | call bprtst ; get status\r | |
839 | ENDIF ;iobyte[33]\r | |
840 | IF NOT iobyte ;[33]\r | |
841 | xra a ; assume it is ok.. this may not be necessary\r | |
842 | ENDIF ;iobyte [33]\r | |
843 | ret\r | |
844 | ;\r | |
845 | ; outlpt - output character in E to printer\r | |
846 | ; console is selected.\r | |
847 | ; preserves de.\r | |
848 | ;\r | |
849 | outlpt:\r | |
850 | push d ; save DE in either case\r | |
851 | call prtflt ; go through printer filter [30]\r | |
852 | ana a ; if A = 0 do nothing,\r | |
853 | jz outlp1 ; if a=0 do nothing\r | |
854 | \r | |
855 | outlp1: pop d ; restore saved register pair\r | |
856 | ret\r | |
857 | \r | |
858 | ; delchr - make delete look like a backspace. Unless delete is a printing\r | |
859 | ; character, we just need to print a backspace. (we'll output clrspc\r | |
860 | ; afterwards)\r | |
861 | delchr:\r | |
862 | \r | |
863 | mvi e,bs ;get a backspace\r | |
864 | jmp outcon\r | |
865 | \r | |
866 | ; erase the character at the current cursor position\r | |
867 | clrspc: mvi e,' '\r | |
868 | call outcon\r | |
869 | mvi e,bs ;get a backspace\r | |
870 | jmp outcon\r | |
871 | \r | |
872 | ; erase the current line\r | |
873 | clrlin: lxi d,eralin\r | |
874 | jmp prtstr\r | |
875 | \r | |
876 | ; erase the whole screen, and go home. preserves b (but not c)\r | |
877 | clrtop: lxi d,erascr\r | |
878 | jmp prtstr\r | |
879 | \r | |
49a5f062 | 880 | ;----------------------------------------------------------------------\r |
b0db0839 L |
881 | \r |
882 | sysver: db 'AVR-CP/M'\r | |
883 | db '$'\r | |
884 | \r | |
49a5f062 | 885 | ;----------------------------------------------------------------------\r |
b0db0839 L |
886 | \r |
887 | clk_div:\r | |
888 | db 1 ;default div\r | |
889 | \r | |
890 | inpptr: dw 0\r | |
891 | inpcnt: db 0\r | |
892 | inbuf:\r | |
893 | db SC16IS740_ADDR\r | |
894 | ds VI2C_BSIZ-1\r | |
895 | \r | |
896 | \r | |
897 | outptr: dw outbuf+2\r | |
898 | outcnt: db 0\r | |
899 | outbuf:\r | |
900 | db SC16IS740_ADDR\r | |
901 | db 0 ;RHR subaddress\r | |
902 | ds OUTSIZE\r | |
903 | \r | |
49a5f062 | 904 | ;----------------------------------------------------------------------\r |
b0db0839 L |
905 | \r |
906 | IF lasm\r | |
907 | LINK CPXVDU.ASM ; get terminal defs etc\r | |
908 | ENDIF ;lasm\r |