Add console input buffer

This commit is contained in:
Ben Chong
2017-07-01 16:10:29 -07:00
parent 7e4aaeabc8
commit 4347bef9af
4 changed files with 250 additions and 15 deletions

148
16c550_irq.asm Normal file
View File

@@ -0,0 +1,148 @@
; 6502 BIOS
; Based on original code by Daryl Rictor
; Adapted to 16550 UART board for RC2014
; Renamed to 16c550.asm
;
; Note: Assumes the use of 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

85
buffer.asm Normal file
View File

@@ -0,0 +1,85 @@
; 64 byte char buffer
;---------------------------------------------------------------------
; Compare Result N Z C
; A, X, or Y < Memory * 0 0
; A, X, or Y = Memory 0 1 1
; A, X, or Y > Memory * 0 1
;---------------------------------------------------------------------
MAXCOUNT = 64
HIWATER = 40
LOWATER = 20
inptr = $380 ;$f2
outptr = $381 ;$f3
charcount = $382 ;$f4
;---------------------------------------------------------------------
; Initialize buffer operations
init_buffer
lda #$00
sta inptr
sta outptr
sta charcount
rts
;---------------------------------------------------------------------
; Store char in buffer
; Entry: A = char
put_buffer
pha
lda charcount
cmp #MAXCOUNT ; Are we at max?
bcs bp_max ; Yes, abort
cmp #HIWATER ;
bcc not_hiw ; Not high water mark
jsr uart_deassert_rts
not_hiw
inc charcount
stx ysav ; Temp storage. 6502 doesn't have enough flexibility...!
ldx inptr ; Grab inptr from memory
pla ; Get char
sta buffer, x ; Store in buffer
inx ; Increment to next location
cpx #64 ; Top of buffer area?
bcc pb_not ; < 64
ldx #$00 ; If >=64, go back to bottom of buffer
pb_not
stx inptr ; Update inptr in memory
ldx ysav ; Restore X
bp_max
rts
;---------------------------------------------------------------------
; Check if char in buffer, C=1 char, C=0 no character
; Exit: A contains char
pull_buffer
sei ; Disable IRQ
lda charcount
beq plb_nochar ; No character in buffer
dec charcount
cmp #LOWATER
bcs not_low ; Not low water
jsr uart_assert_rts
not_low
stx ysav ; Save x
ldx outptr
lda buffer, x
inx
cpx #64 ; Top of buffer?
bcc plb_not ; No
ldx #$00 ; Back to bottom
plb_not
stx outptr ; Save
ldx ysav ; Restore x
sec
bcs plb_end ; Equiv to bra
plb_nochar
clc
plb_end
cli ; Enable IRQ
rts
check_buffer
lda charcount
rts

View File

@@ -18,9 +18,11 @@
.include upload.asm
; Change this line according to the type of UART board
; .include rruart.asm ; uart init
.include 16c550.asm
; .include 6850.asm
; .include rruart.asm ; uart init
; .include 16c550.asm
; .include 6850.asm
.include 16c550_irq.asm
.include sbcmon.asm ; actual monitor
; -----------------------------

View File

@@ -43,8 +43,8 @@ SPTR = $03e5 ; hold stack pointer
PREG = $03e6 ; hold status register (P)
irq_vector = $03e8 ; Interrupt vector
nmi_vector = $03ea ; NMI vector
realpcl = $03eb
realpch = $03ec
;realpcl = $03eb
;realpch = $03ec
;
;
@@ -197,10 +197,10 @@ BRKroutine
sta Preg ; save P
pla ; PCL
tay ; PCL in Y
sty realpcl
; sty realpcl
pla ; PCH
tax ; PCH in X
stx realpch
; stx realpch
tya ; PCL in A
sec ;
sbc #$02 ;
@@ -432,14 +432,14 @@ ghc_abort
;---------------------------------------------------------------------
helptxt
.byte $0d,$0a,"6502 Monitor RC2014 v0.2.0"
.byte CR,LF,"? Print this help"
.byte CR,LF,"D XXXX Dump memory from XXXX"
.byte CR,LF,"E XXXX Edit memory from XXXX"
.byte CR,LF,"G XXXX Go execute from XXXX"
.byte CR,LF,"U Upload Intel HEX file",0
.byte $0d,$0a,"6502 Monitor RC2014 v0.2.1"
.byte CR,LF,"? Print this help"
.byte CR,LF,"D XXXX Dump memory from XXXX"
.byte CR,LF,"E XXXX Edit memory from XXXX"
.byte CR,LF,"G XXXX Go execute from XXXX"
.byte CR,LF,"U Upload Intel HEX file",0
helptxt2:
.byte CR,LF," ESC to quit when upload is done"
.byte CR,LF," ESC to quit when upload is done"
.byte $0d, $0a
.byte $00
@@ -632,7 +632,7 @@ dm_next1 ; Have we done 16 bytes?
dm_end
jmp monitor_loop
dm_prompt .byte "Press any key to continue, ESC to abort",0
dm_prompt .byte "Press any key to continue, ESC to quit",0
;---------------------------------------------------------------------
; Print version