summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominic Radermacher <blip@mockmoon-cybernetics.ch>2017-07-19 14:08:49 +0200
committerDominic Radermacher <blip@mockmoon-cybernetics.ch>2017-07-19 14:08:49 +0200
commitc57a8a9bf49fa7a3231ce8d6e435603e8ab016eb (patch)
tree6c83a316511a185cc497a4fc2237742417d3c718
initial importv0.9
-rw-r--r--.gitignore5
-rw-r--r--Makefile47
-rw-r--r--fw_src/eepr_read.s32
-rw-r--r--fw_src/eepr_write.s100
-rw-r--r--fw_src/obsolete.c29
-rw-r--r--fw_src/talker.s100
-rw-r--r--fw_src/test.s13
-rw-r--r--include/hc11tools.h36
-rw-r--r--include/s19stuff.h12
-rw-r--r--include/serial.h8
-rw-r--r--include/talker.h19
-rw-r--r--include/tty.h73
-rw-r--r--include/ui.h6
-rw-r--r--src/hc11debug.c379
-rw-r--r--src/hc11eepr.c222
-rw-r--r--src/hc11loader.c120
-rw-r--r--src/s19stuff.c148
-rw-r--r--src/serial.c153
-rw-r--r--src/talker.c182
-rw-r--r--src/tty.c232
-rw-r--r--src/ui.c179
21 files changed, 2095 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2a25522
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+# C-Objects
+*.o
+
+# S19 binaries
+/*.s19
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..3129477
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,47 @@
+# New Makefile 2006-01-23
+# $@ = output file, $< = first input, $+ = all input files
+
+ECHO = /bin/echo -e
+RM = /bin/rm -f
+CC = gcc
+STRIP = strip
+CFLAGS = -g -Os -I./include -Wall -Wstrict-prototypes -Wmissing-prototypes
+CFLAGS += -Wshadow -Wextra -Wunused # -Wconversion
+
+PROGS = hc11loader hc11debug hc11eepr
+
+all: $(PROGS)
+
+clean:
+ $(RM) src/*.o
+tidy:
+ $(RM) src/*.o $(PROGS)
+install: $(PROGS)
+ @$(ECHO) "\t==> Installing nothing"
+pack:
+ @$(ECHO) "Cleaning up ..." ; \
+ $(RM) src/*.o lib/* $(PROGS)
+ @$(ECHO) "Creating package ..." ; \
+ VERSION=`cat include/hc11tools.h |grep VERSION |cut -d"\"" -f2`;\
+ tar Jcvf hc11tools-$$VERSION.txz --directory=.. --exclude=fw_src --exclude=*.s19 hc11tools
+
+# Generic instructions. Don't change.
+src/%.o: src/%.c
+ @printf "\t--> Compiling `basename $<`\n"
+ @$(CC) $(CFLAGS) -c $< -o $@
+
+# Specific programs
+hc11loader: src/hc11loader.o src/serial.o src/s19stuff.o
+ @printf "\t==> Linking objects to output file $@\n"
+ @$(CC) $(CFLAGS) $(LDFLAGS) $+ -o $@
+ @$(STRIP) $@
+
+hc11eepr: src/hc11eepr.o src/serial.o src/s19stuff.o
+ @printf "\t==> Linking objects to output file $@\n"
+ @$(CC) $(CFLAGS) $(LDFLAGS) $+ -o $@
+ @$(STRIP) $@
+
+hc11debug: src/hc11debug.o src/serial.o src/s19stuff.o src/talker.o src/tty.o src/ui.o
+ @printf "\t==> Linking objects to output file $@\n"
+ @$(CC) $(CFLAGS) $(LDFLAGS) $+ -o $@
+ @$(STRIP) $@
diff --git a/fw_src/eepr_read.s b/fw_src/eepr_read.s
new file mode 100644
index 0000000..818208f
--- /dev/null
+++ b/fw_src/eepr_read.s
@@ -0,0 +1,32 @@
+
+RAM equ $0000
+EEPROM equ $b600
+
+REGBASE equ $1000
+BAUD equ $2b ; SCI Baud Rate Control
+SCCR2 equ $2d ; SCI Control Register 2
+SCSR equ $2e ; SCI Status Register
+SCDR equ $2f ; SCI Data Register
+
+ org RAM
+init:
+ lds #$00ff ; init stack pointer
+ ldd #$300c ; A=SCP1|SCP0, B=TE|RE
+ staa REGBASE+BAUD ; 9600 bps
+ stab REGBASE+SCCR2
+main:
+ ldx #EEPROM
+loop1:
+ ldaa 0,X ; read byte
+ jsr sci_txd ; acknowledge byte
+ inx
+ cpx #EEPROM+512
+ bne loop1
+end:
+ wai
+ bra end
+sci_txd:
+ tst REGBASE+SCSR
+ bpl sci_txd ; wait until TDRE bit set
+ staa REGBASE+SCDR
+ rts
diff --git a/fw_src/eepr_write.s b/fw_src/eepr_write.s
new file mode 100644
index 0000000..f2c0509
--- /dev/null
+++ b/fw_src/eepr_write.s
@@ -0,0 +1,100 @@
+
+RAM equ $0000
+EEPROM equ $b600
+EEPSIZE equ 256
+
+REGBASE equ $1000
+BAUD equ $2b ; SCI Baud Rate Control
+SCCR2 equ $2d ; SCI Control Register 2
+SCSR equ $2e ; SCI Status Register
+SCDR equ $2f ; SCI Data Register
+BPROT equ $35 ; EEPROM block protect
+PPROG equ $3b
+
+ org RAM
+init:
+ lds #$00ff ; init stack pointer
+ ldd #$330c ; A=SCP1|SCP0, B=TE|RE
+ staa REGBASE+BAUD ; 1200 bps
+ stab REGBASE+SCCR2
+main:
+ clr REGBASE+BPROT
+ ldx #EEPROM
+loop1:
+ bsr sci_rxd ; receive byte
+ jsr eepr_write ; write accu A to address X
+ bsr sci_txd ; acknowledge byte
+ inx
+ cpx #EEPROM+EEPSIZE
+ beq done
+; ldy #$ffff
+loop2:
+; dey
+; beq done ; timeout -> end of code
+; jsr sci_rx_tst ; byte received?
+; beq loop2
+ bra loop1
+done:
+ ldaa #$1f
+ staa REGBASE+BPROT
+ jmp EEPROM ; execute the program
+sci_rx_tst:
+ ldaa REGBASE+SCSR
+ anda #$20 ; receive buf full?
+ rts ; return 0 if not
+sci_rxd:
+ ldaa REGBASE+SCSR
+ bita #%00001010 ; OV or FE bits set ?
+ bne init
+ anda #%00100000 ; RDRF bit set ?
+ beq sci_rxd
+ ldaa REGBASE+SCDR
+ rts
+sci_txd:
+ tst REGBASE+SCSR
+ bpl sci_txd ; wait until TDRE bit set
+ staa REGBASE+SCDR
+ rts
+
+eepr_write:
+ tab
+ comb
+ orab 0,X
+ bne _eepr_erase_ok
+ ldaa #0e
+ rts
+ ldab #%00010110 ; BYTE=1, ERASE=1, EELAT=1
+; stab PPROG
+ stab 0,X
+ ldab #%00010111 ; BYTE=1, ERASE=1, EELAT=1, EEPGM=1
+; stab PPROG
+ bsr delay10ms
+; clr PPROG
+_eepr_erase_ok:
+ cmpa 0,X
+ beq _eepr_write_ok
+_xx0:
+ ldaa #$01
+ rts
+
+ ldab #%00000010 ; EELAT=1
+ stab REGBASE+PPROG
+ staa 0,X
+ ldab #%00000011 ; EELAT=1, EEPGM=1
+ stab REGBASE+PPROG
+ bsr delay10ms
+ clr REGBASE+PPROG
+ ldaa 0,X ; read back for verifying
+ rts
+_eepr_write_ok:
+ ldaa #0 ; read back for verifying
+ rts
+
+delay10ms: ; 20000 cycles to eat at Eclk=2MHz
+ pshx
+ ldx #3330 ; 3330*6 = 19980 cycles
+_delay_10ms_l0:
+ dex
+ bne _delay_10ms_l0
+ pulx
+ rts
diff --git a/fw_src/obsolete.c b/fw_src/obsolete.c
new file mode 100644
index 0000000..640f514
--- /dev/null
+++ b/fw_src/obsolete.c
@@ -0,0 +1,29 @@
+void dump_obj(struct obj *bo)
+{
+ int i;
+
+ for(i=0; i<(bo->end_addr-bo->start_addr); i++) {
+ printf("%02x ", bo->code[i]);
+ if((i+1)%16 == 0) printf("\n");
+ }
+ printf("\n");
+ return;
+}
+
+byte TalkPgm[256] = {
+0x8e,0x01,0xff,0xce,0x10,0x00,0x6f,0x2c,0xcc,0x30,0x0c,0xa7,0x2b,0xe7,0x2d,0x86,
+0x10,0x06,0x7e,0x00,0x12,0xb6,0x10,0x2e,0x84,0x20,0x27,0xf9,0xb6,0x10,0x2f,0x43,
+0x8d,0x46,0x2a,0x51,0x8d,0x33,0x8f,0x8d,0x30,0x17,0x8d,0x2d,0x8f,0x81,0xfe,0x26,
+0x0d,0xa6,0x00,0x8d,0x33,0x17,0x8d,0x21,0x16,0x08,0x5a,0x26,0xf4,0x3b,0x81,0xbe,
+0x26,0x16,0x17,0x8d,0x14,0xe7,0x00,0x18,0xce,0x00,0x01,0x18,0x09,0x26,0xfc,0xe6,
+0x00,0xf7,0x10,0x2f,0x08,0x4a,0x26,0xeb,0x3b,0xf6,0x10,0x2e,0xc5,0x0a,0x26,0xa0,
+0xc4,0x20,0x27,0xf5,0xf6,0x10,0x2f,0x39,0x18,0x8f,0xb6,0x10,0x2e,0x2a,0xfb,0x18,
+0x8f,0xb7,0x10,0x2f,0x39,0x81,0x7e,0x26,0x0c,0x30,0x8f,0x8d,0xeb,0x17,0x8d,0xe8,
+0x30,0xc6,0x09,0x20,0xac,0x81,0x3e,0x26,0x12,0x8d,0xce,0x17,0x8d,0xcb,0x8f,0x35,
+0x86,0x09,0x20,0xaf,0x86,0x4a,0x8d,0xd0,0x0f,0x20,0xfd,0x81,0x4a,0x26,0xb9,0x30,
+0xc6,0x09,0x3a,0x35,0xec,0x07,0x8d,0xc0,0x17,0x8d,0xbd,0xcc,0x00,0x98,0xed,0x07,
+0x20,0xc7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x7e,0x00,0x15,0x7e,0x00,0x58,0x7e,0x00,0x58,0x7e,0x00,0x58,
+0x7e,0x00,0x58,0x7e,0x00,0x58,0x7e,0x00,0x58,0x7e,0x00,0x58,0x7e,0x00,0x58,0x7e,
+0x00,0x58,0x7e,0x00,0x58,0x7e,0x00,0x58,0x7e,0x00,0x58,0x7e,0x00,0x58,0x7e,0x00,
+0x58,0x7e,0x00,0x58,0x7e,0x00,0x58,0x7e,0x00,0x00,0x7e,0x00,0x58,0x7e,0x00,0x58};
diff --git a/fw_src/talker.s b/fw_src/talker.s
new file mode 100644
index 0000000..0b9b612
--- /dev/null
+++ b/fw_src/talker.s
@@ -0,0 +1,100 @@
+
+******************************************************************************
+******************************************************************************
+
+BAUD equ $102b ; SCI Baud Rate Control
+SCCR2 equ $102d ; SCI Control Register 2
+SCSR equ $102e ; SCI Status Register
+SCDR equ $102f ; SCI Data Register
+
+ org $0000 ; program start
+init:
+ lds #$01ff ; init stack pointer
+ ldd #$330c ; A=SCP1|SCP0, B=TE|RE
+ staa BAUD ; => XX00 bps
+ stab SCCR2
+ ldaa #%10010000
+ tap
+idleloop:
+ bra idleloop
+sci_srv:
+ bsr sci_rxd
+ coma
+ bsr sci_txd
+ bpl hi_command
+ psha
+ bsr sci_rxd
+ tab
+ pula
+ xgdx
+ bsr sci_rxd
+ tab
+ bsr sci_rxd
+ xgdx
+ cmpa #$be
+ bne read_mcu_mem
+write_mcu_mem:
+ bsr sci_rxd
+ staa 0,X
+ inx
+ decb
+ bne write_mcu_mem
+ rti
+hi_command:
+ cmpa #$3e
+ beq write_mcu_regs
+read_mcu_regs:
+ tsx ; SP -> X
+ xgdx ; X <-> D
+ bsr sci_txd
+ tba
+ bsr sci_txd
+ tsx
+ ldab #9
+ bra read_mcu_mem
+write_mcu_regs:
+ bsr sci_rxd
+ tab
+ bsr sci_rxd
+ xgdx
+; txs
+ ldab #9
+ bra write_mcu_mem
+sci_rxd:
+ ldaa SCSR
+ bita #%00001010 ; OV or FE bits set ?
+ bne init
+ anda #%00100000 ; RDRF bit set ?
+ beq sci_rxd
+ ldaa SCDR
+ rts
+sci_txd:
+ tst SCSR
+ bpl sci_txd ; wait until TDRE bit set
+ staa SCDR
+ rts
+swi_srv:
+ ldaa #$4a
+ bsr sci_txd
+ tsx
+ ldd 7,X
+ bsr sci_txd
+ tba
+ bsr sci_txd
+ ldd #idleloop
+ std 7,X
+ ldab #7
+read_mcu_mem:
+ ldaa 0,X
+ bsr sci_txd
+ inx
+ decb
+ bne read_mcu_mem
+ rti
+
+ org $00f1
+ jmp sci_srv ; /XIRQ ** NEEDED **
+ jmp swi_srv ; SWI ** NEEDED **
+ jmp init ; Illegal opcode ** NEEDED **
+ jmp init ; COP-Fail
+ jmp init ; Clock Monitor Fail
diff --git a/fw_src/test.s b/fw_src/test.s
new file mode 100644
index 0000000..524aebc
--- /dev/null
+++ b/fw_src/test.s
@@ -0,0 +1,13 @@
+ org $0100
+blink:
+ ldx #REGBASE
+ bclr PORTA,X #%00010000 ; clear bit 5 of port A -> LED off
+loop_1:
+ inx
+ bne loop_1
+ ldx #REGBASE
+ bset PORTA,X #%00010000 ; set bit 5 of port A -> LED on
+loop_2:
+ dex
+ bne loop_2
+ bra blink
diff --git a/include/hc11tools.h b/include/hc11tools.h
new file mode 100644
index 0000000..34b05c0
--- /dev/null
+++ b/include/hc11tools.h
@@ -0,0 +1,36 @@
+
+#include <stdint.h>
+
+#ifndef _HC11TOOLS_H
+ #define _HC11TOOLS_H
+
+ #define VERSION "0.9"
+
+// #define MAX_CODE_SIZE 1024 /* 68HC11F1 has 1 KByte RAM */
+ #define MAX_CODE_SIZE 65536
+
+ /* -----------------------------------------------------------------
+ Type defs
+ ----------------------------------------------------------------- */
+
+ typedef enum BOOL {false, true} boolean;
+
+ struct mcu {
+ uint16_t devid;
+ uint16_t maskid;
+ };
+ struct mcu_regs {
+ uint8_t a;
+ uint8_t b;
+ uint16_t ix;
+ uint16_t iy;
+ uint16_t sp;
+ uint16_t pc;
+ uint8_t ccr;
+ };
+ struct obj {
+ uint8_t code[MAX_CODE_SIZE];
+ int start_addr;
+ int end_addr;
+ };
+#endif
diff --git a/include/s19stuff.h b/include/s19stuff.h
new file mode 100644
index 0000000..ac7df0b
--- /dev/null
+++ b/include/s19stuff.h
@@ -0,0 +1,12 @@
+
+#include "hc11tools.h"
+
+uint8_t hex2chr(char *s);
+
+void s19_chksum_init(void);
+void s19_chksum_add(uint8_t val);
+uint8_t s19_chksum_get(void);
+
+int f_readline(FILE *f, char *buf, int size);
+int parse_s19_line(struct obj *bo, char *buf);
+int load_s19file(struct obj *bo, char *file);
diff --git a/include/serial.h b/include/serial.h
new file mode 100644
index 0000000..1bd8815
--- /dev/null
+++ b/include/serial.h
@@ -0,0 +1,8 @@
+
+#include "hc11tools.h"
+
+int serial_open(char *device, int speed, int c_flags);
+int serial_setspeed(int fd, int speed);
+int serial_waitrxdata(int fd);
+int serial_rx_empty(int fd);
+int upload_firmware(int fd, struct obj *bo);
diff --git a/include/talker.h b/include/talker.h
new file mode 100644
index 0000000..e84f666
--- /dev/null
+++ b/include/talker.h
@@ -0,0 +1,19 @@
+
+#include <stdio.h>
+#include <unistd.h> /* read(), write() */
+
+#include "hc11tools.h"
+#include "serial.h"
+
+int read_byte(int fd, uint8_t *d);
+int read_word(int fd, uint16_t *d);
+
+int send_command(int fd, uint8_t cmd);
+
+int read_mcu_mem(int fd, uint16_t addr, uint8_t *mem, int len);
+int write_mcu_mem(int fd, uint16_t addr, uint8_t *mem, int len);
+
+int read_mcu_regs(int fd, struct mcu_regs *regs);
+int write_mcu_regs(int fd, struct mcu_regs *regs);
+
+int swi_handler(int fd, struct mcu_regs *regs);
diff --git a/include/tty.h b/include/tty.h
new file mode 100644
index 0000000..6ac924f
--- /dev/null
+++ b/include/tty.h
@@ -0,0 +1,73 @@
+
+/* --------------------------------------------------------------------
+ -------------------------------------------------------------------- */
+
+struct Screen {
+ int width;
+ int height;
+} my_scr;
+
+/* keycodes possibly returned by tty_getkey() */
+#define KEY_ENTER 0x000a
+#define KEY_ESC 0x001b
+#define KEY_BS 0x007f
+#define KEY_DEL 0x0233
+#define KEY_INS 0x0232
+#define KEY_HOME 0x0231
+#define KEY_END 0x0234
+#define KEY_PG_UP 0x0235
+#define KEY_PG_DOWN 0x0236
+#define KEY_C_UP 0x0241
+#define KEY_C_DOWN 0x0242
+#define KEY_C_RIGHT 0x0243
+#define KEY_C_LEFT 0x0244
+#define KEY_BREAK 0x0250
+#define KEY_F1 0x0201
+#define KEY_F2 0x0202
+#define KEY_F3 0x0203
+#define KEY_F4 0x0204
+#define KEY_F5 0x0205
+#define KEY_F6 0x0206
+#define KEY_F7 0x0207
+#define KEY_F8 0x0208
+#define KEY_F9 0x0209
+#define KEY_F10 0x0210
+#define KEY_F11 0x0211
+#define KEY_F12 0x0212
+#define KEY_F13 0x0213
+#define KEY_UNKNOWN 0xff00
+#define KEY_TIMEOUT 0xffff
+
+/* modes for tty_setmode() */
+#define MODE_NORMAL 0
+#define MODE_BOLD 1
+#define MODE_UNDERLINE 4
+#define MODE_BLINK 5
+#define MODE_REVERSE 7
+
+/* colors for use with tty_setcolor() */
+#define COLOR_BLACK 0
+#define COLOR_RED 1
+#define COLOR_GREEN 2
+#define COLOR_YELLOW (COLOR_RED+COLOR_GREEN)
+#define COLOR_BLUE 4
+#define COLOR_VIOLETT (COLOR_RED+COLOR_BLUE)
+#define COLOR_CYAN (COLOR_GREEN+COLOR_BLUE)
+#define COLOR_WHITE (COLOR_RED+COLOR_GREEN+COLOR_BLUE)
+
+int tty_init(void);
+int tty_width(void);
+int tty_height(void);
+int tty_setechomode(int mode);
+int tty_getkey(void);
+void tty_cls(void);
+void tty_clreol(void);
+void tty_savecursorpos(void);
+void tty_restorecursorpos(void);
+void tty_gotoxy(int x, int y);
+int tty_setscrollregion(int from, int to);
+void tty_setmode(int mode);
+void tty_setcolor(int bg, int fg);
+void tty_reset(void);
+
+int _tty_getkeycode(int t);
diff --git a/include/ui.h b/include/ui.h
new file mode 100644
index 0000000..55c53c2
--- /dev/null
+++ b/include/ui.h
@@ -0,0 +1,6 @@
+
+char *ccr_to_string(uint8_t ccr);
+char *ui_enter_cmd(char *str);
+void ui_show_mcu_regs(struct mcu_regs *regs);
+void ui_show_mem(uint16_t addr, uint8_t *mem, int len);
+void ui_show_mcu_type(struct mcu *mymcu);
diff --git a/src/hc11debug.c b/src/hc11debug.c
new file mode 100644
index 0000000..ddb886e
--- /dev/null
+++ b/src/hc11debug.c
@@ -0,0 +1,379 @@
+
+/* --------------------------------------------------------------------
+ hc11debug - Debugger for the Motorola 68HC11
+ Copyright (C) 2004 Dominic Radermacher <dominic.radermacher@gmail.com>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h> /* exit() */
+#include <string.h> /* strcmp() */
+#include <ctype.h> /* isdigit() */
+#include <unistd.h> /* read(), write(), sleep(), tcgetattr() */
+#include <termios.h> /* tcgetattr() */
+#include <fcntl.h> /* open() */
+#include <sys/types.h> /* open() */
+#include <sys/stat.h> /* open() */
+
+#include "hc11tools.h"
+#include "s19stuff.h"
+#include "serial.h"
+#include "talker.h"
+#include "tty.h"
+#include "ui.h"
+
+#define DEFAULT_SERDEV "/dev/ttyUSB0"
+
+/* --------------------------------------------------------------------
+ Function prototypes
+ -------------------------------------------------------------------- */
+
+int f_readline(FILE *f, char *buf, int size);
+void usage(char *progname);
+int is_chardev(char *file);
+int parse_args(int argc, char **argv);
+int load_talker(struct obj *bo);
+
+int parse_cmd(int fd, char *cmd);
+
+boolean any(char *str, char c);
+int arg_val(char *arg);
+
+/* --------------------------------------------------------------------
+ Global variables
+ -------------------------------------------------------------------- */
+
+char *device; /* device where the board is connected to */
+boolean skipload, extmem;
+
+int is_chardev(char *file)
+{
+ struct stat stbuf;
+
+ if(stat(file, &stbuf) == -1) {
+ return -1;
+ }
+ if((stbuf.st_mode & S_IFMT) != S_IFCHR) {
+ return -1;
+ }
+ return 0;
+}
+
+int parse_args(int argc, char **argv)
+{
+ int i;
+ char *p;
+
+ for(i=1; i<argc; i++) {
+ p=argv[i];
+ if(*argv[i] != '-') {
+ break;
+ }
+ p++;
+ if(strcmp(p, "d") == 0) { /* Listing file */
+ device=argv[++i];
+ if(is_chardev(device) != 0) {
+ printf("'%s' is no character device\n", device);
+ usage(argv[0]);
+ }
+ } else if(strcmp(p, "-skipload") == 0) {
+ i++;
+ skipload=true;
+ } else if(strcmp(p, "-extmem") == 0) {
+ extmem=true;
+ } else {
+ usage(argv[0]);
+ }
+ }
+ return i;
+}
+
+char old_talker[] =
+"S12300008e01ffce10006f2ccc300ca72be72d8610067e0012b6102e842027f9b6102f43cb\n"
+"S12300208d462a518d338f8d30178d2d8f81fe260da6008d33178d2116085a26f43b81be19\n"
+"S12300402616178d14e70018ce0001180926fce600f7102f084a26eb3bf6102ec50a26a014\n"
+"S1230060c42027f5f6102f39188fb6102e2afb188fb7102f39817e260c308f8deb178de884\n"
+"S123008030c60920ac813e26128dce178dcb8f35860920af864a8dd00f20fd814a26b9307b\n"
+"S11500a0c6093a35ec078dc0178dbdcc0098ed0720c72c\n";
+
+char old_irqvec[] =
+"S12100c47e00157e00587e00587e00587e00587e00587e00587e00587e00587e005801\n"
+"S12100e27e00587e00587e00587e00587e00587e00587e00587e00007e00587e0058f8\n";
+
+char xx_talk[] =
+"S12300008E01FFCC300CB7102BF7102D86900620FE8D38438D442A19368D3016328F8D2B48\n"
+"S1230020168D288F81BE264E8D21A700085A26F83B813E270C308F8D21178D1E30C609205F\n"
+"S1230040358D08168D058FC60920DDB6102E850A26AE842027F5B6102F397D102E2AFBB7F3\n"
+"S1220060102F39864A8DF330EC078DEE178DEBCC000FED07C607A6008DE0085A26F83B1E\n";
+
+char talk_irqvec[] =
+"S11200F17E00117E00637E00007E00007E000012\n";
+
+int load_talker(struct obj *bo)
+{
+ int i, k;
+
+ bo->start_addr=0xffff;
+ bo->end_addr=0x0000;
+ for(i=0; i<(int)sizeof(bo->code); bo->code[i++]=0);
+ printf("Loading talker code...\n");
+ for(i=0; xx_talk[i] != 0; ) {
+ for(k=i; xx_talk[k] != '\n'; k++);
+ xx_talk[k++]=0;
+ parse_s19_line(bo, &xx_talk[i]);
+ i=k;
+ }
+ printf("Loading IRQ vectors...\n");
+ for(i=0; talk_irqvec[i] != 0; ) {
+ for(k=i; talk_irqvec[k] != '\n'; k++);
+ talk_irqvec[k++]=0;
+ parse_s19_line(bo, &talk_irqvec[i]);
+ i=k;
+ }
+ return 0;
+}
+
+void usage(char *progname)
+{
+ printf("usage: %s [options] <s19-file>\n", progname);
+ printf("\toptions:\n");
+ printf("\t-d <device>\tserial device to use (default: %s)\n", DEFAULT_SERDEV);
+ printf("\t--skipload\tskip bootload process (talker already running)\n");
+ printf("\t--extmem\tenable external bus\n");
+ exit(5);
+}
+
+/*
+ * any --- does str contain c?
+ */
+boolean any(char *str, char c)
+{
+ while(*str != 0) {
+ if(*str++ == c) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/* --------------------------------------------------------------------
+ evaluate the decimal value of the argument.
+ input can be binary %01010011, hexadecimal $0f or decimal 45
+ values
+ -------------------------------------------------------------------- */
+
+int arg_val(char *arg)
+{
+ int val=0;
+
+ if(*arg == '%') { /* binary constant */
+ arg++;
+ while(any("01", *arg) == true) {
+ printf("%s -> %i\n", arg, val);
+ val = (val * 2) + ((*arg++)-'0');
+ }
+ } else if(*arg == '@') { /* octal constant */
+ arg++;
+ while(any("01234567", *arg) == true) {
+ val = (val * 8) + ((*arg++)-'0');
+ }
+ } else if(*arg == '$') { /* hex constant */
+ arg++;
+ while(any("0123456789abcdefABCDEF", *arg) == true) {
+ if(*arg > '9') {
+ val = (val * 16) + 10 + (tolower(*arg++)-'a');
+ } else {
+ val = (val * 16) + ((*arg++)-'0');
+ }
+ }
+ } else if(any("0123456789", *arg) == true) { /* decimal constant */
+ while(*arg >= '0' && *arg <= '9') {
+ val = (val * 10) + ((*arg++)-'0');
+ }
+ } else {
+ printf("error while parsing argument '%s'\n", arg);
+ return 0;
+ }
+ return val;
+}
+
+int parse_cmd(int fd, char *cmd)
+{
+ char *p;
+ uint8_t buf[256];
+ int addr=0, len=0, val=0;
+ struct obj code;
+ struct mcu_regs myregs;
+
+ if(strncmp(cmd, "md ", 3) == 0) {
+ if((p=strchr(cmd+3, ' ')) != NULL) { /* we've got 2 args */
+ *p++=0;
+ len=arg_val(p);
+ if(len > 256) {
+ printf("I would not do that if I where you (hint: md <startaddr> [len])\n");
+ return 0;
+ }
+ } else {
+ len=16;
+ }
+ addr=arg_val(cmd+3);
+ printf("memory dump from addr $%04x (len = %i)\n", addr, len);
+ read_mcu_mem(fd, addr, buf, len);
+ ui_show_mem(addr, buf, len);
+ } else if(strncmp(cmd, "ms ", 3) == 0) {
+ if((p=strchr(cmd+3, ' ')) != NULL) {
+ *p++=0;
+ val=arg_val(p);
+ if(val > 255) {
+ printf("value must be 0 .. 255\n");
+ return 0;
+ }
+ } else {
+ printf("hint: ms <addr> <value>\n");
+ return 0;
+ }
+ addr=arg_val(cmd+3);
+ printf("setting value at addr $%04x to $%02x\n", addr, val);
+ buf[0]=val;
+ write_mcu_mem(fd, addr, buf, 1);
+ } else if(strncmp(cmd, "go ", 3) == 0) {
+ addr=arg_val(cmd+3);
+ printf("Starting program at 0x%04x\n", addr);
+ read_mcu_regs(fd, &myregs);
+ myregs.pc=addr;
+ write_mcu_regs(fd, &myregs);
+ ui_show_mcu_regs(&myregs);
+ } else if(strncmp(cmd, "load ", 5) == 0) {
+ load_s19file(&code, cmd+5); /* load s19 source file */
+ addr=code.start_addr;
+ len=code.end_addr - code.start_addr;
+ if(len > 255) {
+ printf("sorry, currently we can load a maximum of 256 bytes\n");
+ return -1;
+ }
+ printf("Writing %i byte starting from addr $%04x (this may take a while)\n", len, addr);
+ write_mcu_mem(fd, addr, &code.code[addr], len);
+ printf("Done\n");
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int fd, i, k;
+ struct obj bootcode;
+ struct mcu mymcu;
+ struct mcu_regs myregs;
+ char *cmd;
+ uint8_t b;
+ uint8_t buf[16];
+
+ if(argc < 2) {
+ usage(argv[0]);
+ }
+ device=DEFAULT_SERDEV;
+ skipload=false;
+ extmem=false; /* we do not use external bus per default */
+ i=parse_args(argc, argv);
+ if((fd=serial_open(device, B1200, CS8+CLOCAL)) < 0) {
+ fprintf(stderr, "error: can not open '%s'\n", device);
+ return 5;
+ }
+ if(skipload == false) {
+ if(i < argc) {
+ load_s19file(&bootcode, argv[i]); /* load s19 source file */
+ } else {
+ load_talker(&bootcode);
+ }
+ if(bootcode.start_addr != 0) {
+ fprintf(stderr, "error: program must start at address $0000\n");
+ return 1;
+ }
+ if(upload_firmware(fd, &bootcode) != 0) {
+ return 5; /* makes no sense to continue then */
+ }
+ sleep(1);
+ }
+/* if(serial_setspeed(fd, B9600) != 0) {
+ printf("failed to switch switching baudrate\n");
+ exit(5);
+ } */
+ mymcu.devid=0;
+ mymcu.maskid=0;
+ /* try to detect mcu type */
+ read_mcu_mem(fd, 0x103c, buf, 1);
+ /* either 0x0c or 0x0d seems bootstrap mode */
+ b=(buf[0]>>4);
+ if((b & 4) == 4) { /* SMOD=1 - special mode */
+ if((b & 8) == 8) {
+ read_mcu_mem(fd, 0xbfd4, buf, 2);
+ mymcu.devid=(buf[0]<<8)+buf[1];
+ read_mcu_mem(fd, 0xbfd2, buf, 2);
+ mymcu.maskid=(buf[0]<<8)+buf[1];
+ }
+ if((b & 2) == 2) {
+ printf("=> Special Test mode\n");
+ } else {
+ // printf("=> Special Bootstrap mode\n");
+ if(extmem == true) {
+ // printf("enabling external bus\n");
+ buf[0] |= 0x20;
+ // write_mcu_mem(fd, 0x103c, buf, 1);
+ }
+ }
+ }
+ tcflush(fd, TCIOFLUSH);
+ i=0;
+ tty_init();
+ tty_setscrollregion(1, tty_height()-4);
+ tty_gotoxy(1, 1);
+ tty_cls();
+ while((k=tty_getkey()) != KEY_ESC) {
+ ui_show_mcu_type(&mymcu);
+ if(serial_rx_empty(fd) != 0) { /* when NOT empty */
+ read_byte(fd, &b);
+ if(b == 0x4a) { /* SWI */
+ swi_handler(fd, &myregs);
+ } else {
+ printf("trap code %02x\n", b);
+ }
+ }
+ if(k == 's') { /* 's' */
+ printf("Stopping MCU (setting to idle loop)\n");
+ read_mcu_regs(fd, &myregs);
+ myregs.pc=0x000f;
+ write_mcu_regs(fd, &myregs);
+ ui_show_mcu_regs(&myregs);
+ i=0;
+ } else if(k == 'r') { /* r */
+ if(read_mcu_regs(fd, &myregs) == 0) {
+ ui_show_mcu_regs(&myregs);
+ }
+ } else if(k == KEY_ENTER) {
+ cmd=ui_enter_cmd(NULL);
+ parse_cmd(fd, cmd);
+ } else if(k == KEY_TIMEOUT) {
+ if(read_mcu_regs(fd, &myregs) == 0) {
+ ui_show_mcu_regs(&myregs);
+ }
+ } else {
+ printf("keycode %04x counter %i\n", k, i);
+ }
+ i++;
+ }
+ tty_reset();
+ close(fd);
+ return 0;
+}
diff --git a/src/hc11eepr.c b/src/hc11eepr.c
new file mode 100644
index 0000000..411e583
--- /dev/null
+++ b/src/hc11eepr.c
@@ -0,0 +1,222 @@
+
+/* --------------------------------------------------------------------
+ hc11eepr - Read and write S19 binaries from/to the EEPROM of the 68HC11
+
+ Copyright (C) 2004 Dominic Radermacher <dominic.radermacher@gmail.com>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <stdlib.h> /* exit() */
+#include <stdint.h>
+#include <string.h> /* strcmp() */
+#include <ctype.h> /* isdigit() */
+#include <unistd.h> /* read(), write(), sleep(), tcgetattr() */
+#include <termios.h> /* tcgetattr() */
+#include <fcntl.h> /* open() */
+#include <sys/types.h> /* open() */
+#include <sys/stat.h> /* open() */
+
+#include "hc11tools.h"
+#include "s19stuff.h"
+#include "serial.h"
+
+#define DEFAULT_SERDEV "/dev/ttyUSB0"
+#define MODE_UNDEF 0
+#define MODE_READ 1
+#define MODE_WRITE 2
+
+/* --------------------------------------------------------------------
+ Global variables
+ -------------------------------------------------------------------- */
+
+char *device; /* device where the board is connected to */
+char mode;
+
+char fw_code_read[] =
+"S12300008E00FFCC300CB7102BF7102DCEB600A600BD001D088CB80026F53E20FD7D102EA0\n"
+"S10900202AFBB7102F3982\n";
+
+char fw_code_write[] =
+"S11300008E00FFCC330CB7102BF7102D7F1035CE9C\n"
+"S1130010B6008D278D3D8D32088CB700270F18CE82\n"
+"S1130020FFFF18092707BD003527F720E5861FB70E\n"
+"S113003010357EB600B6102E842039B6102E850AEF\n"
+"S113004026BE842027F5B6102F397D102E2AFBB743\n"
+"S1130050102F39371653EA002608C616E700C617CC\n"
+"S11300608D12A100270AC602A700C6038D06A600AA\n"
+"S1100070A60033393CCE0D020926FD3839B7\n";
+
+/* --------------------------------------------------------------------
+ Function prototypes
+ -------------------------------------------------------------------- */
+
+void usage(char *progname);
+int is_chardev(char *file);
+int parse_args(int argc, char **argv);
+int load_talker(struct obj *bo, char *code);
+
+int is_chardev(char *file)
+{
+ struct stat stbuf;
+
+ if(stat(file, &stbuf) == -1) {
+ return -1;
+ }
+ if((stbuf.st_mode & S_IFMT) != S_IFCHR) {
+ return -1;
+ }
+ return 0;
+}
+
+int parse_args(int argc, char **argv)
+{
+ int i;
+ char *p;
+
+ for(i=1; i<argc; i++) {
+ p=argv[i];
+ if(*argv[i] != '-') {
+ break;
+ }
+ p++;
+ if(strcmp(p, "d") == 0) { /* Listing file */
+ device=argv[++i];
+ if(is_chardev(device) != 0) {
+ printf("'%s' is no character device\n", device);
+ usage(argv[0]);
+ }
+ } else if(strcmp(p, "-read") == 0) {
+ mode=MODE_READ;
+ } else if(strcmp(p, "-write") == 0) {
+ mode=MODE_WRITE;
+ } else {
+ usage(argv[0]);
+ }
+ }
+ if(i == argc) { /* no sourcefile argument left ! */
+ usage(argv[0]);
+ }
+ return i;
+}
+
+void usage(char *progname)
+{
+ printf("usage: %s [options] <mode> <s19-file>\n", progname);
+ printf("\toptions:\n");
+ printf("\t-d <device>\tserial device to use (default: %s)\n", DEFAULT_SERDEV);
+ exit(5);
+}
+
+int load_talker(struct obj *bo, char *code)
+{
+ int i, k;
+
+ bo->start_addr=0xffff;
+ bo->end_addr=0x0000;
+ for(i=0; i<(int)sizeof(bo->code); bo->code[i++]=0);
+ for(i=0; code[i] != 0; ) {
+ for(k=i; code[k] != '\n'; k++);
+ code[k++]=0;
+ parse_s19_line(bo, &code[i]);
+ i=k;
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int d, i;
+ struct obj bootcode, eeprdata;
+ uint8_t b;
+
+ if(argc < 2) {
+ usage(argv[0]);
+ }
+ mode=MODE_UNDEF;
+ device=DEFAULT_SERDEV;
+ i=parse_args(argc, argv);
+ if(mode == MODE_READ) {
+ load_talker(&bootcode, fw_code_read);
+ } else if(mode == MODE_WRITE) {
+ load_s19file(&bootcode, "eepr_write.s19");
+ load_s19file(&eeprdata, argv[i]); /* load s19 source file */
+ //if(eeprdata.start_addr != 0xb600) {
+ // printf("this s19 was not intended for EEPROM\n");
+ // exit(5);
+ //}
+ } else {
+ usage(argv[0]);
+ }
+ if(bootcode.start_addr != 0) {
+ fprintf(stderr, "error: program must start at address $0000\n");
+ return 1;
+ }
+ if((d=serial_open(device, B1200, CS8+CLOCAL)) < 0) {
+ fprintf(stderr, "error: can not open '%s'\n", device);
+ return 5;
+ }
+ upload_firmware(d, &bootcode);
+ tcflush(d, TCIOFLUSH);
+ if(mode == MODE_READ) {
+ serial_setspeed(d, B9600);
+ for(i=0xb600; i<=0xb7ff; ) {
+ if((i % 32) == 0) {
+ printf("S123%04X", i);
+ s19_chksum_init();
+ s19_chksum_add(35);
+ s19_chksum_add(i>>8);
+ s19_chksum_add(i&0xff);
+ }
+ if(serial_waitrxdata(d) == 0) {
+ fprintf(stderr, "timeout\n");
+ return 5;
+ }
+ if(read(d, &b, 1) != 1) {
+ fprintf(stderr, "read error\n");
+ return 5;
+ }
+ printf("%02X", b);
+ s19_chksum_add(b);
+ i++;
+ if((i % 32) == 0) {
+ printf("%02X\n", s19_chksum_get());
+ }
+ }
+
+ } else if(mode == MODE_WRITE) {
+ for(i=eeprdata.start_addr; i<=eeprdata.end_addr; ) {
+ tcflush(d, TCIOFLUSH);
+ write(d, &eeprdata.code[i], 1);
+ if(serial_waitrxdata(d) == 0) {
+ fprintf(stderr, "timeout\n");
+ return 5;
+ }
+ if(read(d, &b, 1) != 1) {
+ fprintf(stderr, "read error\n");
+ return 5;
+ }
+ if(eeprdata.code[i] != b) {
+ fprintf(stderr, "error on addr $%04X (wrote: %02X, read: %02X). EEPROM defect?\n",
+ i, eeprdata.code[i], b);
+ exit(5);
+ }
+ i++;
+ }
+ printf("Successfully programmed %i bytes to EEPROM\n",
+ eeprdata.end_addr-eeprdata.start_addr);
+ }
+ close(d);
+ return 0;
+}
diff --git a/src/hc11loader.c b/src/hc11loader.c
new file mode 100644
index 0000000..ebb975c
--- /dev/null
+++ b/src/hc11loader.c
@@ -0,0 +1,120 @@
+
+/* --------------------------------------------------------------------
+ hc11loader - Bootloader for the Motorola 68HC11
+
+ Copyright (C) 2004 Dominic Radermacher <dominic.radermacher@gmail.com>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <stdlib.h> /* exit() */
+#include <string.h> /* strcmp() */
+#include <ctype.h> /* isdigit() */
+#include <unistd.h> /* read(), write(), sleep(), tcgetattr() */
+#include <termios.h> /* tcgetattr() */
+#include <fcntl.h> /* open() */
+#include <sys/types.h> /* open() */
+#include <sys/stat.h> /* open() */
+
+#include "hc11tools.h"
+#include "s19stuff.h"
+#include "serial.h"
+
+#define DEFAULT_SERDEV "/dev/ttyUSB0"
+
+/* --------------------------------------------------------------------
+ Global variables
+ -------------------------------------------------------------------- */
+
+char *device; /* device where the board is connected to */
+
+/* --------------------------------------------------------------------
+ Function prototypes
+ -------------------------------------------------------------------- */
+
+void usage(char *progname);
+int is_chardev(char *file);
+int parse_args(int argc, char **argv);
+
+int is_chardev(char *file)
+{
+ struct stat stbuf;
+
+ if(stat(file, &stbuf) == -1) {
+ return -1;
+ }
+ if((stbuf.st_mode & S_IFMT) != S_IFCHR) {
+ return -1;
+ }
+ return 0;
+}
+
+int parse_args(int argc, char **argv)
+{
+ int i;
+ char *p;
+
+ for(i=1; i<argc; i++) {
+ p=argv[i];
+ if(*argv[i] != '-') {
+ break;
+ }
+ p++;
+ if(strcmp(p, "d") == 0) { /* Listing file */
+ device=argv[++i];
+ if(is_chardev(device) != 0) {
+ printf("'%s' is no character device\n", device);
+ usage(argv[0]);
+ }
+ } else {
+ usage(argv[0]);
+ }
+ }
+ if(i == argc) { /* no sourcefile argument left ! */
+ usage(argv[0]);
+ }
+ return i;
+}
+
+void usage(char *progname)
+{
+ printf("usage: %s [options] <s19-file>\n", progname);
+ printf("\toptions:\n");
+ printf("\t-d <device>\tserial device to use (default: %s)\n", DEFAULT_SERDEV);
+ exit(5);
+}
+
+int main(int argc, char **argv)
+{
+ int d, i;
+ struct obj bootcode;
+
+ if(argc < 2) {
+ usage(argv[0]);
+ }
+ device=DEFAULT_SERDEV;
+ i=parse_args(argc, argv);
+ load_s19file(&bootcode, argv[i]); /* load s19 source file */
+ if(bootcode.start_addr != 0) {
+ fprintf(stderr, "error: program must start at address $0000\n");
+ return 1;
+ }
+ if((d=serial_open(device, B1200, CS8+CLOCAL)) < 0) {
+ fprintf(stderr, "error: can not open '%s'\n", device);
+ return 5;
+ }
+ upload_firmware(d, &bootcode);
+ close(d);
+ return 0;
+}
diff --git a/src/s19stuff.c b/src/s19stuff.c
new file mode 100644
index 0000000..59b39fb
--- /dev/null
+++ b/src/s19stuff.c
@@ -0,0 +1,148 @@
+
+/* --------------------------------------------------------------------
+ Copyright (C) 2004 Dominic Radermacher <dominic.radermacher@gmail.com>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <ctype.h> /* isdigit(), tolower() */
+
+#include "s19stuff.h"
+
+static uint8_t _s19_chksum_val=0;
+
+uint8_t hex2chr(char *s)
+{
+ return( ((isdigit(s[0])?s[0]-'0':tolower(s[0])-'a'+10)<<4)
+ + (isdigit(s[1])?s[1]-'0':tolower(s[1])-'a'+10));
+}
+
+void s19_chksum_init(void)
+{
+ _s19_chksum_val=0;
+}
+
+void s19_chksum_add(uint8_t val)
+{
+ _s19_chksum_val += val;
+}
+
+uint8_t s19_chksum_get(void)
+{
+ return ~_s19_chksum_val;
+}
+
+int parse_s19_line(struct obj *bo, char *buf)
+{
+ int i, len, addr, val;
+
+ if(*buf++ != 'S') {
+ return -1;
+ }
+ s19_chksum_init();
+ val=0;
+ if(*buf == '0') {
+ printf("ignoring S0 record\n");
+ return 0;
+ } else if(*buf == '1') {
+ len=hex2chr(++buf);
+ s19_chksum_add(len);
+ buf+=2;
+ addr=hex2chr(buf);
+ s19_chksum_add(addr);
+ buf+=2;
+ addr=addr<<8;
+ val=hex2chr(buf);
+ s19_chksum_add(val);
+ addr+=val;
+ buf+=2;
+ for(i=0; i<len-3; i++) {
+ val=hex2chr(buf);
+ bo->code[addr+i]=val;
+ s19_chksum_add(val);
+ buf+=2;
+ }
+ val=hex2chr(buf);
+ if(val != s19_chksum_get()) { /* checksum does not match */
+ printf("Invalid checksum for S1 Record: len=%d bytes addr=%04x chk=%02x calc=%02x\n", len, addr, val, s19_chksum_get());
+ }
+ if(bo->start_addr > addr) {
+ bo->start_addr = addr;
+ }
+ if(bo->end_addr < (addr+len-3)) {
+ bo->end_addr = addr+len-3;
+ }
+ } else if((*buf == '2') || (*buf == '3') || (*buf == '7') || (*buf == '8')) {
+ printf("S%c records cant be loaded to the 68HC11 (16 bit adress only)\n", *buf);
+ return -1;
+ } else if(*buf == '5') {
+ printf("S5 record count ignored\n");
+ return 0;
+ } else if(*buf == '9') {
+ printf("S9 record ignored yet\n");
+ return 0;
+ }
+ if(val != s19_chksum_get()) {
+ printf("checksum error (found: %02x, expected: %02x)\n", val, s19_chksum_get());
+ }
+ return 0;
+}
+
+/* --------------------------------------------------------------------
+ Description read from file 'f' to buffer 'd' of size 'size'
+ until either the buffer is full, or \n or EOF is
+ found. return the number of read octets or -1
+ if no octets could be read (EOF)
+ -------------------------------------------------------------------- */
+
+int f_readline(FILE *f, char *buf, int size)
+{
+ int n, c;
+ char *p;
+
+ for(n=0, p=buf; n<size; ) {
+ c=fgetc(f);
+ if(c != EOF) {
+ if(c == '\n') break; /* LF -> stop and terminate */
+ *p++=c;
+ n++;
+ } else {
+ if(n != 0) break; /* line NOT empty -> terminate */
+ return -1; /* else return -1 */
+ }
+ }
+ if(n < size) { /* we have left space to terminate string */
+ *p=0;
+ }
+ return n;
+}
+
+int load_s19file(struct obj *bo, char *file)
+{
+ int i;
+ char buf[515]; /* 'S1' + len (2 chars) + 255*2 + '\0' */
+ FILE *f;
+
+ bo->start_addr=0xffff;
+ bo->end_addr=0x0000;
+ for(i=0; i<(int)sizeof(bo->code); bo->code[i++]=0);
+ if((f=fopen(file, "r")) == NULL) {
+ fprintf(stderr, "cant open file '%s'\n", file);
+ return -1;
+ }
+ while((i=f_readline(f, buf, 515)) != -1) {
+ parse_s19_line(bo, buf);
+ }
+ return 0;
+}
diff --git a/src/serial.c b/src/serial.c
new file mode 100644
index 0000000..53a90a6
--- /dev/null
+++ b/src/serial.c
@@ -0,0 +1,153 @@
+
+/* --------------------------------------------------------------------
+ Copyright (C) 2004 Dominic Radermacher <dominic.radermacher@gmail.com>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <unistd.h> /* tcgetattr, read(), write() */
+#include <termios.h> /* tcgetattr, tcflush() */
+#include <fcntl.h> /* open */
+#include <sys/types.h> /* open */
+#include <sys/stat.h> /* open */
+
+#include "hc11tools.h"
+#include "serial.h"
+
+#define SERBUFSIZE 16
+
+/* --------------------------------------------------------------------
+ Function: serial_open
+ Revision: 20040801 (use this version !)
+ -------------------------------------------------------------------- */
+
+int serial_open(char *device, int speed, int c_flags)
+{
+ int fd;
+ struct termios term;
+
+ if((fd = open(device, O_RDWR)) < 0) {
+ return -1;
+ }
+ if(tcgetattr(fd, &term) < 0) { /* Get current characteristics */
+ return -1;
+ }
+ cfsetispeed(&term, speed);
+ cfsetospeed(&term, speed);
+ cfmakeraw(&term); /* makeraw sets default CS8 */
+ term.c_cflag |= c_flags; /* apply c_flags */
+ if(tcsetattr(fd, TCSANOW, &term) < 0) { /* Now set everything */
+ return -1;
+ }
+ return fd;
+}
+
+int serial_setspeed(int fd, int speed)
+{
+ struct termios term;
+
+ if(tcgetattr(fd, &term) < 0) {
+ perror("tcgetattr");
+ return -1;
+ }
+ if(cfsetispeed(&term, speed) < 0) {
+ perror("cfsetispeed");
+ return -1;
+ }
+ if(cfsetospeed(&term, speed) < 0) {
+ perror("cfsetospeed");
+ return -1;
+ }
+ if(tcsetattr(fd, TCSANOW, &term) < 0) {
+ perror("tcsetattr");
+ return -1;
+ }
+ return 0;
+}
+
+int serial_waitrxdata(int fd)
+{
+ fd_set fds;
+ struct timeval tv;
+
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+ return select(fd+1, &fds, NULL, NULL, &tv);
+}
+
+int serial_rx_empty(int fd)
+{
+ fd_set fds;
+ struct timeval tv;
+
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ tv.tv_sec = 0;
+ tv.tv_usec = 10;
+ return select(fd+1, &fds, NULL, NULL, &tv);
+}
+
+int upload_firmware(int fd, struct obj *bo)
+{
+ int i, size, len, trig;
+ uint8_t buf[1];
+
+ trig=SERBUFSIZE/2;
+
+ tcflush(fd, TCIOFLUSH);
+ printf("Press reset on the HC11 board ... ");
+ fflush(stdout);
+ while(serial_waitrxdata(fd) == 0);
+ printf("ok, got BRK\n");
+ if(read(fd, buf, 1) != 1) {
+ return -1;
+ }
+ sleep(1);
+ printf("Sending upload request code (0xff)\n");
+ buf[0]=0xff;
+ if(write(fd, buf, 1) != 1) { /* send upload code */
+ return -1;
+ }
+ size=bo->end_addr-bo->start_addr;
+ printf("Uploading firmware (%i bytes) ... ", size);
+ fflush(stdout);
+ tcflush(fd, TCIOFLUSH);
+ write(fd, &bo->code[0], SERBUFSIZE);
+ for(i=0; i<size; i++) {
+ if((i > 0) && ((i+trig)%trig == 0)) {
+ len=size-(i+trig);
+ if(len > trig) {
+ len=trig;
+ }
+ write(fd, &bo->code[i+trig], len);
+ }
+ if(serial_waitrxdata(fd) == 0) {
+ fprintf(stderr, "serial.c:138: reply timeout - board not ready ?\n");
+ return -1;
+ }
+ if(read(fd, buf, 1) != 1) {
+ fprintf(stderr, "serial.c:142: read error\n");
+ return -1;
+ }
+ if(buf[0] != bo->code[i]) {
+ fprintf(stderr, "serial.c:146: byte #%i: %02x != %02x\n", i, buf[0], bo->code[i]);
+ return -1;
+ }
+ fflush(stdout);
+ }
+ printf("ok\n");
+ return 0;
+}
diff --git a/src/talker.c b/src/talker.c
new file mode 100644
index 0000000..7f8b93f
--- /dev/null
+++ b/src/talker.c
@@ -0,0 +1,182 @@
+
+/* --------------------------------------------------------------------
+ Copyright (C) 2004 Dominic Radermacher <dominic.radermacher@gmail.com>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <stdint.h> /* uint8_t, uint16_t */
+#include <unistd.h> /* read(), write() */
+#include <termios.h> /* tcflush() */
+
+#include "hc11tools.h"
+#include "serial.h"
+#include "talker.h"
+
+int read_byte(int fd, uint8_t *d)
+{
+ if(serial_waitrxdata(fd) == 0) {
+ return -1;
+ }
+ if(read(fd, d, 1) != 1) {
+ return -1;
+ }
+ return 0;
+}
+
+int read_word(int fd, uint16_t *d)
+{
+ uint8_t a;
+
+ if(read_byte(fd, &a) < 0) {
+ return -1;
+ }
+ *d=(a<<8); /* MSB comes first */
+ if(read_byte(fd, &a) < 0) {
+ return -1;
+ }
+ *d|=a; /* then LSB */
+ return 0;
+}
+
+int send_command(int fd, uint8_t cmd)
+{
+ uint8_t buf[1];
+
+ buf[0]=cmd;
+ if(write(fd, buf, 1) != 1) { /* send command */
+ return -1;
+ }
+ if(serial_waitrxdata(fd) != 0) {
+ if(read(fd, buf, 1) != 1) {
+ return -1;
+ }
+ if(buf[0] != ~(cmd)) { /* reply is complement ? */
+ printf("ERR[%02x!=%02x]\n", buf[0], ~cmd);
+ return -1;
+ }
+ return 0;
+ }
+ fprintf(stderr, "reply timeout\n");
+ return -1;
+}
+
+int read_mcu_mem(int fd, uint16_t addr, uint8_t *data, int len)
+{
+ int i;
+ uint8_t buf[2];
+
+ if((len < 1) || (len > 256)) {
+ return -1;
+ }
+ if(send_command(fd, 0x01) != 0) { /* complement = 0xfe */
+ printf("read_mcu_mem (0x01) failed\n");
+ tcflush(fd, TCIOFLUSH);
+ return -1;
+ }
+ buf[0]=len;
+ write(fd, buf, 1);
+ buf[0]=(addr & 0xff); /* LSB */
+ buf[1]=(addr >> 8); /* MSB */
+ write(fd, buf, 2);
+ for(i=0; i<len; i++) {
+ if(read_byte(fd, &data[i]) != 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int write_mcu_mem(int fd, uint16_t addr, uint8_t *data, int len)
+{
+ int i;
+ uint8_t buf[2];
+
+ if((len < 1) || (len > 256)) {
+ return -1;
+ }
+ if(send_command(fd, 0x41) != 0) { /* complement = 0xbe */
+ printf("write_mcu_mem (0x41) failed\n");
+ tcflush(fd, TCIOFLUSH);
+ return -1;
+ }
+ buf[0]=len;
+ write(fd, buf, 1);
+ buf[0]=(addr & 0xff); /* LSB */
+ buf[1]=(addr >> 8); /* MSB */
+ write(fd, buf, 2);
+ for(i=0; i<len; i++) {
+ write(fd, &data[i], 1);
+ }
+ return 0;
+}
+
+int read_mcu_regs(int fd, struct mcu_regs *regs)
+{
+ if(send_command(fd, 0x81) != 0) { /* complement = 0x7e */
+ printf("read_mcu_regs (0x81) failed\n");
+ tcflush(fd, TCIOFLUSH);
+ return -1;
+ }
+ read_word(fd, &regs->sp);
+ read_byte(fd, &regs->ccr);
+ read_byte(fd, &regs->b);
+ read_byte(fd, &regs->a);
+ read_word(fd, &regs->ix);
+ read_word(fd, &regs->iy);
+ read_word(fd, &regs->pc);
+ return 0;
+}
+
+int write_mcu_regs(int fd, struct mcu_regs *regs)
+{
+ uint8_t buf[10];
+
+ if(send_command(fd, 0xc1) != 0) { /* complement = 0x3e */
+ printf("write_mcu_regs (0xc1) failed\n");
+ tcflush(fd, TCIOFLUSH);
+ return -1;
+ }
+ /* buf[0] = LSB, buf[1] = MSB */
+ buf[0]=(regs->sp & 0xff);
+ buf[1]=(regs->sp >> 8);
+ write(fd, buf, 2); /* Set SP */
+ buf[0]=regs->ccr;
+ buf[1]=regs->b;
+ buf[2]=regs->a;
+ buf[3]=(regs->ix >> 8);
+ buf[4]=(regs->ix & 0xff);
+ buf[5]=(regs->iy >> 8);
+ buf[6]=(regs->iy & 0xff);
+ buf[7]=(regs->pc >> 8);
+ buf[8]=(regs->pc & 0xff);
+ write(fd, buf, 9);
+ return 0;
+}
+
+int swi_handler(int fd, struct mcu_regs *regs)
+{
+ uint16_t pc;
+
+ read_word(fd, &pc);
+ printf("SWI on $%04x\n", pc-1); /* stored PC points to next */
+ regs->pc=pc-1; /* well, will be set to idleloop */
+ read_word(fd, &regs->sp);
+ read_byte(fd, &regs->ccr);
+ read_byte(fd, &regs->b);
+ read_byte(fd, &regs->a);
+ read_word(fd, &regs->ix);
+ read_word(fd, &regs->iy);
+ return 0;
+}
diff --git a/src/tty.c b/src/tty.c
new file mode 100644
index 0000000..0a7b7fc
--- /dev/null
+++ b/src/tty.c
@@ -0,0 +1,232 @@
+
+/* --------------------------------------------------------------------
+ tty code for my 68HC11 devtools project
+
+ Copyright (C) 2004 Dominic Radermacher <dominic.radermacher@gmail.com>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h> /* strncpy() */
+#include <termios.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <sys/types.h>
+
+#include "tty.h"
+
+struct _tty_keyseq_struct {
+ char *seq;
+ int code;
+} tty_keyseqs[] = {
+ {"[[A", KEY_F1}, {"OP ", KEY_F1},
+ {"[[B", KEY_F2}, {"OQ", KEY_F2},
+ {"[[C", KEY_F3}, {"OR", KEY_F3},
+ {"[[D", KEY_F4}, {"OS", KEY_F4},
+ {"[[E", KEY_F5}, {"[15~", KEY_F5},
+ {"[17~", KEY_F6},
+ {"[18~", KEY_F7},
+ {"[19~", KEY_F8},
+ {"[20~", KEY_F9},
+ {"[21~", KEY_F10},
+ {"[23~", KEY_F11},
+ {"[24~", KEY_F12},
+ {"[25~", KEY_F13},
+ {"[A", KEY_C_UP},
+ {"[B", KEY_C_DOWN},
+ {"[C", KEY_C_RIGHT},
+ {"[D", KEY_C_LEFT},
+ {"[2~", KEY_INS},
+ {"[3~", KEY_DEL},
+ {"[1~", KEY_HOME}, {"[H", KEY_HOME},
+ {"[5~", KEY_PG_UP},
+ {"[6~", KEY_PG_DOWN},
+ {"[4~", KEY_END}, {"[F", KEY_END},
+ {"[P", KEY_BREAK},
+ {0, 0}
+};
+
+/* --------------------------------------------------------------------
+ Function : Initialisation of the tty.
+ Input value : Structure of screen.
+ Output value : Structure of screen with height and width
+ -------------------------------------------------------------------- */
+
+int tty_init(void)
+{
+ struct termios tios;
+
+ if(tcgetattr(0, &tios) == 0) {
+ tios.c_lflag &= ~ICANON; /* Turn char buffering off */
+ tios.c_lflag &= ~ECHO; /* Turn char displaying off */
+ tios.c_cflag |= CRTSCTS;
+ if(tcsetattr(0, 0, &tios) != 0) {
+ fprintf(stderr, "TTY Error\n");
+ }
+ }
+ printf("\033[r\033[999;999f\033[6n");
+ scanf("\033[%i;%i", &(my_scr.height), &(my_scr.width));
+ return 0;
+}
+
+int _tty_getkeycode(int t)
+{
+ fd_set fds;
+ struct timeval TimeOut;
+ unsigned char b[1];
+ TimeOut.tv_sec = t;
+ TimeOut.tv_usec = 1000; /* Mikrosekunden !! */
+
+ FD_ZERO(&fds);
+ FD_SET(0, &fds); /* 0 means socket stdin */
+ if(select(1, &fds, NULL, NULL, &TimeOut) != 0) {
+ read(0, b, 1);
+ return 0x0000+b[0];
+ } /* else ... */
+ return KEY_TIMEOUT;
+}
+
+/* ---------------------------------------------------------------------
+ Function : Wait for key until timeout, if a key is pressed
+ return its code.
+ Input value : Timeout in seconds.
+ Output value : 0x00xx, xx=keycode, if normal keycode
+ 0x01xx xx=keycode with ALT modifier
+ 0x02xx xx=special ESC sequence code
+ 0xffff if timeout occurs.
+ --------------------------------------------------------------------- */
+
+int tty_getkey(void)
+{
+ int count, k;
+ char b[8];
+
+ if((k=_tty_getkeycode(1)) == KEY_TIMEOUT) {
+ return KEY_TIMEOUT;
+ } else if(k != 0x1b) {
+ return k;
+ } else {
+ for(count=0; ((k=_tty_getkeycode(0)) != KEY_TIMEOUT); count++) {
+ if(count < 7) {
+ b[count]=(k & 0xff);
+ }
+ }
+ if(count == 0) {
+ return 0x001b;
+ } else if(count == 1) { /* ESC <key> = Alt + <key> */
+ return 0x0100 + b[0];
+ } /* all others must be looked up */
+ for(k=0; tty_keyseqs[k].seq != NULL; k++) {
+ if(strncmp(tty_keyseqs[k].seq, b, count) == 0) {
+ return tty_keyseqs[k].code;
+ }
+ }
+// printf("%i ESC %02x %02x %02x %02x\n", count, b[0], b[1], b[2], b[3]);
+ return KEY_UNKNOWN;
+ }
+}
+
+/* --------------------------------------------------------------------
+ Function : Turns display of chars on or off.
+ Input value : Mode, can be 0 (off) or 1 (on)
+ Output value : None.
+ -------------------------------------------------------------------- */
+
+int tty_setechomode(int mode)
+{
+ struct termios tios;
+
+ if(tcgetattr(0, &tios) != 0) {
+ return -1;
+ }
+ if(mode == 0) {
+ tios.c_lflag &= ~ECHO; /* Char displaying off */
+ } else {
+ tios.c_lflag |= ECHO; /* Char displaying on */
+ }
+ if(tcsetattr(0, 0, &tios) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
+inline int tty_width()
+{
+ return my_scr.width;
+}
+
+inline int tty_height()
+{
+ return my_scr.height;
+}
+
+inline void tty_cls(void)
+{
+ printf("\033[2J");
+}
+
+inline void tty_clreol(void)
+{
+ printf("\033[0K"); /* clear from cursor to end of line */
+}
+
+void tty_gotoxy(int x, int y)
+{
+ if(x < 1) x=1;
+ if(x > my_scr.width) x=my_scr.width;
+ if(y < 1) y=1;
+ if(y > my_scr.height) y=my_scr.height;
+ printf("\033[%i;%if", y, x);
+}
+
+int tty_setscrollregion(int from, int to)
+{
+ if((from < 1) || (from >= my_scr.height) || (to < from) || (to > my_scr.height)) {
+ return -1;
+ }
+ printf("\033[%i;%ir", from, to); /* Set scrolling region */
+ return 0;
+}
+
+void tty_setmode(int mode)
+{
+ printf("\033[%im", mode);
+}
+
+void tty_setcolor(int bg, int fg)
+{
+ if((bg < 0) || (bg > 7) || (fg < 0) || (fg > 7)) {
+ return;
+ }
+ printf("\033[%i;%im", 40+bg, 30+fg);
+}
+
+inline void tty_savecursorpos(void)
+{
+ printf("\0337"); /* Save cursor position */
+}
+
+inline void tty_restorecursorpos(void)
+{
+ printf("\0338"); /* Restore cursor */
+}
+
+void tty_reset(void)
+{
+// tty_setscrollregion(1, my_scr.height);
+ tty_setechomode(1); /* is NOT included in full reset */
+ printf("\033c"); /* Full reset */
+}
diff --git a/src/ui.c b/src/ui.c
new file mode 100644
index 0000000..54b0fbc
--- /dev/null
+++ b/src/ui.c
@@ -0,0 +1,179 @@
+
+/* --------------------------------------------------------------------
+ Copyright (C) 2004 Dominic Radermacher <dominic.radermacher@gmail.com>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h> /* memset() */
+
+#include "hc11tools.h"
+#include "tty.h"
+#include "ui.h"
+
+void show_linebuf(char *s, int offs, int scr_x);
+
+char *ccr_to_string(uint8_t ccr)
+{
+ int i;
+ static char ret[9];
+
+ for(i=0; i<8; i++) {
+ ret[7-i]=((ccr&(1<<i))==(1<<i))?'1':'.';
+ }
+ ret[8]=0;
+ return ret;
+}
+
+void show_linebuf(char *s, int offs, int scr_x)
+{
+ int i;
+
+ tty_gotoxy(1, tty_height());
+ printf("> ");
+ for(i=0; i<scr_x-2; i++) {
+ if(s[offs+i] == 0) break;
+ printf("%c", s[offs+i]);
+ }
+ tty_clreol();
+ return;
+}
+
+char *ui_enter_cmd(char *str)
+{
+ int i=0, k, len;
+ int OffsetX=0; /* Position where we edit LineBuf */
+ int LineX=0; /* Offset where we start to *display* LineBuf */
+ int CursorX=0; /* Where is the Cursor */
+ static char LineBuf[1024];
+
+ tty_setechomode(0);
+ tty_savecursorpos();
+ memset(LineBuf, 0, sizeof(LineBuf));
+ if(str != NULL) {
+ len=strlen(str);
+ memcpy(LineBuf, str, len);
+ } else {
+ len=0;
+ }
+ while(1) {
+ show_linebuf(LineBuf, LineX, tty_width());
+ // tty_statusbar_keyhint("Edit text - ESC=Cancel, ENTER=Ok" , i);
+ tty_gotoxy(CursorX+3, tty_height()); /* Put cursor at right position */
+ fflush(stdout);
+ i=tty_getkey();
+ if(i == KEY_ENTER) { /* RETURN = Save */
+ tty_setechomode(1);
+ tty_restorecursorpos();
+ return LineBuf;
+ } else if(i == KEY_HOME) {
+ OffsetX=0;
+ } else if(i == KEY_END) {
+ OffsetX=len;
+ } else if(i == KEY_C_RIGHT) {
+ if(OffsetX < len) {
+ OffsetX++;
+ }
+ } else if(i == KEY_C_LEFT) {
+ if(OffsetX > 0) {
+ OffsetX--;
+ }
+ } else if(i == KEY_DEL) {
+ if(OffsetX < len) {
+ for(k=OffsetX; k<len; k++) {
+ LineBuf[k]=LineBuf[k+1];
+ }
+ len--;
+ }
+ } else if((i == KEY_BS) || (i == 0x0008)) {
+ if(OffsetX > 0) {
+ for(k=OffsetX; k<len; k++) {
+ LineBuf[k-1]=LineBuf[k];
+ }
+ LineBuf[--len]=0;
+ OffsetX--;
+ }
+ } else if((i>31) && (i<127)) {
+ if(OffsetX < (int)(sizeof(LineBuf)-1)) {
+ LineBuf[OffsetX]=i;
+ OffsetX++;
+ len++;
+ }
+ } else if((i==0xfc)||(i==0xf6)||(i==0xe4)||(i==0xdc)||(i==0xd6)||(i==0xc4)||(i==0xdf)) {
+ if(OffsetX < (int)(sizeof(LineBuf)-1)) {
+ LineBuf[OffsetX]=i;
+ OffsetX++;
+ len++;
+ }
+ }
+ if(OffsetX < tty_width()) { /* Now calculate LineX and CursorX */
+ if(OffsetX < (tty_width()/2)) {
+ LineX=0;
+ }
+ CursorX=OffsetX-LineX;
+ } else {
+ k = (tty_width() / 2);
+ LineX=((OffsetX / k)-1)*k;
+ CursorX=OffsetX-LineX;
+ }
+ }
+ return NULL;
+}
+
+void ui_show_mcu_regs(struct mcu_regs *regs)
+{
+ int i;
+
+ tty_savecursorpos();
+ tty_gotoxy(1, tty_height()-3);
+ printf("\033[7m"); /* Set cursor and inverse */
+ printf("PC A B IX IY CCR (SXHINZVC) SP");
+ for(i=48; i<tty_width()-6; i++) {
+ printf(" ");
+ }
+ tty_gotoxy(1, tty_height()-2);
+ printf("\033[0m"); /* Set normal */
+ printf("$%04X $%02X $%02X $%04X $%04X $%02X %%%s $%04X",
+ regs->pc, regs->a, regs->b, regs->ix, regs->iy,
+ regs->ccr, ccr_to_string(regs->ccr), regs->sp);
+ tty_restorecursorpos();
+ fflush(stdout);
+ return;
+}
+
+void ui_show_mcu_type(struct mcu *mymcu)
+{
+ tty_savecursorpos();
+ tty_gotoxy(tty_width()-10, tty_height()-3);
+ printf("\033[7m"); /* Set cursor and inverse */
+ printf("MCU = $%04X", mymcu->devid);
+ printf("\033[0m"); /* Set normal */
+ tty_restorecursorpos();
+ fflush(stdout);
+ return;
+}
+
+void ui_show_mem(uint16_t addr, uint8_t *mem, int len)
+{
+ int i;
+
+ for(i=0; i<len; i++) {
+ if(i%16 == 0) printf("%04x:", addr+i);
+ printf("%02x ", mem[i]);
+ fflush(stdout);
+ if((i+1)%16 == 0) printf("\n");
+ }
+ printf("\n");
+ return;
+}