1pub mod sizes {
2 use crate::constants::{LAYER_COUNT, PALETTE_COUNT, SPRITE_COUNT};
3 use crate::input::controller_type;
4
5 pub const CODE_BANK: u16 = 4200;
6 pub const RAM_BANK: u16 = 4200;
7 pub const MAIN_CODE: u16 = 9000;
8 pub const MAIN_RAM: u16 = 9000;
9 pub const SOUND: u16 = 30;
10 pub const WAVE_TABLE: u16 = 16;
11 pub const INPUT: u16 = 2;
13 pub const CODE_BANK_ID: u16 = 1;
14 pub const RAM_BANK_ID: u16 = 1;
15 pub const SAVE_BANK_ID: u16 = 1;
16 pub const SAVE_BANK: u16 = 4096;
17 pub const SAVE_CONTROL: u16 = 1;
18 pub const SPRITE: u16 = 5;
19 pub const SPRITE_TABLE: u16 = SPRITE_COUNT as u16 * SPRITE;
22 pub const LAYERS_HEADER: u16 = 3 * LAYER_COUNT as u16;
24 pub const LAYERS_CONTENT: u16 = 1320 * 2 * LAYER_COUNT as u16;
26 pub const PALETTE: u16 = 16 * 3; pub const PALETTES_TOTAL: u16 = PALETTE * PALETTE_COUNT as u16;
29 pub const ATLAS: u16 = 100 * 40;
31 pub const ATLAS_BANK_ID: u16 = 1;
32 pub const STACK: u16 = 1000;
33 pub const SP: u16 = 2;
34 pub const FP: u16 = 2;
35 pub const TIMER_CONTROL: u16 = 2;
36 pub const TIMER_VALUE: u16 = 1;
37 pub const TIMERS: u16 = TIMER_CONTROL + TIMER_VALUE * 4;
38 pub const VLINE: u16 = 1;
39 pub const IRQ_RET_ADDR: u16 = 2;
40 pub const IRQ_REG_DUMP: u16 = 8;
41 pub const IRQ_CONTROL: u16 = 1;
42 pub const IRQ_INTERNAL: u16 = IRQ_RET_ADDR + IRQ_REG_DUMP + IRQ_CONTROL;
43 pub const DATETIME: u16 = 6;
45 pub const RAND: u16 = 1;
46 pub const CONTROLLER_PALETTE: u16 = 3 * 8;
48 pub const CONTROLLER_TABLE: u16 = 3 * controller_type::COUNT as u16;
51 pub const CONTROLLER_TOTAL: u16 = CONTROLLER_PALETTE + CONTROLLER_TABLE;
52 pub const ATLAS_TOTAL: u16 = (ATLAS + ATLAS_BANK_ID) * 4;
53 pub const LAYER_TOTAL: u16 = LAYERS_CONTENT + LAYERS_HEADER;
54 pub const GRAPHICS_TOTAL: u16 =
55 LAYER_TOTAL + SPRITE_TABLE + PALETTES_TOTAL + ATLAS_TOTAL + CONTROLLER_TOTAL;
56 pub const SYSTEM_TOTAL: u16 = MAIN_CODE
57 + MAIN_RAM
58 + CODE_BANK
59 + CODE_BANK
60 + RAM_BANK
61 + RAM_BANK
62 + CODE_BANK_ID
63 + CODE_BANK_ID
64 + RAM_BANK_ID
65 + RAM_BANK_ID
66 + STACK
67 + SP
68 + FP
69 + TIMERS
70 + IRQ_INTERNAL
71 + VLINE;
72 pub const HARDWARE_TOTAL: u16 =
73 WAVE_TABLE + SOUND + INPUT + SAVE_BANK_ID + SAVE_BANK + SAVE_CONTROL + DATETIME + RAND;
74 pub const RESERVED: u16 = 106;
75 pub const TOTAL: usize =
76 (GRAPHICS_TOTAL + SYSTEM_TOTAL + HARDWARE_TOTAL) as usize + RESERVED as usize;
77}
78
79#[rustfmt::skip]
80pub mod address {
81 pub const CODE: u16 = 0x0; pub const CODE_BANK_1: u16 = 0x2328; pub const CODE_BANK_2: u16 = 0x3390; pub const RAM: u16 = 0x43F8; pub const RAM_BANK_1: u16 = 0x6720; pub const RAM_BANK_2: u16 = 0x7788; pub const INPUT: u16 = 0x87F0; pub const SOUND: u16 = 0x87F2; pub const SAVE_BANK_ID: u16 = 0x8810; pub const SAVE_BANK: u16 = 0x8811; pub const ATLAS1: u16 = 0x9811; pub const ATLAS2: u16 = 0xA7B1; pub const ATLAS3: u16 = 0xB751; pub const ATLAS4: u16 = 0xC6F1; pub const PALETTES: u16 = 0xD691; pub const SPRITE_TABLE: u16 = 0xD751; pub const LAYER_HEADERS: u16 = 0xDC4C; pub const LAYERS: u16 = 0xDC55; pub const CODE_BANK_1_ID: u16 = 0xFB45; pub const RAM_BANK_1_ID: u16 = 0xFB46; pub const ATLAS1_BANK_ID: u16 = 0xFB47; pub const ATLAS2_BANK_ID: u16 = 0xFB48; pub const ATLAS3_BANK_ID: u16 = 0xFB49; pub const ATLAS4_BANK_ID: u16 = 0xFB4A; pub const SP: u16 = 0xFB4B; pub const FP: u16 = 0xFB4D; pub const TIMER_CONTROL: u16 = 0xFB4F; pub const TIMER_VALUE1: u16 = 0xFB51; pub const TIMER_VALUE2: u16 = 0xFB52; pub const TIMER_VALUE3: u16 = 0xFB53; pub const TIMER_VALUE4: u16 = 0xFB54; pub const IRQ_RET_ADDR: u16 = 0xFB55; pub const IRQ_REG_DUMP: u16 = 0xFB57; pub const CONTROLLER_PALETTE: u16 = 0xFB5F; pub const CONTROLLER_TABLE: u16 = 0xFB77; pub const IRQ_CONTROL: u16 = 0xFB92; pub const SAVE_CONTROL: u16 = 0xFB93; pub const DATETIME: u16 = 0xFB94; pub const RAND: u16 = 0xFB9A; pub const WAVE_TABLE: u16 = 0xFB9B; pub const CODE_BANK_2_ID: u16 = 0xFBAB; pub const RAM_BANK_2_ID: u16 = 0xFBAC; pub const VLINE: u16 = 0xFBAD; pub const RESERVED: u16 = 0xFBAE; pub const STACK: u16 = 0xFC18; pub const MAX: u16 = 0xFFFF; pub mod interrupt {
129 pub const IRQ_INPUT: u16 = 0x0200; pub const IRQ_SCREEN_DRAW: u16 = 0x0220; pub const IRQ_TIMER: u16 = 0x0240; pub const IRQ_CONTROLLER: u16 = 0x0260; pub const IRQ_DATETIME: u16 = 0x0280; pub const IRQ_LINE_DRAW: u16 = 0x02A0; }
136
137 pub const fn is_special_memory(address: u16) -> bool {
139 matches!(
140 address,
141 CODE_BANK_1_ID
142 | RAM_BANK_1_ID
143 |CODE_BANK_2_ID
144 | RAM_BANK_2_ID
145 | ATLAS1_BANK_ID
146 | ATLAS2_BANK_ID
147 | ATLAS3_BANK_ID
148 | ATLAS4_BANK_ID
149 | TIMER_CONTROL
150 | SAVE_CONTROL
151 | SAVE_BANK_ID
152 | SOUND
153 )
154 }
155}
156
157pub mod save_flags {
158 pub const AUTO_SAVE: u8 = 4;
159 pub const WRITE: u8 = 0;
160}
161
162pub mod interrupt_flags {
163 pub const IRQ_SCREEN_DRAW: u8 = 1;
164 pub const IRQ_TIMER: u8 = 2;
165 pub const IRQ_DATETIME: u8 = 4;
166 pub const IRQ_CONTROLLER: u8 = 8;
167 pub const IRQ_INPUT: u8 = 16;
168 pub const IRQ_LINE_DRAW: u8 = 32;
169}
170
171#[cfg(test)]
172mod test {
173 use crate::mem::sizes::{RESERVED, TOTAL};
174 use crate::mem::{address, sizes};
175
176 #[test]
177 #[allow(clippy::assertions_on_constants)] fn test_values() {
179 assert_eq!(TOTAL, 65536);
180 assert!(RESERVED > 6);
183 }
184
185 #[test]
186 fn test_sizes_address() {
187 assert_eq!(address::CODE, 0);
188 assert_eq!(address::CODE_BANK_1, address::CODE + sizes::MAIN_CODE);
189 assert_eq!(
190 address::CODE_BANK_2,
191 address::CODE_BANK_1 + sizes::CODE_BANK
192 );
193 assert_eq!(address::RAM, address::CODE_BANK_2 + sizes::CODE_BANK);
194 assert_eq!(address::RAM_BANK_1, address::RAM + sizes::MAIN_RAM);
195 assert_eq!(address::RAM_BANK_2, address::RAM_BANK_1 + sizes::RAM_BANK);
196 assert_eq!(address::INPUT, address::RAM_BANK_2 + sizes::RAM_BANK);
197 assert_eq!(address::SOUND, address::INPUT + sizes::INPUT);
198 assert_eq!(address::SAVE_BANK_ID, address::SOUND + sizes::SOUND);
199 assert_eq!(
200 address::SAVE_BANK,
201 address::SAVE_BANK_ID + sizes::SAVE_BANK_ID
202 );
203 assert_eq!(address::ATLAS1, address::SAVE_BANK + sizes::SAVE_BANK);
204 assert_eq!(address::ATLAS2, address::ATLAS1 + sizes::ATLAS);
205 assert_eq!(address::ATLAS3, address::ATLAS2 + sizes::ATLAS);
206 assert_eq!(address::ATLAS4, address::ATLAS3 + sizes::ATLAS);
207 assert_eq!(address::PALETTES, address::ATLAS4 + sizes::ATLAS);
208 assert_eq!(
209 address::SPRITE_TABLE,
210 address::PALETTES + sizes::PALETTES_TOTAL
211 );
212 assert_eq!(
213 address::LAYER_HEADERS,
214 address::SPRITE_TABLE + sizes::SPRITE_TABLE
215 );
216 assert_eq!(
217 address::LAYERS,
218 address::LAYER_HEADERS + sizes::LAYERS_HEADER
219 );
220 assert_eq!(
221 address::CODE_BANK_1_ID,
222 address::LAYERS + sizes::LAYERS_CONTENT
223 );
224 assert_eq!(
225 address::RAM_BANK_1_ID,
226 address::CODE_BANK_1_ID + sizes::CODE_BANK_ID
227 );
228 assert_eq!(
229 address::ATLAS1_BANK_ID,
230 address::RAM_BANK_1_ID + sizes::RAM_BANK_ID
231 );
232 assert_eq!(
233 address::ATLAS2_BANK_ID,
234 address::ATLAS1_BANK_ID + sizes::ATLAS_BANK_ID
235 );
236 assert_eq!(
237 address::ATLAS3_BANK_ID,
238 address::ATLAS2_BANK_ID + sizes::ATLAS_BANK_ID
239 );
240 assert_eq!(
241 address::ATLAS4_BANK_ID,
242 address::ATLAS3_BANK_ID + sizes::ATLAS_BANK_ID
243 );
244 assert_eq!(address::SP, address::ATLAS4_BANK_ID + sizes::ATLAS_BANK_ID);
245 assert_eq!(address::FP, address::SP + sizes::SP);
246 assert_eq!(address::TIMER_CONTROL, address::FP + sizes::FP);
247 assert_eq!(
248 address::TIMER_VALUE1,
249 address::TIMER_CONTROL + sizes::TIMER_CONTROL
250 );
251 assert_eq!(
252 address::TIMER_VALUE2,
253 address::TIMER_VALUE1 + sizes::TIMER_VALUE
254 );
255 assert_eq!(
256 address::TIMER_VALUE3,
257 address::TIMER_VALUE2 + sizes::TIMER_VALUE
258 );
259 assert_eq!(
260 address::TIMER_VALUE4,
261 address::TIMER_VALUE3 + sizes::TIMER_VALUE
262 );
263 assert_eq!(
264 address::IRQ_RET_ADDR,
265 address::TIMER_VALUE4 + sizes::TIMER_VALUE
266 );
267 assert_eq!(
268 address::IRQ_REG_DUMP,
269 address::IRQ_RET_ADDR + sizes::IRQ_RET_ADDR
270 );
271 assert_eq!(
272 address::CONTROLLER_PALETTE,
273 address::IRQ_REG_DUMP + sizes::IRQ_REG_DUMP
274 );
275 assert_eq!(
276 address::CONTROLLER_TABLE,
277 address::CONTROLLER_PALETTE + sizes::CONTROLLER_PALETTE
278 );
279 assert_eq!(
280 address::IRQ_CONTROL,
281 address::CONTROLLER_TABLE + sizes::CONTROLLER_TABLE
282 );
283 assert_eq!(
284 address::SAVE_CONTROL,
285 address::IRQ_CONTROL + sizes::IRQ_CONTROL
286 );
287 assert_eq!(
288 address::DATETIME,
289 address::SAVE_CONTROL + sizes::SAVE_CONTROL
290 );
291 assert_eq!(address::RAND, address::DATETIME + sizes::DATETIME);
292 assert_eq!(address::WAVE_TABLE, address::RAND + sizes::RAND);
293 assert_eq!(
294 address::CODE_BANK_2_ID,
295 address::WAVE_TABLE + sizes::WAVE_TABLE
296 );
297 assert_eq!(
298 address::RAM_BANK_2_ID,
299 address::CODE_BANK_2_ID + sizes::CODE_BANK_ID
300 );
301 assert_eq!(address::VLINE, address::RAM_BANK_2_ID + sizes::RAM_BANK_ID);
302 assert_eq!(address::RESERVED, address::VLINE + sizes::VLINE);
303 assert_eq!(address::STACK, address::RESERVED + RESERVED);
304 assert_eq!(65536, address::STACK as usize + sizes::STACK as usize);
305 assert_eq!(address::MAX, 0xFFFF);
306 }
307}