Skip to content

Commit

Permalink
Added BREAKPOINT_COUNT_FRAMES
Browse files Browse the repository at this point in the history
* fixed low level interfaces to return breakpoint id number
  • Loading branch information
robmcmullen committed Aug 18, 2018
1 parent f1e130f commit 02f243e
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 20 deletions.
2 changes: 1 addition & 1 deletion lib6502/6502-emu_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ int lib6502_next_frame(input_t *input, output_t *output, breakpoints_t *breakpoi

memory[0xc000] = input->keychar;
status->final_cycle_in_frame = cycles_per_frame - 1;
libdebugger_calc_frame(&lib6502_calc_frame, memory, (frame_status_t *)output, breakpoints);
bpid = libdebugger_calc_frame(&lib6502_calc_frame, memory, (frame_status_t *)output, breakpoints);
lib6502_get_current_state(output);
return bpid;
}
3 changes: 2 additions & 1 deletion lib6502/lib6502.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ def next_frame(np.ndarray input not None, np.ndarray output not None, np.ndarray
ibuf = input.view(np.uint8)
obuf = output.view(np.uint8)
dbuf = breakpoints.view(np.uint8)
lib6502_next_frame(&ibuf[0], &obuf[0], &dbuf[0])
bpid = lib6502_next_frame(&ibuf[0], &obuf[0], &dbuf[0])
return bpid

def get_current_state(np.ndarray output not None):
cdef np.uint8_t[:] obuf
Expand Down
2 changes: 1 addition & 1 deletion libatari800/atari800_bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ int a8bridge_next_frame(input_template_t *input, output_template_t *output, brea
LIBATARI800_Input_array = input;
INPUT_key_code = PLATFORM_Keyboard();

libdebugger_calc_frame(&a8bridge_calc_frame, MEMORY_mem, &output->status, breakpoints);
bpid = libdebugger_calc_frame(&a8bridge_calc_frame, MEMORY_mem, &output->status, breakpoints);

LIBATARI800_StateSave(output->state, &output->tags);
if (output->status.frame_status == FRAME_FINISHED) {
Expand Down
5 changes: 3 additions & 2 deletions libatari800/libatari800.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ cdef extern:
void a8bridge_configure_state_arrays(void *input, void *output)
void a8bridge_get_current_state(void *output)
void a8bridge_restore_state(void *restore)
void a8bridge_next_frame(void *input, void *output, void *breakpoints)
int a8bridge_next_frame(void *input, void *output, void *breakpoints)

int libatari800_mount_disk_image(int diskno, const char *filename, int readonly)
int libatari800_reboot_with_file(const char *filename)
Expand Down Expand Up @@ -62,7 +62,8 @@ def next_frame(np.ndarray input not None, np.ndarray output not None, np.ndarray
ibuf = input.view(np.uint8)
obuf = output.view(np.uint8)
dbuf = breakpoints.view(np.uint8)
a8bridge_next_frame(&ibuf[0], &obuf[0], &dbuf[0])
bpid = a8bridge_next_frame(&ibuf[0], &obuf[0], &dbuf[0])
return bpid

def get_current_state(np.ndarray output not None):
cdef np.uint8_t[:] obuf
Expand Down
27 changes: 27 additions & 0 deletions libdebugger/libdebugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ int libdebugger_check_breakpoints(breakpoints_t *breakpoints, int cycles, cpu_st
else breakpoints->tokens[index] -= 1;
continue;
}
else if (status == BREAKPOINT_COUNT_FRAMES) {
/* only checked at the end of the frame */
continue;
}
/* otherwise, process normally */
}
clear(&stack);
Expand Down Expand Up @@ -248,8 +252,31 @@ int libdebugger_calc_frame(emu_frame_callback_ptr calc, uint8_t *memory, frame_s
output->frame_status = FRAME_INCOMPLETE;
bpid = calc(output, breakpoints);
if (bpid < 0) {
int status, index, count;

output->frame_status = FRAME_FINISHED;
// libdebugger_memory_access_finish_frame(output);

/* special check for frame count breakpoint */
status = breakpoints->breakpoint_status[0];
if (status & BREAKPOINT_ENABLED) {
printf("checking for count frames breakpoint\n");
index = 0;
count = (int)breakpoints->tokens[index]; /* tokens are unsigned */
if ((status == BREAKPOINT_COUNT_FRAMES) && (count == 0)) {
printf("Count frames breakpoint\n");
bpid = 0;
}
else {
printf("Count frames breakpoint: count=%d\n", count);
breakpoints->tokens[index]--;
}
}
}
if (bpid == 0) {
/* breakpoint 0 is always used to store one-time breakpoints, so they
must be marked as disabled to not fire next time. */
breakpoints->breakpoint_status[0] = BREAKPOINT_DISABLED;
}
return bpid;
}
1 change: 1 addition & 0 deletions libdebugger/libdebugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ typedef struct {
#define BREAKPOINT_COUNT_INSTRUCTIONS 0x21
#define BREAKPOINT_COUNT_CYCLES 0x22
#define BREAKPOINT_AT_RETURN 0x23
#define BREAKPOINT_COUNT_FRAMES 0x24

#define BREAKPOINT_DISABLED 0x40

Expand Down
15 changes: 13 additions & 2 deletions omni8bit/debugger/debugger.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ def count_cycles(self, count):
c['tokens'][self.index] = count
self.enable()

def count_frames(self, count):
# shortcut to create a break after `count` instructions
c = self.debugger.debug_cmd[0]
c['breakpoint_status'][self.id] = dd.BREAKPOINT_COUNT_FRAMES
c['tokens'][self.index] = count
self.enable()

def break_at_return(self):
# shortcut to create a PC=addr breakpoint
c = self.debugger.debug_cmd[0]
Expand Down Expand Up @@ -202,17 +209,21 @@ def create_breakpoint(self, addr=None):
return Breakpoint(self, bpid, addr)

def get_breakpoint(self, bpid):
if bpid < 0:
return None
return Breakpoint(self, bpid)

def step_into(self, number=1):
b = Breakpoint(self, 0)
b.step_into(number)
b.enable()

def count_frames(self, number=1):
b = Breakpoint(self, 0)
b.count_frames(number)

def count_cycles(self, cycles=1):
b = Breakpoint(self, 0)
b.count_cycles(number)
b.enable()

def iter_breakpoints(self):
for i in range(dd.NUM_BREAKPOINT_ENTRIES):
Expand Down
1 change: 1 addition & 0 deletions omni8bit/debugger/dtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
BREAKPOINT_COUNT_INSTRUCTIONS = 0x21
BREAKPOINT_COUNT_CYCLES = 0x22
BREAKPOINT_AT_RETURN = 0x23
BREAKPOINT_COUNT_FRAMES = 0x24

BREAKPOINT_DISABLED = 0x40

Expand Down
15 changes: 2 additions & 13 deletions omni8bit/emulator_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,6 @@ def cycles_user(self):
def cycles_since_power_on(self):
return self.status['cycles_since_power_on'][0]

@property
def break_condition(self):
if self.status['frame_status'][0] == FRAME_BREAKPOINT:
bpid = self.status['breakpoint_id'][0]
return self.get_breakpoint(bpid)
elif self.status['frame_status'][0] == FRAME_WATCHPOINT:
bpid = self.status['breakpoint_id'][0]
return self.get_watchpoint(bpid)
else:
return None

@property
def stack_pointer(self):
raise NotImplementedError("define stack_pointer property in subclass")
Expand Down Expand Up @@ -257,13 +246,13 @@ def next_frame(self):
self.process_key_state()
if not self.is_frame_finished:
print(f"next_frame: continuing frame from cycle {self.current_cycle_in_frame} of frame {self.current_frame_number}")
self.low_level_interface.next_frame(self.input, self.output_raw, self.debug_cmd)
bpid = self.low_level_interface.next_frame(self.input, self.output_raw, self.debug_cmd)
if self.is_frame_finished:
self.frame_count += 1
self.process_frame_events()
self.save_history()
self.forced_modifier = None
return self.break_condition
return self.get_breakpoint(bpid)

def process_frame_events(self):
still_waiting = []
Expand Down

0 comments on commit 02f243e

Please sign in to comment.