├── fpga ├── novena_fpga-1.22.bit ├── fpga-config.sh ├── devmem2.c └── novena-fpga.c ├── .gitignore ├── src ├── ax215 │ ├── crc-16.h │ ├── Makefile │ ├── gpio.h │ ├── disasm-mnem.h │ ├── eim.h │ ├── sd.h │ ├── gpio.c │ ├── fuzz.c │ ├── crc-16.c │ ├── main.c │ ├── eim.c │ ├── disasm-mnem.c │ ├── execute.c │ └── disasm.c └── as31 │ ├── Makefile │ ├── as31.c │ ├── run.c │ ├── parser.h │ ├── as31.h │ ├── as31_gtk.c │ ├── lexer.c │ └── symbol.c ├── progs ├── fuzzer.asm ├── blink-led-ax215.asm ├── blink-led.asm ├── dump-rom.asm ├── TestBoot.asm ├── debugger.asm └── romdump.asm ├── Makefile ├── README.md ├── doc └── ax215.md └── tests ├── extra.ref └── paulmon2.ref /fpga/novena_fpga-1.22.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xobs/ax2xx-code/HEAD/fpga/novena_fpga-1.22.bit -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.bin 3 | 4 | *.swp 5 | *.swo 6 | 7 | /as31 8 | as31.1 9 | 10 | /ax211 11 | -------------------------------------------------------------------------------- /src/ax215/crc-16.h: -------------------------------------------------------------------------------- 1 | #ifndef __CRC16_H__ 2 | #define __CRC16_H__ 3 | #include 4 | uint16_t crc16(void *data_p, uint16_t length); 5 | uint8_t crc7(const uint8_t *buffer, size_t len); 6 | uint32_t crc32(const void *buf, int size); 7 | 8 | #endif // __CRC16_H__ 9 | -------------------------------------------------------------------------------- /src/ax215/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=gpio.c sd.c main.c crc-16.c eim.c debugger.c \ 2 | disasm.c disasm-mnem.c fuzz.c execute.c 3 | OBJECTS=$(SOURCES:.c=.o) 4 | EXEC=../../ax215 5 | MY_CFLAGS += -Wall -O0 -g 6 | MY_LIBS += -lreadline 7 | 8 | all: $(OBJECTS) 9 | $(CC) $(LIBS) $(LDFLAGS) $(OBJECTS) $(MY_LIBS) -o $(EXEC) 10 | 11 | clean: 12 | rm -f $(EXEC) $(OBJECTS) 13 | 14 | .c.o: 15 | $(CC) -c $(CFLAGS) $(MY_CFLAGS) $< -o $@ 16 | 17 | -------------------------------------------------------------------------------- /src/ax215/gpio.h: -------------------------------------------------------------------------------- 1 | #ifndef __GPIO_H__ 2 | #define __GPIO_H__ 3 | 4 | #define GPIO_IS_EIM (0x80000000) 5 | 6 | enum gpio_dir { 7 | GPIO_IN = 0, 8 | GPIO_OUT = 1, 9 | }; 10 | 11 | int gpio_export(int gpio); 12 | int gpio_unexport(int gpio); 13 | int gpio_set_direction(int gpio, int is_output); 14 | int gpio_set_value(int gpio, int value); 15 | int gpio_get_value(int gpio); 16 | 17 | 18 | int eim_set_direction(int gpio, int is_output); 19 | int eim_set_value(int gpio, int value); 20 | int eim_get_value(int gpio); 21 | #endif /* __GPIO_H__ */ 22 | -------------------------------------------------------------------------------- /fpga/fpga-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ -z $1 ] 3 | then 4 | echo "Usage: $0 [fpga-file]" 5 | exit 1 6 | fi 7 | 8 | bitfile=$1 9 | 10 | echo "Setting export of reset pin" 11 | echo 135 > /sys/class/gpio/export 2> /dev/null 12 | echo "setting reset pin to out" 13 | echo out > /sys/class/gpio/gpio135/direction 2> /dev/null 14 | echo "flipping reset" 15 | echo 0 > /sys/class/gpio/gpio135/value 2> /dev/null 16 | echo 1 > /sys/class/gpio/gpio135/value 2> /dev/null 17 | 18 | echo "configuring FPGA" 19 | 20 | dd if=${bitfile} of=/dev/spidev2.0 bs=128 21 | 22 | echo "turning on clock to FPGA" 23 | devmem2 0x020c8160 w 0x00000D2B 24 | -------------------------------------------------------------------------------- /progs/fuzzer.asm: -------------------------------------------------------------------------------- 1 | .org 0x7b00 2 | 3 | ; This gets called from an interrupt. 4 | start: 5 | .db 0xa5, 0x00, 0x00 6 | .db 0xa5, 0x01, 0x01 7 | .db 0xa5, 0x02, 0x02 8 | .db 0xa5, 0x03, 0x03 9 | .db 0xa5, 0x04, 0x04 10 | .db 0xa5, 0x05, 0x05 11 | .db 0xa5, 0x06, 0x06 12 | .db 0xa5, 0x07, 0x07 13 | mov R2, #0 14 | mov R3, #3 15 | ; mov R4, #0 16 | nop 17 | nop 18 | top_of_pause1: 19 | djnz R2, top_of_pause1 20 | djnz R3, top_of_pause1 21 | ; djnz R4, top_of_pause1 22 | nop 23 | nop 24 | 25 | anti_start: 26 | .db 0xa5, 0x80, 0x80 27 | .db 0xa5, 0x81, 0x81 28 | .db 0xa5, 0x82, 0x82 29 | .db 0xa5, 0x83, 0x83 30 | .db 0xa5, 0x84, 0x84 31 | .db 0xa5, 0x85, 0x85 32 | .db 0xa5, 0x86, 0x86 33 | .db 0xa5, 0x87, 0x87 34 | mov R2, #0 35 | mov R3, #3 36 | ; mov R4, #0 37 | nop 38 | nop 39 | top_of_pause2: 40 | djnz R2, top_of_pause2 41 | djnz R3, top_of_pause2 42 | ; djnz R4, top_of_pause2 43 | nop 44 | nop 45 | sjmp start 46 | -------------------------------------------------------------------------------- /src/ax215/disasm-mnem.h: -------------------------------------------------------------------------------- 1 | /* global.h 2 | * 3 | * Data shared by all modules 4 | * 5 | * Copyright 2001, 2002 by David Sullins 6 | * 7 | * This file is part of Dis51. 8 | * 9 | * Dis51 is free software; you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, version 2 of the License. 12 | * 13 | * Dis51 is distributed in the hope that it will be useful, but WITHOUT ANY 14 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * Dis51; if not, write to the Free Software Foundation, Inc., 59 Temple 20 | * Place, Suite 330, Boston, MA 02111-1307 USA 21 | * 22 | * You may contact the author at davesullins@earthlink.net. 23 | */ 24 | 25 | #ifndef _GLOBAL_H_ 26 | #define _GLOBAL_H_ 27 | 28 | /* global data */ 29 | extern int Lst; 30 | extern unsigned short lbl[65536]; 31 | extern const char mnemonic[256][20]; 32 | extern const char op_format[256]; 33 | extern const char sfrname[128][5]; 34 | extern const char sfbitname[128][6]; 35 | 36 | #endif /* _GLOBAL_H_ */ 37 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # as31 - 8031/8051 Assembler 2 | # 3 | # Maintained at: http://www.pjrc.com/tech/8051/ 4 | # Please report problems to: paul@pjrc.com 5 | # 6 | # 7 | # REVISION HISTORY: 8 | # Jan. 19, 1990 Created. (Ken Stauffer). 9 | # Jan. 30, 1990 Theo played here. 10 | # Late 1994 Paul Stoffregen updates the code 11 | # Sept 1995 bug fixes, add obsure option for cgi 12 | # April 2000 fix filename handling 13 | # convert everything to ANSI C and bison 14 | # properly handle 0b0h as hex 0xB0, not binary 0 15 | # Make most errors into warning, and modify parser 16 | # to recover and continue to the end of the file 17 | # so that all warning are shown. 18 | # March 2001 fix crash with srecord format 19 | # command line version returns non-zero on error 20 | 21 | 22 | #Use this CFLAGS line with gcc on linux 23 | CFLAGS=-O3 -Wall 24 | CC=gcc 25 | 26 | PROGRAM_SOURCES=A5TestBoot.bin TestBoot.bin dump-rom.bin blink-led.bin \ 27 | debugger.bin fuzzer.bin blink-led-ax215.bin romdump.bin 28 | PROGRAMS=$(PROGRAM_SOURCES:.asm=.bin) 29 | 30 | DBG_OFFSET=18176 31 | 32 | all: as31 ax215 $(PROGRAMS) 33 | 34 | as31: src/as31 35 | +make -C src/as31 36 | 37 | ax215: src/ax215 38 | +make -C src/ax215 39 | 40 | %.bin: progs/%.asm as31 41 | ./as31 -Fbin $< 42 | @mv progs/$@ tmp.bin 43 | @dd if=tmp.bin of=$@ bs=$(DBG_OFFSET) skip=1 2> /dev/null 44 | @rm -f tmp.bin 45 | 46 | clean: 47 | make -C src/ax215 clean 48 | make -C src/as31 clean 49 | rm -f TestBoot.bin dump-rom.bin blink-led.bin 50 | -------------------------------------------------------------------------------- /src/as31/Makefile: -------------------------------------------------------------------------------- 1 | # as31 - 8031/8051 Assembler 2 | # 3 | # Maintained at: http://www.pjrc.com/tech/8051/ 4 | # Please report problems to: paul@pjrc.com 5 | # 6 | # 7 | # REVISION HISTORY: 8 | # Jan. 19, 1990 Created. (Ken Stauffer). 9 | # Jan. 30, 1990 Theo played here. 10 | # Late 1994 Paul Stoffregen updates the code 11 | # Sept 1995 bug fixes, add obsure option for cgi 12 | # April 2000 fix filename handling 13 | # convert everything to ANSI C and bison 14 | # properly handle 0b0h as hex 0xB0, not binary 0 15 | # Make most errors into warning, and modify parser 16 | # to recover and continue to the end of the file 17 | # so that all warning are shown. 18 | # March 2001 fix crash with srecord format 19 | # command line version returns non-zero on error 20 | 21 | 22 | #Use this CFLAGS line with gcc on linux 23 | CFLAGS=-O3 -Wall 24 | CC=gcc 25 | 26 | #Use this CFLAGS line on solaris, etc 27 | #CFLAGS=-O 28 | 29 | #Try these for HPUX 30 | #CFLAGS=-O2 31 | #CC=gcc 32 | 33 | OBJ=run.o lexer.o parser.o symbol.o emitter.o 34 | 35 | all: ../../as31 36 | 37 | ../../as31: $(OBJ) as31.o 38 | $(CC) $(CFLAGS) -o ../../as31 $(OBJ) as31.o 39 | chmod a+rx ../../as31 40 | strip ../../as31 41 | 42 | as31_gtk: $(OBJ) as31_gtk.o 43 | $(CC) $(CFLAGS) -o as31_gtk $(OBJ) as31_gtk.o `gtk-config --libs` 44 | chmod a+rx as31 45 | strip as31 46 | 47 | as31_gtk.o: as31_gtk.c as31.h 48 | $(CC) $(CFLAGS) `gtk-config --cflags` -c as31_gtk.c 49 | 50 | as31.o: as31.c as31.h 51 | emitter.o: emitter.c as31.h 52 | symbol.o: symbol.c as31.h parser.h 53 | lexer.o: lexer.c as31.h parser.h 54 | parser.o: parser.c as31.h 55 | run.o: run.c as31.h 56 | 57 | clean: 58 | rm -f ../../as31 as31.1 as31_gtk *~ *.o core 59 | rm -f *.lst *.hex *.tdr *.byte *.od *.srec 60 | -------------------------------------------------------------------------------- /progs/blink-led-ax215.asm: -------------------------------------------------------------------------------- 1 | .equ IEN0, 0xA8 2 | 3 | .equ RESET, 0 4 | 5 | .equ reg1, 0xef 6 | .equ reg2, 0x99 7 | .equ reg3, 0xb4 8 | .equ reg4, 0x84 9 | 10 | .equ sleep1, 0 11 | .equ sleep2, 128 12 | .equ sleep3, 1 13 | 14 | .org 0x7b00 15 | 16 | ; This gets called from an interrupt. 17 | ;start: 18 | ; anl 0x80, #0xFE 19 | ; orl 0x80, #2 20 | ; pop PSW ; Program Status Word 21 | ; pop ACC ; Accumulator 22 | ; mov A, #0x20 ; '2' 23 | ; push ACC ; Accumulator 24 | ; mov A, #0x7b ; ')' 25 | ; push ACC ; Accumulator 26 | ; reti 27 | ;; --------------------------------------------------------------------------- 28 | ;.org 0x7b20 29 | ; mov IEN0, #0 ; Interrupt Enable Register 0 30 | ; mov SP, #0x80 ; Stack Pointer 31 | 32 | 33 | start: 34 | mov reg1, #0x00 35 | ; mov reg2, #0x6f 36 | ; mov reg3, #0xe5 37 | ; mov reg4, #0x7d 38 | 39 | pause_a_while1: 40 | mov R2, #sleep1 41 | mov R3, #sleep2 42 | mov R4, #sleep3 43 | top_of_pause1: 44 | djnz R2, top_of_pause1 45 | djnz R3, top_of_pause1 46 | djnz R4, top_of_pause1 47 | 48 | 49 | mov reg1, #0xff 50 | ; mov reg2, #0xc7 51 | ; mov reg3, #0x7f 52 | ; mov reg4, #0x3d 53 | 54 | pause_a_while2: 55 | mov R2, #sleep1 56 | mov R3, #sleep2 57 | mov R4, #sleep3 58 | top_of_pause2: 59 | djnz R2, top_of_pause2 60 | djnz R3, top_of_pause2 61 | djnz R4, top_of_pause2 62 | 63 | 64 | sjmp start 65 | -------------------------------------------------------------------------------- /src/as31/as31.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * FILE: main.c 3 | * PACKAGE: as31 - 8031/8051 Assembler. 4 | * 5 | * DESCRIPTION: 6 | * The file contains main(). It handles the arguments and makes 7 | * sure that pass 1 is done before pass 2 etc... 8 | * 9 | * REVISION HISTORY: 10 | * Jan. 19, 1990 - Created. (Ken Stauffer) 11 | * 12 | * AUTHOR: 13 | * All code in this file written by Ken Stauffer (University of Calgary). 14 | * January, 1990. "Written by: Ken Stauffer" 15 | * 16 | * March, 2001, Paul Stoffregen: see Makefile for details 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "as31.h" 24 | 25 | 26 | 27 | int main(int argc, char **argv) 28 | { 29 | char *dashF=NULL, *dashA=NULL; 30 | int use_stdout=0, do_lst=0; 31 | int r, i; 32 | 33 | fprintf(stderr, "AS31 2.0b3 (beta), March 20, 2001\n"); 34 | fprintf(stderr, "Please report problems to: paul@pjrc.com\n\n"); 35 | 36 | 37 | if (argc < 2) { 38 | fprintf(stderr, 39 | "Usage: %s [-l] [-s] [-Ffmt] [-Aarg] file.asm\n", 40 | argv[0]); 41 | fprintf(stderr, "\t -l : create list file\n"); 42 | fprintf(stderr, "\t -s : send output to stdout\n"); 43 | fprintf(stderr, "\t -F : output format (intel hex default)\n"); 44 | fprintf(stderr, "\t -A : optional output format argument\n"); 45 | emitusage(); 46 | exit(1); 47 | } 48 | 49 | for (i=1; i 4 | 5 | 6 | enum sd_r1_states { 7 | SD_R1_IDLE_STATE = 0, 8 | }; 9 | 10 | enum sd_cmds { 11 | SD_CMD0 = 0, 12 | SD_CMD1 = 1, 13 | SD_CMD8 = 8, 14 | SD_CMD9 = 9, 15 | SD_CMD12 = 12, 16 | SD_CMD13 = 13, 17 | SD_CMD10 = 10, 18 | SD_CMD16 = 16, 19 | SD_CMD17 = 17, 20 | SD_CMD41 = 41, 21 | SD_CMD55 = 55, 22 | SD_CMD58 = 58, 23 | }; 24 | 25 | enum sd_value { 26 | SD_ON = 1, 27 | SD_OFF = 0, 28 | }; 29 | 30 | enum sd_cs { 31 | CS_SEL = 0, 32 | CS_DESEL = 1, 33 | }; 34 | 35 | 36 | struct sd_state; 37 | 38 | struct sd_state *sd_init(uint32_t cmd_in, uint32_t cmd_out, uint32_t clk, 39 | uint32_t cs, uint32_t dat1, uint32_t dat2, uint32_t power); 40 | void sd_deinit(struct sd_state **state); 41 | 42 | int sd_reset(struct sd_state *state, int send_cmd0); 43 | int sd_get_ocr(struct sd_state *state, uint8_t ocr[4]); 44 | int sd_get_cid(struct sd_state *state, uint8_t cid[16]); 45 | int sd_get_csd(struct sd_state *state, uint8_t csd[16]); 46 | int sd_get_sr(struct sd_state *state, uint8_t sr[6]); 47 | int sd_set_blocklength(struct sd_state *state, uint32_t blklen); 48 | int sd_read_block(struct sd_state *state, uint32_t offset, void *block, uint32_t count); 49 | int sd_write_block(struct sd_state *state, uint32_t offset, const void *block, uint32_t count); 50 | int sd_txrx(struct sd_state *state, void *bfr, int count, uint8_t *out, int getbytes); 51 | 52 | int sd_mmc_dat4_crc16(uint8_t *bfr, uint8_t *crc_bfr, int size); 53 | 54 | int print_hex(uint8_t *block, int count); 55 | int print_hex_offset(uint8_t *block, int count, int offset); 56 | 57 | 58 | void xmit_spi ( 59 | struct sd_state *state, 60 | const uint8_t *buff, /* Data to be sent */ 61 | uint32_t bc /* Number of bytes to send */ 62 | ); 63 | void xmit_mmc_cmd ( 64 | struct sd_state *state, 65 | const uint8_t *buff, /* Data to be sent */ 66 | uint32_t bc /* Number of bytes to send */ 67 | ); 68 | void xmit_mmc_dat1 ( 69 | struct sd_state *state, 70 | const uint8_t *buff, /* Data to be sent */ 71 | uint32_t bc /* Number of bytes to send */ 72 | ); 73 | void xmit_mmc_dat4 ( 74 | struct sd_state *state, 75 | const uint8_t *buff, /* Data to be sent */ 76 | uint32_t bc /* Number of bytes to send */ 77 | ); 78 | 79 | void rcvr_spi ( 80 | struct sd_state *state, 81 | uint8_t *buff, /* Pointer to read buffer */ 82 | uint32_t bc /* Number of bytes to receive */ 83 | ); 84 | void rcvr_mmc_cmd ( 85 | struct sd_state *state, 86 | uint8_t *buff, /* Pointer to read buffer */ 87 | uint32_t bc /* Number of bytes to receive */ 88 | ); 89 | void rcvr_mmc_dat1 ( 90 | struct sd_state *state, 91 | uint8_t *buff, /* Pointer to read buffer */ 92 | uint32_t bc /* Number of bytes to receive */ 93 | ); 94 | void rcvr_mmc_dat4 ( 95 | struct sd_state *state, 96 | uint8_t *buff, /* Pointer to read buffer */ 97 | uint32_t bc /* Number of bytes to receive */ 98 | ); 99 | 100 | int sd_toggle_clk(struct sd_state *state, int times); 101 | int rcvr_mmc_cmd_start(struct sd_state *state, int tries); 102 | int rcvr_mmc_dat0_start(struct sd_state *state, int tries); 103 | 104 | int sd_enter_factory_mode(struct sd_state *state, uint8_t type); 105 | 106 | int sd_read_pins(struct sd_state *state); 107 | int sd_set_dat_output(struct sd_state *state, int datN); 108 | int sd_set_dat_input(struct sd_state *state, int datN); 109 | int sd_set_dat_value(struct sd_state *state, int datN, int value); 110 | 111 | #endif /* __SD_H__ */ 112 | -------------------------------------------------------------------------------- /src/ax215/gpio.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "gpio.h" 13 | 14 | #define GPIO_PATH "/sys/class/gpio" 15 | #define EXPORT_PATH GPIO_PATH "/export" 16 | #define UNEXPORT_PATH GPIO_PATH "/unexport" 17 | 18 | static int gpio_is_exported(int gpio) { 19 | char gpio_path[256]; 20 | struct stat buf; 21 | int ret; 22 | snprintf(gpio_path, sizeof(gpio_path)-1, GPIO_PATH "/gpio%d/direction", gpio); 23 | ret = stat(gpio_path, &buf); 24 | if (ret == -1) 25 | return 0; 26 | return 1; 27 | } 28 | 29 | 30 | static int gpio_export_unexport(char *path, int gpio) { 31 | int fd; 32 | char str[16]; 33 | int bytes; 34 | 35 | fd = open(path, O_WRONLY); 36 | if (fd == -1) { 37 | perror("Unable to find GPIO files -- /sys/class/gpio enabled?"); 38 | return -errno; 39 | } 40 | 41 | bytes = snprintf(str, sizeof(str)-1, "%d", gpio) + 1; 42 | 43 | if (-1 == write(fd, str, bytes)) { 44 | fprintf(stderr, "Unable to modify gpio%d: %s", 45 | gpio, strerror(errno)); 46 | close(fd); 47 | return -errno; 48 | } 49 | 50 | close(fd); 51 | return 0; 52 | } 53 | 54 | int gpio_export(int gpio) { 55 | if (gpio&GPIO_IS_EIM) 56 | return 0; 57 | if (gpio_is_exported(gpio)) 58 | return 0; 59 | return gpio_export_unexport(EXPORT_PATH, gpio); 60 | } 61 | 62 | int gpio_unexport(int gpio) { 63 | if (gpio&GPIO_IS_EIM) 64 | return 0; 65 | if (!gpio_is_exported(gpio)) 66 | return 0; 67 | return gpio_export_unexport(UNEXPORT_PATH, gpio); 68 | } 69 | 70 | int gpio_set_direction(int gpio, int is_output) { 71 | char gpio_path[256]; 72 | int fd; 73 | int ret; 74 | 75 | if (gpio&GPIO_IS_EIM) 76 | return eim_set_direction(gpio&(~GPIO_IS_EIM), is_output); 77 | 78 | snprintf(gpio_path, sizeof(gpio_path)-1, GPIO_PATH "/gpio%d/direction", gpio); 79 | 80 | fd = open(gpio_path, O_WRONLY); 81 | if (fd == -1) { 82 | fprintf(stderr, "Direction file: [%s]\n", gpio_path); 83 | perror("Couldn't open direction file for gpio"); 84 | return -errno; 85 | } 86 | 87 | if (is_output) 88 | ret = write(fd, "out", 4); 89 | else 90 | ret = write(fd, "in", 3); 91 | 92 | if (ret == -1) { 93 | perror("Couldn't set output direction"); 94 | close(fd); 95 | return -errno; 96 | } 97 | 98 | close(fd); 99 | return 0; 100 | } 101 | 102 | 103 | int gpio_set_value(int gpio, int value) { 104 | char gpio_path[256]; 105 | int fd; 106 | int ret; 107 | 108 | if (gpio&GPIO_IS_EIM) 109 | return eim_set_value(gpio&(~GPIO_IS_EIM), value); 110 | 111 | snprintf(gpio_path, sizeof(gpio_path)-1, GPIO_PATH "/gpio%d/value", gpio); 112 | 113 | fd = open(gpio_path, O_WRONLY); 114 | if (fd == -1) { 115 | fprintf(stderr, "Value file: [%s]\n", gpio_path); 116 | perror("Couldn't open value file for gpio"); 117 | return -errno; 118 | } 119 | 120 | if (value) 121 | ret = write(fd, "1", 2); 122 | else 123 | ret = write(fd, "0", 2); 124 | 125 | if (ret == -1) { 126 | fprintf(stderr, "Couldn't set GPIO %d output value: %s\n", 127 | gpio, strerror(errno)); 128 | close(fd); 129 | return -errno; 130 | } 131 | 132 | close(fd); 133 | return 0; 134 | } 135 | 136 | 137 | int gpio_get_value(int gpio) { 138 | char gpio_path[256]; 139 | int fd; 140 | 141 | if (gpio&GPIO_IS_EIM) 142 | return eim_get_value(gpio&(~GPIO_IS_EIM)); 143 | 144 | snprintf(gpio_path, sizeof(gpio_path)-1, GPIO_PATH "/gpio%d/value", gpio); 145 | 146 | fd = open(gpio_path, O_RDONLY); 147 | if (fd == -1) { 148 | perror("Couldn't open value file for gpio"); 149 | return -errno; 150 | } 151 | 152 | if (read(fd, gpio_path, sizeof(gpio_path)) <= 0) { 153 | perror("Couldn't get input value"); 154 | close(fd); 155 | return -errno; 156 | } 157 | 158 | close(fd); 159 | 160 | return gpio_path[0] != '0'; 161 | } 162 | 163 | 164 | -------------------------------------------------------------------------------- /fpga/devmem2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * devmem2.c: Simple program to read/write from/to any location in memory. 3 | * 4 | * Copyright (C) 2000, Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) 5 | * 6 | * 7 | * This software has been developed for the LART computing board 8 | * (http://www.lart.tudelft.nl/). The development has been sponsored by 9 | * the Mobile MultiMedia Communications (http://www.mmc.tudelft.nl/) 10 | * and Ubiquitous Communications (http://www.ubicom.tudelft.nl/) 11 | * projects. 12 | * 13 | * The author can be reached at: 14 | * 15 | * Jan-Derk Bakker 16 | * Information and Communication Theory Group 17 | * Faculty of Information Technology and Systems 18 | * Delft University of Technology 19 | * P.O. Box 5031 20 | * 2600 GA Delft 21 | * The Netherlands 22 | * 23 | * 24 | * This program is free software; you can redistribute it and/or modify 25 | * it under the terms of the GNU General Public License as published by 26 | * the Free Software Foundation; either version 2 of the License, or 27 | * (at your option) any later version. 28 | * 29 | * This program is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32 | * GNU General Public License for more details. 33 | * 34 | * You should have received a copy of the GNU General Public License 35 | * along with this program; if not, write to the Free Software 36 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 37 | * 38 | */ 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \ 53 | __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0) 54 | 55 | #define MAP_SIZE 4096UL 56 | #define MAP_MASK (MAP_SIZE - 1) 57 | 58 | int main(int argc, char **argv) { 59 | int fd; 60 | void *map_base, *virt_addr; 61 | unsigned long read_result, writeval; 62 | off_t target; 63 | int access_type = 'w'; 64 | 65 | if(argc < 2) { 66 | fprintf(stderr, "\nUsage:\t%s { address } [ type [ data ] ]\n" 67 | "\taddress : memory address to act upon\n" 68 | "\ttype : access operation type : [b]yte, [h]alfword, [w]ord\n" 69 | "\tdata : data to be written\n\n", 70 | argv[0]); 71 | exit(1); 72 | } 73 | target = strtoul(argv[1], 0, 0); 74 | 75 | if(argc > 2) 76 | access_type = tolower(argv[2][0]); 77 | 78 | 79 | if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL; 80 | printf("/dev/mem opened.\n"); 81 | fflush(stdout); 82 | 83 | /* Map one page */ 84 | map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK); 85 | if(map_base == (void *) -1) FATAL; 86 | printf("Memory mapped at address %p.\n", map_base); 87 | fflush(stdout); 88 | 89 | virt_addr = map_base + (target & MAP_MASK); 90 | switch(access_type) { 91 | case 'b': 92 | read_result = *((unsigned char *) virt_addr); 93 | break; 94 | case 'h': 95 | read_result = *((unsigned short *) virt_addr); 96 | break; 97 | case 'w': 98 | read_result = *((unsigned long *) virt_addr); 99 | break; 100 | default: 101 | fprintf(stderr, "Illegal data type '%c'.\n", access_type); 102 | exit(2); 103 | } 104 | printf("Value at address 0x%X (%p): 0x%X\n", target, virt_addr, read_result); 105 | fflush(stdout); 106 | 107 | if(argc > 3) { 108 | writeval = strtoul(argv[3], 0, 0); 109 | switch(access_type) { 110 | case 'b': 111 | *((unsigned char *) virt_addr) = writeval; 112 | read_result = *((unsigned char *) virt_addr); 113 | break; 114 | case 'h': 115 | *((unsigned short *) virt_addr) = writeval; 116 | read_result = *((unsigned short *) virt_addr); 117 | break; 118 | case 'w': 119 | *((unsigned long *) virt_addr) = writeval; 120 | read_result = *((unsigned long *) virt_addr); 121 | break; 122 | } 123 | printf("Written 0x%X; readback 0x%X\n", writeval, read_result); 124 | fflush(stdout); 125 | } 126 | 127 | if(munmap(map_base, MAP_SIZE) == -1) FATAL; 128 | close(fd); 129 | return 0; 130 | } 131 | 132 | -------------------------------------------------------------------------------- /src/as31/run.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "as31.h" 8 | 9 | 10 | 11 | /* global variables */ 12 | unsigned long lc; 13 | char *asmfile; 14 | int fatal=0, abort_asap=0; 15 | int pass=0; 16 | int dashl=0; 17 | FILE *listing=NULL, *fin=NULL; 18 | 19 | 20 | 21 | int run_as31(const char *infile, int lst, int use_stdout, 22 | const char *fmt, const char *arg) 23 | { 24 | char *outfile=NULL, *lstfile=NULL; 25 | const char *extension; 26 | int has_dot_asm=0; 27 | int len, baselen, extlen; 28 | 29 | /* first, figure out all the file names */ 30 | 31 | dashl = lst; 32 | extension = emit_extension(fmt); 33 | extlen = strlen(extension); 34 | 35 | len = baselen = strlen(infile); 36 | if (len >= 4 && strcasecmp(infile + len - 4, ".asm") == 0) { 37 | has_dot_asm = 1; 38 | baselen -= 4; 39 | } 40 | 41 | asmfile = (char *)malloc(baselen + 5); 42 | strcpy(asmfile, infile); 43 | 44 | if (dashl) { 45 | lstfile = (char *)malloc(baselen + 5); 46 | strncpy(lstfile, infile, baselen); 47 | strcpy(lstfile + baselen, ".lst"); 48 | } 49 | 50 | if (use_stdout) { 51 | outfile = NULL; 52 | } else { 53 | outfile = (char *)malloc(baselen + extlen + 2); 54 | strncpy(outfile, infile, baselen); 55 | *(outfile + baselen) = '.'; 56 | strcpy(outfile + baselen + 1, extension); 57 | } 58 | 59 | /* now open the files */ 60 | 61 | fin = freopen(asmfile, "r", stdin); 62 | if (fin == NULL) { 63 | if (!has_dot_asm) { 64 | strcpy(asmfile + baselen, ".asm"); 65 | fin = freopen(asmfile, "r", stdin); 66 | } 67 | if (fin == NULL) { 68 | mesg_f("Cannot open input file: %s\n", asmfile); 69 | free(asmfile); 70 | if (outfile) free(outfile); 71 | if (lstfile) free(lstfile); 72 | return -1; 73 | } 74 | } 75 | 76 | if (dashl) { 77 | listing = fopen(lstfile,"w"); 78 | if( listing == NULL ) { 79 | mesg_f("Cannot open file: %s for writing.\n", 80 | lstfile); 81 | fclose(fin); 82 | free(asmfile); 83 | if (outfile) free(outfile); 84 | if (lstfile) free(lstfile); 85 | return -1; 86 | } 87 | } 88 | 89 | /* what happens if this doesn't work */ 90 | emitopen(outfile, fmt, arg); 91 | 92 | syminit(); 93 | clear_location_counter(); 94 | fatal = abort_asap = 0; 95 | lineno = 1; 96 | pass=0; 97 | lc = 0; 98 | 99 | /* 100 | ** P A S S 1 101 | */ 102 | 103 | if (!use_stdout) mesg_f("Begin Pass #1\n"); 104 | yyparse(); 105 | if (fatal) { 106 | mesg_f("Errors in pass1, assembly aborted\n"); 107 | } else { 108 | 109 | rewind(fin); 110 | lineno = 1; 111 | pass++; 112 | lc = 0; 113 | emitaddr(lc); 114 | 115 | /* 116 | ** P A S S 2 117 | */ 118 | if (!use_stdout) mesg_f("Begin Pass #2\n"); 119 | yyparse(); 120 | } 121 | if (fatal) { 122 | mesg_f("Errors in pass2, assembly aborted\n"); 123 | } 124 | 125 | emitclose(); 126 | fclose(fin); 127 | if (dashl) fclose(listing); 128 | free(asmfile); 129 | if (outfile) free(outfile); 130 | if (lstfile) free(lstfile); 131 | freesym(); 132 | if (fatal) return -1; 133 | return 0; 134 | } 135 | 136 | 137 | /* the parser, lexer and other stuff that actually do the */ 138 | /* assembly will call to these two functions to report any */ 139 | /* errors or warning. error() calls exit() in the command */ 140 | /* line version, but the abort_asap flag was added, and the */ 141 | /* parser check it at the end of every line */ 142 | 143 | void error(const char *fmt, ...) 144 | { 145 | va_list args; 146 | char buf[2048]; 147 | int len; 148 | 149 | abort_asap++; 150 | fatal++; 151 | va_start(args, fmt); 152 | 153 | len = snprintf(buf, sizeof(buf), "Error, line %d, ", lineno); 154 | len += vsnprintf(buf + len, sizeof(buf) - len, fmt, args); 155 | snprintf(buf + len, sizeof(buf) - len, ".\n"); 156 | mesg(buf); 157 | } 158 | 159 | 160 | void warn(const char *fmt, ...) 161 | { 162 | va_list args; 163 | char buf[2048]; 164 | int len; 165 | 166 | fatal++; 167 | va_start(args, fmt); 168 | 169 | len = snprintf(buf, sizeof(buf), "Warning, line %d, ", lineno); 170 | len += vsnprintf(buf + len, sizeof(buf) - len, fmt, args); 171 | snprintf(buf + len, sizeof(buf) - len, ".\n"); 172 | mesg(buf); 173 | } 174 | 175 | 176 | void mesg_f(const char *fmt, ...) 177 | { 178 | va_list args; 179 | char buf[2048]; 180 | 181 | va_start(args, fmt); 182 | 183 | vsnprintf(buf, sizeof(buf), fmt, args); 184 | mesg(buf); 185 | } 186 | 187 | -------------------------------------------------------------------------------- /src/as31/parser.h: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 2.3. */ 2 | 3 | /* Skeleton interface for Bison's Yacc-like parsers in C 4 | 5 | Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 6 | Free Software Foundation, Inc. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2, or (at your option) 11 | any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program; if not, write to the Free Software 20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 | Boston, MA 02110-1301, USA. */ 22 | 23 | /* As a special exception, you may create a larger work that contains 24 | part or all of the Bison parser skeleton and distribute that work 25 | under terms of your choice, so long as that work isn't itself a 26 | parser generator using the skeleton or a modified version thereof 27 | as a parser skeleton. Alternatively, if you modify or redistribute 28 | the parser skeleton itself, you may (at your option) remove this 29 | special exception, which will cause the skeleton and the resulting 30 | Bison output files to be licensed under the GNU General Public 31 | License without this special exception. 32 | 33 | This special exception was added by the Free Software Foundation in 34 | version 2.2 of Bison. */ 35 | 36 | /* Tokens. */ 37 | #ifndef YYTOKENTYPE 38 | # define YYTOKENTYPE 39 | /* Put the tokens into the symbol table, so that GDB and other debuggers 40 | know about them. */ 41 | enum yytokentype { 42 | STRING = 258, 43 | D_ORG = 259, 44 | D_BYTE = 260, 45 | D_WORD = 261, 46 | D_SKIP = 262, 47 | D_EQU = 263, 48 | D_FLAG = 264, 49 | D_END = 265, 50 | ACALL = 266, 51 | ADD = 267, 52 | ADDC = 268, 53 | AJMP = 269, 54 | ANL = 270, 55 | CJNE = 271, 56 | CLR = 272, 57 | CPL = 273, 58 | DA = 274, 59 | DEC = 275, 60 | DIV = 276, 61 | DJNZ = 277, 62 | INC = 278, 63 | JB = 279, 64 | JBC = 280, 65 | JC = 281, 66 | JMP = 282, 67 | JNB = 283, 68 | JNC = 284, 69 | JNZ = 285, 70 | JZ = 286, 71 | LCALL = 287, 72 | LJMP = 288, 73 | MOV = 289, 74 | MOVC = 290, 75 | MOVX = 291, 76 | NOP = 292, 77 | MUL = 293, 78 | ORL = 294, 79 | POP = 295, 80 | PUSH = 296, 81 | RET = 297, 82 | RETI = 298, 83 | RL = 299, 84 | RLC = 300, 85 | RR = 301, 86 | RRC = 302, 87 | SETB = 303, 88 | SJMP = 304, 89 | SUBB = 305, 90 | SWAP = 306, 91 | XCH = 307, 92 | XCHD = 308, 93 | XRL = 309, 94 | AB = 310, 95 | A = 311, 96 | C = 312, 97 | PC = 313, 98 | DPTR = 314, 99 | BITPOS = 315, 100 | R0 = 316, 101 | R1 = 317, 102 | R2 = 318, 103 | R3 = 319, 104 | R4 = 320, 105 | R5 = 321, 106 | R6 = 322, 107 | R7 = 323, 108 | VALUE = 324, 109 | SYMBOL = 325 110 | }; 111 | #endif 112 | /* Tokens. */ 113 | #define STRING 258 114 | #define D_ORG 259 115 | #define D_BYTE 260 116 | #define D_WORD 261 117 | #define D_SKIP 262 118 | #define D_EQU 263 119 | #define D_FLAG 264 120 | #define D_END 265 121 | #define ACALL 266 122 | #define ADD 267 123 | #define ADDC 268 124 | #define AJMP 269 125 | #define ANL 270 126 | #define CJNE 271 127 | #define CLR 272 128 | #define CPL 273 129 | #define DA 274 130 | #define DEC 275 131 | #define DIV 276 132 | #define DJNZ 277 133 | #define INC 278 134 | #define JB 279 135 | #define JBC 280 136 | #define JC 281 137 | #define JMP 282 138 | #define JNB 283 139 | #define JNC 284 140 | #define JNZ 285 141 | #define JZ 286 142 | #define LCALL 287 143 | #define LJMP 288 144 | #define MOV 289 145 | #define MOVC 290 146 | #define MOVX 291 147 | #define NOP 292 148 | #define MUL 293 149 | #define ORL 294 150 | #define POP 295 151 | #define PUSH 296 152 | #define RET 297 153 | #define RETI 298 154 | #define RL 299 155 | #define RLC 300 156 | #define RR 301 157 | #define RRC 302 158 | #define SETB 303 159 | #define SJMP 304 160 | #define SUBB 305 161 | #define SWAP 306 162 | #define XCH 307 163 | #define XCHD 308 164 | #define XRL 309 165 | #define AB 310 166 | #define A 311 167 | #define C 312 168 | #define PC 313 169 | #define DPTR 314 170 | #define BITPOS 315 171 | #define R0 316 172 | #define R1 317 173 | #define R2 318 174 | #define R3 319 175 | #define R4 320 176 | #define R5 321 177 | #define R6 322 178 | #define R7 323 179 | #define VALUE 324 180 | #define SYMBOL 325 181 | 182 | 183 | 184 | 185 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 186 | typedef int YYSTYPE; 187 | # define yystype YYSTYPE /* obsolescent; will be withdrawn */ 188 | # define YYSTYPE_IS_DECLARED 1 189 | # define YYSTYPE_IS_TRIVIAL 1 190 | #endif 191 | 192 | extern YYSTYPE yylval; 193 | 194 | -------------------------------------------------------------------------------- /src/as31/as31.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * FILE: as31.h 3 | * PACKAGE: as31 - 8031/8051 Assembler. 4 | * 5 | * DESCRIPTION: 6 | * The sole header file for the 8031/8051 assembler package. 7 | * It defines several structures used by the yacc stack. 8 | * It defines several macros for testing the bitsize of numeric 9 | * quantities. 10 | * 11 | * Some macros to extract information from the mode structure. 12 | * 13 | * REVISION HISTORY: 14 | * Jan. 19, 1990 - Created. (Ken Stauffer) 15 | * 16 | * AUTHOR: 17 | * All code in this file written by Ken Stauffer (University of Calgary). 18 | * January, 1990. 19 | * 20 | */ 21 | 22 | #include 23 | 24 | /* ---------------------------------------------------------------------- 25 | * user / keyword symbol structures: 26 | */ 27 | 28 | struct opcode { 29 | char *name; 30 | int type; 31 | unsigned char *bytes; 32 | }; 33 | 34 | struct symbol { 35 | char *name; 36 | char predefined; 37 | char type; 38 | long value; 39 | struct symbol *next; 40 | }; 41 | 42 | #define UNDEF 0 43 | #define LABEL 1 44 | 45 | /* these are unused... maybe someday the can be used and the */ 46 | /* parser can check that each addressing mode is using the */ 47 | /* correct type of data, or a generic LABEL type */ 48 | #define BIT 2 49 | #define IMEM 3 50 | #define EMEM 3 51 | #define CONST 4 52 | #define REG 5 53 | 54 | /* ---------------------------------------------------------------------- 55 | * addressing mode stuff: 56 | */ 57 | 58 | struct mode { 59 | unsigned char mode; /* value to index with */ 60 | unsigned char size; /* # of bytes used */ 61 | unsigned char orval; /* value OR'd to obcode */ 62 | unsigned char byte1; /* extra byte 1 */ 63 | unsigned char byte2; /* extra byte 2 */ 64 | }; 65 | 66 | #define set_md(m,a) ((m).mode=(a)) 67 | #define set_sz(m,a) ((m).size=(a)) 68 | #define set_ov(m,a) ((m).orval=(a)) 69 | #define set_b1(m,a) ((m).byte1=(a)) 70 | #define set_b2(m,a) ((m).byte2=(a)) 71 | 72 | #define get_md(m) ((m).mode) 73 | #define get_sz(m) ((m).size) 74 | #define get_ov(m) ((m).orval) 75 | #define get_b1(m) ((m).byte1) 76 | #define get_b2(m) ((m).byte2) 77 | 78 | /* ---------------------------------------------------------------------- 79 | * yacc stack stuff: 80 | */ 81 | 82 | struct value { 83 | long v; 84 | unsigned char d; /* expression defined flag */ 85 | }; 86 | 87 | union ystack { 88 | long value; 89 | struct value val; 90 | struct opcode *op; 91 | struct symbol *sym; 92 | struct mode mode; 93 | char *str; 94 | }; 95 | 96 | #define YYSTYPE union ystack 97 | 98 | /* ---------------------------------------------------------------------- 99 | * IS_BIT_MAPPED_RAM: 100 | * True is the byte 'a' is the byte address of a bit mapped 101 | * RAM location. 102 | */ 103 | #define isbmram(a) (((a)&0xf0)==0x20) 104 | 105 | /* ---------------------------------------------------------------------- 106 | * IS_BIT_MAPPED_SFR: 107 | * True is the byte 'a' is the byte address of a bit mapped 108 | * SPECIAL FUCTION REGISTER. 109 | */ 110 | #define isbmsfr(a) (((a)&0x80) && !((a) & 0x07)) 111 | 112 | /* ---------------------------------------------------------------------- 113 | * isbit8, ... 114 | * Macros to check the sizes of values and to convert 115 | * a value to a certain, size. 116 | * 117 | */ 118 | #define size8 (~0x00ff) 119 | #define size11 (~0x07ff) 120 | #define size13 (~0x1fff) 121 | #define size16 (~0xffff) 122 | 123 | #define size10 (~0x03ff) 124 | #define size12 (~0x0fff) 125 | #define size15 (~0x7fff) 126 | 127 | #define isbit8(v) ( !( ((v)>=0) ? (v)&size8 : -(v)>=128) ) 128 | #define isbit11(v) ( !( ((v)>=0) ? (v)&size11 : (-(v))&size10 ) ) 129 | #define isbit13(v) ( !( ((v)>=0) ? (v)&size13 : (-(v))&size12 ) ) 130 | #define isbit16(v) ( !( ((v)>=0) ? (v)&size16 : (-(v))&size15 ) ) 131 | 132 | /* ---------------------------------------------------------------------- 133 | * Size of user hash table. Use a prime number for best performance 134 | */ 135 | #define HASHTABSIZE 4999 136 | 137 | /* ---------------------------------------------------------------------- 138 | * Macros to nicely test which pass we are in. 139 | */ 140 | #define pass1 (!pass) 141 | #define pass2 (pass) 142 | 143 | 144 | 145 | /* from lexer.c */ 146 | extern int yylex(void); 147 | extern int seek_eol(void); 148 | extern const char *get_last_token(void); 149 | extern int lineno; 150 | 151 | 152 | /* from parser.y */ 153 | extern int yyparse(void); 154 | extern void clear_location_counter(void); 155 | 156 | 157 | /* from emitter.c */ 158 | extern void emitusage(void); 159 | extern const char *emit_extension(const char *ftype); 160 | extern const char *emit_desc_lookup(int num); 161 | extern const char *emit_desc_to_name_lookup(const char *desc); 162 | extern int emitopen(const char *file, const char *ftype, const char *arg); 163 | extern void emitclose(void); 164 | extern void emitaddr(unsigned long a); 165 | extern void emitbyte(int b); 166 | 167 | 168 | /* from symbol.c */ 169 | extern struct opcode *lookop(const char *s); 170 | extern struct symbol *looksym(const char *s); 171 | extern void syminit(void); 172 | extern void freesym(void); 173 | 174 | 175 | /* from run.c */ 176 | extern int run_as31(const char *infile, int lst, int use_stdout, 177 | const char *fmt, const char *arg); 178 | extern void error(const char *fmt, ...); 179 | extern void warn(const char *fmt, ...); 180 | extern void mesg_f(const char *fmt, ...); 181 | extern int dashl; 182 | extern int pass; 183 | extern int abort_asap; 184 | extern unsigned long lc; 185 | extern FILE *listing; 186 | 187 | 188 | /* from as31.c or as31_gtk.c */ 189 | extern void mesg(const char *str); 190 | 191 | 192 | -------------------------------------------------------------------------------- /progs/TestBoot.asm: -------------------------------------------------------------------------------- 1 | .equ IEN0, 0xA8 2 | .equ SDICMD, 0x8D 3 | 4 | .equ SDOADDRL, 0x96 5 | .equ SDOADDRH, 0x97 6 | 7 | .equ SDOBYTESL, 0x93 8 | .equ SDOBYTESH, 0x94 9 | 10 | .equ SDODMAADDRL, 0x99 11 | .equ SDODMAADDRH, 0x9A 12 | 13 | .equ SDODMABYTESL, 0x91 14 | .equ SDODMABYTESH, 0x92 15 | 16 | .equ FSR_80, 0x80 17 | .equ FSR_88, 0x88 18 | .equ FSR_8E, 0x8E 19 | .equ FSR_90, 0x90 20 | .equ FSR_D8, 0xD8 21 | .equ FSR_EB, 0xEB 22 | .equ FSR_FC, 0xFC 23 | 24 | .equ RESET, 0 25 | 26 | .org 0x2900 27 | 28 | ; This gets called from an interrupt. 29 | start: 30 | ljmp reset_vector 31 | 32 | ; --------------------------------------------------------------------------- 33 | 34 | ROM_2903: ; CODE XREF: ROM:2938 35 | mov FSR_D8, #0xE8 ; 'F' 36 | mov FSR_EB, FSR_FC 37 | anl FSR_8E, #0xFE 38 | anl FSR_8E, #0xFD 39 | anl FSR_8E, #0xFB 40 | anl FSR_8E, #0xF7 41 | anl FSR_80, #0x7F 42 | orl FSR_80, #4 43 | orl FSR_80, #8 44 | ret 45 | ; --------------------------------------------------------------------------- 46 | 47 | reset_vector: ; CODE XREF: ROM:2900 48 | anl FSR_80, #0xFE 49 | orl FSR_80, #2 50 | pop PSW ; Program Status Word 51 | pop ACC ; Accumulator 52 | mov A, #0x32 ; '2' 53 | push ACC ; Accumulator 54 | mov A, #0x29 ; ')' 55 | push ACC ; Accumulator 56 | reti 57 | ; --------------------------------------------------------------------------- 58 | mov IEN0, #0 ; Interrupt Enable Register 0 59 | mov SP, #0x80 ; Stack Pointer 60 | acall ROM_2903 61 | 62 | ROM_293A: ; CODE XREF: ROM:293E 63 | ; ROM:2953 ... 64 | clr 0x24.0 65 | mov A, FSR_8E 66 | jnb ACC.0, ROM_293A ; Accumulator 67 | anl FSR_8E, #0xFE 68 | 69 | ROM_2944: ; CODE XREF: ROM:2948 70 | mov A, FSR_90 71 | anl A, #0xC 72 | jnz ROM_2944 73 | mov A, SDICMD ; SD Incoming Command 74 | xrl A, #0xB 75 | jz ROM_2956 76 | orl FSR_90, #1 77 | ljmp ROM_293A 78 | ; --------------------------------------------------------------------------- 79 | 80 | ROM_2956: ; CODE XREF: ROM:294E 81 | anl FSR_8E, #0xFD 82 | mov SDOADDRL, #0x74 ; 't' ; SD Outgoing Address / 4 (low) 83 | mov SDOADDRH, #5 ; SD Outgoing Address / 4 (high) 84 | mov SDOBYTESL, #3 ; SD Outgoing bytes (low) 85 | mov SDOBYTESH, #0 ; SD Outgoing bytes (high) 86 | mov 0x88, #1 87 | mov R7, #0 88 | mov R6, #0 89 | 90 | ROM_296C: ; CODE XREF: ROM:29A0 91 | ; ROM:29A8 92 | anl FSR_8E, #0xFB 93 | mov SDODMAADDRL, R7 ; SD Outgoing DMA Address (low) 94 | mov SDODMAADDRH, R6 ; SD Outgoing DMA Address (high) 95 | clr C 96 | mov A, R7 97 | add A, #0x40 ; '@' 98 | mov R7, A 99 | mov A, R6 100 | addc A, #0 101 | mov R6, A 102 | mov SDODMABYTESL, #0xFF ; SD Outgoing DMA Bytes (low) 103 | mov SDODMABYTESH, #1 ; SD Outgoing DMA Bytes (high) 104 | orl FSR_80, #1 105 | 106 | ROM_2985: ; CODE XREF: ROM:2987 107 | mov A, FSR_8E 108 | jnb ACC.2, ROM_2985 ; Accumulator 109 | mov A, FSR_80 110 | anl A, #0x20 111 | jnz ROM_29AB 112 | mov A, FSR_80 113 | anl A, #0x10 114 | jnz ROM_29AB 115 | mov A, FSR_80 116 | jb ACC.6, ROM_29A3 ; Accumulator 117 | clr 0x24.0 118 | orl FSR_80, #2 119 | ljmp ROM_296C 120 | ; --------------------------------------------------------------------------- 121 | 122 | ROM_29A3: ; CODE XREF: ROM:2998 123 | setb 0x24.0 124 | orl FSR_80, #2 125 | ljmp ROM_296C 126 | ; --------------------------------------------------------------------------- 127 | 128 | ROM_29AB: ; CODE XREF: ROM:298E 129 | ; ROM:2994 130 | anl FSR_8E, #0xFE 131 | anl FSR_8E, #0xFD 132 | anl FSR_8E, #0xFB 133 | 134 | ROM_29B4: ; CODE XREF: ROM:29B8 135 | mov A, FSR_90 136 | anl A, #0xC 137 | jnz ROM_29B4 138 | mov SDOADDRL, #0x74 ; 't' ; SD Outgoing Address / 4 (low) 139 | mov SDOADDRH, #5 ; SD Outgoing Address / 4 (high) 140 | mov SDOBYTESL, #3 ; SD Outgoing bytes (low) 141 | mov SDOBYTESH, #0 ; SD Outgoing bytes (high) 142 | mov FSR_88, #1 143 | 144 | ROM_29C9: ; CODE XREF: ROM:29CB 145 | mov A, FSR_8E 146 | jnb ACC.1, ROM_29C9 ; Accumulator 147 | anl FSR_8E, #0xFD 148 | anl FSR_80, #0xFE 149 | orl FSR_80, #2 150 | jnb 0x24.0, ROM_29DD 151 | ljmp ROM_293A 152 | ; --------------------------------------------------------------------------- 153 | 154 | ROM_29DD: ; CODE XREF: ROM:29D7 155 | mov SP, #0x80 ; Stack Pointer 156 | ljmp RESET ; Power-on program execution start 157 | -------------------------------------------------------------------------------- /src/as31/as31_gtk.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * FILE: main.c 3 | * PACKAGE: as31 - 8031/8051 Assembler. 4 | * 5 | * DESCRIPTION: 6 | * The file contains main(). It handles the arguments and makes 7 | * sure that pass 1 is done before pass 2 etc... 8 | * 9 | * REVISION HISTORY: 10 | * Jan. 19, 1990 - Created. (Ken Stauffer) 11 | * 12 | * AUTHOR: 13 | * All code in this file written by Ken Stauffer (University of Calgary). 14 | * January, 1990. "Written by: Ken Stauffer" 15 | * 16 | * April, 2000, Paul Stoffregen: see Makefile for details 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "as31.h" 27 | 28 | 29 | void do_assemble(GtkWidget *widget, gpointer *data); 30 | gint delete_handler(GtkWidget *widget, gpointer *data); 31 | 32 | 33 | /* make all the GTK widgets global, instead of passing lots */ 34 | /* of pointers into the callbacks, through the parser, etc */ 35 | 36 | GtkWidget *file_label, *file_entry, *otype_combo; 37 | GtkWidget *list_check, *go_button; 38 | GtkWidget *otype_label, *output_text; 39 | GtkWidget *main_window, *main_vbox; 40 | GtkWidget *top_hbox, *middle_hbox, *bottom_hbox; 41 | 42 | 43 | int main(int argc, char **argv) 44 | { 45 | GList *otypelist; 46 | const char *desc; 47 | int n; 48 | 49 | gtk_init(&argc, &argv); 50 | 51 | /* create all the gtk widgets... it's a pain to type in all */ 52 | /* this stuff, maybe someday I'll have to learn about glade */ 53 | 54 | file_label = gtk_label_new("ASM File: "); 55 | gtk_label_set_justify(GTK_LABEL(file_label), GTK_JUSTIFY_RIGHT); 56 | gtk_widget_show(file_label); 57 | 58 | otype_label = gtk_label_new("Output Format"); 59 | gtk_label_set_justify(GTK_LABEL(otype_label), GTK_JUSTIFY_RIGHT); 60 | gtk_widget_show(otype_label); 61 | 62 | file_entry = gtk_entry_new(); 63 | /* fill in a default filename, from a previous session ??? */ 64 | gtk_widget_show(file_entry); 65 | 66 | list_check = gtk_check_button_new_with_label("Create List File"); 67 | /* check or unchecked based on previous usage */ 68 | gtk_widget_show(list_check); 69 | 70 | otype_combo = gtk_combo_new(); 71 | otypelist = NULL; 72 | n = 0; 73 | while ((desc = emit_desc_lookup(n++)) != NULL) { 74 | otypelist = g_list_append(otypelist, strdup(desc)); 75 | } 76 | gtk_combo_set_popdown_strings(GTK_COMBO(otype_combo), otypelist); 77 | gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(otype_combo)->entry), 78 | FALSE); 79 | /* set to same output format as a previous run ?? */ 80 | gtk_widget_show(otype_combo); 81 | 82 | go_button = gtk_button_new_with_label("Assemble"); 83 | gtk_widget_show(go_button); 84 | 85 | output_text = gtk_text_new(NULL, NULL); 86 | gtk_text_set_editable(GTK_TEXT(output_text), FALSE); 87 | gtk_widget_show(output_text); 88 | 89 | top_hbox = gtk_hbox_new(FALSE, 2); 90 | gtk_box_pack_start(GTK_BOX(top_hbox), file_label, FALSE, FALSE, 2); 91 | gtk_box_pack_start(GTK_BOX(top_hbox), file_entry, TRUE, TRUE, 2); 92 | gtk_widget_show(top_hbox); 93 | 94 | middle_hbox = gtk_hbox_new(FALSE, 2); 95 | gtk_box_pack_start(GTK_BOX(middle_hbox), otype_label, FALSE, FALSE, 2); 96 | gtk_box_pack_start(GTK_BOX(middle_hbox), otype_combo, FALSE, FALSE, 2); 97 | gtk_widget_show(middle_hbox); 98 | 99 | bottom_hbox = gtk_hbox_new(FALSE, 2); 100 | gtk_box_pack_start(GTK_BOX(bottom_hbox), go_button, FALSE, FALSE, 2); 101 | gtk_box_pack_start(GTK_BOX(bottom_hbox), list_check, FALSE, FALSE, 2); 102 | gtk_widget_show(bottom_hbox); 103 | 104 | main_vbox = gtk_vbox_new(FALSE, 2); 105 | gtk_box_pack_start(GTK_BOX(main_vbox), top_hbox, FALSE, FALSE, 2); 106 | gtk_box_pack_start(GTK_BOX(main_vbox), middle_hbox, FALSE, FALSE, 2); 107 | gtk_box_pack_start(GTK_BOX(main_vbox), bottom_hbox, FALSE, FALSE, 2); 108 | gtk_box_pack_start(GTK_BOX(main_vbox), output_text, TRUE, TRUE, 2); 109 | gtk_widget_show(main_vbox); 110 | 111 | main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 112 | gtk_container_add(GTK_CONTAINER(main_window), main_vbox); 113 | gtk_widget_show(main_window); 114 | 115 | /* attach signal handlers so we can actually do something */ 116 | 117 | gtk_signal_connect(GTK_OBJECT(main_window), "delete_event", 118 | GTK_SIGNAL_FUNC(delete_handler), NULL); 119 | 120 | gtk_signal_connect(GTK_OBJECT(go_button), "pressed", 121 | GTK_SIGNAL_FUNC(do_assemble), NULL); 122 | 123 | /* that's it, everything past here is a callback from GTK */ 124 | 125 | mesg("WARNING: this is an alpha-quality release.\n"); 126 | mesg("It WILL crash the second time you assemble !!\n"); 127 | mesg("Please report any problems that occur on the\n"); 128 | mesg("first assembly to: paul@pjrc.com\n"); 129 | 130 | gtk_main(); 131 | return 0; 132 | } 133 | 134 | 135 | /* actually do the assembly. The entire assembly is done from */ 136 | /* start to finish in this callback attached to the "assemble now" */ 137 | /* button. It's not so nice to spend a lot of CPU time in a */ 138 | /* callback, because all the gtk widgets stop responding until */ 139 | /* we're done, but it keeps things simple, and at least the */ 140 | /* window manager takes care of raise/lower and reposition, */ 141 | /* ...unlike ms windoze where those are handled by the */ 142 | /* application's event loop. It would be "nice" to launch a */ 143 | /* thread that would do the assembly, but for a simple free */ 144 | /* software project (where the assembly completes rapidly on */ 145 | /* any modern cpu), I don't want to bother with all the unpleasant */ 146 | /* threading issues */ 147 | 148 | void 149 | do_assemble(GtkWidget *widget, gpointer *data) 150 | { 151 | const char *fmt=NULL, *filename; 152 | int r, do_lst; 153 | 154 | 155 | /* collect info from the GTK widgets */ 156 | 157 | do_lst = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(list_check)); 158 | 159 | filename = gtk_entry_get_text(GTK_ENTRY(file_entry)); 160 | if (filename == NULL || *filename == '\0') { 161 | mesg("You need to specify the ASM file\n"); 162 | return; 163 | } 164 | 165 | fmt = emit_desc_to_name_lookup(gtk_entry_get_text( 166 | GTK_ENTRY(GTK_COMBO(otype_combo)->entry))); 167 | if (fmt == NULL) { 168 | mesg("Please select a valid output type\n"); 169 | return; 170 | } 171 | 172 | /* now we can begin working like normal */ 173 | 174 | r = run_as31(filename, do_lst, 0, fmt, NULL); 175 | 176 | if (r == 0) { 177 | mesg("Assembly complete, no errors :)\n"); 178 | } 179 | } 180 | 181 | 182 | /* quit the program if they close it */ 183 | 184 | gint 185 | delete_handler(GtkWidget *widget, gpointer *data) 186 | { 187 | gtk_main_quit(); 188 | return FALSE; 189 | } 190 | 191 | 192 | /* the assembler calls here to display any messages */ 193 | 194 | void mesg(const char *str) 195 | { 196 | if (str == NULL) str = "(null)"; 197 | /* printf("%s", str); */ 198 | gtk_text_insert(GTK_TEXT(output_text), NULL, NULL, 199 | NULL, str, strlen(str)); 200 | } 201 | 202 | -------------------------------------------------------------------------------- /progs/debugger.asm: -------------------------------------------------------------------------------- 1 | .equ IEN, 0xA8 2 | 3 | .equ SD_DATL, 0xD6 ; "Low" byte of SD transmission 4 | .equ SD_DATH, 0xD7 ; "High" byte of SD transmission 5 | 6 | .equ SD_BYTESL, 0xDE ; SD transmission byte count 7 | .equ SD_BYTESH, 0xDF ; SD transmission byte count 8 | 9 | .equ SD_XMIT, 0xE7 ; Write here to start an SD transmission 10 | .equ SD_XMIT_STATE, 0xE8 ; State machine from active SD transmission 11 | 12 | 13 | .equ SDCMD, 0xE6 ; A copy of the incoming SD command 14 | .equ SDI1, 0xE9 ; A copy of the incoming SD argument 1 15 | .equ SDI2, 0xEA ; A copy of the incoming SD argument 2 16 | .equ SDI3, 0xEB ; A copy of the incoming SD argument 3 17 | .equ SDI4, 0xEC ; A copy of the incoming SD argument 4 18 | 19 | ; RAM map: 20 | ; 0x20 - 0x24: Outgoing SD transmission bytes 21 | ; 0x30 - 0x34: Incoming SD transmission bytes 22 | ; 0x35 - 0x39: ISR trigger count 23 | 24 | 25 | .org 0x4700 26 | ; This gets called from the ROM. 27 | ; --------------------------------------------------------------------------- 28 | ; This gets called from an interrupt context, from within ROM. We want to 29 | ; manipulate the stack so that when we return from interrupt, code execution 30 | ; will continue at an address immediately following this code section. 31 | reset_vector: 32 | mov A, #0x0C 33 | push ACC 34 | mov A, #0x47 35 | push ACC 36 | reti ; Return from interrupt, ending up at 0x470c 37 | 38 | ;--------------------------------------------------------------------------- 39 | .org 0x470C 40 | start: 41 | 42 | mov IEN, #0 ; Disable interrupts 43 | mov SP, #0x80 ; Reset stack pointer 44 | ljmp main ; Enter the main() loop 45 | 46 | 47 | main: 48 | lcall receive_one_packet ; Grab the packet, leave it in 49 | ; the SFRs 50 | 51 | mov 0x20, 0x30 ; Put the incoming CMD in the outgoing 52 | ; buffer, so it's part of the response. 53 | 54 | mov 0x21, #0 ; Pre-clear these values, as they will 55 | mov 0x22, #0 ; most commonly be zero in the response. 56 | mov 0x23, #0 ; This saves many bytes later on. 57 | mov 0x24, #0 58 | 59 | mov A, 0x30 ; Grab the command that was received 60 | add A, 0x30 ; and multiply it by three, as ljmp 61 | add A, 0x30 ; opcodes are three bytes. 62 | 63 | mov DPTR, #sdi_jumptable 64 | jmp @A+DPTR 65 | sdi_jumptable: 66 | ljmp cmd0_null 67 | ljmp cmd1_hello 68 | ljmp cmd2_peek 69 | ljmp cmd3_poke 70 | ljmp cmd4_jump 71 | ljmp cmd5_nand 72 | ljmp cmd6_sfr_get 73 | ljmp cmd7_sfr_set 74 | ljmp cmd8_ext_op 75 | ljmp cmd9_error 76 | ljmp cmd10_irq 77 | 78 | cmd0_null: 79 | ljmp transmit_and_loop 80 | 81 | cmd1_hello: 82 | mov 0x21, 0x31 83 | mov 0x22, 0x32 84 | mov 0x23, 0x33 85 | mov 0x24, 0x34 86 | ljmp transmit_and_loop 87 | 88 | cmd2_peek: 89 | ; Take the first two received bytes, and use them as DPTR 90 | mov DPH, 0x31 ; DPH start src 91 | mov DPL, 0x32 ; DPL start src 92 | movx A, @DPTR 93 | mov 0x21, A 94 | 95 | ;inc DPTR 96 | movx A, @DPTR 97 | mov 0x22, A 98 | 99 | ;inc DPTR 100 | movx A, @DPTR 101 | mov 0x23, A 102 | 103 | ;inc DPTR 104 | movx A, @DPTR 105 | mov 0x24, A 106 | 107 | ljmp transmit_and_loop 108 | 109 | cmd3_poke: 110 | mov DPH, 0x31 111 | mov DPL, 0x32 112 | movx A, @DPTR 113 | mov 0x21, A ; Save the old value 114 | 115 | mov DPH, 0x31 116 | mov DPL, 0x32 117 | mov A, 0x33 ; Copy the new value 118 | movx @DPTR, A 119 | 120 | sjmp transmit_and_loop 121 | 122 | cmd4_jump: 123 | mov DPH, 0x31 124 | mov DPL, 0x32 125 | clr A 126 | jmp @A+DPTR 127 | sjmp transmit_and_loop 128 | 129 | cmd5_nand: 130 | mov 0x21, #1 131 | mov 0x22, #2 132 | mov 0x23, #3 133 | mov 0x24, #4 134 | sjmp transmit_and_loop 135 | 136 | cmd6_sfr_get: 137 | ; This will get replaced by "mov 0x21, [SFR]" at runtime 138 | .db 0xa5, 0x60, 0x61 139 | sjmp transmit_and_loop 140 | 141 | cmd7_sfr_set: 142 | ; This will get replaced by "mov [SFR], 0x31" at runtime 143 | .db 0xa5, 0x62, 0x63 144 | inc 0x31 145 | mov 0x21, 0x31 146 | sjmp transmit_and_loop 147 | 148 | cmd8_ext_op: 149 | .db 0xa5, 0x64, 0x65, 0x66, 0x67 150 | sjmp transmit_and_loop 151 | 152 | ; Send an error packet back 153 | cmd9_error: 154 | ;mov 0x21, #0xa5 155 | sjmp transmit_and_loop 156 | 157 | cmd10_irq: 158 | mov 0x21, IE ; Save old interrupt enable state 159 | mov A, 0x31 160 | jz dont_update_irqs 161 | mov IE, 0x32 162 | dont_update_irqs: 163 | sjmp transmit_and_loop 164 | 165 | 166 | transmit_and_loop: 167 | lcall transmit_from_ram 168 | ljmp main 169 | 170 | 171 | 172 | ; Library routines 173 | .org 0x4800 174 | 175 | 176 | ; pause_a_while(while1, while2, while3) 177 | ; R5 [in]: "Small" amount to wait 178 | ; R6 [in]: "Medium" amount to wait 179 | ; R7 [in]: "Large" amount to wait 180 | ; Will count from 0 to R7R6R5. Every time a smaller value underflows, its 181 | ; larger neighbor will decrement. E.g. if R5 underflows from 0 to 255, R6 182 | ; will be decremented. This will conitnue until all values are zero. 183 | pause_a_while: 184 | mov R5, #0x00 185 | mov R6, #0xf0 186 | mov R7, #0x05 187 | top_of_pause: 188 | djnz R5, top_of_pause 189 | djnz R6, top_of_pause 190 | ;djnz R7, top_of_pause 191 | ret 192 | 193 | 194 | ; ===================== SD FUNCTIONS ===================== 195 | ; These functions allow you to transmit data over the SD bus, or 196 | ; receive data back. All functions are blocking, and will only 197 | ; return when they are completely finished and the card is idle. 198 | 199 | ; void setup_sd_rcv(void) 200 | ; Prepares the SD registers to accept an SD packet. 201 | ; INPUT: None 202 | ; OUTPUT: None 203 | setup_sd_rcv: 204 | clr 0xA0.2 205 | anl SD_XMIT_STATE, #0xF0 206 | mov 0xE3, #0x0f ; Don't know what this does, but 207 | ; having it here increases reliability. 208 | ret 209 | 210 | ; void receive_one_packet(void) 211 | ; Received a single four-byte-plus-command packet, and stores it in RAM, 212 | ; at offsets 0x30 - 0x34. 213 | ; RAM offset 0x30 contains the SD command, while offsets 0x31-0x34 contain 214 | ; the data bytes. 215 | ; Returns only once the bytes have been received. 216 | ; 217 | ; INPUT: None 218 | ; OUTPUT: Command byte stored at 0x30 219 | ; Data bytes 1 - 4 stored at offsets 0x31 - 0x34 220 | receive_one_packet: 221 | acall setup_sd_rcv 222 | wait_for_packet_start: 223 | mov A, SD_XMIT_STATE 224 | jnb ACC.0, wait_for_packet_start 225 | anl SD_XMIT_STATE, #0xFE 226 | orl 0xE3, #1 227 | wait_for_packet_end: 228 | jnb 0x90.4, wait_for_packet_end 229 | jb 0x90.0, wait_for_packet_start 230 | mov 0x30, SDCMD 231 | mov 0x31, SDI4 232 | mov 0x32, SDI3 233 | mov 0x33, SDI2 234 | mov 0x34, SDI1 235 | ret 236 | 237 | ; void transmit_from_ram(void) 238 | ; Transmits one four-byte-plus-command packet from RAM, located at 239 | ; offset 0x20. Make sure the command packet at offset 0x20 has its 240 | ; start bit set (i.e. (byte & 0x7f)) so the receiving side knows when 241 | ; the stream starts. 242 | ; Returns once the packet has been completely transmitted. 243 | ; 244 | ; INPUT: Command at offset 0x20, data at offsets 0x21-24 245 | ; OUTPUT: None 246 | transmit_from_ram: 247 | orl 0x20, #0x40 ; Make sure the outgoing command packet 248 | anl 0x20, #0x7F ; has its sync and start bits set. 249 | anl SD_XMIT_STATE, #0xFD 250 | mov 0x1f, #0x00 251 | mov SD_DATL, #0xE8 252 | mov SD_DATH, #0x12 253 | mov SD_BYTESL, #0x04 254 | mov SD_BYTESH, #0 255 | mov SD_XMIT, #0xf1 256 | 257 | wait_for_xmit_done: 258 | mov A, SD_XMIT_STATE 259 | jnb ACC.1, wait_for_xmit_done 260 | anl SD_XMIT_STATE, #0xFD 261 | ret 262 | 263 | 264 | 265 | ; ===================== DEBUG FUNCTIONS ===================== 266 | ; These functions can be useful for figuring out what the card 267 | ; is up to. They are not used during normal operation. 268 | 269 | 270 | ; void noreturn emit_known_stuff(void) 271 | ; Emits a known pattern out the SD pins. This can be useful for knowing 272 | ; where code execution has reached, when you don't know how to use the 273 | ; SPI bus. 274 | ; 275 | ; INPUT: None 276 | ; OUTPUT: None 277 | emit_known_stuff: 278 | mov 0xef, #0xff 279 | nop 280 | nop 281 | nop 282 | mov R5, #0xff 283 | mov R6, #0x20 284 | emit_known_loop1: 285 | djnz R5, emit_known_loop1 286 | djnz R6, emit_known_loop1 287 | mov 0xef, #0x00 288 | mov R5, #0xff 289 | mov R6, #0x20 290 | emit_known_loop2: 291 | djnz R5, emit_known_loop2 292 | djnz R6, emit_known_loop2 293 | sjmp emit_known_stuff 294 | 295 | .org 0x4900 296 | -------------------------------------------------------------------------------- /src/ax215/fuzz.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "sd.h" 11 | 12 | #define MAX_POOLS 16 13 | #define MAX_SLOTS 32 14 | #define SFR_SPOTS 8 15 | 16 | enum pool_types { 17 | pool_sfr, 18 | pool_sleep, 19 | pool_misc, 20 | pool_val0, 21 | pool_val1, 22 | pool_valtype, 23 | }; 24 | 25 | enum pool_misc_types { 26 | pool_misc_totals, 27 | pool_misc_sleeptime, 28 | }; 29 | 30 | union rand_seed { 31 | struct { 32 | uint32_t seed; 33 | uint16_t run; 34 | } fields; 35 | uint16_t seed[3]; 36 | }; 37 | 38 | static int fill_rand_pools(int run, int seed, 39 | uint8_t pools[MAX_POOLS][MAX_SLOTS]) 40 | { 41 | int i, j; 42 | union rand_seed rand_seed; 43 | rand_seed.fields.seed = seed; 44 | rand_seed.fields.run = run; 45 | 46 | printf("\nRun %-4d Seed: %8d\n", run, seed); 47 | for (i = 0; i < MAX_POOLS; i++) 48 | for (j = 0; j < MAX_SLOTS; j++) 49 | pools[i][j] = nrand48(rand_seed.seed); 50 | return 0; 51 | } 52 | 53 | static int patch_fuzzer(struct sd_state *state, uint8_t *file, int filesize, 54 | uint8_t pools[MAX_POOLS][MAX_SLOTS]) 55 | { 56 | int matched = 0; 57 | int total; 58 | int i; 59 | 60 | total = 1 + (pools[pool_misc][pool_misc_totals] % SFR_SPOTS); 61 | total = 2; 62 | 63 | // Patch the binary, and at the same time disassemble the code. 64 | // We look for 0xa5 opcodes, and patch these with our own custom commands. 65 | printf("start:\n"); 66 | for (i = 0; i < filesize; i++) { 67 | 68 | if (file[i] >= 0x78 && file[i] <= 0x7f) { 69 | uint8_t reg = file[i] & 7; 70 | printf(" mov R%d, #0x%02x\n", reg, pools[pool_sleep][reg]); 71 | file[i + 1] = pools[pool_sleep][reg]; 72 | i++; 73 | } 74 | 75 | else if (file[i] >= 0xd8 && file[i] <= 0xdf) { 76 | printf(" djnz R%d, %d\n", file[i] & 7, (int8_t)file[i + 1]); 77 | i++; 78 | } 79 | 80 | else if (file[i] == 0xa5) { 81 | 82 | if ((file[i + 1] == file[i + 2]) 83 | && ((file[i + 1] & 0x7f) < SFR_SPOTS)) { 84 | int reg = file[i + 1] & 0x7f; 85 | 86 | // The first instance will have this bit set to 0. The second 87 | // instance will have it set to 1. Thus, you can do interesting 88 | // things here. 89 | int is_anti = (file[i + 1] & 0x80); 90 | if (reg < total) { 91 | uint8_t val; 92 | 93 | if (is_anti) { 94 | if ((pools[pool_valtype][reg] & 3) == 0) 95 | val = pools[pool_val0][reg]; 96 | else if ((pools[pool_valtype][reg] & 3) == 1) 97 | val = ~pools[pool_val0][reg]; 98 | else 99 | val = pools[pool_val1][reg]; 100 | } 101 | else 102 | val = pools[pool_val0][reg]; 103 | 104 | file[i + 0] = 0x75; // mov SFR, #immediate 105 | file[i + 1] = pools[pool_sfr][reg] | 0x80; // Dest register 106 | file[i + 2] = val; // Immediate value 107 | 108 | printf(" mov SFR_%02X, #0x%02x\n", 109 | pools[pool_sfr][reg] | 0x80, val); 110 | } 111 | else { 112 | printf(" nop\n"); 113 | /* Fill with NOPs */ 114 | file[i + 0] = 0; 115 | file[i + 1] = 0; 116 | file[i + 2] = 0; 117 | } 118 | matched++; 119 | i += 2; 120 | } 121 | else { 122 | printf("Error locating special opcode (%d %02x %02x / %02x)\n", 123 | i, file[i+1], file[i+2], file[i+1]&0x7f); 124 | return -1; 125 | } 126 | } 127 | 128 | else if (file[i] == 0x80) { 129 | printf(" sjmp %d\n", (int8_t)file[i + 1]); 130 | i++; 131 | } 132 | 133 | else if (file[i] == 0x00) 134 | printf(" nop\n"); 135 | 136 | else 137 | printf("Unrecognized opcode: 0x%02x\n", file[i]); 138 | } 139 | 140 | if (matched != SFR_SPOTS * 2) { 141 | printf("Couldn't find %d matches, only found %d\n", 142 | SFR_SPOTS * 2, matched); 143 | return -2; 144 | } 145 | 146 | return 0; 147 | } 148 | 149 | 150 | static int interesting_one_cycle(struct sd_state *state, int run, int seed) { 151 | uint8_t pools[MAX_POOLS][MAX_SLOTS]; 152 | uint8_t response[1]; 153 | uint8_t slow_response[64]; 154 | uint8_t file[512+(4*sizeof(uint16_t))]; 155 | int filesize; 156 | int i = 0; 157 | int ret; 158 | 159 | memset(response, 0, sizeof(response)); 160 | memset(file, 0, sizeof(file)); 161 | 162 | fill_rand_pools(run, seed, pools); 163 | 164 | memset(file, 0, sizeof(file)); 165 | int fd = open("fuzzer.bin", O_RDONLY); 166 | if (-1 == fd) { 167 | perror("Couldn't open binary program"); 168 | exit(1); 169 | } 170 | filesize = read(fd, file, 512); 171 | close(fd); 172 | 173 | if (filesize < 0) { 174 | perror("Couldn't read file"); 175 | return -1; 176 | } 177 | 178 | ret = patch_fuzzer(state, file, filesize, pools); 179 | if (ret < 0) 180 | return ret; 181 | 182 | // Actually enter factory mode (sends CMD63/APPO and waits for response) 183 | ret = sd_enter_factory_mode(state, run); 184 | if (-1 == ret) { 185 | printf("Couldn't enter factory mode\n"); 186 | return ret; 187 | } 188 | 189 | // Transmit the file 190 | sd_mmc_dat4_crc16(file, file+(sizeof(file)-8), sizeof(file)-8); 191 | xmit_mmc_dat4(state, file, sizeof(file)); 192 | rcvr_spi(state, response, sizeof(response)); 193 | 194 | 195 | // Wait for some sign of life 196 | int sd_pins = sd_read_pins(state); 197 | int changes = 0; 198 | int sleeptime = 10 *(1 + (pools[pool_misc][pool_misc_sleeptime] & 0x3f)); 199 | for (i = 0; i < sizeof(slow_response); i++) { 200 | usleep(sleeptime); 201 | slow_response[i] = sd_read_pins(state); 202 | if (slow_response[i] != sd_pins) { 203 | changes++; 204 | } 205 | sd_pins = slow_response[i]; 206 | } 207 | 208 | printf("\n"); 209 | printf("Waiting %d usec between samples\n", sleeptime); 210 | printf("Response:\n"); 211 | print_hex(response, sizeof(response)); 212 | printf("%d state changes, slow response:\n", changes); 213 | print_hex(slow_response, sizeof(slow_response)); 214 | printf("Finished up run: %-4d Seed: %8d\n", run, seed); 215 | printf("\n==================================================\n"); 216 | 217 | 218 | if (changes >= 5) { 219 | printf("Potential match\n"); 220 | return 1; 221 | } 222 | 223 | return 0; 224 | } 225 | 226 | int do_fuzz(struct sd_state *state, int *seed, int *loop) { 227 | int run; 228 | int val; 229 | int s; 230 | 231 | if (seed) 232 | val = interesting_one_cycle(state, loop?*loop:0, *seed); 233 | else if (loop) 234 | val = interesting_one_cycle(state, *loop, rand()); 235 | else { 236 | val = 0; 237 | run = 0; 238 | for (; !val; run++) { 239 | s = rand(); 240 | val = interesting_one_cycle(state, run, s); 241 | 242 | // If we get an interesting value, try running it again. 243 | if (val > 0) { 244 | printf("Potentially interesting. " 245 | "Trying seed %d again...\n", s); 246 | val = interesting_one_cycle(state, run, s); 247 | 248 | // If we get an interesting value, try running it again. 249 | if (val>0) { 250 | printf("Still potentially interesting. " 251 | "Trying seed %d one last time...\n", s); 252 | val = interesting_one_cycle(state, run, s); 253 | } 254 | } 255 | 256 | // Re-run when val<0, as it means the card didn't go ready 257 | if (val<0) { 258 | run--; 259 | val = 0; 260 | } 261 | } 262 | } 263 | 264 | return val; 265 | } 266 | -------------------------------------------------------------------------------- /src/ax215/crc-16.c: -------------------------------------------------------------------------------- 1 | #include 2 | static const uint16_t table[256] = 3 | {0, 4129, 8258, 12387, 16516, 20645, 24774, 28903, 33032, 37161, 41290, 4 | 45419, 49548, 53677, 57806, 61935, 4657, 528, 12915, 8786, 21173, 5 | 17044, 29431, 25302, 37689, 33560, 45947, 41818, 54205, 50076, 62463, 6 | 58334, 9314, 13379, 1056, 5121, 25830, 29895, 17572, 21637, 42346, 7 | 46411, 34088, 38153, 58862, 62927, 50604, 54669, 13907, 9842, 5649, 8 | 1584, 30423, 26358, 22165, 18100, 46939, 42874, 38681, 34616, 63455, 9 | 59390, 55197, 51132, 18628, 22757, 26758, 30887, 2112, 6241, 10242, 10 | 14371, 51660, 55789, 59790, 63919, 35144, 39273, 43274, 47403, 23285, 11 | 19156, 31415, 27286, 6769, 2640, 14899, 10770, 56317, 52188, 64447, 12 | 60318, 39801, 35672, 47931, 43802, 27814, 31879, 19684, 23749, 11298, 13 | 15363, 3168, 7233, 60846, 64911, 52716, 56781, 44330, 48395, 36200, 14 | 40265, 32407, 28342, 24277, 20212, 15891, 11826, 7761, 3696, 65439, 15 | 61374, 57309, 53244, 48923, 44858, 40793, 36728, 37256, 33193, 45514, 16 | 41451, 53516, 49453, 61774, 57711, 4224, 161, 12482, 8419, 20484, 17 | 16421, 28742, 24679, 33721, 37784, 41979, 46042, 49981, 54044, 58239, 18 | 62302, 689, 4752, 8947, 13010, 16949, 21012, 25207, 29270, 46570, 19 | 42443, 38312, 34185, 62830, 58703, 54572, 50445, 13538, 9411, 5280, 20 | 1153, 29798, 25671, 21540, 17413, 42971, 47098, 34713, 38840, 59231, 21 | 63358, 50973, 55100, 9939, 14066, 1681, 5808, 26199, 30326, 17941, 22 | 22068, 55628, 51565, 63758, 59695, 39368, 35305, 47498, 43435, 22596, 23 | 18533, 30726, 26663, 6336, 2273, 14466, 10403, 52093, 56156, 60223, 24 | 64286, 35833, 39896, 43963, 48026, 19061, 23124, 27191, 31254, 2801, 25 | 6864, 10931, 14994, 64814, 60687, 56684, 52557, 48554, 44427, 40424, 26 | 36297, 31782, 27655, 23652, 19525, 15522, 11395, 7392, 3265, 61215, 27 | 65342, 53085, 57212, 44955, 49082, 36825, 40952, 28183, 32310, 20053, 28 | 24180, 11923, 16050, 3793, 7920}; 29 | 30 | /***----------Table-driven crc function----------***/ 31 | /* Inputs: - size of the character array, the CRC */ 32 | /* of which is being computed */ 33 | /* - the initial value of the register to */ 34 | /* be used in the calculation */ 35 | /* - a pointer to the first element of */ 36 | /* said character array */ 37 | /* Outputs: the crc as an unsigned short int */ 38 | int crc16(void *data_p, int size) { 39 | uint8_t *data = data_p; 40 | uint16_t crc = 0; 41 | while(size--) { 42 | crc = (crc << 8) ^ table[((crc >> 8) ^ *data++) & 0xFFFF]; 43 | } 44 | return crc; 45 | } 46 | 47 | 48 | /* Table for CRC-7 (polynomial x^7 + x^3 + 1) */ 49 | static const uint8_t crc7_syndrome_table[256] = { 50 | 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 51 | 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, 52 | 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, 53 | 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e, 54 | 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, 55 | 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45, 56 | 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, 57 | 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c, 58 | 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, 59 | 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13, 60 | 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, 61 | 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a, 62 | 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, 63 | 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21, 64 | 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, 65 | 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38, 66 | 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, 67 | 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36, 68 | 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, 69 | 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f, 70 | 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, 71 | 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 72 | 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, 73 | 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d, 74 | 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, 75 | 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52, 76 | 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, 77 | 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b, 78 | 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, 79 | 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60, 80 | 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, 81 | 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79 82 | }; 83 | 84 | static inline uint8_t crc7_byte(uint8_t crc, uint8_t data) 85 | { 86 | return crc7_syndrome_table[(crc << 1) ^ data]; 87 | } 88 | 89 | /** 90 | * crc7 - update the CRC7 for the data buffer 91 | * @crc: previous CRC7 value 92 | * @buffer: data pointer 93 | * @len: number of bytes in the buffer 94 | * Context: any 95 | * 96 | * Returns the updated CRC7 value. 97 | */ 98 | uint8_t crc7(const uint8_t *buffer, int len) 99 | { 100 | uint8_t crc = 0; 101 | while (len--) 102 | crc = crc7_byte(crc, *buffer++); 103 | return crc; 104 | } 105 | 106 | 107 | static uint32_t crc32_tab[] = { 108 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 109 | 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 110 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 111 | 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 112 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 113 | 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 114 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 115 | 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 116 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 117 | 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 118 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 119 | 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 120 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 121 | 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 122 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 123 | 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 124 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 125 | 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 126 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 127 | 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 128 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 129 | 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 130 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 131 | 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 132 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 133 | 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 134 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 135 | 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 136 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 137 | 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 138 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 139 | 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 140 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 141 | 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 142 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 143 | 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 144 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 145 | 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 146 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 147 | 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 148 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 149 | 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 150 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 151 | }; 152 | 153 | uint32_t crc32(const void *buf, int size) 154 | { 155 | const uint8_t *p; 156 | uint32_t crc = 0; 157 | 158 | p = buf; 159 | crc = crc ^ ~0U; 160 | 161 | while (size--) 162 | crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); 163 | 164 | return crc ^ ~0U; 165 | } 166 | -------------------------------------------------------------------------------- /src/ax215/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "sd.h" 13 | #include "gpio.h" 14 | #include "eim.h" 15 | #include "crc-16.h" 16 | 17 | /** Definitions for Novena EIM interface */ 18 | #define CS_PIN GPIO_IS_EIM | 3 19 | #define MISO_PIN GPIO_IS_EIM | 0 20 | #define CLK_PIN GPIO_IS_EIM | 4 21 | #define MOSI_PIN GPIO_IS_EIM | 5 22 | #define DAT1_PIN GPIO_IS_EIM | 1 23 | #define DAT2_PIN GPIO_IS_EIM | 2 24 | #define POWER_PIN 17 //GPIO1_IO17 25 | 26 | 27 | // R1 Response Codes (from SD Card Product Manual v1.9 section 5.2.3.1) 28 | #define R1_IN_IDLE_STATE (1<<0) // The card is in idle state and running initializing process. 29 | #define R1_ERASE_RESET (1<<1) // An erase sequence was cleared before executing because of an out of erase sequence command was received. 30 | #define R1_ILLEGAL_COMMAND (1<<2) // An illegal command code was detected 31 | #define R1_COM_CRC_ERROR (1<<3) // The CRC check of the last command failed. 32 | #define R1_ERASE_SEQ_ERROR (1<<4) // An error in the sequence of erase commands occured. 33 | #define R1_ADDRESS_ERROR (1<<5) // A misaligned address, which did not match the block length was used in the command. 34 | #define R1_PARAMETER (1<<6) // The command's argument (e.g. address, block length) was out of the allowed range for this card. 35 | 36 | enum program_mode { 37 | mode_help, 38 | mode_fuzz, 39 | mode_get_csd_cid, 40 | mode_validate_file, 41 | mode_execute_file, 42 | mode_debugger, 43 | }; 44 | 45 | int dbg_main(struct sd_state *state); 46 | int do_fuzz(struct sd_state *state, int *seed, int *loop); 47 | int do_execute_file(struct sd_state *state, int run, int seed, char *filename); 48 | 49 | static int print_header(uint8_t *bfr) { 50 | printf(" CMD %2d {%02x %02x %02x %02x %02x %02x} ", 51 | bfr[0]&0x3f, bfr[0], bfr[1], bfr[2], bfr[3], bfr[4], bfr[5]); 52 | return 0; 53 | } 54 | 55 | 56 | static int send_cmdX(struct sd_state *state, 57 | uint8_t cmd, 58 | uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4, 59 | int print_size) { 60 | uint8_t bfr[6]; 61 | uint8_t out_bfr[print_size]; 62 | int result; 63 | static int run = 0; 64 | memset(out_bfr, 0, sizeof(out_bfr)); 65 | cmd = (cmd&0x3f)|0x40; 66 | bfr[0] = cmd; 67 | bfr[1] = a1; 68 | bfr[2] = a2; 69 | bfr[3] = a3; 70 | bfr[4] = a4; 71 | bfr[5] = (crc7(bfr, 5)<<1)|1; 72 | result = sd_txrx(state, bfr, sizeof(bfr), out_bfr, print_size); 73 | if (result!=-1 && !(result&R1_ILLEGAL_COMMAND)) { 74 | out_bfr[0] = result; 75 | printf("Run %-4d ", run); 76 | print_header(bfr); 77 | printf("\n"); 78 | print_hex(out_bfr, print_size); 79 | } 80 | run++; 81 | return result; 82 | } 83 | 84 | 85 | static int do_get_csd_cid(struct sd_state *state) { 86 | sd_reset(state, 2); 87 | 88 | printf("CSD:\n"); 89 | send_cmdX(state, 9, 0, 0, 0, 0, 32); 90 | printf("\n"); 91 | 92 | printf("CID:\n"); 93 | send_cmdX(state, 10, 0, 0, 0, 0, 32); 94 | printf("\n"); 95 | return 0; 96 | } 97 | 98 | static int drain_nand_addrs(struct sd_state *state) { 99 | int i; 100 | int val; 101 | int addrs; 102 | for (i=0; addrs; i++) { 103 | val = eim_get(fpga_r_nand_adr_hi); 104 | addrs = eim_get(fpga_r_nand_adr_stat)&eim_nand_adr_bits; 105 | } 106 | return val; 107 | } 108 | 109 | static int read_file(char *filename, uint8_t *bfr, int size) { 110 | int fd = open(filename, O_RDONLY); 111 | if (-1 == fd) { 112 | printf("Unable to load rom file %s: %s\n", filename, strerror(errno)); 113 | return 1; 114 | } 115 | read(fd, bfr, size); 116 | close(fd); 117 | return 0; 118 | } 119 | 120 | 121 | static int load_and_enter_debugger(struct sd_state *state, char *filename) { 122 | uint8_t response[8]; 123 | uint8_t file[512+(4*sizeof(uint16_t))]; 124 | memset(file, 0xff, sizeof(file)); 125 | 126 | // Load in the debugger stub 127 | if (read_file(filename, file, 512)) 128 | return 1; 129 | 130 | while(1) { 131 | int ret; 132 | int tries; 133 | // Actually enter factory mode (sends CMD63/APPO and waits for response) 134 | ret = -1; 135 | for (tries=0; ret<0; tries++) { 136 | ret = sd_enter_factory_mode(state, 0); 137 | if (-1 == ret) 138 | printf("Couldn't enter factory mode, trying again\n"); 139 | } 140 | // Couldn't enter factory mode, abort 141 | if (-1 == ret) 142 | return 1; 143 | 144 | sd_mmc_dat4_crc16(file, file+(sizeof(file)-8), sizeof(file)-8); 145 | xmit_mmc_dat4(state, file, sizeof(file)); 146 | 147 | /* Wait for the debugger to initialize */ 148 | ret = rcvr_mmc_cmd_start(state, 100); 149 | if (-1 == ret) { 150 | printf("DAT0 never started\n"); 151 | continue; 152 | } 153 | printf("Entered factory mode after %d tries\n", ret); 154 | rcvr_spi(state, response, 1); 155 | 156 | break; 157 | } 158 | return 0; 159 | } 160 | 161 | 162 | 163 | static int do_validate_file(struct sd_state *state) { 164 | int addrs; 165 | 166 | // Drain address data 167 | addrs = eim_get(fpga_r_nand_adr_stat)&eim_nand_adr_bits; 168 | printf("Pre-draining %d addresses\n", addrs); 169 | drain_nand_addrs(state); 170 | 171 | sd_reset(state, 1); 172 | send_cmdX(state, 9, 0, 0, 0, 0, 32); 173 | usleep(900000); 174 | 175 | addrs = eim_get(fpga_r_nand_adr_stat)&eim_nand_adr_bits; 176 | printf("Draining %d addresses\n", addrs); 177 | drain_nand_addrs(state); 178 | 179 | usleep(50000); 180 | addrs = eim_get(fpga_r_nand_adr_stat)&eim_nand_adr_bits; 181 | if (addrs) { 182 | printf("Invalid firmware. There are %d addrs left\n", addrs); 183 | } 184 | else { 185 | printf("Firmware okay.\n"); 186 | return 0; 187 | } 188 | 189 | return 1; 190 | } 191 | 192 | 193 | static int do_debugger(struct sd_state *state, char *filename) { 194 | int ret; 195 | do { 196 | if (load_and_enter_debugger(state, filename)) 197 | return 1; 198 | printf("Loaded debugger\n"); 199 | 200 | 201 | ret = dbg_main(state); 202 | } while (ret == -EAGAIN); 203 | return ret; 204 | } 205 | 206 | 207 | 208 | static int print_help(char *name) { 209 | printf("Usage:\n" 210 | "Modes:\n" 211 | "\t%s -f Runs a fuzz test in factory mode\n" 212 | "\t%s -c Boots normally and prints CSD/CID\n" 213 | "\t%s -v Validate the firmware file\n" 214 | "\t%s -d [dbgr] Enters debugger, launching the specified filename\n" 215 | "\t%s -x [file] Enters factory mode and executes the file\n" 216 | "Options:\n" 217 | " -s [seed] Specifies a seed for random values\n" 218 | " -r [run] Execute the loop with run=[loop]\n" 219 | , 220 | name, name, name, name, name); 221 | return 0; 222 | } 223 | 224 | int main(int argc, char **argv) { 225 | int ret = 0; 226 | struct sd_state *state; 227 | enum program_mode mode = mode_help; 228 | int ch; 229 | 230 | int seed; 231 | int have_seed = 0; 232 | 233 | int loop; 234 | int have_loop = 0; 235 | 236 | char prog_filename[512]; 237 | char debugger_filename[512]; 238 | 239 | 240 | srand(time(NULL)); 241 | 242 | state = sd_init(MISO_PIN, MOSI_PIN, CLK_PIN, CS_PIN, 243 | DAT1_PIN, DAT2_PIN, POWER_PIN); 244 | if (!state) 245 | return 1; 246 | 247 | printf("FPGA hardware v%d.%d\n", 248 | eim_get(fpga_r_ddr3_v_major), 249 | eim_get(fpga_r_ddr3_v_minor)); 250 | 251 | while ((ch = getopt(argc, argv, "vfchs:r:x:d:")) != -1) { 252 | switch(ch) { 253 | case 'c': 254 | mode = mode_get_csd_cid; 255 | break; 256 | 257 | case 'f': 258 | mode = mode_fuzz; 259 | break; 260 | 261 | case 's': 262 | have_seed = 1; 263 | seed = strtoul(optarg, NULL, 0); 264 | break; 265 | 266 | case 'r': 267 | have_loop = 1; 268 | loop = strtoul(optarg, NULL, 0); 269 | break; 270 | 271 | case 'v': 272 | mode = mode_validate_file; 273 | break; 274 | 275 | case 'x': 276 | strncpy(prog_filename, optarg, sizeof(prog_filename)-1); 277 | mode = mode_execute_file; 278 | break; 279 | 280 | case 'd': 281 | strncpy(debugger_filename, optarg, sizeof(debugger_filename)-1); 282 | mode = mode_debugger; 283 | break; 284 | 285 | case 'h': 286 | default: 287 | print_help(argv[0]); 288 | return 0; 289 | break; 290 | } 291 | } 292 | 293 | if (!have_seed) 294 | seed = rand(); 295 | if (!have_loop) 296 | loop = 0; 297 | 298 | if (mode == mode_help) 299 | ret = print_help(argv[0]); 300 | else if (mode == mode_fuzz) 301 | ret = do_fuzz(state, have_seed?&seed:NULL, have_loop?&loop:NULL); 302 | else if (mode == mode_get_csd_cid) 303 | ret = do_get_csd_cid(state); 304 | else if (mode == mode_validate_file) 305 | ret = do_validate_file(state); 306 | else if (mode == mode_execute_file) 307 | ret = do_execute_file(state, loop, seed, prog_filename); 308 | else if (mode == mode_debugger) 309 | ret = do_debugger(state, debugger_filename); 310 | 311 | //sd_deinit(&state); 312 | 313 | return ret; 314 | } 315 | -------------------------------------------------------------------------------- /src/ax215/eim.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "gpio.h" 13 | #include "eim.h" 14 | 15 | #define EIM_BASE (0x08000000) 16 | #define EIM_DOUT (0x0010) 17 | #define EIM_DIR (0x0012) 18 | #define EIM_DIN (0x1010) 19 | 20 | static int *mem_32 = 0; 21 | static short *mem_16 = 0; 22 | static char *mem_8 = 0; 23 | static int *prev_mem_range = 0; 24 | 25 | uint8_t cached_dout = 0; 26 | uint8_t cached_dir = 0; 27 | 28 | static int read_kernel_memory(long offset, int virtualized, int size) { 29 | int result; 30 | static int mem_fd; 31 | 32 | int *mem_range = (int *)(offset & ~0xFFFF); 33 | if( mem_range != prev_mem_range ) { 34 | prev_mem_range = mem_range; 35 | 36 | if(mem_32) 37 | munmap(mem_32, 0xFFFF); 38 | if(mem_fd) 39 | close(mem_fd); 40 | 41 | if(virtualized) { 42 | mem_fd = open("/dev/kmem", O_RDWR); 43 | if( mem_fd < 0 ) { 44 | perror("Unable to open /dev/kmem"); 45 | mem_fd = 0; 46 | return -1; 47 | } 48 | } 49 | else { 50 | mem_fd = open("/dev/mem", O_RDWR); 51 | if( mem_fd < 0 ) { 52 | perror("Unable to open /dev/mem"); 53 | mem_fd = 0; 54 | return -1; 55 | } 56 | } 57 | 58 | mem_32 = mmap(0, 0xffff, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, offset&~0xFFFF); 59 | if( -1 == (int)mem_32 ) { 60 | perror("Unable to mmap file"); 61 | 62 | if( -1 == close(mem_fd) ) 63 | perror("Also couldn't close file"); 64 | 65 | mem_fd=0; 66 | return -1; 67 | } 68 | mem_16 = (short *)mem_32; 69 | mem_8 = (char *)mem_32; 70 | } 71 | 72 | int scaled_offset = (offset-(offset&~0xFFFF)); 73 | if(size==1) 74 | result = mem_8[scaled_offset/sizeof(char)]; 75 | else if(size==2) 76 | result = mem_16[scaled_offset/sizeof(short)]; 77 | else 78 | result = mem_32[scaled_offset/sizeof(long)]; 79 | 80 | return result; 81 | } 82 | 83 | int write_kernel_memory(long offset, long value, int virtualized, int size) { 84 | int old_value = read_kernel_memory(offset, virtualized, size); 85 | int scaled_offset = (offset-(offset&~0xFFFF)); 86 | if(size==1) 87 | mem_8[scaled_offset/sizeof(char)] = value; 88 | else if(size==2) 89 | mem_16[scaled_offset/sizeof(short)] = value; 90 | else 91 | mem_32[scaled_offset/sizeof(long)] = value; 92 | return old_value; 93 | } 94 | 95 | 96 | static int prep_eim(void) { 97 | int i; 98 | 99 | // set up pads to be mapped to EIM 100 | for( i = 0; i < 16; i++ ) { 101 | write_kernel_memory( 0x20e0114 + i*4, 0x0, 0, 4 ); // mux mapping 102 | write_kernel_memory( 0x20e0428 + i*4, 0xb0b1, 0, 4 ); // pad strength config'd for a 100MHz rate 103 | } 104 | 105 | // mux mapping 106 | write_kernel_memory( 0x20e046c - 0x314, 0x0, 0, 4 ); // BCLK 107 | write_kernel_memory( 0x20e040c - 0x314, 0x0, 0, 4 ); // CS0 108 | write_kernel_memory( 0x20e0410 - 0x314, 0x0, 0, 4 ); // CS1 109 | write_kernel_memory( 0x20e0414 - 0x314, 0x0, 0, 4 ); // OE 110 | write_kernel_memory( 0x20e0418 - 0x314, 0x0, 0, 4 ); // RW 111 | write_kernel_memory( 0x20e041c - 0x314, 0x0, 0, 4 ); // LBA 112 | write_kernel_memory( 0x20e0468 - 0x314, 0x0, 0, 4 ); // WAIT 113 | write_kernel_memory( 0x20e0408 - 0x314, 0x0, 0, 4 ); // A16 114 | write_kernel_memory( 0x20e0404 - 0x314, 0x0, 0, 4 ); // A17 115 | write_kernel_memory( 0x20e0400 - 0x314, 0x0, 0, 4 ); // A18 116 | 117 | // pad strength 118 | write_kernel_memory( 0x20e046c, 0xb0b1, 0, 4 ); // BCLK 119 | write_kernel_memory( 0x20e040c, 0xb0b1, 0, 4 ); // CS0 120 | write_kernel_memory( 0x20e0410, 0xb0b1, 0, 4 ); // CS1 121 | write_kernel_memory( 0x20e0414, 0xb0b1, 0, 4 ); // OE 122 | write_kernel_memory( 0x20e0418, 0xb0b1, 0, 4 ); // RW 123 | write_kernel_memory( 0x20e041c, 0xb0b1, 0, 4 ); // LBA 124 | write_kernel_memory( 0x20e0468, 0xb0b1, 0, 4 ); // WAIT 125 | write_kernel_memory( 0x20e0408, 0xb0b1, 0, 4 ); // A16 126 | write_kernel_memory( 0x20e0404, 0xb0b1, 0, 4 ); // A17 127 | write_kernel_memory( 0x20e0400, 0xb0b1, 0, 4 ); // A18 128 | 129 | write_kernel_memory( 0x020c4080, 0xcf3, 0, 4 ); // ungate eim slow clocks 130 | 131 | // rework timing for sync use 132 | // 0011 0 001 1 001 0 001 00 00 1 011 1 0 1 1 1 1 1 1 133 | // PSZ WP GBC AUS CSREC SP DSZ BCS BCD WC BL CREP CRE RFL WFL MUM SRD SWR CSEN 134 | // 135 | // PSZ = 0011 64 words page size 136 | // WP = 0 (not protected) 137 | // GBC = 001 min 1 cycles between chip select changes 138 | // AUS = 0 address shifted according to port size 139 | // CSREC = 001 min 1 cycles between CS, OE, WE signals 140 | // SP = 0 no supervisor protect (user mode access allowed) 141 | // DSZ = 001 16-bit port resides on DATA[15:0] 142 | // BCS = 00 0 clock delay for burst generation 143 | // BCD = 00 divide EIM clock by 0 for burst clock 144 | // WC = 1 write accesses are continuous burst length 145 | // BL = 011 32 word memory wrap length 146 | // CREP = 1 non-PSRAM, set to 1 147 | // CRE = 0 CRE is disabled 148 | // RFL = 1 fixed latency reads 149 | // WFL = 1 fixed latency writes 150 | // MUM = 1 multiplexed mode enabled 151 | // SRD = 1 synch reads 152 | // SWR = 1 synch writes 153 | // CSEN = 1 chip select is enabled 154 | 155 | // write_kernel_memory( 0x21b8000, 0x5191C0B9, 0, 4 ); 156 | write_kernel_memory( 0x21b8000, 0x31910BBF, 0, 4 ); 157 | 158 | // EIM_CS0GCR2 159 | // MUX16_BYP_GRANT = 1 160 | // ADH = 1 (1 cycles) 161 | // 0x1001 162 | write_kernel_memory( 0x21b8004, 0x1000, 0, 4 ); 163 | 164 | 165 | // EIM_CS0RCR1 166 | // 00 000101 0 000 0 000 0 000 0 000 0 000 0 000 167 | // RWSC RADVA RAL RADVN OEA OEN RCSA RCSN 168 | // RWSC 000101 5 cycles for reads to happen 169 | // 170 | // 0000 0111 0000 0011 0000 0000 0000 0000 171 | // 0 7 0 3 0 0 0 0 172 | // 0000 0101 0000 0000 0 000 0 000 0 000 0 000 173 | write_kernel_memory( 0x21b8008, 0x05000000, 0, 4 ); 174 | write_kernel_memory( 0x21b8008, 0x0A024000, 0, 4 ); 175 | write_kernel_memory( 0x21b8008, 0x09014000, 0, 4 ); 176 | // EIM_CS0RCR2 177 | // 0000 0000 0 000 00 00 0 010 0 001 178 | // APR PAT RL RBEA RBEN 179 | // APR = 0 mandatory because MUM = 1 180 | // PAT = XXX because APR = 0 181 | // RL = 00 because async mode 182 | // RBEA = 000 these match RCSA/RCSN from previous field 183 | // RBEN = 000 184 | // 0000 0000 0000 0000 0000 0000 185 | write_kernel_memory( 0x21b800c, 0x00000000, 0, 4 ); 186 | 187 | // EIM_CS0WCR1 188 | // 0 0 000100 000 000 000 000 010 000 000 000 189 | // WAL WBED WWSC WADVA WADVN WBEA WBEN WEA WEN WCSA WCSN 190 | // WAL = 0 use WADVN 191 | // WBED = 0 allow BE during write 192 | // WWSC = 000100 4 write wait states 193 | // WADVA = 000 same as RADVA 194 | // WADVN = 000 this sets WE length to 1 (this value +1) 195 | // WBEA = 000 same as RBEA 196 | // WBEN = 000 same as RBEN 197 | // WEA = 010 2 cycles between beginning of access and WE assertion 198 | // WEN = 000 1 cycles to end of WE assertion 199 | // WCSA = 000 cycles to CS assertion 200 | // WCSN = 000 cycles to CS negation 201 | // 1000 0111 1110 0001 0001 0100 0101 0001 202 | // 8 7 E 1 1 4 5 1 203 | // 0000 0111 0000 0100 0000 1000 0000 0000 204 | // 0 7 0 4 0 8 0 0 205 | // 0000 0100 0000 0000 0000 0100 0000 0000 206 | // 0 4 0 0 0 4 0 0 207 | 208 | write_kernel_memory( 0x21b8010, 0x09080800, 0, 4 ); 209 | // write_kernel_memory( 0x21b8010, 0x02040400, 0, 4 ); 210 | 211 | // EIM_WCR 212 | // BCM = 1 free-run BCLK 213 | // GBCD = 0 don't divide the burst clock 214 | write_kernel_memory( 0x21b8090, 0x701, 0, 4 ); 215 | 216 | // EIM_WIAR 217 | // ACLK_EN = 1 218 | write_kernel_memory( 0x21b8094, 0x10, 0, 4 ); 219 | 220 | return 0; 221 | } 222 | 223 | static uint16_t *ranges[8]; 224 | 225 | static uint16_t *eim_open(enum eim_type type) { 226 | static int fd; 227 | int range = (type>>16)&7; 228 | 229 | if (ranges[range]) 230 | return ((uint16_t *) (((uint8_t *)ranges[range])+(type&0xffff))); 231 | 232 | prep_eim(); 233 | 234 | fd = open("/dev/mem", O_RDWR); 235 | if (fd == -1) { 236 | perror("Couldn't open /dev/mem"); 237 | return NULL; 238 | } 239 | 240 | // printf("Opening up range %d, offset %p\n", range, EIM_BASE+(type&0xffff0000)); 241 | ranges[range] = mmap(NULL, 0xffff, PROT_READ | PROT_WRITE, MAP_SHARED, fd, EIM_BASE+(type&0xffff0000)); 242 | if (ranges[range] == ((uint16_t *)-1)) { 243 | perror("Couldn't mmap EIM region"); 244 | return NULL; 245 | } 246 | 247 | return eim_open(type); 248 | } 249 | 250 | uint16_t eim_get(enum eim_type type) { 251 | return *eim_open(type); 252 | } 253 | 254 | uint16_t eim_set(enum eim_type type, uint16_t value) { 255 | uint16_t *ptr = eim_open(type); 256 | uint16_t old = *ptr; 257 | *ptr = value; 258 | return old; 259 | } 260 | 261 | int eim_set_direction(int gpio, int is_output) { 262 | gpio &= ~GPIO_IS_EIM; 263 | if (is_output) { 264 | if (cached_dir & (1<> gpio)&1; 301 | } 302 | 303 | -------------------------------------------------------------------------------- /src/as31/lexer.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * FILE: lexer.c 3 | * PACKAGE: as31 - 8031/8051 Assembler. 4 | * 5 | * DESCRIPTION: 6 | * This file contains the lexical tokenizer for the assembler. 7 | * Since yacc is being used the lexer is called yylex(). 8 | * 9 | * In order to produce a listing, some record of the users 10 | * source line must be kept. This is done by adding 11 | * get_ch(), and unget_ch() routine which returns/ungets a character 12 | * but also places information into a secret array. 13 | * 14 | * When a newline is encountered the text line is returned as 15 | * an attribute on the '\n' character. 16 | * 17 | * REVISION HISTORY: 18 | * Jan. 19, 1990 - Created. (Ken Stauffer) 19 | * 20 | * AUTHOR: 21 | * All code in this file written by Ken Stauffer (University of Calgary). 22 | * January, 1990. 23 | * 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "as31.h" 32 | #include "parser.h" 33 | 34 | 35 | int lineno; 36 | int last_token_len=0; 37 | char last_token[256], prev_token[256]; 38 | 39 | static char line[100]; 40 | static char *lineptr=line; 41 | 42 | /* ---------------------------------------------------------------------- 43 | * get_ch: 44 | * Get a character from stdin, place char in line[] 45 | */ 46 | 47 | int get_ch(void) 48 | { 49 | register int c; 50 | 51 | c = getchar(); 52 | if (last_token_len >=0 && last_token_len < 254 && 53 | c != EOF && (last_token_len > 0 || !isspace(c))) { 54 | last_token[last_token_len++] = c; 55 | } 56 | if( c != EOF && lineptr - line < sizeof(line) ) 57 | *lineptr++ = c; 58 | return(c); 59 | } 60 | 61 | /* ---------------------------------------------------------------------- 62 | * unget_ch: 63 | * Unget a character and move lineptr back by one. 64 | */ 65 | 66 | void unget_ch(int c) 67 | { 68 | ungetc(c,stdin); 69 | if( lineptr > line ) 70 | lineptr--; 71 | } 72 | 73 | 74 | 75 | /* when there is a parse error, yyparse should call here to */ 76 | /* advance to the end of the current line, so we can continue */ 77 | /* parsing the rest of the file */ 78 | 79 | int seek_eol(void) 80 | { 81 | int c; 82 | 83 | last_token_len = -1; 84 | do { 85 | c = get_ch(); 86 | } while (c != '\n' && c != EOF); 87 | if (c == '\n') { 88 | unget_ch(c); 89 | return 1; 90 | } 91 | return 0; 92 | } 93 | 94 | /* return a pointer to the last successfully parsed token, so */ 95 | /* we can give a nicer error message when there is a syntax error */ 96 | 97 | const char *get_last_token(void) 98 | { 99 | /* 100 | if (last_token_len < 0) last_token_len = 0; 101 | last_token[last_token_len] = '\0'; 102 | */ 103 | return prev_token; 104 | } 105 | 106 | 107 | 108 | /* ---------------------------------------------------------------------- 109 | * yylex: 110 | * The tokens themselves are returned via return(token) 111 | * 112 | * Some tokens have attributes. These attributes are returned 113 | * by setting a global variable yylval: 114 | * 115 | * yylval.value 116 | * numbers (any base) 117 | * strings (in pass 1). 118 | * bit positions .0, .1, .2, ... 119 | * 120 | * yylval.str 121 | * strings (in pass 2). 122 | * '\n' (both passes). 123 | * 124 | * yylval.sym 125 | * User defined symbols. 126 | * 127 | * yylval.op 128 | * Reserved keyword (opcode/directive/misc.) 129 | * 130 | * No other fields in yylval are used by yylex(). 131 | * 132 | * Characters that do not have an attribute do 133 | * not set anything in the yylval variable. 134 | * 135 | */ 136 | 137 | 138 | 139 | int yylex(void) 140 | { 141 | static int nl_flag=0; /* sync. error messages and the cur. line */ 142 | register int c; 143 | char buf[1024]; /* temporary buffer */ 144 | char *p; /* general pointer */ 145 | struct symbol *sym; 146 | struct opcode *op; 147 | 148 | int octal=0,hex=0,decimal=0,binary=0; 149 | register long value = 0; 150 | 151 | if (last_token_len > 0) { 152 | last_token[last_token_len] = '\0'; 153 | strcpy(prev_token, last_token); 154 | } else { 155 | *prev_token = '\0'; 156 | } 157 | last_token_len=0; 158 | 159 | if( nl_flag ) { 160 | nl_flag = 0; 161 | lineno++; 162 | } 163 | 164 | for(;;) { 165 | c = get_ch(); 166 | switch(c) { 167 | case EOF: return(EOF); 168 | case ' ': 169 | case '\r': 170 | case '\t': 171 | break; 172 | 173 | case '\n': 174 | nl_flag = 1; 175 | yylval.str = line; 176 | *lineptr = '\0'; 177 | lineptr = line; 178 | return('\n'); 179 | 180 | case ';': 181 | while((c=get_ch()) != EOF && c!='\n'); 182 | nl_flag= 1; 183 | yylval.str = line; 184 | *lineptr = '\0'; 185 | lineptr = line; 186 | return(c); 187 | 188 | case '"': 189 | p = buf; 190 | while((c=get_ch()) != EOF && c!='"' && c!='\n') { 191 | if( c == '\\' ) { 192 | switch(c=get_ch()) { 193 | case 'n': c = '\n'; break; 194 | case 'r': c = '\r'; break; 195 | case 't': c = '\t'; break; 196 | case 'b': c = '\b'; break; 197 | case '"': c = '"'; break; 198 | case '\\': c = '\\'; break; 199 | default: 200 | warn("Invalid escape character: \\%c",c); 201 | } 202 | } 203 | if( p-buf='0' && c<='7' ) { 233 | yylval.value = c-'0'; 234 | return(BITPOS); 235 | } 236 | unget_ch(c); 237 | return('.'); 238 | 239 | case '\'': 240 | c = get_ch(); 241 | if( c=='\\' ) { 242 | switch(c=get_ch()) { 243 | case 'n': c = '\n'; break; 244 | case 'r': c = '\r'; break; 245 | case 't': c = '\t'; break; 246 | case 'b': c = '\b'; break; 247 | case '0': c = 0; break; 248 | case 'o': c = 0; break; 249 | case 'O': c = 0; break; 250 | case '\\': c = '\\'; break; 251 | case '\'': c = '\''; break; 252 | default: 253 | warn("Invalid escape character: \\%c",c); 254 | } 255 | } 256 | if( get_ch() != '\'' ) 257 | warn("Missing quote in character constant"); 258 | yylval.value = c; 259 | return(VALUE); 260 | 261 | case '0': /* parse a number */ 262 | case '1': /* could be followed by a: */ 263 | case '2': /* 'b','B' - Binary */ 264 | case '3': /* 'h','H' - Hex */ 265 | case '4': /* 'd','D' - Decimal */ 266 | case '5': /* 'o','O' - Octal */ 267 | case '6': /* *** Numbers must start with a digit */ 268 | case '7': /* Numbers could be also preceeded by: */ 269 | case '8': /* 0x - Hex */ 270 | case '9': /* 0b - binary */ 271 | 272 | p = buf; 273 | do { 274 | if( p-buf='a' && *p<='f' ) 330 | value += *p-'a'+ 10; 331 | else if( *p>='A' && *p<='F' ) 332 | value += *p-'A'+ 10; 333 | else 334 | warn("Invalid hex digit: %c",*p); 335 | } 336 | yylval.value = value; 337 | return(VALUE); 338 | } 339 | 340 | if (decimal) { 341 | if (hex) warn("ambiguous number, dec or hex"); 342 | if (binary) warn("ambiguous number, dec or bin"); 343 | if (octal) warn("ambiguous number, dec or oct"); 344 | for(p=buf; *p; p++ ) { 345 | if( isdigit(*p) ) 346 | value = value*10 + *p-'0'; 347 | else 348 | warn("Invalid decimal digit: %c",*p); 349 | } 350 | yylval.value = value; 351 | return(VALUE); 352 | } 353 | 354 | if (octal) { 355 | if (hex) warn("ambiguous number, oct or hex"); 356 | if (binary) warn("ambiguous number, oct or bin"); 357 | if (decimal) warn("ambiguous number, oct or dec"); 358 | for(p=buf; *p; p++ ) { 359 | if( *p>='0' && *p<='7' ) 360 | value = (value << 3) + (*p - '0'); 361 | else 362 | warn("Invalid octal digit: %c",*p); 363 | } 364 | yylval.value = value; 365 | return(VALUE); 366 | } 367 | 368 | default: 369 | if( isalpha(c) || c=='_' ) { 370 | p = buf; 371 | do { 372 | if( p-buftype); 381 | } 382 | sym = looksym(buf); 383 | yylval.sym = sym; 384 | return(SYMBOL); 385 | } else 386 | return(c); 387 | } /* switch */ 388 | } /* for */ 389 | 390 | } /* yylex */ 391 | 392 | 393 | -------------------------------------------------------------------------------- /src/ax215/disasm-mnem.c: -------------------------------------------------------------------------------- 1 | /* global.c 2 | * 3 | * Data shared by all modules 4 | * 5 | * Copyright 2001 - 2003 by David Sullins 6 | * 7 | * This file is part of Dis51. 8 | * 9 | * Dis51 is free software; you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, version 2 of the License. 12 | * 13 | * Dis51 is distributed in the hope that it will be useful, but WITHOUT ANY 14 | * WArrANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * Dis51; if not, write to the Free Software Foundation, Inc., 59 Temple 20 | * Place, Suite 330, Boston, MA 02111-1307 USA 21 | * 22 | * You may contact the author at davesullins@earthlink.net. 23 | */ 24 | 25 | int Lst; 26 | short lbl[65536]; 27 | 28 | const char mnemonic[256][20] = { 29 | /* 0 */ 30 | "nop", 31 | "ajmp %s\n", 32 | "ljmp %s\n", 33 | "rr A", 34 | "inc A", 35 | "inc %s", 36 | "inc @R0", 37 | "inc @R1", 38 | "inc R0", 39 | "inc R1", 40 | "inc R2", 41 | "inc R3", 42 | "inc R4", 43 | "inc R5", 44 | "inc R6", 45 | "inc R7", 46 | /* 1 */ 47 | "jbc %s, %s", 48 | "acall %s", 49 | "lcall %s", 50 | "rrc A", 51 | "dec A", 52 | "dec %s", 53 | "dec @R0", 54 | "dec @R1", 55 | "dec R0", 56 | "dec R1", 57 | "dec R2", 58 | "dec R3", 59 | "dec R4", 60 | "dec R5", 61 | "dec R6", 62 | "dec R7", 63 | /* 2 */ 64 | "jb %s, %s", 65 | "ajmp %s\n", 66 | "ret\n", 67 | "rl A", 68 | "add A, #%s", 69 | "add A, %s", 70 | "add A, @R0", 71 | "add A, @R1", 72 | "add A, R0", 73 | "add A, R1", 74 | "add A, R2", 75 | "add A, R3", 76 | "add A, R4", 77 | "add A, R5", 78 | "add A, R6", 79 | "add A, R7", 80 | /* 3 */ 81 | "jnb %s, %s", 82 | "acall %s", 83 | "reti\n", 84 | "rlc A", 85 | "addc A, #%s", 86 | "addc A, %s", 87 | "addc A, @R0", 88 | "addc A, @R1", 89 | "addc A, R0", 90 | "addc A, R1", 91 | "addc A, R2", 92 | "addc A, R3", 93 | "addc A, R4", 94 | "addc A, R5", 95 | "addc A, R6", 96 | "addc A, R7", 97 | /* 4 */ 98 | "jc %s", 99 | "ajmp %s\n", 100 | "orl %s, A", 101 | "orl %s, #%s", 102 | "orl A, #%s", 103 | "orl A, %s", 104 | "orl A, @R0", 105 | "orl A, @R1", 106 | "orl A, R0", 107 | "orl A, R1", 108 | "orl A, R2", 109 | "orl A, R3", 110 | "orl A, R4", 111 | "orl A, R5", 112 | "orl A, R6", 113 | "orl A, R7", 114 | /* 5 */ 115 | "jnc %s", 116 | "acall %s", 117 | "anl %s, A", 118 | "anl %s, #%s", 119 | "anl A, #%s", 120 | "anl A, %s", 121 | "anl A, @R0", 122 | "anl A, @R1", 123 | "anl A, R0", 124 | "anl A, R1", 125 | "anl A, R2", 126 | "anl A, R3", 127 | "anl A, R4", 128 | "anl A, R5", 129 | "anl A, R6", 130 | "anl A, R7", 131 | /* 6 */ 132 | "jz %s", 133 | "ajmp %s\n", 134 | "xrl %s, A", 135 | "xrl %s, #%s", 136 | "xrl A, #%s", 137 | "xrl A, %s", 138 | "xrl A, @R0", 139 | "xrl A, @R1", 140 | "xrl A, R0", 141 | "xrl A, R1", 142 | "xrl A, R2", 143 | "xrl A, R3", 144 | "xrl A, R4", 145 | "xrl A, R5", 146 | "xrl A, R6", 147 | "xrl A, R7", 148 | /* 7 */ 149 | "jnz %s", 150 | "acall %s", 151 | "orl C, %s", 152 | "jmp @A+DPTR\n", 153 | "mov A, #%s", 154 | "mov %s, #%s", 155 | "mov @R0, #%s", 156 | "mov @R1, #%s", 157 | "mov R0, #%s", 158 | "mov R1, #%s", 159 | "mov R2, #%s", 160 | "mov R3, #%s", 161 | "mov R4, #%s", 162 | "mov R5, #%s", 163 | "mov R6, #%s", 164 | "mov R7, #%s", 165 | /* 8 */ 166 | "sjmp %s\n", 167 | "ajmp %s\n", 168 | "anl C, %s", 169 | "movc A, @A+PC", 170 | "div AB", 171 | "mov %s, %s", 172 | "mov %s, @R0", 173 | "mov %s, @R1", 174 | "mov %s, R0", 175 | "mov %s, R1", 176 | "mov %s, R2", 177 | "mov %s, R3", 178 | "mov %s, R4", 179 | "mov %s, R5", 180 | "mov %s, R6", 181 | "mov %s, R7", 182 | /* 9 */ 183 | "mov DPTR, #0%X%02X", 184 | "acall %s", 185 | "mov %s, C", 186 | "movc A, @A+DPTR", 187 | "subb A, #%s", 188 | "subb A, %s", 189 | "subb A, @R0", 190 | "subb A, @R1", 191 | "subb A, R0", 192 | "subb A, R1", 193 | "subb A, R2", 194 | "subb A, R3", 195 | "subb A, R4", 196 | "subb A, R5", 197 | "subb A, R6", 198 | "subb A, R7", 199 | /* A */ 200 | "orl C, /%s", 201 | "ajmp %s\n", 202 | "mov C, %s", 203 | "inc DPTR", 204 | "mul AB", 205 | "", /* undefined opcode */ 206 | "mov @R0, %s", 207 | "mov @R1, %s", 208 | "mov R0, %s", 209 | "mov R1, %s", 210 | "mov R2, %s", 211 | "mov R3, %s", 212 | "mov R4, %s", 213 | "mov R5, %s", 214 | "mov R6, %s", 215 | "mov R7, %s", 216 | /* B */ 217 | "anl C, /%s", 218 | "acall %s", 219 | "cpl %s", 220 | "cpl C", 221 | "cjne A, #%s, %s", 222 | "cjne A, %s, %s", 223 | "cjne @R0, #%s, %s", 224 | "cjne @R1, #%s, %s", 225 | "cjne R0, #%s, %s", 226 | "cjne R1, #%s, %s", 227 | "cjne R2, #%s, %s", 228 | "cjne R3, #%s, %s", 229 | "cjne R4, #%s, %s", 230 | "cjne R5, #%s, %s", 231 | "cjne R6, #%s, %s", 232 | "cjne R7, #%s, %s", 233 | /* C */ 234 | "push %s", 235 | "ajmp %s\n", 236 | "clr %s", 237 | "clr C", 238 | "swap A", 239 | "xch A, %s", 240 | "xch A, @R0", 241 | "xch A, @R1", 242 | "xch A, R0", 243 | "xch A, R1", 244 | "xch A, R2", 245 | "xch A, R3", 246 | "xch A, R4", 247 | "xch A, R5", 248 | "xch A, R6", 249 | "xch A, R7", 250 | /* D */ 251 | "pop %s", 252 | "acall %s", 253 | "setb %s", 254 | "setb C", 255 | "da A", 256 | "djnz %s, %s", 257 | "xchd A, @R0", 258 | "xchd A, @R1", 259 | "djnz R0, %s", 260 | "djnz R1, %s", 261 | "djnz R2, %s", 262 | "djnz R3, %s", 263 | "djnz R4, %s", 264 | "djnz R5, %s", 265 | "djnz R6, %s", 266 | "djnz R7, %s", 267 | /* E */ 268 | "movx A, @DPTR", 269 | "ajmp %s\n", 270 | "movx A, @R0", 271 | "movx A, @R1", 272 | "clr A", 273 | "mov A, %s", 274 | "mov A, @R0", 275 | "mov A, @R1", 276 | "mov A, R0", 277 | "mov A, R1", 278 | "mov A, R2", 279 | "mov A, R3", 280 | "mov A, R4", 281 | "mov A, R5", 282 | "mov A, R6", 283 | "mov A, R7", 284 | /* F */ 285 | "movx @DPTR, A", 286 | "acall %s", 287 | "movx @R0, A", 288 | "movx @R1, A", 289 | "cpl A", 290 | "mov %s, A", 291 | "mov @R0, A", 292 | "mov @R1, A", 293 | "mov R0, A", 294 | "mov R1, A", 295 | "mov R2, A", 296 | "mov R3, A", 297 | "mov R4, A", 298 | "mov R5, A", 299 | "mov R6, A", 300 | "mov R7, A" 301 | }; 302 | 303 | 304 | /* op_format table 305 | * 306 | * 0 = illegal opcode 307 | * 1 = no operands 308 | * 2 = one immediate operand 309 | * 3 = one direct operand 310 | * 4 = one bit-addressed operand 311 | * 5 = one relative address operand 312 | * 6 = one absolute address operand 313 | * 7 = two-byte immediate operand 314 | * 8 = two operands: direct, immediate 315 | * 9 = two operands: direct, direct 316 | * 10 = two operands: immediate, relative address 317 | * 11 = two operands: direct, relative address 318 | * 12 = two operands: bit address, relative address 319 | * 13 = two-byte long address operand 320 | */ 321 | const char op_format[256] = { 322 | 1, 6, 13, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 */ 323 | 12, 6, 13, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */ 324 | 12, 6, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 2 */ 325 | 12, 6, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 3 */ 326 | 5, 6, 3, 8, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */ 327 | 5, 6, 3, 8, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 5 */ 328 | 5, 6, 3, 8, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */ 329 | 5, 6, 4, 1, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 7 */ 330 | 5, 6, 4, 1, 1, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 8 */ 331 | 7, 6, 4, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */ 332 | 4, 6, 4, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* A */ 333 | 4, 6, 4, 1, 10, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, /* B */ 334 | 3, 6, 4, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C */ 335 | 3, 6, 4, 1, 1, 11, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, /* D */ 336 | 1, 6, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E */ 337 | 1, 6, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* F */ 338 | }; 339 | 340 | const char sfbitname[128][6] = { 341 | /* 80 */ 342 | "P0.0", "P0.1", "P0.2", "P0.3", "P0.4", "P0.5", "P0.6", "P0.7", 343 | /* 88 */ 344 | "IT0", "IE0", "IT1", "IE1", "TR0", "TF0", "TR1", "TF1", 345 | /* 90 */ 346 | "P1.0", "P1.1", "P1.2", "P1.3", "P1.4", "P1.5", "P1.6", "P1.7", 347 | /* 98 */ 348 | "RI", "TI", "RB8", "TB8", "REN", "SM2", "SM1", "SM0", 349 | /* A0 */ 350 | "P2.0", "P2.1", "P2.2", "P2.3", "P2.4", "P2.5", "P2.6", "P2.7", 351 | /* A8 */ 352 | "EX0", "ET0", "EX1", "ET1", "ES", "0xAD", "0xAE", "EA", 353 | /* B0 */ 354 | "P3.0", "P3.1", "P3.2", "P3.3", "P3.4", "P3.5", "P3.6", "P3.7", 355 | /* B8 */ 356 | "PX0", "PT0", "PX1", "PT1", "PS", "0xBD", "0xBE", "0xBF", 357 | /* C0 */ 358 | "0xC0", "0xC1", "0xC2", "0xC3", "0xC4", "0xC5", "0xC6", "0xC7", 359 | /* C8 */ 360 | "0xC8", "0xC9", "0xCA", "0xCB", "0xCC", "0xCD", "0xCE", "0xCF", 361 | /* D0 */ 362 | "P", "0xD1", "OV", "RS0", "RS1", "F0", "AC", "CY", 363 | /* D8 */ 364 | "0xD8", "0xD9", "0xDA", "0xDB", "0xDC", "0xDD", "0xDE", "0xDF", 365 | /* E0 */ 366 | "ACC.0", "ACC.1", "ACC.2", "ACC.3", "ACC.4", "ACC.5", "ACC.6", "ACC.7", 367 | /* E8 */ 368 | "0xE8", "0xE9", "0xEA", "0xEB", "0xEC", "0xED", "0xEE", "0xEF", 369 | /* F0 */ 370 | "B.0", "B.1", "B.2", "B.3", "B.4", "B.5", "B.6", "B.7", 371 | /* F8 */ 372 | "0xF8", "0xF9", "0xFA", "0xFB", "0xFC", "0xFD", "0xFE", "0xFF" 373 | }; 374 | 375 | const char sfrname[128][5] = { 376 | /* 80 */ 377 | "P0", "SP", "DPL", "DPH", "0x84", "0x85", "0x86", "PCON", 378 | /* 88 */ 379 | "TCON", "TMOD", "TL0", "TL1", "TH0", "TH1", "0x8E", "0x8F", 380 | /* 90 */ 381 | "P1", "0x91", "0x92", "0x93", "0x94", "0x95", "0x96", "0x97", 382 | /* 98 */ 383 | "SCON", "SBUF", "0x9A", "0x9B", "0x9C", "0x9D", "0x9E", "0x9F", 384 | /* A0 */ 385 | "P2", "0xA1", "0xA2", "0xA3", "0xA4", "0xA5", "0xA6", "0xA7", 386 | /* A8 */ 387 | "IE", "0xA9", "0xAA", "0xAB", "0xAC", "0xAD", "0xAE", "0xAF", 388 | /* B0 */ 389 | "P3", "0xB1", "0xB2", "0xB3", "0xB4", "0xB5", "0xB6", "0xB7", 390 | /* B8 */ 391 | "IP", "0xB9", "0xBA", "0xBB", "0xBC", "0xBD", "0xBE", "0xBF", 392 | /* C0 */ 393 | "0xC0", "0xC1", "0xC2", "0xC3", "0xC4", "0xC5", "0xC6", "0xC7", 394 | /* C8 */ 395 | "0xC8", "0xC9", "0xCA", "0xCB", "0xCC", "0xCD", "0xCE", "0xCF", 396 | /* D0 */ 397 | "PSW", "0xD1", "0xD2", "0xD3", "0xD4", "0xD5", "0xD6", "0xD7", 398 | /* D8 */ 399 | "0xD8", "0xD9", "0xDA", "0xDB", "0xDC", "0xDD", "0xDE", "0xDF", 400 | /* E0 */ 401 | "ACC", "0xE1", "0xE2", "0xE3", "0xE4", "0xE5", "0xE6", "0xE7", 402 | /* E8 */ 403 | "0xE8", "0xE9", "0xEA", "0xEB", "0xEC", "0xED", "0xEE", "0xEF", 404 | /* F0 */ 405 | "B", "0F1", "0xF2", "0xF3", "0xF4", "0xF5", "0xF6", "0xF7", 406 | /* F8 */ 407 | "0xF8", "0xF9", "0xFA", "0xFB", "0xFC", "0xFD", "0xFE", "0xFFh" 408 | }; 409 | -------------------------------------------------------------------------------- /fpga/novena-fpga.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | struct reg_info { 9 | char *name; 10 | int offset; 11 | int size; 12 | char *description; 13 | }; 14 | 15 | static int fd = 0; 16 | static int *mem_32 = 0; 17 | static short *mem_16 = 0; 18 | static char *mem_8 = 0; 19 | static int *prev_mem_range = 0; 20 | 21 | 22 | int read_kernel_memory(long offset, int virtualized, int size) { 23 | int result; 24 | 25 | int *mem_range = (int *)(offset & ~0xFFFF); 26 | if( mem_range != prev_mem_range ) { 27 | // fprintf(stderr, "New range detected. Reopening at memory range %p\n", mem_range); 28 | prev_mem_range = mem_range; 29 | 30 | if(mem_32) 31 | munmap(mem_32, 0xFFFF); 32 | if(fd) 33 | close(fd); 34 | 35 | if(virtualized) { 36 | fd = open("/dev/kmem", O_RDWR); 37 | if( fd < 0 ) { 38 | perror("Unable to open /dev/kmem"); 39 | fd = 0; 40 | return -1; 41 | } 42 | } 43 | else { 44 | fd = open("/dev/mem", O_RDWR); 45 | if( fd < 0 ) { 46 | perror("Unable to open /dev/mem"); 47 | fd = 0; 48 | return -1; 49 | } 50 | } 51 | 52 | mem_32 = mmap(0, 0xffff, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset&~0xFFFF); 53 | if( -1 == (int)mem_32 ) { 54 | perror("Unable to mmap file"); 55 | 56 | if( -1 == close(fd) ) 57 | perror("Also couldn't close file"); 58 | 59 | fd=0; 60 | return -1; 61 | } 62 | mem_16 = (short *)mem_32; 63 | mem_8 = (char *)mem_32; 64 | } 65 | 66 | int scaled_offset = (offset-(offset&~0xFFFF)); 67 | // fprintf(stderr, "Returning offset 0x%08x\n", scaled_offset); 68 | if(size==1) 69 | result = mem_8[scaled_offset/sizeof(char)]; 70 | else if(size==2) 71 | result = mem_16[scaled_offset/sizeof(short)]; 72 | else 73 | result = mem_32[scaled_offset/sizeof(long)]; 74 | 75 | return result; 76 | } 77 | 78 | #define TEST_LEN 32768 79 | 80 | void test_fpga(void) { 81 | int result; 82 | volatile unsigned short *cs0; 83 | volatile unsigned short dummy; 84 | int i; 85 | unsigned short test[TEST_LEN]; 86 | unsigned short tval; 87 | unsigned int iters = 0, errs = 0; 88 | 89 | if(mem_32) 90 | munmap(mem_32, 0xFFFF); 91 | if(fd) 92 | close(fd); 93 | 94 | fd = open("/dev/mem", O_RDWR); 95 | if( fd < 0 ) { 96 | perror("Unable to open /dev/mem"); 97 | fd = 0; 98 | return; 99 | } 100 | 101 | mem_32 = mmap(0, 0xffff, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x08000000); 102 | cs0 = (volatile unsigned short *)mem_32; 103 | 104 | i = 0; 105 | while(1) { 106 | for( i = 0; i < TEST_LEN; i ++ ) { 107 | test[i] = (unsigned short) rand(); 108 | #if 0 109 | if( !(i % 16) ) 110 | printf( "\n" ); 111 | printf( "%04x ", test[i] ); 112 | #endif 113 | } 114 | 115 | for( i = 0; i < TEST_LEN; i ++ ) { 116 | cs0[i] = test[i]; 117 | } 118 | #if 0 119 | printf( "\n. . . . . . . . .\n" ); 120 | #endif 121 | 122 | for( i = 0; i < TEST_LEN; i ++ ) { 123 | iters++; 124 | #if 0 125 | if( !(i % 16) ) 126 | printf( "\n" ); 127 | printf( "%04x ", cs0[i] ); 128 | #else 129 | tval = cs0[i]; 130 | if( test[i] != tval ) { 131 | printf( "\nFail at %d: wrote %04x, got %04x/%04x\n", i, test[i], tval, cs0[i] ); 132 | errs++; 133 | } else { 134 | #if 0 135 | if( !(i % 16) ) 136 | printf( "\n" ); 137 | printf( "%04x ", test[i] ); 138 | #endif 139 | } 140 | #endif 141 | } 142 | #if 0 143 | printf( "\n---------------\n" ); 144 | #endif 145 | if( !(iters % 0x100000) ) { 146 | printf( "%d iters, %d errs\n", iters, errs ); 147 | fflush(stdout); 148 | } 149 | } 150 | 151 | } 152 | 153 | int write_kernel_memory(long offset, long value, int virtualized, int size) { 154 | int old_value = read_kernel_memory(offset, virtualized, size); 155 | int scaled_offset = (offset-(offset&~0xFFFF)); 156 | if(size==1) 157 | mem_8[scaled_offset/sizeof(char)] = value; 158 | else if(size==2) 159 | mem_16[scaled_offset/sizeof(short)] = value; 160 | else 161 | mem_32[scaled_offset/sizeof(long)] = value; 162 | return old_value; 163 | } 164 | 165 | void print_usage(char *progname) { 166 | printf("Usage:\n" 167 | "%s [-h]\n" 168 | "\t-h This help message\n" 169 | "\t-s Set up FPGA comms parameter\n" 170 | "\t-t Test FPGA memory interface\n" 171 | "", progname); 172 | } 173 | 174 | 175 | static inline int swab(int arg) { 176 | return ((arg&0xff)<<24) | ((arg&0xff00)<<8) | ((arg&0xff0000)>>8) | ((arg&0xff000000)>>24); 177 | } 178 | 179 | void setup_fpga() { 180 | int i; 181 | printf( "setting up EIM pads and configuring timing\n" ); 182 | // set up pads to be mapped to EIM 183 | for( i = 0; i < 16; i++ ) { 184 | write_kernel_memory( 0x20e0114 + i*4, 0x0, 0, 4 ); // mux mapping 185 | write_kernel_memory( 0x20e0428 + i*4, 0xb0b1, 0, 4 ); // pad strength config'd for a 100MHz rate 186 | } 187 | 188 | // mux mapping 189 | write_kernel_memory( 0x20e046c - 0x314, 0x0, 0, 4 ); // BCLK 190 | write_kernel_memory( 0x20e040c - 0x314, 0x0, 0, 4 ); // CS0 191 | write_kernel_memory( 0x20e0410 - 0x314, 0x0, 0, 4 ); // CS1 192 | write_kernel_memory( 0x20e0414 - 0x314, 0x0, 0, 4 ); // OE 193 | write_kernel_memory( 0x20e0418 - 0x314, 0x0, 0, 4 ); // RW 194 | write_kernel_memory( 0x20e041c - 0x314, 0x0, 0, 4 ); // LBA 195 | write_kernel_memory( 0x20e0468 - 0x314, 0x0, 0, 4 ); // WAIT 196 | write_kernel_memory( 0x20e0408 - 0x314, 0x0, 0, 4 ); // A16 197 | write_kernel_memory( 0x20e0404 - 0x314, 0x0, 0, 4 ); // A17 198 | write_kernel_memory( 0x20e0400 - 0x314, 0x0, 0, 4 ); // A18 199 | 200 | // pad strength 201 | write_kernel_memory( 0x20e046c, 0xb0b1, 0, 4 ); // BCLK 202 | write_kernel_memory( 0x20e040c, 0xb0b1, 0, 4 ); // CS0 203 | write_kernel_memory( 0x20e0410, 0xb0b1, 0, 4 ); // CS1 204 | write_kernel_memory( 0x20e0414, 0xb0b1, 0, 4 ); // OE 205 | write_kernel_memory( 0x20e0418, 0xb0b1, 0, 4 ); // RW 206 | write_kernel_memory( 0x20e041c, 0xb0b1, 0, 4 ); // LBA 207 | write_kernel_memory( 0x20e0468, 0xb0b1, 0, 4 ); // WAIT 208 | write_kernel_memory( 0x20e0408, 0xb0b1, 0, 4 ); // A16 209 | write_kernel_memory( 0x20e0404, 0xb0b1, 0, 4 ); // A17 210 | write_kernel_memory( 0x20e0400, 0xb0b1, 0, 4 ); // A18 211 | 212 | write_kernel_memory( 0x020c4080, 0xcf3, 0, 4 ); // ungate eim slow clocks 213 | 214 | // EIM_CS0GCR1 215 | // 0101 0 001 1 001 0 001 11 00 0 000 1 0 1 1 1 0 0 1 216 | // PSZ WP GBC AUS CSREC SP DSZ BCS BCD WC BL CREP CRE RFL WFL MUM SRD SWR CSEN 217 | // 218 | // PSZ = 0101 256 words page size 219 | // WP = 0 (not protected) 220 | // GBC = 001 min 1 cycles between chip select changes 221 | // AUS = 0 address shifted according to port size 222 | // CSREC = 001 min 1 cycles between CS, OE, WE signals 223 | // SP = 0 no supervisor protect (user mode access allowed) 224 | // DSZ = 001 16-bit port resides on DATA[15:0] 225 | // BCS = 11 3 clock delay for burst generation 226 | // BCD = 00 divide EIM clock by 1 for burst clock 227 | // WC = 0 specify write bust according to BL 228 | // BL = 000 4 words wrap burst length 229 | // CREP = 1 non-PSRAM, set to 1 230 | // CRE = 0 CRE is disabled 231 | // RFL = 1 fixed latency reads (don't monitor WAIT) 232 | // WFL = 1 fixed latency writes (don't monitor WAIT) 233 | // MUM = 1 multiplexed mode enabled 234 | // SRD = 0 no synch reads 235 | // SWR = 0 no synch writes 236 | // CSEN = 1 chip select is enabled 237 | 238 | // 0101 0111 1111 0001 1100 0000 1011 1 0 0 1 239 | // 0x5 7 F 1 C 0 B 9 240 | 241 | // 0101 0001 1001 0001 1100 0000 1011 1001 242 | // 5 1 9 1 c 0 B 9 243 | 244 | write_kernel_memory( 0x21b8000, 0x5191C0B9, 0, 4 ); 245 | 246 | // EIM_CS0GCR2 247 | // MUX16_BYP_GRANT = 1 248 | // ADH = 1 (1 cycles) 249 | // 0x1001 250 | write_kernel_memory( 0x21b8004, 0x1001, 0, 4 ); 251 | 252 | 253 | // EIM_CS0RCR1 254 | // 00 000101 0 000 0 000 0 000 0 000 0 000 0 000 255 | // RWSC RADVA RAL RADVN OEA OEN RCSA RCSN 256 | // RWSC 000101 5 cycles for reads to happen 257 | // 258 | // 0000 0111 0000 0011 0000 0000 0000 0000 259 | // 0 7 0 3 0 0 0 0 260 | // 0000 0101 0000 0000 0 000 0 000 0 000 0 000 261 | // write_kernel_memory( 0x21b8008, 0x05000000, 0, 4 ); 262 | write_kernel_memory( 0x21b8008, 0x0A024000, 0, 4 ); 263 | // EIM_CS0RCR2 264 | // 0000 0000 0 000 00 00 0 010 0 001 265 | // APR PAT RL RBEA RBEN 266 | // APR = 0 mandatory because MUM = 1 267 | // PAT = XXX because APR = 0 268 | // RL = 00 because async mode 269 | // RBEA = 000 these match RCSA/RCSN from previous field 270 | // RBEN = 000 271 | // 0000 0000 0000 0000 0000 0000 272 | write_kernel_memory( 0x21b800c, 0x00000000, 0, 4 ); 273 | 274 | // EIM_CS0WCR1 275 | // 0 0 000100 000 000 000 000 010 000 000 000 276 | // WAL WBED WWSC WADVA WADVN WBEA WBEN WEA WEN WCSA WCSN 277 | // WAL = 0 use WADVN 278 | // WBED = 0 allow BE during write 279 | // WWSC = 000100 4 write wait states 280 | // WADVA = 000 same as RADVA 281 | // WADVN = 000 this sets WE length to 1 (this value +1) 282 | // WBEA = 000 same as RBEA 283 | // WBEN = 000 same as RBEN 284 | // WEA = 010 2 cycles between beginning of access and WE assertion 285 | // WEN = 000 1 cycles to end of WE assertion 286 | // WCSA = 000 cycles to CS assertion 287 | // WCSN = 000 cycles to CS negation 288 | // 1000 0111 1110 0001 0001 0100 0101 0001 289 | // 8 7 E 1 1 4 5 1 290 | // 0000 0111 0000 0100 0000 1000 0000 0000 291 | // 0 7 0 4 0 8 0 0 292 | // 0000 0100 0000 0000 0000 0100 0000 0000 293 | // 0 4 0 0 0 4 0 0 294 | 295 | write_kernel_memory( 0x21b8010, 0x09080600, 0, 4 ); 296 | 297 | // EIM_WCR 298 | // BCM = 1 free-run BCLK 299 | // GBCD = 0 don't divide the burst clock 300 | write_kernel_memory( 0x21b8090, 0x1, 0, 4 ); 301 | 302 | // EIM_WIAR 303 | // ACLK_EN = 1 304 | write_kernel_memory( 0x21b8094, 0x10, 0, 4 ); 305 | 306 | printf( "done.\n" ); 307 | } 308 | 309 | int main(int argc, char **argv) { 310 | int dump_registers = 0; 311 | unsigned int read_offset = 0; 312 | unsigned int write_offset = 0; 313 | unsigned int write_value = 0; 314 | int virtualized = 0; 315 | int ch; 316 | int fd; 317 | 318 | char *prog = argv[0]; 319 | argv++; 320 | argc--; 321 | 322 | if(!argc) { 323 | print_usage(prog); 324 | return 1; 325 | } 326 | 327 | while(argc > 0) { 328 | if(!strcmp(*argv, "-h")) { 329 | argc--; 330 | argv++; 331 | print_usage(prog); 332 | } 333 | else if(!strcmp(*argv, "-s")) { 334 | argc--; 335 | argv++; 336 | setup_fpga(); 337 | } 338 | else if(!strcmp(*argv, "-t")) { 339 | argc--; 340 | argv++; 341 | test_fpga(); 342 | } 343 | else { 344 | print_usage(prog); 345 | return 1; 346 | } 347 | } 348 | 349 | return 0; 350 | } 351 | -------------------------------------------------------------------------------- /src/ax215/execute.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "sd.h" 16 | #include "gpio.h" 17 | #include "eim.h" 18 | #include "crc-16.h" 19 | 20 | #define ROM_FILENAME "data-ax215.rom" 21 | /** Definitions for Novena EIM interface */ 22 | #define CS_PIN GPIO_IS_EIM | 3 23 | #define MISO_PIN GPIO_IS_EIM | 0 24 | #define CLK_PIN GPIO_IS_EIM | 4 25 | #define MOSI_PIN GPIO_IS_EIM | 5 26 | #define DAT1_PIN GPIO_IS_EIM | 1 27 | #define DAT2_PIN GPIO_IS_EIM | 2 28 | #define POWER_PIN 17 //GPIO1_IO17 29 | 30 | 31 | // R1 Response Codes (from SD Card Product Manual v1.9 section 5.2.3.1) 32 | #define R1_IN_IDLE_STATE (1<<0) // The card is in idle state and running initializing process. 33 | #define R1_ERASE_RESET (1<<1) // An erase sequence was cleared before executing because of an out of erase sequence command was received. 34 | #define R1_ILLEGAL_COMMAND (1<<2) // An illegal command code was detected 35 | #define R1_COM_CRC_ERROR (1<<3) // The CRC check of the last command failed. 36 | #define R1_ERASE_SEQ_ERROR (1<<4) // An error in the sequence of erase commands occured. 37 | #define R1_ADDRESS_ERROR (1<<5) // A misaligned address, which did not match the block length was used in the command. 38 | #define R1_PARAMETER (1<<6) // The command's argument (e.g. address, block length) was out of the allowed range for this card. 39 | 40 | enum execute_mode { 41 | dump_rom, 42 | enter_debugger, 43 | known_state, 44 | }; 45 | 46 | 47 | static int read_file(char *filename, uint8_t *bfr, int size) { 48 | int ret; 49 | int fd; 50 | 51 | fd = open(filename, O_RDONLY); 52 | if (-1 == fd) { 53 | printf("Unable to load rom file %s: %s\n", filename, strerror(errno)); 54 | return 1; 55 | } 56 | ret = read(fd, bfr, size); 57 | if (-1 == ret) 58 | perror("Couldn't read from file"); 59 | 60 | ret = close(fd); 61 | if (-1 == ret) 62 | perror("Couldn't close file"); 63 | return 0; 64 | } 65 | 66 | static int look_for_known_state(struct sd_state *state, int sleeptime) { 67 | // Wait for some sign of life 68 | int sd_pins = sd_read_pins(state); 69 | int i; 70 | uint8_t slow_response[512]; 71 | int changes = 0; 72 | for (i = 0; i < sizeof(slow_response); i++) { 73 | usleep(sleeptime); 74 | slow_response[i] = sd_read_pins(state); 75 | if (slow_response[i] != sd_pins) { 76 | changes++; 77 | } 78 | sd_pins = slow_response[i]; 79 | } 80 | 81 | printf("Observed %d changes:\n", changes); 82 | print_hex(slow_response, sizeof(slow_response)); 83 | return changes; 84 | } 85 | 86 | int do_dump_rom(struct sd_state *state, int sleeptime) { 87 | int fd; 88 | int offset = 0; 89 | 90 | // Wait for some sign of life 91 | uint8_t sd_pins; 92 | uint8_t slow_response; 93 | int seeks; 94 | uint8_t byte, bit; 95 | int dbg = 0; 96 | uint8_t *rom; 97 | int rom_size = 65536; 98 | int first_bit = 1; 99 | 100 | fd = open(ROM_FILENAME, O_RDWR | O_CREAT | O_TRUNC, 0644); 101 | if (-1 == fd) { 102 | perror("Unable to open output rom file"); 103 | return -1; 104 | } 105 | 106 | if (-1 == lseek(fd, rom_size - 1, SEEK_SET)) { 107 | perror("Couldn't seek to grow output file"); 108 | return -1; 109 | } 110 | byte = 0; 111 | if (-1 == write(fd, &byte, 1)) { 112 | perror("Couldn't grow output rom file"); 113 | return -1; 114 | } 115 | if (-1 == lseek(fd, 0, SEEK_SET)) { 116 | perror("Couldn't seek to beginning of file"); 117 | return -1; 118 | } 119 | 120 | rom = mmap(0, rom_size - 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 121 | if( -1 == (int)rom ) { 122 | perror("Unable to mmap output rom file"); 123 | 124 | if( -1 == close(fd) ) 125 | perror("Also couldn't close file"); 126 | 127 | return -1; 128 | } 129 | 130 | memset(rom, 0, rom_size); 131 | for (offset = 0; offset < rom_size; offset++) { 132 | byte = 0; 133 | for (bit = 0; bit < 8; bit++) { 134 | uint8_t values[256]; 135 | memset(values, 0, sizeof(values)); 136 | 137 | seeks = 0; 138 | do { 139 | usleep(sleeptime); 140 | slow_response = sd_read_pins(state); 141 | if (dbg) 142 | printf("%02x ", slow_response); 143 | values[slow_response]++; 144 | if (seeks++ > 300) { 145 | printf("Card hung\n"); 146 | goto bail; 147 | } 148 | } while (slow_response == 0x48); 149 | 150 | /* Give the other pin a little more time to settle */ 151 | for (seeks = 0; seeks < 3; seeks++) { 152 | usleep(sleeptime); 153 | slow_response = sd_read_pins(state); 154 | if (dbg) 155 | printf("%02x ", slow_response); 156 | values[slow_response]++; 157 | } 158 | 159 | seeks = 0; 160 | do { 161 | usleep(sleeptime); 162 | slow_response = sd_read_pins(state); 163 | if (dbg) 164 | printf("%02x ", slow_response); 165 | values[slow_response]++; 166 | if (seeks++ > 300) { 167 | printf("Card hung\n"); 168 | goto bail; 169 | } 170 | } while (slow_response != 0x48); 171 | 172 | /* Count which byte "wins" */ 173 | int max = 0; 174 | for (seeks = 0; seeks < 256; seeks++) 175 | if (values[seeks] > values[max] && seeks != 0x48) 176 | max = seeks; 177 | 178 | sd_pins = max; 179 | if (dbg) 180 | printf(" [%02x] ", sd_pins); 181 | 182 | if (first_bit) { 183 | printf(" First bit, ignoring\n"); 184 | first_bit = 0; 185 | bit--; 186 | continue; 187 | } 188 | 189 | if ((sd_pins & 0x10)) { 190 | byte |= (1 << (7 - bit)); 191 | if (dbg) 192 | printf(" - 1\n"); 193 | } 194 | else { 195 | if (dbg) 196 | printf(" - 0\n"); 197 | } 198 | } 199 | rom[offset] = byte; 200 | if (!dbg) 201 | fprintf(stderr, "\r%d%% %d/%d bytes [0x%02x]", 202 | (offset * 100) / 65536,offset, 65536, byte); 203 | else 204 | printf("~~ Byte: [0x%02x]\n", byte); 205 | 206 | /* 207 | if (offset >= 2) { 208 | if (rom[0] == 1 && rom[1] == 2 && rom[2] == 4) { 209 | printf("No dice\n"); 210 | goto bail; 211 | } 212 | else { 213 | printf("Success?\n"); 214 | munmap(rom, rom_size); 215 | close(fd); 216 | return 0; 217 | } 218 | } 219 | */ 220 | } 221 | 222 | return 0; 223 | 224 | bail: 225 | munmap(rom, rom_size); 226 | close(fd); 227 | return 1; 228 | } 229 | 230 | static int do_send_debugger_hello(struct sd_state *state) 231 | { 232 | uint8_t cmdsize = 6; 233 | uint8_t cmd[cmdsize]; 234 | int i; 235 | int ret = 0; 236 | 237 | for (i=0; i Can be set to 0, stays 0 152 | 0xf1 -> Can be set to 0, stays 0 153 | 0xf2 -> Can be set to 0, stays 0 154 | 0xf3 -> Can be set to 0, reads 0x60 155 | 0xf4 -> Can be set to 0, reads 0xff 156 | 0xf5 -> Can be set to 0, stays 0 157 | 0xf6 -> Can be set to 0, stays 0 158 | 0xf7 -> Can be set to 0, reads 0x07 159 | 0xf8 - 0xff -> Can be set to 0, stays 0 160 | 161 | 162 | Extended Instructions 163 | ===================== 164 | 165 | All extended instructions begin with 0xa5. 166 | 167 | 0xa5 0x16 -> Increment ER1 168 | 169 | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 170 | | 8 | 9 | A | B | C | D | E | F | 171 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 172 | 00 | | | | | | | | | 173 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 174 | 08 | | | | | | | | | 175 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 176 | 10 | NOT32 | CLR32 | INC32 | SUB32 | NOT32 | CLR32 | INC32 | SUB32 | 177 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 178 | 18 | NOT32 | CLR32 | INC32 | SUB32 | NOT32 | CLR32 | INC32 | SUB32 | 179 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 180 | 20 | | | | | | | | | 181 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 182 | 28 | | | | | | | | | 183 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 184 | 30 | | | | | | | | | 185 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 186 | 38 | | | | | | | | | 187 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 188 | 40 | | | | | | | | | 189 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 190 | 48 | | | | | | | | | 191 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 192 | 50 | | | | | | | | | 193 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 194 | 58 | | | | | | | | | 195 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 196 | 60 | | | | | | | | | 197 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 198 | 68 | | | | | | | | | 199 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 200 | 70 | | | | | | | | | 201 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 202 | 78 | | | | | | | | | 203 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 204 | 80 | | | | | | | | | 205 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 206 | 88 | | | | | | | | | 207 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 208 | 90 | | | | | | | | | 209 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 210 | 98 | | | | | | | | | 211 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 212 | A0 | | | | | | | | | 213 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 214 | A8 | | | | | | | | | 215 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 216 | B0 | | | | | | | | | 217 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 218 | B8 | | | | | | | | | 219 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 220 | C0 | | | | | | | | | 221 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 222 | C8 | | | | | | | | | 223 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 224 | D0 | | | | | | | | | 225 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 226 | D8 | | | | | | | | | 227 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 228 | E0 | | | | | | | | | 229 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 230 | E8 | | | | | | | | | 231 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 232 | F0 | | | | | | | | | 233 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 234 | F8 | | | | | | | | | 235 | -----+-------+-------+-------+-------+-------+-------+-------+-------+ 236 | 237 | -------------------------------------------------------------------------------- /tests/extra.ref: -------------------------------------------------------------------------------- 1 | :10100000A5E5E0A5FE4C0000000000000000000087 2 | :10101000000000000000000000000000FFFFFFFFD4 3 | :081020004C69737400020048E2 4 | :1010400011257D14C2D1114CDDFC0125EFF5835132 5 | :101050004FEEF582514FE493FAA3E493FBA3E4939C 6 | :10106000FCEA5408700FEA035478F8EA54074890F1 7 | :1010700016C8938008EAC4540F901362935403F87F 8 | :101080002EFEEF3400FF743A512A719D20D121EADF 9 | :10109000514F719DB80104790B8011EB514F719D37 10 | :1010A000B8020479088005EC514F7906719DD9FC8E 11 | :1010B000EA54087010901748EA035478F8EA540785 12 | :1010C0004893F980099017C8EAC4540F93F9901E09 13 | :1010D000FE7808C374204007E99309A2E7547F51C2 14 | :1010E0002AD8F1741BC0E07411C0E0EA5408700FF4 15 | :1010F000EA035478F8EA5407489016C8938008EA3F 16 | :10110000C4540F9013629354FC03031490111D23D5 17 | :101110002582F582E43583F583E4730125412D4171 18 | :101120003C21812172414841044152415821A22170 19 | :10113000D7415E4169416D4108411021AA218321B7 20 | :101140007441714177417D413E411C418121DF4124 21 | :101150001441C54185418B41914195419B41A94134 22 | :10116000AF41B541BB410C41BF41CB41D741E74104 23 | :10117000ED2231F67440512A7452512AEA54014149 24 | :101180004531F6EB20E703EB414F9012F5E493A3D2 25 | :1011900060F5F8C39B7003020038E493A330E7FACC 26 | :1011A00080EB511031F8742F512AEB547823C4F896 27 | :1011B000EB54806014901372E893901F933582F57E 28 | :1011C000825002058331978005E82420514F742E08 29 | :1011D000512AEB5407414531F6318331F8ECFBEBF2 30 | :1011E0002EF582EB20E703E48002E4F43FF583026E 31 | :1011F00000367440412A5108742C512A7420412A27 32 | :101200007423412A318331F87441412A31AA31F8DB 33 | :101210007443412A31F25108742B512A7444512AE3 34 | :101220007450512A7454512A7452020030EF54F809 35 | :10123000F8EAC403540748514FEB414F31F674525A 36 | :10124000512AEA540702002E510831F85100EB02EE 37 | :1012500000343183ECFB414A511031F821AA510886 38 | :1012600031F85100EB514F21DB513E416031744167 39 | :101270006051087442412A513E31F821DF31832107 40 | :10128000DB31AA21DB513E31F84108513E31F821D2 41 | :1012900083513E414A318331F8413EEBC0E0ECFBE3 42 | :1012A000318331F8D0E0FB2183318331F82174316F 43 | :1012B0007431F84108317431F821833174414A5155 44 | :1012C0001C31F85100EB514FEC414F31F631F251E6 45 | :1012D00008742B512A411C31F631F25108742B51FC 46 | :1012E0002A7450512A411031F631F2411C31F25129 47 | :1012F0001C31F84108E04143C38153D0824450CCB3 48 | :10130000834450C88050B09050B1A050B2B050B398 49 | :1013100099534255C6CD5448B2C85432434FCECCEF 50 | :10132000544CB2CB5243415032C8CA52434150325E 51 | :10133000CC8C5448B08A544CB08D5448B18B544C2A 52 | :10134000B1F0C2D05053D7A849C5B849D089544D3F 53 | :101350004FC48854434FCE9853434FCE8750434F8A 54 | :10136000CE00595909090909097A7E0976330952CB 55 | :101370000971000206080C0E101214161B1E202301 56 | :101380002425F8F0E493C398227950E58DF404F80D 57 | :10139000D8FED9F722514F743A412A514F74204157 58 | :0113A0002A22 59 | :10140000A5E5E0A5FE53000000000000000000007C 60 | :10141000000000000000000000000000FFFFFFFFD0 61 | :0C14200053696E676C652D537465700095 62 | :1014400030B306901D85020045900013E49324FEFE 63 | :101450006005901DA88146A393F8E4A393F58288C4 64 | :101460008374027182700EA3741471827007A37466 65 | :10147000EF71826011A882A983901DB59146E95150 66 | :101480004FE8514F0125E5B85404F5B8901D689117 67 | :1014900046EF514FEE514F901D52914612003C20A5 68 | :1014A000D50D5007901D7131970125AE82AF83C2D3 69 | :1014B0008A901DC49146901EBC3197E4758108C086 70 | :1014C000E0C0E08E828F83F5D0F8F9FAFBFCFDFED8 71 | :1014D000FFF5F0757CDD757D14D2AAD2AF737189EA 72 | :1014E000D0E0F9D0E0F8D082D083D0D0D0E032C0C4 73 | :1014F000E0C0D0C083C082E8C0E0E9C0E07189D21A 74 | :1015000099719D719DE58124FBF8E6719BE5F07171 75 | :101510009B08E62354015145719D08E6514F08E6AA 76 | :10152000719B719D08E6719508E67195EA7195EBDE 77 | :101530007195EC7195ED7195EE7195EF719B719DC3 78 | :10154000E824F8719B719D719DE57C8E7CFEE57DA4 79 | :101550008F7DFFEAC0E0EBC0E0ECC0E0D2D1114CDF 80 | :10156000D0E0FCD0E0FBD0E0FAAF7DAE7CE581249A 81 | :10157000F9F8E6F57C08E6F57D120062120040B449 82 | :101580000D0281DEB4200281DEB43F07901E35914A 83 | :1015900046A179B45113901EB53197C2AA718975CD 84 | :1015A000080075090075810932B44802A1CDB45212 85 | :1015B00002A1FDB45302C167B44102C1AAB42E070F 86 | :1015C000901EBC3197A179A179743D412A901E03E8 87 | :1015D0003197E47195719DA88118E6719B08E651D9 88 | :1015E0004F7802790EA1ECE871957910719DE65162 89 | :1015F0004F08D9F81125B880EE1125A17990134430 90 | :101600003197B1C9E58124FCF8E6719B901348A895 91 | :10161000A8D16090134BA8B8D16090134EA889D17F 92 | :1016200060901353A888D160901358A898D1609007 93 | :10163000135DA887D1607454512A7430512AB1C9FE 94 | :10164000E58C514FE58A514F719D7454512A743184 95 | :10165000512AB1C9E58D514FE58B514F1125A17923 96 | :101660003197B1C9E8619B7817719DD8FC901DEB4B 97 | :101670003197E58124F9F8E68E7CFE08E68F7DFF40 98 | :10168000EAC0E0EBC0E0ECC0E0D2D1114CD0E0FC0D 99 | :10169000D0E0FBD0E0FAE58124F9F8EEAE7CF57CF1 100 | :1016A000F608EFAF7DF57DF6A179E58124FBF89092 101 | :1016B0001E25319712003A400820D505F61125A1C4 102 | :1016C00079901D713197A179AD066F393946494935 103 | :1016D00063066F39394649496306AD39160E111153 104 | :1016E0006306AD39160E111166061A1F160E11117A 105 | :1016F00066061A1F160E111166061A1F160E111114 106 | :1017000066062269161F9292660622A14D8386867E 107 | :101710009B06969D160E11112606225D4DAD8E8EEE 108 | :101720002606423D2F2B37374606423D390E111112 109 | :101730004606423D39571111A5061111390E1111F6 110 | :10174000A9068989391A89895A0E48732B2B2B2BA4 111 | :1017500030004375212121212E0E676E06060606F4 112 | :1017600038006A700A0A0A0A330E5D5D5D5D5D5DD0 113 | :101770003B00121212121212410E8F8F8F8F8F8F19 114 | :101780003E005D354C4C4C4C7C0E124F244C4C4C66 115 | :101790004C004C4F808080805D0E4C2B57924C4CFF 116 | :1017A00012001C1C15151515630E191984888888DC 117 | :1017B000600078781F278B8B530E5353194C4C4C79 118 | :1017C000530053531C4C4C4C2B21060A5D128F4C7A 119 | :0817D0004C804C1588274C4C9D 120 | :10180000A5E5E0A5FE450000000000000000000086 121 | :10181000000000000000000000000000FFFFFFFFCC 122 | :101820004D656D6F727920456469746F722028561A 123 | :06183000543130302900A4 124 | :101840007C0051C6ECC2E3FC1200623119B41B02E9 125 | :10185000618DB40B024124B40A02414BB408024129 126 | :1018600066B415024195B40C0451C60144B411028A 127 | :10187000618DB4030FEC54FEFC71CF901D36B14660 128 | :1018800051E10144B4040FEC4401FC71CF901D3BC5 129 | :10189000B14651E10144B4070221ECB4050221E054 130 | :1018A000B406022159B4010FEC30E198D2E2FC9168 131 | :1018B00054916471210144B4180FEC30E186C2E206 132 | :1018C000FC9154916471210144B419024141B41A4C 133 | :1018D000024146F5F0EC20E102014430E210E5F06F 134 | :1018E0007198B5F0F48F838E821200564195E5F021 135 | :1018F00012004012006540E1F88F838E82EC20E3F5 136 | :101900000AE8FDECD2E3FC71210148EDC454F02853 137 | :10191000120056ECC2E3FC4195C0E0EC20E106C2A7 138 | :10192000E3FCD0E02230E3F9D0E0C0E01200401246 139 | :10193000006550EED0E0C0E0B41B0EECC2E3FC71D9 140 | :1019400021D0E0D0E0D0E001448F838E82ED120000 141 | :1019500056ECC2E3FC712180C9EC540270020144D0 142 | :101960009154ECC0E09019C2B14C12003C404820A8 143 | :10197000D545A882A9839019D2B14612003C4037C0 144 | :1019800020D534AC82AD839019DBB14C12003A40C3 145 | :101990002620D523FAECFEEDFFD0E0FC8882898377 146 | :1019A000EA120056EEB5820CEFB5830891549164AB 147 | :1019B00051E10144A380E9D0E0FC9154916471218C 148 | :1019C000014446696C6C1F833B2046697273743A0C 149 | :1019D000200020204C6173743A200020A83A200097 150 | :1019E0009154EC6402FC9164712101449154901A69 151 | :1019F0001DB14CECC0E012003CD0E0FC401320D5FF 152 | :101A000010AE82AF8371CF741471D5916451E1012E 153 | :101A10004471CF741471D59164712101441F831FE7 154 | :101A2000813A2000714DEEC39410FEEF9400FFEE5A 155 | :101A3000F454F06008740171DD7169014451E101F1 156 | :101A4000441F51E101440F51E10144714DEE241056 157 | :101A5000FEEF3400FFEE54F06008740171D5716937 158 | :101A6000014451E10144714D740371E5EEC39401E9 159 | :101A7000FEEF9400FFEE44F0F4600471690144EE5F 160 | :101A8000F454F0600C743071ED740171DD71690112 161 | :101A90004451E10144714D740371ED8E828F83A333 162 | :101AA000AE82AF83EE540F600471690144EE54F0CE 163 | :101AB000600C743071E5740171D57169014451E1B4 164 | :101AC00001447420A140901CFCB146913BB1499166 165 | :101AD00018B1499132B149741071D59132B149911F 166 | :101AE0006471CF740271D57582008F837810B1490B 167 | :101AF000120036743AB140AA82AB8351C271AAB1C6 168 | :101B000043A3E582540F70F38A828B8351C251C282 169 | :101B100051C271AA7198B140A3E582540F70F3D8F5 170 | :101B2000CD71CFEEC4540F240371D5EE540F243879 171 | :101B300071ED71F571B37198B1409101EE540F23BD 172 | :101B4000F4243471E571F571B3B1438101EE540FA2 173 | :101B500023F4243171ED71B37198B140EE540F2329 174 | :101B6000F4243471E571B3A143EE540F23F424310E 175 | :101B700071ED71B3719871F5B1409101EE540F237D 176 | :101B8000F4243471E571B371F5B1438101EE54F081 177 | :101B9000C4F4241371D5A149547FB47F0374202267 178 | :101BA000C3942050027400242022EC20E003E4932C 179 | :101BB00022E022C083C0828F838E82EC20E30D203E 180 | :101BC000E004E4938001E0D082D08322ED80F8919C 181 | :101BD0000B7448A140910BB14F7442A140910BB1DD 182 | :101BE0004F7441A140910BB14F7444A140910BB18E 183 | :101BF0004F7443A140901BFAA1461B5B303B376DED 184 | :101C000000901C06A1461B5B306D00C0E0741BB148 185 | :101C100040745BB140D0E022901D04B14678005181 186 | :101C2000C2742BB140E812002E08B810F2901D0AC1 187 | :101C3000A1467848742DB140D8FA22EC20E00590F6 188 | :101C40001D368003901D3BB146780851C2D8FC90E8 189 | :101C50001D1EA14C71CF741471D57A4851C2DAFCA3 190 | :101C6000744861E5EC30E112901CBC20E203901C4A 191 | :101C7000D7B146901CF2B1468005901CB4B1469095 192 | :101C80001C84A14620205E473D476F746F20205E74 193 | :101C9000433D436F646520205E443D446174612090 194 | :101CA000205E4C3D52656472617720205E513D514B 195 | :101CB000756974005E452D45646974005E413D1B85 196 | :101CC0005B303B376D41534349491B5B306D2020EE 197 | :101CD0005E583D486578005E413D41534349492087 198 | :101CE000205E583D1B5B303B376D4865781B5B3091 199 | :101CF0006D0020205E463D46696C6C001B5B481BF6 200 | :101D00005B324A00414444523A0020202041534370 201 | :101D10004949204551554956494C414E54003830A7 202 | :101D200035311F9A1F831FD86F722C1FF81FFE2C8E 203 | :101D3000203139393600434F444500444154410075 204 | :101D4000020030020034020038020048020045025E 205 | :101D50000050292C206F72203C4553433E20746F65 206 | :101D600020657869743A20000D1F888083812028BF 207 | :101D70000020436F6D6D616E642041626F72746507 208 | :101D8000642E0D0A000DA1C520636F6E6E6563742D 209 | :101D900020494E5431202870696E20313329206C3F 210 | :101DA0006F7780BACFCC0D009432B3C7AE812030AC 211 | :101DB0003031330D001FB8B3FFA520766563746F13 212 | :101DC00072AE20000D4E6F77866E696E67A6CFCC1F 213 | :101DD000206D6F64653A20203C5245543E3DCC2C2A 214 | :101DE000203F3D2048656C700D0D00536B6970708D 215 | :101DF000696E6720496E737472756374696F6E2DB6 216 | :101E00003E20000D0A4C6F633A2020496E74205228 217 | :101E1000414D204D656D6F727920436F6E74656E14 218 | :101E200074730D0A004E6577204163632056616C20 219 | :101E300075653A20000D1FCF1FCC1F9E3A0D3C52F6 220 | :101E400045543E2086D4F60D203C53503E2086D487 221 | :101E5000F60D20273F272020FF8ED70D20272E2785 222 | :101E60002020FFC4FD730D202752272020FF207360 223 | :101E700070656369616C2066756E6374696F6EC4AA 224 | :101E8000730D20274827202084DBC0920D20275384 225 | :101E9000272020FCD4F60D202741272020F0A22067 226 | :101EA0004163632076616C75650D202751272020E2 227 | :101EB000C8CFCC0D0E517569740D0A002020414326 228 | :101EC000432042204320445054522020523020527C 229 | :101ED0003120523220523320523420523520523693 230 | :101EE000205237202053502020204164647220204B 231 | :101EF000496E737472756374696F6E0D0A004143A5 232 | :101F0000414CCC004144C400414444C3414A4DD0FB 233 | :101F1000414ECC434A4EC5434CD24350CC44C144BD 234 | :101F200045C34449D6444A4EDA494EC34AC24A429E 235 | :101F3000C34AC34A4DD04A4EC24A4EC34A4EDA4AF9 236 | :101F4000DA4C43414CCC4C4A4DD04D4FD64D4F56B8 237 | :101F5000C34D4F56D84D55CC4E4FD04F52CC504F0D 238 | :101F6000D0505553C85245D4524554C952CC524C06 239 | :101F7000C352D25252C3534554C2534A4DD0535503 240 | :101F800042C2535741D05843C8584348C45852CC12 241 | :101F90003F3FBF50B054434FCE50B153434FCE504C 242 | :101FA000B249C550B349D043B05432434FCE5053D9 243 | :091FB000D744B84143C3FDC2FE51 244 | :00000001FF 245 | -------------------------------------------------------------------------------- /tests/paulmon2.ref: -------------------------------------------------------------------------------- 1 | :030000000208A44F 2 | :080003000220038E828F83228C 3 | :08000B0002200BAE82AF83223C 4 | :08001300022013742D0173009B 5 | :08001B0002201B1173017100AA 6 | :080023000220231116017100F7 7 | :03002B0002202B85 8 | :10002E00217601730167216521872194018A01CE12 9 | :10003E0021CE21A802093A020B59017D0201BB0211 10 | :10004E000AA2020AA8020AE602086502082B0207A3 11 | :10005E00B602078C020A21214A3098FDC298E59912 12 | :10006E0022117174203099FDC299F59922117DC02B 13 | :10007E00E0740D1173740A1173D0E022C2D51162AF 14 | :10008E0031A8B41B03D3E422B40D05D2D5C3E422A8 15 | :10009E00FA314A40E9CA1173116231A8B41B0280C9 16 | :1000AE00E4B40D03EAC322B40804117380D0B4156E 17 | :1000BE000280F7FB314A40E0CB1173EAC44BC322F6 18 | :1000CE007A007B007C04C2D5116231A8B41B07D321 19 | :1000DE00E4F583F58222B408028003B47F0CBC04DD 20 | :1000EE000280E5117331390C80DEB40D108B838ADA 21 | :1000FE0082BC0407E4F583F582D2D5C322FD314AD2 22 | :10010E0040C6CD120073EDC0E03128D0E02AFAE4EB 23 | :10011E003BFBDCB4C38A828B8322EBC454F0FBEA34 24 | :10012E00C4540F4BFBEAC454F0FA22EAC4540FFA3B 25 | :10013E00EBC454F04AFAEBC4540FFB22C324D05044 26 | :10014E001424F64004240AC32224F9500824FA4049 27 | :10015E00042410C322D322C0E0C4540F24F650024C 28 | :10016E002407243A1173D0E0C0E0540F24F6500255 29 | :10017E002407243A1173D0E022C0E0E5833165E50F 30 | :10018E00823165D0E022C0E0E493A3600AA2E75476 31 | :10019E007F1173400280F1D0E022C0E0C394614031 32 | :1001AE0009941A5005D0E024E022D0E0227800C055 33 | :1001BE00E0E4936008A2E7084003A380F4D0E022B5 34 | :1001CE00C0E0C3309808E599B41B01D3C298D0E0C3 35 | :1001DE0022900DF51145EF3165EE316531941162C6 36 | :1001EE0031A875F0DFC0F075F001C0F0F5F0901099 37 | :1001FE0000F18C5024758204E493B4FE150582E45C 38 | :10020E0093B5F00E11717582203194117D75824077 39 | :10021E00E4730583E583B400D8E5F0B43F07900F8F 40 | :10022E005D1145A1D0B44D07900F65114581C0B445 41 | :10023E005207900F6A1145A137B44407900F6E1103 42 | :10024E004541A8B45507900F711145C145B44E07ED 43 | :10025E00900F741145E137B44A07900F781145811C 44 | :10026E0012B44807900F7E11458149B44507900F8F 45 | :10027E008A1145818AB44307900F8F1145E113B45B 46 | :10028E005A0B74006012900F931145E147B4490860 47 | :10029E00900F84114502076D017D900E8F114578E8 48 | :1002AE00107A10760008DAFB1167B41B028072B464 49 | :1002BE003A0679007141800A314A40EC7906714163 50 | :1002CE0080E6742E11737C007160F87160F5837195 51 | :1002DE0060F5827160B40102802D7022E8601471A5 52 | :1002EE0060FA79017141EA120865E43402F971414C 53 | :1002FE00A3D8E97160EC60B07904714180AAE8601E 54 | :10030E00F27160D8FC80ECE860047160D8F3716023 55 | :10031E00EC70E57138900EAE114530987A11678009 56 | :10032E00767138900EA61145806D78007900D9FE51 57 | :10033E00D8FA22E95407232410F907E770020907B7 58 | :10034E0022D3878209878309E5827005E5837001D0 59 | :10035E00C322116731A8B41B06D0E0D0E080C2B42E 60 | :10036E003A0A79057141D0E0D0E041D0314A5006C9 61 | :10037E007907714180DCFA116731A8B41B0280D96C 62 | :10038E00B43A0280DD314A50067907714180E8CADD 63 | :10039E00C44AFA2CFCEA22EEC0E0EFC0E0900EB5A3 64 | :1003AE00114579107EBE7F0E910E7EC47F0E910E8A 65 | :1003BE007EC97F0E910E7A05714F4009DAFA900FC1 66 | :1003CE000511458025900ED4114579167ED87F0EE5 67 | :1003DE0091007EE97F0E91007EF17F0E91007EF7F7 68 | :1003EE007F0E91007EFC7F0E9100D0E0FFD0E0FEEC 69 | :1003FE00017D714F50091171120AE6110611452245 70 | :10040E00714F80F2900E37114511063187900E050F 71 | :10041E00114511CE20D5065002E10E110E117D9020 72 | :10042E000F1311451106E4F5D0F5F0F8F9FAFBFCBF 73 | :10043E00FDFEFF758108C0E0C0E0737A10117B11DC 74 | :10044E00063187743A111E7B101106E493A33165B1 75 | :10045E001171DBF7116F7B101106E493A3547FB477 76 | :10046E007F01E424E04001E424201173DBEC117DD4 77 | :10047E00D1CA110E31CE4002DAC5017D900E79112E 78 | :10048E004511063187743A111E74281173110EE44A 79 | :10049E00933165900E521145118A20D510400E11E0 80 | :1004AE0006120865117D1106A3110E8191900E841E 81 | :1004BE000145900E41114578151171D8FC11457505 82 | :1004CE008310F18C4002017D116F7582203194757D 83 | :1004DE00822031BB7421C398F874201173D8FC7537 84 | :1004EE0082003187780674201173D8FC758204E47B 85 | :1004FE0093AA83B4FE05900F4B8018B4FD05900FA0 86 | :10050E00528010B42305900F4F8008B4F90280EE8C 87 | :10051E00900F5911458A83117D74FFB5830281D4E2 88 | :10052E000583E583B4009B81D4117B7AFF90100084 89 | :10053E0015830583E583B400028021F18C501D756F 90 | :10054E008204E4934403F460E9116F0A74412A11A2 91 | :10055E001E11267582203194117DA140BAFF05909F 92 | :10056E000E0E0145900E0011457441117311167453 93 | :10057E00412A1173900E0511451162B41B02017DC3 94 | :10058E00FB741FC39AEB400231A81173FB117DEB74 95 | :10059E00C3944140CFFBEAC39B40C90B901000159A 96 | :1005AE00830583E583B400028017F18C50137582A6 97 | :1005BE0004E4934403F460E9DBE7117D7582408126 98 | :1005CE003422900F3311457C3F900F60D13A7C4D11 99 | :1005DE00D13A7C52D13A7C44D13A7C55D13A7C4EB8 100 | :1005EE00D13A7C4AD13A7C48D13A7C49D13A7C45C1 101 | :1005FE00D13A7C43D13A740060047C5AD13A900FC0 102 | :10060E00411145901000F18C5020758204E493B492 103 | :10061E00FE11116F0582E49311731126758220313C 104 | :10062E0094117D0583E583B400DC017D116FEC111F 105 | :10063E007311261145017DD1DC900F1D1145EB3153 106 | :10064E0065EA31651145ED3165EC3165117D8D83BE 107 | :10065E008C82A3AC82AD83900E2D11451167B41B15 108 | :10066E0002E10C117D8A828B83ECC39582FAED95A3 109 | :10067E00837009EA603254F0700280027A10743A84 110 | :10068E001173EA31653187E58325822AFBE43165F2 111 | :10069E00E49331652BFBA3DAF7EBF4043165117D9E 112 | :1006AE00D1CA31CE50C38056743A1173E4316531DC 113 | :1006BE0065316504316574FF3165017BE8C0E07812 114 | :1006CE000CE58C04000070FBD8F7D0E0F822117B0B 115 | :1006DE00900E5B114511CE402120D51EC083C082E5 116 | :1006EE00117D900E65114511CEAD83AC82D0E0FA2E 117 | :1006FE00D0E0FB400520D502017DD0E0D0E0117D99 118 | :10070E00900DED0145D1DC900E6F1145116231A8AF 119 | :10071E00B459EB117B8B838A82E4120865EDB583A5 120 | :10072E0005ECB5820122A380F0900E24114511CE66 121 | :10073E0040CE20D5CB110E017B117B900F9311452E 122 | :10074E00742C111E900E6F1145116231A8B459AE62 123 | :10075E00117B1207B6900F985003900F9F01451111 124 | :10076E007D7800117DB88002017DE83165743A1103 125 | :10077E00731171E6316508E8540F70F580E57582E6 126 | :10078E0000E493B4A517A3E493B4E511A3E493B4E2 127 | :10079E00E00BA3E493B4A505758200D32274FFB5D4 128 | :1007AE008302C322058380D674006038908000E4F3 129 | :1007BE0093F4700DA37400B582F57400B583F0C385 130 | :1007CE0022908000E4936006E412082B4016A37476 131 | :1007DE0000B582F07400B583EB9080007CE87D0458 132 | :1007EE00DC04DD02D3227420A2AF92D1C2AFF0F0AE 133 | :1007FE007B147AE5DAFEDBFA74A0F07A05DAFEE411 134 | :10080E0093A2D192AFF470D8A37400B583EA7400AA 135 | :10081E00B582E574FF908000F0E4F0C322F5F0EAB3 136 | :10082E00C0E0EBC0E07A197440A2AF92D1C2AFF033 137 | :10083E00E5F0F07B13DBFE74C0F07B05DBFEE4938A 138 | :10084E00A2D192AFC395F06003DADCD3E4F0D0E02E 139 | :10085E00FBD0E0FAE5F022C0E0C0F0F5F0740060E5 140 | :10086E001BE583B4FF02800B5012B480028004504B 141 | :10087E00028009E5F0112BD0F0D0E022E5F0F0E493 142 | :10088E0093C395F06009E0C395F06003D38001C374 143 | :10089E00D0F0D0E02232E4F5A8F5B875D00011A35F 144 | :1008AE0011A3F4F580F590F5A0F5B075813079C8F7 145 | :1008BE007AF9DAFED9FA740060137400600F78FAD0 146 | :1008CE00A20079C8D9FE4005D8F61207B675F0F920 147 | :1008DE00310D313A75F0FD310D781812007DD8FBCF 148 | :1008EE00780F7420120073D8FB900DBB120B599029 149 | :1008FE000DCF120B591204C07E007F200201DF9033 150 | :10090E00100012078C5024758204E493B5F015C0C4 151 | :10091E00F0C083742EC0E07409C0E0758240E473A9 152 | :10092E00D083D0F00583E583B400D7227400701411 153 | :10093E00E57B637A556379CC63781DB57A08B57912 154 | :10094E0005B578024100758780759842758911E466 155 | :10095E00F588F58AF58CF58BF58D78C8791E30B053 156 | :10096E00E5D9FBD8F720B0FD20B0FA20B0F720B0C3 157 | :10097E00F420B0F130B0FDD28E208FCA20B0FA2014 158 | :10098E008FC430B0FA208FBE20B0FAD28C208FB632 159 | :10099E0030B0FAC28EC28C208FACE58B33F5F0E509 160 | :1009AE008D3340A2A2F73400F404609AF58D758B56 161 | :1009BE00FF758921D29CD28EE58DF404F978FFD88B 162 | :1009CE00FED9FA309811C298E599547F24F6600743 163 | :1009DE0024056003020954E58A33F8E58C33F940A7 164 | :1009EE00F3E833F5F0E933A2F7340060E7F404B529 165 | :1009FE008DE2F57BF57AF579F578637A556379CCE6 166 | :100A0E0063781DF58DF58B758921758780759852E4 167 | :100A1E00D28E22309806120067B41B51120067B4B2 168 | :100A2E001B4B518F209803741B22120067B45B443A 169 | :100A3E00518F3098DE120067B44103740B22B4421A 170 | :100A4E0003740A22B44303741522B44403740822B7 171 | :100A5E00B435028007B4360280028018C0E0518F90 172 | :100A6E0030980B120067B47E09D0E024E422D0E067 173 | :100A7E0080A1D0E0518F30989A120067B41BF58098 174 | :100A8E00A1EAC0E07A14E58C2098050470FADAF633 175 | :100A9E00D0E0FA22C0F0C0E08013C0F0C0E030E732 176 | :100AAE000C742D120073D0E0C0E0F4240175F064D4 177 | :100ABE0084D2D56007C2D52430120073E5F075F0EC 178 | :100ACE000A8430D50260052430120073E5F024301C 179 | :100ADE00120073D0E0D0F022C0E0E8C0E0C2D5AA88 180 | :100AEE0082AB837C107D2771446007243012007323 181 | :100AFE00D2D57CE87D037144700330D507243012C3 182 | :100B0E000073D2D57C647D007144700330D5072408 183 | :100B1E0030120073D2D5EAABF075F00A8470033050 184 | :100B2E00D5052430120073E5F08BF02430120073DB 185 | :100B3E00D0E0F8D0E022780008C3EA9CFAEB9DFBE7 186 | :100B4E0050F618EA2CFAEB3DFBE822C0E0E8C0E0D4 187 | :100B5E00E9C0E0ECC0E0D2D1D2D5E493A360252069 188 | :100B6E00E72E547FB40D0712007DD2D180ECB41F56 189 | :100B7E0004C2D580E5B40E0512007D8007C2D112E5 190 | :100B8E00007380D6D0E0FCD0E0F9D0E0F8D0E022BF 191 | :100B9E00547FF820D103120071C2D1C082C083905D 192 | :100BAE000C137C00E86007F9910270FCD9FA9102EF 193 | :100BBE00603CB40F1291020483801E6866776779D9 194 | :100BCE006278766B716A7A0483800E657461726ED8 195 | :100BDE0069736F6C756D706463A2D592E5D2D5B8EA 196 | :100BEE001402C2E5B80C02C2E512007380C0D083B5 197 | :100BFE00D0826168E493BC00057CFF540F227C0018 198 | :100C0E00A3C4540F228290E82386054CF844B3B057 199 | :100C1E00B1485FF0117FA0157F1C2ED1405A50F1C4 200 | :100C2E0003BFBA0C2F96018D3F95380D6F5F1207DB 201 | :100C3E00710E562F483B6258201F7670322440B8F2 202 | :100C4E0040E1618F01340BCA89D3C0A3B958800427 203 | :100C5E00F80285602591F092731F107F1254931045 204 | :100C6E00444807D126564FD0F66472E0B83BD5F013 205 | :100C7E00164F56306F48025FA8201F017630D560A0 206 | :100C8E002541A42C60056F013F261F30078E1DF0F5 207 | :100C9E006399F042B8201F2330027AD1602FF0F60C 208 | :100CAE00058F931A5028F082046FA30D3F1F5140F9 209 | :100CBE0023013E0543017A01176493302A088C24E0 210 | :100CCE003099B0F31960254135098ECB19123005D4 211 | :100CDE001F311D04144F761204AB279056012FA816 212 | :100CEE00D5F0AA26205F1CF0F361FE0141730127A7 213 | :100CFE00C1C0848FD6018770564F19701FA8D99026 214 | :100D0E0076021743FE01C1840B157F028B14308FC0 215 | :100D1E0063396F19F011C9106D023F91097A41D0F4 216 | :100D2E00BA0C1D395F07F2111720416B3509F775A3 217 | :100D3E00120BA7CC48023F6412A00C27E39FC014ED 218 | :100D4E00777011407121C0682541F0627FD1D021AA 219 | :100D5E00E16258B0F3051F733077B16F19E0194394 220 | :100D6E00E0582FF6A414D02303FE31F5143099F871 221 | :100D7E00033F6422516025412FE30156279309FE5C 222 | :100D8E0011FE79BA607542EA6258A0E51F534FD141 223 | :100D9E00C0A3094253F71204621B30F505F7690C24 224 | :100DAE00351B70822F2F144F51C064250057656C70 225 | :100DBE00636F6D658094322C2062791FF81FFE0DD3 226 | :100DCE000E202053656594322E444F432C94322EC0 227 | :100DDE00455155A494322E484452B4D58D2E0E2032 228 | :100DEE001F9E1FA0210D0E9432204C6F633A0020DF 229 | :100DFE003EA086CA822800292C958C80C83A2000F5 230 | :100E0E001F9782C373C7A6832CBA204A554D5080B4 231 | :100E1E0086A172820D0E0D0D1F8783813A20001F51 232 | :100E2E00E4FB206B65793A20000D0D1F88808381CD 233 | :100E3E002028000D0D1F821FFD001F812020202065 234 | :100E4E00201FC90E29201F871FB23A200046697243 235 | :100E5E0073741F813A20004C6173741F813A2020F5 236 | :100E6E00001FB9A120737572653F000D0D1F9C9A6E 237 | :100E7E00922C8C80C80E20201F9CC12C8E81F70DC9 238 | :100E8E000E0D0D1F9F206173636969F9961F98847B 239 | :100E9E00892C958C80A00D0E0D1F8AA065640D0EF9 240 | :100EAE000D1F8AC1640D0E53756D6D6172793A0E08 241 | :100EBE0020C67391640E208B91640E208B20777266 242 | :100ECE00697474656E0E1F9B3A0E208B20756E61D1 243 | :100EDE00626C65802077726974650E202062616491 244 | :100EEE00F5730E20859F96C60E2085849D0E208557 245 | :100EFE00206E6F6E849D0E1F979B206465746563D4 246 | :100F0E007465640D0E0D866E696E67823A0D0E0D58 247 | :100F1E000D53656E64696E671F988489AC2020003E 248 | :100F2E0020802020000D0D5374616E646172641F69 249 | :100F3E009E730E1FDA1FF465641F9E730E1F9A9E1A 250 | :100F4E00001F82001F8F1FE21FAA003F3F3F001F9E 251 | :100F5E00D7001F8ED7D1001FD18273001F8682004B 252 | :100F6E001F8A001F93001F8781001F8880838100C6 253 | :100F7E001F84DB9A83001F84DBC083001F9C9A9220 254 | :100F8E00001FED83001FCB9990001F9990CB640D2D 255 | :060F9E000E1F859B0D0EE5 256 | :00000001FF 257 | -------------------------------------------------------------------------------- /src/ax215/disasm.c: -------------------------------------------------------------------------------- 1 | /* pass2.c 2 | * 3 | * Functions for pass 2 of the disassembler. 4 | * 5 | * Copyright 2001 - 2003 by David Sullins 6 | * 7 | * This file is part of Dis51. 8 | * 9 | * Dis51 is free software; you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, version 2 of the License. 12 | * 13 | * Dis51 is distributed in the hope that it will be useful, but WITHOUT ANY 14 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * Dis51; if not, write to the Free Software Foundation, Inc., 59 Temple 20 | * Place, Suite 330, Boston, MA 02111-1307 USA 21 | * 22 | * You may contact the author at davesullins@earthlink.net. 23 | */ 24 | 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "disasm-mnem.h" 31 | 32 | static void pass1(uint8_t *bfr, int size, int offset); 33 | 34 | /* nextbyte: read a byte from memory 35 | * 36 | */ 37 | uint8_t nextbyte(uint8_t *bfr, int *addr) { 38 | uint8_t c = bfr[*addr]; 39 | (*addr)++; 40 | return c; 41 | } 42 | 43 | /* longaddr 44 | * 45 | */ 46 | static int longaddr_print(uint8_t op1, uint8_t op2, char *label, int label_sz) 47 | { 48 | int addr; 49 | 50 | /* calculate address */ 51 | addr = ((((int)op1)<<8) | op2); 52 | 53 | /* form label string */ 54 | snprintf(label, label_sz, "label_%d", lbl[addr]); 55 | 56 | return lbl[addr]; 57 | } 58 | 59 | /* absaddr 60 | * 61 | */ 62 | static int absaddr_print(uint8_t opcode, uint8_t operand, int memPtr, char *label) 63 | { 64 | int addr; 65 | 66 | /* calculate address */ 67 | addr = ((memPtr & 0xf800) | (((int)opcode & 0xe0)<<3) | operand); 68 | 69 | /* form label string */ 70 | sprintf(label, "label_%d", lbl[addr]); 71 | 72 | return lbl[addr]; 73 | } 74 | 75 | /* reladdr 76 | * 77 | */ 78 | static int reladdr_print(uint8_t operand, int memPtr, char *label) 79 | { 80 | int addr; 81 | 82 | /* calculate address */ 83 | addr = memPtr + (signed char)operand; 84 | 85 | /* form label string */ 86 | sprintf(label, "label_%d", lbl[addr]); 87 | 88 | return lbl[addr]; 89 | } 90 | 91 | 92 | /* printhex 93 | * 94 | * Pretty format a hexadecimal number in a string. 95 | */ 96 | static void printhex(uint8_t num, char *name) 97 | { 98 | if ((num >= 0xa0) || ((num <= 0xf) && (num >= 0xa))) 99 | snprintf(name, 5, "0x0%x", num); 100 | else 101 | snprintf(name, 5, "0x%x", num); 102 | } 103 | 104 | /* sfrdecode 105 | * 106 | * Convert a direct memory value to a SFR name if appropriate. 107 | * Otherwise output the formatted number. 108 | */ 109 | static void sfrdecode(uint8_t sfr, char *name) 110 | { 111 | if (sfr & 0x80) 112 | strncpy(name, sfrname[sfr&0x7f], 5); 113 | else 114 | printhex(sfr, name); 115 | } 116 | 117 | /* sfbitdecode 118 | * 119 | * Convert a bit memory value to a SF bit name if appropriate. 120 | * Otherwise output the formatted number. 121 | */ 122 | static void sfbitdecode(uint8_t sfbit, char *name) 123 | { 124 | if (sfbit & 0x80) 125 | strncpy(name, sfbitname[sfbit&0x7f], 6); 126 | else 127 | printhex(sfbit, name); 128 | } 129 | 130 | /* _listhex, listhex 131 | * 132 | * Output list-format address and data for the -l command line switch. 133 | * 134 | * Contributed by Peter Peres. 135 | */ 136 | #define listhex(len,addr,ofile) { if(Lst) _listhex(ofile,bfr,addr,len); } 137 | static void _listhex(FILE *file, uint8_t *bfr, int addr, int len) 138 | { 139 | fprintf( file, " %04X %02X", addr-len, bfr[addr-len] ); 140 | switch(len) { 141 | case 3: 142 | fprintf( file, "%02X", bfr[addr-2] ); 143 | case 2: 144 | fprintf( file, "%02X", bfr[addr-1] ); 145 | if(len == 2) 146 | fprintf( file, " "); 147 | break; 148 | default: 149 | fprintf( file, " "); 150 | } 151 | fprintf( file, "\t\t" ); 152 | } 153 | 154 | /* dis_inst2: Disassemble one instruction to ofile 155 | * 156 | * Returns address immediately after instruction. 157 | */ 158 | static int dis_inst2(FILE *ofile, uint8_t *bfr, int addr) 159 | { 160 | uint8_t opcode; 161 | uint8_t op1, op2; 162 | char label[64]; 163 | char name[6]; 164 | char name2[5]; 165 | int bytes = 1; 166 | 167 | /* Fetch opcode */ 168 | opcode = nextbyte(bfr, &addr); 169 | 170 | /* Fetch second and third byte, if appropriate */ 171 | if (op_format[opcode] > 1) { 172 | op1 = nextbyte(bfr, &addr); 173 | bytes = 2; 174 | } 175 | if (op_format[opcode] > 6) { 176 | op2 = nextbyte(bfr, &addr); 177 | bytes = 3; 178 | } 179 | 180 | /* Output decoded instruction */ 181 | if(!Lst) 182 | fprintf(ofile, "\t"); 183 | else 184 | listhex(bytes, addr, ofile); 185 | switch(op_format[opcode]) { 186 | case 0: 187 | /* A5 is an illegal opcode */ 188 | fprintf(ofile, "DB 85h ; illegal opcode"); 189 | case 1: 190 | /* no operands */ 191 | fprintf(ofile, mnemonic[opcode]); 192 | break; 193 | case 2: 194 | /* one immediate operand */ 195 | printhex(op1, name); 196 | fprintf(ofile, mnemonic[opcode], name); 197 | break; 198 | case 3: 199 | /* one direct operand */ 200 | sfrdecode(op1, name); 201 | fprintf(ofile, mnemonic[opcode], name); 202 | break; 203 | case 4: 204 | /* one bit-addressed operand */ 205 | sfbitdecode(op1, name); 206 | fprintf(ofile, mnemonic[opcode], name); 207 | break; 208 | case 5: 209 | /* one operand, relative address */ 210 | /* relative addr calculation */ 211 | reladdr_print(op1, addr, label); 212 | fprintf(ofile, mnemonic[opcode], label); 213 | break; 214 | case 6: 215 | /* one operand, absolute address */ 216 | /* absolute addr calculation */ 217 | absaddr_print(opcode, op1, addr, label); 218 | fprintf(ofile, mnemonic[opcode], label); 219 | break; 220 | case 7: 221 | /* two-byte immediate operand */ 222 | /* MOV DPTR, #immediate16 */ 223 | fprintf(ofile, mnemonic[opcode], op1, op2); 224 | break; 225 | case 8: 226 | /* two operands: direct, immediate */ 227 | sfrdecode(op1, name); 228 | printhex(op2, name2); 229 | fprintf(ofile, mnemonic[opcode], name, name2); 230 | break; 231 | case 9: 232 | /* two operands: direct, direct */ 233 | /* (operands in reverse order) */ 234 | sfrdecode(op1, name); 235 | sfrdecode(op2, name2); 236 | fprintf(ofile, mnemonic[opcode], name2, name); 237 | break; 238 | case 10: 239 | /* two operands: immediate, relative */ 240 | printhex(op1, name); 241 | reladdr_print(op2, addr, label); 242 | fprintf(ofile, mnemonic[opcode], name, label); 243 | break; 244 | case 11: 245 | /* two operands: direct, relative */ 246 | sfrdecode(op1, name); 247 | reladdr_print(op2, addr, label); 248 | fprintf(ofile, mnemonic[opcode], name, label); 249 | break; 250 | case 12: 251 | /* two operands: bit, relative */ 252 | sfbitdecode(op1, name); 253 | reladdr_print(op2, addr, label); 254 | fprintf(ofile, mnemonic[opcode], name, label); 255 | break; 256 | case 13: 257 | /* long address */ 258 | /* long addr calculation */ 259 | longaddr_print(op1, op2, label, sizeof(label) - 1); 260 | fprintf(ofile, mnemonic[opcode], label); 261 | break; 262 | default: 263 | /* error in op_format table */ 264 | fprintf(ofile, "DB 0%Xh ; error in op_format table", 265 | opcode); 266 | } 267 | fprintf(ofile, "\n"); 268 | 269 | return addr; 270 | } 271 | 272 | /* pass2: Disassemble memory to given output file (pass 2) 273 | * 274 | */ 275 | int disasm_8051(FILE *ofile, uint8_t *src_bfr, int size, int offset) { 276 | int addr = offset; 277 | uint8_t bfr[size+offset]; 278 | memset(bfr, 0, sizeof(bfr)); 279 | memcpy(bfr+offset, src_bfr, size); 280 | 281 | pass1(bfr, size, offset); 282 | 283 | fprintf(ofile, ".org 0x%04X\n", addr); 284 | while (addr < offset+size) 285 | { 286 | /* Step 2: Output a label if one exists */ 287 | if (lbl[addr]) 288 | fprintf(ofile, "label_%d:\n", lbl[addr]); 289 | 290 | /* Disassemble next instruction */ 291 | addr = dis_inst2(ofile, bfr, addr); 292 | } 293 | return 0; 294 | } 295 | 296 | 297 | /* newlbl is used by longaddr, absaddr, and reladdr 298 | * Keep track of next available label 299 | */ 300 | static unsigned short newlbl = 0; 301 | 302 | /* longaddr 303 | * 304 | */ 305 | static int longaddr(uint8_t op1, uint8_t op2) 306 | { 307 | int addr; 308 | 309 | /* calculate address */ 310 | addr = ((((int)op1)<<8) | op2); 311 | 312 | /* check if this address has already been labelled */ 313 | if (lbl[addr] == 0) 314 | lbl[addr] = ++newlbl; 315 | 316 | return addr; 317 | } 318 | 319 | /* absaddr 320 | * 321 | */ 322 | static int absaddr(uint8_t opcode, uint8_t operand, int memPtr) 323 | { 324 | int addr; 325 | 326 | /* calculate address */ 327 | addr = ((memPtr & 0xf800) | (((int)opcode & 0xe0)<<3) | operand); 328 | 329 | /* check if this address has already been labelled */ 330 | if (lbl[addr] == 0) 331 | lbl[addr] = ++newlbl; 332 | 333 | return addr; 334 | } 335 | 336 | /* reladdr 337 | * 338 | */ 339 | static int reladdr(uint8_t operand, int memPtr) 340 | { 341 | int addr; 342 | 343 | /* calculate address */ 344 | addr = memPtr + (signed char)operand; 345 | 346 | /* check if this address has already been labelled */ 347 | if (lbl[addr] == 0) 348 | lbl[addr] = ++newlbl; 349 | 350 | return addr; 351 | } 352 | 353 | /* dis_inst: Disassemble one instruction (pass 1) 354 | * 355 | * Also increments memPtr to point to the next instruction address. 356 | * 357 | * Return -1 on error. 358 | * Otherwise, return opcode byte. 359 | * 360 | * CAVEAT: Indirect jumps not handled (JMP @A+DPTR) 361 | */ 362 | static int dis_inst1(uint8_t *bfr, int size, int addr) 363 | { 364 | uint8_t opcode; 365 | uint8_t op1, op2; 366 | int newaddr = -1; 367 | 368 | opcode = nextbyte(bfr, &addr); 369 | 370 | switch(op_format[opcode]) { 371 | case 0: 372 | /* A5 is an illegal opcode */ 373 | fprintf(stderr, 374 | "Illegal opcode A5 at address %04X\n", addr-1); 375 | newaddr = -1; 376 | break; 377 | case 1: 378 | /* no operands */ 379 | newaddr = addr; 380 | /* if this is a return, stop disassembly */ 381 | if ((opcode & 0xef) == 0x22) 382 | newaddr = -1; 383 | /* we don't handle indirect jumps */ 384 | else if (opcode == 0x73) 385 | newaddr = -1; 386 | break; 387 | case 2: 388 | case 3: 389 | case 4: 390 | /* one operand */ 391 | nextbyte(bfr, &addr); 392 | newaddr = addr; 393 | break; 394 | case 5: 395 | /* one operand, relative address */ 396 | op1 = nextbyte(bfr, &addr); 397 | /* relative addr calculation */ 398 | newaddr = reladdr(op1, addr); 399 | /* if this is a branch, continue disassembly */ 400 | // if (opcode != 0x80) 401 | // pass1(bfr, size, addr); 402 | break; 403 | case 6: 404 | /* one operand, absolute address */ 405 | op1 = nextbyte(bfr, &addr); 406 | /* absolute addr calculation */ 407 | newaddr = absaddr(opcode, op1, addr); 408 | /* if this is a call, continue disassembly */ 409 | // if (opcode & 0x10) 410 | // pass1(bfr, size, addr); 411 | break; 412 | case 7: 413 | case 8: 414 | case 9: 415 | /* two operands */ 416 | nextbyte(bfr, &addr); 417 | nextbyte(bfr, &addr); 418 | newaddr = addr; 419 | break; 420 | case 10: 421 | case 11: 422 | case 12: 423 | /* two operands, relative address */ 424 | nextbyte(bfr, &addr); 425 | op2 = nextbyte(bfr, &addr); 426 | /* relative addr calculation */ 427 | newaddr = reladdr(op2, addr); 428 | /* this is always a branch instruction */ 429 | // pass1(bfr, size, addr); 430 | break; 431 | case 13: 432 | /* long address */ 433 | op1 = nextbyte(bfr, &addr); 434 | op2 = nextbyte(bfr, &addr); 435 | /* long addr calculation */ 436 | newaddr = longaddr(op1, op2); 437 | /* if this is a call, continue disassembly */ 438 | // if (opcode == 0x12) 439 | // pass1(bfr, size, addr); 440 | break; 441 | default: 442 | /* error in op_format table */ 443 | fprintf(stderr, 444 | "Invalid opcode format, error in format table\n"); 445 | newaddr = -1; 446 | break; 447 | } 448 | 449 | return addr; 450 | } 451 | 452 | /* pass1: Disassemble instructions starting at given entry point (pass 1) 453 | * 454 | */ 455 | static void pass1(uint8_t *bfr, int size, int offset) { 456 | int base = offset; 457 | while ((offset != -1) && (offset >= base) && (offset < base+size)) { 458 | /* no error, we haven't been here before, and non-empty */ 459 | /* disassemble next instruction */ 460 | offset = dis_inst1(bfr, size, offset); 461 | } 462 | } 463 | -------------------------------------------------------------------------------- /progs/romdump.asm: -------------------------------------------------------------------------------- 1 | .equ IEN, 0xA8 2 | 3 | .equ SFR_80, 0x80 4 | .equ SD_DATL, 0xD6 5 | .equ SD_DATH, 0xD7 6 | 7 | .equ SD_BYTES, 0xDE ; SD byte count 8 | 9 | .equ SDDIR, 0xEB 10 | .equ SDSM, 0x90 11 | 12 | .equ SDCMD, 0xE6 13 | .equ SD_XMIT, 0xE7 14 | .equ SD_XMIT_STATE, 0xE8 15 | .equ SDI1, 0xE9 16 | .equ SDI2, 0xEA 17 | .equ SDI3, 0xEB 18 | .equ SDI4, 0xEC 19 | 20 | .equ RESET, 0 21 | .equ PORT1, 0xF6 22 | 23 | .equ NPS, 0x9e 24 | 25 | .equ LED_STATE, 0x40 26 | 27 | .equ NCMD, 0xa1 28 | .equ NSRCL, 0xa2 29 | .equ NSRCH, 0xa3 30 | 31 | .equ SD_WAITING, 0x24 32 | 33 | .org 0x4700 34 | ; This gets called from the ROM. 35 | ; --------------------------------------------------------------------------- 36 | ; This gets called from an interrupt context, from within ROM. We want to 37 | ; manipulate the stack so that when we return from interrupt, code execution 38 | ; will continue at an address immediately following this code section. 39 | reset_vector: 40 | anl 0xDC, #0xFE 41 | pop ACC 42 | pop ACC 43 | mov A, #0x10 44 | push ACC 45 | mov A, #0x47 46 | push ACC 47 | reti ; Return from interrupt, ending up at 0x7b0c 48 | 49 | 50 | ;--------------------------------------------------------------------------- 51 | .org 0x4710 52 | start: 53 | 54 | mov IEN, #0 ; Disable interrupts 55 | mov SP, #0x80 ; Reset stack pointer 56 | acall setup_sd_rcv 57 | ; acall reset_isrs 58 | ljmp dump_rom 59 | acall more_setup 60 | ljmp main ; Enter the main() loop 61 | 62 | ; --------------------------------------------------------------------------- 63 | ; SD interrupt handler. Called from an interrupt context. 64 | ;.org 0x7b80 65 | sdi_isr: 66 | push ACC 67 | push 0x80 68 | push DPH 69 | push DPL 70 | push PSW 71 | mov PSW, #8 72 | mov SFR_80, #8 73 | clr SD_XMIT_STATE.0 74 | clr SD_XMIT_STATE.1 75 | orl 0xE3, #1 76 | anl 0xCE, #0xEC 77 | 78 | ; Get ready to jump to the command, stored in SDCMD 79 | mov A, SDCMD 80 | 81 | ; Double the CMD value, because ajmp opcodes are two-bytes 82 | rl A 83 | 84 | ; Actually jump. This jumps to 2*SDCMD 85 | mov DPTR, #sdi_jumptable 86 | jmp @A+DPTR 87 | 88 | ; --------------------------------------------------------------------------- 89 | 90 | setup_sd_rcv: 91 | clr 0xA0.2 92 | anl 0xE8, #0xFE 93 | anl 0xE8, #0xFD 94 | anl 0xE8, #0xFB 95 | anl 0xE8, #0xF7 96 | orl 0xDC, #4 97 | orl 0xDC, #8 98 | ret 99 | 100 | more_setup: 101 | lcall pause_a_while 102 | wait_for_packet_start: 103 | mov R5, #0 104 | mov A, 0xE8 105 | jnb ACC.0, wait_for_packet_start 106 | anl 0xE8, #0xFE 107 | wait_for_packet_end: 108 | jnb 0x90.4, wait_for_packet_end 109 | nop 110 | 111 | ;; 112 | anl 0xe8, #0xFD 113 | mov 0x20, #2 114 | mov 0x21, #5 115 | mov 0x22, #32 116 | mov 0x23, #66 117 | mov SD_DATL, #0xE8 118 | mov SD_DATH, #0x1F 119 | mov 0xDE, #0x03 120 | mov 0xDF, #0 121 | mov 0xE7, #0x01 122 | 123 | ; anl 0xE8, #0xFB 124 | ; orl 0xE5, #0x40 125 | ; mov 0xD4, #7 126 | ; mov 0xD5, #3 127 | ; mov 0xE1, #99 128 | ; mov 0xE2, #101 129 | ; orl 0xDC, #1 130 | ; 131 | ;transmitting: 132 | ; mov A, 0xE8 133 | ; jnb ACC.1, transmitting 134 | ; anl 0xE8, #0xFD 135 | ; anl 0xDC, #0xFE 136 | ; anl 0xE5, #0xBF 137 | ; orl 0xDC, #2 138 | 139 | waiting: 140 | sjmp waiting 141 | 142 | ret 143 | 144 | ; Point the ISR stored in DPTR to address 0x7b30 145 | ; DPTR [in]: Address of the ISR to set 146 | set_isr: 147 | mov A, #0x02 ; ljmp 148 | movx @DPTR, A 149 | 150 | inc DPTR 151 | mov A, #0x7b 152 | movx @DPTR, A 153 | 154 | inc DPTR 155 | mov A, #0x30 156 | movx @DPTR, A 157 | 158 | ret 159 | 160 | ; Wait for an SD packet to completely transfer 161 | ;wait_for_packet: 162 | ; mov A, SDSM 163 | ; anl A, #0xC 164 | ; jnz wait_for_packet 165 | ; ret 166 | 167 | 168 | ; --------------------------------------------------------------------------- 169 | 170 | 171 | setup_sdport: 172 | mov 0xd1, #0xe8 173 | orl 0xe9, #1 174 | nop 175 | nop 176 | nop 177 | nop 178 | nop 179 | nop 180 | nop 181 | nop 182 | orl 0xe9, #0x80 183 | ret 184 | 185 | reset_sdport: 186 | clr EA 187 | orl 0xd1, #1 188 | orl 0xb9, #2 189 | wait_sd_ready: 190 | jnb 0xe8.1, wait_sd_ready 191 | clr 0xe8.1 192 | ret 193 | 194 | reset_isrs: 195 | ; Set up ISR to call function at 0x7b3f. We're interested 196 | ; in both interrupt 0 and interrupt 1. 197 | ; These fire whenever we get an SD command. 198 | ;mov DPTR, #0x0003 199 | ;lcall set_isr 200 | ;mov DPTR, #0x0203 201 | ;lcall set_isr 202 | 203 | mov DPTR, #0x0000 ; IRQ0 204 | mov A, #0x32 ; reti instruction 205 | movx @DPTR, A 206 | 207 | mov DPTR, #0x0003 ; IRQ1 208 | mov A, #0x32 ; reti instruction 209 | movx @DPTR, A 210 | 211 | ; Make IRQ2 and IRQ3 simply "reti" 212 | mov DPTR, #0x000b ; IRQ2 213 | mov A, #0x32 ; reti instruction 214 | movx @DPTR, A 215 | 216 | mov DPTR, #0x0013 ; IRQ3 217 | mov A, #0x32 ; reti instruction 218 | movx @DPTR, A 219 | 220 | mov DPTR, #0x001b ; IRQ4 221 | mov A, #0x32 ; reti instruction 222 | movx @DPTR, A 223 | 224 | ret 225 | 226 | 227 | sdi_jumptable: 228 | ajmp cmd0 229 | ajmp cmd1 230 | ajmp cmd2 231 | ajmp sd3_SendCSD 232 | 233 | 234 | cmd0: 235 | cmd1: 236 | cmd2: 237 | sd3_SendCSD: 238 | jnb SDSM.4, sd3_SendCSD 239 | orl 0xCF, #0x10 240 | mov SD_DATL, #0xE8 241 | mov SD_DATH, #0x1F 242 | orl 0xCE, #1 243 | mov SD_BYTES, #0xF 244 | mov 0xE7, #0x71 245 | wait_for_csd_done: 246 | jnb SD_XMIT_STATE.2, wait_for_csd_done 247 | clr SD_XMIT_STATE.2 248 | ajmp return_from_sdi_irq 249 | 250 | 251 | return_from_sdi_irq: 252 | pop PSW 253 | pop DPL 254 | pop DPH 255 | pop 0x80 256 | pop ACC 257 | reti 258 | 259 | 260 | ; lcall wait_for_packet 261 | ; mov 0x31, SDCMD ; Copy the incoming SD packet 262 | ; mov 0x20, SDI1 ; to an area of memory commonly used 263 | ; mov 0x21, SDI2 ; by the SD transmission engine. Copy the 264 | ; mov 0x22, SDI3 ; incoming packet here as part of an echo-back 265 | ; mov 0x23, SDI4 ; program. 266 | ; 267 | ; orl SDSM, #1 ; Kick the SD state machine (what does this do?) 268 | 269 | exit_sdi_isr: 270 | pop PSW 271 | pop DPL 272 | pop DPH 273 | pop 0x80 274 | pop ACC 275 | ; setb SD_WAITING.1 ; Indicate we have a command waiting 276 | reti 277 | ; 278 | ;main_loop: 279 | ; mov A, 0x31 ; Copy SD command register to accumulator 280 | ; cjne A, #0x00, not_c00 281 | ; ajmp cmd_null 282 | ;not_c00:cjne A, #0x01, not_c01 283 | ; ajmp cmd_echo 284 | ;not_c01:cjne A, #0x02, not_c02 285 | ; ajmp cmd_peek 286 | ;not_c02:cjne A, #0x03, not_c03 287 | ; ajmp cmd_poke 288 | ;not_c03:cjne A, #0x04, not_c04 289 | ; ajmp cmd_jump 290 | ;not_c04:cjne A, #0x05, not_c05 291 | ; ajmp cmd_nand 292 | ;not_c05:cjne A, #0x06, not_c06 293 | ; ajmp cmd_sfr_set 294 | ;not_c06:cjne A, #0x07, not_c07 295 | ; ajmp cmd_sfr_get 296 | ;not_c07:cjne A, #0x08, not_c08 297 | ; ajmp cmd_ext_op 298 | ;not_c08:ajmp cmd_error 299 | ; 300 | ;; Send a 'hello' packet 301 | ;cmd_hello: 302 | ; mov 0x20, #0x41 303 | ; mov 0x21, #0x1f 304 | ; mov 0x22, #0x0f 305 | ; mov 0x23, #0x0f 306 | ; ajmp xmit_response 307 | ; 308 | ;; Send all zeroes 309 | ;cmd_null: 310 | ; mov 0x20, #0 311 | ; mov 0x21, #0 312 | ; mov 0x22, #0 313 | ; mov 0x23, #0 314 | ; ajmp xmit_response 315 | ; 316 | ;; Send an echo back 317 | ;cmd_echo: 318 | ; ajmp xmit_response 319 | ; 320 | ;; Peek at an area of memory 321 | ;cmd_peek: 322 | ; mov DPH, 0x20 ; DPH start src 323 | ; mov DPL, 0x21 ; DPL start src 324 | ; movx A, @DPTR 325 | ; mov 0x20, A 326 | ; inc DPTR 327 | ; 328 | ; movx A, @DPTR 329 | ; mov 0x21, A 330 | ; inc DPTR 331 | ; 332 | ; movx A, @DPTR 333 | ; mov 0x22, A 334 | ; inc DPTR 335 | ; 336 | ; movx A, @DPTR 337 | ; mov 0x23, A 338 | ; 339 | ; sjmp xmit_response 340 | ; 341 | ;; Poke into an area of memory 342 | ;cmd_poke: 343 | ; mov DPH, 0x20 344 | ; mov DPL, 0x21 345 | ; movx A, @DPTR 346 | ; mov B, A ; Save the old value 347 | ; 348 | ; mov A, 0x22 ; Copy the new value 349 | ; movx @DPTR, A 350 | ; 351 | ; mov 0x22, B 352 | ; mov 0x23, #0 353 | ; sjmp xmit_response 354 | ; 355 | ;; Jump to an address 356 | ;cmd_jump: 357 | ; mov 0x20, #1 358 | ; mov 0x21, #1 359 | ; mov 0x22, #1 360 | ; mov 0x23, #1 361 | ; sjmp xmit_response 362 | ; 363 | ;cmd_nand: 364 | ; mov NSRCL, 0x21 365 | ; mov NSRCH, 0x22 366 | ; mov NCMD, 0x20 367 | ; mov 0x20, #1 368 | ; mov 0x21, #2 369 | ; mov 0x22, #3 370 | ; mov 0x23, #4 371 | ; sjmp xmit_response 372 | ; 373 | ;cmd_sfr_get: 374 | ; ; This will get replaced by "mov 0x20, [SFR]" at runtime 375 | ; .db 0xa5, 0x60, 0x61 376 | ; mov 0x21, #0 377 | ; mov 0x22, #0 378 | ; mov 0x23, #0 379 | ; sjmp xmit_response 380 | ; 381 | ;cmd_sfr_set: 382 | ; ; This will get replaced by "mov [SFR], 0x20" at runtime 383 | ; .db 0xa5, 0x62, 0x63 384 | ; mov 0x21, #0 385 | ; mov 0x22, #0 386 | ; mov 0x23, #0 387 | ; sjmp xmit_response 388 | ; 389 | ;cmd_ext_op: 390 | ; .db 0xa5, 0x64, 0x65 391 | ; mov 0x20, #0 392 | ; mov 0x21, #0 393 | ; mov 0x22, #0 394 | ; mov 0x23, #0 395 | ; sjmp xmit_response 396 | ; 397 | ;; Send an error packet back 398 | ;cmd_error: 399 | ; mov 0x20, #0xa5 400 | ; mov 0x21, #0xa5 401 | ; mov 0x22, #0xa5 402 | ; mov 0x23, #0xa5 403 | ; sjmp xmit_response 404 | ; 405 | ;xmit_response: 406 | ; acall reset_sdport ; Set up the SD pins 407 | ; 408 | ;; mov SDDL, #0x74 ; Point the outgoing address at 409 | ;; mov SDDH, #0x05 ; the contents of RAM_0x20..RAM_0x24 410 | ;; 411 | ;; mov SD_BYTES, #0x03 ; Output four [sic] bytes 412 | ;; 413 | ;; mov SD_XMIT, #0x71 ; Kick off the transfer 414 | ; mov 0xd4, #0x91 415 | ; mov 0xd5, #0 416 | ; mov 0xe1, #7 417 | ; mov 0xe2, #0 418 | ; orl 0xe5, #1 419 | ; orl 0xb9, #8 420 | ;wait_xfer_done: 421 | ; jnb 0xe8.3, wait_xfer_done 422 | ; clr 0xe8.3 423 | ; anl 0xd1, #0xfe 424 | ; mov 0xcf, #4 425 | ; 426 | ; sjmp wait_for_next_command 427 | ; 428 | ;wait_for_next_command: 429 | ; clr SD_WAITING.1 430 | ;wait_sd_cmd: 431 | ; jnb SD_WAITING.1, wait_sd_cmd 432 | ; ajmp main_loop 433 | 434 | 435 | ; pause_a_while(while1, while2, while3) 436 | ; R5 [in]: "Small" amount to wait 437 | ; R6 [in]: "Medium" amount to wait 438 | ; R7 [in]: "Large" amount to wait 439 | ; Will count from 0 to R7R6R5. Every time a smaller value underflows, its 440 | ; larger neighbor will decrement. E.g. if R5 underflows from 0 to 255, R6 441 | ; will be decremented. This will conitnue until all values are zero. 442 | pause_a_while: 443 | mov R5, #0x00 444 | mov R6, #0x20 445 | mov R7, #0x01 446 | top_of_pause: 447 | djnz R5, top_of_pause 448 | djnz R6, top_of_pause 449 | ;djnz R7, top_of_pause 450 | ret 451 | 452 | ;====================== 453 | ; END OF ISR STUFF 454 | ;====================== 455 | 456 | main: 457 | setb 0x22.0 458 | mov A, 0x31 459 | jnz do_something 460 | mov A, 0xB5 461 | sjmp main 462 | 463 | do_something: 464 | clr EA 465 | mov DPTR, #main_jumptable 466 | 467 | ; ljmp instructions are three bytes, so triple the cmd size 468 | mov A, 0x31 469 | add A, 0x31 470 | add A, 0x31 471 | mov 0x31, #0 472 | setb EA 473 | jmp @A+DPTR 474 | 475 | main_jumptable: 476 | ljmp main_do_nothing 477 | 478 | 479 | main_do_nothing: 480 | ljmp main 481 | 482 | 483 | ; Debug routines 484 | emit_known_stuff: 485 | mov 0xef, #0xff 486 | nop 487 | nop 488 | nop 489 | mov R5, #0xff 490 | mov R6, #0x20 491 | loop1: 492 | djnz R5, loop1 493 | djnz R6, loop1 494 | mov 0xef, #0x00 495 | mov R5, #0xff 496 | mov R6, #0x20 497 | loop2: 498 | djnz R5, loop2 499 | djnz R6, loop2 500 | sjmp emit_known_stuff 501 | 502 | 503 | dump_rom: 504 | mov DPTR, #0 505 | dump_rom_top: 506 | mov 0xef, #0xff 507 | nop 508 | nop 509 | nop 510 | mov R5, #0xff 511 | mov R6, #0x20 512 | dump_loop1: 513 | djnz R5, dump_loop1 514 | djnz R6, dump_loop1 515 | mov 0xef, #0xfe 516 | mov R5, #0xff 517 | mov R6, #0x20 518 | dump_loop2: 519 | djnz R5, dump_loop2 520 | djnz R6, dump_loop2 521 | sjmp dump_rom_top 522 | -------------------------------------------------------------------------------- /src/as31/symbol.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * FILE: symbol.c 3 | * PACKAGE: as31 - 8031/8051 Assembler. 4 | * 5 | * DESCRIPTION: 6 | * This file contains the symbol table search/insertion routines 7 | * associated with user defined symbols. 8 | * 9 | * The reserved keyword (instructions/directives) look up routine 10 | * is defined here. 11 | * 12 | * The opcode table for all of the instructions is located in this 13 | * file. 14 | * 15 | * REVISION HISTORY: 16 | * Jan. 19, 1990 - Created. (Ken Stauffer) 17 | * 18 | * AUTHOR: 19 | * All code in this file written by Ken Stauffer (University of Calgary) 20 | * January, 1990. 21 | * 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | /* normally in stdlib.h, but that include file also defines */ 28 | /* "div" which conflicts with the div in this file */ 29 | extern void *malloc(size_t size); 30 | extern void free(void *ptr); 31 | 32 | 33 | #include "as31.h" 34 | #include "parser.h" 35 | 36 | #define B(a) (0xF0+(a)) 37 | #define ACC(a) (0xE0+(a)) 38 | #define PSW(a) (0xD0+(a)) 39 | #define T2CON(a) (0xC8+(a)) 40 | #define IP(a) (0xB8+(a)) 41 | #define P3(a) (0xB0+(a)) 42 | #define IE(a) (0xA8+(a)) 43 | #define P2(a) (0xA0+(a)) 44 | #define SCON(a) (0x98+(a)) 45 | #define P1(a) (0x90+(a)) 46 | #define TCON(a) (0x88+(a)) 47 | #define P0(a) (0x80+(a)) 48 | 49 | /* ---------------------------------------------------------------------- 50 | * sinit[] 51 | * These symbols are not reserved keywords. 52 | * This array contains the initial symbol table entries 53 | * for the user symbol table. The symbols are 54 | * basically convienient names that make writing 55 | * in 8031/8051 bearable. 56 | * 57 | * The function syminit() inserts these entries into the 58 | * symbol table. 59 | * 60 | */ 61 | 62 | static struct symbol sinit[] = { 63 | { "AC", 1, LABEL, PSW(6), NULL }, 64 | { "ACC", 1, LABEL, ACC(0), NULL }, 65 | { "B", 1, LABEL, B(0), NULL }, 66 | { "CY", 1, LABEL, PSW(7), NULL }, 67 | { "DPH", 1, LABEL, 0x83, NULL }, 68 | { "DPL", 1, LABEL, 0x82, NULL }, 69 | { "EA", 1, LABEL, IE(7), NULL }, 70 | { "ES", 1, LABEL, IE(4), NULL }, 71 | { "ET0", 1, LABEL, IE(1), NULL }, 72 | { "ET1", 1, LABEL, IE(3), NULL }, 73 | { "ET2", 1, LABEL, IE(5), NULL }, 74 | { "EX0", 1, LABEL, IE(0), NULL }, 75 | { "EX1", 1, LABEL, IE(2), NULL }, 76 | { "EXEN2", 1, LABEL, T2CON(3),NULL }, 77 | { "EXF2", 1, LABEL, T2CON(6),NULL }, 78 | { "F0", 1, LABEL, PSW(5), NULL }, 79 | { "IE", 1, LABEL, IE(0), NULL }, 80 | { "IE0", 1, LABEL, TCON(1),NULL }, 81 | { "IE1", 1, LABEL, TCON(3),NULL }, 82 | { "INT0", 1, LABEL, P3(2), NULL }, 83 | { "INT1", 1, LABEL, P3(3), NULL }, 84 | { "IP", 1, LABEL, IP(0), NULL }, 85 | { "IT0", 1, LABEL, TCON(0),NULL }, 86 | { "IT1", 1, LABEL, TCON(2),NULL }, 87 | { "OV", 1, LABEL, PSW(2), NULL }, 88 | { "P", 1, LABEL, PSW(0), NULL }, 89 | { "P0", 1, LABEL, P0(0), NULL }, 90 | { "P1", 1, LABEL, P1(0), NULL }, 91 | { "P2", 1, LABEL, P2(0), NULL }, 92 | { "P3", 1, LABEL, P3(0), NULL }, 93 | { "PCON", 1, LABEL, 0x87, NULL }, 94 | { "PS", 1, LABEL, IP(4), NULL }, 95 | { "PSW", 1, LABEL, PSW(0), NULL }, 96 | { "PT0", 1, LABEL, IP(1), NULL }, 97 | { "PT1", 1, LABEL, IP(3), NULL }, 98 | { "PT2", 1, LABEL, IP(5), NULL }, 99 | { "PX0", 1, LABEL, IP(0), NULL }, 100 | { "PX1", 1, LABEL, IP(2), NULL }, 101 | { "RB8", 1, LABEL, SCON(2),NULL }, 102 | { "RCAP2H", 1, LABEL, 0xCB, NULL }, 103 | { "RCAP2L", 1, LABEL, 0xCA, NULL }, 104 | { "RCLK", 1, LABEL, T2CON(5),NULL }, 105 | { "REN", 1, LABEL, SCON(4),NULL }, 106 | { "RD", 1, LABEL, P3(7), NULL }, 107 | { "RI", 1, LABEL, SCON(0),NULL }, 108 | { "RL2", 1, LABEL, T2CON(0),NULL }, 109 | { "RS0", 1, LABEL, PSW(3), NULL }, 110 | { "RS1", 1, LABEL, PSW(4), NULL }, 111 | { "RXD", 1, LABEL, P3(0), NULL }, 112 | { "SBUF", 1, LABEL, 0x99, NULL }, 113 | { "SCON", 1, LABEL, SCON(0),NULL }, 114 | { "SM0", 1, LABEL, SCON(7),NULL }, 115 | { "SM1", 1, LABEL, SCON(6),NULL }, 116 | { "SM2", 1, LABEL, SCON(5),NULL }, 117 | { "SP", 1, LABEL, 0x81, NULL }, 118 | { "T0", 1, LABEL, P3(4), NULL }, 119 | { "T1", 1, LABEL, P3(5), NULL }, 120 | { "T2", 1, LABEL, P0(0), NULL }, 121 | { "T2CON", 1, LABEL, T2CON(0),NULL }, 122 | { "T2EX", 1, LABEL, P0(1), NULL }, 123 | { "TB8", 1, LABEL, SCON(3),NULL }, 124 | { "TCLK", 1, LABEL, T2CON(4),NULL }, 125 | { "TCON", 1, LABEL, TCON(0),NULL }, 126 | { "TF0", 1, LABEL, TCON(5),NULL }, 127 | { "TF1", 1, LABEL, TCON(7),NULL }, 128 | { "TF2", 1, LABEL, T2CON(7),NULL }, 129 | { "TH0", 1, LABEL, 0x8C, NULL }, 130 | { "TH1", 1, LABEL, 0x8D, NULL }, 131 | { "TH2", 1, LABEL, 0xCD, NULL }, 132 | { "TI", 1, LABEL, SCON(1),NULL }, 133 | { "TL0", 1, LABEL, 0x8A, NULL }, 134 | { "TL1", 1, LABEL, 0x8B, NULL }, 135 | { "TL2", 1, LABEL, 0xCC, NULL }, 136 | { "TMOD", 1, LABEL, 0x89, NULL }, 137 | { "TR0", 1, LABEL, TCON(4),NULL }, 138 | { "TR1", 1, LABEL, TCON(6),NULL }, 139 | { "TR2", 1, LABEL, T2CON(2),NULL }, 140 | { "TXD", 1, LABEL, P3(1), NULL }, 141 | { "WR", 1, LABEL, P3(6), NULL }, 142 | }; 143 | 144 | #define SINITSIZE (sizeof(sinit)/sizeof(sinit[0])) 145 | 146 | /* ---------------------------------------------------------------------- 147 | * opcode vectors: 148 | * These arrays contain the various opcodes for the 149 | * various forms an instruction may take. 150 | * 151 | * The ordering of these opcodes is very critical to the 152 | * proper fuctioning of the assembler. 153 | * 154 | * When a given form of an instruction is parsed, the parser 155 | * indexes one of these arrays by the correct amount and thus 156 | * obtains the correct opcode for the particular form. 157 | * 158 | */ 159 | 160 | static unsigned char acall[]= { 0x11 }; 161 | static unsigned char add[]= { 0x28, 0x25, 0x26, 0x24 }; 162 | static unsigned char addc[]= { 0x38, 0x35, 0x36, 0x34 }; 163 | static unsigned char ajmp[]= { 0x01 }; 164 | static unsigned char anl[]= { 0x58, 0x55, 0x56, 0x54, 0x52, 0x53, 0x82, 165 | 0xb0 }; 166 | static unsigned char cjne[]= { 0xb5, 0xb4, 0xb8, 0xb6 }; 167 | static unsigned char clr[]= { 0xe4, 0xc3, 0xc2 }; 168 | static unsigned char cpl[]= { 0xf4, 0xb3, 0xb2 }; 169 | static unsigned char da[]= { 0xd4 }; 170 | static unsigned char dec[]= { 0x14, 0x18, 0x15, 0x16 }; 171 | static unsigned char div[]= { 0x84 }; 172 | static unsigned char djnz[]= { 0xd8, 0xd5 }; 173 | static unsigned char inc[]= { 0x04, 0x08, 0x05, 0x06, 0xa3 }; 174 | static unsigned char jb[]= { 0x20 }; 175 | static unsigned char jbc[]= { 0x10 }; 176 | static unsigned char jc[]= { 0x40 }; 177 | static unsigned char jmp[]= { 0x73 }; 178 | static unsigned char jnb[]= { 0x30 }; 179 | static unsigned char jnc[]= { 0x50 }; 180 | static unsigned char jnz[]= { 0x70 }; 181 | static unsigned char jz[]= { 0x60 }; 182 | static unsigned char lcall[]= { 0x12 }; 183 | static unsigned char ljmp[]= { 0x02 }; 184 | static unsigned char mov[]= { 0xe8, 0xe5, 0xe6, 0x74, 0xf5, 0x75, 0xf8, 185 | 0xa8, 0x78, 0x88, 0x85, 0x86, 0xf6, 0xa6, 186 | 0x76, 0x90, 0xa2, 0x92 }; 187 | static unsigned char movc[]= { 0x93, 0x83 }; 188 | static unsigned char movx[]= { 0xe2, 0xe3, 0xe0, 0xf2, 0xf3, 0xf0 }; 189 | static unsigned char mul[]= { 0xa4 }; 190 | static unsigned char nop[]= { 0x00 }; 191 | static unsigned char orl[]= { 0x48, 0x45, 0x46, 0x44, 0x42, 0x43, 0x72, 192 | 0xa0 }; 193 | static unsigned char pop[]= { 0xd0 }; 194 | static unsigned char push[]= { 0xc0 }; 195 | static unsigned char ret[]= { 0x22 }; 196 | static unsigned char reti[]= { 0x32 }; 197 | static unsigned char rl[]= { 0x23 }; 198 | static unsigned char rlc[]= { 0x33 }; 199 | static unsigned char rr[]= { 0x03 }; 200 | static unsigned char rrc[]= { 0x13 }; 201 | static unsigned char setb[]= { 0xd3, 0xd2 }; 202 | static unsigned char sjmp[]= { 0x80 }; 203 | static unsigned char subb[]= { 0x98, 0x95, 0x96, 0x94 }; 204 | static unsigned char swap[]= { 0xc4 }; 205 | static unsigned char xch[]= { 0xc8, 0xc5, 0xc6 }; 206 | static unsigned char xchd[]= { 0xd6 }; 207 | static unsigned char xrl[]= { 0x68, 0x65, 0x66, 0x64, 0x62, 0x63 }; 208 | 209 | /* ---------------------------------------------------------------------- 210 | * optable[] 211 | * This table contains opcodes, directives and a few reserved 212 | * symbols. 213 | * 214 | * The second field is the keywords token value. 215 | * 216 | * Unless the symbol is an opcode, the third field will 217 | * be NULL. 218 | * 219 | * The third field is a pointer to an array of opcode bytes. 220 | * 221 | * --> This list must be in order by the first field 222 | */ 223 | 224 | static struct opcode optable[] = { 225 | {"a", A, NULL }, 226 | {"ab", AB, NULL }, 227 | {"acall", ACALL, acall }, 228 | {"add", ADD, add }, 229 | {"addc", ADDC, addc }, 230 | {"ajmp", AJMP, ajmp }, 231 | {"anl", ANL, anl }, 232 | {"byte", D_BYTE, NULL }, 233 | {"c", C, NULL }, 234 | {"cjne", CJNE, cjne }, 235 | {"clr", CLR, clr }, 236 | {"cpl", CPL, cpl }, 237 | {"da", DA, da }, 238 | {"db", D_BYTE, NULL }, 239 | {"dec", DEC, dec }, 240 | {"div", DIV, div }, 241 | {"djnz", DJNZ, djnz }, 242 | {"dptr", DPTR, NULL }, 243 | {"dw", D_WORD, NULL }, 244 | {"end", D_END, NULL }, 245 | {"equ", D_EQU, NULL }, 246 | {"flag", D_FLAG, NULL }, 247 | {"inc", INC, inc }, 248 | {"jb", JB, jb }, 249 | {"jbc", JBC, jbc }, 250 | {"jc", JC, jc }, 251 | {"jmp", JMP, jmp }, 252 | {"jnb", JNB, jnb }, 253 | {"jnc", JNC, jnc }, 254 | {"jnz", JNZ, jnz }, 255 | {"jz", JZ, jz }, 256 | {"lcall", LCALL, lcall }, 257 | {"ljmp", LJMP, ljmp }, 258 | {"mov", MOV, mov }, 259 | {"movc", MOVC, movc }, 260 | {"movx", MOVX, movx }, 261 | {"mul", MUL, mul }, 262 | {"nop", NOP, nop }, 263 | {"org", D_ORG, NULL }, 264 | {"orl", ORL, orl }, 265 | {"pc", PC, NULL }, 266 | {"pop", POP, pop }, 267 | {"push", PUSH, push }, 268 | {"r0", R0, NULL }, 269 | {"r1", R1, NULL }, 270 | {"r2", R2, NULL }, 271 | {"r3", R3, NULL }, 272 | {"r4", R4, NULL }, 273 | {"r5", R5, NULL }, 274 | {"r6", R6, NULL }, 275 | {"r7", R7, NULL }, 276 | {"ret", RET, ret }, 277 | {"reti", RETI, reti }, 278 | {"rl", RL, rl }, 279 | {"rlc", RLC, rlc }, 280 | {"rr", RR, rr }, 281 | {"rrc", RRC, rrc }, 282 | {"setb", SETB, setb }, 283 | {"sjmp", SJMP, sjmp }, 284 | {"skip", D_SKIP, NULL }, 285 | {"subb", SUBB, subb }, 286 | {"swap", SWAP, swap }, 287 | {"word", D_WORD, NULL }, 288 | {"xch", XCH, xch }, 289 | {"xchd", XCHD, xchd }, 290 | {"xrl", XRL, xrl } 291 | }; 292 | 293 | #define OPTABSIZE (sizeof(optable)/sizeof(struct opcode)) 294 | 295 | 296 | /* ---------------------------------------------------------------------- 297 | * lookop: 298 | * Do a binary search through optable[], for a matching 299 | * symbol. Return the symbol found or NULL. 300 | * 301 | */ 302 | 303 | struct opcode *lookop(const char *s) 304 | { 305 | register int low,high,mid,cond; 306 | 307 | low = 0; 308 | high = OPTABSIZE-1; 309 | while( low<=high ) { 310 | mid = (low+high)/2; 311 | if( (cond = strcasecmp(s,optable[mid].name)) < 0 ) 312 | high = mid-1; 313 | else if(cond > 0 ) 314 | low = mid+1; 315 | else 316 | return(&optable[mid]); 317 | } 318 | return(NULL); 319 | } 320 | 321 | /* ---------------------------------------------------------------------- 322 | * symtab, hash, looksym: 323 | * User symbol table routines. 324 | * symtab is the hash table for the user symbols. 325 | * (chaining is used for collision resolution). 326 | * 327 | */ 328 | 329 | static struct symbol *symtab[HASHTABSIZE]; 330 | 331 | int hash(const char *s) 332 | { 333 | register const char *p; 334 | register unsigned h=0, g; 335 | 336 | for (p=s; *p; p++) { 337 | h = (h<<4) + toupper(*p); 338 | if ( (g = h&0xf0000000) ) { 339 | h = h ^ (g >> 24); 340 | h = h ^ g; 341 | } 342 | } 343 | return( h % HASHTABSIZE ); 344 | } 345 | 346 | struct symbol *looksym(const char *s) 347 | { 348 | register struct symbol *ptr, *prev; 349 | char *p; 350 | register int hv; 351 | 352 | hv = hash(s); 353 | 354 | prev = NULL; 355 | for(ptr=symtab[hv]; ptr; ptr = ptr->next) { 356 | if( !strcasecmp(ptr->name,s) ) { 357 | if( prev != NULL ) { 358 | prev->next = ptr->next; 359 | ptr->next = symtab[hv]; 360 | symtab[hv] = ptr; 361 | } 362 | return(ptr); 363 | } 364 | prev = ptr; 365 | } 366 | 367 | if ( (p = malloc(strlen(s) + 1)) ) { 368 | strcpy(p,s); 369 | } else { 370 | error("Cannot allocate %d bytes",strlen(s)+1); 371 | } 372 | 373 | ptr = (struct symbol *) malloc( sizeof(struct symbol) ); 374 | if( ptr == NULL ) 375 | error("Cannot allocate %d bytes",sizeof(struct symbol)); 376 | ptr->name = p; 377 | ptr->predefined = 0; 378 | ptr->type = UNDEF; 379 | ptr->next = symtab[hv]; 380 | symtab[hv] = ptr; 381 | return(ptr); 382 | } 383 | 384 | /* ---------------------------------------------------------------------- 385 | * syminit: 386 | * Initializes the hash table, with the initial symbols from 387 | * sinit[] 388 | * 389 | */ 390 | 391 | // static struct symbol *symtab[HASHTABSIZE]; 392 | 393 | void syminit(void) 394 | { 395 | register int i,hv; 396 | 397 | /* clear all entries in the symbol table */ 398 | memset(symtab, 0, sizeof(struct symbol *) * HASHTABSIZE); 399 | 400 | /* load all the pre-defined symbols */ 401 | for(i=0; ipredefined) { 421 | sym = sym->next; 422 | } else { 423 | if (sym->name) free(sym->name); 424 | next = sym->next; 425 | free(sym); 426 | sym = next; 427 | } 428 | } 429 | } 430 | } 431 | 432 | 433 | 434 | --------------------------------------------------------------------------------