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
|