view emu/main.c @ 42:792da050d8c4 tip

more dox
author james <jb302@eecs.qmul.ac.uk>
date Tue, 22 Apr 2014 14:25:14 +0100
parents 0f3bd942a7d4
children
line wrap: on
line source
#include <stdio.h>
#include <stdlib.h>

#define MAIN
#include "mem.h"
#include "iset.h"

/* fill instruction table 
 * MCS-51 - this needs to be stored in code memory */
FUNCTION_TABLE const iset = {
    NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
    SET, CLR, SET, CLR, SET, CLR, CPL, CPL,
    XCSD, SFA, LAF, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
    ANL, ANL, ANL, ANL, ANL, ANL, ANL, ANL,
    ORL, ORL, ORL, ORL, ORL, ORL, ORL, ORL,
    XRL, XRL, XRL, XRL, XRL, XRL, XRL, XRL,
    RL, RLC, RR, RRC, INC, DEC, INC, DEC,
    ADD, ADD, ADD, ADD, ADD, ADD, ADD, ADD,
    ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, ADDC,
    SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
    SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, SUBB,
    PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, PJMP,
    PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, PCALL,
    DJNZ, DJNZ, DJNZ, DJNZ, CJNE, CJNE, CJNE, CJNE,
    LJMP, LCALL, RET, RETI, SJMP, JMP, JMP, CJNE,
    JZ, JNZ, JC, JNC, JPO, JPE, JS, JNS,
    PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH,
    POP, POP, POP, POP, POP, POP, POP, POP,
    MUL, DIV, DA, NOP, IN, OUT, INT, HLT
};

BYTE pause;     /* becomes 1 when we hit a break point in run mode */
BYTE free_run;  /* free run if not 0 */
BYTE pause;     /* pause flag */
WIDE ac;        /* address counter */
BYTE args[4];   /* dbg args */

WIDE bp[8] = {  0xFFFF,
                0xFFFF,
                0xFFFF,
                0xFFFF,
                0xFFFF,
                0xFFFF,
                0xFFFF,
                0xFFFF
};

/* don't need the file on the MCS-51 version */
FILE *fp;
void
snd(BYTE c) {
    /* putchar(c); */
    fp = fopen("out", "a");
    fputc(c, fp);
    fclose(fp);
}

BYTE
rcv(void) {
    return getchar();
}

void
step(void) {
    IR = fetch();
    iset.ops[IR]();
}

void
run(void) {
    while (pause != 1) {
        step();
        for (ac = 0; ac < 8; ac++) {
            if (bp[ac] == get_wide(PC)) {
                pause = 1;
            }
        }
    }
}

void controller() {
    if (free_run == 0) {
            switch (rcv()) {

                /* step */
                case 0x00:
                    step();
                    break;

                /* run for length steps*/
                case 0x01:
                    run();
                    break;

                /* set reg */
                case 0x02:
                    args[0] = rcv(); /* reg */
                    args[1] = rcv(); /* val */
                    regs[args[0]] = args[1];
                    break;

                /* get reg */
                case 0x03:
                    args[0] = rcv(); /* reg */
                    snd(regs[args[0]]);
                    break;

                /* set flag */
                case 0x04:
                    args[0] = rcv(); /* flag */
                    args[1] = rcv(); /* on? */
                    set_flag(args[0], args[1]);
                    break;
        
                /* get flag */
                case 0x05:
                    args[0] = rcv(); /* flag */
                    snd(get_flag(args[0]));
                    break;

                /* write mem block */
                case 0x06:
                    args[0] = rcv(); /* addr high */
                    args[1] = rcv(); /* addr low */
                    args[2] = rcv(); /* length high */
                    args[3] = rcv(); /* length low */
                    tmpw = MWIDE(args[0], args[1]);         
                    for (ac = tmpw; ac < tmpw + MWIDE(args[2], args[3]); ac++) { 
                        if (ac >= 0xFFFF) {
                            break;
                        }
                        mem[ac] = rcv();
                    }
                    break;

                /* read mem block */
                case 0x07:
                    args[0] = rcv(); /* addr high */
                    args[1] = rcv(); /* addr low */
                    args[2] = rcv(); /* length high */
                    args[3] = rcv(); /* length low */
                    tmpw = MWIDE(args[0], args[1]);         
                    for (ac = tmpw; ac < tmpw + MWIDE(args[2], args[3]); ac++) { 
                        if (ac >= 0xFFFF) {
                            break;
                        }
                        snd(mem[ac]);
                    }
                    break;

                /* get A */
                case 0x08:
                    snd(A);
                    break;
                
                /* get flags */
                case 0x09:
                    snd(flags);
                    break;
                
                /* get instruction register */
                case 0x0A:
                    snd(IR);
                    break;
                
                /* run for length */
                case 0x0B:
                    args[0] = rcv(); /* length high */
                    args[1] = rcv(); /* length low */
                    for (tmpw = 0 ; tmpw < MWIDE(args[0], args[1]) ; tmpw++) {
                        step();
                    }
                    break;

                case 0x0C:
                    free_run = 1;
                    break;
                
                /* set break point */
                case 0x0D:
                    args[0] = rcv(); /* bp index */
                    args[1] = rcv(); /* address high */
                    args[2] = rcv(); /* address low */
                    if (args[0] > 7) {
                        break;
                    }
                    bp[args[0]] = MWIDE(args[1], args[2]);
                    break;
                
                /* test cmd */
                case 0x54:
                    snd('A');
                    break;
           }
        }
    else {
        step();
    }
}

void 
main(void) {
    /* dont go into free run on restart */
    free_run = 0;
    for (;;) {
        controller();
    }
}