view emu52/src/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 <reg52.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 code 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 addrc;        /* address counter */
BYTE args[4];   /* dbg args */

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


void
snd(BYTE c) {
putchar(c);
}

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

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

void
run(void) {
    while (pause != 1) {
        step();
        for (addrc = 0; addrc < 8; addrc++) {
            if (bp[addrc] == 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 (addrc = tmpw; addrc < tmpw + MWIDE(args[2], args[3]); addrc++) { 
                        if (addrc >= 0xFFFF) {
                            break;
                        }
                        mem[addrc] = 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 (addrc = tmpw; addrc < tmpw + MWIDE(args[2], args[3]); addrc++) { 
                        if (addrc >= 0xFFFF) {
                            break;
                        }
                        snd(mem[addrc]);
                    }
                    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) {
     /* serial set up
     * SCON - mode 1, 8-bit UART, enable rcvr
     * TMOD - timer 1, mode 2, 8-bit reload
     * TH1 - reload value for 1200 baud @ 12MHz
     * TR1 - timer 1 run
     * TI - set TI to send first char of UART */
    /* dont go into free run on restart */
    free_run = 0;
    SCON  = 0x50;
    TMOD |= 0x20;
    TH1   = 0xE8;
    TR1   = 1;
    TI    = 1;
    for (;;) {
        controller();
    }
}