]> git.sur5r.net Git - cc65/commitdiff
Merge pull request #64 from groessler/something_to_pull
authorOliver Schmidt <ol.sc@web.de>
Sat, 7 Dec 2013 15:36:22 +0000 (07:36 -0800)
committerOliver Schmidt <ol.sc@web.de>
Sat, 7 Dec 2013 15:36:22 +0000 (07:36 -0800)
Serial driver for Atari

asminc/ser-error.inc
asminc/ser-kernel.inc
include/serial.h
libsrc/atari/libref.s
libsrc/atari/rs232.s_ [deleted file]
libsrc/atari/ser/atrrdev.s [new file with mode: 0644]
libsrc/atari/ser_libref.s [new file with mode: 0644]
testcode/lib/ser-test.c

index f1592876b617ef7886a3d0fd3a29ff09499d36d0..ff4e2b448b984c58bbc8e321da1e819f0358bd9b 100644 (file)
@@ -48,6 +48,7 @@
         SER_ERR_INIT_FAILED             ; Initialization failed
         SER_ERR_INV_IOCTL               ; IOCTL not supported
         SER_ERR_INSTALLED               ; A driver is already installed
+        SER_ERR_NOT_OPEN                ; Driver not open
 
         SER_ERR_COUNT                   ; Special: Number of error codes
 .endenum
index e59501da6b01ac33b0502b821da9fa46bf9813e2..3ddb7f3006c9cdd9bcefcd681077dc81c104ddb4 100644 (file)
@@ -96,6 +96,7 @@ SER_BAUD_115200         =       $12
 SER_BAUD_230400         =       $13
 SER_BAUD_31250          =       $14
 SER_BAUD_62500          =       $15
+SER_BAUD_56_875         =       $16
 
 ; Data bit settings
 SER_BITS_5              =       $00
index f88ab114eb116cdf1e30b249bfdf1c7b127e3733..cecba90c5d2d5526623175ee08b129e22975e1f8 100644 (file)
@@ -67,6 +67,7 @@
 #define SER_BAUD_230400         0x13
 #define SER_BAUD_31250          0x14
 #define SER_BAUD_62500          0x15
+#define SER_BAUD_56_875         0x16
 
 /* Data bit settings */
 #define SER_BITS_5              0x00
 #define SER_ERR_INIT_FAILED     0x08    /* Initialization failed */
 #define SER_ERR_INV_IOCTL       0x09    /* IOCTL not supported */
 #define SER_ERR_INSTALLED       0x0A    /* A driver is already installed */
