Skip to content

Commit cc9035e

Browse files
committed
Use new breakpoint management module in CLI.
1 parent c8726cd commit cc9035e

File tree

2 files changed

+86
-42
lines changed

2 files changed

+86
-42
lines changed

src/ceda_packet.rs

Whitespace-only changes.

src/cli.c

Lines changed: 86 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "floppy.h"
99
#include "int.h"
1010
#include "macro.h"
11+
#include "monitor.h"
1112
#include "serial.h"
1213
#include "time.h"
1314
#include "tokenizer.h"
@@ -80,7 +81,7 @@ static ceda_string_t *cli_pause(const char *arg) {
8081

8182
static ceda_string_t *cli_continue(const char *arg) {
8283
(void)arg;
83-
cpu_step(); // possibly step past the breakpoint
84+
monitor_pass();
8485
cpu_pause(false);
8586
return NULL;
8687
}
@@ -124,49 +125,107 @@ static ceda_string_t *cli_step(const char *arg) {
124125
}
125126

126127
static ceda_string_t *cli_break(const char *arg) {
127-
char word[LINE_BUFFER_SIZE];
128128

129-
// skip argv[0]
129+
char word[LINE_BUFFER_SIZE];
130130
arg = tokenizer_next_word(word, arg, LINE_BUFFER_SIZE);
131131

132-
// extract address
132+
char what[LINE_BUFFER_SIZE];
133+
arg = tokenizer_next_word(what, arg, LINE_BUFFER_SIZE);
134+
bool is_what = arg != NULL;
135+
133136
unsigned int _address;
137+
zuint16 address = 0;
134138
arg = tokenizer_next_hex(&_address, arg);
139+
bool is_address = arg != NULL;
140+
if (is_address) {
141+
if (_address >= 0x10000) {
142+
ceda_string_t *msg = ceda_string_new(0);
143+
ceda_string_cpy(msg, USER_BAD_ARG_STR "address must be 16 bit\n");
144+
return msg;
145+
}
146+
address = (zuint16)_address;
147+
}
135148

136-
// no address => show current breakpoints
137-
if (arg == NULL) {
138-
CpuBreakpoint *breakpoints;
139-
const size_t countof_breakpoints = cpu_getBreakpoints(&breakpoints);
149+
unsigned int _value;
150+
zuint8 value = 0;
151+
arg = tokenizer_next_hex(&_value, arg);
152+
bool is_value = arg != NULL;
153+
if (is_value) {
154+
if (_value >= 0x100) {
155+
ceda_string_t *msg = ceda_string_new(0);
156+
ceda_string_cpy(msg, USER_BAD_ARG_STR "value must be 8 bit\n");
157+
return msg;
158+
}
159+
value = (zuint8)_value;
160+
}
161+
162+
// no "what" => show current monitors
163+
if (!is_what) {
164+
const Monitor *monitors;
165+
const size_t countof_breakpoints = monitor_get(&monitors);
140166
int count = 0;
141167
ceda_string_t *msg = ceda_string_new(0);
142168
for (size_t i = 0; i < countof_breakpoints; ++i) {
143-
if (!breakpoints[i].valid)
169+
if (!monitors[i].valid)
144170
continue;
171+
static const struct associator_t {
172+
monitor_kind_t kind;
173+
char letter;
174+
} associators[] = {
175+
{MONITOR_EXEC, 'X'}, //
176+
{MONITOR_READ_MEM, 'R'}, //
177+
{MONITOR_WRITE_MEM, 'W'}, //
178+
{MONITOR_READ_IO, 'i'}, //
179+
{MONITOR_WRITE_IO, 'o'}, //
180+
};
181+
char kind = '-';
182+
for (size_t j = 0; j < ARRAY_SIZE(associators); ++j) {
183+
if (associators[j].kind == monitors[i].kind) {
184+
kind = associators[j].letter;
185+
break;
186+
}
187+
}
145188
++count;
146-
ceda_string_printf(msg, "%lu\t%04x\n", i, breakpoints[i].address);
189+
ceda_string_printf(msg, "%lu\t%c\t%04x\n", i, kind,
190+
monitors[i].address);
147191
}
148192
if (count == 0) {
149193
ceda_string_cpy(msg, "no breakpoint set\n");
150194
}
151195
return msg;
152196
}
197+
// add a new monitor
153198

154-
if (_address >= 0x10000) {
199+
if (!is_address) {
155200
ceda_string_t *msg = ceda_string_new(0);
156-
ceda_string_cpy(msg, USER_BAD_ARG_STR "address must be 16 bit\n");
201+
ceda_string_cpy(msg, USER_BAD_ARG_STR "missing address\n");
157202
return msg;
158203
}
159-
const zuint16 address = (zuint16)_address;
160204

161-
// actually set breakpoint
162-
bool ret = cpu_addBreakpoint(address);
205+
bool ret = false;
206+
if (strcmp(what, "break") == 0) {
207+
ret = monitor_addBreakpoint(address);
208+
} else if (strcmp(what, "read") == 0) {
209+
ret = monitor_addReadWatchpoint(address);
210+
} else if (strcmp(what, "write") == 0) {
211+
ret = monitor_addWriteWatchpoint(address, is_value ? &value : NULL);
212+
} else if (strcmp(what, "in") == 0) {
213+
ret = monitor_addInWatchpoint(address);
214+
} else if (strcmp(what, "out") == 0) {
215+
ret = monitor_addOutWatchpoint(address, is_value ? &value : NULL);
216+
} else {
217+
ceda_string_t *msg = ceda_string_new(0);
218+
ceda_string_cpy(msg, USER_BAD_ARG_STR "unknown monitor kind\n");
219+
return msg;
220+
}
163221

164222
if (!ret) {
165223
ceda_string_t *msg = ceda_string_new(0);
166224
ceda_string_cpy(msg, USER_NO_SPACE_LEFT_STR);
167225
return msg;
168226
}
169227

228+
// all ok, no output
170229
return NULL;
171230
}
172231

@@ -178,16 +237,6 @@ static ceda_string_t *cli_delete(const char *arg) {
178237
// skip argv[0]
179238
arg = tokenizer_next_word(word, arg, LINE_BUFFER_SIZE);
180239

181-
char what[LINE_BUFFER_SIZE];
182-
// extract what to delete (breakpoint, watchpoint, ...)
183-
arg = tokenizer_next_word(what, arg, LINE_BUFFER_SIZE);
184-
185-
// missing what
186-
if (arg == NULL) {
187-
ceda_string_cpy(msg, USER_BAD_ARG_STR "missing delete target\n");
188-
return msg;
189-
}
190-
191240
// extract index
192241
arg = tokenizer_next_word(word, arg, LINE_BUFFER_SIZE);
193242

@@ -206,15 +255,8 @@ static ceda_string_t *cli_delete(const char *arg) {
206255
}
207256

208257
// actually delete something
209-
if (strcmp(what, "breakpoint") == 0) {
210-
if (!cpu_deleteBreakpoint(index)) {
211-
ceda_string_cpy(msg, "can't delete breakpoint\n");
212-
return msg;
213-
}
214-
} else if (strcmp(what, "watchpoint") == 0) {
215-
// TODO(giomba): implement this for watchpoints
216-
} else {
217-
ceda_string_cpy(msg, USER_BAD_ARG_STR "unknown delete target\n");
258+
if (!monitor_delete(index)) {
259+
ceda_string_cpy(msg, "can't delete monitor\n");
218260
return msg;
219261
}
220262

@@ -361,9 +403,9 @@ static ceda_string_t *cli_dis(const char *arg) {
361403
* Expected command line syntax:
362404
* save <filename> <start> <end>
363405
* where
364-
* filename: name of the file where to save the dump (no spaces allowed)
365-
* start: starting memory address, in hex
366-
* end: ending memory address, in hex
406+
* filename: name of the file where to save the dump (no spaces
407+
* allowed) start: starting memory address, in hex end: ending memory
408+
* address, in hex
367409
*
368410
* Data is saved [start;end)
369411
*
@@ -376,7 +418,8 @@ static ceda_string_t *cli_dis(const char *arg) {
376418
*
377419
* @param arg Pointer to the command line string.
378420
*
379-
* @return char* NULL in case of success, pointer to error message otherwise.
421+
* @return char* NULL in case of success, pointer to error message
422+
* otherwise.
380423
*/
381424
static ceda_string_t *cli_save(const char *arg) {
382425
char word[LINE_BUFFER_SIZE];
@@ -611,9 +654,10 @@ static ceda_string_t *cli_umount(const char *arg) {
611654
* filename: name of the file from which to load the dump (no spaces
612655
* allowed) start: starting memory address, in hex
613656
*
614-
* When loading, this routine will use the starting address saves inside the
615-
* file, unless a starting address is explicitly specified on the command
616-
* line, in which case, the starting address of the file will be overridden.
657+
* When loading, this routine will use the starting address saves inside
658+
* the file, unless a starting address is explicitly specified on the
659+
* command line, in which case, the starting address of the file will be
660+
* overridden.
617661
*
618662
* Example: load video memory dump, but one row below
619663
* load video.crt d050
@@ -808,7 +852,7 @@ static ceda_string_t *cli_help(const char *arg);
808852
static const cli_command cli_commands[] = {
809853
{"dis", "disassembly binary data", cli_dis},
810854
{"break", "set or show cpu breakpoints", cli_break},
811-
{"delete", "delete cpu breakpoint", cli_delete},
855+
{"delete", "delete cpu monitor/breakpoint", cli_delete},
812856
{"pause", "pause cpu execution", cli_pause},
813857
{"continue", "continue cpu execution", cli_continue},
814858
{"reg", "show cpu registers", cli_reg},

0 commit comments

Comments
 (0)