CAPS lock, More instructions and compatibility

GLFW doesn't pass through Mac CAPS lock key for some reason.
CAPS button in GUI works, though.
Implement more instructions, mostly for ChopLifter
    DEC abs, X
    INC abs, X
    AND (ind), Y
    AND abs, X
    ROR abs
Now ChopLifter needs unimplemented SED!  Probably uses decimal mode while printing score.
Set "then" at end of CPU loop to try to throttle better.  Not sure it helps.
This commit is contained in:
Brad Grantham 2016-11-28 14:22:22 -08:00
parent f107f4b23d
commit ca376dab5a
2 changed files with 107 additions and 23 deletions

View File

@ -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<chrono::system_clock> then;
while(1) {
if(!debugging) {
poll_keyboard();
@ -2405,13 +2463,12 @@ int main(int argc, char **argv)
}
}
chrono::time_point<chrono::system_clock> 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<chrono::milliseconds>(now - then);
if(!run_fast || pause_cpu)
this_thread::sleep_for(chrono::milliseconds(millis_per_slice) - elapsed_millis);
then = now;
} else {

View File

@ -47,7 +47,7 @@ static int gButtonPressed = -1;
deque<event> 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<void()> action_on;
std::function<void()> action_off;
toggle(const string& content_, std::function<void()> action_on_, std::function<void()> action_off_) :
toggle(const string& content_, bool initial_state, std::function<void()> action_on_, std::function<void()> 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<float, float> 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<widget*> 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});
}
}