| ;; 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 |