summaryrefslogtreecommitdiff
path: root/roms/7seg_counter_irq_timer_smart_update.asm
blob: e18bfc7db2e40856536b179dd5b4a71ef4dc9e5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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

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)

 .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 ACR
 
 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
 txa
 pha
 tya
 pha
 bit T1LCL			; clear timer1 interrupt
 bit PORTA			; clear CA1 interrupt
 dec TICKS
 bne irq_done
 lda #INTERVAL
 sta TICKS
 inc CURRENT			; increment internal counter
irq_done:
 pla
 tay
 pla
 tax
 pla
 cli
 rti

 .org #$fffa
 .word nmi
 .word reset
 .word irq