aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAstatin <[email protected]>2025-03-22 01:31:25 +0900
committerAstatin <[email protected]>2025-03-22 01:32:12 +0900
commit6613a89b4d31e3718bb20d144ae93bedfeb35a78 (patch)
tree427639309824a5b98eb55493b0df169a3f032f41
parentc07b53df795c2c0eadcb4cc19c7bb83f44a10855 (diff)
Add custom DMG bootrom
-rw-r--r--Astatin-logo.pngbin270 -> 0 bytes
-rw-r--r--assets/Astatin-bootrom.gbasm (renamed from Astatin-logo.gbasm)94
-rw-r--r--src/gamepad.rs18
-rw-r--r--src/main.rs33
4 files changed, 122 insertions, 23 deletions
diff --git a/Astatin-logo.png b/Astatin-logo.png
deleted file mode 100644
index 206aaf1..0000000
--- a/Astatin-logo.png
+++ /dev/null
Binary files differ
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 {