diff options
author | Astatin <[email protected]> | 2025-03-22 01:31:25 +0900 |
---|---|---|
committer | Astatin <[email protected]> | 2025-03-22 01:32:12 +0900 |
commit | 6613a89b4d31e3718bb20d144ae93bedfeb35a78 (patch) | |
tree | 427639309824a5b98eb55493b0df169a3f032f41 | |
parent | c07b53df795c2c0eadcb4cc19c7bb83f44a10855 (diff) |
Add custom DMG bootrom
-rw-r--r-- | Astatin-logo.png | bin | 270 -> 0 bytes | |||
-rw-r--r-- | assets/Astatin-bootrom.gbasm (renamed from Astatin-logo.gbasm) | 94 | ||||
-rw-r--r-- | src/gamepad.rs | 18 | ||||
-rw-r--r-- | src/main.rs | 33 |
4 files changed, 122 insertions, 23 deletions
diff --git a/Astatin-logo.png b/Astatin-logo.png Binary files differdeleted file mode 100644 index 206aaf1..0000000 --- a/Astatin-logo.png +++ /dev/null diff --git a/Astatin-logo.gbasm b/assets/Astatin-bootrom.gbasm index 23c25b9..3fd2d23 100644 --- a/Astatin-logo.gbasm +++ b/assets/Astatin-bootrom.gbasm @@ -1,3 +1,4 @@ +; .INCLUDE "minimal.gbasm" LD SP,$fffe EmptyVRAM: @@ -22,34 +23,110 @@ SetupLogoTile: LD (HL+), A INC DE DEC C + LD A, $00 + CP C JR NZ, =SetupLogoTile.loop + LD A, $01 + LD ($8092), A + LD ($8093), A + + LD C, $10 + SetupHeart.loop: + LD A, (DE) + LD (HL+), A + LD (HL+), A + INC DE + DEC C + LD A, $00 + CP C + JR NZ, =SetupHeart.loop + LD A, $01 LogoFirstLine: - LD HL, $9800 + LD HL, $9905 LogoFirstLine.loop: LD (HL+), A INC A CP $0a JR NZ, =LogoFirstLine.loop + LD (HL), $14 + LogoSecondLine: - LD HL, $9820 + LD HL, $9925 LogoSecondLine.loop: LD (HL+), A INC A CP $13 JR NZ, =LogoSecondLine.loop +LD A, $13 +LD ($98ee), A + +; Palette LD A, $fc LD ($47), A -LD A,$91 +; LCD on +LD A, $91 +LD ($42), A LD ($40), A +; Sound on +LD A, $80 +LD ($26), A + +; Channel 1 lengths +LD ($11), A + +LD A, $f3 +; Channel 1 volume & envelope +LD ($12), A + +; Panning +LD ($25), A + +LD A, $77 +LD ($24), A + +LD C, $58 Loop: - JR =Loop + LD B, $12 + .Wait_VBlank: + LD A, ($44) + CP $90 + JR NZ, =.Wait_VBlank + DEC B + LD A, $00 + CP B + JR NZ, =.Wait_VBlank + + LD A, C + LD ($42), A + DEC C + CP $02 + LD D, $83 + CALL Z, =.sound1 + CP $00 + JR NZ, =Loop + LD D, $c1 + CALL =.sound1 + + .Lock: + JP =End + + .sound1: + LD E, A + LD A, D + LD ($13), A + LD A, $87 + LD ($14), A + LD A, E + RET + + Logo: .DB $3f, $ff, $f0, $f0 .DB $c0, $f0, $f0, $f0 @@ -70,4 +147,11 @@ Logo: .DB $cf, $cf, $cf, $cf .DB $cf, $0f, $0f, $0f -.PADTO 0x100 +Heart: +.DB $00, $00, $00, $00, $00, $00, $00, $7c +.DB $82, $29, $55, $45, $29, $11, $82, $7c + +.PADTO 0xfc +End: + LD A, $01 + LD ($50), A diff --git a/src/gamepad.rs b/src/gamepad.rs index c47464b..87c445c 100644 --- a/src/gamepad.rs +++ b/src/gamepad.rs @@ -10,7 +10,7 @@ pub struct Gamepad { } pub trait Input { - fn update_events(&mut self, cycles: u128); + fn update_events(&mut self, cycles: u128) -> Option<u128>; fn get_action_gamepad_reg(&self) -> u8; fn get_direction_gamepad_reg(&self) -> u8; } @@ -40,8 +40,9 @@ impl Gamepad { } impl Input for Gamepad { - fn update_events(&mut self, _cycles: u128) { + fn update_events(&mut self, _cycles: u128) -> Option<u128> { while let Some(_) = self.gilrs.next_event() {} + None } fn get_action_gamepad_reg(&self) -> u8 { @@ -114,7 +115,7 @@ impl Keyboard { } impl Input for Keyboard { - fn update_events(&mut self, _cycles: u128) { + fn update_events(&mut self, _cycles: u128) -> Option<u128> { let mut res = 0xf; let keys = self.keys.borrow(); @@ -155,6 +156,8 @@ impl Input for Keyboard { } self.direction_reg = res; + + None } fn get_action_gamepad_reg(&self) -> u8 { @@ -185,7 +188,7 @@ impl GamepadRecorder { } impl Input for GamepadRecorder { - fn update_events(&mut self, cycles: u128) { + fn update_events(&mut self, cycles: u128) -> Option<u128> { self.input.update_events(cycles); let new_action_reg = self.input.get_action_gamepad_reg(); @@ -212,6 +215,7 @@ impl Input for GamepadRecorder { self.action_reg = new_action_reg; self.direction_reg = new_direction_reg; + None } fn get_action_gamepad_reg(&self) -> u8 { @@ -252,9 +256,9 @@ impl GamepadReplay { } impl Input for GamepadReplay { - fn update_events(&mut self, cycles: u128) { + fn update_events(&mut self, cycles: u128) -> Option<u128> { if let Some(next_cycle_update) = self.next_cycle_update { - if cycles > next_cycle_update { + if cycles >= next_cycle_update { let mut inputs: [u8; 2] = [0; 2]; self.record_file @@ -273,6 +277,8 @@ impl Input for GamepadReplay { }; } } + + return self.next_cycle_update; } fn get_action_gamepad_reg(&self) -> u8 { diff --git a/src/main.rs b/src/main.rs index 66b60e5..7798bc3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,6 +42,9 @@ struct Cli { #[arg(short, long, default_value_t = 1.0)] speed: f32, + + #[arg(short, long, default_value_t = false)] + debug: bool, } fn main() { @@ -85,12 +88,15 @@ fn main() { gamepad = Box::new(GamepadRecorder::new(gamepad, record_file)); }; - let mut nanos_sleep: i128 = 0; + state.is_debug = cli.debug; + + let mut nanos_sleep: f64 = 0.0; let mut halt_time = 0; let mut was_previously_halted = false; let mut last_ram_bank_enabled = false; let mut now = SystemTime::now(); + let mut next_precise_gamepad_update: Option<u128> = None; loop { if was_previously_halted && !state.mem.halt { @@ -114,22 +120,16 @@ fn main() { state.check_interrupts().unwrap(); state.mem.update_serial(); - nanos_sleep += c as i128 * (consts::CPU_CYCLE_LENGTH_NANOS as f32 / cli.speed) as i128; - if nanos_sleep > 0 { - gamepad.update_events(total_cycle_counter); + nanos_sleep += c as f64 * (consts::CPU_CYCLE_LENGTH_NANOS as f64 / cli.speed as f64) as f64; + + if nanos_sleep >= 0.0 || next_precise_gamepad_update.map_or(false, |c| (c >= total_cycle_counter)) { + next_precise_gamepad_update = gamepad.update_events(total_cycle_counter); let (action_button_reg, direction_button_reg) = ( gamepad.get_action_gamepad_reg(), gamepad.get_direction_gamepad_reg(), ); - if let Some(fb) = state.mem.display.redraw_request { - if let Some(window::WindowSignal::Exit) = window.update(&fb) { - break; - } - } - // gamepad.check_special_actions(&mut state.is_debug); - if state.mem.joypad_is_action && (action_button_reg & (state.mem.joypad_reg >> 4)) != (state.mem.joypad_reg >> 4) || (!state.mem.joypad_is_action @@ -140,6 +140,15 @@ fn main() { } state.mem.joypad_reg = direction_button_reg | (action_button_reg << 4); + } + + + if nanos_sleep > 0.0 { + if let Some(fb) = state.mem.display.redraw_request { + if let Some(window::WindowSignal::Exit) = window.update(&fb) { + break; + } + } if !cli.loop_lock_timing { thread::sleep(time::Duration::from_nanos(nanos_sleep as u64 / 10)); @@ -152,7 +161,7 @@ fn main() { } nanos_sleep = - nanos_sleep - SystemTime::now().duration_since(now).unwrap().as_nanos() as i128; + nanos_sleep - SystemTime::now().duration_since(now).unwrap().as_nanos() as f64; now = SystemTime::now(); if last_ram_bank_enabled && !state.mem.ram_bank_enabled { |