📄 xstormy16_stub.c
字号:
{ unsigned char *buffer = &remcomBuffer[0]; unsigned checksum; int count; char ch; while (1) { /* wait around for the start character, ignore all other characters */ while (getDebugChar () != '$') ; checksum = 0; count = 0; while ((ch = getDebugChar ()) == '$') ; /* now, read until a # or end of buffer is found */ while (ch != '#' && count < BUFMAX - 1) { checksum = checksum + ch; buffer[count] = ch; count = count + 1; ch = getDebugChar (); } buffer[count] = 0; if (ch == '#') { unsigned xmitcsum; ch = getDebugChar (); xmitcsum = hex (ch) << 4; ch = getDebugChar (); xmitcsum += hex (ch); /* If one of the above 'hex' calls returns -1, xmitcsum will have high bits set, and so the test below will fail. */ if ((checksum & 0xFF) != xmitcsum) putDebugChar ('-'); /* failed checksum */ else { putDebugChar ('+'); /* successful transfer */ return &buffer[0]; } } }}/* send the packet in buffer. */static void putPacket (unsigned char *buffer_p){ /* $<packet info>#<checksum>. */ do { unsigned checksum; unsigned char *buffer = buffer_p; putDebugChar('$'); checksum = 0; while (*buffer) { putDebugChar(*buffer); checksum += *buffer; buffer++; } putDebugChar('#'); putDebugChar(hexchars[(checksum >> 4) % 16]); putDebugChar(hexchars[checksum % 16]); } while (getDebugChar() != '+');}/* Convert the memory pointed to by mem into hex, and return it as a packet. */static voidputHex (char c, unsigned long mem_arg, int count){ do { unsigned long mem = mem_arg; int i; unsigned checksum; putDebugChar('$'); checksum = 0; if (c) { checksum = c; putDebugChar(c); } for (i = 0; i < count; i++) { unsigned char c = get_char (mem); char ch = hexchars[c >> 4]; putDebugChar(ch); checksum += ch; ch = hexchars[c % 16]; putDebugChar(ch); checksum += ch; mem++; } putDebugChar('#'); putDebugChar(hexchars[(checksum >> 4) % 16]); putDebugChar(hexchars[checksum % 16]); } while (getDebugChar() != '+');}/* Function: gdb_write(char *, int) Make gdb write n bytes to stdout (not assumed to be null-terminated). */ voidgdb_write (char *data, int len){ ERR_DETECT_REG &= ~SER0_IRQ_ENA; putHex ('O', (unsigned long)(unsigned int)data, len); ERR_DETECT_REG |= SER0_IRQ_ENA;}intgdb_read (char *buf, int nbytes){ int i = 0; ERR_DETECT_REG &= ~SER0_IRQ_ENA; for (i = 0; i < nbytes; i++) { *(buf + i) = getDebugChar(); if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { (*(buf + i + 1)) = 0; break; } } ERR_DETECT_REG |= SER0_IRQ_ENA; return (i);}static intvalid_addr_range (unsigned long mem, int count){ unsigned long last = mem + count - 1; if (last < 0x800L) return 1; if (mem < 0x7f00L) return 0; if (last > 0x7ffffL) return 0; return 1;}/* Convert the hex array pointed to by buf into binary to be placed in mem. Return a pointer to the character AFTER the last byte written. */static voidhex2mem (unsigned char *buf, unsigned long mem, int count){ int i; unsigned char ch; for (i=0;i<count;i++) { ch = hex(*buf++) << 4; ch = ch + hex(*buf++); set_char (mem++, ch); }}/**********************************************//* WHILE WE FIND NICE HEX CHARS, BUILD AN INT *//* RETURN NUMBER OF CHARS PROCESSED *//**********************************************/static int hexToInt (unsigned char **ptr, long *intValue){ int numChars = 0; int hexValue; *intValue = 0; while (**ptr) { hexValue = hex(**ptr); if (hexValue >=0) { *intValue = (*intValue <<4) | (unsigned) hexValue; numChars ++; } else break; (*ptr)++; } return (numChars);}/* Function: opcode_size Determine number of bytes in full opcode by examining first word.*/static intopcode_size(unsigned int opcode){ if ((opcode & 0xff00) == 0) return 2; if ((opcode & 0xf800) == 0) return 4; if ((opcode & 0xf800) == 0x7800) return 4; if ((opcode & 0xf000) == 0xc000) return 4; if ((opcode & 0xf100) == 0x2000) return 4; if ((opcode & 0xfff0) == 0x30e0) return 4; if ((opcode & 0xf008) == 0x6008) return 4; if ((opcode & 0xf808) == 0x7008) return 4; opcode >>= 8; if (opcode == 0x0c || opcode == 0x0d || opcode == 0x31) return 4; return 2;}static struct { unsigned long addr; unsigned long addr2; unsigned int opcode; unsigned int opcode2;} stepinfo;/* Function: prepare_to_step Called from handle_exception to prepare the user program to single-step. Places a trap instruction after the target instruction, with special extra handling for branch instructions.*/static voidprepare_to_step(void){ unsigned long pc = registers.pc; unsigned long next_pc, next_pc2; unsigned int op, op2, sp; unsigned char op_msb, op_lsb; int r12; char r8; op = get_word(pc); op_msb = (op >> 8) & 0xff; op_lsb = op & 0xff; op2 = get_word(pc + 2); next_pc = pc + opcode_size(op); next_pc2 = 0; if (op_msb == 0) { if (op_lsb == 2) { /* IRET */ sp = registers.r[SP]; next_pc = *(unsigned *)(sp - 4); next_pc = (next_pc << 16) | *(unsigned *)(sp - 6); } else if (op_lsb == 3) { /* RET */ sp = registers.r[SP]; next_pc = *(unsigned *)(sp - 2); next_pc = (next_pc << 16) | *(unsigned *)(sp - 4); } else { op2 = op_lsb & 0xf0; if (op2 && op2 < 0x40) { /* {CALLR,BR,ICALLR} Rs */ next_pc = (pc + 2) + (int)registers.r[op_lsb & 0xf]; } else if (op2 < 0x80 || op2 == 0xa0 || op2 == 0xb0) { /* {JMP,ICALL,CALL} Rb,Rs */ next_pc = registers.r[(op_lsb & 0x10) ? 9 : 8]; next_pc = (next_pc << 16) | (unsigned int)registers.r[op_lsb & 0xf]; } } } else if (op_msb < 4) { /* {CALLF,JMPF,ICALLF} a24 */ next_pc = ((unsigned long)op2) << 8; next_pc |= op_lsb; } else if (op_msb < 8) { if ((op2 & 0xf000) == 0) { /* Bx Rd,#imm4,r12 */ /* Bx Rd,Rs,r12 */ r12 = op2 << 4; r12 >>= 4; next_pc2 = (pc + 4) + r12; } } else if (op_msb == 0x0c || op_msb == 0x0d || (op_msb & 0xf1) == 0x20 || ((op_msb >= 0x7c && op_msb <= 0x7f) && (op2 & 0x8000) == 0)) { /* Bxx Rd,Rs,r12 */ /* Bxx Rd,#imm8,r12 */ /* Bx m8,#imm3,r12 */ /* Bx s8,#imm3,r12 */ r12 = op2 << 4; r12 >>= 4; next_pc2 = (pc + 4) + r12; } else if ((op_msb & 0xf0) == 0x10) { /* {BR,CALLR} r12 */ r12 = (op & 0xffe) << 4; r12 >>= 4; next_pc = (pc + 2) + r12; } else if ((op_msb & 0xe0) == 0xc0) { /* Bxx Rx,#imm16,r8 */ /* TBxx r8 */ r8 = op_lsb; next_pc2 = next_pc + r8; } stepinfo.addr = next_pc; stepinfo.opcode = get_word(next_pc); set_word(next_pc, BREAKPOINT_OPCODE); if (next_pc2) { stepinfo.addr2 = next_pc2; stepinfo.opcode2 = get_word(next_pc2); set_word(next_pc2, BREAKPOINT_OPCODE); }}/* Function: finish_from_step Called from handle_exception to finish up when the user program returns from a single-step. Replaces the instructions that had been overwritten by breakpoint. */static voidfinish_from_step (void){ if (stepinfo.addr) /* anything to do? */ { set_word(stepinfo.addr, stepinfo.opcode); stepinfo.addr = 0; if (stepinfo.addr2) { set_word(stepinfo.addr2, stepinfo.opcode2); stepinfo.addr2 = 0; } }}/* * UART support */#define UART0_BASE 0x7f38#define UART1_BASE 0x7f48#define UART_CR(base) (*(volatile unsigned char *)(base))#define UART_RXD(base) (*(volatile unsigned int *)((base) + 2))#define UART_TXD(base) (*(volatile unsigned int *)((base) + 4))#define UART_CR_RUN 0x80#define UART_CR_ERR 0x40#define UART_CR_BAUD_115k 0x20#define UART_CR_PARITY 0x10#define UART_CR_TXEMPTY 0x08#define UART_CR_TXIEN 0x04#define UART_CR_RXRDY 0x02#define UART_CR_RXIEN 0x01#define DBG_UART UART0_BASEstatic voidputDebugChar(unsigned ch){ while ((UART_CR(DBG_UART) & UART_CR_TXEMPTY) == 0) ; UART_TXD(DBG_UART) = ch;}static unsigned chargetDebugChar(void){ while ((UART_CR(DBG_UART) & UART_CR_RXRDY) == 0) ; return UART_RXD(DBG_UART);}voiduart_init(void){ UART_CR(DBG_UART) |= (UART_CR_RUN | UART_CR_RXIEN);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -