gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/libc/targets/mos6502/nes/timer_isr.s
1 ;
2 ; Emulation of GB's timer interrupt (TIM) via calls from NES's 60Hz / 50Hz vblank NMI
3 ;
4 ; Timer values are based on GBC running in double-speed mode
5 ;
6
7 .include "global.s"
8
9 .area _DATA
10 _TIMA_REG:: .ds 2
11 _TMA_REG:: .ds 1
12 _TAC_REG:: .ds 1
13
14 .area _XINIT
15 .db 0x00
16 .db 0x00
17 .db .TIMER_VBLANK_PARITY_MODE_SYSTEM_60HZ
18 .db 0x04
19
20 .area _HOME
21
22 ; Lookup tables for adjusted rates based on GB TAC register
23 .TAC_lookup_lo:
24 ; PAL
25 .db <163 ; 8192 / 50 = 163.84 ~= 164
26 .db <10486 ; 524288 / 50 = 10485.76 ~= 10486
27 .db <2621 ; 131072 / 50 = 2621.44 ~= 2621
28 .db <655 ; 32768 / 50 = 655.36 ~= 655
29 ; NTSC
30 .db <136 ; 8192 / 60 = 136.5333... ~= 136
31 .db <8738 ; 524288 / 60 = 8738.1333... ~= 8378
32 .db <2184 ; 131072 / 60 = 2184.5333... ~= 2184
33 .db <546 ; 32768 / 60 = 546.1333... ~= 546
34 ;
35 .TAC_lookup_hi:
36 ; PAL
37 .db >163 ; 8192 / 50 = 163.84 ~= 164
38 .db >10486 ; 524288 / 50 = 10485.76 ~= 10486
39 .db >2621 ; 131072 / 50 = 2621.44 ~= 2621
40 .db >655 ; 32768 / 50 = 655.36 ~= 655
41 ; NTSC
42 .db >136 ; 8192 / 60 = 136.5333... ~= 136
43 .db >8738 ; 524288 / 60 = 8738.1333... ~= 8378
44 .db >2184 ; 131072 / 60 = 2184.5333... ~= 2184
45 .db >546 ; 32768 / 60 = 546.1333... ~= 546
46
47 ;
48 ; Call timer interrupt repeatedly to emulate desired GB playback rate via vblank NMI.
49 ;
50 .tim_emulation::
51 lda _TAC_REG
52 and #7
53 ; Early-out if timer enabled bit not set
54 cmp #4
55 bcs 1$
56 rts
57 1$:
58 and #3
59 bit *__SYSTEM
60 bmi .tim_emulation_dendy
61 bvs .tim_emulation_pal
62 ; +4 to index NTSC table
63 ora #0x04
64 .tim_emulation_dendy:
65 .tim_emulation_pal:
66 pha ; Save TAC lookup index to stack
67 .tim_emulation_loop:
68 ; Finished when TIMA_REG <= 0
69 bit _TIMA_REG+1
70 bmi .tim_emulation_calls_done
71 lda _TIMA_REG
72 beq .tim_emulation_calls_done
73 ; Skip if handler disabled (check for RTS)
74 lda .jmp_to_TIM_isr
75 cmp #0x60
76 beq .tim_emulation_isr_disabled
77 ; Save REGTEMP to stack
78 ldx #17
79 4$:
80 lda *ALL_REGTEMPS_BEGIN,x
81 pha
82 dex
83 bpl 4$
84 ; Call handler
85 jsr .jmp_to_TIM_isr
86 ; Restore REGTEMP from stack
87 ldx #0
88 5$:
89 pla
90 sta *ALL_REGTEMPS_BEGIN,x
91 inx
92 cpx #18
93 bne 5$
94 .tim_emulation_isr_disabled:
95 ; TIMA_REG += TMA_REG
96 lda _TIMA_REG
97 clc
98 adc _TMA_REG
99 sta _TIMA_REG
100 lda _TIMA_REG+1
101 adc #0xFF
102 sta _TIMA_REG+1
103 jmp .tim_emulation_loop
104 ;
105 .tim_emulation_calls_done:
106 pla ; Restore TAC lookup index from stack
107 tay
108 ; TIMA_REG += initial value
109 lda _TIMA_REG
110 clc
111 adc .TAC_lookup_lo,y
112 sta _TIMA_REG
113 lda _TIMA_REG+1
114 adc .TAC_lookup_hi,y
115 sta _TIMA_REG+1
116 rts
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.