diff options
Diffstat (limited to 'arm9/source/dev.c')
-rw-r--r-- | arm9/source/dev.c | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/arm9/source/dev.c b/arm9/source/dev.c new file mode 100644 index 0000000..1b9a1dc --- /dev/null +++ b/arm9/source/dev.c @@ -0,0 +1,213 @@ +#include "dev.h" + + +// Reset every device on a device bus. +void dev_reset(DeviceBus *d) { + system_reset(&d->system); + memory_reset(&d->memory); + math_reset(&d->math); + clock_reset(&d->clock); + input_reset(&d->input); + screen_reset(&d->screen); + stream_reset(&d->stream); + fs_reset(&d->file); +} + +// Read a byte from a device bus. +u8 dev_read(DeviceBus *d, u8 port) { + switch(port) { + // SYSTEM DEVICE + case 0x02: return d->system.wake; + case 0x08: return readbuf_read(&d->system.name); + case 0x09: return readbuf_read(&d->system.authors); + case 0x0E: return GETH(connected_devices()); + case 0x0F: return GETL(connected_devices()); + // MEMORY DEVICE + case 0x10: return GETH(d->memory.allocated); + case 0x11: return GETL(d->memory.allocated); + case 0x12: return GETH(d->memory.head1.offset); + case 0x13: return GETL(d->memory.head1.offset); + case 0x14: return d->memory.head1.page; + case 0x15: return d->memory.head1.byte; + case 0x16: + case 0x17: return memory_read(&d->memory.head1); + case 0x1A: return GETH(d->memory.head2.offset); + case 0x1B: return GETL(d->memory.head2.offset); + case 0x1C: return d->memory.head2.page; + case 0x1D: return d->memory.head2.byte; + case 0x1E: + case 0x1F: return memory_read(&d->memory.head2); + // MATH DEVICE + case 0x20: return GETH(math_get_x(&d->math)); + case 0x21: return GETL(math_get_x(&d->math)); + case 0x22: return GETH(math_get_y(&d->math)); + case 0x23: return GETL(math_get_y(&d->math)); + case 0x24: return GETH(math_get_r(&d->math)); + case 0x25: return GETL(math_get_r(&d->math)); + case 0x26: return GETH(math_get_t(&d->math)); + case 0x27: return GETL(math_get_t(&d->math)); + case 0x28: return GETHH(math_get_prod(&d->math)); + case 0x29: return GETHL(math_get_prod(&d->math)); + case 0x2A: return GETLH(math_get_prod(&d->math)); + case 0x2B: return GETLL(math_get_prod(&d->math)); + case 0x2C: return GETH(math_get_quot(&d->math)); + case 0x2D: return GETL(math_get_quot(&d->math)); + case 0x2E: return GETH(math_get_rem(&d->math)); + case 0x2F: return GETL(math_get_rem(&d->math)); + // CLOCK DEVICE + case 0x30: return YEAR(get_datetime()); + case 0x31: return MONTH(get_datetime()); + case 0x32: return DAY(get_datetime()); + case 0x33: return HOUR(get_datetime()); + case 0x34: return MINUTE(get_datetime()); + case 0x35: return SECOND(get_datetime()); + case 0x36: clock_uptime_read(&d->clock); + return GETH(d->clock.uptime); + case 0x37: return GETL(d->clock.uptime); + case 0x38: timer_read(&d->clock.t1); + return GETH(d->clock.t1.read); + case 0x39: return GETL(d->clock.t1.read); + case 0x3A: timer_read(&d->clock.t2); + return GETH(d->clock.t2.read); + case 0x3B: return GETL(d->clock.t2.read); + case 0x3C: timer_read(&d->clock.t3); + return GETH(d->clock.t3.read); + case 0x3D: return GETL(d->clock.t3.read); + case 0x3E: timer_read(&d->clock.t4); + return GETH(d->clock.t4.read); + case 0x3F: return GETL(d->clock.t4.read); + // INPUT DEVICE + case 0x40: input_read_x(&d->input); + return GETH(d->input.x_read); + case 0x41: return GETL(d->input.x_read); + case 0x42: input_read_y(&d->input); + return GETH(d->input.y_read); + case 0x43: return GETL(d->input.y_read); + case 0x48: return BOOL(d->input.pointer); + case 0x49: return d->input.pointer << 7; + case 0x4A: return circbuf_read(&d->input.keybuffer); + case 0x4C: return d->input.gamepad; + // SCREEN DEVICE + case 0x50: return GETH(d->screen.x); + case 0x51: return GETL(d->screen.x); + case 0x52: return GETH(d->screen.y); + case 0x53: return GETL(d->screen.y); + case 0x54: return GETH(PIXELS_WIDTH); + case 0x55: return GETL(PIXELS_WIDTH); + case 0x56: return GETH(PIXELS_HEIGHT); + case 0x57: return GETL(PIXELS_HEIGHT); + // FILE DEVICE + case 0x90: return BOOL(fs_get_open(&d->file)); + case 0x91: return BOOL(fs_get_error(&d->file)); + case 0x92: + case 0x93: return fs_read_byte(&d->file); + case 0x94: return pathbuf_read(&d->file.path); + case 0x95: return BOOL(fs_get_type(&d->file)); + case 0x96: return pathbuf_read(&d->file.child_path); + case 0x97: return BOOL(fs_get_child_type(&d->file)); + case 0x98: return GETHH(d->file.address); + case 0x99: return GETHL(d->file.address); + case 0x9A: return GETLH(d->file.address); + case 0x9B: return GETLL(d->file.address); + case 0x9C: fs_calculate_length(&d->file); return GETHH(d->file.length); + case 0x9D: fs_calculate_length(&d->file); return GETHL(d->file.length); + case 0x9E: fs_calculate_length(&d->file); return GETLH(d->file.length); + case 0x9F: fs_calculate_length(&d->file); return GETLL(d->file.length); + // DEFAULT + default: return 0; + } +} + +// Write a byte to a device bus. +Signal dev_write(DeviceBus *d, u8 port, u8 v) { + switch(port) { + // SYSTEM DEVICE + case 0x00: SETH(d->system.sleep, v); break; + case 0x01: SETL(d->system.sleep, v); return SIG_SLEEP; + case 0x03: if (v) { return SIG_FORK; } else { return SIG_RESET; } + case 0x08: readbuf_set_pointer(&d->system.name); break; + case 0x09: readbuf_set_pointer(&d->system.authors); break; + // MEMORY DEVICE + case 0x10: SETH(d->memory.count, v); break; + case 0x11: SETL(d->memory.count, v); memory_allocate(&d->memory); break; + case 0x12: SETH(d->memory.head1.offset, v); + memory_refresh_cache(&d->memory, &d->memory.head1); break; + case 0x13: SETL(d->memory.head1.offset, v); + memory_refresh_cache(&d->memory, &d->memory.head1); break; + case 0x14: d->memory.head1.page = v; + memory_refresh_page(&d->memory.head1); break; + case 0x15: d->memory.head1.byte = v; break; + case 0x16: + case 0x17: memory_write(&d->memory.head1, v); break; + case 0x18: SETH(d->memory.copy, v); break; + case 0x19: SETL(d->memory.copy, v); memory_copy(&d->memory); break; + case 0x1A: SETH(d->memory.head2.offset, v); + memory_refresh_cache(&d->memory, &d->memory.head2); break; + case 0x1B: SETL(d->memory.head2.offset, v); + memory_refresh_cache(&d->memory, &d->memory.head2); break; + case 0x1C: d->memory.head2.page = v; + memory_refresh_page(&d->memory.head2); break; + case 0x1D: d->memory.head2.byte = v; break; + case 0x1E: + case 0x1F: memory_write(&d->memory.head2, v); break; + // MATH DEVICE + case 0x20: math_clear_cartesian(&d->math); SETH(d->math.x, v); break; + case 0x21: math_clear_cartesian(&d->math); SETL(d->math.x, v); break; + case 0x22: math_clear_cartesian(&d->math); SETH(d->math.y, v); break; + case 0x23: math_clear_cartesian(&d->math); SETL(d->math.y, v); break; + case 0x24: math_clear_polar(&d->math); SETH(d->math.r, v); break; + case 0x25: math_clear_polar(&d->math); SETL(d->math.r, v); break; + case 0x26: math_clear_polar(&d->math); SETH(d->math.t, v); break; + case 0x27: math_clear_polar(&d->math); SETL(d->math.t, v); break; + // CLOCK DEVICE + case 0x38: SETH(d->clock.t1.write, v); break; + case 0x39: SETL(d->clock.t1.write, v); timer_write(&d->clock.t1); break; + case 0x3A: SETH(d->clock.t2.write, v); break; + case 0x3B: SETL(d->clock.t2.write, v); timer_write(&d->clock.t2); break; + case 0x3C: SETH(d->clock.t3.write, v); break; + case 0x3D: SETL(d->clock.t3.write, v); timer_write(&d->clock.t3); break; + case 0x3E: SETH(d->clock.t4.write, v); break; + case 0x3F: SETL(d->clock.t4.write, v); timer_write(&d->clock.t4); break; + // INPUT DEVICE + case 0x4A: circbuf_clear(&d->input.keybuffer); + v ? open_keyboard() : close_keyboard(); break; + // SCREEN DEVICE + case 0x50: SETH(d->screen.x, v); break; + case 0x51: SETL(d->screen.x, v); break; + case 0x52: SETH(d->screen.y, v); break; + case 0x53: SETL(d->screen.y, v); break; + case 0x58: SETH(d->screen.colour, v); break; + case 0x59: SETL(d->screen.colour, v); + screen_commit_colour(&d->screen); break; + case 0x5A: SETH(d->screen.selected, v); break; + case 0x5B: SETL(d->screen.selected, v); break; + case 0x5C: + case 0x5D: spritebuf_push(&d->screen.sprite, v); break; + case 0x5E: screen_draw(&d->screen, v); break; + case 0x5F: screen_move_cursor(&d->screen, v); break; + // STREAM DEVICE + case 0x83: stream_end(&d->stream); break; + case 0x86: + case 0x87: stream_write(&d->stream, v); break; + // FILE DEVICE + case 0x90: fs_push_open(&d->file, v); break; + case 0x91: fs_push_action(&d->file, v); break; + case 0x92: + case 0x93: fs_write_byte(&d->file, v); break; + case 0x94: pathbuf_set_pointer(&d->file.path, v); break; + case 0x95: fs_ascend(&d->file); break; + case 0x96: pathbuf_set_pointer(&d->file.child_path, v); break; + case 0x97: fs_descend(&d->file); break; + case 0x98: SETHH(d->file.address_write, v); break; + case 0x99: SETHL(d->file.address_write, v); break; + case 0x9A: SETLH(d->file.address_write, v); break; + case 0x9B: SETLL(d->file.address_write, v); fs_seek(&d->file); break; + case 0x9C: SETHH(d->file.length_write, v); break; + case 0x9D: SETHL(d->file.length_write, v); break; + case 0x9E: SETLH(d->file.length_write, v); break; + case 0x9F: SETLL(d->file.length_write, v); fs_resize(&d->file); break; + // DEFAULT + default: break; + } + return SIG_NONE; +} |