From 6613a89b4d31e3718bb20d144ae93bedfeb35a78 Mon Sep 17 00:00:00 2001 From: Astatin Date: Sat, 22 Mar 2025 01:31:25 +0900 Subject: Add custom DMG bootrom --- Astatin-logo.gbasm | 73 -------------------- Astatin-logo.png | Bin 270 -> 0 bytes assets/Astatin-bootrom.gbasm | 157 +++++++++++++++++++++++++++++++++++++++++++ src/gamepad.rs | 18 +++-- src/main.rs | 33 +++++---- 5 files changed, 190 insertions(+), 91 deletions(-) delete mode 100644 Astatin-logo.gbasm delete mode 100644 Astatin-logo.png create mode 100644 assets/Astatin-bootrom.gbasm diff --git a/Astatin-logo.gbasm b/Astatin-logo.gbasm deleted file mode 100644 index 23c25b9..0000000 --- a/Astatin-logo.gbasm +++ /dev/null @@ -1,73 +0,0 @@ -LD SP,$fffe - -EmptyVRAM: - LD HL, $8000 - - EmptyVRAM.loop: - LD A, $00 - LD (HL+), A - LD A, $A0 - CP H - JR NZ, =EmptyVRAM.loop - -SetupLogoTile: - LD C, $48 - LD DE, =Logo - LD HL, $8010 - SetupLogoTile.loop: - LD A, (DE) - LD (HL+), A - LD (HL+), A - LD (HL+), A - LD (HL+), A - INC DE - DEC C - JR NZ, =SetupLogoTile.loop - -LD A, $01 - -LogoFirstLine: - LD HL, $9800 - LogoFirstLine.loop: - LD (HL+), A - INC A - CP $0a - JR NZ, =LogoFirstLine.loop - -LogoSecondLine: - LD HL, $9820 - LogoSecondLine.loop: - LD (HL+), A - INC A - CP $13 - JR NZ, =LogoSecondLine.loop - -LD A, $fc -LD ($47), A - -LD A,$91 -LD ($40), A - -Loop: - JR =Loop -Logo: -.DB $3f, $ff, $f0, $f0 -.DB $c0, $f0, $f0, $f0 -.DB $00, $00, $00, $fe -.DB $00, $1e, $7f, $1e -.DB $00, $00, $80, $1f -.DB $00, $01, $07, $e1 -.DB $03, $e3, $f8, $e3 -.DB $c0, $c0, $00, $cf -.DB $00, $01, $01, $3c -.DB $ff, $f0, $f0, $f0 -.DB $f3, $f0, $f0, $f0 -.DB $e0, $fe, $1f, $fe -.DB $1e, $1e, $9e, $1e -.DB $00, $1f, $78, $1f -.DB $79, $f9, $79, $f9 -.DB $e3, $e3, $e3, $e3 -.DB $cf, $cf, $cf, $cf -.DB $cf, $0f, $0f, $0f - -.PADTO 0x100 diff --git a/Astatin-logo.png b/Astatin-logo.png deleted file mode 100644 index 206aaf1..0000000 Binary files a/Astatin-logo.png and /dev/null differ diff --git a/assets/Astatin-bootrom.gbasm b/assets/Astatin-bootrom.gbasm new file mode 100644 index 0000000..3fd2d23 --- /dev/null +++ b/assets/Astatin-bootrom.gbasm @@ -0,0 +1,157 @@ +; .INCLUDE "minimal.gbasm" +LD SP,$fffe + +EmptyVRAM: + LD HL, $8000 + + EmptyVRAM.loop: + LD A, $00 + LD (HL+), A + LD A, $A0 + CP H + JR NZ, =EmptyVRAM.loop + +SetupLogoTile: + LD C, $48 + LD DE, =Logo + LD HL, $8010 + SetupLogoTile.loop: + LD A, (DE) + LD (HL+), A + LD (HL+), A + LD (HL+), A + 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, $9905 + LogoFirstLine.loop: + LD (HL+), A + INC A + CP $0a + JR NZ, =LogoFirstLine.loop + + LD (HL), $14 + +LogoSecondLine: + 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 + +; 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: + 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 +.DB $00, $00, $00, $fe +.DB $00, $1e, $7f, $1e +.DB $00, $00, $80, $1f +.DB $00, $01, $07, $e1 +.DB $03, $e3, $f8, $e3 +.DB $c0, $c0, $00, $cf +.DB $00, $01, $01, $3c +.DB $ff, $f0, $f0, $f0 +.DB $f3, $f0, $f0, $f0 +.DB $e0, $fe, $1f, $fe +.DB $1e, $1e, $9e, $1e +.DB $00, $1f, $78, $1f +.DB $79, $f9, $79, $f9 +.DB $e3, $e3, $e3, $e3 +.DB $cf, $cf, $cf, $cf +.DB $cf, $0f, $0f, $0f + +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; 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 { 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 { 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 { 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 { 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 = 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 { -- cgit v1.2.3-70-g09d2