+#define SER_ERR_NOT_OPEN        0x0B    /* Driver is not open */
 
 /* Struct containing parameters for the serial port */
 struct ser_params {
index 171bd6de6047ef15374814355d1b5ea5ad06d025..8d96ff62d23d18252cc7f9906c12dcd063563bb9 100644 (file)
@@ -2,11 +2,13 @@
 ; Oliver Schmidt, 2013-05-31
 ;
 
-        .export         em_libref, joy_libref, tgi_libref
+        .export         em_libref, joy_libref, tgi_libref, ser_libref
         .import         _exit
+        .import         atari_ser_libref
 
 em_libref       := _exit
 joy_libref      := _exit
+ser_libref      := atari_ser_libref
 .ifdef __ATARIXL__
         .import CIO_handler
 tgi_libref      := CIO_handler
diff --git a/libsrc/atari/rs232.s_ b/libsrc/atari/rs232.s_
deleted file mode 100644 (file)
index 35f20ca..0000000
+++ /dev/null
@@ -1,389 +0,0 @@
-;
-; Christian Groessler, Dec-2001
-;
-; RS232 routines using the R: device (currently tested with an 850 only)
-;
-; unsigned char __fastcall__ rs232_init (char hacked);
-; unsigned char __fastcall__ rs232_params (unsigned char params, unsigned char parity);
-; unsigned char __fastcall__ rs232_done (void);
-; unsigned char __fastcall__ rs232_get (char* B);
-; unsigned char __fastcall__ rs232_put (char B);
-; unsigned char __fastcall__ rs232_pause (void); [TODO]
-; unsigned char __fastcall__ rs232_unpause (void); [TODO]
-; unsigned char __fastcall__ rs232_status (unsigned char* status,
-;                                          unsigned char* errors); [TODO]
-;
-
-        .import         findfreeiocb
-        .import         __do_oserror
-        .import         fddecusage
-        .import         fdtoiocb
-        .import         __inviocb
-        .import         clriocb
-        .import         newfd
-        .import         _close, pushax, popax, popa
-        .importzp       ptr1, tmp2, tmp3
-
-        .export         _rs232_init, _rs232_params, _rs232_done, _rs232_get
-        .export         _rs232_put, _rs232_pause, _rs232_unpause, _rs232_status
-
-        .include        "atari.inc"
-        .include        "errno.inc"
-        .include        "rs232.inc"
-
-        .rodata
-
-rdev:   .byte   "R:", ATEOL, 0
-
-        .bss
-
-; receive buffer
-RECVBUF_SZ = 256
-recv_buf: .res  RECVBUF_SZ
-
-cm_run: .res    1       ; concurrent mode running?
-
-        .data
-
-rshand: .word   $ffff
-
-        .code
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_init (char hacked);
-; /* Initialize the serial port. The parameter is ignored in the Atari version.
-;  * return 0/-1 for OK/Error
-;  */
-;
-
-.proc   _rs232_init
-
-        jsr     findfreeiocb
-        bne     init_err
-        txa
-        tay                     ; move iocb # into Y
-        lda     #3
-        sta     tmp3            ; name length + 1
-        lda     #<rdev
-        ldx     #>rdev
-        jsr     newfd
-        tya
-        bcs     doopen          ; C set: open needed / device not already open
-
-        pha
-        jsr     _rs232_done     ;** shut down if started  @@@TODO check this out!!
-        pla
-
-doopen: tax
-        pha
-        jsr     clriocb
-        pla
-        tax
-        lda     #<rdev
-        sta     ICBAL,x
-        lda     #>rdev
-        sta     ICBAH,x
-        lda     #OPEN
-        sta     ICCOM,x
-
-        lda     #$0D            ; mode in+out+concurrent
-        sta     ICAX1,x
-        lda     #0
-        sta     ICAX2,x
-        sta     ICBLL,x         ; zap buf len
-        sta     ICBLH,x
-        jsr     CIOV
-        bmi     cioerr1
-
-        lda     tmp2            ; get fd
-        sta     rshand
-        ldx     #0
-        stx     rshand+1
-        txa
-        rts
-
-cioerr1:jsr     fddecusage      ; decrement usage counter of fd as open failed
-
-init_err:
-        ldx     #0
-        lda     #RS_ERR_INIT_FAILED
-        rts
-
-.endproc        ; _rs232_init
-
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_params (unsigned char params, unsigned char parity);
-;
-; Set communication parameters.
-;
-; params contains baud rate, stop bits and word size
-; parity contains parity
-;
-; 850 manual documents restrictions on the baud rate (not > 300), when not
-; using 8 bit word size. So only 8 bit is currently tested.
-;
-
-.proc   _rs232_params
-
-        sta     tmp2
-        lda     rshand
-        cmp     #$ff
-        bne     work            ; work only if initialized
-        lda     #RS_ERR_NOT_INITIALIZED
-        bne     done
-work:   lda     rshand
-        ldx     #0
-        jsr     fdtoiocb        ; get iocb index into X
-        bmi     inverr          ; shouldn't happen
-        tax
-
-        ; set handshake lines
-
-        lda     #34             ; xio 34, set cts, dtr etc
-        sta     ICCOM,x
-        lda     #192+48+3       ; DTR on, RTS on, XMT on
-        sta     ICAX1,x
-        lda     #0
-        sta     ICBLL,x
-        sta     ICBLH,x
-        sta     ICBAL,x
-        sta     ICBAH,x
-        sta     ICAX2,x
-        jsr     CIOV
-        bmi     cioerr
-
-        ; set baud rate, word size, stop bits and ready monitoring
-
-        lda     #36             ; xio 36, baud rate
-        sta     ICCOM,x
-        jsr     popa            ; get parameter
-        sta     ICAX1,x
-        ;ICAX2 = 0, monitor nothing
-        jsr     CIOV
-        bmi     cioerr
-
-        ; set translation and parity
-
-        lda     #38             ; xio 38, translation and parity
-        sta     ICCOM,x
-        lda     tmp2
-        ora     #32             ; no translation
-        sta     ICAX1,x
-        jsr     CIOV
-        bmi     cioerr
-
-        lda     #0
-done:   ldx     #0
-        rts
-
-inverr: jmp     __inviocb
-
-.endproc        ;_rs232_params
-
-cioerr: jmp     __do_oserror
-
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_done (void);
-; /* Close the port, deinstall the interrupt hander. You MUST call this function
-;  * before terminating the program, otherwise the machine may crash later. If
-;  * in doubt, install an exit handler using atexit(). The function will do
-;  * nothing, if it was already called.
-;  */
-;
-
-.proc   _rs232_done
-
-        lda     rshand
-        cmp     #$ff
-        beq     done
-work:   ldx     rshand+1
-        jsr     pushax
-        jsr     _close
-        pha
-        txa
-        pha
-        ldx     #$ff
-        stx     rshand
-        stx     rshand+1
-        inx
-        stx     cm_run
-        pla
-        tax
-        pla
-done:   rts
-
-.endproc        ;rs232_done
-
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_get (char* B);
-; /* Get a character from the serial port. If no characters are available, the
-;  * function will return RS_ERR_NO_DATA, so this is not a fatal error.
-;  */
-;
-
-.proc   _rs232_get
-
-        ldy     rshand
-        cpy     #$ff
-        bne     work            ; work only if initialized
-        lda     #RS_ERR_NOT_INITIALIZED
-        bne     nierr
-
-work:   sta     ptr1
-        stx     ptr1+1          ; store pointer to received char
-
-        lda     rshand
-        ldx     #0
-        jsr     fdtoiocb
-        tax
-        lda     cm_run          ; concurrent mode already running?
-        bne     go
-        jsr     ena_cm          ; turn on concurrent mode
-
-go:     ; check whether there is any input available
-
-        lda     #STATIS         ; status request, returns bytes pending
-        sta     ICCOM,x
-        jsr     CIOV
-        bmi     cioerr          ; @@@ error handling
-
-        lda     DVSTAT+1        ; get byte count pending
-        ora     DVSTAT+2
-        beq     nix_da          ; no input waiting...
-
-        ; input is available: get it!
-
-        lda     #GETCHR         ; get raw bytes
-        sta     ICCOM,x         ; in command code
-        lda     #0
-        sta     ICBLL,x
-        sta     ICBLH,x
-        sta     ICBAL,x
-        sta     ICBAH,x
-        jsr     CIOV            ; go get it
-        bmi     cioerr          ; @@@ error handling
-
-        ldx     #0
-        sta     (ptr1,x)        ; return received byte
-        txa
-        rts
-
-nierr:  ldx     #0
-        rts
-
-nix_da: lda     #RS_ERR_NO_DATA
-        ldx     #0
-        rts
-
-.endproc        ;_rs232_get
-
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_put (char B);
-; /* Send a character via the serial port. There is a transmit buffer, but
-;  * transmitting is not done via interrupt. The function returns
-;  * RS_ERR_OVERFLOW if there is no space left in the transmit buffer.
-;  */
-;
-
-.proc   _rs232_put
-
-        ldy     rshand
-        cpy     #$ff
-        bne     work            ; work only if initialized
-        lda     #RS_ERR_NOT_INITIALIZED
-        bne     nierr
-
-work:   pha
-        lda     rshand
-        ldx     #0
-        jsr     fdtoiocb
-        tax
-        lda     cm_run          ; concurrent mode already running?
-        bne     go
-        jsr     ena_cm          ; turn on concurrent mode
-
-        ; @@@TODO:       check output buffer overflow
-go:     lda     #PUTCHR         ; put raw bytes
-        sta     ICCOM,x         ; in command code
-        lda     #0
-        sta     ICBLL,x
-        sta     ICBLH,x
-        sta     ICBAL,x
-        sta     ICBAH,x
-        pla                     ; get the char back
-        jsr     CIOV            ; go do it
-        rts
-
-nierr:  ldx     #0
-        rts
-
-.endproc        ;_rs232_put
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_pause (void);
-; /* Assert flow control and disable interrupts. */
-;
-
-_rs232_pause:
-
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_unpause (void);
-; /* Re-enable interrupts and release flow control */
-;
-
-_rs232_unpause:
-
-
-;----------------------------------------------------------------------------
-;
-; unsigned char __fastcall__ rs232_status (unsigned char* status,
-;                                          unsigned char* errors);
-; /* Return the serial port status. */
-;
-
-_rs232_status:
-
-        lda     #255
-        tax
-        rts
-
-
-; enable concurrent rs232 mode
-; gets iocb index in X
-; all registers destroyed
-
-.proc   ena_cm
-
-        lda     #40             ; XIO 40, start concurrent IO
-        sta     ICCOM,x
-        sta     cm_run          ; indicate concurrent mode is running
-        lda     #0
-        sta     ICAX1,x
-        sta     ICAX2,x
-        lda     #<recv_buf
-        sta     ICBAL,x
-        lda     #>recv_buf
-        sta     ICBAH,x
-        lda     #<RECVBUF_SZ
-        sta     ICBLL,x
-        lda     #>RECVBUF_SZ
-        sta     ICBLH,x
-        lda     #$0D            ; value from 850 man, p62.  must be 0D?,
-        sta     ICAX1,x         ;  or any non-zero?
-        jmp     CIOV
-
-.endproc        ;ena_cm
-
-        .end
diff --git a/libsrc/atari/ser/atrrdev.s b/libsrc/atari/ser/atrrdev.s
new file mode 100644 (file)
index 0000000..7243e29
--- /dev/null
@@ -0,0 +1,579 @@
+;
+; Christian Groessler, Dec-2001
+; converted to driver interface Dec-2013
+;
+; RS232 routines using the R: device (currently tested with an 850 only)
+;
+
+        .include        "zeropage.inc"
+        .include        "ser-kernel.inc"
+        .include        "ser-error.inc"
+        .include        "atari.inc"
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment        "JUMPTABLE"
+
+; Driver signature
+
+        .byte   $73, $65, $72           ; "ser"
+        .byte   SER_API_VERSION         ; Serial API version number
+
+; Library reference
+
+libref: .addr   $0000
+
+; Jump table
+
+        .word   SER_INSTALL
+        .word   SER_UNINSTALL
+        .word   SER_OPEN
+        .word   SER_CLOSE
+        .word   SER_GET
+        .word   SER_PUT
+        .word   SER_STATUS
+        .word   SER_IOCTL
+        .word   SER_IRQ
+
+
+        .rodata
+
+rdev:   .byte   "R:", ATEOL, 0
+bauds:  .byte   1               ; SER_BAUD_45_5
+        .byte   2               ; SER_BAUD_50
+        .byte   4               ; SER_BAUD_75
+        .byte   5               ; SER_BAUD_110
+        .byte   6               ; SER_BAUD_134_5
+        .byte   7               ; SER_BAUD_150
+        .byte   8               ; SER_BAUD_300
+        .byte   9               ; SER_BAUD_600
+        .byte   10              ; SER_BAUD_1200
+        .byte   11              ; SER_BAUD_1800
+        .byte   12              ; SER_BAUD_2400
+        .byte   0               ; SER_BAUD_3600
+        .byte   13              ; SER_BAUD_4800
+        .byte   0               ; SER_BAUD_7200
+        .byte   14              ; SER_BAUD_9600
+        .byte   0               ; SER_BAUD_19200
+        .byte   0               ; SER_BAUD_38400
+        .byte   0               ; SER_BAUD_57600
+        .byte   0               ; SER_BAUD_115200
+        .byte   0               ; SER_BAUD_230400
+        .byte   0               ; SER_BAUD_31250
+        .byte   0               ; SER_BAUD_62500
+        .byte   3               ; SER_BAUD_56_875
+num_bauds       =       * - bauds
+databits:
+        .byte   48              ; SER_BITS_5
+        .byte   32              ; SER_BITS_6
+        .byte   16              ; SER_BITS_7
+        .byte   0               ; SER_BITS_8
+num_databits    =       * - databits
+parities:
+        .byte   0               ; SER_PAR_NONE
+        .byte   4+1             ; SER_PAR_ODD
+        .byte   2+8             ; SER_PAR_EVEN
+        ;.byte  0               ; SER_PAR_MARK
+        ;.byte  0               ; SER_PAR_SPACE
+num_parities    =       * - parities
+
+        .bss
+
+; receive buffer
+RECVBUF_SZ = 256
+recv_buf: .res  RECVBUF_SZ
+
+cm_run: .res    1       ; concurrent mode running?
+
+        .data
+
+rshand: .word   $ffff
+
+; jump table into main program, initialized from libref
+my_newfd:
+        .byte   $4C
+        .word   0
+my__close:
+        .byte   $4C
+        .word   0
+my_pushax:
+        .byte   $4C
+        .word   0
+my_popax:
+        .byte   $4C
+        .word   0
+my_findfreeiocb:
+        .byte   $4C
+        .word   0
+my___do_oserror:
+        .byte   $4C
+        .word   0
+my_fddecusage:
+        .byte   $4C
+        .word   0
+my_fdtoiocb:
+        .byte   $4C
+        .word   0
+my___inviocb:
+        .byte   $4C
+        .word   0
+my_clriocb:
+        .byte   $4C
+        .word   0
+my_CIOV:
+        .byte   $4C
+        .word   0
+
+        .code
+
+invbaud:
+        lda     #<SER_ERR_BAUD_UNAVAIL
+        ldx     #>SER_ERR_BAUD_UNAVAIL
+openerr:
+        rts
+
+
+;----------------------------------------------------------------------------
+; SER_OPEN: A pointer to a ser_params structure is passed in ptr1.
+; Must return an SER_ERR_xx code in a/x.
+
+SER_OPEN:
+        jsr     do_open
+        bne     openerr
+
+; set line parameters
+        lda     rshand
+        ldx     #0
+        jsr     my_fdtoiocb     ; get iocb index into X
+        bmi     openerr         ; shouldn't happen
+        tax
+
+        ; set baud rate, word size, stop bits and ready monitoring
+
+        ; build ICAX1 value
+        ldy     #SER_PARAMS::BAUDRATE
+        lda     (ptr1),y
+        cmp     #num_bauds
+        bcs     invbaud
+
+        tay
+        lda     bauds,y
+        beq     invbaud
+        sta     ICAX1,x
+
+        ldy     #SER_PARAMS::DATABITS
+        lda     (ptr1),y
+        cmp     #num_databits
+        bcs     init_err
+
+        tay
+        lda     databits,y
+        ora     ICAX1,x
+        sta     ICAX1,x
+
+        ldy     #SER_PARAMS::STOPBITS
+        lda     (ptr1),y
+        clc
+        ror     a
+        ror     a
+        ora     ICAX1,x
+        sta     ICAX1,x
+
+        lda     #36             ; xio 36, baud rate
+        sta     ICCOM,x
+        lda     #0
+        ;ICAX2 = 0, monitor nothing
+        sta     ICAX2,x
+        sta     ICBLL,x
+        sta     ICBLH,x
+        sta     ICBAL,x
+        sta     ICBAH,x
+        jsr     my_CIOV
+        bmi     cioerr
+
+        ; check if the handshake setting is valid
+        ldy     #SER_PARAMS::HANDSHAKE
+        lda     (ptr1),y
+        cmp     #SER_HS_HW      ; this is all we support
+        bne     init_err
+
+        ; set handshake lines
+        lda     #34             ; xio 34, set cts, dtr etc
+        sta     ICCOM,x
+        lda     #192+48+3       ; DTR on, RTS on, XMT on
+        sta     ICAX1,x
+        jsr     my_CIOV
+        bmi     cioerr
+
+        ; set translation and parity
+        ldy     #SER_PARAMS::PARITY
+        lda     (ptr1),y
+        cmp     #num_parities
+        bcs     init_err
+
+        tay
+        lda     parities,y
+        ora     #32             ; no translation
+        sta     ICAX1,x
+
+        lda     #38             ; xio 38, translation and parity
+        sta     ICCOM,x
+        jsr     my_CIOV
+        bmi     cioerr
+
+        lda     #<SER_ERR_OK
+        tax                             ; A is zero
+        rts
+
+inverr: jmp     my___inviocb
+
+cioerr:
+        ; @@@ need to close IOCB here
+        jsr     my_fddecusage   ; decrement usage counter of fd as open failed
+
+init_err:
+        ldx     #0
+        lda     #SER_ERR_INIT_FAILED
+        rts
+
+;---- open the device
+
+do_open:
+        jsr     my_findfreeiocb
+        bne     init_err
+        txa
+        tay                     ; move iocb # into Y
+        lda     #3
+        sta     tmp3            ; name length + 1
+        lda     #<rdev
+        ldx     #>rdev
+        jsr     my_newfd
+        tya
+        bcs     @doopen         ; C set: open needed / device not already open
+
+        pha
+        jsr     SER_CLOSE       ;** shut down if started  @@@TODO check this out!!
+        pla
+
+@doopen:tax
+        pha
+        jsr     my_clriocb
+        pla
+        tax
+        lda     #<rdev
+        sta     ICBAL,x
+        lda     #>rdev
+        sta     ICBAH,x
+        lda     #OPEN
+        sta     ICCOM,x
+
+        lda     #$0D            ; mode in+out+concurrent
+        sta     ICAX1,x
+        lda     #0
+        sta     ICAX2,x
+        sta     ICBLL,x         ; zap buf len
+        sta     ICBLH,x
+        jsr     my_CIOV
+        bmi     cioerr
+
+        lda     tmp2            ; get fd (from newfd)
+        sta     rshand
+        ldx     #0
+        stx     rshand+1
+        txa
+        rts
+
+;----------------------------------------------------------------------------
+; CLOSE: Close the port, disable interrupts and flush the buffer. Called
+; without parameters. Must return an error code in a/x.
+;
+;----------------------------------------------------------------------------
+; SER_UNINSTALL routine. Is called before the driver is removed from memory.
+; Must return an SER_ERR_xx code in a/x.
+;
+
+SER_UNINSTALL:
+SER_CLOSE:
+        lda     rshand
+        cmp     #$ff
+        beq     @done
+
+        ldx     rshand+1
+        jsr     my__close
+        ldx     #$ff
+        stx     rshand
+        stx     rshand+1
+        inx
+        stx     cm_run
+@done:  lda     #<SER_ERR_OK
+        ldx     #>SER_ERR_OK
+        rts
+
+;----------------------------------------------------------------------------
+; SER_GET: Will fetch a character from the receive buffer and store it into the
+; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
+; return.
+;
+
+SER_GET:
+        ldy     rshand
+        cpy     #$ff
+        beq     ni_err           ; work only if initialized
+
+        lda     rshand
+        ldx     #0
+        jsr     my_fdtoiocb
+        tax
+        lda     cm_run          ; concurrent mode already running?
+        bne     @go
+        jsr     ena_cm          ; turn on concurrent mode
+
+@go:    ; check whether there is any input available
+
+        lda     #STATIS         ; status request, returns bytes pending
+        sta     ICCOM,x
+        jsr     my_CIOV
+        bmi     ser_error
+
+        lda     DVSTAT+1        ; get byte count pending
+        ora     DVSTAT+2
+        beq     @nix_da         ; no input waiting...
+
+        ; input is available: get it!
+
+        lda     #GETCHR         ; get raw bytes
+        sta     ICCOM,x         ; in command code
+        lda     #0
+        sta     ICBLL,x
+        sta     ICBLH,x
+        sta     ICBAL,x
+        sta     ICBAH,x
+        jsr     my_CIOV         ; go get it
+        bmi     ser_error
+
+        ldx     #0
+        sta     (ptr1,x)        ; return received byte
+        txa
+        rts
+
+@nix_da:lda     #SER_ERR_NO_DATA
+        ldx     #0
+        rts
+
+ser_error:
+        lda     #SER_ERR_OVERFLOW       ; there is no large selection of serial error codes... :-/
+        ldx     #0
+        rts
+
+ni_err: lda     #SER_ERR_NOT_OPEN
+        ldx     #0
+        rts
+
+;----------------------------------------------------------------------------
+; SER_PUT: Output character in A.
+; Must return an error code in a/x.
+;
+
+SER_PUT:
+        ldy     rshand
+        cpy     #$ff
+        beq     ni_err          ; work only if initialized
+
+        pha                     ; remember char to write
+        lda     rshand
+        ldx     #0
+        jsr     my_fdtoiocb
+        tax
+
+        lda     cm_run          ; concurrent mode already running?
+        bne     @go
+        jsr     ena_cm          ; turn on concurrent mode
+
+        ; @@@TODO:       check output buffer overflow
+@go:    lda     #PUTCHR         ; put raw bytes
+        sta     ICCOM,x         ; in command code
+        lda     #0
+        sta     ICBLL,x
+        sta     ICBLH,x
+        sta     ICBAL,x
+        sta     ICBAH,x
+        pla                     ; get the char back
+        jsr     my_CIOV         ; go do it
+        bmi     ser_error
+        lda     #0
+        tax
+        rts
+
+;----------------------------------------------------------------------------
+; SER_STATUS: Return the status in the variable pointed to by ptr1.
+; Must return an error code in a/x.
+;
+
+SER_STATUS:
+        ; fall through to SER_IOCTL
+
+;----------------------------------------------------------------------------
+; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+SER_IOCTL:
+        lda     #<SER_ERR_INV_IOCTL     ; We don't support ioclts for now
+        ldx     #>SER_ERR_INV_IOCTL
+        rts
+
+;----------------------------------------------------------------------------
+; SER_IRQ: Not used on the Atari
+;
+
+SER_IRQ     = $0000
+
+;----------------------------------------------------------------------------
+; SER_INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an SER_ERR_xx code in a/x.
+
+SER_INSTALL:
+        ; check if R: device is installed
+        ldy     #0
+search: lda     HATABS,y                ; get device name
+        cmp     #'R'
+        beq     found
+        iny
+        iny
+        iny
+        cpy     #MAXDEV
+        bcc     search
+
+; R: device not found, return error
+
+        lda     #<SER_ERR_NO_DEVICE
+        ldx     #0
+        rts
+
+; R: device found, initialize jump table into main program
+
+found:  lda     ptr3
+        pha
+        lda     ptr3+1
+        pha
+        lda     libref
+        sta     ptr3
+        lda     libref+1
+        sta     ptr3+1
+
+        ldy     #0
+        lda     (ptr3),y
+        sta     my_newfd+1
+        iny
+        lda     (ptr3),y
+        sta     my_newfd+2
+        iny
+
+        lda     (ptr3),y
+        sta     my__close+1
+        iny
+        lda     (ptr3),y
+        sta     my__close+2
+        iny
+
+        lda     (ptr3),y
+        sta     my_pushax+1
+        iny
+        lda     (ptr3),y
+        sta     my_pushax+2
+        iny
+
+        lda     (ptr3),y
+        sta     my_popax+1
+        iny
+        lda     (ptr3),y
+        sta     my_popax+2
+        iny
+
+        lda     (ptr3),y
+        sta     my_findfreeiocb+1
+        iny
+        lda     (ptr3),y
+        sta     my_findfreeiocb+2
+        iny
+
+        lda     (ptr3),y
+        sta     my___do_oserror+1
+        iny
+        lda     (ptr3),y
+        sta     my___do_oserror+2
+        iny
+
+        lda     (ptr3),y
+        sta     my_fddecusage+1
+        iny
+        lda     (ptr3),y
+        sta     my_fddecusage+2
+        iny
+
+        lda     (ptr3),y
+        sta     my_fdtoiocb+1
+        iny
+        lda     (ptr3),y
+        sta     my_fdtoiocb+2
+        iny
+
+        lda     (ptr3),y
+        sta     my___inviocb+1
+        iny
+        lda     (ptr3),y
+        sta     my___inviocb+2
+        iny
+
+        lda     (ptr3),y
+        sta     my_clriocb+1
+        iny
+        lda     (ptr3),y
+        sta     my_clriocb+2
+        iny
+
+        lda     (ptr3),y
+        sta     my_CIOV+1
+        iny
+        lda     (ptr3),y
+        sta     my_CIOV+2
+        ;iny
+
+        pla
+        sta     ptr3+1
+        pla
+        sta     ptr3
+
+        lda     #<SER_ERR_OK
+        tax                     ; A is zero
+        rts
+
+
+; enable concurrent rs232 mode
+; gets iocb index in X
+; all registers destroyed
+
+.proc   ena_cm
+
+        lda     #40             ; XIO 40, start concurrent IO
+        sta     ICCOM,x
+        sta     cm_run          ; indicate concurrent mode is running
+        lda     #$0D            ; value from 850 manual, p62.  must be $0D?,
+        sta     ICAX1,x         ;  or any non-zero?
+        lda     #0
+        sta     ICAX2,x
+        lda     #<recv_buf
+        sta     ICBAL,x
+        lda     #>recv_buf
+        sta     ICBAH,x
+        lda     #<RECVBUF_SZ
+        sta     ICBLL,x
+        lda     #>RECVBUF_SZ
+        sta     ICBLH,x
+        jmp     my_CIOV
+
+.endproc        ;ena_cm
diff --git a/libsrc/atari/ser_libref.s b/libsrc/atari/ser_libref.s
new file mode 100644 (file)
index 0000000..4b5c585
--- /dev/null
@@ -0,0 +1,28 @@
+
+       .include        "atari.inc"
+
+       .import _close, pushax, popax
+        .import         findfreeiocb
+        .import         __do_oserror
+        .import         fddecusage
+        .import         fdtoiocb
+        .import         __inviocb
+        .import         clriocb
+        .import         newfd
+
+       .export atari_ser_libref
+
+.rodata
+
+atari_ser_libref:
+       .word   newfd
+       .word   _close
+       .word   pushax
+       .word   popax
+        .word   findfreeiocb
+        .word   __do_oserror
+        .word   fddecusage
+        .word   fdtoiocb
+        .word   __inviocb
+        .word   clriocb
+       .word   CIOV
index c929189a39646461db9e72064b14e505bda9fc11..6e3f5fc8a583b858138635fc2c4ba208704a2d26 100644 (file)
 #define DRIVERNAME      "a2e.ssc.ser"
 #elif defined(__APPLE2__)
 #define DRIVERNAME      "a2.ssc.ser"
+#elif defined(__ATARIXL__)
+#define DRIVERNAME      "atrxrdev.ser"
+#elif defined(__ATARI__)
+#define DRIVERNAME      "atrrdev.ser"
 #else
 #define DRIVERNAME      "unknown"
 #error "Unknown target system"
@@ -24,7 +28,7 @@
 
 
 static const struct ser_params Params = {
-    SER_BAUD_19200,     /* Baudrate */
+    SER_BAUD_9600,      /* Baudrate */
     SER_BITS_8,         /* Number of data bits */
     SER_STOP_1,         /* Number of stop bits */
     SER_PAR_NONE,       /* Parity setting */