diff --git a/apple2e.cpp b/apple2e.cpp index 40b88a9..6ae3c1a 100644 --- a/apple2e.cpp +++ b/apple2e.cpp @@ -801,7 +801,9 @@ struct MAINboard : board_base } if(addr == 0xC030) { if(debug & DEBUG_RW) printf("write SPKR\n"); - // click + fill_flush_audio(); + data = 0x00; + speaker_energized = !speaker_energized; return true; } printf("unhandled MMIO Write at %04X\n", addr); @@ -1141,6 +1143,13 @@ struct CPU6502 break; } + case 0xDE: { // DEC abs, X + int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256 + x; + set_flags(N | Z, m = bus.read(addr) - 1); + bus.write(addr, m); + break; + } + case 0xCE: { // DEC abs int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256; set_flags(N | Z, m = bus.read(addr) - 1); @@ -1153,6 +1162,15 @@ struct CPU6502 break; } + case 0xFE: { // INC abs, X + int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256 + x; + if((addr - x) / 256 != addr / 256) + clk++; + set_flags(N | Z, m = bus.read(addr) + 1); + bus.write(addr, m); + break; + } + case 0xEE: { // INC abs int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256; set_flags(N | Z, m = bus.read(addr) + 1); @@ -1619,6 +1637,23 @@ struct CPU6502 break; } + case 0x31: { // AND (ind), y + unsigned char zpg = read_pc_inc(bus); + int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xFF) * 256 + y; + if((addr - y) / 256 != addr / 256) + clk++; + set_flags(N | Z, a = a & bus.read(addr)); + break; + } + + case 0x3D: { // AND abs, x + int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256; + set_flags(N | Z, a = a & bus.read(addr + x)); + if((addr + x) / 256 != addr / 256) + clk++; + break; + } + case 0x39: { // AND abs, y int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256; set_flags(N | Z, a = a & bus.read(addr + y)); @@ -1664,6 +1699,16 @@ struct CPU6502 break; } + case 0x6E: { // ROR abs + int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256; + m = bus.read(addr); + bool c = isset(C); + flag_change(C, m & 0x01); + set_flags(N | Z, m = (c ? 0x80 : 0x00) | (m >> 1)); + bus.write(addr, m); + break; + } + case 0x66: { // ROR unsigned char zpg = read_pc_inc(bus); m = bus.read(zpg); @@ -2157,7 +2202,7 @@ enum APPLE2Einterface::EventType process_events(MAINboard *board, bus_frontend& { static bool shift_down = false; static bool control_down = false; - // skip CAPS for now + static bool caps_down = false; while(APPLE2Einterface::event_waiting()) { APPLE2Einterface::event e = APPLE2Einterface::dequeue_event(); @@ -2173,7 +2218,9 @@ enum APPLE2Einterface::EventType process_events(MAINboard *board, bus_frontend& shift_down = true; else if((e.value == APPLE2Einterface::LEFT_CONTROL) || (e.value == APPLE2Einterface::RIGHT_CONTROL)) control_down = true; - else if(e.value == APPLE2Einterface::ENTER) { + else if(e.value == APPLE2Einterface::CAPS_LOCK) { + caps_down = true; + } else if(e.value == APPLE2Einterface::ENTER) { board->enqueue_key(141 - 128); } else if(e.value == APPLE2Einterface::TAB) { board->enqueue_key(' '); @@ -2193,14 +2240,20 @@ enum APPLE2Einterface::EventType process_events(MAINboard *board, bus_frontend& auto it = interface_key_to_apple2e.find(e.value); if(it != interface_key_to_apple2e.end()) { const key_to_ascii& k = (*it).second; - if(!shift_down && !control_down) - board->enqueue_key(k.no_shift_no_control); - else if(shift_down && !control_down) - board->enqueue_key(k.yes_shift_no_control); - else if(!shift_down && control_down) - board->enqueue_key(k.no_shift_yes_control); - else if(shift_down && control_down) - board->enqueue_key(k.yes_shift_yes_control); + if(!shift_down) { + if(!control_down) { + if(caps_down && (e.value >= 'A') && (e.value <= 'Z')) + board->enqueue_key(k.yes_shift_no_control); + else + board->enqueue_key(k.no_shift_no_control); + } else + board->enqueue_key(k.no_shift_yes_control); + } else { + if(!control_down) + board->enqueue_key(k.yes_shift_no_control); + else + board->enqueue_key(k.yes_shift_yes_control); + } } } } else if(e.type == APPLE2Einterface::KEYUP) { @@ -2208,6 +2261,9 @@ enum APPLE2Einterface::EventType process_events(MAINboard *board, bus_frontend& shift_down = false; else if((e.value == APPLE2Einterface::LEFT_CONTROL) || (e.value == APPLE2Einterface::RIGHT_CONTROL)) control_down = false; + else if(e.value == APPLE2Einterface::CAPS_LOCK) { + caps_down = false; + } } if(e.type == APPLE2Einterface::RESET) { bus.reset(); cpu.reset(bus); @@ -2381,6 +2437,8 @@ int main(int argc, char **argv) APPLE2Einterface::start(); + chrono::time_point then; + while(1) { if(!debugging) { poll_keyboard(); @@ -2405,13 +2463,12 @@ int main(int argc, char **argv) } } - chrono::time_point then; int clocks_per_slice; if(pause_cpu) clocks_per_slice = 0; else { if(run_fast) - clocks_per_slice = machine_clock_rate; + clocks_per_slice = machine_clock_rate / 5; else clocks_per_slice = millis_per_slice * machine_clock_rate / 1000; } @@ -2439,6 +2496,8 @@ int main(int argc, char **argv) auto elapsed_millis = chrono::duration_cast(now - then); if(!run_fast || pause_cpu) this_thread::sleep_for(chrono::milliseconds(millis_per_slice) - elapsed_millis); + + then = now; } else { diff --git a/interface.cpp b/interface.cpp index c502334..1781221 100644 --- a/interface.cpp +++ b/interface.cpp @@ -47,7 +47,7 @@ static int gButtonPressed = -1; deque event_queue; -bool force_caps_on = false; // XXX implement! +bool force_caps_on = true; bool draw_using_color = false; // XXX implement! bool event_waiting() @@ -694,14 +694,19 @@ struct toggle : public text_widget std::function action_on; std::function action_off; - toggle(const string& content_, std::function action_on_, std::function action_off_) : + toggle(const string& content_, bool initial_state, std::function action_on_, std::function action_off_) : text_widget(content_), - on(false), + on(initial_state), action_on(action_on_), action_off(action_off_) { - set(bg, 0, 0, 0, 1); - set(fg, 1, 1, 1, 1); + if(initial_state) { + set(fg, 0, 0, 0, 1); + set(bg, 1, 1, 1, 1); + } else { + set(fg, 1, 1, 1, 1); + set(bg, 0, 0, 0, 1); + } } virtual tuple get_min_dimensions() const @@ -776,6 +781,7 @@ struct toggle : public text_widget }; vbox *ui; +toggle *caps_toggle; void initialize_gl(void) { @@ -818,10 +824,10 @@ void initialize_gl(void) momentary *reset_momentary = new momentary("RESET", [](){event_queue.push_back({RESET, 0});}); momentary *reboot_momentary = new momentary("REBOOT", [](){event_queue.push_back({REBOOT, 0});}); - toggle *fast_toggle = new toggle("FAST", [](){event_queue.push_back({SPEED, 1});}, [](){event_queue.push_back({SPEED, 0});}); - toggle *caps_toggle = new toggle("CAPS", [](){force_caps_on = true;}, [](){force_caps_on = false;}); - toggle *color_toggle = new toggle("COLOR", [](){draw_using_color = true;}, [](){draw_using_color = false;}); - toggle *pause_toggle = new toggle("PAUSE", [](){event_queue.push_back({PAUSE, 1});}, [](){event_queue.push_back({PAUSE, 0});}); + toggle *fast_toggle = new toggle("FAST", false, [](){event_queue.push_back({SPEED, 1});}, [](){event_queue.push_back({SPEED, 0});}); + caps_toggle = new toggle("CAPS", true, [](){force_caps_on = true;}, [](){force_caps_on = false;}); + toggle *color_toggle = new toggle("COLOR", false, [](){draw_using_color = true;}, [](){draw_using_color = false;}); + toggle *pause_toggle = new toggle("PAUSE", false, [](){event_queue.push_back({PAUSE, 1});}, [](){event_queue.push_back({PAUSE, 0});}); vector widgets = {reset_momentary, reboot_momentary, fast_toggle, caps_toggle, color_toggle, pause_toggle}; ui = new vbox(widgets); CheckOpenGL(__FILE__, __LINE__); @@ -888,6 +894,16 @@ static void error_callback(int error, const char* description) static void key(GLFWwindow *window, int key, int scancode, int action, int mods) { static bool super_down = false; + static bool caps_lock_down = false; + + // XXX not ideal, can be enqueued out of turn + if(caps_lock_down && !force_caps_on) { + caps_lock_down = false; + event_queue.push_back({KEYUP, CAPS_LOCK}); + } else if(!caps_lock_down && force_caps_on) { + caps_lock_down = true; + event_queue.push_back({KEYDOWN, CAPS_LOCK}); + } if(action == GLFW_PRESS) { if(key == GLFW_KEY_RIGHT_SUPER || key == GLFW_KEY_LEFT_SUPER) @@ -896,11 +912,20 @@ static void key(GLFWwindow *window, int key, int scancode, int action, int mods) const char* text = glfwGetClipboardString(window); if (text) event_queue.push_back({PASTE, 0, strdup(text)}); - } else + } else { + if(key == GLFW_KEY_CAPS_LOCK) { + force_caps_on = true; + caps_toggle->on = true; + } event_queue.push_back({KEYDOWN, key}); + } } else if(action == GLFW_RELEASE) { if(key == GLFW_KEY_RIGHT_SUPER || key == GLFW_KEY_LEFT_SUPER) super_down = false; + if(key == GLFW_KEY_CAPS_LOCK) { + force_caps_on = false; + caps_toggle->on = false; + } event_queue.push_back({KEYUP, key}); } }