Merge pull request #64 from groessler/something_to_pull
Serial driver for Atari
This commit is contained in:
@@ -48,6 +48,7 @@
|
|||||||
SER_ERR_INIT_FAILED ; Initialization failed
|
SER_ERR_INIT_FAILED ; Initialization failed
|
||||||
SER_ERR_INV_IOCTL ; IOCTL not supported
|
SER_ERR_INV_IOCTL ; IOCTL not supported
|
||||||
SER_ERR_INSTALLED ; A driver is already installed
|
SER_ERR_INSTALLED ; A driver is already installed
|
||||||
|
SER_ERR_NOT_OPEN ; Driver not open
|
||||||
|
|
||||||
SER_ERR_COUNT ; Special: Number of error codes
|
SER_ERR_COUNT ; Special: Number of error codes
|
||||||
.endenum
|
.endenum
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ SER_BAUD_115200 = $12
|
|||||||
SER_BAUD_230400 = $13
|
SER_BAUD_230400 = $13
|
||||||
SER_BAUD_31250 = $14
|
SER_BAUD_31250 = $14
|
||||||
SER_BAUD_62500 = $15
|
SER_BAUD_62500 = $15
|
||||||
|
SER_BAUD_56_875 = $16
|
||||||
|
|
||||||
; Data bit settings
|
; Data bit settings
|
||||||
SER_BITS_5 = $00
|
SER_BITS_5 = $00
|
||||||
|
|||||||
@@ -67,6 +67,7 @@
|
|||||||
#define SER_BAUD_230400 0x13
|
#define SER_BAUD_230400 0x13
|
||||||
#define SER_BAUD_31250 0x14
|
#define SER_BAUD_31250 0x14
|
||||||
#define SER_BAUD_62500 0x15
|
#define SER_BAUD_62500 0x15
|
||||||
|
#define SER_BAUD_56_875 0x16
|
||||||
|
|
||||||
/* Data bit settings */
|
/* Data bit settings */
|
||||||
#define SER_BITS_5 0x00
|
#define SER_BITS_5 0x00
|
||||||
@@ -111,6 +112,7 @@
|
|||||||
#define SER_ERR_INIT_FAILED 0x08 /* Initialization failed */
|
#define SER_ERR_INIT_FAILED 0x08 /* Initialization failed */
|
||||||
#define SER_ERR_INV_IOCTL 0x09 /* IOCTL not supported */
|
#define SER_ERR_INV_IOCTL 0x09 /* IOCTL not supported */
|
||||||
#define SER_ERR_INSTALLED 0x0A /* A driver is already installed */
|
#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 containing parameters for the serial port */
|
||||||
struct ser_params {
|
struct ser_params {
|
||||||
|
|||||||
@@ -2,11 +2,13 @@
|
|||||||
; Oliver Schmidt, 2013-05-31
|
; Oliver Schmidt, 2013-05-31
|
||||||
;
|
;
|
||||||
|
|
||||||
.export em_libref, joy_libref, tgi_libref
|
.export em_libref, joy_libref, tgi_libref, ser_libref
|
||||||
.import _exit
|
.import _exit
|
||||||
|
.import atari_ser_libref
|
||||||
|
|
||||||
em_libref := _exit
|
em_libref := _exit
|
||||||
joy_libref := _exit
|
joy_libref := _exit
|
||||||
|
ser_libref := atari_ser_libref
|
||||||
.ifdef __ATARIXL__
|
.ifdef __ATARIXL__
|
||||||
.import CIO_handler
|
.import CIO_handler
|
||||||
tgi_libref := CIO_handler
|
tgi_libref := CIO_handler
|
||||||
|
|||||||
@@ -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
|
|
||||||
579
libsrc/atari/ser/atrrdev.s
Normal file
579
libsrc/atari/ser/atrrdev.s
Normal file
@@ -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
|
||||||
28
libsrc/atari/ser_libref.s
Normal file
28
libsrc/atari/ser_libref.s
Normal file
@@ -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
|
||||||
@@ -17,6 +17,10 @@
|
|||||||
#define DRIVERNAME "a2e.ssc.ser"
|
#define DRIVERNAME "a2e.ssc.ser"
|
||||||
#elif defined(__APPLE2__)
|
#elif defined(__APPLE2__)
|
||||||
#define DRIVERNAME "a2.ssc.ser"
|
#define DRIVERNAME "a2.ssc.ser"
|
||||||
|
#elif defined(__ATARIXL__)
|
||||||
|
#define DRIVERNAME "atrxrdev.ser"
|
||||||
|
#elif defined(__ATARI__)
|
||||||
|
#define DRIVERNAME "atrrdev.ser"
|
||||||
#else
|
#else
|
||||||
#define DRIVERNAME "unknown"
|
#define DRIVERNAME "unknown"
|
||||||
#error "Unknown target system"
|
#error "Unknown target system"
|
||||||
@@ -24,7 +28,7 @@
|
|||||||
|
|
||||||
|
|
||||||
static const struct ser_params Params = {
|
static const struct ser_params Params = {
|
||||||
SER_BAUD_19200, /* Baudrate */
|
SER_BAUD_9600, /* Baudrate */
|
||||||
SER_BITS_8, /* Number of data bits */
|
SER_BITS_8, /* Number of data bits */
|
||||||
SER_STOP_1, /* Number of stop bits */
|
SER_STOP_1, /* Number of stop bits */
|
||||||
SER_PAR_NONE, /* Parity setting */
|
SER_PAR_NONE, /* Parity setting */
|
||||||
|
|||||||
Reference in New Issue
Block a user