mirror of
https://github.com/bradgrantham/apple2e.git
synced 2025-01-01 03:31:18 +00:00
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:
parent
f107f4b23d
commit
ca376dab5a
85
apple2e.cpp
85
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<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 {
|
||||
|
||||
|
@ -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});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user