Skip to content

Commit 7a14266

Browse files
committed
Use new breakpoint management module in CLI.
1 parent ec4beca commit 7a14266

1 file changed

Lines changed: 70 additions & 42 deletions

File tree

src/cli.c

Lines changed: 70 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "floppy.h"
1010
#include "int.h"
1111
#include "macro.h"
12+
#include "monitor.h"
1213
#include "serial.h"
1314
#include "time.h"
1415
#include "tokenizer.h"
@@ -90,7 +91,6 @@ static ceda_string_t *cli_pause(const char *arg) {
9091

9192
static ceda_string_t *cli_continue(const char *arg) {
9293
(void)arg;
93-
cpu_step(); // possibly step past the breakpoint
9494
cpu_pause(false);
9595
return NULL;
9696
}
@@ -134,49 +134,92 @@ static ceda_string_t *cli_step(const char *arg) {
134134
}
135135

136136
static ceda_string_t *cli_break(const char *arg) {
137-
char word[LINE_BUFFER_SIZE];
138137

139-
// skip argv[0]
138+
char word[LINE_BUFFER_SIZE];
140139
arg = tokenizer_next_word(word, arg, LINE_BUFFER_SIZE);
141140

142-
// extract address
141+
char what[LINE_BUFFER_SIZE];
142+
arg = tokenizer_next_word(what, arg, LINE_BUFFER_SIZE);
143+
bool is_what = arg != NULL;
144+
143145
unsigned int _address;
146+
zuint16 address = 0;
144147
arg = tokenizer_next_hex(&_address, arg);
148+
bool is_address = arg != NULL;
149+
if (is_address) {
150+
if (_address >= 0x10000) {
151+
ceda_string_t *msg = ceda_string_new(0);
152+
ceda_string_cpy(msg, USER_BAD_ARG_STR "address must be 16 bit\n");
153+
return msg;
154+
}
155+
address = (zuint16)_address;
156+
}
145157

146-
// no address => show current breakpoints
147-
if (arg == NULL) {
148-
CpuBreakpoint *breakpoints;
149-
const size_t countof_breakpoints = cpu_getBreakpoints(&breakpoints);
158+
unsigned int _value;
159+
zuint8 value = 0;
160+
arg = tokenizer_next_hex(&_value, arg);
161+
bool is_value = arg != NULL;
162+
if (is_value) {
163+
if (_value >= 0x100) {
164+
ceda_string_t *msg = ceda_string_new(0);
165+
ceda_string_cpy(msg, USER_BAD_ARG_STR "value must be 8 bit\n");
166+
return msg;
167+
}
168+
value = (zuint8)_value;
169+
}
170+
171+
// no "what" => show current monitors
172+
if (!is_what) {
173+
const Monitor *monitors;
174+
const size_t countof_breakpoints = monitor_get(&monitors);
150175
int count = 0;
151176
ceda_string_t *msg = ceda_string_new(0);
152177
for (size_t i = 0; i < countof_breakpoints; ++i) {
153-
if (!breakpoints[i].valid)
178+
if (!monitors[i].valid)
154179
continue;
180+
const char *description =
181+
monitor_getKindDescription(monitors[i].kind);
155182
++count;
156-
ceda_string_printf(msg, "%lu\t%04x\n", i, breakpoints[i].address);
183+
ceda_string_printf(msg, "%lu\t%s\t%04x\n", i, description,
184+
monitors[i].address);
157185
}
158186
if (count == 0) {
159187
ceda_string_cpy(msg, "no breakpoint set\n");
160188
}
161189
return msg;
162190
}
191+
// add a new monitor
163192

164-
if (_address >= 0x10000) {
193+
if (!is_address) {
165194
ceda_string_t *msg = ceda_string_new(0);
166-
ceda_string_cpy(msg, USER_BAD_ARG_STR "address must be 16 bit\n");
195+
ceda_string_cpy(msg, USER_BAD_ARG_STR "missing address\n");
167196
return msg;
168197
}
169-
const uint16_t address = (uint16_t)_address;
170198

171-
// actually set breakpoint
172-
bool ret = cpu_addBreakpoint(address);
199+
bool ret = false;
200+
if (strcmp(what, "exec") == 0) {
201+
ret = monitor_addBreakpoint(address);
202+
} else if (strcmp(what, "read") == 0) {
203+
ret = monitor_addReadWatchpoint(address);
204+
} else if (strcmp(what, "write") == 0) {
205+
ret = monitor_addWriteWatchpoint(address, is_value ? &value : NULL);
206+
} else if (strcmp(what, "in") == 0) {
207+
ret = monitor_addInWatchpoint(address);
208+
} else if (strcmp(what, "out") == 0) {
209+
ret = monitor_addOutWatchpoint(address, is_value ? &value : NULL);
210+
} else {
211+
ceda_string_t *msg = ceda_string_new(0);
212+
ceda_string_cpy(msg, USER_BAD_ARG_STR "unknown monitor kind\n");
213+
return msg;
214+
}
173215

174216
if (!ret) {
175217
ceda_string_t *msg = ceda_string_new(0);
176218
ceda_string_cpy(msg, USER_NO_SPACE_LEFT_STR);
177219
return msg;
178220
}
179221

222+
// all ok, no output
180223
return NULL;
181224
}
182225

@@ -188,16 +231,6 @@ static ceda_string_t *cli_delete(const char *arg) {
188231
// skip argv[0]
189232
arg = tokenizer_next_word(word, arg, LINE_BUFFER_SIZE);
190233

191-
char what[LINE_BUFFER_SIZE];
192-
// extract what to delete (breakpoint, watchpoint, ...)
193-
arg = tokenizer_next_word(what, arg, LINE_BUFFER_SIZE);
194-
195-
// missing what
196-
if (arg == NULL) {
197-
ceda_string_cpy(msg, USER_BAD_ARG_STR "missing delete target\n");
198-
return msg;
199-
}
200-
201234
// extract index
202235
arg = tokenizer_next_word(word, arg, LINE_BUFFER_SIZE);
203236

@@ -216,15 +249,8 @@ static ceda_string_t *cli_delete(const char *arg) {
216249
}
217250

218251
// actually delete something
219-
if (strcmp(what, "breakpoint") == 0) {
220-
if (!cpu_deleteBreakpoint(index)) {
221-
ceda_string_cpy(msg, "can't delete breakpoint\n");
222-
return msg;
223-
}
224-
} else if (strcmp(what, "watchpoint") == 0) {
225-
// TODO(giomba): implement this for watchpoints
226-
} else {
227-
ceda_string_cpy(msg, USER_BAD_ARG_STR "unknown delete target\n");
252+
if (!monitor_delete(index)) {
253+
ceda_string_cpy(msg, "can't delete monitor\n");
228254
return msg;
229255
}
230256

@@ -371,9 +397,9 @@ static ceda_string_t *cli_dis(const char *arg) {
371397
* Expected command line syntax:
372398
* save <filename> <start> <end>
373399
* where
374-
* filename: name of the file where to save the dump (no spaces allowed)
375-
* start: starting memory address, in hex
376-
* end: ending memory address, in hex
400+
* filename: name of the file where to save the dump (no spaces
401+
* allowed) start: starting memory address, in hex end: ending memory
402+
* address, in hex
377403
*
378404
* Data is saved [start;end)
379405
*
@@ -386,7 +412,8 @@ static ceda_string_t *cli_dis(const char *arg) {
386412
*
387413
* @param arg Pointer to the command line string.
388414
*
389-
* @return char* NULL in case of success, pointer to error message otherwise.
415+
* @return char* NULL in case of success, pointer to error message
416+
* otherwise.
390417
*/
391418
static ceda_string_t *cli_save(const char *arg) {
392419
char word[LINE_BUFFER_SIZE];
@@ -621,9 +648,10 @@ static ceda_string_t *cli_umount(const char *arg) {
621648
* filename: name of the file from which to load the dump (no spaces
622649
* allowed) start: starting memory address, in hex
623650
*
624-
* When loading, this routine will use the starting address saves inside the
625-
* file, unless a starting address is explicitly specified on the command
626-
* line, in which case, the starting address of the file will be overridden.
651+
* When loading, this routine will use the starting address saves inside
652+
* the file, unless a starting address is explicitly specified on the
653+
* command line, in which case, the starting address of the file will be
654+
* overridden.
627655
*
628656
* Example: load video memory dump, but one row below
629657
* load video.crt d050
@@ -824,7 +852,7 @@ static ceda_string_t *cli_help(const char *arg);
824852
static const cli_command cli_commands[] = {
825853
{"dis", "disassembly binary data", cli_dis},
826854
{"break", "set or show cpu breakpoints", cli_break},
827-
{"delete", "delete cpu breakpoint", cli_delete},
855+
{"delete", "delete cpu monitor/breakpoint", cli_delete},
828856
{"pause", "pause cpu execution", cli_pause},
829857
{"continue", "continue cpu execution", cli_continue},
830858
{"reg", "show cpu registers", cli_reg},

0 commit comments

Comments
 (0)