330 lines
9 KiB
ArmAsm
330 lines
9 KiB
ArmAsm
|
;; The following code is written and is copyrighted by
|
||
|
;; Groepaz/Hitmen
|
||
|
|
||
|
;; Small changes by Adam Dunkels (renamed ss232 -> rs232)
|
||
|
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
; silver surfer polling mode driver for cc65
|
||
|
; - work from here to create a full featured driver with interupts.
|
||
|
; gpz fixed 20020828: fatal bug fixed in _rs232_params
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
|
||
|
rs16550base = $de08
|
||
|
|
||
|
fifo_rxd = rs16550base+$00 ;8 (r)
|
||
|
fifo_txd = rs16550base+$00 ;8 (w)
|
||
|
|
||
|
fifo_dll = rs16550base+$00 ;8 (r/w)
|
||
|
fifo_dlm = rs16550base+$01 ;9 (r/w)
|
||
|
|
||
|
fifo_ier = rs16550base+$01 ;9
|
||
|
|
||
|
fifo_fcr = rs16550base+$02 ;a (w)
|
||
|
fifo_iir = rs16550base+$02 ;a (r)
|
||
|
fifo_lcr = rs16550base+$03 ;b
|
||
|
fifo_mcr = rs16550base+$04 ;c
|
||
|
fifo_lsr = rs16550base+$05 ;d
|
||
|
fifo_msr = rs16550base+$06 ;e (r)
|
||
|
fifo_scratch = rs16550base+$07 ;f (r/w)
|
||
|
|
||
|
|
||
|
|
||
|
.export _rs232_init
|
||
|
.export _rs232_done
|
||
|
.export _rs232_params
|
||
|
.export _rs232_put
|
||
|
.export _rs232_get
|
||
|
|
||
|
.importzp ptr1, ptr2
|
||
|
.import popa, popax
|
||
|
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
; Error codes. Beware: The codes must match the codes in the C header file
|
||
|
|
||
|
ErrNotInitialized = $01
|
||
|
ErrBaudTooFast = $02
|
||
|
ErrBaudNotAvail = $03
|
||
|
ErrNoData = $04
|
||
|
ErrOverflow = $05
|
||
|
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
;unsigned char __fastcall__ rs232_init (char hacked);
|
||
|
;/* Initialize the serial port, install the interrupt handler. The parameter
|
||
|
; * has no effect for now and should be set to 0.
|
||
|
; */
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
|
||
|
.code
|
||
|
|
||
|
_rs232_init:
|
||
|
; enable ssurfer-port
|
||
|
lda $de01
|
||
|
ora #$01
|
||
|
sta $de01
|
||
|
|
||
|
; disable nmi's from ssurfer
|
||
|
lda #%00000000
|
||
|
sta fifo_ier
|
||
|
|
||
|
; activate dtr
|
||
|
lda #%00000001
|
||
|
sta fifo_mcr
|
||
|
|
||
|
lda #$00 ; ok
|
||
|
tax
|
||
|
rts
|
||
|
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
;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.
|
||
|
; */
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
|
||
|
_rs232_done:
|
||
|
; disable nmi's from ssurfer
|
||
|
lda #%00000000
|
||
|
sta fifo_ier
|
||
|
|
||
|
; deactivate dtr
|
||
|
sta fifo_mcr
|
||
|
|
||
|
; disable ssurfer-port
|
||
|
lda $de01
|
||
|
and #$fe
|
||
|
sta $de01
|
||
|
|
||
|
lda #$00 ; ok
|
||
|
tax
|
||
|
rts
|
||
|
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
;unsigned char __fastcall__ rs232_params (unsigned char params, unsigned char parity);
|
||
|
;/* Set the port parameters. Use a combination of the #defined values above. */
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
|
||
|
.data
|
||
|
|
||
|
_rs232_baudrates:
|
||
|
|
||
|
.word (7372800 / ( 50 * 16))
|
||
|
.word (7372800 / ( 110 * 16))
|
||
|
.word (7372800 / ( 269 * 8))
|
||
|
.word (7372800 / ( 300 * 16))
|
||
|
.word (7372800 / ( 600 * 16))
|
||
|
.word (7372800 / ( 1200 * 16))
|
||
|
.word (7372800 / ( 2400 * 16))
|
||
|
.word (7372800 / ( 4800 * 16))
|
||
|
.word (7372800 / ( 9600 * 16))
|
||
|
.word (7372800 / ( 19200 * 16))
|
||
|
.word (7372800 / ( 38400 * 16))
|
||
|
.word (7372800 / ( 57600 * 16))
|
||
|
.word (7372800 / ( 115200 * 16))
|
||
|
.word (7372800 / ( 230400 * 16))
|
||
|
|
||
|
.bss
|
||
|
|
||
|
_rs232_tmp1:
|
||
|
.res 1
|
||
|
|
||
|
.code
|
||
|
|
||
|
_rs232_params:
|
||
|
|
||
|
sta _rs232_tmp1 ; save parity
|
||
|
|
||
|
; reset fifo
|
||
|
lda #%10000111
|
||
|
sta fifo_fcr
|
||
|
|
||
|
; that delay thing really needed ?!
|
||
|
; (original datasheet mentions a delay here)
|
||
|
; ldy #$00
|
||
|
; dey
|
||
|
; bny *-1
|
||
|
|
||
|
; set dlab
|
||
|
lda #%10000011 ; we assmume 8n1
|
||
|
sta fifo_lcr
|
||
|
|
||
|
jsr popa
|
||
|
tay ; save param
|
||
|
|
||
|
; set baudrate
|
||
|
clc
|
||
|
lsr a
|
||
|
lsr a
|
||
|
lsr a
|
||
|
lsr a
|
||
|
asl a
|
||
|
tax
|
||
|
lda _rs232_baudrates,x
|
||
|
sta fifo_dll
|
||
|
lda _rs232_baudrates+1,x
|
||
|
sta fifo_dlm
|
||
|
|
||
|
tya ; param
|
||
|
and #$0f
|
||
|
ora _rs232_tmp1 ; parity
|
||
|
|
||
|
; reset dlab
|
||
|
sta fifo_lcr
|
||
|
|
||
|
lda #$00 ; ok
|
||
|
tax
|
||
|
rts
|
||
|
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
; check if byte available, returns AKKU=0 if none
|
||
|
|
||
|
ss_getlsr:
|
||
|
lda fifo_lsr
|
||
|
and #$01
|
||
|
rts
|
||
|
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
;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.
|
||
|
; */
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
; get byte (non blocking, returns byte in A or CARRY=1 - error)
|
||
|
|
||
|
_rs232_get:
|
||
|
sta ptr1
|
||
|
stx ptr1+1
|
||
|
|
||
|
jsr ss_getlsr ; check if byte available
|
||
|
; bne sk32 ; yes
|
||
|
bne sk33 ; yes
|
||
|
|
||
|
; activate rts
|
||
|
lda #%00000011
|
||
|
sta fifo_mcr
|
||
|
sk32:
|
||
|
|
||
|
; deactivate rts
|
||
|
; lda #%00000001
|
||
|
; sta fifo_mcr
|
||
|
|
||
|
jsr ss_getlsr ; check if byte available
|
||
|
bne sk33 ; yes
|
||
|
|
||
|
; deactivate rts
|
||
|
lda #%00000001
|
||
|
sta fifo_mcr
|
||
|
|
||
|
lda #ErrNoData ; no data
|
||
|
ldx #0
|
||
|
rts
|
||
|
sk33:
|
||
|
; deactivate rts
|
||
|
lda #%00000001
|
||
|
sta fifo_mcr
|
||
|
|
||
|
; get byte
|
||
|
ldy #$00
|
||
|
lda fifo_rxd
|
||
|
sta (ptr1),y
|
||
|
|
||
|
lda #0 ; ok
|
||
|
tax
|
||
|
rts
|
||
|
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
;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.
|
||
|
; */
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
|
||
|
_rs232_put:
|
||
|
tax
|
||
|
; transmit buf ready?
|
||
|
lda fifo_lsr
|
||
|
and #%00100000
|
||
|
bne @sk1
|
||
|
@sk2:
|
||
|
lda #ErrOverflow ; overflow
|
||
|
ldx #$00
|
||
|
rts
|
||
|
@sk1:
|
||
|
; reciever ready?
|
||
|
lda fifo_msr
|
||
|
and #%00010000
|
||
|
beq @sk2
|
||
|
|
||
|
stx fifo_txd
|
||
|
|
||
|
lda #$00 ; ok
|
||
|
tax
|
||
|
rts
|
||
|
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
;unsigned char __fastcall__ rs232_pause (void);
|
||
|
;/* Assert flow control and disable interrupts. */
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
|
||
|
_rs232_pause:
|
||
|
; activate rts
|
||
|
lda #%00000011
|
||
|
sta fifo_mcr
|
||
|
|
||
|
lda #$00 ; ok
|
||
|
tax
|
||
|
rts
|
||
|
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
;unsigned char __fastcall__ rs232_unpause (void);
|
||
|
;/* Re-enable interrupts and release flow control */
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
|
||
|
_rs232_unpause:
|
||
|
; deactivate rts
|
||
|
lda #%00000001
|
||
|
sta fifo_mcr
|
||
|
|
||
|
lda #$00 ; ok
|
||
|
tax
|
||
|
rts
|
||
|
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
;unsigned char __fastcall__ rs232_status (unsigned char* status,
|
||
|
; unsigned char* errors);
|
||
|
;/* Return the serial port status. */
|
||
|
;----------------------------------------------------------------------------------------------
|
||
|
|
||
|
_rs232_status:
|
||
|
sta ptr2
|
||
|
stx ptr2+1
|
||
|
jsr popax
|
||
|
sta ptr1
|
||
|
stx ptr1+1
|
||
|
|
||
|
ldy #$00
|
||
|
|
||
|
; Get status
|
||
|
lda fifo_iir
|
||
|
and #%00000001
|
||
|
sta _rs232_tmp1
|
||
|
lda fifo_msr
|
||
|
lsr a
|
||
|
and #%01010000
|
||
|
ora _rs232_tmp1
|
||
|
sta _rs232_tmp1
|
||
|
lda fifo_lsr
|
||
|
and #%00101110
|
||
|
ora _rs232_tmp1
|
||
|
sta (ptr1),y
|
||
|
|
||
|
; Get errors
|
||
|
lda #$00 ; ok
|
||
|
sta (ptr2),y
|
||
|
|
||
|
lda #$00 ; ok
|
||
|
tax
|
||
|
rts
|