Mercurial > hg > ede
changeset 29:83e80c2c489c
seperated working emu code from broken emu code.
wrote dbg interface
author | james <jb302@eecs.qmul.ac.uk> |
---|---|
date | Sun, 13 Apr 2014 22:42:57 +0100 |
parents | 6d32e54e5c16 |
children | c0c2e99b6bb0 |
files | asm/asm.pyc bin/emu build.sh cli.py dbg/cli.py dbg/dbg.py dbg/dbg.pyc dbg/out doc/general/.~lock.elb816_opcodes.csv# emu/iset.c emu/main.c emu/mem.c emu/mem.h emu/test_mem.c out tests/asm/a.out tests/asm/full.bin tests/emu/mem/test_mem tests/emu/mem/test_mem.bin tests/emu/mem/test_mem.c tests/emu/test.c tests/emu/test_mem tests/emu/test_mem.bin |
diffstat | 22 files changed, 502 insertions(+), 179 deletions(-) [+] |
line wrap: on
line diff
--- a/build.sh Fri Apr 11 14:38:09 2014 +0100 +++ b/build.sh Sun Apr 13 22:42:57 2014 +0100 @@ -1,5 +1,7 @@ #!/bin/bash -gcc -std=c89 emu/main.c emu/mem.c -o bin/emu +gcc -std=c89 emu/main.c emu/mem.c emu/iset.c -o bin/emu killall emu; rm out; -ipython -i dbg/dbg.py + +#cd dbg/ +#ipython -i dbg.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cli.py Sun Apr 13 22:42:57 2014 +0100 @@ -0,0 +1,139 @@ +#!/usr/bin/env python +# cli.py - a command line to control the emulator using +# the debug control class + +import struct +from StringIO import StringIO +from io import BytesIO +from subprocess import Popen, PIPE, STDOUT + +from asm import asm +from dbg import dbg + +syms = { + 'R0_0':0, + 'R1_0':1, + 'R2_0':2, + 'R3_0':3, + 'DPH':4, + 'SPH':5, + 'PCH':6, + 'TMPH':7, + 'RO_1':8, + 'R1_1':9, + 'R2_1':10, + 'R3_1':11, + 'DPL':12, + 'SPL':13, + 'PCL':14, + 'TMPL':15, + 'BS':0, + 'IE':1, + 'OV':2, + 'S':3, + 'P':4, + 'AC':5, + 'Z':6, + 'C':7 + } + +emu = dbg.controller() +emu.Emu = Popen(['bin/emu'], stdout=PIPE, stdin=PIPE, stderr=PIPE) + + +# assemble and execute inline asm. +# bytecode is copied to where ever the PC is and then executed +def exc(): + + while True: + # file like objects for source and byte code + code = StringIO() + bytecode = BytesIO() + + # get the PC + pch = struct.unpack('>B', emu.get_reg(syms['PCH']))[0] + pcl = struct.unpack('>B', emu.get_reg(syms['PCL']))[0] + + # get user input + c = raw_input() + if c == 'exit': + break + code.write(c) + + try: + # assemble and determine length bytes + a, l = asm.first_pass(code) + if l.keys() != []: + print 'labels not yet supported in interpreter mode' + continue + bytecode = asm.second_pass(bytecode, a, l) + bytecode.seek(0) + byte_array = bytearray(bytecode.read()) + except: + print 'invalid instruction' + continue + + print hex(pcl | (pch << 8)), [hex(b) for b in byte_array] + # write to emu memory and execute + emu.set_block(pch, pcl, byte_array) + emu.step() + +cmds = { + 'step':emu.step, + 'run':emu.run, + 'gr':emu.get_reg, + 'sr':emu.set_reg, + 'gf':emu.get_flag, + 'sf':emu.set_flag, + 'gb':emu.get_block, + 'sb':emu.set_block, + 'ga':emu.get_a, + 'gfs':emu.get_flags, + 'gir':emu.get_ir, + } + +if __name__ == '__main__': + + while True: + + inp = raw_input('> ').split() + if inp == []: + continue + cmd = inp[0] + args = [] + + #try: + # deal with inline execution independently + if cmd == 'exc': + exc() + continue + + # set block has unique argument syntax + if cmd == 'sb': + args.append(int(inp[1], 0)) + args.append(int(inp[2], 0)) + args.append([int(x, 0) for x in inp[3:]]) + cmds[cmd](*args) + continue + + # decode args + i = 0 + for word in inp[1:]: + if word in syms.keys(): + args.append(syms[word]) + # only arguments after 3 will be data for set block + # this needs to be in a list + else: + args.append(int(word, 0)) + i = i + 1 + + resp = cmds[cmd](*args) + if resp == None: + continue + else: + print [hex(struct.unpack('>B', x)[0]) for x in resp] + + #except: + # print 'invalid command or argument syntax' + # continue +
--- a/dbg/cli.py Fri Apr 11 14:38:09 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -from assembler.language import * -from struct import pack -#from debugger import dbg - -while True: - c = raw_input().lower().split() - mne = c[0] - args = ''.join(c[1:]).split(',') - sym, data = tokenize(mne, args) - op = pack('>B', iset[mne][sym][0]) - print op, data -
--- a/dbg/dbg.py Fri Apr 11 14:38:09 2014 +0100 +++ b/dbg/dbg.py Sun Apr 13 22:42:57 2014 +0100 @@ -2,89 +2,89 @@ # dbg.py - debug client import struct import os, sys -from subprocess import Popen, PIPE, STDOUT +from time import sleep -emu = Popen(['./a.out'], stdout=PIPE, stdin=PIPE, stderr=PIPE) +# talks to the emulator +# see dbgi() in emu/main.c for the inverse +class controller: + + def __init__(self): + self.Emu = None + open('out', 'w').close() + + def snd(self, m): + self.Emu.stdin.write(struct.pack('>B', m)) -def snd(m): - emu.stdin.write(struct.pack('>B', m)) + def rcv(self, l): + lc = 0 + while lc != l: + lc = os.path.getsize('out') + sleep(0.5) + with open('out', 'r') as f: + c = f.read() + open('out', 'w').close() + return c -def rcv(): - with open('out', 'r') as f: - c = f.read() - return c + def step(self): + self.snd(0x00) -def step(): - snd(0x00) + def run(self, lenh, lenl): + self.snd(0x01) + snd(lenh) + snd(lenl) -def run(): - snd(0x01) + def set_reg(self, reg, data): + self.snd(0x02) + self.snd(reg) # reg + self.snd(data) # data -def set_reg(reg, data): - snd(0x02) - snd(reg) # reg - snd(data) # data + def get_reg(self, reg): + self.snd(0x03) + self.snd(reg) # reg + return self.rcv(1) -def get_reg(reg): - snd(0x03) - snd(reg) # reg - #return rcv() + def set_flag(self, flag, on): + self.snd(0x04) + if on == 0: + self.snd(flag) + self.snd(0) + else: + self.snd(flag) + self.snd(1) -def set_flag(flag, on): - snd(0x04) - if on == 0: - snd(flag) - snd(0) - else: - snd(flag) - snd(1) + def get_flag(self, flag): + self.snd(0x05) + self.snd(flag) + return self.rcv(1) -def get_flag(flag): - snd(0x05) - snd(flag) - #return rcv() + def set_block(self, addrh, addrl, data): + self.snd(0x06) + self.snd(addrh) # address high byte + self.snd(addrl) # address low byte + self.snd((len(data) >> 8) & 0xFF) + self.snd(len(data) & 0xFF) + for b in data: + self.snd(b) # data -def set_block(addrh, addrl, lenh, lenl, data): - snd(0x06) - snd(addrh) # address high byte - snd(addrl) # address low byte - snd(lenh) - snd(lenl) - for b in data: - snd(b) # data + def get_block(self, addrh, addrl, lenh, lenl): + block = [] + self.snd(0x07) + self.snd(addrh) # address high byte + self.snd(addrl) # address low byte + self.snd(lenh) + self.snd(lenl) + return self.rcv(lenl | (lenh << 8)) -def get_block(addrh, addrl, lenh, lenl): - block = [] - snd(0x07) - snd(addrh) # address high byte - snd(addrl) # address low byte - snd(lenh) - snd(lenl) - #lc = 0 - #while lc != l: - # lc = os.path.getsize('out'); - #return rcv() + def get_a(self): + self.snd(0x09) + return self.rcv(1) -registers = { - 'r0':0, - 'r1':1, - 'r2':2, - 'r3':3, - 'dph':4, - 'dpl':5, - 'sph':6, - 'spl':7, - 'a':8, - 'flags':9 - } + def get_flags(self): + self.snd(0x0A) + return self.rcv(1) -cmds = { - 'step':step, - 'run':run, - 'sr':set_reg, - 'gr':get_reg, - 'sf':set_flag, - 'gf':get_flag, - 'sb':set_block, - 'gb':get_block - } + def get_ir(self): + self.snd(0x0B) + return self.rcv(1) + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dbg/out Sun Apr 13 22:42:57 2014 +0100 @@ -0,0 +1,1 @@ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/general/.~lock.elb816_opcodes.csv# Sun Apr 13 22:42:57 2014 +0100 @@ -0,0 +1,1 @@ +,jmz,xthUnk,12.04.2014 15:52,file:///home/jmz/.config/libreoffice/4; \ No newline at end of file
--- a/emu/iset.c Fri Apr 11 14:38:09 2014 +0100 +++ b/emu/iset.c Sun Apr 13 22:42:57 2014 +0100 @@ -21,15 +21,15 @@ switch (IR) { case 0x08: - set_flag(0x07, 0x01); + set_flag(C, 0x01); break; case 0x0A: - set_flag(0x00, 0x01); + set_flag(BS, 0x01); break; case 0x0C: - set_flag(0x01, 0x01); + set_flag(IE, 0x01); break; default: @@ -45,15 +45,15 @@ switch (IR) { case 0x09: - set_flag(0x07, 0x00); + set_flag(C, 0x00); break; case 0x0B: - set_flag(0x00, 0x00); + set_flag(BS, 0x00); break; case 0x0D: - set_flag(0x01, 0x00); + set_flag(IE, 0x00); break; default: @@ -68,11 +68,11 @@ switch (IR) { case 0x0E: - if (get_flag(0x07) == 0) { - set_flag(0x07, 0x01); + if (get_flag(C) == 0) { + set_flag(C, 0x01); } else { - set_flag(0x07, 0x00); + set_flag(C, 0x00); } case 0x0F: @@ -120,7 +120,7 @@ case 0x00: switch (IR & 0xF8) { - /* 0b00010XXX */ + /* 0b00010XXX - special MOVs*/ case 0x10: switch (NNN) { @@ -154,7 +154,7 @@ } break; - /* 0b00011XXX */ + /* 0b00011XXX - direct, indirect and indexed MOVs*/ case 0x18: switch (NNN) { @@ -172,12 +172,14 @@ /* MOV A, @A+DPTR */ case 2: - A = mem[A + get_wide(DPTR)]; + set_wide(TMP, A + get_wide(DPTR)); + A = mem[get_wide(TMP)]; break; /* MOV A, @A+PC */ case 3: - A = mem[A + get_wide(PC)]; + set_wide(TMP, A + get_wide(PC)); + A = mem[TMP]; break; /* MOV A, @addr16 */ @@ -194,12 +196,14 @@ /* MOV A, @DPTR */ case 6: - A = mem[get_wide(DPTR)]; + set_wide(TMP, get_wide(DPTR)); + A = mem[get_wide(TMP)]; break; /* MOV @DPTR, A */ case 7: - mem[get_wide(DPTR)] = A; + set_wide(TMP, get_wide(DPTR)); + mem[get_wide(TMP)] = A; break; default: @@ -207,29 +211,41 @@ } break; - /* 0b00100nnn */ + /* 0b00100nnn - MOV @DPTR, Rn*/ case 0x20: + set_wide(TMP, get_wide(DPTR)); + set_reg(NNN, mem[get_wide(TMP)]); break; - /* 0b00101nnn */ + /* 0b00101nnn - immediate movs - MOV Rn, #data8*/ case 0x28: + set_reg(NNN, fetch()); break; - /* 0b00110nnn */ + /* 0b00110nnn - MOV Rn, A */ case 0x30: + set_reg(NNN, A); break; /* 0b00111nnn */ case 0x38: + A = get_reg(NNN); break; default: break; } - break; + break;; /* 0b01mmmnnn */ case 0x40: + if (NNN == MMM) { + set_wide(TMP, get_wide(DPTR)); + set_reg(NNN, mem[get_wide(TMP)]); + } + else { + set_reg(MMM, get_reg(NNN)); + } break; default:
--- a/emu/main.c Fri Apr 11 14:38:09 2014 +0100 +++ b/emu/main.c Sun Apr 13 22:42:57 2014 +0100 @@ -42,9 +42,9 @@ MUL, DIV, DA, NOP, IN, OUT, INT, HLT }; -BYTE run; -WIDE ac; -BYTE args[4]; +BYTE free_run; /* free run if not 0 */ +WIDE ac; /* address counter */ +BYTE args[4]; /* dbg args */ /* don't need the file on the MCS-51 version */ FILE *fp; @@ -67,14 +67,8 @@ (*iset[IR])(); } -void -boot(void) { - run = 0; -} - - void dbgi() { - if (run == 0) { + if (free_run == 0) { switch (rcv()) { /* step */ @@ -84,7 +78,12 @@ /* run */ case 0x01: - run = 1; + args[0] = rcv(); /* length high */ + args[1] = rcv(); /* length low */ + tmpw = get_wide(PC); + for (ac = tmpw ; ac < tmpw + MWIDE(args[0], args[1]) ; ac++) { + step(); + } break; /* set reg */ @@ -119,8 +118,8 @@ args[1] = rcv(); /* addr low */ args[2] = rcv(); /* length high */ args[3] = rcv(); /* length low */ - tmpw = args[1] | (args[0] << 8); - for (ac = tmpw; ac < (tmpw + (args[3] | (args[2] << 8))); ac++) { + tmpw = MWIDE(args[0], args[1]); + for (ac = tmpw; ac < tmpw + MWIDE(args[2], args[3]); ac++) { if (ac >= 0xFFFF) { break; } @@ -134,8 +133,8 @@ args[1] = rcv(); /* addr low */ args[2] = rcv(); /* length high */ args[3] = rcv(); /* length low */ - tmpw = args[1] | (args[0] << 8); - for (ac = tmpw; ac < (tmpw + (args[3] | (args[2] << 8))); ac++) { + tmpw = MWIDE(args[0], args[1]); + for (ac = tmpw; ac < tmpw + MWIDE(args[2], args[3]); ac++) { if (ac >= 0xFFFF) { break; } @@ -146,63 +145,27 @@ /* get A */ case 0x09: snd(A); + break; /* get flags */ - case 0x0F: + case 0x0A: snd(flags); + break; /* get instruction register */ - case 0x10: + case 0x0B: snd(IR); + break; } } } void main(void) { - - A = 0xAA; - IR = 0x12; - - unsigned char i; - for (i = 0 ; i < 8 ; i++) { - set_flag(i, 1); + /* dont go into free run on restart */ + free_run = 0; + for (;;) { + dbgi(); } - - set_wide(DPTR, 0xDE1D); - set_wide(PC, 0xBEFA); - set_wide(SP, 0xADEA); - set_wide(TMP, 0xEFC3); - - for (i = 0; i < 4; i++) { - regs[i] = i; - } - - for (i = 8; i < 0x0C; i++) { - regs[i] = 0x10 | (i - 8); - } - - /* 0xAA 0x12 0xFF - * 0x00 0x01 0x02 0x03 - * 0xDE 0xAD 0xBE 0xFF - * 0x10 0x11 0x12 0x13 - * 0x1D 0xEA 0xFA 0xC3 */ - - putchar(A); - putchar(IR); - putchar(flags); - - for (i = 0; i < 0x10; i++) { - putchar(regs[i]); - } - - unsigned short int data_pointer = get_wide(DPTR); - unsigned short int program_counter = get_wide(PC); - unsigned short int stack_pointer = get_wide(SP); - unsigned short int temp = get_wide(tmp); - - - - }
--- a/emu/mem.c Fri Apr 11 14:38:09 2014 +0100 +++ b/emu/mem.c Sun Apr 13 22:42:57 2014 +0100 @@ -19,27 +19,25 @@ void set_flag(BYTE flag, BYTE on) { if (flag <= 7) { - switch (on) { - - case 0: - flags = CBIT(flags, flag); - - default: - flags = SBIT(flags, flag); + if (on == 0x00) { + flags = CBIT(flags, flag); + } + else { + flags = SBIT(flags, flag); } } } WIDE get_wide(BYTE reg) { - /* low | (high << 8) */ - return (regs[reg + 12] | (regs[reg + 4] << 8)); + /* high, low */ + return MWIDE(regs[reg + 4], regs[reg + 12]); } void set_wide(BYTE reg, WIDE val) { - regs[reg + 4] = (val >> 8) & 0xFF; /* high */ - regs[reg + 12] = val & 0xFF; /* low */ + regs[reg + 4] = GHIGH(val); /* high */ + regs[reg + 12] = GLOW(val); /* low */ } void @@ -59,9 +57,63 @@ WIDE fetch_wide(void) { - WIDE val = mem[get_wide(PC)] | (mem[get_wide(PC + 1)] << 8); + WIDE val = MWIDE(mem[get_wide(PC)], mem[get_wide(PC) + g1]); inc_pc(2); return val; } +/* 0b000 = R0 + * 0b001 = R1 + * 0b010 = R2 + * 0b011 = R3 + * 0b100 = DPH + * 0b101 = DPL + * 0b110 = SPH + * 0b111 = SPL */ +BYTE +get_reg(BYTE reg) { + if (reg < 4) { + return regs[reg | (get_flag(BS) << 3)]; + } + else { + switch (reg) { + + case 4: + return regs[DPH]; + case 5: + return regs[DPL]; + case 6: + return regs[SPH]; + case 7: + return regs[SPL]; + default: + return 0; + } + } +} +void +set_reg(BYTE reg, BYTE val) { + if (reg < 4) { + regs[reg | (get_flag(BS) << 3)] = val; + } + else { + switch (reg) { + + case 4: + regs[DPH] = val; + break; + case 5: + regs[DPL] = val; + break; + case 6: + regs[SPH] = val; + break; + case 7: + regs[SPL] = val; + break; + default: + break; + } + } +}
--- a/emu/mem.h Fri Apr 11 14:38:09 2014 +0100 +++ b/emu/mem.h Sun Apr 13 22:42:57 2014 +0100 @@ -45,6 +45,11 @@ #define SBIT(byte, n) (byte | (0x01 << n)) #define CBIT(byte, n) (byte ^ (0x01 << n)) +/* for making and breaking 16 bit values */ +#define MWIDE(high, low) (low | (high << 8)) +#define GHIGH(wide) ((wide >> 8) & 0xFF) +#define GLOW(wide) (wide & 0xFF) + typedef unsigned char BYTE; typedef unsigned short WIDE; @@ -82,7 +87,7 @@ get_flag(BYTE flag); EXTERN void -set_flag(BYTE byte, BYTE on); +set_flag(BYTE flag, BYTE on); /* functions for dealing with 16-bit registers * access the 16 bit registers. @@ -107,4 +112,12 @@ EXTERN WIDE fetch_wide(); +/* for mapping the register encoding in the instruction + * set to the register address */ +EXTERN BYTE +get_reg(BYTE reg); + +EXTERN void +set_reg(BYTE reg, BYTE val); + #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emu/test_mem.c Sun Apr 13 22:42:57 2014 +0100 @@ -0,0 +1,70 @@ +#include <stdio.h> + +#define MAIN +#include "mem.h" + +void +main(void) { + A = 0xAA; + IR = 0x12; + + unsigned char i; + for (i = 0 ; i < 8 ; i++) { + set_flag(i, 1); + } + + set_wide(DPTR, 0xDE1D); + set_wide(SP, 0xADEA); + set_wide(PC, 0xBEFA); + set_wide(TMP, 0xEFC3); + + for (i = 0; i < 4; i++) { + regs[i] = i; + } + + for (i = 8; i < 0x0C; i++) { + regs[i] = 0x10 | (i - 8); + } + + /* 0xAC 0x12 0xFF + * 0x00 0x01 0x02 0x03 + * 0xDE 0xAD 0xBE 0xFF + * 0x10 0x11 0x12 0x13 + * 0x1D 0xEA 0xFA 0xC3 + * 0xDE 0x1D 0xBE 0xFA + * 0xAD 0xEA 0xEF 0xC3*/ + + putchar(A); + putchar(IR); + putchar(flags); + + for (i = 0; i < 0x10; i++) { + putchar(regs[i]); + } + + unsigned short int data_pointer = get_wide(DPTR); + unsigned short int program_counter = get_wide(PC); + unsigned short int stack_pointer = get_wide(SP); + unsigned short int temp = get_wide(TMP); + + putchar((data_pointer >> 8) & 0xFF); + putchar(data_pointer & 0xFF); + putchar((program_counter >> 8) & 0xFF); + putchar(program_counter & 0xFF); + putchar((stack_pointer >> 8) & 0xFF); + putchar(stack_pointer & 0xFF); + putchar((temp >> 8) & 0xFF); + putchar(temp & 0xFF); + + + int ac; + for (ac = 0 ; ac < 0x10000 ; ac++) { + mem[ac] = ac & 0xFF; + } + for (ac = 0 ; ac < 0x10000 ; ac++) { + putchar(fetch()); + } +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/emu/mem/test_mem.c Sun Apr 13 22:42:57 2014 +0100 @@ -0,0 +1,70 @@ +#include <stdio.h> + +#define MAIN +#include "mem.h" + +void +main(void) { + A = 0xAA; + IR = 0x12; + + unsigned char i; + for (i = 0 ; i < 8 ; i++) { + set_flag(i, 1); + } + + set_wide(DPTR, 0xDE1D); + set_wide(SP, 0xADEA); + set_wide(PC, 0xBEFA); + set_wide(TMP, 0xEFC3); + + for (i = 0; i < 4; i++) { + regs[i] = i; + } + + for (i = 8; i < 0x0C; i++) { + regs[i] = 0x10 | (i - 8); + } + + /* 0xAC 0x12 0xFF + * 0x00 0x01 0x02 0x03 + * 0xDE 0xAD 0xBE 0xFF + * 0x10 0x11 0x12 0x13 + * 0x1D 0xEA 0xFA 0xC3 + * 0xDE 0x1D 0xBE 0xFA + * 0xAD 0xEA 0xEF 0xC3*/ + + putchar(A); + putchar(IR); + putchar(flags); + + for (i = 0; i < 0x10; i++) { + putchar(regs[i]); + } + + unsigned short int data_pointer = get_wide(DPTR); + unsigned short int program_counter = get_wide(PC); + unsigned short int stack_pointer = get_wide(SP); + unsigned short int temp = get_wide(TMP); + + putchar((data_pointer >> 8) & 0xFF); + putchar(data_pointer & 0xFF); + putchar((program_counter >> 8) & 0xFF); + putchar(program_counter & 0xFF); + putchar((stack_pointer >> 8) & 0xFF); + putchar(stack_pointer & 0xFF); + putchar((temp >> 8) & 0xFF); + putchar(temp & 0xFF); + + + int ac; + for (ac = 0 ; ac < 0x10000 ; ac++) { + mem[ac] = ac & 0xFF; + } + for (ac = 0 ; ac < 0x10000 ; ac++) { + putchar(fetch()); + } +} + + +
--- a/tests/emu/test.c Fri Apr 11 14:38:09 2014 +0100 +++ b/tests/emu/test.c Sun Apr 13 22:42:57 2014 +0100 @@ -1,5 +1,13 @@ #include <stdio.h> +unsigned char regs[0x10]; + void main(void) { + unsigned char* enregs[8]; + unsigned char *p; + p = regs; + *enregs[8] = {p, p+1, p+2, p+3, p+12, p+4, p+13, p+5}; + *enregs[4] = 0xFF; + printf("%d", regs[12]); }