#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; }