romdevtools 0.71.1 → 0.84.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +19 -16
- package/CHANGELOG.md +175 -0
- package/README.md +5 -5
- package/examples/README.md +1 -0
- package/examples/gametank/templates/gt_draw.h +91 -0
- package/examples/gametank/templates/gt_hud.h +89 -0
- package/examples/gametank/templates/gt_palette.h +59 -0
- package/examples/gametank/templates/gt_sound.h +90 -0
- package/examples/gametank/templates/gt_sprites.h +53 -0
- package/examples/gametank/templates/platformer.c +318 -0
- package/examples/gametank/templates/puzzle.c +295 -0
- package/examples/gametank/templates/racing.c +139 -0
- package/examples/gametank/templates/shmup.c +277 -0
- package/examples/gametank/templates/sports.c +119 -0
- package/package.json +23 -22
- package/src/cores/capabilities.js +24 -0
- package/src/cores/registry.js +7 -1
- package/src/host/LibretroHost.js +90 -17
- package/src/host/callbacks.js +20 -2
- package/src/host/cpu-state.js +17 -0
- package/src/host/gametank-acp-state.js +53 -0
- package/src/http/skill-doc.js +10 -6
- package/src/mcp/tools/audio.js +1 -1
- package/src/mcp/tools/cart-parts.js +76 -0
- package/src/mcp/tools/lifecycle.js +1 -1
- package/src/mcp/tools/platform-tools.js +9 -1
- package/src/platforms/gametank/lib/gt/audio/acp_image.bin +0 -0
- package/src/platforms/gametank/lib/gt/audio/audio_coprocessor.c +55 -0
- package/src/platforms/gametank/lib/gt/audio/audio_coprocessor.h +34 -0
- package/src/platforms/gametank/lib/gt/audio/audio_fw.asm +223 -0
- package/src/platforms/gametank/lib/gt/audio/audio_fw_blob.s +8 -0
- package/src/platforms/gametank/lib/gt/audio/instruments.c +79 -0
- package/src/platforms/gametank/lib/gt/audio/instruments.h +25 -0
- package/src/platforms/gametank/lib/gt/audio/music.c +370 -0
- package/src/platforms/gametank/lib/gt/audio/music.h +35 -0
- package/src/platforms/gametank/lib/gt/audio/note_numbers.h +132 -0
- package/src/platforms/gametank/lib/gt/audio/scaled_sines.raw +0 -0
- package/src/platforms/gametank/lib/gt/audio/sine_256_-63_63.bin +0 -0
- package/src/platforms/gametank/lib/gt/banking.c +29 -0
- package/src/platforms/gametank/lib/gt/banking.h +8 -0
- package/src/platforms/gametank/lib/gt/banking2.s +41 -0
- package/src/platforms/gametank/lib/gt/crt0.s +102 -0
- package/src/platforms/gametank/lib/gt/draw_logo.s +55 -0
- package/src/platforms/gametank/lib/gt/feature/persist/persist.c +103 -0
- package/src/platforms/gametank/lib/gt/feature/persist/persist.h +13 -0
- package/src/platforms/gametank/lib/gt/feature/random/random.c +40 -0
- package/src/platforms/gametank/lib/gt/feature/random/random.h +18 -0
- package/src/platforms/gametank/lib/gt/feature/text/text.c +111 -0
- package/src/platforms/gametank/lib/gt/feature/text/text.h +25 -0
- package/src/platforms/gametank/lib/gt/gametank.c +12 -0
- package/src/platforms/gametank/lib/gt/gametank.h +80 -0
- package/src/platforms/gametank/lib/gt/gametank_logo.inc +393 -0
- package/src/platforms/gametank/lib/gt/gen/assets/assets_index.h +9 -0
- package/src/platforms/gametank/lib/gt/gen/assets/sdk_default.h +5 -0
- package/src/platforms/gametank/lib/gt/gen/bank_nums.h +11 -0
- package/src/platforms/gametank/lib/gt/gen/modules_enabled.h +4 -0
- package/src/platforms/gametank/lib/gt/gen/modules_enabled.inc +4 -0
- package/src/platforms/gametank/lib/gt/gfx/draw_direct.c +132 -0
- package/src/platforms/gametank/lib/gt/gfx/draw_direct.h +75 -0
- package/src/platforms/gametank/lib/gt/gfx/draw_queue.c +177 -0
- package/src/platforms/gametank/lib/gt/gfx/draw_queue.h +35 -0
- package/src/platforms/gametank/lib/gt/gfx/draw_util.s +157 -0
- package/src/platforms/gametank/lib/gt/gfx/gfx_sys.c +43 -0
- package/src/platforms/gametank/lib/gt/gfx/gfx_sys.h +46 -0
- package/src/platforms/gametank/lib/gt/gfx/sprites.c +216 -0
- package/src/platforms/gametank/lib/gt/gfx/sprites.h +41 -0
- package/src/platforms/gametank/lib/gt/init.c +9 -0
- package/src/platforms/gametank/lib/gt/input.c +26 -0
- package/src/platforms/gametank/lib/gt/input.h +20 -0
- package/src/platforms/gametank/lib/gt/interrupt.s +67 -0
- package/src/platforms/gametank/lib/gt/vectors.s +14 -0
- package/src/platforms/gametank/lib/gt/wait.s +53 -0
- package/src/playtest/playtest.js +174 -26
- package/src/playtest/resampler/build.sh +19 -0
- package/src/playtest/resampler/index.mjs +75 -0
- package/src/playtest/resampler/resampler.c +129 -0
- package/src/playtest/resampler/resampler.mjs +2 -0
- package/src/playtest/resampler/resampler.wasm +0 -0
- package/src/toolchains/arm-none-eabi-gcc/gcc.js +39 -188
- package/src/toolchains/asar/asar.js +10 -15
- package/src/toolchains/cc65/cc65.js +82 -92
- package/src/toolchains/cc65/da65.js +12 -17
- package/src/toolchains/cc65/preset-resolver.js +13 -2
- package/src/toolchains/cc65/presets/gametank/gametank.h +80 -0
- package/src/toolchains/cc65/presets/gametank/sdk.cfg +32 -0
- package/src/toolchains/cc65/presets/gametank/sdk.crt0.s +61 -0
- package/src/toolchains/cc65/presets/gametank/sdk.vectors.s +11 -0
- package/src/toolchains/cc65/presets/gametank/single-bank.cfg +28 -0
- package/src/toolchains/cc65/presets/gametank/single-bank.crt0.s +71 -0
- package/src/toolchains/cc65/presets/gametank/single-bank.vectors.s +12 -0
- package/src/toolchains/common/c-build.js +109 -0
- package/src/toolchains/common/gcc-toolchain.js +164 -0
- package/src/toolchains/common/wasm-tool.js +101 -0
- package/src/toolchains/dasm/dasm.js +12 -18
- package/src/toolchains/gba-c/gba-c.js +253 -305
- package/src/toolchains/genesis-c/genesis-c.js +196 -225
- package/src/toolchains/index.js +58 -4
- package/src/toolchains/m68k-elf-gcc/gcc.js +39 -202
- package/src/toolchains/mips-c/mips-c.js +68 -78
- package/src/toolchains/mips-elf-gcc/gcc.js +55 -118
- package/src/toolchains/rgbds/rgbds.js +7 -19
- package/src/toolchains/sdcc/sdcc.js +35 -26
- package/src/toolchains/sh-c/sh-c.js +44 -52
- package/src/toolchains/sh-elf-gcc/gcc.js +55 -110
- package/src/toolchains/sjasm/sjasm.js +10 -14
- package/src/toolchains/snes-c/snes-c.js +125 -150
- package/src/toolchains/tcc816/tcc816.js +10 -15
- package/src/toolchains/vasm68k/vasm68k.js +11 -16
- package/src/toolchains/wladx/wladx.js +5 -17
- package/src/toolchains/z80/binutils.js +5 -11
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
#include "sprites.h"
|
|
2
|
+
#include "gametank.h"
|
|
3
|
+
#include "banking.h"
|
|
4
|
+
#include <zlib.h>
|
|
5
|
+
#include "bank_nums.h"
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
For each sprite bank:
|
|
9
|
+
HEADS mask of which quadrants contain the anchor of a sheet
|
|
10
|
+
OCCUPIED mask of which quadrants are allocated
|
|
11
|
+
HEADS:4 | OCCUPIED:4
|
|
12
|
+
*/
|
|
13
|
+
static char bank_occupied[8] = { 0, 0, 0, 0, 0, 0, 0, 0};
|
|
14
|
+
|
|
15
|
+
typedef union PointerUnion {
|
|
16
|
+
void* ptr;
|
|
17
|
+
struct {
|
|
18
|
+
char lsb, msb;
|
|
19
|
+
} b;
|
|
20
|
+
} PointerUnion;
|
|
21
|
+
|
|
22
|
+
#define SPRITE_SLOT_COUNT 32
|
|
23
|
+
static char frametable_L[SPRITE_SLOT_COUNT];
|
|
24
|
+
static char frametable_H[SPRITE_SLOT_COUNT];
|
|
25
|
+
static char frametable_B[SPRITE_SLOT_COUNT];
|
|
26
|
+
static char sprite_size_cache[SPRITE_SLOT_COUNT];
|
|
27
|
+
|
|
28
|
+
#define HEAD_CORNER_NW 16
|
|
29
|
+
#define HEAD_CORNER_NE 32
|
|
30
|
+
#define HEAD_CORNER_SW 64
|
|
31
|
+
#define HEAD_CORNER_SE 128
|
|
32
|
+
|
|
33
|
+
void load_spritesheet(const unsigned char* spriteData, char srcBank, char ramBank) {
|
|
34
|
+
char oldFlags = flagsMirror;
|
|
35
|
+
char oldBanks = banksMirror;
|
|
36
|
+
char bankNum = ramBank & 7;
|
|
37
|
+
char xbit = (ramBank & 8) << 4;
|
|
38
|
+
char ybit = (ramBank & 16) << 3;
|
|
39
|
+
push_rom_bank();
|
|
40
|
+
change_rom_bank(srcBank);
|
|
41
|
+
flagsMirror = DMA_ENABLE;
|
|
42
|
+
*dma_flags = flagsMirror;
|
|
43
|
+
*vram_VX = 0;
|
|
44
|
+
*vram_VY = 0;
|
|
45
|
+
*vram_GX = xbit;
|
|
46
|
+
*vram_GY = ybit;
|
|
47
|
+
*vram_WIDTH = 1;
|
|
48
|
+
*vram_HEIGHT = 1;
|
|
49
|
+
*vram_START = 1;
|
|
50
|
+
*vram_START = 0;
|
|
51
|
+
|
|
52
|
+
flagsMirror = 0;
|
|
53
|
+
*dma_flags = flagsMirror;
|
|
54
|
+
banksMirror = bankflip | GRAM_PAGE(ramBank);
|
|
55
|
+
*bank_reg = banksMirror;
|
|
56
|
+
inflatemem(vram, spriteData);
|
|
57
|
+
flagsMirror = oldFlags;
|
|
58
|
+
banksMirror = oldBanks;
|
|
59
|
+
*dma_flags = flagsMirror;
|
|
60
|
+
*bank_reg = banksMirror;
|
|
61
|
+
pop_rom_bank();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
void clear_spritebank(char bank) {
|
|
65
|
+
char oldFlags = flagsMirror;
|
|
66
|
+
char oldBanks = banksMirror;
|
|
67
|
+
char bankNum = bank & 7;
|
|
68
|
+
char xbit = (bank & 8) << 4;
|
|
69
|
+
char ybit = (bank & 16) << 3;
|
|
70
|
+
unsigned int i = 0;
|
|
71
|
+
flagsMirror = DMA_ENABLE;
|
|
72
|
+
*dma_flags = flagsMirror;
|
|
73
|
+
*vram_VX = 0;
|
|
74
|
+
*vram_VY = 0;
|
|
75
|
+
*vram_GX = xbit;
|
|
76
|
+
*vram_GY = ybit;
|
|
77
|
+
*vram_WIDTH = 1;
|
|
78
|
+
*vram_HEIGHT = 1;
|
|
79
|
+
*vram_START = 1;
|
|
80
|
+
*vram_START = 0;
|
|
81
|
+
|
|
82
|
+
flagsMirror = 0;
|
|
83
|
+
*dma_flags = flagsMirror;
|
|
84
|
+
banksMirror = bankflip | GRAM_PAGE(bank);
|
|
85
|
+
*bank_reg = banksMirror;
|
|
86
|
+
for(i = 0; i < 16384; i++) {
|
|
87
|
+
vram[i] = 0;
|
|
88
|
+
}
|
|
89
|
+
flagsMirror = oldFlags;
|
|
90
|
+
banksMirror = oldBanks;
|
|
91
|
+
*dma_flags = flagsMirror;
|
|
92
|
+
*bank_reg = banksMirror;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
SpriteSlot allocate_sprite(const SpritePage* sprite) {
|
|
96
|
+
register const SpritePage* current;
|
|
97
|
+
register char mask, i, free_page;
|
|
98
|
+
push_rom_bank();
|
|
99
|
+
change_rom_bank(BANK_LOADERS);
|
|
100
|
+
mask = 0; i = 1;
|
|
101
|
+
for(current = sprite; current != 0; current = current->next) {
|
|
102
|
+
if(current->data != 0) {
|
|
103
|
+
mask |= i;
|
|
104
|
+
}
|
|
105
|
+
i = i << 1;
|
|
106
|
+
}
|
|
107
|
+
free_page = 0xFF;
|
|
108
|
+
for(i = 0; i < 8; ++i) {
|
|
109
|
+
if(!(bank_occupied[i] & mask)) {
|
|
110
|
+
bank_occupied[i] |= mask | HEAD_CORNER_NW;
|
|
111
|
+
free_page = i;
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
if(mask == PAGE_MASK_FULL) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if(mask != PAGE_MASK_WIDE) {
|
|
118
|
+
//if mask doesn't span horizontally
|
|
119
|
+
if(!(bank_occupied[i] & (mask << 1))) {
|
|
120
|
+
bank_occupied[i] |= ((mask << 1) & 0b1010) | HEAD_CORNER_NE;
|
|
121
|
+
free_page = i | SPRITE_OFFSET_X_MASK;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if(mask != PAGE_MASK_TALL) {
|
|
126
|
+
//if mask doesn't span vertically
|
|
127
|
+
if(!(bank_occupied[i] & (mask << 2))) {
|
|
128
|
+
bank_occupied[i] |= ((mask << 2) & 0b1100) | HEAD_CORNER_SW;
|
|
129
|
+
free_page = i | SPRITE_OFFSET_Y_MASK;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if(mask == 1) {
|
|
134
|
+
if(!(bank_occupied[i] & (mask << 3))) {
|
|
135
|
+
bank_occupied[i] |= ((mask << 3) & 0b1000) | HEAD_CORNER_SE;
|
|
136
|
+
free_page = i | SPRITE_OFFSET_XY_MASK;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if(SPRITE_SLOT_INVALID(free_page)) {
|
|
143
|
+
pop_rom_bank();
|
|
144
|
+
return 0xFF;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
sprite_size_cache[free_page] = mask;
|
|
148
|
+
|
|
149
|
+
i = 1;
|
|
150
|
+
|
|
151
|
+
mask = (free_page & SPRITE_OFFSET_XY_MASK);
|
|
152
|
+
for(current = sprite; current != 0; current = current->next) {
|
|
153
|
+
if(current->data != 0) {
|
|
154
|
+
load_spritesheet(current->data, current->bank, (free_page & 7) | mask);
|
|
155
|
+
}
|
|
156
|
+
i = i << 1;
|
|
157
|
+
mask += 8;
|
|
158
|
+
}
|
|
159
|
+
pop_rom_bank();
|
|
160
|
+
return free_page;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
void set_sprite_frametable(SpriteSlot sprite, const Frame *frametable, char frametable_bank) {
|
|
164
|
+
frametable_B[sprite] = frametable_bank;
|
|
165
|
+
frametable_L[sprite] = (*((PointerUnion*)(&frametable))).b.lsb;
|
|
166
|
+
frametable_H[sprite] = (*((PointerUnion*)(&frametable))).b.msb;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
void free_sprite(SpriteSlot slot) {
|
|
170
|
+
register char anchor, clear_mask, heads;
|
|
171
|
+
anchor = slot & SPRITE_OFFSET_XY_MASK;
|
|
172
|
+
heads = bank_occupied[slot & 7] >> 4;
|
|
173
|
+
clear_mask = ~heads;
|
|
174
|
+
switch(slot & SPRITE_OFFSET_XY_MASK) {
|
|
175
|
+
case 0:
|
|
176
|
+
clear_mask &= 0b1111;
|
|
177
|
+
clear_mask |= 1;
|
|
178
|
+
if((clear_mask & 0b0110) != 0b0110) {
|
|
179
|
+
clear_mask &= 7;
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
case SPRITE_OFFSET_X_MASK:
|
|
183
|
+
clear_mask &= 0b1010;
|
|
184
|
+
clear_mask |= 2;
|
|
185
|
+
if(sprite_size_cache[slot] == 1) {
|
|
186
|
+
clear_mask &= 7;
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
case SPRITE_OFFSET_Y_MASK:
|
|
190
|
+
clear_mask &= 0b1100;
|
|
191
|
+
clear_mask |= 4;
|
|
192
|
+
if(sprite_size_cache[slot] == 1) {
|
|
193
|
+
clear_mask &= 7;
|
|
194
|
+
}
|
|
195
|
+
break;
|
|
196
|
+
case SPRITE_OFFSET_XY_MASK:
|
|
197
|
+
clear_mask = 0b1000;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
clear_mask |= (clear_mask << 4);
|
|
201
|
+
bank_occupied[slot & 7] &= ~clear_mask;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
Frame sprite_temp_frame;
|
|
205
|
+
static PointerUnion dsf_frametable;
|
|
206
|
+
|
|
207
|
+
void sprite_fetch_frame(SpriteSlot sprite, char frame) {
|
|
208
|
+
push_rom_bank();
|
|
209
|
+
change_rom_bank(frametable_B[sprite]);
|
|
210
|
+
dsf_frametable.b.lsb = frametable_L[sprite];
|
|
211
|
+
dsf_frametable.b.msb = frametable_H[sprite];
|
|
212
|
+
sprite_temp_frame = ((Frame*) dsf_frametable.ptr)[frame];
|
|
213
|
+
pop_rom_bank();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
void pushRect();
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#ifndef SPRITES_H
|
|
2
|
+
#define SPRITES_H
|
|
3
|
+
#include "gfx_sys.h"
|
|
4
|
+
|
|
5
|
+
#define SPRITE_SLOT_INVALID(x) (x & 0b11100000)
|
|
6
|
+
|
|
7
|
+
//Sprite sheets MUST be one of these
|
|
8
|
+
#define PAGE_MASK_SINGLE 1
|
|
9
|
+
#define PAGE_MASK_WIDE 3
|
|
10
|
+
#define PAGE_MASK_TALL 5
|
|
11
|
+
#define PAGE_MASK_FULL 15
|
|
12
|
+
|
|
13
|
+
#define SPRITE_OFFSET_X_MASK 8
|
|
14
|
+
#define SPRITE_OFFSET_Y_MASK 16
|
|
15
|
+
#define SPRITE_OFFSET_XY_MASK 24
|
|
16
|
+
|
|
17
|
+
#define SPRITE_OFFSET_X(slot) ((slot & SPRITE_OFFSET_X_MASK) ? 128 : 0)
|
|
18
|
+
#define SPRITE_OFFSET_Y(slot) ((slot & SPRITE_OFFSET_Y_MASK) ? 128 : 0)
|
|
19
|
+
|
|
20
|
+
#define CONSTRUCT_SPRITE_SLOT(slot, quadrant) ((slot) | (quadrant))
|
|
21
|
+
|
|
22
|
+
typedef char SpriteSlot;
|
|
23
|
+
|
|
24
|
+
typedef struct SpritePage {
|
|
25
|
+
const unsigned char* data;
|
|
26
|
+
char bank;
|
|
27
|
+
const struct SpritePage* next;
|
|
28
|
+
} SpritePage;
|
|
29
|
+
|
|
30
|
+
extern Frame sprite_temp_frame;
|
|
31
|
+
|
|
32
|
+
void load_spritesheet(const unsigned char* spriteData, char srcBank, char ramBank);
|
|
33
|
+
void clear_spritebank(char bank);
|
|
34
|
+
|
|
35
|
+
void sprite_fetch_frame(SpriteSlot sprite, char frame);
|
|
36
|
+
|
|
37
|
+
SpriteSlot allocate_sprite(const SpritePage* sprite);
|
|
38
|
+
void set_sprite_frametable(SpriteSlot sprite, const Frame *frametable, char frametable_bank);
|
|
39
|
+
void free_sprite(SpriteSlot slot);
|
|
40
|
+
|
|
41
|
+
#endif
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#include "input.h"
|
|
2
|
+
#include "gametank.h"
|
|
3
|
+
|
|
4
|
+
int player1_buttons = 0, player1_old_buttons = 0, player1_new_buttons = 0;
|
|
5
|
+
int player2_buttons = 0, player2_old_buttons = 0, player2_new_buttons = 0;
|
|
6
|
+
|
|
7
|
+
#pragma optimize (push, off)
|
|
8
|
+
void update_inputs(){
|
|
9
|
+
char inputsA, inputsB;
|
|
10
|
+
inputsA = *gamepad_2;
|
|
11
|
+
inputsA = *gamepad_1;
|
|
12
|
+
inputsB = *gamepad_1;
|
|
13
|
+
|
|
14
|
+
player1_old_buttons = player1_buttons;
|
|
15
|
+
player1_buttons = ~((((int) inputsB) << 8) | inputsA);
|
|
16
|
+
player1_buttons &= INPUT_MASK_ALL_KEYS;
|
|
17
|
+
player1_new_buttons = player1_buttons & ~player1_old_buttons;
|
|
18
|
+
|
|
19
|
+
inputsA = *gamepad_2;
|
|
20
|
+
inputsB = *gamepad_2;
|
|
21
|
+
player2_old_buttons = player2_buttons;
|
|
22
|
+
player2_buttons = ~((((int) inputsB) << 8) | inputsA);
|
|
23
|
+
player2_buttons &= INPUT_MASK_ALL_KEYS;
|
|
24
|
+
player2_new_buttons = player2_buttons & ~player2_old_buttons;
|
|
25
|
+
}
|
|
26
|
+
#pragma optimize (pop)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#ifndef INPUT_H
|
|
2
|
+
#define INPUT_H
|
|
3
|
+
|
|
4
|
+
extern int player1_buttons, player1_old_buttons, player1_new_buttons;
|
|
5
|
+
extern int player2_buttons, player2_old_buttons, player2_new_buttons;
|
|
6
|
+
|
|
7
|
+
#define INPUT_MASK_UP 2056
|
|
8
|
+
#define INPUT_MASK_DOWN 1028
|
|
9
|
+
#define INPUT_MASK_LEFT 512
|
|
10
|
+
#define INPUT_MASK_RIGHT 256
|
|
11
|
+
#define INPUT_MASK_A 16
|
|
12
|
+
#define INPUT_MASK_B 4096
|
|
13
|
+
#define INPUT_MASK_C 8192
|
|
14
|
+
#define INPUT_MASK_START 32
|
|
15
|
+
#define INPUT_MASK_ALL_KEYS (INPUT_MASK_UP|INPUT_MASK_DOWN|INPUT_MASK_LEFT|INPUT_MASK_RIGHT|INPUT_MASK_A|INPUT_MASK_B|INPUT_MASK_C|INPUT_MASK_START)
|
|
16
|
+
#define INPUT_MASK_ANY_DIRECTION (INPUT_MASK_UP|INPUT_MASK_DOWN|INPUT_MASK_LEFT|INPUT_MASK_RIGHT)
|
|
17
|
+
|
|
18
|
+
void update_inputs();
|
|
19
|
+
|
|
20
|
+
#endif
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
; ---------------------------------------------------------------------------
|
|
2
|
+
; interrupt.s
|
|
3
|
+
; ---------------------------------------------------------------------------
|
|
4
|
+
;
|
|
5
|
+
; Interrupt handler.
|
|
6
|
+
;
|
|
7
|
+
; Checks for a BRK instruction and returns from all valid interrupts.
|
|
8
|
+
|
|
9
|
+
.include "modules_enabled.inc"
|
|
10
|
+
|
|
11
|
+
.import _frameflag
|
|
12
|
+
.import _draw_busy
|
|
13
|
+
.export _irq_int, _nmi_int
|
|
14
|
+
|
|
15
|
+
.ifdef ENABLE_MODULE_DRAWQUEUE
|
|
16
|
+
.import _next_draw_queue, _queue_end, _queue_pending, _queue_start
|
|
17
|
+
.endif
|
|
18
|
+
|
|
19
|
+
.pc02
|
|
20
|
+
|
|
21
|
+
DMA_Start = $4006
|
|
22
|
+
|
|
23
|
+
.segment "CODE"
|
|
24
|
+
|
|
25
|
+
.PC02 ; Force 65C02 assembly mode
|
|
26
|
+
|
|
27
|
+
; ---------------------------------------------------------------------------
|
|
28
|
+
; Non-maskable interrupt (NMI) service routine
|
|
29
|
+
|
|
30
|
+
_nmi_int:
|
|
31
|
+
PHA
|
|
32
|
+
LDA $1FFF
|
|
33
|
+
BNE nmi_done
|
|
34
|
+
STZ _frameflag
|
|
35
|
+
nmi_done:
|
|
36
|
+
PLA
|
|
37
|
+
RTI
|
|
38
|
+
|
|
39
|
+
; ---------------------------------------------------------------------------
|
|
40
|
+
; Maskable interrupt (IRQ) service routine
|
|
41
|
+
|
|
42
|
+
.ifdef ENABLE_MODULE_DRAWQUEUE
|
|
43
|
+
_irq_int:
|
|
44
|
+
PHX ; Save X register contents to stack
|
|
45
|
+
PHA
|
|
46
|
+
PHY
|
|
47
|
+
|
|
48
|
+
;make sure DMA isn't running then compare head and tail of queue
|
|
49
|
+
;to determine whether there is more to process
|
|
50
|
+
STZ DMA_Start
|
|
51
|
+
STZ _queue_pending
|
|
52
|
+
STZ _draw_busy
|
|
53
|
+
LDA _queue_start
|
|
54
|
+
CMP _queue_end
|
|
55
|
+
BEQ finish_irq
|
|
56
|
+
JSR _next_draw_queue
|
|
57
|
+
finish_irq:
|
|
58
|
+
PLY
|
|
59
|
+
PLA ; Restore accumulator contents
|
|
60
|
+
PLX ; Restore X register contents
|
|
61
|
+
RTI ; Return from all IRQ interrupts
|
|
62
|
+
.else
|
|
63
|
+
_irq_int:
|
|
64
|
+
STZ DMA_Start
|
|
65
|
+
STZ _draw_busy
|
|
66
|
+
RTI
|
|
67
|
+
.endif
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
; ---------------------------------------------------------------------------
|
|
2
|
+
; vectors.s
|
|
3
|
+
; ---------------------------------------------------------------------------
|
|
4
|
+
;
|
|
5
|
+
; Defines the interrupt vector table.
|
|
6
|
+
|
|
7
|
+
.import _init
|
|
8
|
+
.import _nmi_int, _irq_int
|
|
9
|
+
|
|
10
|
+
.segment "VECTORS"
|
|
11
|
+
|
|
12
|
+
.addr _nmi_int ; NMI vector
|
|
13
|
+
.addr _init ; Reset vector
|
|
14
|
+
.addr _irq_int ; IRQ/BRK vector
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
; ---------------------------------------------------------------------------
|
|
2
|
+
; wait.s
|
|
3
|
+
; ---------------------------------------------------------------------------
|
|
4
|
+
;
|
|
5
|
+
; Wait for interrupt and return
|
|
6
|
+
|
|
7
|
+
.export _wait, _stop, _nop5, _nop10
|
|
8
|
+
|
|
9
|
+
; ---------------------------------------------------------------------------
|
|
10
|
+
; Wait for interrupt: Forces the assembler to emit a WAI opcode ($CB)
|
|
11
|
+
; ---------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
.segment "CODE"
|
|
14
|
+
|
|
15
|
+
.proc _wait: near
|
|
16
|
+
|
|
17
|
+
.byte $CB ; Inserts a WAI opcode
|
|
18
|
+
RTS ; Return to caller
|
|
19
|
+
|
|
20
|
+
.endproc
|
|
21
|
+
|
|
22
|
+
; ---------------------------------------------------------------------------
|
|
23
|
+
; Stop: Forces the assembler to emit a STP opcode ($DB)
|
|
24
|
+
; ---------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
.proc _stop: near
|
|
27
|
+
|
|
28
|
+
.byte $DB ; Inserts a STP opcode
|
|
29
|
+
|
|
30
|
+
.endproc
|
|
31
|
+
|
|
32
|
+
.proc _nop5
|
|
33
|
+
NOP
|
|
34
|
+
NOP
|
|
35
|
+
NOP
|
|
36
|
+
NOP
|
|
37
|
+
NOP
|
|
38
|
+
RTS
|
|
39
|
+
.endproc
|
|
40
|
+
|
|
41
|
+
.proc _nop10
|
|
42
|
+
NOP
|
|
43
|
+
NOP
|
|
44
|
+
NOP
|
|
45
|
+
NOP
|
|
46
|
+
NOP
|
|
47
|
+
NOP
|
|
48
|
+
NOP
|
|
49
|
+
NOP
|
|
50
|
+
NOP
|
|
51
|
+
NOP
|
|
52
|
+
RTS
|
|
53
|
+
.endproc
|