pub mod sizes {
use crate::constants::{LAYER_COUNT, PALETTE_COUNT, SPRITE_COUNT};
pub const CODE_BANK: u16 = 8700;
pub const RAM_BANK: u16 = 8700;
pub const CODE: u16 = CODE_BANK * 2;
pub const RAM: u16 = RAM_BANK * 2;
pub const SOUND: u16 = 30;
pub const INPUT: u16 = 2;
pub const CODE_BANK_ID: u16 = 1;
pub const RAM_BANK_ID: u16 = 1;
pub const SAVE_BANK_ID: u16 = 1;
pub const SAVE_BANK: u16 = 4096;
pub const SAVE_CONTROL: u16 = 1;
pub const SPRITE: u16 = 5;
pub const SPRITE_TABLE: u16 = SPRITE_COUNT as u16 * SPRITE;
pub const LAYERS_HEADER: u16 = 3 * LAYER_COUNT as u16;
pub const LAYERS_CONTENT: u16 = 1320 * 2 * LAYER_COUNT as u16;
pub const PALETTE: u16 = 16 * 3; pub const PALETTES_TOTAL: u16 = PALETTE * PALETTE_COUNT as u16;
pub const ATLAS: u16 = 100 * 80;
pub const ATLAS_BANK_ID: u16 = 1;
pub const STACK: u16 = 900;
pub const SP: u16 = 2;
pub const FP: u16 = 2;
pub const TIMER_CONTROL: u16 = 2;
pub const TIMER_VALUE: u16 = 1;
pub const TIMERS: u16 = TIMER_CONTROL + TIMER_VALUE * 4;
pub const VLINE: u16 = 1;
pub const IRQ_RET_ADDR: u16 = 2;
pub const IRQ_REG_DUMP: u16 = 8;
pub const IRQ_CONTROL: u16 = 1;
pub const IRQ_INTERNAL: u16 = IRQ_RET_ADDR + IRQ_REG_DUMP + IRQ_CONTROL;
pub const DATETIME: u16 = 6;
pub const RAND: u16 = 1;
pub const CONTROLLER_TYPE: u16 = 1;
pub const CONTROLLER_GRAPHIC: u16 = 8;
pub const CONTROLLER_GRAPHICS: u16 = 11 * CONTROLLER_GRAPHIC;
pub const CONTROLLER_PALETTE: u16 = 3 * 4; pub const CONTROLLER_TABLE: u16 = 3 * 8;
pub const CONTROLLER_TOTAL: u16 =
CONTROLLER_TYPE + CONTROLLER_GRAPHICS + CONTROLLER_PALETTE + CONTROLLER_TABLE;
pub const ATLAS_TOTAL: u16 = ATLAS + ATLAS + ATLAS_BANK_ID + ATLAS_BANK_ID;
pub const LAYER_TOTAL: u16 = LAYERS_CONTENT + LAYERS_HEADER;
pub const GRAPHICS_TOTAL: u16 =
LAYER_TOTAL + SPRITE_TABLE + PALETTES_TOTAL + ATLAS_TOTAL + CONTROLLER_TOTAL;
pub const SYSTEM_TOTAL: u16 =
CODE + RAM + CODE_BANK_ID + RAM_BANK_ID + STACK + SP + FP + TIMERS + IRQ_INTERNAL + VLINE;
pub const HARDWARE_TOTAL: u16 =
SOUND + INPUT + SAVE_BANK_ID + SAVE_BANK + SAVE_CONTROL + DATETIME + RAND;
pub const RESERVED: u16 = 151;
pub const TOTAL: u16 = GRAPHICS_TOTAL + SYSTEM_TOTAL + HARDWARE_TOTAL + RESERVED;
}
pub mod address {
pub const CODE: u16 = 0x0; pub const CODE_BANK: u16 = 0x21FC; pub const RAM: u16 = 0x43F8; pub const RAM_BANK: u16 = 0x65F4; 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 = 0xB751; 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_ID: u16 = 0xFB45; pub const RAM_BANK_ID: u16 = 0xFB46; pub const ATLAS1_BANK_ID: u16 = 0xFB47; pub const ATLAS2_BANK_ID: u16 = 0xFB48; pub const SP: u16 = 0xFB49; pub const FP: u16 = 0xFB4B; pub const TIMER_CONTROL: u16 = 0xFB4D; pub const TIMER_VALUE1: u16 = 0xFB4F; pub const TIMER_VALUE2: u16 = 0xFB50; pub const TIMER_VALUE3: u16 = 0xFB51; pub const TIMER_VALUE4: u16 = 0xFB52; pub const IRQ_RET_ADDR: u16 = 0xFB53; pub const IRQ_REG_DUMP: u16 = 0xFB55; pub const VLINE: u16 = 0xFB5D; pub const CONTROLLER_TYPE: u16 = 0xFB5E; pub const CONTROLLER_GRAPHICS: u16 = 0xFB5F; pub const CONTROLLER_PALETTE: u16 = 0xFBB7; pub const CONTROLLER_TABLE: u16 = 0xFBC3; pub const IRQ_CONTROL: u16 = 0xFBDB; pub const SAVE_CONTROL: u16 = 0xFBDC; pub const DATETIME: u16 = 0xFBDD; pub const RAND: u16 = 0xFBE3; pub const RESERVED: u16 = 0xFBE4; pub const STACK: u16 = 0xFC7B; pub const MAX: u16 = 0xFFFF;
pub mod interrupt {
pub const IRQ_INPUT: u16 = 0x0500;
pub const IRQ_LINE_DRAW: u16 = 0x0540;
pub const IRQ_SCREEN_DRAW: u16 = 0x0800;
pub const IRQ_TIMER: u16 = 0x05C0;
pub const IRQ_CONTROLLER: u16 = 0x0600;
}
pub const fn is_special_memory(address: u16) -> bool {
matches!(
address,
CODE_BANK_ID
| RAM_BANK_ID
| ATLAS1_BANK_ID
| ATLAS2_BANK_ID
| TIMER_CONTROL
| SAVE_CONTROL
| SAVE_BANK_ID
| SOUND
| CONTROLLER_TYPE
)
}
}
pub mod save_flags {
pub const AUTO_SAVE: u8 = 4;
pub const WRITE: u8 = 0;
}
pub mod interrupt_flags {
pub const IRQ_INPUT: u8 = 0;
pub const IRQ_LINE_DRAW: u8 = 1;
pub const IRQ_SCREEN_DRAW: u8 = 2;
pub const IRQ_TIMER: u8 = 3;
pub const IRQ_CONTROLLER: u8 = 4;
}
#[cfg(test)]
mod test {
use crate::mem::sizes::TOTAL;
use crate::mem::{address, sizes};
#[test]
fn test_values() {
assert_eq!(TOTAL, u16::MAX);
}
#[test]
fn test_sizes_address() {
assert_eq!(address::CODE, 0);
assert_eq!(address::CODE_BANK, address::CODE + sizes::CODE_BANK);
assert_eq!(address::RAM, address::CODE_BANK + sizes::CODE_BANK);
assert_eq!(address::RAM_BANK, address::RAM + sizes::RAM_BANK);
assert_eq!(address::INPUT, address::RAM_BANK + sizes::RAM_BANK);
assert_eq!(address::SOUND, address::INPUT + sizes::INPUT);
assert_eq!(address::SAVE_BANK_ID, address::SOUND + sizes::SOUND);
assert_eq!(
address::SAVE_BANK,
address::SAVE_BANK_ID + sizes::SAVE_BANK_ID
);
assert_eq!(address::ATLAS1, address::SAVE_BANK + sizes::SAVE_BANK);
assert_eq!(address::ATLAS2, address::ATLAS1 + sizes::ATLAS);
assert_eq!(address::PALETTES, address::ATLAS2 + sizes::ATLAS);
assert_eq!(
address::SPRITE_TABLE,
address::PALETTES + sizes::PALETTES_TOTAL
);
assert_eq!(
address::LAYER_HEADERS,
address::SPRITE_TABLE + sizes::SPRITE_TABLE
);
assert_eq!(
address::LAYERS,
address::LAYER_HEADERS + sizes::LAYERS_HEADER
);
assert_eq!(
address::CODE_BANK_ID,
address::LAYERS + sizes::LAYERS_CONTENT
);
assert_eq!(
address::RAM_BANK_ID,
address::CODE_BANK_ID + sizes::CODE_BANK_ID
);
assert_eq!(
address::ATLAS1_BANK_ID,
address::RAM_BANK_ID + sizes::RAM_BANK_ID
);
assert_eq!(
address::ATLAS2_BANK_ID,
address::ATLAS1_BANK_ID + sizes::ATLAS_BANK_ID
);
assert_eq!(address::SP, address::ATLAS2_BANK_ID + sizes::ATLAS_BANK_ID);
assert_eq!(address::FP, address::SP + sizes::SP);
assert_eq!(address::TIMER_CONTROL, address::FP + sizes::FP);
assert_eq!(
address::TIMER_VALUE1,
address::TIMER_CONTROL + sizes::TIMER_CONTROL
);
assert_eq!(
address::TIMER_VALUE2,
address::TIMER_VALUE1 + sizes::TIMER_VALUE
);
assert_eq!(
address::TIMER_VALUE3,
address::TIMER_VALUE2 + sizes::TIMER_VALUE
);
assert_eq!(
address::TIMER_VALUE4,
address::TIMER_VALUE3 + sizes::TIMER_VALUE
);
assert_eq!(
address::IRQ_RET_ADDR,
address::TIMER_VALUE4 + sizes::TIMER_VALUE
);
assert_eq!(
address::IRQ_REG_DUMP,
address::IRQ_RET_ADDR + sizes::IRQ_RET_ADDR
);
assert_eq!(address::VLINE, address::IRQ_REG_DUMP + sizes::IRQ_REG_DUMP);
assert_eq!(address::CONTROLLER_TYPE, address::VLINE + sizes::VLINE);
assert_eq!(
address::CONTROLLER_GRAPHICS,
address::CONTROLLER_TYPE + sizes::CONTROLLER_TYPE
);
assert_eq!(
address::CONTROLLER_PALETTE,
address::CONTROLLER_GRAPHICS + sizes::CONTROLLER_GRAPHICS
);
assert_eq!(
address::CONTROLLER_TABLE,
address::CONTROLLER_PALETTE + sizes::CONTROLLER_PALETTE
);
assert_eq!(
address::IRQ_CONTROL,
address::CONTROLLER_TABLE + sizes::CONTROLLER_TABLE
);
assert_eq!(
address::SAVE_CONTROL,
address::IRQ_CONTROL + sizes::IRQ_CONTROL
);
assert_eq!(
address::DATETIME,
address::SAVE_CONTROL + sizes::SAVE_CONTROL
);
assert_eq!(address::RAND, address::DATETIME + sizes::DATETIME);
assert_eq!(address::RESERVED, address::RAND + sizes::RAND);
assert_eq!(address::STACK, address::RESERVED + sizes::RESERVED);
assert_eq!(address::MAX, address::STACK + sizes::STACK);
}
}