Files
6502-cpu-monitor/16c550_irq.asm
Ben Chong 16732e6cab Clean up
2017-07-02 21:28:52 -07:00

150 lines
5.3 KiB
NASM

; 6502 BIOS
; Based on original code by Daryl Rictor
; Adapted to 16550 UART board for RC2014
; Renamed to 16c550.asm
; Changes are copyright Ben Chong and freely licensed to the community
;
; Note: Does not require a 16C550 with autoflow control
;
; ----------------- assembly instructions ----------------------------
;
; this is a subroutine library only
; it must be included in an executable source file
;
;
;*** I/O Locations *******************************
; Define the i/o address of the UART chip
;*** 16C550 UART ************************
uart_base = $c0c0
uart_reg0 = $c0c0
uart_reg1 = $c0c1
uart_reg2 = $c0c2
uart_reg3 = $c0c3
uart_reg4 = $c0c4
uart_reg5 = $c0c5
uart_reg6 = $c0c6
uart_reg7 = $c0c7
uart_xmit = uart_reg0 ; Used by upload.asm
;
;***********************************************************************
; UART I/O Support Routines
; We'll use Daryl's routine names for compatibility with his software/code
; Otherwise, we'll use UART-agnostic nomemclature
;---------------------------------------------------------------------
;
ACIA1_init
uart_init
lda #>uart_irq
ldx #<uart_irq
stx irq_vector
sta irq_vector+1
jsr init_buffer ; Initialize IRQ buffer
lda #$80 ; Line control register, Set DLAB=1
sta uart_reg3
lda #$01 ; 115200 with 1.8432MHz; OSC / (16 * Baudrate)
sta uart_reg0 ; Divisor latch
lda #$00
sta uart_reg1 ; Divisor latch
LDA #$03 ; Line control register, 8N1, DLAB=0
sta uart_reg3
LDA #$02 ; Modem control register
sta uart_reg4 ; Enable RTS
LDA #$87 ; FIFO enable, reset RCVR/XMIT FIFO
sta uart_reg2
; jsr AFE_16C550 ; Enable auto flow control
lda #$01 ; Enable receiver interrupt
sta uart_reg1
rts ; done
;---------------------------------------------------------------------
; Input char from UART (blocking)
; Exit: character in A
ACIA1_Input
uart_input
jsr check_buffer
beq uart_input
jsr pull_buffer
rts ;
;---------------------------------------------------------------------
; Non-blocking get character routine
; Scan for input (no wait), C=1 char, C=0 no character
ACIA1_Scan
uart_scan
clc
jsr check_buffer
beq uart_scan2
jsr pull_buffer ; Exit with C=1
uart_scan2
rts
;---------------------------------------------------------------------
; output to OutPut Port
; Entry: character in A
; Exit: character in A
ACIA1_Output
uart_output
pha ; save registers
uart_out1
lda uart_reg5 ; serial port status
and #$20 ; is tx buffer empty
beq uart_out1 ; no
pla ; get chr
sta uart_reg0 ; put character to Port
rts ; done
;---------------------------------------------------------------------
; Enable autoflow control
AFE_16C550
LDA #$87 ; Trigger level, FIFO enable, reset FIFO
sta uart_reg2
; Use this to enable autoflow control
LDA #$22 ; Modem control register
sta uart_reg4 ; Enable AFE
rts
;------------------------------------------------------------------------------
; This is the UART-specific call to bring RTS high to disable transmit from terminal
; We can use A
uart_deassert_rts
lda #$00
sta uart_reg4
rts
;------------------------------------------------------------------------------
; This is the UART-specific call to bring RTS low to re-enable transmit
uart_assert_rts
lda #$02
sta uart_reg4
rts
;---------------------------------------------------------------------
uart_irq
; Check if our interrupt
lda uart_reg5 ; Serial port status
and #$01 ; is recvr full
beq ui_end ; no char to get
; It's our interrupt
ui_loop
lda uart_reg0 ; get chr
jsr put_buffer
lda uart_reg5 ; Serial port status
and #$01 ; is recvr full
bne ui_loop ; Yes, still full
ui_end
jmp null_irq
.include buffer.asm
;
;end of file