summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac1
-rw-r--r--s51/.gitignore1
-rw-r--r--s51/s51-command.c216
-rw-r--r--s51/s51-main.c27
-rw-r--r--s51/s51-parse.c2
-rw-r--r--s51/s51.h6
7 files changed, 234 insertions, 21 deletions
diff --git a/Makefile.am b/Makefile.am
index 71aee980..11b0b700 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1 +1 @@
-SUBDIRS=lib ccload target/blink
+SUBDIRS=lib ccload s51 target/blink
diff --git a/configure.ac b/configure.ac
index 6182d71c..a14c802b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -92,4 +92,5 @@ AC_OUTPUT([
Makefile
lib/Makefile
ccload/Makefile
+s51/Makefile
])
diff --git a/s51/.gitignore b/s51/.gitignore
new file mode 100644
index 00000000..cb909cf0
--- /dev/null
+++ b/s51/.gitignore
@@ -0,0 +1 @@
+s51
diff --git a/s51/s51-command.c b/s51/s51-command.c
index 8a5d4c08..278bca25 100644
--- a/s51/s51-command.c
+++ b/s51/s51-command.c
@@ -51,22 +51,85 @@ command_quit (FILE *output, int argc, char **argv)
return command_error;
}
+static void
+dump_bytes(FILE *output, uint8_t *memory, int length, uint16_t start)
+{
+ int group, i;
+
+ for (group = 0; group < length; group += 8) {
+ fprintf(output, "0x%04x ", start + group);
+ for (i = group; i < length && i < group + 8; i++)
+ fprintf(output, "%02x ", memory[i]);
+ for (; i < group + 8; i++)
+ fprintf(output, " ");
+ for (i = group; i < length && i < group + 8; i++) {
+ if (isascii(memory[i]) && isprint(memory[i]))
+ fprintf(output, "%c", memory[i]);
+ else
+ fprintf(output, ".");
+ }
+ fprintf(output, "\n");
+ }
+}
+
enum command_result
command_di (FILE *output, int argc, char **argv)
{
- return command_error;
+ uint16_t start, end;
+ uint8_t memory[65536];
+ uint8_t status;
+ int length;
+
+ if (argc != 3)
+ return command_error;
+ if (parse_uint16(argv[1], &start) != command_proceed)
+ return command_error;
+ if (parse_uint16(argv[2], &end) != command_proceed)
+ return command_error;
+ length = (int) end - (int) start + 1;
+ status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length);
+ dump_bytes(output, memory, length, start);
+ return command_proceed;
}
enum command_result
command_ds (FILE *output, int argc, char **argv)
{
- return command_error;
+ uint16_t start, end;
+ uint8_t memory[65536];
+ uint8_t status;
+ int length;
+
+ if (argc != 3)
+ return command_error;
+ if (parse_uint16(argv[1], &start) != command_proceed)
+ return command_error;
+ if (parse_uint16(argv[2], &end) != command_proceed)
+ return command_error;
+ length = (int) end - (int) start + 1;
+ status = ccdbg_read_memory(s51_dbg, start + 0xdf00, memory, length);
+ dump_bytes(output, memory, length, start);
+ return command_proceed;
}
enum command_result
command_dx (FILE *output, int argc, char **argv)
{
- return command_error;
+ uint16_t start, end;
+ uint8_t memory[65536];
+ uint8_t status;
+ int length;
+
+ if (argc != 3)
+ return command_error;
+ if (parse_uint16(argv[1], &start) != command_proceed)
+ return command_error;
+ if (parse_uint16(argv[2], &end) != command_proceed)
+ return command_error;
+ length = (int) end - (int) start + 1;
+ status = ccdbg_read_memory(s51_dbg, start, memory, length);
+ dump_bytes(output, memory, length, start);
+ return command_proceed;
}
enum command_result
@@ -87,7 +150,6 @@ command_pc (FILE *output, int argc, char **argv)
uint16_t pc;
if (argv[1]) {
enum command_result result;
-
result = parse_uint16(argv[1], &pc);
if (result != command_proceed)
return result;
@@ -99,16 +161,104 @@ command_pc (FILE *output, int argc, char **argv)
return command_proceed;
}
+struct cc_break {
+ int enabled;
+ int temporary;
+ uint16_t address;
+};
+
+#define CC_NUM_BREAKPOINTS 4
+
+static struct cc_break breakpoints[CC_NUM_BREAKPOINTS];
+
+enum command_result
+set_breakpoint(FILE *output, uint16_t address, int temporary)
+{
+ int b;
+ uint8_t status;
+ for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
+ if (breakpoints[b].enabled == 0)
+ break;
+ if (breakpoints[b].address == address)
+ break;
+ }
+ if (b == CC_NUM_BREAKPOINTS) {
+ fprintf(output, "Error: too many breakpoints requested\n");
+ return command_proceed;
+ }
+ if (breakpoints[b].enabled == 0) {
+ breakpoints[b].address = address;
+ status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, address);
+ fprintf(output, "set_hw_brkpnt status 0x%02x\n", status);
+ }
+ ++breakpoints[b].enabled;
+ fprintf(output, "Breakpoint %d at 0x%04x\n", b, address);
+ breakpoints[b].temporary += temporary;
+ return command_proceed;
+}
+
+enum command_result
+clear_breakpoint(FILE *output, uint16_t address, int temporary)
+{
+ int b;
+ uint8_t status;
+
+ for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
+ if (breakpoints[b].enabled != 0 &&
+ ((breakpoints[b].temporary != 0) == (temporary != 0)) &&
+ breakpoints[b].address == address)
+ break;
+ }
+ if (b == CC_NUM_BREAKPOINTS) {
+ fprintf(output, "Error: no matching breakpoint found\n");
+ return command_proceed;
+ }
+ --breakpoints[b].enabled;
+ --breakpoints[b].temporary;
+ if (breakpoints[b].enabled == 0) {
+ breakpoints[b].address = -1;
+ ccdbg_set_hw_brkpnt(s51_dbg, b, 0, address);
+ fprintf(output, "set_hw_brkpnt status 0x%02x\n", status);
+ }
+ return command_proceed;
+}
+
enum command_result
command_break (FILE *output, int argc, char **argv)
{
- return command_error;
+ int b;
+ uint16_t address;
+ enum command_result result;
+
+ if (argc == 1) {
+ for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
+ if (breakpoints[b].enabled)
+ fprintf(output, "Breakpoint %d 0x%04x\n",
+ b, breakpoints[b].address);
+ return command_proceed;
+ }
+ if (argc != 2)
+ return command_error;
+ result = parse_uint16(argv[1], &address);
+ if (result != command_proceed)
+ return result;
+
+ return set_breakpoint(output, address, 0);
}
enum command_result
command_clear (FILE *output, int argc, char **argv)
{
- return command_error;
+ int b;
+ uint16_t address;
+ enum command_result result;
+
+ if (argc != 2)
+ return command_error;
+ result = parse_uint16(argv[1], &address);
+ if (result != command_proceed)
+ return result;
+ return clear_breakpoint(output, address, 0);
}
enum command_result
@@ -132,19 +282,29 @@ command_run (FILE *output, int argc, char **argv)
start = ccdbg_get_pc(s51_dbg);
fprintf(output, "Resume at 0x%04x\n", start);
ccdbg_resume(s51_dbg);
+// cc_wait(s51_dbg);
return command_proceed;
}
enum command_result
command_next (FILE *output, int argc, char **argv)
{
- return command_error;
+ return command_step(output, argc, argv);
}
enum command_result
command_step (FILE *output, int argc, char **argv)
{
- return command_error;
+ uint16_t pc;
+ uint8_t opcode;
+ uint8_t a;
+
+ a = ccdbg_step_instr(s51_dbg);
+ fprintf(output, " ACC= 0x%02x\n", a);
+ pc = ccdbg_get_pc(s51_dbg);
+ ccdbg_read_memory(s51_dbg, pc, &opcode, 1);
+ fprintf(output, " ? 0x%04x %02x\n", pc, opcode);
+ return command_proceed;
}
enum command_result
@@ -169,3 +329,43 @@ command_reset (FILE *output, int argc, char **argv)
ccdbg_debug_mode(s51_dbg);
return command_proceed;
}
+
+enum command_result
+command_status(FILE *output, int argc, char **argv)
+{
+ uint8_t status;
+
+ status = ccdbg_read_status(s51_dbg);
+ if ((status & CC_STATUS_CHIP_ERASE_DONE) == 0)
+ fprintf(output, "\tChip erase in progress\n");
+ if (status & CC_STATUS_PCON_IDLE)
+ fprintf(output, "\tCPU is idle (clock gated)\n");
+ if (status & CC_STATUS_CPU_HALTED)
+ fprintf(output, "\tCPU halted\n");
+ else
+ fprintf(output, "\tCPU running\n");
+ if ((status & CC_STATUS_POWER_MODE_0) == 0)
+ fprintf(output, "\tPower Mode 1-3 selected\n");
+ if (status & CC_STATUS_HALT_STATUS)
+ fprintf(output, "\tHalted by software or hw breakpoint\n");
+ else
+ fprintf(output, "\tHalted by debug command\n");
+ if (status & CC_STATUS_DEBUG_LOCKED)
+ fprintf(output, "\tDebug interface is locked\n");
+ if ((status & CC_STATUS_OSCILLATOR_STABLE) == 0)
+ fprintf(output, "\tOscillators are not stable\n");
+ if (status & CC_STATUS_STACK_OVERFLOW)
+ fprintf(output, "\tStack overflow\n");
+ return command_proceed;
+}
+
+uint8_t cc_wait(struct ccdbg *dbg)
+{
+ uint8_t status;
+ for(;;) {
+ status = ccdbg_read_status(dbg);
+ if (status & CC_STATUS_CPU_HALTED)
+ break;
+ }
+ return status;
+}
diff --git a/s51/s51-main.c b/s51/s51-main.c
index e8bf2d7d..9a5ca7c2 100644
--- a/s51/s51-main.c
+++ b/s51/s51-main.c
@@ -43,7 +43,7 @@ main(int argc, char **argv)
FILE *console_out = stdout;
char *endptr;
- while ((opt = getopt(argc, argv, "PVvHht:X:c:Z:s:S:p:")) != -1) {
+ while ((opt = getopt(argc, argv, "PVvHht:X:c:r:Z:s:S:p:")) != -1) {
switch (opt) {
case 't':
cpu = optarg;
@@ -63,6 +63,7 @@ main(int argc, char **argv)
break;
case 'c':
break;
+ case 'r':
case 'Z':
s51_port = strtol(optarg, &endptr, 0);
if (endptr == optarg || strlen(endptr) != 0)
@@ -100,6 +101,11 @@ main(int argc, char **argv)
perror ("socket");
exit(1);
}
+ r = setsockopt(l, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (int));
+ if (r) {
+ perror("setsockopt");
+ exit(1);
+ }
in.sin_family = AF_INET;
in.sin_port = htons(s51_port);
in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -108,11 +114,6 @@ main(int argc, char **argv)
perror("bind");
exit(1);
}
- r = setsockopt(l, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (int));
- if (r) {
- perror("setsockopt");
- exit(1);
- }
r = listen(l, 5);
if (r) {
perror("listen");
@@ -121,21 +122,23 @@ main(int argc, char **argv)
for (;;) {
struct sockaddr_in client_addr;
socklen_t client_len = sizeof (struct sockaddr_in);
- FILE *client;
+ FILE *client_in, *client_out;
- s = accept(r, (struct sockaddr *)
+ s = accept(l, (struct sockaddr *)
&client_addr, &client_len);
if (s < 0) {
perror("accept");
exit(1);
}
- client = fdopen(s, "rw");
- if (!client) {
+ client_in = fdopen(s, "r");
+ client_out = fdopen(s, "w");
+ if (!client_in || !client_out) {
perror("fdopen");
exit(1);
}
- command_read(client, client);
- fclose(client);
+ command_read(client_in, client_out);
+ fclose(client_in);
+ fclose(client_out);
}
} else
command_read(console_in, console_out);
diff --git a/s51/s51-parse.c b/s51/s51-parse.c
index ba0d611c..56a63e24 100644
--- a/s51/s51-parse.c
+++ b/s51/s51-parse.c
@@ -58,6 +58,8 @@ static struct command_function functions[] = {
"Halt the processor\n" },
{ "reset","res",command_reset, "[res]et",
"Reset the CPU\n" },
+ { "status","status",command_status, "status",
+ "Display CC1111 debug status\n" },
};
#define NUM_FUNCTIONS (sizeof functions / sizeof functions[0])
diff --git a/s51/s51.h b/s51/s51.h
index b916acb6..3ca4734c 100644
--- a/s51/s51.h
+++ b/s51/s51.h
@@ -74,5 +74,11 @@ command_halt (FILE *output, int argc, char **argv);
enum command_result
command_reset (FILE *output, int argc, char **argv);
+enum command_result
+command_status (FILE *output, int argc, char **argv);
+
+uint8_t
+cc_wait(struct ccdbg *dbg);
+
void
command_read (FILE *input, FILE *output);