summaryrefslogtreecommitdiff
path: root/roms
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-11-20 18:11:22 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2020-11-20 18:11:22 +0100
commit56ae2c7b25157e44c50ab982236fee8bbcca0463 (patch)
treed95a4bd2d8e7c21d30eedbe101440e5c080675bd /roms
parent4c167d48f0f972ff9a5f0e10247aab71c50a141b (diff)
download6502-56ae2c7b25157e44c50ab982236fee8bbcca0463.tar.gz
6502-56ae2c7b25157e44c50ab982236fee8bbcca0463.tar.bz2
some more IRQ work
Diffstat (limited to 'roms')
-rw-r--r--roms/7seg_counter_irq_timer.asm2
-rw-r--r--roms/7seg_counter_irq_timer_smart_update.asm16
-rw-r--r--roms/7seg_counter_irq_timer_start_stop.asm170
-rw-r--r--roms/README1
4 files changed, 182 insertions, 7 deletions
diff --git a/roms/7seg_counter_irq_timer.asm b/roms/7seg_counter_irq_timer.asm
index 8326762..b031886 100644
--- a/roms/7seg_counter_irq_timer.asm
+++ b/roms/7seg_counter_irq_timer.asm
@@ -4,8 +4,8 @@ T1LCL = $6004
T1LCH = $6005
ACR = $600b
PCR = $600c
+IFR = $600d
IER = $600e
-IFR = $600f
SER = %00000001
RCLK = %00000010
diff --git a/roms/7seg_counter_irq_timer_smart_update.asm b/roms/7seg_counter_irq_timer_smart_update.asm
index 2b009de..e18bfc7 100644
--- a/roms/7seg_counter_irq_timer_smart_update.asm
+++ b/roms/7seg_counter_irq_timer_smart_update.asm
@@ -4,8 +4,8 @@ T1LCL = $6004
T1LCH = $6005
ACR = $600b
PCR = $600c
+IFR = $600d
IER = $600e
-IFR = $600f
SER = %00000001
RCLK = %00000010
@@ -106,8 +106,10 @@ nmi:
irq:
pha
- phx
- phy
+ txa
+ pha
+ tya
+ pha
bit T1LCL ; clear timer1 interrupt
bit PORTA ; clear CA1 interrupt
dec TICKS
@@ -115,9 +117,11 @@ irq:
lda #INTERVAL
sta TICKS
inc CURRENT ; increment internal counter
-irq_done:
- ply
- plx
+irq_done:
+ pla
+ tay
+ pla
+ tax
pla
cli
rti
diff --git a/roms/7seg_counter_irq_timer_start_stop.asm b/roms/7seg_counter_irq_timer_start_stop.asm
new file mode 100644
index 0000000..3c7aed5
--- /dev/null
+++ b/roms/7seg_counter_irq_timer_start_stop.asm
@@ -0,0 +1,170 @@
+PORTA = $6001
+DDRA = $6003
+T1LCL = $6004
+T1LCH = $6005
+ACR = $600b
+PCR = $600c
+IFR = $600d
+IER = $600e
+
+SER = %00000001
+RCLK = %00000010
+SRCLK = %00000100
+
+INTERVAL = 33 ; increase counter 3 times per scond
+WAIT_INTERVAL = 99 ; wait one second on button press
+
+CURRENT = $0 ; current counter
+VISIBLE = $1 ; visible counter (as last printed to the 7-segment display)
+TICKS = $2 ; internal ticks counter (on overflow increment counter)
+RUNNING = $3 ; if counter is running or stopped
+COUNTER = $4 ; counter, increment on button press, show only shortly when button pressed
+
+ .org #$f800
+
+reset:
+ sei ; disallow interrupts during initialization
+
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ lda #%11000010 ; enable CA1 and timer1 interrupts
+ sta IER
+ lda #$0 ; negative edge triggering
+ sta PCR
+
+ lda ACR
+ and #$7F
+ ora #%01000000 ; setup timer for free running timer1, no PB7
+ sta ACR
+
+ lda #%00000111 ; set output on 7seg control pins of PORTA
+ sta DDRA
+
+ lda #$0 ; initialize 8-bit counter and tick counter
+ sta CURRENT
+ lda #$FF ; the visible counter is different at init, so we force
+ sta VISIBLE ; the drawing of the initial value
+ lda #INTERVAL
+ sta TICKS
+ lda #$FF
+ sta RUNNING
+
+ lda #$0 ; initialize button press counter
+ sta COUNTER
+
+ lda #$0F ; initialize counter of VIA timer1 ($270f = 9999 at 1MHz)
+ sta T1LCL
+ lda #$27
+ sta T1LCH
+
+ cli ; allow interrupts now
+
+mainloop: ; main loop, just print value of counter
+ sei
+ lda CURRENT
+ cmp VISIBLE
+ cli
+ beq mainloop
+ jsr print7seg ; update value
+ sei
+ lda CURRENT
+ sta VISIBLE
+ cli
+ jmp mainloop
+
+print7seg:
+ ldy #$8 ; 8 bits to shift
+loop7seg:
+ rol a
+ bcc zerobit ; C=0, bang a zero to SER
+onebit:
+ ldx #(SER) ; C=1, bang a one to SER
+ stx PORTA
+ ldx #(SER | SRCLK)
+ stx PORTA
+ ldx #(SER)
+ stx PORTA
+ jmp next
+zerobit:
+ ldx #$0 ; C=0, bang a zero to SER
+ stx PORTA
+ ldx #SRCLK
+ stx PORTA
+ ldx #$0
+ stx PORTA
+ jmp next
+next:
+ dey
+ bne loop7seg
+ rol a ; restore A register
+output:
+ ldx #0 ; bang RCLK to store output in latch
+ stx PORTA
+ ldx #RCLK
+ stx PORTA
+ ldx #0
+ stx PORTA
+ rts
+
+nmi:
+ rti
+
+irq:
+ pha ; save state
+ txa
+ pha
+ tya
+ pha
+ lda IFR ; check interrupt register of VIA
+ bpl irq_done ; bit 7 set? if not, not an interrupt of the VIA
+ asl ; bit 6 in sign (timer1)
+ bmi timer1
+ asl ; bit 5 in sign (timer2, unused)
+ asl ; bit 4 in sign (cb1, unused)
+ asl ; bit 3 in sign (cb2, unused)
+ asl ; bit 2 in sign (shift, unused)
+ asl ; bit 1 in sign (CA1)
+ bmi ca1
+ asl ; bit 0 in sign (CA2, unused)
+ jmp irq_done ; no more interrupt to handle from VIA
+
+timer1:
+ bit T1LCL ; clear timer1 interrupt
+ lda #$FF
+ cmp RUNNING
+ bne irq_done
+
+tick:
+ dec TICKS
+ bne irq_done
+ lda #INTERVAL
+ sta TICKS
+ inc CURRENT ; increment internal counter
+ jmp irq_done
+
+ca1:
+ lda RUNNING ; toggle running flag
+ eor #$FF
+ sta RUNNING
+ inc COUNTER
+ lda COUNTER
+ sta CURRENT
+ lda #WAIT_INTERVAL
+ sta TICKS
+ bit PORTA ; clear CA1 interrupt (button press)
+ jmp irq_done
+
+irq_done:
+ pla
+ tay
+ pla
+ tax
+ pla
+ cli
+ rti
+
+ .org #$fffa
+ .word nmi
+ .word reset
+ .word irq
diff --git a/roms/README b/roms/README
index d19afae..9e2c72c 100644
--- a/roms/README
+++ b/roms/README
@@ -23,3 +23,4 @@ wait.hex - test 65C02 WAI special opcode
7seg_counter_reset_on_irq.asm - counter, reset on IRQ (usable at 1 KHz)
7seg_counter_reset_on_irq_delay.asm - counter, reset on IRQ (usable at 1 MHz)
7seg_counter_irq_timer_smart_update.asm - counter, working version, update when needed, proper interrupt handling
+7seg_counter_irq_timer_start_stop.asm - counter, allow stopping/starting, distinguish kind of interrupts