Use VIA T2, implment output
This commit is contained in:
parent
4a6e099f5f
commit
83cfce2960
1 changed files with 93 additions and 25 deletions
116
driver.a65
116
driver.a65
|
@ -24,6 +24,7 @@ BAUD_RATE = 300
|
|||
|
||||
; we expect to be loaded somewhere in the middle of user ram
|
||||
; TODO verify if this is safe with the Editor/Basic 2.0 ROM
|
||||
; or if there is a way to limit memory usage by the ROM
|
||||
.org $7000
|
||||
|
||||
; entry points
|
||||
|
@ -67,7 +68,7 @@ BAUD_RATE = 300
|
|||
initialized: .byte 0
|
||||
; saved IRQ vector
|
||||
oldvector: .word 0
|
||||
; current CRA value on CA1 change (bit contains the state of CA1)
|
||||
; state of the CA1 input: bit2=0 low level, bit2=1 high level
|
||||
ca1state: .byte 0
|
||||
; output buffer
|
||||
; this is 16bit, because we need to process start and stop bits as well
|
||||
|
@ -116,13 +117,18 @@ BAUD_RATE = 300
|
|||
lda #<irqhandler
|
||||
sta IRQVec+1
|
||||
|
||||
; the timer is only started when a transmission is actually initiated
|
||||
; but we'll enable VIA timer 1 interrupt
|
||||
lda VIA_IER
|
||||
ora #%01000000
|
||||
; VIA timer 2 cannot be enabled and disabled on the fly, so we'll
|
||||
; configure it here and arm it later
|
||||
; one-shot mode
|
||||
lda VIA_CR
|
||||
and #%11011111
|
||||
sta VIA_CR
|
||||
; enable interrupt
|
||||
; interrupt enable is done by setting bit7 and the desired interrupt
|
||||
; bit in IER to 1 (no need to read-modify-write)
|
||||
lda #%10100000
|
||||
sta VIA_IER
|
||||
|
||||
|
||||
; set up the PIA1 and VIA to process I/O
|
||||
; TXD: VIA PB3, output
|
||||
lda VIA_DDRB
|
||||
|
@ -186,9 +192,9 @@ BAUD_RATE = 300
|
|||
; IRQ disable
|
||||
and #%11111110
|
||||
sta PIA1_CRA
|
||||
; and the VIA timer 1
|
||||
lda VIA_IER
|
||||
and #%10111111
|
||||
; and the VIA timer 2
|
||||
; clearing is done by setting bit 7 to 0 and the desired interrupt to 1
|
||||
lda #%00100000
|
||||
sta VIA_IER
|
||||
|
||||
; we leave the I/O pins and the state alone
|
||||
|
@ -336,17 +342,13 @@ BAUD_RATE = 300
|
|||
rts
|
||||
|
||||
; start the timer
|
||||
@starttimer:
|
||||
; set up the VIA timer 1 to fire periodically
|
||||
starttimer:
|
||||
; arm VIA timer 2 by latching the counter
|
||||
period = PHI2_CLOCK/BAUD_RATE
|
||||
lda #>period
|
||||
sta VIA_T1CL
|
||||
lda #<period
|
||||
sta VIA_T1CH
|
||||
; VIA timer 1 free-run mode
|
||||
lda VIA_CR
|
||||
ora #%01000000
|
||||
sta VIA_CR
|
||||
; return
|
||||
rts
|
||||
|
||||
|
@ -398,20 +400,86 @@ BAUD_RATE = 300
|
|||
sta PIA1_CRA
|
||||
|
||||
@handletimer:
|
||||
; VIA timer 1 fired?
|
||||
; VIA timer 2 fired?
|
||||
lda VIA_IFR
|
||||
and #%01000000
|
||||
and #%00100000
|
||||
; zero, no interrupt
|
||||
beq @irqreturn
|
||||
|
||||
; handle timer interrupt
|
||||
; reset timer 1 interrupt
|
||||
; FIXME should we do this? perhaps someone else is also expecting a VIA interrupt
|
||||
; if not, we *must* reset it
|
||||
lda VIA_T1CL
|
||||
; timer 2 fired: rearm (we're in one-shot mode!), and clear the interrupt flag
|
||||
; FIXME this should be done earlier, for more accurate timing
|
||||
; FIXME we could skip writing the low byte here, writing the high byte is enough
|
||||
jsr starttimer
|
||||
|
||||
@processfifo:
|
||||
; TODO process input and output
|
||||
@loadout:
|
||||
; do we have more bits to send?
|
||||
lda outshift
|
||||
; yes, skip loading next byte
|
||||
bne @shiftout
|
||||
|
||||
; load next byte from FIFO
|
||||
|
||||
; do we have more bytes?
|
||||
lda outqlen
|
||||
; nope, skip ahead to input processing
|
||||
beq @shiftin
|
||||
|
||||
; load length
|
||||
ldx outqlen
|
||||
; decrement, also gives the index
|
||||
dex
|
||||
; load next byte from fifo
|
||||
lda outq,x
|
||||
; store new queue length
|
||||
stx outqlen
|
||||
|
||||
; prepare shift register
|
||||
; bit0 = start bit = 0
|
||||
; bit1..7 = data0..6
|
||||
clc
|
||||
rol
|
||||
sta outbuf
|
||||
; bit8 = data7
|
||||
; bit9 = stop bit = 1
|
||||
lda #%00000001
|
||||
rol
|
||||
sta outbuf+1
|
||||
; set shift length
|
||||
lda #10
|
||||
sta outshift
|
||||
|
||||
@shiftout:
|
||||
; make sure overflow flag is clear, so we can do unconditional branches
|
||||
clv
|
||||
; load shift register bit 0
|
||||
lda outbuf
|
||||
and #%00000001
|
||||
; set or clear?
|
||||
beq @shiftoutclear
|
||||
; set output
|
||||
lda #%00001000
|
||||
ora VIA_PB
|
||||
bvc @shiftoutstore
|
||||
@shiftoutclear:
|
||||
; clear output
|
||||
lda #%11110111
|
||||
and VIA_PB
|
||||
@shiftoutstore:
|
||||
sta VIA_PB
|
||||
|
||||
; shift the next bit in
|
||||
; 0 -> high byte -> carry
|
||||
lsr outbuf+1
|
||||
; carry -> low byte
|
||||
ror outbuf
|
||||
|
||||
; decrement counter
|
||||
dec outshift
|
||||
|
||||
@shiftin:
|
||||
; TODO process input bit-bang
|
||||
@storein:
|
||||
; TODO process input fifo
|
||||
|
||||
@irqreturn:
|
||||
; restore registers
|
||||
|
|
Loading…
Reference in a new issue