mirror of
https://github.com/JorjBauer/aiie.git
synced 2024-12-26 08:29:31 +00:00
patching together more mouse work
This commit is contained in:
parent
b09df8e5f9
commit
0b8e027096
8
Makefile
8
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
|
||||
|
||||
|
142
apple/mouse.cpp
142
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 */
|
||||
}
|
||||
|
@ -32,6 +32,10 @@ class Mouse : public Slot {
|
||||
private:
|
||||
uint8_t status;
|
||||
uint8_t interruptsTriggered;
|
||||
|
||||
uint16_t lastX, lastY;
|
||||
bool lastButton;
|
||||
bool curButton;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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; idx<sizeof(cmdbuf); idx++) {
|
||||
cmdbuf[idx] = g_vm->getMMU()->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; idx<sizeof(cmdbuf); idx++) {
|
||||
cmdbuf[idx] = g_vm->getMMU()->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<address>\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<address>'
|
||||
@ -214,6 +254,7 @@ void Debugger::step()
|
||||
write(cd, buf, strlen(buf));
|
||||
}
|
||||
}
|
||||
goto doover;
|
||||
break;
|
||||
|
||||
case 'G': // Goto (set PC)
|
||||
|
@ -19,6 +19,8 @@ class Debugger {
|
||||
pthread_t listenThreadID;
|
||||
|
||||
uint32_t breakpoint;
|
||||
bool steppingOut;
|
||||
bool singleStep;
|
||||
};
|
||||
|
||||
|
||||
|
@ -2,13 +2,27 @@
|
||||
#define __PHYSICALMOUSE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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
|
||||
|
@ -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());
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user