aboutsummaryrefslogtreecommitdiff
path: root/arm9/source/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/source/dev.c')
-rw-r--r--arm9/source/dev.c213
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;
+}