Skip to content

Commit b44abd5

Browse files
committed
vdp: fix read auto-increment wrapping
We did not mask the incremented address value properly, so the read address pointer wrapped at 1024 instead of 16384. This is what caused the map bug in the Sonic intro screen. Add test for read wrapping and one specifically for this bug.
1 parent 07388fe commit b44abd5

1 file changed

Lines changed: 50 additions & 1 deletion

File tree

src/vdp.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ impl VdpState {
782782
}
783783
let val = self.vram_buffer;
784784
self.vram_buffer = self.vram[self.addr as usize];
785-
self.addr = (self.addr + 1) & 0x3FF;
785+
self.addr = (self.addr + 1) & 0x3FFF;
786786

787787
Ok(val)
788788
}
@@ -1179,3 +1179,52 @@ fn split_io() {
11791179
assert_eq!(vdp.input(VDP_DATA), Ok(0xB2));
11801180
assert_eq!(vdp.input(VDP_DATA), Ok(0xC3));
11811181
}
1182+
1183+
#[test]
1184+
fn read_wrap() {
1185+
use crate::io::Device;
1186+
let vdp = Vdp::default();
1187+
1188+
// write some data first
1189+
assert_eq!(vdp.out(VDP_CMD, 0xFE), Ok(()));
1190+
assert_eq!(vdp.out(VDP_CMD, 0x7F), Ok(()));
1191+
1192+
assert_eq!(vdp.out(VDP_DATA, 0xA1), Ok(()));
1193+
assert_eq!(vdp.out(VDP_DATA, 0xB2), Ok(()));
1194+
1195+
// address 0 (we are not testing write wrapping)
1196+
assert_eq!(vdp.out(VDP_CMD, 0), Ok(()));
1197+
assert_eq!(vdp.out(VDP_CMD, 0x40), Ok(()));
1198+
1199+
assert_eq!(vdp.out(VDP_DATA, 0xC3), Ok(()));
1200+
assert_eq!(vdp.out(VDP_DATA, 0xD4), Ok(()));
1201+
1202+
// read the data
1203+
assert_eq!(vdp.out(VDP_CMD, 0xFE), Ok(()));
1204+
assert_eq!(vdp.out(VDP_CMD, 0x3F), Ok(()));
1205+
1206+
assert_eq!(vdp.input(VDP_DATA), Ok(0xA1));
1207+
assert_eq!(vdp.input(VDP_DATA), Ok(0xB2));
1208+
assert_eq!(vdp.input(VDP_DATA), Ok(0xC3));
1209+
assert_eq!(vdp.input(VDP_DATA), Ok(0xD4));
1210+
1211+
// Now the bug we had: we don't want wrapping at 1024
1212+
let vdp = Vdp::default();
1213+
// write some data first
1214+
assert_eq!(vdp.out(VDP_CMD, 0xFE), Ok(()));
1215+
assert_eq!(vdp.out(VDP_CMD, 0x43), Ok(()));
1216+
1217+
assert_eq!(vdp.out(VDP_DATA, 0xA1), Ok(()));
1218+
assert_eq!(vdp.out(VDP_DATA, 0xB2), Ok(()));
1219+
assert_eq!(vdp.out(VDP_DATA, 0xC3), Ok(()));
1220+
assert_eq!(vdp.out(VDP_DATA, 0xD4), Ok(()));
1221+
1222+
// read the data
1223+
assert_eq!(vdp.out(VDP_CMD, 0xFE), Ok(()));
1224+
assert_eq!(vdp.out(VDP_CMD, 0x03), Ok(()));
1225+
1226+
assert_eq!(vdp.input(VDP_DATA), Ok(0xA1));
1227+
assert_eq!(vdp.input(VDP_DATA), Ok(0xB2));
1228+
assert_eq!(vdp.input(VDP_DATA), Ok(0xC3));
1229+
assert_eq!(vdp.input(VDP_DATA), Ok(0xD4));
1230+
}

0 commit comments

Comments
 (0)