summaryrefslogtreecommitdiff
path: root/roms/7seg_counter_irq_timer_smart_update.asm
blob: 2b009de1f13c0527cdbf885825b434dfc6a02a4b (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
PORTA = $6001
DDRA  = $6003
T1LCL = $6004
T1LCH = $6005
ACR   = $600b
PCR   = $600c
IER   = $600e
IFR   = $600f

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
 phx
 phy
 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: 
 ply
 plx
 pla
 cli
 rti

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