2 ; Christian Groessler, Dec-2001
3 ; converted to driver interface Nov-2013
5 ; RS232 routines using the R: device (currently tested with an 850 only)
8 .include "zeropage.inc"
9 .include "ser-kernel.inc"
10 .include "ser-error.inc"
31 .macro print_string text
34 .macro print_string text
37 @start: .byte text, ATEOL
49 lda #<(@cont - @start)
51 lda #>(@cont - @start)
65 ; ------------------------------------------------------------------------
66 ; Header. Includes jump table
72 .byte $73, $65, $72 ; "ser"
73 .byte SER_API_VERSION ; Serial API version number
94 rdev: .byte "R:", ATEOL, 0
95 bauds: .byte 1 ; SER_BAUD_45_5
98 .byte 5 ; SER_BAUD_110
99 .byte 6 ; SER_BAUD_134_5
100 .byte 7 ; SER_BAUD_150
101 .byte 8 ; SER_BAUD_300
102 .byte 9 ; SER_BAUD_600
103 .byte 10 ; SER_BAUD_1200
104 .byte 11 ; SER_BAUD_1800
105 .byte 12 ; SER_BAUD_2400
106 .byte 0 ; SER_BAUD_3600
107 .byte 13 ; SER_BAUD_4800
108 .byte 0 ; SER_BAUD_7200
109 .byte 14 ; SER_BAUD_9600
110 .byte 0 ; SER_BAUD_19200
111 .byte 0 ; SER_BAUD_38400
112 .byte 0 ; SER_BAUD_57600
113 .byte 0 ; SER_BAUD_115200
114 .byte 0 ; SER_BAUD_230400
115 .byte 0 ; SER_BAUD_31250
116 .byte 0 ; SER_BAUD_62500
117 .byte 3 ; SER_BAUD_56_875
118 num_bauds = * - bauds
120 .byte 48 ; SER_BITS_5
121 .byte 32 ; SER_BITS_6
122 .byte 16 ; SER_BITS_7
124 num_databits = * - databits
126 .byte 0 ; SER_PAR_NONE
127 .byte 4+1 ; SER_PAR_ODD
128 .byte 2+8 ; SER_PAR_EVEN
129 ;.byte 0 ; SER_PAR_MARK
130 ;.byte 0 ; SER_PAR_SPACE
131 num_parities = * - parities
137 recv_buf: .res RECVBUF_SZ
139 cm_run: .res 1 ; concurrent mode running?
145 ; jump table into main program, initialized from libref
183 lda #<SER_ERR_BAUD_UNAVAIL
184 ldx #>SER_ERR_BAUD_UNAVAIL
189 ;----------------------------------------------------------------------------
190 ; SER_OPEN: A pointer to a ser_params structure is passed in ptr1.
191 ; Must return an SER_ERR_xx code in a/x.
197 ; set line parameters
200 jsr my_fdtoiocb ; get iocb index into X
201 bmi openerr ; shouldn't happen
204 ; set baud rate, word size, stop bits and ready monitoring
214 ldy #SER_PARAMS::BAUDRATE
224 ldy #SER_PARAMS::DATABITS
234 ldy #SER_PARAMS::STOPBITS
244 lda #36 ; xio 36, baud rate
247 ;ICAX2 = 0, monitor nothing
256 ; check if the handshake setting is valid
257 ldy #SER_PARAMS::HANDSHAKE
259 cmp #SER_HS_HW ; this is all we support
262 ; set handshake lines
263 lda #34 ; xio 34, set cts, dtr etc
265 lda #192+48+3 ; DTR on, RTS on, XMT on
270 ; set translation and parity
271 ldy #SER_PARAMS::PARITY
278 ora #32 ; no translation
283 lda #38 ; xio 38, translation and parity
292 inverr: jmp my___inviocb
295 ; @@@ need to close IOCB here
296 jsr my_fddecusage ; decrement usage counter of fd as open failed
300 lda #SER_ERR_INIT_FAILED
303 ;---- open the device
309 tay ; move iocb # into Y
311 sta tmp3 ; name length + 1
316 bcs @doopen ; C set: open needed / device not already open
319 jsr SER_CLOSE ;** shut down if started @@@TODO check this out!!
334 lda #$0D ; mode in+out+concurrent
338 sta ICBLL,x ; zap buf len
343 lda tmp2 ; get fd (from newfd)
350 ;----------------------------------------------------------------------------
351 ; CLOSE: Close the port, disable interrupts and flush the buffer. Called
352 ; without parameters. Must return an error code in a/x.
357 print_string "SER_CLOSE called"
364 print_string "SER_CLOSE do work"
375 @done: lda #<SER_ERR_OK
378 print_string "SER_CLOSE returns"
382 ;----------------------------------------------------------------------------
383 ; SER_GET: Will fetch a character from the receive buffer and store it into the
384 ; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
391 bne @work ; work only if initialized
392 lda #SER_ERR_NOT_OPEN
399 lda cm_run ; concurrent mode already running?
401 jsr ena_cm ; turn on concurrent mode
403 @go: ; check whether there is any input available
405 lda #STATIS ; status request, returns bytes pending
410 lda DVSTAT+1 ; get byte count pending
412 beq @nix_da ; no input waiting...
414 ; input is available: get it!
416 lda #GETCHR ; get raw bytes
417 sta ICCOM,x ; in command code
423 jsr my_CIOV ; go get it
427 sta (ptr1,x) ; return received byte
431 @nix_da:lda #SER_ERR_NO_DATA
436 lda #SER_ERR_OVERFLOW ; there is no large selection of serial error codes... :-/
443 ;----------------------------------------------------------------------------
444 ; SER_PUT: Output character in A.
445 ; Must return an error code in a/x.
451 bne @work ; work only if initialized
452 lda #SER_ERR_NOT_OPEN
455 @work: pha ; char to write
464 jsr dump_hex ; dump char to write
469 lda cm_run ; concurrent mode already running?
471 jsr ena_cm ; turn on concurrent mode
473 ; @@@TODO: check output buffer overflow
474 @go: lda #PUTCHR ; put raw bytes
475 sta ICCOM,x ; in command code
481 pla ; get the char back
482 jsr my_CIOV ; go do it
488 ;----------------------------------------------------------------------------
489 ; SER_STATUS: Return the status in the variable pointed to by ptr1.
490 ; Must return an error code in a/x.
494 ; fall through to SER_IOCTL
496 ;----------------------------------------------------------------------------
497 ; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
498 ; specific data in ptr1, and the ioctl code in A.
499 ; Must return an error code in a/x.
503 lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
504 ldx #>SER_ERR_INV_IOCTL
507 ;----------------------------------------------------------------------------
508 ; SER_IRQ: Not used on the Atari
513 ;----------------------------------------------------------------------------
514 ; SER_INSTALL routine. Is called after the driver is loaded into memory. If
515 ; possible, check if the hardware is present.
516 ; Must return an SER_ERR_xx code in a/x.
520 ;print_string "SER_INSTALL with error"
526 ; check if R: device is installed
529 search: lda HATABS,y ; get device name
538 ; R: device not found, return error
540 lda #<SER_ERR_NO_DEVICE
544 ; R: device found, initialize jump table into main program
585 sta my_findfreeiocb+1
588 sta my_findfreeiocb+2
592 sta my___do_oserror+1
595 sta my___do_oserror+2
642 ;----------------------------------------------------------------------------
643 ; SER_UNINSTALL routine. Is called before the driver is removed from memory.
644 ; Must return an SER_ERR_xx code in a/x.
648 print_string "SER_UNINSTALL called"
653 .macro print_string2 addr, len
656 sta ICBAL,x ; address
709 nl_txt_len = * - nl_txt
712 print_string2 nl_txt, nl_txt_len
716 iocb_txt: .byte " IOCB number: "
717 iocb_txt_len = * - iocb_txt
721 print_string2 iocb_txt, iocb_txt_len
725 open_txt: .byte "OPEN"
726 open_txt_len = * - open_txt
730 print_string2 open_txt, open_txt_len
735 put_txt: .byte "PUT "
736 put_txt_len = * - put_txt
740 print_string2 put_txt, put_txt_len
744 aux1_txt: .byte "AUX1: "
745 aux1_txt_len = * - aux1_txt
749 print_string2 aux1_txt,aux1_txt_len
773 ; no need to preserve regs
794 sta ICBAL,x ; address
806 ; ldy #SER_PARAMS::BAUDRATE
820 ; ptr1 - pointer to string buffer
821 ; ptr2 - pointer to rs232 params
873 sta ICBAL,x ; address
886 ; enable concurrent rs232 mode
887 ; gets iocb index in X
888 ; all registers destroyed
892 lda #40 ; XIO 40, start concurrent IO
894 sta cm_run ; indicate concurrent mode is running
906 lda #$0D ; value from 850 man, p62. must be $0D?,
907 sta ICAX1,x ; or any non-zero?
912 ;*****************************************************************************
913 ;* Unterprogramm: HEX16 *
914 ;* Aufgabe: 16-bit Binärzahl in String wandeln (hexadezimal) *
915 ;* Übergabe: ptr1 - Zeiger auf 4-byte Zielpuffer *
916 ;* AX - zu wandelnde Zahl (high X, low A) *
917 ;* Zurück: ptr1 - Zeiger hinter Hexstring *
921 ;* alle Register zerstört *
922 ;*****************************************************************************
932 ;*****************************************************************************
933 ;* Unterprogramm: HEX8 *
934 ;* Aufgabe: 8-bit Binärzahl in String wandeln (hexadezimal) *
935 ;* Übergabe: ptr1 - Zeiger auf 2-byte Zielpuffer *
936 ;* A - zu wandelnde Zahl *
937 ;* Zurück: ptr1 - Zeiger hinter Hexstring *
940 ;* alle Register zerstört *
941 ;*****************************************************************************