diff --git a/Makefile b/Makefile index 886e889..eaf2de5 100755 --- a/Makefile +++ b/Makefile @@ -8,17 +8,17 @@ CXXFLAGS=-Wall -I/usr/include/SDL2 -I .. -I . -I apple -I nix -I sdl -I/usr/loca TSRC=cpu.cpp util/testharness.cpp -COMMONSRCS=cpu.cpp apple/appledisplay.cpp apple/applekeyboard.cpp apple/applemmu.cpp apple/applevm.cpp apple/diskii.cpp apple/nibutil.cpp LRingBuffer.cpp globals.cpp apple/parallelcard.cpp apple/fx80.cpp lcg.cpp apple/hd32.cpp images.cpp apple/appleui.cpp vmram.cpp bios.cpp apple/noslotclock.cpp apple/woz.cpp apple/crc32.c apple/woz-serializer.cpp +COMMONSRCS=cpu.cpp apple/appledisplay.cpp apple/applekeyboard.cpp apple/applemmu.cpp apple/applevm.cpp apple/diskii.cpp apple/nibutil.cpp LRingBuffer.cpp globals.cpp apple/parallelcard.cpp apple/fx80.cpp lcg.cpp apple/hd32.cpp images.cpp apple/appleui.cpp vmram.cpp bios.cpp apple/noslotclock.cpp apple/woz.cpp apple/crc32.c apple/woz-serializer.cpp apple/mouse.c -COMMONOBJS=cpu.o apple/appledisplay.o apple/applekeyboard.o apple/applemmu.o apple/applevm.o apple/diskii.o apple/nibutil.o LRingBuffer.o globals.o apple/parallelcard.o apple/fx80.o lcg.o apple/hd32.o images.o apple/appleui.o vmram.o bios.o apple/noslotclock.o apple/woz.o apple/crc32.o apple/woz-serializer.o apple/mouse.o apple/pia6821.o +COMMONOBJS=cpu.o apple/appledisplay.o apple/applekeyboard.o apple/applemmu.o apple/applevm.o apple/diskii.o apple/nibutil.o LRingBuffer.o globals.o apple/parallelcard.o apple/fx80.o lcg.o apple/hd32.o images.o apple/appleui.o vmram.o bios.o apple/noslotclock.o apple/woz.o apple/crc32.o apple/woz-serializer.o apple/mouse.o FBSRCS=linuxfb/linux-speaker.cpp linuxfb/fb-display.cpp linuxfb/linux-keyboard.cpp linuxfb/fb-paddles.cpp nix/nix-filemanager.cpp linuxfb/aiie.cpp linuxfb/linux-printer.cpp nix/nix-clock.cpp nix/nix-prefs.cpp FBOBJS=linuxfb/linux-speaker.o linuxfb/fb-display.o linuxfb/linux-keyboard.o linuxfb/fb-paddles.o nix/nix-filemanager.o linuxfb/aiie.o linuxfb/linux-printer.o nix/nix-clock.o nix/nix-prefs.o -SDLSRCS=sdl/sdl-speaker.cpp sdl/sdl-display.cpp sdl/sdl-keyboard.cpp sdl/sdl-paddles.cpp nix/nix-filemanager.cpp sdl/aiie.cpp sdl/sdl-printer.cpp nix/nix-clock.cpp nix/nix-prefs.cpp nix/debugger.cpp nix/disassembler.cpp +SDLSRCS=sdl/sdl-speaker.cpp sdl/sdl-display.cpp sdl/sdl-keyboard.cpp sdl/sdl-paddles.cpp nix/nix-filemanager.cpp sdl/aiie.cpp sdl/sdl-printer.cpp nix/nix-clock.cpp nix/nix-prefs.cpp nix/debugger.cpp nix/disassembler.cpp sdl/sdl-mouse.cpp -SDLOBJS=sdl/sdl-speaker.o sdl/sdl-display.o sdl/sdl-keyboard.o sdl/sdl-paddles.o nix/nix-filemanager.o sdl/aiie.o sdl/sdl-printer.o nix/nix-clock.o nix/nix-prefs.o nix/debugger.o nix/disassembler.o +SDLOBJS=sdl/sdl-speaker.o sdl/sdl-display.o sdl/sdl-keyboard.o sdl/sdl-paddles.o nix/nix-filemanager.o sdl/aiie.o sdl/sdl-printer.o nix/nix-clock.o nix/nix-prefs.o nix/debugger.o nix/disassembler.o sdl/sdl-mouse.o ROMS=apple/applemmu-rom.h apple/diskii-rom.h apple/parallel-rom.h apple/hd32-rom.h MouseInterface.rom diff --git a/apple/mouse.cpp b/apple/mouse.cpp index e252ef4..ad0ad25 100644 --- a/apple/mouse.cpp +++ b/apple/mouse.cpp @@ -5,6 +5,7 @@ #include "mouse-rom.h" enum { + SW_W_INIT = 0x00, SW_R_HOMEMOUSE = 0x08, SW_R_POSMOUSE = 0x09, SW_R_CLEARMOUSE = 0x0A, @@ -15,6 +16,11 @@ enum { SW_W_SETMOUSE = 0x0F }; +// The first 3 soft switch bits technically should pass directly to +// the PIA6821. In practice, so far, I've only seen the first (SW_W_INIT) +// used when PR#4 is invoked to initialize the mouse interface from DOS, +// so for the moment I'll just catch that specifically. + enum { ST_MOUSEENABLE = 1, ST_INTMOUSE = 2, @@ -26,6 +32,8 @@ Mouse::Mouse() { status = 0; interruptsTriggered = 0; + lastX = lastY = 0; + lastButton = false; } Mouse::~Mouse() @@ -50,29 +58,43 @@ uint8_t Mouse::readSwitches(uint8_t s) { switch (s) { case SW_R_HOMEMOUSE: - printf("unimplemented SW_R_HOMEMOUSE\n"); - /* physical mouse X = $578/$478; - * physical mouse Y = $5f8/$4f8 */ + g_mouse->setPosition( (g_ram.readByte(0x578) << 8) | g_ram.readByte(0x478), + (g_ram.readByte(0x5F8) << 8) | g_ram.readByte(0x4F8) + ); break; case SW_R_POSMOUSE: - printf("unimplemented SW_R_POSMOUSE\n"); - /* physical mouse X = $578+4/$478+4; - * physical mouse Y + $5F8+4/$4f8+4 */ + g_mouse->setPosition( (g_ram.readByte(0x578+4) << 8) | g_ram.readByte(0x478+4), + (g_ram.readByte(0x5F8+4) << 8) | g_ram.readByte(0x4F8+4) + ); break; case SW_R_CLEARMOUSE: g_ram.writeByte(0x578+4, 0); g_ram.writeByte(0x478+4, 0); g_ram.writeByte(0x5F8+4, 0); g_ram.writeByte(0x4F8+4, 0); - /* physical mouse X = Y = 0 */ + g_mouse->setPosition(0,0); break; case SW_R_READMOUSE: - printf("unimplemented SW_R_READMOUSE\n"); - // FIXME: read from physical mouse and write to: - g_ram.writeByte(0x578+4, 0); // high X - g_ram.writeByte(0x478+4, 0); // low X - g_ram.writeByte(0x5F8+4, 0); // high Y - g_ram.writeByte(0x4F8+4, 0); // low Y + { + uint16_t xpos, ypos; + g_mouse->getPosition(&xpos, &ypos); + if (lastX != xpos || lastY != ypos) { + interruptsTriggered |= 0x20; // "x or y changed since last reading" + lastX = xpos; lastY = ypos; + } + curButton = g_mouse->getButton(); + uint8_t newStatus = g_ram.readByte(0x778+4) & ~0xC0; + if (curButton) { newStatus |= 0x80; }; + if (lastButton) { newStatus |= 0x40; }; + + uint16_t xv = xpos >> 8; xv &= 0xFF; + printf("XPOS: %d => 0x%X 0x%X\n", xpos, xv, xpos & 0xFF); + + g_ram.writeByte(0x578+4, xv); // high X + g_ram.writeByte(0x478+4, xpos & 0xFF); // low X + g_ram.writeByte(0x5F8+4, (ypos >> 8) & 0xFF); // high Y + g_ram.writeByte(0x4F8+4, ypos); // low Y + } break; case SW_R_INITMOUSE: // Set clamp to (0,0) - (1023,1023) @@ -80,11 +102,15 @@ uint8_t Mouse::readSwitches(uint8_t s) g_ram.writeByte(0x478, 0); // low of lowclamp g_ram.writeByte(0x5F8, 0x03); // high of highclamp g_ram.writeByte(0x4F8, 0xFF); // low of highclamp - printf("unimplemented SW_R_INITMOUSE\n"); - /* physicalMouse->setClamp(XCLAMP, 0, 1023); - * physicalMouse->setClamp(YCLAMP, 0, 1023); */ + g_mouse->setClamp(XCLAMP, 0, 1023); + g_mouse->setClamp(YCLAMP, 0, 1023); break; case SW_R_SERVEMOUSE: + if (lastButton) interruptsTriggered |= 0x40; + if (curButton != lastButton) { + interruptsTriggered |= 0x80; + lastButton = curButton; + } g_ram.writeByte(0x778+4, interruptsTriggered); g_ram.writeByte(0x6B8+4, interruptsTriggered); // hack to appease ROM interruptsTriggered = 0; @@ -98,25 +124,30 @@ uint8_t Mouse::readSwitches(uint8_t s) void Mouse::writeSwitches(uint8_t s, uint8_t v) { switch (s) { + case SW_W_INIT: + v &= 0x03; // just the low 3 bits apparently? + printf("Simple init: value is 0x%X\n", v); + status = v; + g_ram.writeByte(0x7f8 + 4, v); + break; case SW_W_CLAMPMOUSE: { uint16_t lowval = (g_ram.readByte(0x578) << 8) | (g_ram.readByte(0x478)); uint16_t highval = (g_ram.readByte(0x5F8) << 8) | (g_ram.readByte(0x4F8)); if (v) { - // Y is clamping - /* physicalMouse->setClamp(YCLAMP, lowval, highval); */ + g_mouse->setClamp(YCLAMP, lowval, highval); } else { // X is clamping - /* physicalMouse->setClamp(XCLAMP, lowval, highval); */ + g_mouse->setClamp(XCLAMP, lowval, highval); } - printf("unimplemented SW_W_CLAMPMOUSE [0x%X]\n", v); } break; case SW_W_SETMOUSE: status = v; + g_ram.writeByte(0x7f8 + 4, v); break; default: - printf("mouse: unknown switch write 0x%X\n", s); + printf("mouse: unknown switch write 0x%X = 0x%2X\n", s, v); break; } } @@ -125,7 +156,7 @@ void Mouse::loadROM(uint8_t *toWhere) { /* Actual mouse ROM Disassembly: C400- 2C 58 FF BIT $FF58 ; test bits in FF58 w/ A -C403- 70 1B BVS $C420 ; V will contain bit 6 from $FF58, which should be $20 on boot-up +C403- 70 1B BVS $C420 ; V will contain bit 6 from $FF58, which should be $60 on boot-up (RTS), which has $40 set, so should branch here C405- 38 SEC C406- 90 18 BCC $C420 ; no-op; unless called @ $C406 directly? @@ -154,13 +185,12 @@ C41D- AE C41E- AE C41F- AE -; Main +; Main (installs KSW for IN# handling) C420- 48 PHA ; push accumulator to stack C421- 98 TYA C422- 48 PHA ; push Y to stack C423- 8A TXA C424- 48 PHA ; push X to stack -C424- 48 PHA C425- 08 PHP ; push status to stack C426- 78 SEI ; disable interrupts @@ -176,28 +206,30 @@ C426- 78 SEI ; disable interrupts ; TSX ; LDA $100, X ; grab the return address off the stack -C427- 20 58 FF JSR $FF58 -C42A- BA TSX -C42B- BD 00 01 LDA $0100,X -C42E- AA TAX +C427- 20 58 FF JSR $FF58 ; call something that will RTS +C42A- BA TSX ; pull stack pointer to X +C42B- BD 00 01 LDA $0100,X ; grab A from the current stack pointer, which has our return addr +C42E- AA TAX ; X = return addr C42F- 0A ASL C430- 0A ASL C431- 0A ASL C432- 0A ASL -C433- A8 TAY -C434- 28 PLP ; restore status from stack -C435- 50 0F BVC $C446 ; overflow is clear if ... ? -C437- A5 38 LDA $38 ; >> what's in $38? +C433- A8 TAY ; Y = (return addr) << 4 +C434- 28 PLP ; restore status from stack (includes V,C) +C435- 50 0F BVC $C446 ; overflow is clear from when we were called? +C437- A5 38 LDA $38 ; >> $38 is the IN# vector ("KSW") low byte C439- D0 0D BNE $C448 ; restore stack & return C43B- 8A TXA -C43C- 45 39 EOR $39 ; >> what's in $39? +C43C- 45 39 EOR $39 ; >> KSW high byte C43E- D0 08 BNE $C448 ; restore stack & return C440- A9 05 LDA #$05 C442- 85 38 STA $38 ; ($38) = $05 -C442- 85 38 STA $38 C444- D0 0B BNE $C451 +;; we wind up here when the entry vector $c405 is called directly (from $9eba) C446- B0 09 BCS $C451 ; carry set if ... ? + +;; entry point when called as PR# so BASIC/DOS can init the mouse C448- 68 PLA ; pull X from stack C449- AA TAX C44A- 68 PLA ; pull Y from stack, but @@ -277,6 +309,7 @@ C4A7- D0 F1 BNE $C49A C4A9- EA NOP C4AA- A9 07 LDA #$07 C4AC- D0 EC BNE $C49A +; "TimeData" to set freq before init to 50/60 Hz? Doesn't look like it... C4AE- A2 03 LDX #$03 C4B0- 38 SEC C4B1- 60 RTS @@ -314,8 +347,7 @@ Patch: C471 from 99 82 C0 60 => 8D CF C0 60 SERVEMOUSE @ $C4B2: 78 SEI - AD CE C0 LDA $C0CE ; use soft switch 0xE (read) to trigger this - expect ne\ -w value to be placed in $7f8+4 and $6b8+4 + AD CE C0 LDA $C0CE ; use soft switch 0xE (read) to trigger this - expect new value to be placed in $7f8+4 and $6b8+4 A2 04 LDX #$04 ; our slot number, for cleanup code 18 CLC 90 C1 BCC $C47C @@ -324,7 +356,7 @@ Patch: C4B2 from 08 A5 00 48 A9 60 85 00 78 => 78 AD CE C0 A2 04 18 90 C1 READMOUSE -C48E- AD CB C0 LDA $C04B ; soft switch 0x0B for readmouse +C48E- AD CB C0 LDA $C0CB ; soft switch 0x0B for readmouse 18 CLC 60 RTS @@ -332,14 +364,14 @@ Patch: from A9 04 99 83 C0 => AD CB C0 18 60 CLEARMOUSE -C49F- AD CA C0 LDA $C04A ; soft switch 0x0A for clearmouse +C49F- AD CA C0 LDA $C0CA ; soft switch 0x0A for clearmouse 18 CLC 60 RTS Patch: from EA A9 05 D0 F6 => AD CA C0 18 60 POSMOUSE -C4a4- AD C9 C0 LDA $C049 ; soft switch 0x09 for posmouse +C4a4- AD C9 C0 LDA $C0C9 ; soft switch 0x09 for posmouse 18 CLC 60 RTS @@ -347,20 +379,20 @@ Patch: from EA A9 06 D0 F1 => AD C9 C0 18 60 CLAMPMOUSE -C48A- 8D CD C0 STA $C04D ; use write to soft switch 0x0D to trigger clamp +C48A- 8D CD C0 STA $C0CD ; use write to soft switch 0x0D to trigger clamp 60 RTS Patch: from 99 83 C0 60 => 8D CD C0 60 HOMEMOUSE -C4A9- AD C8 C0 LDA $c048 ; soft switch 0x08 for homemouse (read) +C4A9- AD C8 C0 LDA $c0C8 ; soft switch 0x08 for homemouse (read) 18 CLC 60 RTS Patch: from EA A9 07 D0 EC => AD C8 C0 18 60 INITMOUSE -C498- AD CC C0 LDA $C04C ; soft switch 0x0C read for initmouse +C498- AD CC C0 LDA $C0CC ; soft switch 0x0C read for initmouse 18 CLC 60 RTS @@ -376,8 +408,8 @@ Patch: from A9 02 99 83 C0 => AD CC C0 18 60 0x0A, 0x0A, 0x0A, 0xA8, 0x28, 0x50, 0x0F, 0xA5, // C430 0x38, 0xd0, 0x0d, 0x8a, 0x45, 0x39, 0xd0, 0x08, 0xa9, 0x05, 0x85, 0x38, 0xd0, 0x0b, 0xb0, 0x09, // C440 - 0x68, 0xaa, 0x68, 0xea, 0x68, 0x99, 0x80, 0xc0, - 0x60, 0x99, 0x81, 0xc0, 0x68, 0xbd, 0x38, 0x06, // C450 + 0x68, 0xaa, 0x68, 0xea, 0x68, 0xea, 0xea, 0xea, + 0x60, 0x99, 0x81, 0xc0, 0x68, 0xbd, 0x38, 0x06, // C450 0xaa, 0x68, 0xa8, 0x68, 0xbd, 0x00, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // C460 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0x10, 0xb0, @@ -426,13 +458,25 @@ void Mouse::maintainMouse(int64_t cycleCount) static int64_t nextInterruptTime = cycleCount + 17050; if ( (status & ST_MOUSEENABLE) && - (status & ST_INTVBL) ) { - if (cycleCount >= nextInterruptTime) { - g_cpu->irq(); + (status & ST_INTVBL) && + (cycleCount >= nextInterruptTime) ) { + g_cpu->irq(); + + interruptsTriggered |= ST_INTVBL; + + nextInterruptTime += 17050; + } else { + uint16_t xpos, ypos; + g_mouse->getPosition(&xpos, &ypos); - interruptsTriggered |= ST_INTVBL; + if ( (status & ST_MOUSEENABLE) && + (status & ST_INTMOUSE) && + (xpos != lastX || ypos != lastY) ) { + g_cpu->irq(); - nextInterruptTime += 17050; + interruptsTriggered |= ST_INTMOUSE; + lastX = xpos; lastY = ypos; } } + /* FIXME: still need button */ } diff --git a/apple/mouse.h b/apple/mouse.h index 83a045d..5a29e7c 100644 --- a/apple/mouse.h +++ b/apple/mouse.h @@ -32,6 +32,10 @@ class Mouse : public Slot { private: uint8_t status; uint8_t interruptsTriggered; + + uint16_t lastX, lastY; + bool lastButton; + bool curButton; }; #endif diff --git a/globals.cpp b/globals.cpp index e614a4c..8f7f2ea 100644 --- a/globals.cpp +++ b/globals.cpp @@ -5,6 +5,7 @@ Cpu *g_cpu = NULL; VM *g_vm = NULL; PhysicalDisplay *g_display = NULL; PhysicalKeyboard *g_keyboard = NULL; +PhysicalMouse *g_mouse = NULL; PhysicalSpeaker *g_speaker = NULL; PhysicalPaddles *g_paddles = NULL; PhysicalPrinter *g_printer = NULL; diff --git a/globals.h b/globals.h index 5edd239..634c8fa 100644 --- a/globals.h +++ b/globals.h @@ -8,6 +8,7 @@ #include "vm.h" #include "physicaldisplay.h" #include "physicalkeyboard.h" +#include "physicalmouse.h" #include "physicalspeaker.h" #include "physicalpaddles.h" #include "physicalprinter.h" @@ -41,6 +42,7 @@ extern Cpu *g_cpu; extern VM *g_vm; extern PhysicalDisplay *g_display; extern PhysicalKeyboard *g_keyboard; +extern PhysicalMouse *g_mouse; extern PhysicalSpeaker *g_speaker; extern PhysicalPaddles *g_paddles; extern PhysicalPrinter *g_printer; diff --git a/nix/debugger.cpp b/nix/debugger.cpp index aea5cc4..b547ce0 100644 --- a/nix/debugger.cpp +++ b/nix/debugger.cpp @@ -51,6 +51,9 @@ Debugger::Debugger() server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(12345); + steppingOut = false; + singleStep = false; + if (bind(sd, (struct sockaddr *) &server, sizeof(server)) < 0) { perror("error binding to debug socket"); exit(1); @@ -71,10 +74,14 @@ Debugger::~Debugger() bool getAddress(const char *buf, unsigned int *addrOut) { unsigned int val; - if (sscanf(buf, " 0x%X", &val) == 1) { + if (sscanf(buf, " 0x%X", &val) == 1 || + sscanf(buf, " 0x%x", &val) == 1 + ) { *addrOut = val; return true; - } else if (sscanf(buf, " $%X", &val) == 1) { + } else if (sscanf(buf, " $%X", &val) == 1 || + sscanf(buf, " $%x", &val) == 1 + ) { *addrOut = val; return true; } else if (sscanf(buf, " %d", &val) == 1) { @@ -91,11 +98,10 @@ bool getAddress(const char *buf, unsigned int *addrOut) #define HEXCHAR(x) ((x>='0'&&x<='9')?x-'0':(x>='a'&&x<='f')?x-'a'+10:(x>='A'&&x<='F')?x-'A'+10:(x=='i' || x=='I')?1:(x=='o' || x=='O')?0:0) #define FROMHEXP(p) ((HEXCHAR(*p) << 4) | HEXCHAR(*(p+1))) -bool steppingOut = false; - void Debugger::step() { static char buf[256]; + uint8_t cmdbuf[50]; // FIXME: add more than just RTS(0x60) here if (steppingOut && @@ -124,38 +130,54 @@ void Debugger::step() return; } - uint8_t cmdbuf[50]; - - uint16_t loc=g_cpu->pc; - for (int i=0; i<50/3; i++) { - for (int idx=0; idxgetMMU()->read(loc+idx); - } - loc += dis.instructionToMnemonic(loc, cmdbuf, buf, sizeof(buf)); - write(cd, buf, strlen(buf)); - buf[0] = 13; - buf[1] = 10; - write(cd, buf, 2); - } - - - if (breakpoint && g_cpu->pc != breakpoint) { + if (!singleStep && breakpoint && g_cpu->pc != breakpoint) { // Running until we reach the breakpoint return; } + singleStep = false; // we have taken a single step, so reset flag uint8_t b; // byte value used in parsing unsigned int val; // common value buffer used in parsing - GETCH; - snprintf(buf, sizeof(buf), "Got char %d\012\015", b); + // debugging what's at FF58 right now + uint8_t tmp = g_vm->getMMU()->read(0xff58); + sprintf(buf, " 0xFF58: 0x%.2X\r\n", tmp); write(cd, buf, strlen(buf)); + doover: + do { + GETCH; + } while (b != 'c' && // continue (with breakpoint set) + b != 'q' && // quit + b != 's' && // single step + b != 'S' && // step out + b != 'b' && // set breakpoint + b != 'd' && // show disassembly + b != 'L' && // load memory (lines) + b != '*' // show memory (byte) + ); + switch (b) { - case 'c': // Continue - close connection and let execution flow + case 'c': // continue (if there is a breakpoint set) + if (breakpoint) { + snprintf(buf, sizeof(buf), "Continuing until breakpoint 0x%X\012\015", breakpoint); + write(cd, buf, strlen(buf)); + } else { + snprintf(buf, sizeof(buf), "No breakpoint to continue until\012\015"); + write(cd, buf, strlen(buf)); + goto doover; + } + break; + + case 'q': // Close debugging socket and quit printf("Closing debugging socket\n"); + breakpoint = 0; close(cd); cd=-1; break; + + case 's': + singleStep = true; // for when breakpoint is set: just step once + break; case 'S': steppingOut = true; @@ -176,6 +198,23 @@ void Debugger::step() write(cd, buf, strlen(buf)); break; + case 'd': // show disassembly @ PC + { + uint16_t loc=g_cpu->pc; + for (int i=0; i<50/3; i++) { + for (int idx=0; idxgetMMU()->read(loc+idx); + } + loc += dis.instructionToMnemonic(loc, cmdbuf, buf, sizeof(buf)); + write(cd, buf, strlen(buf)); + buf[0] = 13; + buf[1] = 10; + write(cd, buf, 2); + } + } + goto doover; + break; + case 'L': // Load data to memory. Use: "L 0x
\n" followed by lines of packed hex; ends with a blank line { printf("Loading data\n"); @@ -198,6 +237,7 @@ void Debugger::step() } } } + goto doover; break; case '*': // read 1 byte of memory. Use '* 0x
' @@ -214,6 +254,7 @@ void Debugger::step() write(cd, buf, strlen(buf)); } } + goto doover; break; case 'G': // Goto (set PC) diff --git a/nix/debugger.h b/nix/debugger.h index 05d7bc7..66936c9 100644 --- a/nix/debugger.h +++ b/nix/debugger.h @@ -19,6 +19,8 @@ class Debugger { pthread_t listenThreadID; uint32_t breakpoint; + bool steppingOut; + bool singleStep; }; diff --git a/physicalmouse.h b/physicalmouse.h index 6fb82a7..9189d11 100644 --- a/physicalmouse.h +++ b/physicalmouse.h @@ -2,13 +2,27 @@ #define __PHYSICALMOUSE_H #include +#include + +enum { + XCLAMP = 0, + YCLAMP = 1 +}; class PhysicalMouse { public: - PhysicalMouse() {} + PhysicalMouse() { lowClamp[XCLAMP] = lowClamp[YCLAMP] = 0; highClamp[XCLAMP] = highClamp[YCLAMP] = 1023; } virtual ~PhysicalMouse() {}; virtual void maintainMouse() = 0; + + virtual void setClamp(uint8_t direction, uint16_t low, uint16_t high) { lowClamp[direction] = low; highClamp[direction] = high; printf("clamp %d %d-%d\n", direction, low, high); } + virtual void setPosition(uint16_t x, uint16_t y) = 0; + virtual void getPosition(uint16_t *x, uint16_t *y) = 0; + virtual bool getButton() = 0; + +protected: + uint16_t lowClamp[2], highClamp[2]; }; #endif diff --git a/sdl/aiie.cpp b/sdl/aiie.cpp index 04ba5c4..97648e7 100644 --- a/sdl/aiie.cpp +++ b/sdl/aiie.cpp @@ -7,6 +7,7 @@ #include "applevm.h" #include "sdl-display.h" #include "sdl-keyboard.h" +#include "sdl-mouse.h" #include "sdl-speaker.h" #include "sdl-paddles.h" #include "nix-filemanager.h" @@ -291,7 +292,7 @@ struct timespec runMaintenance(struct timespec now) initialized = true; } - timespec_add_us(&startTime, 100000*cycleCount, &nextRuntime); // FIXME: what's a good time here? 1/10 sec? + timespec_add_us(&startTime, 16667*cycleCount, &nextRuntime); // FIXME: what's a good time here? 60 Hz? // Check if it's time to run - and if not, return how long it will // be until we need to run @@ -305,6 +306,7 @@ struct timespec runMaintenance(struct timespec now) if (!g_biosInterrupt) { // If the BIOS is running, then let it handle the keyboard directly g_keyboard->maintainKeyboard(); + g_mouse->maintainMouse(); } doDebugging(); @@ -389,6 +391,7 @@ int main(int argc, char *argv[]) g_vm = new AppleVM(); g_keyboard = new SDLKeyboard(g_vm->getKeyboard()); + g_mouse = new SDLMouse(); // Now that the VM exists and it has created an MMU, we tell the CPU how to access memory through the MMU. g_cpu->SetMMU(g_vm->getMMU()); diff --git a/sdl/sdl-keyboard.cpp b/sdl/sdl-keyboard.cpp index 89b0b1a..bb81c34 100644 --- a/sdl/sdl-keyboard.cpp +++ b/sdl/sdl-keyboard.cpp @@ -1,6 +1,7 @@ #include "sdl-keyboard.h" #include "sdl-paddles.h" +#include "sdl-mouse.h" #include "globals.h" SDLKeyboard::SDLKeyboard(VMKeyboard *k) : PhysicalKeyboard(k) @@ -149,12 +150,18 @@ void SDLKeyboard::maintainKeyboard() if (event.key.repeat == 0) handleKeypress(&event.key); break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + ((SDLMouse *)g_mouse)->mouseButtonEvent(event.type == SDL_MOUSEBUTTONDOWN); + break; case SDL_MOUSEMOTION: // We are handling the SDL input loop, so need to pass this off to the paddles. :/ // FIXME: nasty rooting around in other objects and typecasting. // FIXME: event.motion.state & SDL_BUTTON_LMASK, et al? ((SDLPaddles *)g_paddles)->gotMouseMovement(event.motion.x, event.motion.y); + ((SDLMouse *)g_mouse)->gotMouseEvent(event.motion.state, // button + event.motion.xrel, event.motion.yrel); break; case SDL_QUIT: