--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# 1101 with zeros
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+# try sending READ_STATUS
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
WARN=-Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes\
-Wmissing-declarations -Wnested-externs -fno-strict-aliasing
CFLAGS=-g -I$(KINC) $(WARN)
+LIBS=-lusb
-OBJS=ccdbg.o ccdbg-command.o ccdbg-io.o cccp.o
+KERNEL_OBJS=cccp.o
+LIBUSB_OBJS=cp-usb.o
+
+OBJS=ccdbg.o ccdbg-command.o ccdbg-io.o $(LIBUSB_OBJS)
INCS=ccdbg.h cccp.h
PROG=ccdbg
$(PROG): $(OBJS)
- $(CC) $(CFLAGS) -o $@ $(OBJS)
+ $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
clean:
rm -f $(PROG) $(OBJS)
{
/* force two rising clocks while holding RESET_N low */
ccdbg_half_clock(dbg);
- cccp_write(dbg, CC_RESET_N|CC_CLOCK, 0); ccdbg_half_clock(dbg);
- cccp_write(dbg, CC_CLOCK, CC_CLOCK); ccdbg_half_clock(dbg);
- cccp_write(dbg, CC_CLOCK, 0); ccdbg_half_clock(dbg);
- cccp_write(dbg, CC_CLOCK, CC_CLOCK); ccdbg_half_clock(dbg);
- cccp_write(dbg, CC_RESET_N, CC_RESET_N); ccdbg_half_clock(dbg);
+ ccdbg_write(dbg, CC_RESET_N|CC_CLOCK, 0); ccdbg_half_clock(dbg);
+ ccdbg_write(dbg, CC_CLOCK, CC_CLOCK); ccdbg_half_clock(dbg);
+ ccdbg_write(dbg, CC_CLOCK, 0); ccdbg_half_clock(dbg);
+ ccdbg_write(dbg, CC_CLOCK, CC_CLOCK); ccdbg_half_clock(dbg);
+ ccdbg_write(dbg, CC_RESET_N, CC_RESET_N); ccdbg_half_clock(dbg);
}
void
ccdbg_reset(struct ccdbg *dbg)
{
ccdbg_half_clock(dbg);
- cccp_write(dbg, CC_RESET_N, 0); ccdbg_half_clock(dbg);
- cccp_write(dbg, CC_RESET_N, CC_RESET_N);
+ ccdbg_write(dbg, CC_RESET_N, 0); ccdbg_half_clock(dbg);
+ ccdbg_write(dbg, CC_RESET_N, CC_RESET_N);
}
uint8_t
perror("calloc");
return NULL;
}
+ dbg->clock = 1;
+#ifdef USE_KERNEL
dbg->fd = open(file, 2);
if (dbg->fd < 0) {
perror(file);
}
cccp_init(dbg);
cccp_write(dbg, CC_CLOCK, CC_CLOCK);
+#else
+ cp_usb_init(dbg);
+#endif
dbg->clock = 1;
return dbg;
}
void
ccdbg_close(struct ccdbg *dbg)
{
+#if USE_KERNEL
cccp_fini(dbg);
close (dbg->fd);
+#else
+ cp_usb_fini(dbg);
+#endif
free (dbg);
}
+int
+ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value)
+{
+#if USE_KERNEL
+ return cccp_write(dbg, mask, value);
+#else
+ cp_usb_write(dbg, mask, value);
+ return 0;
+#endif
+}
+
+uint8_t
+ccdbg_read(struct ccdbg *dbg)
+{
+#if USE_KERNEL
+ return cccp_read_all(dbg);
+#else
+ return cp_usb_read(dbg);
+#endif
+}
+
void
ccdbg_clock_1_0(struct ccdbg *dbg)
{
ccdbg_quarter_clock(dbg);
assert(dbg->clock == 1);
- cccp_write(dbg, CC_CLOCK, 0);
+ ccdbg_write(dbg, CC_CLOCK, 0);
dbg->clock = 0;
ccdbg_quarter_clock(dbg);
}
{
ccdbg_quarter_clock(dbg);
assert(dbg->clock == 0);
- cccp_write(dbg, CC_CLOCK, CC_CLOCK);
+ ccdbg_write(dbg, CC_CLOCK, CC_CLOCK);
dbg->clock = 1;
ccdbg_quarter_clock(dbg);
}
if (bit)
data |= CC_DATA;
ccdbg_half_clock(dbg);
- cccp_write(dbg, CC_DATA|CC_CLOCK, data);
+ ccdbg_write(dbg, CC_DATA|CC_CLOCK, data);
ccdbg_half_clock(dbg);
- cccp_write(dbg, CC_CLOCK, 0);
+ ccdbg_write(dbg, CC_CLOCK, 0);
// printf ("%d", bit);
}
uint8_t data;
ccdbg_half_clock(dbg);
- cccp_write(dbg, CC_CLOCK, CC_CLOCK);
+ ccdbg_write(dbg, CC_CLOCK, CC_CLOCK);
ccdbg_half_clock(dbg);
- cccp_write(dbg, CC_CLOCK, 0);
- data = cccp_read(dbg, CC_DATA);
- return data ? 1 : 0;
+ ccdbg_write(dbg, CC_CLOCK, 0);
+ data = ccdbg_read(dbg);
+ return (data & CC_DATA) ? 1 : 0;
}
uint8_t
{
uint8_t get;
- cccp_write(dbg, CC_DATA|CC_CLOCK|CC_RESET_N, set);
- get = cccp_read_all(dbg);
+ ccdbg_write(dbg, CC_DATA|CC_CLOCK|CC_RESET_N, set);
+ get = ccdbg_read(dbg);
printf("%c %c %c -> %c %c %c\n",
is_bit(set, 'C', CC_CLOCK),
is_bit(set, 'D', CC_DATA),
static void
_ccdbg_debug_mode(struct ccdbg *dbg)
{
+ printf ("#\n");
+ printf ("# Debug mode\n");
+ printf ("#\n");
ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N);
ccdbg_write_read(dbg, CC_DATA );
ccdbg_write_read(dbg, CC_CLOCK|CC_DATA );
ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N);
}
+static void
+_ccdbg_send_bit(struct ccdbg *dbg, uint8_t bit)
+{
+ if (bit) bit = CC_DATA;
+ ccdbg_write_read(dbg, CC_CLOCK|bit|CC_RESET_N);
+ ccdbg_write_read(dbg, bit|CC_RESET_N);
+}
+
+static void
+_ccdbg_send_byte(struct ccdbg *dbg, uint8_t byte)
+{
+ int bit;
+ printf ("#\n");
+ printf ("# Send Byte 0x%02x\n", byte);
+ printf ("#\n");
+ for (bit = 7; bit >= 0; bit--) {
+ _ccdbg_send_bit(dbg, (byte >> bit) & 1);
+ if (bit == 3)
+ printf ("\n");
+ }
+}
+
+static void
+_ccdbg_send_bits(struct ccdbg *dbg, int n, uint32_t bits)
+{
+ int bit;
+ printf ("#\n");
+ printf ("# Send %d bits 0x%08x\n", n, bits);
+ printf ("#\n");
+ for (bit = n - 1; bit >= 0; bit--) {
+ _ccdbg_send_bit(dbg, (bits >> bit) & 1);
+ if ((bit & 3) == 3)
+ printf ("\n");
+ }
+}
+
+static void
+_ccdbg_print_bits(int n, uint32_t bits)
+{
+ int bit;
+
+ for (bit = n - 1; bit >= 0; bit--)
+ printf ("%d", (bits >> bit) & 1);
+}
+
+static uint32_t
+_ccdbg_read_bits(struct ccdbg *dbg, int bits)
+{
+ int bit;
+ uint32_t val = 0;
+ uint8_t get;
+
+ printf ("#\n");
+ printf ("# Read %d bits\n", bits);
+ printf ("#\n");
+ for (bit = 0; bit < bits; bit++) {
+ ccdbg_write_read(dbg, CC_CLOCK|CC_DATA|CC_RESET_N);
+ get = ccdbg_write_read(dbg, CC_DATA|CC_RESET_N);
+ val <<= 1;
+ if (get & CC_DATA)
+ val |= 1;
+ if ((bit & 3) == 3)
+ printf ("\n");
+ }
+ printf ("#\n");
+ printf ("# Read "); _ccdbg_print_bits(bits, val); printf ("\n");
+ printf ("#\n");
+ return val;
+}
+
+static int
+_ccdbg_check_bits(uint32_t bits, uint8_t match)
+{
+ int bit;
+
+ for (bit = 0; bit < 24; bit++)
+ if (((bits >> bit) & 0xff) == match)
+ return 1;
+ return 0;
+}
+
+static uint32_t
+_ccdbg_play(struct ccdbg *dbg, int num_sync, uint32_t sync)
+{
+ uint32_t bits;
+ _ccdbg_debug_mode(dbg);
+ _ccdbg_send_bits(dbg, num_sync, sync);
+ _ccdbg_send_byte(dbg, CC_GET_CHIP_ID);
+ bits = _ccdbg_read_bits(dbg, 16);
+ _ccdbg_send_byte(dbg, CC_GET_CHIP_ID);
+ bits = _ccdbg_read_bits(dbg, 16);
+// _ccdbg_send_byte(dbg, CC_READ_STATUS);
+ _ccdbg_reset(dbg);
+ if (_ccdbg_check_bits(bits, 0x11)) {
+ printf("#\n#match with %d bits 0x%08x\n#\n", num_sync, sync);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+_ccdbg_play_num(struct ccdbg *dbg, int num)
+{
+ uint32_t sync;
+ uint32_t max;
+
+ printf ("#\n#play %d\n#\n", num);
+ max = (1 << num);
+ for (sync = 0; sync < max; sync++)
+ if (_ccdbg_play(dbg, num, sync))
+ return 1;
+ return 0;
+}
+
+static int
+_ccdbg_play_many(struct ccdbg *dbg, int max)
+{
+ int num;
+
+ for (num = 0; num < max; num++)
+ if (_ccdbg_play_num(dbg, num))
+ return 1;
+ return 0;
+}
+
static void
ccdbg_manual(struct ccdbg *dbg, FILE *input)
{
dbg = ccdbg_open("/dev/ttyUSB0");
if (!dbg)
exit (1);
- ccdbg_manual(dbg, stdin);
#if 0
+ _ccdbg_play(dbg, 0, 0);
+ _ccdbg_play_many(dbg, 8);
+#endif
+ ccdbg_manual(dbg, stdin);
+#if 0
ccdbg_debug_mode(dbg);
status = ccdbg_read_status(dbg);
printf("Status: 0x%02x\n", status);
chip_id = ccdbg_get_chip_id(dbg);
printf("Chip id: 0x%04x\n", chip_id);
-#endif
_ccdbg_reset(dbg);
+#endif
ccdbg_close(dbg);
exit (0);
}
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
+#undef USE_KERNEL
+#ifdef USE_KERNEL
#include <cp2101.h>
-
#define CC_DATA CP2101_GPIO_MASK(0)
#define CC_CLOCK CP2101_GPIO_MASK(1)
#define CC_RESET_N CP2101_GPIO_MASK(2)
+#else
+#define CC_CLOCK 0x1
+#define CC_DATA 0x2
+#define CC_RESET_N 0x4
+#include <usb.h>
+#endif
+
/* painfully slow for now */
-#define CC_CLOCK_US (1 * 1000)
+#define CC_CLOCK_US (100 * 1000)
struct ccdbg {
+ usb_dev_handle *usb_dev;
+ uint8_t gpio;
+#ifdef USE_KERNEL
int fd;
+#endif
uint8_t debug_data;
int clock;
};
void
ccdbg_half_clock(struct ccdbg *dbg);
+int
+ccdbg_write(struct ccdbg *dbg, uint8_t mask, uint8_t value);
+
+uint8_t
+ccdbg_read(struct ccdbg *dbg);
+
struct ccdbg *
ccdbg_open(char *file);
uint16_t
ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len);
+/* cp-usb.c */
+void
+cp_usb_init(struct ccdbg *dbg);
+
+void
+cp_usb_fini(struct ccdbg *dbg);
+
+void
+cp_usb_write(struct ccdbg *dbg, uint8_t mask, uint8_t value);
+
+uint8_t
+cp_usb_read(struct ccdbg *dbg);
+
#endif /* _CCDBG_H_ */
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# GET_CHIP_ID
+
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C . R 0
+. . R
+
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# start reading again
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
--- /dev/null
+/*
+ * 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 <usb.h>
+
+#define CP2101_UART 0x00
+#define UART_ENABLE 0x0001
+#define UART_DISABLE 0x0000
+#define REQTYPE_HOST_TO_DEVICE 0x41
+#define REQTYPE_DEVICE_TO_HOST 0xc1
+
+static int
+cp_usb_gpio_get(struct ccdbg *dbg, uint8_t *gpio_get)
+{
+ return usb_control_msg(dbg->usb_dev, /* dev */
+ 0xc0, /* request */
+ 0xff, /* requesttype */
+ 0x00c2, /* value */
+ 0, /* index */
+ (char *) gpio_get, /* bytes */
+ 1, /* size */
+ 300); /* timeout */
+}
+
+static int
+cp_usb_gpio_set(struct ccdbg *dbg, uint8_t mask, uint8_t value)
+{
+ uint16_t gpio_set = ((uint16_t) value << 8) | mask;
+
+ return usb_control_msg(dbg->usb_dev, /* dev */
+ 0x40, /* request */
+ 0xff, /* requesttype */
+ 0x37e1, /* value */
+ gpio_set, /* index */
+ NULL, /* bytes */
+ 0, /* size */
+ 300); /* timeout */
+}
+
+static int
+cp_usb_uart_enable_disable(struct ccdbg *dbg, uint16_t enable)
+{
+ return usb_control_msg(dbg->usb_dev,
+ CP2101_UART,
+ REQTYPE_HOST_TO_DEVICE,
+ enable,
+ 0,
+ NULL,
+ 0,
+ 300);
+}
+
+void
+cp_usb_init(struct ccdbg *dbg)
+{
+ usb_dev_handle *dev_handle;
+ struct usb_device *dev;
+ struct usb_bus *bus, *busses;
+ int interface;
+ int ret;
+ uint8_t gpio;
+
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+
+ busses = usb_get_busses();
+ for (bus = busses; bus; bus = bus->next) {
+ for (dev = bus->devices; dev; dev = dev->next) {
+ if (dev->descriptor.idVendor == 0x10c4 &&
+ dev->descriptor.idProduct == 0xea60)
+ break;
+ }
+ if (dev)
+ break;
+ }
+ if (!dev){
+ perror("No CP2103 found\n");
+ exit(1);
+ }
+ interface = 0;
+ dev_handle = usb_open(dev);
+ usb_detach_kernel_driver_np(dev_handle, interface);
+ usb_claim_interface(dev_handle, interface);
+ dbg->usb_dev = dev_handle;
+ ret = cp_usb_uart_enable_disable(dbg, UART_DISABLE);
+ dbg->gpio = 0xf;
+ ret = cp_usb_gpio_set(dbg, 0xf, dbg->gpio);
+ ret = cp_usb_gpio_get(dbg, &gpio);
+}
+
+void
+cp_usb_fini(struct ccdbg *dbg)
+{
+ cp_usb_uart_enable_disable(dbg, UART_DISABLE);
+ usb_close(dbg->usb_dev);
+}
+
+void
+cp_usb_write(struct ccdbg *dbg, uint8_t mask, uint8_t value)
+{
+ uint8_t new_gpio;
+ int ret;
+
+ new_gpio = (dbg->gpio & ~mask) | (value & mask);
+ if (new_gpio != dbg->gpio) {
+ ret = cp_usb_gpio_set(dbg, new_gpio ^ dbg->gpio, new_gpio);
+ if (ret < 0)
+ perror("gpio_set");
+ dbg->gpio = new_gpio;
+ }
+}
+
+uint8_t
+cp_usb_read(struct ccdbg *dbg)
+{
+ int ret;
+ uint8_t gpio;
+
+ ret = cp_usb_gpio_get(dbg, &gpio);
+ if (ret < 0)
+ perror("gpio_set");
+ return gpio;
+}
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# GET_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# GET_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# GET_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D .
+
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+
+#
+# Ok, we're in debug mode now
+#
+
+#
+# GET_CHIP_ID
+
+#C . R 0
+#. . R
+#C D R 1
+#. D R
+#C D R 1
+#. D R
+#C . R 0
+#. . R
+#
+#C D R 1
+#. D R
+#C . R 0
+#. . R
+#C . R 0
+#. . R
+#C . R 0
+#. . R
+#
+##
+## Read the chip id
+##
+#
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#C D R
+#. D R
+#
+
+#
+# GET_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
--- /dev/null
+#
+# Halt 0x44
+#
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+# status byte
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+#
+# DEBUG_INSTR
+#
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+# MOV 0xfe, 0x02
+
+# 0x75 0x02 0xfe
+
+# 0x75
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+# 0xfe
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+C . R 0
+. . R
+
+# 0x02
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+
+# status byte
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+#
+# DEBUG_INSTR
+#
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+# MOV 0x90, 0xfd
+# 0x75 0xfd 0x90
+
+# 0x75
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+# 0x90
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+# 0xff
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+# status byte
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+#
+# DEBUG_INSTR
+#
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+# MOV 0x90, 0xfd
+# 0x75 0xfd 0x90
+
+# 0x75
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+# 0x90
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+# 0xfd
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C D R 1
+. D R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+# status byte
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# GET_STATUS
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
--- /dev/null
+# reset
+C D R
+C D R
+C D R
+C D R
--- /dev/null
+#
+# Debug mode - drive RESET_N low for two clock cycles
+#
+C D R
+. D .
+C D .
+. D .
+C D .
+. D R
+
+#
+# WR_CONFIG
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C D R 1
+. D R
+C D R 1
+. D R
+C . R 0
+. . R
+C D R 1
+. D R
+
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+
+#
+# RD_CONFIG
+#
+
+C . R 0
+. . R
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+
+C . R 0
+. . R
+C D R 1
+. D R
+C . R 0
+. . R
+C . R 0
+. . R
+
+#
+# Now read for a while
+#
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R
+C D R
+. D R