-
Notifications
You must be signed in to change notification settings - Fork 1
/
100hz-example.asm
96 lines (71 loc) · 3 KB
/
100hz-example.asm
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
\ ******************************************************************
\ * 100Hz Interrupt example.
\ * Using the User VIA so this can run alongside the MOS.
\ ******************************************************************
IRQ1V = &204
IRQ2V = &206
\ ******************************************************************
\ * Zero page vars
\ ******************************************************************
ORG &70
GUARD &9F
.timer_count skip 1
.old_irq skip 2
\ ******************************************************************
\ * Code
\ ******************************************************************
ORG &2000
GUARD &3000
.start
.main
{
sei ; disable CPU IRQs
lda #&C0 ; A=%10100000 (enable Timer 1 interrupt)
sta &FE6E ; set Interrupt enable register on User VIA
lda IRQ1V : sta old_irq
lda IRQ1V+1 : sta old_irq+1 ; save contents of IRQ1V
lda #LO(irq_handler) : sta IRQ1V
lda #HI(irq_handler) : sta IRQ1V+1 ; set new IRQ handler
\\ Set Timer 1 on User VIA to have continous interrupts.
lda #&40 ; A%=%01000000 (Timer 1 control)
sta &FE6B ; set Auxilary control register on User VIA
\\ Remember 6522 VIA timers run at 1MHz!
\\ Set Timer 1 _counter_ value on User VIA to 5000us.
lda #LO(5000) : sta &FE64
lda #HI(5000) : sta &FE65
\\ Set Timer 1 _latch_ value on User VIA to 10000us = 10ms = 100Hz
\\ Note that the latch takes 2us to load into the counter so we subtract 2 from the value to adjust.
lda #LO(10000 - 2) : sta &FE66
lda #HI(10000 - 2) : sta &FE67
cli ; enable CPU IRQs
rts
}
\ ******************************************************************
\ * IRQ handler
\ ******************************************************************
.irq_handler
{
lda &FC : pha ; store A on the stack
lda &FE6D ; read Interrupt flag register on User VIA
and #&80 ; check for Timer 1 interrupt
beq return_to_os ; if not then pass on to MOS IRQ handler
\\ Handle Timer interrupt.
\\ Clear Timer 1 interrupt flag by reading the Timer 1 low-order register.
lda &FE64
\\ Increment our counter.
inc timer_count
\\ Use bottom bit of the counter to set the ULA palette register.
\\ Set colour 0 to either 7 (black) or 6 (red).
lda timer_count
and #&01
eor #7 ; ULA colours are inverted
sta &fe21 ; ULA palette register
.return_to_os
pla : sta &FC ; restore A register
jmp (old_irq) ; jump to MOS IRQ handler
}
.end
\ ******************************************************************
\ * Save the code
\ ******************************************************************
SAVE "build/100hz.bin", start, end, main