summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile9
-rw-r--r--Makefile.blink20
-rw-r--r--blink.c44
-rw-r--r--ccdbg-hex.c284
-rw-r--r--ccdbg-memory.c18
-rw-r--r--ccdbg.c15
-rw-r--r--ccdbg.h27
7 files changed, 412 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 2fd8ec6d..801068cd 100644
--- a/Makefile
+++ b/Makefile
@@ -10,12 +10,16 @@ KERNEL_OBJS=cccp.o
LIBUSB_OBJS=cp-usb.o
OBJS=ccdbg.o ccdbg-command.o ccdbg-debug.o \
- ccdbg-io.o ccdbg-memory.o \
+ ccdbg-hex.o ccdbg-io.o ccdbg-memory.o \
$(LIBUSB_OBJS)
INCS=ccdbg.h cccp.h
PROG=ccdbg
+LOAD=blink
+
+all: $(PROG) $(LOAD)
+
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
@@ -23,3 +27,6 @@ clean:
rm -f $(PROG) $(OBJS)
$(OBJS): $(INCS)
+
+blink: blink.c Makefile.blink
+ make -f Makefile.blink
diff --git a/Makefile.blink b/Makefile.blink
new file mode 100644
index 00000000..37c3c672
--- /dev/null
+++ b/Makefile.blink
@@ -0,0 +1,20 @@
+CC=sdcc
+NO_OPT=--nogcse --noinvariant --noinduction --nojtbound --noloopreverse \
+ --nolabelopt --nooverlay --peep-asm
+DEBUG=--debug
+
+CFLAGS=--model-large $(DEBUG) --less-pedantic --xram-size 4096\
+ --stack-auto --no-peep --int-long-reent --float-reent
+
+LDFLAGS=-L/usr/share/sdcc/lib/large \
+ --code-loc 0xf000 --xram-loc 0xf400
+
+SRC=blink.c
+OBJ=$(SRC:.c=.rel)
+
+%.rel : %.c
+ $(CC) -c $(CFLAGS) -o$*.rel $<
+
+blink: $(OBJ)
+ $(CC) $(LDFLAGS) $(CFLAGS) -o$@ $(OBJ)
+
diff --git a/blink.c b/blink.c
new file mode 100644
index 00000000..fcbc04d0
--- /dev/null
+++ b/blink.c
@@ -0,0 +1,44 @@
+
+sfr at 0x80 P0;
+sfr at 0x90 P1;
+sfr at 0xA0 P2;
+
+#define PERCFG SFR(0xF1)
+#define ADCCFG SFR(0xF2)
+#define P0SEL SFR(0xF3)
+#define P1SEL SFR(0xF4)
+#define P2SEL SFR(0xF5)
+
+sfr at 0xFD P0DIR;
+sfr at 0xFE P1DIR;
+sfr at 0xFE P2DIR;
+sfr at 0x8F P0INP;
+sfr at 0xF6 P1INP;
+sfr at 0xF7 P2INP;
+
+#define P0IFG SFR(0x89)
+#define P1IFG SFR(0x8A)
+#define P2IFG SFR(0x8B)
+
+#define nop() _asm \
+ nop \
+ _endasm;
+
+main ()
+{
+ int i, j;
+ /* Set p1_1 to output */
+ P1DIR = 0x02;
+ P1INP = 0x00;
+ P2INP = 0x00;
+ for (;;) {
+ P1 = 0xff;
+ for (j = 0; j < 100; j++)
+ for (i = 0; i < 1000; i++)
+ nop();
+ P1 = 0xfd;
+ for (j = 0; j < 100; j++)
+ for (i = 0; i < 1000; i++)
+ nop();
+ }
+}
diff --git a/ccdbg-hex.c b/ccdbg-hex.c
new file mode 100644
index 00000000..d9d27cdf
--- /dev/null
+++ b/ccdbg-hex.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+#include <stdarg.h>
+#include <ctype.h>
+
+struct hex_input {
+ FILE *file;
+ int line;
+ char *name;
+};
+
+enum hex_read_state {
+ read_marker,
+ read_length,
+ read_address,
+ read_type,
+ read_data,
+ read_checksum,
+ read_newline,
+ read_white,
+ read_done,
+};
+
+
+static void
+ccdbg_hex_error(struct hex_input *input, char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ fprintf(stderr, "Hex error %s:%d: ", input->name, input->line);
+ vfprintf(stderr, format, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+}
+
+static void
+ccdbg_hex_free(struct hex_record *record)
+{
+ if (!record) return;
+ free(record);
+}
+
+static struct hex_record *
+ccdbg_hex_alloc(uint8_t length)
+{
+ struct hex_record *record;
+
+ record = calloc(1, sizeof(struct hex_record) + length);
+ record->length = length;
+ return record;
+}
+
+static int
+ishex(char c)
+{
+ return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F');
+}
+
+static int
+fromhex(char c)
+{
+ if (isdigit(c))
+ return c - '0';
+ if ('a' <= c && c <= 'f')
+ return c - 'a' + 10;
+ if ('A' <= c && c <= 'F')
+ return c - 'A' + 10;
+ abort();
+ return 0;
+}
+
+static uint8_t
+ccdbg_hex_checksum(struct hex_record *record)
+{
+ uint8_t checksum = 0;
+ int i;
+
+ checksum += record->length;
+ checksum += record->address >> 8;
+ checksum += record->address & 0xff;
+ checksum += record->type;
+ for (i = 0; i < record->length; i++)
+ checksum += record->data[i];
+ return -checksum;
+}
+
+static struct hex_record *
+ccdbg_hex_read_record(struct hex_input *input)
+{
+ struct hex_record *record = NULL;
+ enum hex_read_state state = read_marker;
+ char c;
+ int nhexbytes;
+ uint32_t hex;
+ uint32_t ndata;
+ uint8_t checksum;
+
+ while (state != read_done) {
+ c = getc(input->file);
+ if (c == EOF && state != read_white) {
+ ccdbg_hex_error(input, "Unexpected EOF");
+ goto bail;
+ }
+ if (c == '\n')
+ input->line++;
+ switch (state) {
+ case read_marker:
+ if (c != ':') {
+ ccdbg_hex_error(input, "Missing ':'");
+ goto bail;
+ }
+ state = read_length;
+ nhexbytes = 2;
+ hex = 0;
+ break;
+ case read_length:
+ case read_address:
+ case read_type:
+ case read_data:
+ case read_checksum:
+ if (!ishex(c)) {
+ ccdbg_hex_error(input, "Non-hex char '%c'",
+ c);
+ goto bail;
+ }
+ hex = hex << 4 | fromhex(c);
+ --nhexbytes;
+ if (nhexbytes != 0)
+ break;
+
+ switch (state) {
+ case read_length:
+ record = ccdbg_hex_alloc(hex);
+ if (!record) {
+ ccdbg_hex_error(input, "Out of memory");
+ goto bail;
+ }
+ state = read_address;
+ nhexbytes = 4;
+ break;
+ case read_address:
+ record->address = hex;
+ state = read_type;
+ nhexbytes = 2;
+ break;
+ case read_type:
+ record->type = hex;
+ state = read_data;
+ nhexbytes = 2;
+ ndata = 0;
+ break;
+ case read_data:
+ record->data[ndata] = hex;
+ ndata++;
+ nhexbytes = 2;
+ break;
+ case read_checksum:
+ record->checksum = hex;
+ state = read_newline;
+ break;
+ default:
+ break;
+ }
+ if (state == read_data)
+ if (ndata == record->length) {
+ nhexbytes = 2;
+ state = read_checksum;
+ }
+ hex = 0;
+ break;
+ case read_newline:
+ if (c != '\n' && c != '\r') {
+ ccdbg_hex_error(input, "Missing newline");
+ goto bail;
+ }
+ state = read_white;
+ break;
+ case read_white:
+ if (!isspace(c)) {
+ if (c == '\n')
+ input->line--;
+ if (c != EOF)
+ ungetc(c, input->file);
+ state = read_done;
+ }
+ break;
+ case read_done:
+ break;
+ }
+ }
+ checksum = ccdbg_hex_checksum(record);
+ if (checksum != record->checksum) {
+ ccdbg_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n",
+ record->checksum, checksum);
+ goto bail;
+ }
+ return record;
+
+bail:
+ ccdbg_hex_free(record);
+ return NULL;
+}
+
+void
+ccdbg_hex_file_free(struct hex_file *hex)
+{
+ int i;
+
+ if (!hex)
+ return;
+ for (i = 0; i < hex->nrecord; i++)
+ ccdbg_hex_free(hex->records[i]);
+ free (hex);
+}
+
+static int
+ccdbg_hex_record_compar(const void *av, const void *bv)
+{
+ const struct hex_record *a = *(struct hex_record **) av;
+ const struct hex_record *b = *(struct hex_record **) bv;
+
+ return (int) a->address - (int) b->address;
+}
+
+struct hex_file *
+ccdbg_hex_file_read(FILE *file, char *name)
+{
+ struct hex_input input;
+ struct hex_file *hex = NULL, *newhex;
+ struct hex_record *record;
+ int srecord = 1;
+ int done = 0;
+
+ hex = calloc (1, sizeof (struct hex_file) + sizeof (struct hex_record *));
+ input.name = name;
+ input.line = 1;
+ input.file = file;
+ while (!done) {
+ record = ccdbg_hex_read_record(&input);
+ if (!record)
+ goto bail;
+ if (hex->nrecord == srecord) {
+ srecord *= 2;
+ newhex = realloc(hex,
+ sizeof (struct hex_file) +
+ srecord * sizeof (struct hex_record *));
+ if (!newhex)
+ goto bail;
+ hex = newhex;
+ }
+ hex->records[hex->nrecord++] = record;
+ if (record->type == HEX_RECORD_EOF)
+ done = 1;
+ }
+ /*
+ * Sort them into increasing addresses, except for EOF
+ */
+ qsort(hex->records, hex->nrecord - 1, sizeof (struct hex_record *),
+ ccdbg_hex_record_compar);
+ return hex;
+
+bail:
+ ccdbg_hex_file_free(hex);
+ return NULL;
+}
+
diff --git a/ccdbg-memory.c b/ccdbg-memory.c
index ffc09679..fa953d17 100644
--- a/ccdbg-memory.c
+++ b/ccdbg-memory.c
@@ -73,3 +73,21 @@ ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
*bytes++ = ccdbg_execute(dbg, read8);
return 0;
}
+
+uint8_t
+ccdbg_write_hex(struct ccdbg *dbg, struct hex_file *hex)
+{
+ int i;
+ struct hex_record *record;
+
+ for (i = 0; i < hex->nrecord; i++) {
+ record = hex->records[i];
+ if (record->type == HEX_RECORD_EOF)
+ break;
+ printf("Write %d bytes at 0x%04x\n",
+ record->length, record->address);
+ ccdbg_write_memory(dbg, record->address,
+ record->data, record->length);
+ }
+ return 0;
+}
diff --git a/ccdbg.c b/ccdbg.c
index a3548143..3a34d0e9 100644
--- a/ccdbg.c
+++ b/ccdbg.c
@@ -64,6 +64,7 @@ main (int argc, char **argv)
uint16_t pc;
uint8_t memory[0x10];
int i;
+ struct hex_file *hex;
dbg = ccdbg_open("/dev/ttyUSB0");
if (!dbg)
@@ -71,7 +72,9 @@ main (int argc, char **argv)
#if 0
ccdbg_manual(dbg, stdin);
#endif
-#if 1
+ hex = ccdbg_hex_file_read(stdin, "<stdin>");
+ if (!hex)
+ exit (1);
ccdbg_reset(dbg);
ccdbg_debug_mode(dbg);
status = ccdbg_read_status(dbg);
@@ -80,9 +83,9 @@ main (int argc, char **argv)
printf("Chip id: 0x%04x\n", chip_id);
status = ccdbg_halt(dbg);
printf ("halt status: 0x%02x\n", status);
-/* ccdbg_execute(dbg, instructions); */
- ccdbg_write_memory(dbg, 0xf000, mem_instr, sizeof (mem_instr));
- ccdbg_read_memory(dbg, 0xf000, memory, sizeof (memory));
+
+ ccdbg_write_hex(dbg, hex);
+ ccdbg_hex_file_free(hex);
for (i = 0; i < sizeof (memory); i++)
printf (" %02x", memory[i]);
printf ("\n");
@@ -91,6 +94,10 @@ main (int argc, char **argv)
printf ("pc starts at 0x%04x\n", pc);
status = ccdbg_resume(dbg);
printf ("resume status: 0x%02x\n", status);
+#if 0
+/* ccdbg_execute(dbg, instructions); */
+ ccdbg_write_memory(dbg, 0xf000, mem_instr, sizeof (mem_instr));
+ ccdbg_read_memory(dbg, 0xf000, memory, sizeof (memory));
#endif
ccdbg_close(dbg);
exit (0);
diff --git a/ccdbg.h b/ccdbg.h
index 0f07e2e9..05abc97f 100644
--- a/ccdbg.h
+++ b/ccdbg.h
@@ -151,6 +151,30 @@ ccdbg_add_debug(int level);
void
ccdbg_clear_debug(int level);
+/* ccdbg-hex.c */
+struct hex_record {
+ uint8_t length;
+ uint16_t address;
+ uint8_t type;
+ uint8_t checksum;
+ uint8_t data[0];
+};
+
+struct hex_file {
+ int nrecord;
+ struct hex_record *records[0];
+};
+
+#define HEX_RECORD_NORMAL 0x00
+#define HEX_RECORD_EOF 0x01
+#define HEX_RECORD_EXTENDED_ADDRESS 0x02
+
+struct hex_file *
+ccdbg_hex_file_read(FILE *file, char *name);
+
+void
+ccdbg_hex_file_free(struct hex_file *hex);
+
/* ccdbg-io.c */
void
ccdbg_half_clock(struct ccdbg *dbg);
@@ -230,6 +254,9 @@ ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
uint8_t
ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes);
+uint8_t
+ccdbg_write_hex(struct ccdbg *dbg, struct hex_file *hex);
+
/* cp-usb.c */
void
cp_usb_init(struct ccdbg *dbg);