Add console input buffer
This commit is contained in:
148
16c550_irq.asm
Normal file
148
16c550_irq.asm
Normal 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
85
buffer.asm
Normal 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
|
||||
8
sbc.asm
8
sbc.asm
@@ -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
|
||||
|
||||
; -----------------------------
|
||||
|
||||
24
sbcmon.asm
24
sbcmon.asm
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user