mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-09-29 23:54:53 +00:00
65c02 Debugger fixen
* Threading fixes to allow CPU thread to iterate while under control of interface/video thread
This commit is contained in:
parent
c300e3e016
commit
f34eff338b
@ -2716,8 +2716,6 @@ continue1: xorl %eax, %eax
|
|||||||
|
|
||||||
exception: testb $ResetSig, %al
|
exception: testb $ResetSig, %al
|
||||||
jnz ex_reset0
|
jnz ex_reset0
|
||||||
testb $DebugStepSig, %al
|
|
||||||
jnz ex_step
|
|
||||||
jmp ex_irq
|
jmp ex_irq
|
||||||
|
|
||||||
ex_reset0: testb $0xff, SN(joy_button0) // OpenApple
|
ex_reset0: testb $0xff, SN(joy_button0) // OpenApple
|
||||||
@ -2787,12 +2785,6 @@ emul_reinit: movb $0, SN(cpu65__signal) // Return to timing
|
|||||||
Debugger hooks
|
Debugger hooks
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
ex_step: orb $~DebugStepSig, SN(cpu65__signal)
|
|
||||||
SaveState
|
|
||||||
call SN(c_stepping_yield)
|
|
||||||
RestoreState
|
|
||||||
JumpNextInstruction
|
|
||||||
|
|
||||||
E(cpu65_direct_write)
|
E(cpu65_direct_write)
|
||||||
/* NB: dependent on register choices */
|
/* NB: dependent on register choices */
|
||||||
pushl %edi
|
pushl %edi
|
||||||
|
@ -119,15 +119,3 @@ void cpu65_uninterrupt(int reason)
|
|||||||
pthread_mutex_unlock(&irq_mutex);
|
pthread_mutex_unlock(&irq_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu65_set_stepping(int flag)
|
|
||||||
{
|
|
||||||
if (flag)
|
|
||||||
{
|
|
||||||
cpu65_interrupt(DebugStepSig);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cpu65_interrupt(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -66,8 +66,6 @@ extern void cpu65_uninterrupt(int reason);
|
|||||||
|
|
||||||
extern void cpu65_run(void);
|
extern void cpu65_run(void);
|
||||||
|
|
||||||
extern void cpu65_set_stepping(int flag);
|
|
||||||
|
|
||||||
extern void cpu65_direct_write(int ea,int data);
|
extern void cpu65_direct_write(int ea,int data);
|
||||||
|
|
||||||
extern struct memory_vector cpu65_vmem[65536];
|
extern struct memory_vector cpu65_vmem[65536];
|
||||||
@ -84,7 +82,6 @@ extern uint8_t emul_reinitialize;
|
|||||||
#endif /* !__ASSEMBLER__ */
|
#endif /* !__ASSEMBLER__ */
|
||||||
|
|
||||||
#define ResetSig 0x02
|
#define ResetSig 0x02
|
||||||
#define DebugStepSig 0x04
|
|
||||||
#define IRQ6522 0x08
|
#define IRQ6522 0x08
|
||||||
#define IRQSpeech 0x10
|
#define IRQSpeech 0x10
|
||||||
#define IRQSSC 0x20
|
#define IRQSSC 0x20
|
||||||
|
@ -19,9 +19,6 @@
|
|||||||
/* from misc.c */
|
/* from misc.c */
|
||||||
extern uid_t user, privileged;
|
extern uid_t user, privileged;
|
||||||
|
|
||||||
/* from debugger.c */
|
|
||||||
extern void c_do_debugging();
|
|
||||||
|
|
||||||
/* parameters for generic and keyboard-simulated joysticks */
|
/* parameters for generic and keyboard-simulated joysticks */
|
||||||
extern short joy_x;
|
extern short joy_x;
|
||||||
extern short joy_y;
|
extern short joy_y;
|
||||||
@ -30,6 +27,7 @@ extern unsigned char joy_button1;
|
|||||||
|
|
||||||
/* mutex used to synchronize between cpu and main threads */
|
/* mutex used to synchronize between cpu and main threads */
|
||||||
pthread_mutex_t interface_mutex = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t interface_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
pthread_cond_t interface_cond = PTHREAD_COND_INITIALIZER;
|
||||||
|
|
||||||
#ifdef LINUX_JOYSTICK
|
#ifdef LINUX_JOYSTICK
|
||||||
#include <linux/joystick.h>
|
#include <linux/joystick.h>
|
||||||
@ -270,7 +268,7 @@ void c_handle_input(int scancode, int pressed)
|
|||||||
|
|
||||||
#ifdef DEBUGGER
|
#ifdef DEBUGGER
|
||||||
case kF7:
|
case kF7:
|
||||||
c_do_debugging();
|
c_interface_debugging();
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -137,6 +137,7 @@
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
extern pthread_mutex_t interface_mutex;
|
extern pthread_mutex_t interface_mutex;
|
||||||
|
extern pthread_cond_t interface_cond;
|
||||||
extern bool caps_lock;
|
extern bool caps_lock;
|
||||||
|
|
||||||
#ifdef LINUX_JOYSTICK
|
#ifdef LINUX_JOYSTICK
|
||||||
|
@ -20,25 +20,38 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
/* debugger defines */
|
#ifdef DEBUGGER
|
||||||
#define BUF_X 39
|
extern volatile bool is_debugging;
|
||||||
#define BUF_Y 22
|
#else
|
||||||
|
#define is_debugging false
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
STEPPING = 0,
|
||||||
|
NEXTING,
|
||||||
|
FINISHING,
|
||||||
|
UNTILING,
|
||||||
|
GOING
|
||||||
|
} stepping_type_t;
|
||||||
|
|
||||||
|
typedef struct stepping_struct_t {
|
||||||
|
stepping_type_t step_type;
|
||||||
|
uint16_t step_count;
|
||||||
|
uint16_t step_frame;
|
||||||
|
uint16_t step_pc;
|
||||||
|
bool should_break;
|
||||||
|
} stepping_struct_t;
|
||||||
|
|
||||||
|
#define DEBUGGER_BUF_X 39
|
||||||
|
#define DEBUGGER_BUF_Y 22
|
||||||
#define MAX_BRKPTS 16
|
#define MAX_BRKPTS 16
|
||||||
#define SCREEN_X 81 // 80col + 1
|
|
||||||
#define SCREEN_Y 24
|
|
||||||
#define PROMPT_X 2
|
|
||||||
#define PROMPT_Y BUF_Y - 1
|
|
||||||
#define PROMPT_END_X BUF_X - 2
|
|
||||||
#define command_line command_buf[PROMPT_Y]
|
|
||||||
#define uchar unsigned char
|
|
||||||
|
|
||||||
/* debugger commands */
|
/* debugger commands */
|
||||||
enum token_type { MEM, DIS, REGS, SETMEM, STEP, FINISH, UNTIL, GO, VM,
|
enum token_type { MEM, DIS, REGS, SETMEM, STEP, FINISH, UNTIL, GO, VM,
|
||||||
BREAK, WATCH, CLEAR, IGNORE, STATUS, OPCODES, LC, DRIVE,
|
BREAK, WATCH, CLEAR, IGNORE, STATUS, OPCODES, LC, DRIVE,
|
||||||
SEARCH, HELP, LOG, BSAVE, BLOAD, SAVE, UNKNOWN };
|
SEARCH, HELP, LOG, BSAVE, BLOAD, SAVE, UNKNOWN };
|
||||||
|
|
||||||
enum addressing_mode
|
typedef enum {
|
||||||
{
|
|
||||||
addr_implied,
|
addr_implied,
|
||||||
addr_accumulator,
|
addr_accumulator,
|
||||||
addr_immediate,
|
addr_immediate,
|
||||||
@ -54,27 +67,21 @@ enum addressing_mode
|
|||||||
addr_j_indirect, /* non-zeropage indirects, used in JMP only */
|
addr_j_indirect, /* non-zeropage indirects, used in JMP only */
|
||||||
addr_j_indirect_x,
|
addr_j_indirect_x,
|
||||||
addr_relative
|
addr_relative
|
||||||
};
|
} addressing_mode_t;
|
||||||
|
|
||||||
struct opcode_struct
|
struct opcode_struct
|
||||||
{
|
{
|
||||||
const char *mnemonic;
|
const char *mnemonic;
|
||||||
enum addressing_mode mode;
|
addressing_mode_t mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct opcode_struct *opcodes;
|
extern const struct opcode_struct *opcodes;
|
||||||
|
|
||||||
extern int step_next; /* stepping over instructions */
|
// Debugger commands
|
||||||
extern char second_buf[BUF_Y][BUF_X]; /* scratch buffer for output */
|
|
||||||
extern int num_buffer_lines; /* num lines of output */
|
|
||||||
extern int arg1, arg2, arg3; /* command arguments */
|
|
||||||
extern int breakpoints[MAX_BRKPTS]; /* memory breakpoints */
|
|
||||||
extern int watchpoints[MAX_BRKPTS]; /* memory watchpoints */
|
|
||||||
|
|
||||||
void clear_debugger_screen();
|
void clear_debugger_screen();
|
||||||
void bload(FILE*, char*, int);
|
void bload(FILE*, char*, int);
|
||||||
void show_misc_info();
|
void show_misc_info();
|
||||||
unsigned char get_current_opcode();
|
uint8_t get_current_opcode();
|
||||||
void dump_mem(int, int, int, int, int);
|
void dump_mem(int, int, int, int, int);
|
||||||
void search_mem(char*, int, int);
|
void search_mem(char*, int, int);
|
||||||
void set_mem(int, char*);
|
void set_mem(int, char*);
|
||||||
@ -87,17 +94,15 @@ void show_regs();
|
|||||||
void display_help();
|
void display_help();
|
||||||
void show_lc_info();
|
void show_lc_info();
|
||||||
void show_disk_info();
|
void show_disk_info();
|
||||||
void do_step_or_next(int);
|
void set_halt_opcode(uint8_t opcode);
|
||||||
void begin_cpu_step();
|
|
||||||
void end_cpu_step();
|
|
||||||
int at_haltpt();
|
|
||||||
void set_halt_opcode(unsigned char opcode);
|
|
||||||
void set_halt_65c02();
|
void set_halt_65c02();
|
||||||
void clear_halt_65c02();
|
void clear_halt_65c02();
|
||||||
void clear_halt_opcode(unsigned char opcode);
|
void clear_halt_opcode(uint8_t opcode);
|
||||||
void show_opcode_breakpts();
|
void show_opcode_breakpts();
|
||||||
|
|
||||||
void c_stepping_yield();
|
bool c_debugger_should_break();
|
||||||
|
void c_debugger_begin_stepping(stepping_struct_t s);
|
||||||
|
void c_interface_debugging();
|
||||||
|
|
||||||
extern const struct opcode_struct opcodes_6502[256];
|
extern const struct opcode_struct opcodes_6502[256];
|
||||||
extern const struct opcode_struct opcodes_65c02[256];
|
extern const struct opcode_struct opcodes_65c02[256];
|
||||||
|
@ -28,6 +28,12 @@
|
|||||||
|
|
||||||
YY_BUFFER_STATE buffer = 0;
|
YY_BUFFER_STATE buffer = 0;
|
||||||
|
|
||||||
|
extern char second_buf[DEBUGGER_BUF_Y][DEBUGGER_BUF_X];/* scratch buffer for output */
|
||||||
|
extern int num_buffer_lines; /* num lines of output */
|
||||||
|
extern int arg1, arg2, arg3; /* command arguments */
|
||||||
|
extern int breakpoints[MAX_BRKPTS]; /* memory breakpoints */
|
||||||
|
extern int watchpoints[MAX_BRKPTS]; /* memory watchpoints */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
d{is} {lc1|lc2} {/bank/}{addr} {+}{len}
|
d{is} {lc1|lc2} {/bank/}{addr} {+}{len}
|
||||||
m{em} {lc1|lc2} {/bank/}{addr} {+}{len}
|
m{em} {lc1|lc2} {/bank/}{addr} {+}{len}
|
||||||
@ -436,50 +442,56 @@ ADDRS [0-9a-fA-F]+
|
|||||||
}
|
}
|
||||||
|
|
||||||
{BOS}(st?e?p?|ne?x?t?){EOS} {
|
{BOS}(st?e?p?|ne?x?t?){EOS} {
|
||||||
/* step / step next instruction */
|
|
||||||
if (*debugtext == 'n') step_next = 1;
|
|
||||||
|
|
||||||
do_step_or_next(1);
|
stepping_struct_t s = {
|
||||||
|
.step_type = STEPPING,
|
||||||
|
.step_count = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
if (*debugtext == 'n') {
|
||||||
|
s.step_type = NEXTING;
|
||||||
|
}
|
||||||
|
|
||||||
|
c_debugger_begin_stepping(s);
|
||||||
return STEP;
|
return STEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
{BOS}(st?e?p?|ne?x?t?){WS}+{HEX}+{EOS} {
|
{BOS}(st?e?p?|ne?x?t?){WS}+{HEX}+{EOS} {
|
||||||
/* step / step next <n> instructions */
|
|
||||||
if (*debugtext == 'n') step_next = 1;
|
|
||||||
|
|
||||||
while (!isspace(*debugtext)) ++debugtext;
|
while (!isspace(*debugtext)) ++debugtext;
|
||||||
|
|
||||||
arg1 = strtol(debugtext, (char**)NULL, 16);
|
arg1 = strtol(debugtext, (char**)NULL, 16);
|
||||||
if ((arg1 < 1) || (arg1 > 255)) arg1 = 255;
|
if ((arg1 < 1) || (arg1 > 255)) arg1 = 255;
|
||||||
|
|
||||||
do_step_or_next(arg1);
|
stepping_struct_t s = {
|
||||||
|
.step_type = STEPPING,
|
||||||
|
.step_count = arg1
|
||||||
|
};
|
||||||
|
|
||||||
|
if (*debugtext == 'n') {
|
||||||
|
s.step_type = NEXTING;
|
||||||
|
}
|
||||||
|
|
||||||
|
c_debugger_begin_stepping(s);
|
||||||
return STEP;
|
return STEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
{BOS}fi?n?i?s?h?{EOS} {
|
{BOS}fi?n?i?s?h?{EOS} {
|
||||||
int step_frame = 1;
|
|
||||||
unsigned char op;
|
|
||||||
|
|
||||||
/* step until finished with curent stack frame */
|
stepping_struct_t s = {
|
||||||
while ((c_mygetch(0) == -1) && !at_haltpt()) {
|
.step_type = FINISHING,
|
||||||
op = get_current_opcode();
|
.step_frame = 1
|
||||||
|
};
|
||||||
|
|
||||||
if (op == 0x20) ++step_frame; /* JSR */
|
c_debugger_begin_stepping(s);
|
||||||
if (op == 0x60) --step_frame; /* RTS */
|
|
||||||
|
|
||||||
if (!step_frame) break; /* finished */
|
|
||||||
begin_cpu_step();
|
|
||||||
}
|
|
||||||
end_cpu_step(); /* print location */
|
|
||||||
return FINISH;
|
return FINISH;
|
||||||
}
|
}
|
||||||
|
|
||||||
{BOS}un?t?i?l?{EOS} {
|
{BOS}un?t?i?l?{EOS} {
|
||||||
/* step until PC == next instruction. good for finishing backward
|
/* step until PC == next instruction. good for finishing backward
|
||||||
loops */
|
loops */
|
||||||
unsigned char op;
|
uint8_t op = get_current_opcode();
|
||||||
int delta=0;
|
int delta=0;
|
||||||
op = get_current_opcode();
|
|
||||||
|
|
||||||
switch (opcodes[op].mode)
|
switch (opcodes[op].mode)
|
||||||
{
|
{
|
||||||
@ -506,11 +518,12 @@ ADDRS [0-9a-fA-F]+
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg1 = cpu65_current.pc + delta;
|
stepping_struct_t s = {
|
||||||
|
.step_type = UNTILING,
|
||||||
|
.step_pc = cpu65_current.pc + delta
|
||||||
|
};
|
||||||
|
|
||||||
while ((cpu65_current.pc != arg1) && !at_haltpt() && (c_mygetch(0) == -1))
|
c_debugger_begin_stepping(s);
|
||||||
begin_cpu_step();
|
|
||||||
end_cpu_step(); /* print location */
|
|
||||||
return UNTIL;
|
return UNTIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,17 +533,21 @@ ADDRS [0-9a-fA-F]+
|
|||||||
|
|
||||||
/* DANGEROUS! */
|
/* DANGEROUS! */
|
||||||
cpu65_current.pc = strtol(debugtext, (char**)NULL, 16);
|
cpu65_current.pc = strtol(debugtext, (char**)NULL, 16);
|
||||||
while (!at_haltpt() && (c_mygetch(0) == -1))
|
|
||||||
begin_cpu_step();
|
stepping_struct_t s = {
|
||||||
end_cpu_step(); /* print location */
|
.step_type = GOING
|
||||||
|
};
|
||||||
|
|
||||||
|
c_debugger_begin_stepping(s);
|
||||||
return GO;
|
return GO;
|
||||||
}
|
}
|
||||||
|
|
||||||
{BOS}go?{EOS} {
|
{BOS}go?{EOS} {
|
||||||
/* run while remaining in debugger console */
|
stepping_struct_t s = {
|
||||||
while (!at_haltpt() && (c_mygetch(0) == -1))
|
.step_type = GOING
|
||||||
begin_cpu_step();
|
};
|
||||||
end_cpu_step(); /* print location */
|
|
||||||
|
c_debugger_begin_stepping(s);
|
||||||
return GO;
|
return GO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,7 +603,7 @@ ADDRS [0-9a-fA-F]+
|
|||||||
return BREAK;
|
return BREAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_halt_opcode((unsigned char)arg1);
|
set_halt_opcode((uint8_t)arg1);
|
||||||
return BREAK;
|
return BREAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,9 +672,9 @@ ADDRS [0-9a-fA-F]+
|
|||||||
sprintf(second_buf[num_buffer_lines++], "invalid opcode");
|
sprintf(second_buf[num_buffer_lines++], "invalid opcode");
|
||||||
return CLEAR;
|
return CLEAR;
|
||||||
}
|
}
|
||||||
clear_halt_opcode((unsigned char)arg1);
|
clear_halt_opcode((uint8_t)arg1);
|
||||||
sprintf(second_buf[num_buffer_lines++], "cleared opcode %02X",
|
sprintf(second_buf[num_buffer_lines++], "cleared opcode %02X",
|
||||||
(unsigned char)arg1);
|
(uint8_t)arg1);
|
||||||
}
|
}
|
||||||
return CLEAR;
|
return CLEAR;
|
||||||
}
|
}
|
||||||
@ -740,11 +757,11 @@ ADDRS [0-9a-fA-F]+
|
|||||||
|
|
||||||
{BOS}key{WS}+{HEX}+{EOS} {
|
{BOS}key{WS}+{HEX}+{EOS} {
|
||||||
/* send key code to emulator */
|
/* send key code to emulator */
|
||||||
unsigned char key;
|
uint8_t key;
|
||||||
|
|
||||||
while (!isspace(*debugtext)) ++debugtext;
|
while (!isspace(*debugtext)) ++debugtext;
|
||||||
while (isspace(*debugtext)) ++debugtext;
|
while (isspace(*debugtext)) ++debugtext;
|
||||||
key = (unsigned char) strtol(debugtext, &debugtext, 16);
|
key = (uint8_t) strtol(debugtext, &debugtext, 16);
|
||||||
|
|
||||||
apple_ii_64k[0][0xC000] = key;
|
apple_ii_64k[0][0xC000] = key;
|
||||||
apple_ii_64k[1][0xC000] = key;
|
apple_ii_64k[1][0xC000] = key;
|
||||||
|
@ -18,7 +18,19 @@
|
|||||||
|
|
||||||
const struct opcode_struct *opcodes;
|
const struct opcode_struct *opcodes;
|
||||||
|
|
||||||
int step_next; /* stepping over instructions */
|
static stepping_struct_t stepping_struct;
|
||||||
|
|
||||||
|
volatile bool is_debugging = false;
|
||||||
|
|
||||||
|
#define BUF_X DEBUGGER_BUF_X
|
||||||
|
#define BUF_Y DEBUGGER_BUF_Y
|
||||||
|
#define SCREEN_X 81 // 80col + 1
|
||||||
|
#define SCREEN_Y 24
|
||||||
|
#define PROMPT_X 2
|
||||||
|
#define PROMPT_Y BUF_Y - 1
|
||||||
|
#define PROMPT_END_X BUF_X - 2
|
||||||
|
#define command_line command_buf[PROMPT_Y]
|
||||||
|
|
||||||
char second_buf[BUF_Y][BUF_X]; /* scratch buffer for output */
|
char second_buf[BUF_Y][BUF_X]; /* scratch buffer for output */
|
||||||
int num_buffer_lines; /* num lines of output */
|
int num_buffer_lines; /* num lines of output */
|
||||||
int arg1, arg2, arg3; /* command arguments */
|
int arg1, arg2, arg3; /* command arguments */
|
||||||
@ -56,7 +68,7 @@ static char screen[SCREEN_Y][SCREEN_X] =
|
|||||||
static char command_buf[BUF_Y][BUF_X]; /* command line prompt */
|
static char command_buf[BUF_Y][BUF_X]; /* command line prompt */
|
||||||
char lexbuf[BUF_X+2]; /* comman line to be flex'ed */
|
char lexbuf[BUF_X+2]; /* comman line to be flex'ed */
|
||||||
|
|
||||||
unsigned char current_opcode;
|
uint8_t current_opcode;
|
||||||
|
|
||||||
int op_breakpoints[256]; /* opcode breakpoints */
|
int op_breakpoints[256]; /* opcode breakpoints */
|
||||||
|
|
||||||
@ -123,13 +135,18 @@ int c_get_current_rambank(int addrs) {
|
|||||||
return !!(softswitches & SS_ALTZP);
|
return !!(softswitches & SS_ALTZP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
get_last_opcode () - returns the last executed opcode
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
uint8_t get_last_opcode() {
|
||||||
|
return cpu65_debug.opcode;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
get_current_opcode () - returns the opcode from the address that
|
get_current_opcode () - returns the opcode from the address that
|
||||||
the PC is currently reading from.
|
the PC is currently reading from.
|
||||||
returns 0 = bank 0
|
|
||||||
1 = bank 1
|
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
unsigned char get_current_opcode() {
|
uint8_t get_current_opcode() {
|
||||||
int bank = c_get_current_rambank(cpu65_current.pc);
|
int bank = c_get_current_rambank(cpu65_current.pc);
|
||||||
int lcbank = 0;
|
int lcbank = 0;
|
||||||
|
|
||||||
@ -175,7 +192,7 @@ unsigned char get_current_opcode() {
|
|||||||
|
|
||||||
void dump_mem(int addrs, int len, int lc, int do_ascii, int rambank) {
|
void dump_mem(int addrs, int len, int lc, int do_ascii, int rambank) {
|
||||||
int i, j, mod, end;
|
int i, j, mod, end;
|
||||||
unsigned char op;
|
uint8_t op;
|
||||||
int orig_addrs = addrs; /* address for display */
|
int orig_addrs = addrs; /* address for display */
|
||||||
|
|
||||||
/* check which rambank */
|
/* check which rambank */
|
||||||
@ -285,7 +302,7 @@ void dump_mem(int addrs, int len, int lc, int do_ascii, int rambank) {
|
|||||||
void search_mem(char *hexstr, int lc, int rambank) {
|
void search_mem(char *hexstr, int lc, int rambank) {
|
||||||
int i = 0, j = 0, end, op;
|
int i = 0, j = 0, end, op;
|
||||||
static char scratch[3];
|
static char scratch[3];
|
||||||
unsigned char byte;
|
uint8_t byte;
|
||||||
|
|
||||||
end = (lc) ? 0x3000 : 0x10000;
|
end = (lc) ? 0x3000 : 0x10000;
|
||||||
|
|
||||||
@ -299,7 +316,7 @@ void search_mem(char *hexstr, int lc, int rambank) {
|
|||||||
for (i = 0; i < end; i++)
|
for (i = 0; i < end; i++)
|
||||||
{
|
{
|
||||||
strncpy(scratch, hexstr+j, 2); /* extract a byte */
|
strncpy(scratch, hexstr+j, 2); /* extract a byte */
|
||||||
byte = (unsigned char) strtol(scratch, (char**)NULL, 16);
|
byte = (uint8_t) strtol(scratch, (char**)NULL, 16);
|
||||||
|
|
||||||
if (lc)
|
if (lc)
|
||||||
{
|
{
|
||||||
@ -342,7 +359,7 @@ void search_mem(char *hexstr, int lc, int rambank) {
|
|||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
void set_mem(int addrs, char *hexstr) {
|
void set_mem(int addrs, char *hexstr) {
|
||||||
static char scratch[3];
|
static char scratch[3];
|
||||||
unsigned char data;
|
uint8_t data;
|
||||||
|
|
||||||
if ((addrs < 0) || (addrs > 0xffff))
|
if ((addrs < 0) || (addrs > 0xffff))
|
||||||
{
|
{
|
||||||
@ -353,7 +370,7 @@ void set_mem(int addrs, char *hexstr) {
|
|||||||
while (*hexstr)
|
while (*hexstr)
|
||||||
{
|
{
|
||||||
strncpy(scratch, hexstr, 2);
|
strncpy(scratch, hexstr, 2);
|
||||||
data = (unsigned char) strtol(scratch, (char**)NULL, 16);
|
data = (uint8_t) strtol(scratch, (char**)NULL, 16);
|
||||||
|
|
||||||
/* call the set_memory routine, which knows how to route the
|
/* call the set_memory routine, which knows how to route the
|
||||||
request */
|
request */
|
||||||
@ -379,7 +396,7 @@ void set_mem(int addrs, char *hexstr) {
|
|||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
void set_lc_mem(int addrs, int lcbank, char *hexstr) {
|
void set_lc_mem(int addrs, int lcbank, char *hexstr) {
|
||||||
static char scratch[3];
|
static char scratch[3];
|
||||||
unsigned char data;
|
uint8_t data;
|
||||||
|
|
||||||
if ((addrs >= 0xd000) && (addrs <= 0xffff))
|
if ((addrs >= 0xd000) && (addrs <= 0xffff))
|
||||||
{
|
{
|
||||||
@ -395,7 +412,7 @@ void set_lc_mem(int addrs, int lcbank, char *hexstr) {
|
|||||||
while (*hexstr)
|
while (*hexstr)
|
||||||
{
|
{
|
||||||
strncpy(scratch, hexstr, 2);
|
strncpy(scratch, hexstr, 2);
|
||||||
data = (unsigned char) strtol(scratch, (char**)NULL, 16);
|
data = (uint8_t) strtol(scratch, (char**)NULL, 16);
|
||||||
|
|
||||||
/* ??? no way to write to aux LC banks */
|
/* ??? no way to write to aux LC banks */
|
||||||
|
|
||||||
@ -432,9 +449,9 @@ void set_lc_mem(int addrs, int lcbank, char *hexstr) {
|
|||||||
"safely" set memory...
|
"safely" set memory...
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
void bload(FILE *f, char *name, int addrs) {
|
void bload(FILE *f, char *name, int addrs) {
|
||||||
unsigned char *hexstr = NULL;
|
uint8_t *hexstr = NULL;
|
||||||
int len = -1;
|
int len = -1;
|
||||||
unsigned char data;
|
uint8_t data;
|
||||||
|
|
||||||
if ((addrs < 0) || (addrs > 0xffff))
|
if ((addrs < 0) || (addrs > 0xffff))
|
||||||
{
|
{
|
||||||
@ -444,7 +461,7 @@ void bload(FILE *f, char *name, int addrs) {
|
|||||||
|
|
||||||
while ((len = fread(temp, 1, TEMPSIZE, f)))
|
while ((len = fread(temp, 1, TEMPSIZE, f)))
|
||||||
{
|
{
|
||||||
hexstr = (unsigned char*)temp;
|
hexstr = (uint8_t*)temp;
|
||||||
for (; len > 0; len--)
|
for (; len > 0; len--)
|
||||||
{
|
{
|
||||||
data = *hexstr;
|
data = *hexstr;
|
||||||
@ -472,7 +489,7 @@ void bload(FILE *f, char *name, int addrs) {
|
|||||||
|
|
||||||
void disasm(int addrs, int len, int lc, int rambank) {
|
void disasm(int addrs, int len, int lc, int rambank) {
|
||||||
static char fmt[64];
|
static char fmt[64];
|
||||||
unsigned char op;
|
uint8_t op;
|
||||||
char arg1, arg2;
|
char arg1, arg2;
|
||||||
int i, j, k, end, orig_addrs = addrs;
|
int i, j, k, end, orig_addrs = addrs;
|
||||||
|
|
||||||
@ -557,9 +574,9 @@ void disasm(int addrs, int len, int lc, int rambank) {
|
|||||||
arg1 = apple_ii_64k[rambank][++j];
|
arg1 = apple_ii_64k[rambank][++j];
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(fmt, "/%02X/%04X: %02X%02X %s %s", rambank, k, op, (unsigned char)arg1, opcodes[op].mnemonic, disasm_templates[opcodes[op].mode]);
|
sprintf(fmt, "/%02X/%04X: %02X%02X %s %s", rambank, k, op, (uint8_t)arg1, opcodes[op].mnemonic, disasm_templates[opcodes[op].mode]);
|
||||||
|
|
||||||
sprintf(second_buf[i], fmt, (unsigned char)arg1);
|
sprintf(second_buf[i], fmt, (uint8_t)arg1);
|
||||||
k+=2;
|
k+=2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -585,8 +602,8 @@ void disasm(int addrs, int len, int lc, int rambank) {
|
|||||||
arg2 = apple_ii_64k[rambank][++j];
|
arg2 = apple_ii_64k[rambank][++j];
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(fmt, "/%02X/%04X: %02X%02X%02X %s %s", rambank, k, op, (unsigned char)arg1, (unsigned char)arg2, opcodes[op].mnemonic, disasm_templates[opcodes[op].mode]);
|
sprintf(fmt, "/%02X/%04X: %02X%02X%02X %s %s", rambank, k, op, (uint8_t)arg1, (uint8_t)arg2, opcodes[op].mnemonic, disasm_templates[opcodes[op].mode]);
|
||||||
sprintf(second_buf[i], fmt, (unsigned char)arg2, (unsigned char)arg1);
|
sprintf(second_buf[i], fmt, (uint8_t)arg2, (uint8_t)arg1);
|
||||||
k+=3;
|
k+=3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -606,14 +623,14 @@ void disasm(int addrs, int len, int lc, int rambank) {
|
|||||||
arg1 = apple_ii_64k[rambank][++j];
|
arg1 = apple_ii_64k[rambank][++j];
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(fmt, "/%02X/%04X: %02X%02X %s %s", rambank, k, op, (unsigned char)arg1, opcodes[op].mnemonic, disasm_templates[opcodes[op].mode]);
|
sprintf(fmt, "/%02X/%04X: %02X%02X %s %s", rambank, k, op, (uint8_t)arg1, opcodes[op].mnemonic, disasm_templates[opcodes[op].mode]);
|
||||||
if (arg1 < 0)
|
if (arg1 < 0)
|
||||||
{
|
{
|
||||||
sprintf(second_buf[i], fmt, k + arg1 + 2, '-', (unsigned char)(-arg1));
|
sprintf(second_buf[i], fmt, k + arg1 + 2, '-', (uint8_t)(-arg1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf(second_buf[i], fmt, k + arg1 + 2, '+', (unsigned char)arg1);
|
sprintf(second_buf[i], fmt, k + arg1 + 2, '+', (uint8_t)arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
k+=2;
|
k+=2;
|
||||||
@ -688,7 +705,7 @@ void show_regs() {
|
|||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
static int will_branch() {
|
static int will_branch() {
|
||||||
|
|
||||||
unsigned char op = get_current_opcode();
|
uint8_t op = get_current_opcode();
|
||||||
|
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
@ -760,14 +777,14 @@ void clear_halt(int *type, int pt) {
|
|||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
set_halt_opcode () = set a breakpoint on a particular opcode.
|
set_halt_opcode () = set a breakpoint on a particular opcode.
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
void set_halt_opcode(unsigned char opcode) {
|
void set_halt_opcode(uint8_t opcode) {
|
||||||
op_breakpoints[opcode] = 1;
|
op_breakpoints[opcode] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
clear_halt_opcode () = unset an opcode breakpoint.
|
clear_halt_opcode () = unset an opcode breakpoint.
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
void clear_halt_opcode(unsigned char opcode) {
|
void clear_halt_opcode(uint8_t opcode) {
|
||||||
op_breakpoints[opcode] = 0;
|
op_breakpoints[opcode] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,40 +793,40 @@ void clear_halt_opcode(unsigned char opcode) {
|
|||||||
assumes that you are in //e mode...
|
assumes that you are in //e mode...
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
void set_halt_65c02() {
|
void set_halt_65c02() {
|
||||||
set_halt_opcode((uchar)0x02); set_halt_opcode((uchar)0x04);
|
set_halt_opcode((uint8_t)0x02); set_halt_opcode((uint8_t)0x04);
|
||||||
set_halt_opcode((uchar)0x0C); set_halt_opcode((uchar)0x12);
|
set_halt_opcode((uint8_t)0x0C); set_halt_opcode((uint8_t)0x12);
|
||||||
set_halt_opcode((uchar)0x14); set_halt_opcode((uchar)0x1A);
|
set_halt_opcode((uint8_t)0x14); set_halt_opcode((uint8_t)0x1A);
|
||||||
set_halt_opcode((uchar)0x1C); set_halt_opcode((uchar)0x32);
|
set_halt_opcode((uint8_t)0x1C); set_halt_opcode((uint8_t)0x32);
|
||||||
set_halt_opcode((uchar)0x34); set_halt_opcode((uchar)0x3A);
|
set_halt_opcode((uint8_t)0x34); set_halt_opcode((uint8_t)0x3A);
|
||||||
set_halt_opcode((uchar)0x3C); set_halt_opcode((uchar)0x52);
|
set_halt_opcode((uint8_t)0x3C); set_halt_opcode((uint8_t)0x52);
|
||||||
set_halt_opcode((uchar)0x5A); set_halt_opcode((uchar)0x64);
|
set_halt_opcode((uint8_t)0x5A); set_halt_opcode((uint8_t)0x64);
|
||||||
set_halt_opcode((uchar)0x72); set_halt_opcode((uchar)0x74);
|
set_halt_opcode((uint8_t)0x72); set_halt_opcode((uint8_t)0x74);
|
||||||
set_halt_opcode((uchar)0x7A); set_halt_opcode((uchar)0x7C);
|
set_halt_opcode((uint8_t)0x7A); set_halt_opcode((uint8_t)0x7C);
|
||||||
set_halt_opcode((uchar)0x80); set_halt_opcode((uchar)0x89);
|
set_halt_opcode((uint8_t)0x80); set_halt_opcode((uint8_t)0x89);
|
||||||
set_halt_opcode((uchar)0x92); set_halt_opcode((uchar)0x9C);
|
set_halt_opcode((uint8_t)0x92); set_halt_opcode((uint8_t)0x9C);
|
||||||
set_halt_opcode((uchar)0x9E); set_halt_opcode((uchar)0xB2);
|
set_halt_opcode((uint8_t)0x9E); set_halt_opcode((uint8_t)0xB2);
|
||||||
set_halt_opcode((uchar)0xD2); set_halt_opcode((uchar)0xDA);
|
set_halt_opcode((uint8_t)0xD2); set_halt_opcode((uint8_t)0xDA);
|
||||||
set_halt_opcode((uchar)0xF2); set_halt_opcode((uchar)0xFA);
|
set_halt_opcode((uint8_t)0xF2); set_halt_opcode((uint8_t)0xFA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
clear_halt_65c02 () = clear all 65c02 instructions
|
clear_halt_65c02 () = clear all 65c02 instructions
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
void clear_halt_65c02() {
|
void clear_halt_65c02() {
|
||||||
clear_halt_opcode((uchar)0x02); clear_halt_opcode((uchar)0x04);
|
clear_halt_opcode((uint8_t)0x02); clear_halt_opcode((uint8_t)0x04);
|
||||||
clear_halt_opcode((uchar)0x0C); clear_halt_opcode((uchar)0x12);
|
clear_halt_opcode((uint8_t)0x0C); clear_halt_opcode((uint8_t)0x12);
|
||||||
clear_halt_opcode((uchar)0x14); clear_halt_opcode((uchar)0x1A);
|
clear_halt_opcode((uint8_t)0x14); clear_halt_opcode((uint8_t)0x1A);
|
||||||
clear_halt_opcode((uchar)0x1C); clear_halt_opcode((uchar)0x32);
|
clear_halt_opcode((uint8_t)0x1C); clear_halt_opcode((uint8_t)0x32);
|
||||||
clear_halt_opcode((uchar)0x34); clear_halt_opcode((uchar)0x3A);
|
clear_halt_opcode((uint8_t)0x34); clear_halt_opcode((uint8_t)0x3A);
|
||||||
clear_halt_opcode((uchar)0x3C); clear_halt_opcode((uchar)0x52);
|
clear_halt_opcode((uint8_t)0x3C); clear_halt_opcode((uint8_t)0x52);
|
||||||
clear_halt_opcode((uchar)0x5A); clear_halt_opcode((uchar)0x64);
|
clear_halt_opcode((uint8_t)0x5A); clear_halt_opcode((uint8_t)0x64);
|
||||||
clear_halt_opcode((uchar)0x72); clear_halt_opcode((uchar)0x74);
|
clear_halt_opcode((uint8_t)0x72); clear_halt_opcode((uint8_t)0x74);
|
||||||
clear_halt_opcode((uchar)0x7A); clear_halt_opcode((uchar)0x7C);
|
clear_halt_opcode((uint8_t)0x7A); clear_halt_opcode((uint8_t)0x7C);
|
||||||
clear_halt_opcode((uchar)0x80); clear_halt_opcode((uchar)0x89);
|
clear_halt_opcode((uint8_t)0x80); clear_halt_opcode((uint8_t)0x89);
|
||||||
clear_halt_opcode((uchar)0x92); clear_halt_opcode((uchar)0x9C);
|
clear_halt_opcode((uint8_t)0x92); clear_halt_opcode((uint8_t)0x9C);
|
||||||
clear_halt_opcode((uchar)0x9E); clear_halt_opcode((uchar)0xB2);
|
clear_halt_opcode((uint8_t)0x9E); clear_halt_opcode((uint8_t)0xB2);
|
||||||
clear_halt_opcode((uchar)0xD2); clear_halt_opcode((uchar)0xDA);
|
clear_halt_opcode((uint8_t)0xD2); clear_halt_opcode((uint8_t)0xDA);
|
||||||
clear_halt_opcode((uchar)0xF2); clear_halt_opcode((uchar)0xFA);
|
clear_halt_opcode((uint8_t)0xF2); clear_halt_opcode((uint8_t)0xFA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
@ -822,7 +839,7 @@ int at_haltpt() {
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* check op_breakpoints */
|
/* check op_breakpoints */
|
||||||
unsigned char op = get_current_opcode();
|
uint8_t op = get_last_opcode();
|
||||||
if (op_breakpoints[op])
|
if (op_breakpoints[op])
|
||||||
{
|
{
|
||||||
sprintf(second_buf[num_buffer_lines++], "stopped at %04X bank %d instruction %02X", cpu65_current.pc, c_get_current_rambank(cpu65_current.pc), op);
|
sprintf(second_buf[num_buffer_lines++], "stopped at %04X bank %d instruction %02X", cpu65_current.pc, c_get_current_rambank(cpu65_current.pc), op);
|
||||||
@ -1043,9 +1060,7 @@ void clear_debugger_screen() {
|
|||||||
end_cpu_step () - finish a stepping command
|
end_cpu_step () - finish a stepping command
|
||||||
display the next instruction, and tell whether it will branch
|
display the next instruction, and tell whether it will branch
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
void end_cpu_step() {
|
static void end_cpu_step() {
|
||||||
|
|
||||||
cpu65_set_stepping(0);
|
|
||||||
|
|
||||||
clear_debugger_screen();
|
clear_debugger_screen();
|
||||||
disasm(cpu65_current.pc, 1, 0, -1);
|
disasm(cpu65_current.pc, 1, 0, -1);
|
||||||
@ -1057,80 +1072,113 @@ void end_cpu_step() {
|
|||||||
|
|
||||||
sprintf(second_buf[num_buffer_lines++], "%s", (branch) ? "will branch" : "will not branch");
|
sprintf(second_buf[num_buffer_lines++], "%s", (branch) ? "will branch" : "will not branch");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
begin_cpu_step() - step the CPU
|
begin_cpu_step() - step the CPU
|
||||||
set the CPU into stepping mode and yield to CPU thread
|
set the CPU into stepping mode and yield to CPU thread
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
void begin_cpu_step()
|
static void begin_cpu_step()
|
||||||
{
|
|
||||||
cpu65_set_stepping(1);
|
|
||||||
c_stepping_yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
|
||||||
c_stepping_yield()
|
|
||||||
called to yield execution between cpu and main threads when stepping
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
void c_stepping_yield()
|
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
if ((err = pthread_mutex_unlock(&interface_mutex)))
|
|
||||||
{
|
do {
|
||||||
ERRLOG("pthread_mutex_unlock : %d", err);
|
if ((err = pthread_cond_signal(&interface_cond))) {
|
||||||
|
ERRLOG("pthread_cond_signal : %d", err);
|
||||||
|
}
|
||||||
|
if ((err = pthread_cond_wait(&interface_cond, &interface_mutex))) {
|
||||||
|
ERRLOG("pthread_cond_wait : %d", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// presumably other thread executes while we yield and sleep ...
|
if (c_mygetch(0) != -1) {
|
||||||
if ((err = pthread_yield()))
|
break;
|
||||||
{
|
|
||||||
ERRLOG("pthread_yield ; %d", err);
|
|
||||||
}
|
}
|
||||||
static struct timespec deltat = { .tv_sec=0, .tv_nsec=1 };
|
} while (!stepping_struct.should_break);
|
||||||
nanosleep(&deltat, NULL);
|
|
||||||
|
|
||||||
if ((err = pthread_mutex_lock(&interface_mutex)))
|
if ((err = pthread_cond_signal(&interface_cond))) {
|
||||||
{
|
ERRLOG("pthread_cond_signal : %d", err);
|
||||||
ERRLOG("pthread_mutex_lock : %d", err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end_cpu_step();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
do_step_or_next () - step into or step over commands
|
c_debugger_should_break()
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
void do_step_or_next(int step_count) {
|
bool c_debugger_should_break() {
|
||||||
char ch;
|
|
||||||
unsigned char op;
|
|
||||||
int step_frame = 0;
|
|
||||||
|
|
||||||
/* do step while step_count AND no breaks AND no keypress */
|
// WARNING : this state management function should be called from CPU thread only!
|
||||||
do
|
|
||||||
{
|
|
||||||
op = get_current_opcode();
|
|
||||||
|
|
||||||
if (step_next && (op == 0x20))
|
if (at_haltpt()) {
|
||||||
|
stepping_struct.should_break = true;
|
||||||
|
} else {
|
||||||
|
uint8_t op = get_last_opcode();
|
||||||
|
|
||||||
|
switch (stepping_struct.step_type) {
|
||||||
|
case STEPPING:
|
||||||
{
|
{
|
||||||
do
|
--stepping_struct.step_count;
|
||||||
|
if (stepping_struct.step_count == 0) {
|
||||||
|
stepping_struct.should_break = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NEXTING:
|
||||||
{
|
{
|
||||||
op = get_current_opcode();
|
if (stepping_struct.step_count > 0) {
|
||||||
if (op == 0x20)
|
--stepping_struct.step_count;
|
||||||
{
|
|
||||||
++step_frame; /* JSR */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == 0x60)
|
if (op == 0x20) {
|
||||||
{
|
++stepping_struct.step_frame; // JSR
|
||||||
--step_frame; /* RTS */
|
}
|
||||||
|
if (op == 0x60) {
|
||||||
|
--stepping_struct.step_frame; // RTS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((stepping_struct.step_frame == 0) && (stepping_struct.step_count == 0)) {
|
||||||
|
stepping_struct.should_break = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UNTILING:
|
||||||
|
{
|
||||||
|
if (stepping_struct.step_pc == cpu65_current.pc) {
|
||||||
|
stepping_struct.should_break = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FINISHING:
|
||||||
|
{
|
||||||
|
if (op == 0x20) {
|
||||||
|
++stepping_struct.step_frame; // JSR
|
||||||
|
}
|
||||||
|
if (op == 0x60) {
|
||||||
|
--stepping_struct.step_frame; // RTS
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stepping_struct.step_frame == 0) {
|
||||||
|
stepping_struct.should_break = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GOING:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stepping_struct.should_break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
c_debugger_begin_stepping () - step into or step over commands
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
void c_debugger_begin_stepping(stepping_struct_t s) {
|
||||||
|
stepping_struct = s;
|
||||||
begin_cpu_step();
|
begin_cpu_step();
|
||||||
} while (((ch = c_mygetch(0)) == -1) && !at_haltpt() && step_frame);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
begin_cpu_step();
|
|
||||||
}
|
|
||||||
} while (--step_count && !at_haltpt() && (c_mygetch(0) == -1));
|
|
||||||
|
|
||||||
end_cpu_step();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
@ -1173,7 +1221,6 @@ void do_debug_command() {
|
|||||||
int i = 0, j = 0, k = 0;
|
int i = 0, j = 0, k = 0;
|
||||||
|
|
||||||
/* reset key local vars */
|
/* reset key local vars */
|
||||||
step_next = 0;
|
|
||||||
num_buffer_lines = 0;
|
num_buffer_lines = 0;
|
||||||
|
|
||||||
/* call lex to perform the command.*/
|
/* call lex to perform the command.*/
|
||||||
@ -1233,14 +1280,15 @@ void do_debug_command() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
c_do_debugging()
|
c_interface_debugging()
|
||||||
main debugging console
|
main debugging console
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void c_do_debugging() {
|
void c_interface_debugging() {
|
||||||
|
|
||||||
static char lex_initted = 0;
|
static char lex_initted = 0;
|
||||||
|
|
||||||
|
int err = 0;
|
||||||
int i;
|
int i;
|
||||||
int ch;
|
int ch;
|
||||||
int command_pos = PROMPT_X;
|
int command_pos = PROMPT_X;
|
||||||
@ -1275,6 +1323,8 @@ void c_do_debugging() {
|
|||||||
c_interface_print(0, i, 2, screen[ i ] );
|
c_interface_print(0, i, 2, screen[ i ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_debugging = true;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/* print command line */
|
/* print command line */
|
||||||
@ -1289,8 +1339,7 @@ void c_do_debugging() {
|
|||||||
|
|
||||||
if (ch == kESC)
|
if (ch == kESC)
|
||||||
{
|
{
|
||||||
c_interface_exit(-1);
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1313,5 +1362,13 @@ void c_do_debugging() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c_interface_exit(-1);
|
||||||
|
is_debugging = false;
|
||||||
|
if ((err = pthread_cond_signal(&interface_cond)))
|
||||||
|
{
|
||||||
|
ERRLOG("pthread_cond_signal : %d", err);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
src/timing.c
32
src/timing.c
@ -160,6 +160,9 @@ void cpu_thread(void *dummyptr) {
|
|||||||
bool negative = false;
|
bool negative = false;
|
||||||
long drift_adj_nsecs = 0; // generic drift adjustment between target and actual
|
long drift_adj_nsecs = 0; // generic drift adjustment between target and actual
|
||||||
|
|
||||||
|
int debugging_cycles0 = 0;
|
||||||
|
int debugging_cycles = 0;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
unsigned long dbg_ticks = 0;
|
unsigned long dbg_ticks = 0;
|
||||||
int speaker_neg_feedback = 0;
|
int speaker_neg_feedback = 0;
|
||||||
@ -201,15 +204,42 @@ void cpu_thread(void *dummyptr) {
|
|||||||
cpu65_cycles_to_execute = 0;
|
cpu65_cycles_to_execute = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu65_cycle_count = 0;
|
|
||||||
g_nCyclesExecuted = 0;
|
g_nCyclesExecuted = 0;
|
||||||
|
|
||||||
#ifdef AUDIO_ENABLED
|
#ifdef AUDIO_ENABLED
|
||||||
MB_StartOfCpuExecute();
|
MB_StartOfCpuExecute();
|
||||||
#endif
|
#endif
|
||||||
|
if (is_debugging) {
|
||||||
|
debugging_cycles0 = cpu65_cycles_to_execute;
|
||||||
|
debugging_cycles = cpu65_cycles_to_execute;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (is_debugging) {
|
||||||
|
cpu65_cycles_to_execute = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu65_cycle_count = 0;
|
||||||
cpu65_run(); // run emulation for cpu65_cycles_to_execute cycles ...
|
cpu65_run(); // run emulation for cpu65_cycles_to_execute cycles ...
|
||||||
|
|
||||||
|
if (is_debugging) {
|
||||||
|
debugging_cycles -= cpu65_cycle_count;
|
||||||
|
if (c_debugger_should_break() || (debugging_cycles <= 0)) {
|
||||||
|
int err = 0;
|
||||||
|
if ((err = pthread_cond_signal(&interface_cond))) {
|
||||||
|
ERRLOG("pthread_cond_signal : %d", err);
|
||||||
|
}
|
||||||
|
if ((err = pthread_cond_wait(&interface_cond, &interface_mutex))) {
|
||||||
|
ERRLOG("pthread_cond_wait : %d", err);
|
||||||
|
}
|
||||||
|
if (debugging_cycles <= 0) {
|
||||||
|
cpu65_cycle_count = debugging_cycles0 - debugging_cycles/*<=0*/;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (is_debugging);
|
||||||
|
|
||||||
cycles_adjust = cpu65_cycles_to_execute; // counter is decremented in cpu65_run()
|
cycles_adjust = cpu65_cycles_to_execute; // counter is decremented in cpu65_run()
|
||||||
if (cycles_adjust < 0)
|
if (cycles_adjust < 0)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user