-
Notifications
You must be signed in to change notification settings - Fork 115
/
nmihook.a65
148 lines (140 loc) · 3.08 KB
/
nmihook.a65
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "memmap.i65"
; *=$2A04
nmihook:
php
rep #$20 : .al
pha
lda @$004218 ; initial backup as early as possible
sta @NMI_PAD
sep #$20 : .as
- bra - ; branch1 filled in by FPGA
; rules for branch tgt:
; if (buttons disabled OR manual read in progress) AND wram patching enabled: nmi_patches
; if (buttons disabled OR manual read in progress) AND wram patching disabled: nmi_exit
; if buttons enabled AND AJR enabled AND CMD != 0: nmi_echocmd
; if buttons enabled AND AJR enabled AND CMD == 0 AND wram patching enabled: nmi_patches
; if buttons enabled AND AJR enabled AND CMD == 0 AND wram patching disabled: nmi_exit
; if buttons enabled AND AJR disabled: nmi_manual_read
; FPGA state:
; - wram patching enabled (MCU side: cheats enabled AND wram cheats present) AND wram gate
; - wram patching gate (FPGA side toggle)
; - buttons enabled
; - manual read in progress
; - AJR enabled
; wram patching gate (same as cheat enable):
; - if buttons enabled and CMD = $83: disable
; - if buttons enabled and CMD = $82: enable
nmi_manual_read:
phb
phd
lda #$2b
xba
lda #$00
tcd
phk
plb
lda #$01
sta $4016
stz $4016
rep #$10 : .xl
phx
ldx #$0008
- lda $4016
ror
rol <NMI_PAD+1
dex
bne -
ldx #$0008
- lda $4016
ror
rol <NMI_PAD
dex
bne -
plx
pld
plb
; button combination -> command is mapped by FPGA
nmi_echocmd: ; echo cmd to MCU for misc handling
lda @NMI_CMD
sta @MCU_CMD
; 2nd branch point to determine whether to jump to WRAM cheats,
; halt system (for reset), or continue
- bra - ; nmi_patches, nmi_stop, or nmi_exit
nmi_patches:
jsr NMI_WRAM_CHEATS
nmi_exit:
; clean up
sta @NMI_VECT_DISABLE
rep #$20 : .al
pla
plp
jmp ($ff77) ; '77' is replaced by FPGA depending on hook entry
nmi_stop:
sei
sep #$20 : .as
phk
plb
stz $4200
lda #$80
sta $2100
- bra -
resethook: ; EMULATION MODE
.as : .xs
bra resethook_skip
; mask interrupt handler call
sei
; x stores the count of scanlines
ldx #$20
ldy #$00
; setup irq on h-position $100. this value was acquired via manual training
lda #$00
sta $4207
inc
sta $4208
lda #$10
sta $4200
- wai
; sep seems to set the alignment correctly so an integer value in $4207/$4208 detects h-blank
; there seem to be more distinct phases now. different padding may change this.
sep #$20
lda $4212
; ignore lines in v-blank
bmi +
; decrement non-vblank scanlines encountered
dex
; shift h-blank bit into upper position
asl
; no error if not in h-blank
bpl +
; increment error counter if h-blank is set (early h-blank)
iny
; ack interrupt and check if we have hit all scanlines
+ lda $4211
cpx #$00
bne -
; stop interrupts and check if we have any errors
stz $4200
dex
stx $4207
dey
bmi +
; perform reset
lda #$85
sta @MCU_CMD
- bra -
; clean up state
+ inx
iny
resethook_skip:
lda #$86
sta @MCU_CMD
resethook_loop:
- lda $4212
bpl -
- lda $4212
bmi -
lda $213f
bmi resethook_loop
stz NMI_VECT_DISABLE
jmp ($fffc)
.byt "bram_end"