annotate 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
rev   line source
jb302@28 1 #include <stdio.h>
jb302@28 2 #include <stdlib.h>
jb302@28 3
jb302@28 4 #define MAIN
jb302@28 5 #include "mem.h"
jb302@28 6 #include "iset.h"
jb302@28 7
jb302@28 8 /* fill instruction table
jb302@28 9 * MCS-51 - this needs to be stored in code memory */
jb302@34 10 FUNCTION_TABLE const iset = {
jb302@28 11 NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
jb302@28 12 SET, CLR, SET, CLR, SET, CLR, CPL, CPL,
jb302@28 13 XCSD, SFA, LAF, MOV, MOV, MOV, MOV, MOV,
jb302@28 14 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 15 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 16 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 17 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 18 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 19 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 20 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 21 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 22 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 23 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 24 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 25 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 26 MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV,
jb302@28 27 ANL, ANL, ANL, ANL, ANL, ANL, ANL, ANL,
jb302@28 28 ORL, ORL, ORL, ORL, ORL, ORL, ORL, ORL,
jb302@28 29 XRL, XRL, XRL, XRL, XRL, XRL, XRL, XRL,
jb302@28 30 RL, RLC, RR, RRC, INC, DEC, INC, DEC,
jb302@28 31 ADD, ADD, ADD, ADD, ADD, ADD, ADD, ADD,
jb302@28 32 ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, ADDC,
jb302@28 33 SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
jb302@28 34 SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, SUBB,
jb302@28 35 PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, PJMP,
jb302@28 36 PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, PCALL,
jb302@28 37 DJNZ, DJNZ, DJNZ, DJNZ, CJNE, CJNE, CJNE, CJNE,
jb302@28 38 LJMP, LCALL, RET, RETI, SJMP, JMP, JMP, CJNE,
jb302@28 39 JZ, JNZ, JC, JNC, JPO, JPE, JS, JNS,
jb302@28 40 PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH,
jb302@28 41 POP, POP, POP, POP, POP, POP, POP, POP,
jb302@28 42 MUL, DIV, DA, NOP, IN, OUT, INT, HLT
jb302@28 43 };
jb302@28 44
jb302@34 45 BYTE pause; /* becomes 1 when we hit a break point in run mode */
jb302@29 46 BYTE free_run; /* free run if not 0 */
jb302@34 47 BYTE pause; /* pause flag */
jb302@29 48 WIDE ac; /* address counter */
jb302@29 49 BYTE args[4]; /* dbg args */
jb302@28 50
jb302@34 51 WIDE bp[8] = { 0xFFFF,
jb302@34 52 0xFFFF,
jb302@34 53 0xFFFF,
jb302@34 54 0xFFFF,
jb302@34 55 0xFFFF,
jb302@34 56 0xFFFF,
jb302@34 57 0xFFFF,
jb302@34 58 0xFFFF
jb302@34 59 };
jb302@34 60
jb302@28 61 /* don't need the file on the MCS-51 version */
jb302@28 62 FILE *fp;
jb302@28 63 void
jb302@28 64 snd(BYTE c) {
jb302@28 65 /* putchar(c); */
jb302@28 66 fp = fopen("out", "a");
jb302@28 67 fputc(c, fp);
jb302@28 68 fclose(fp);
jb302@28 69 }
jb302@28 70
jb302@28 71 BYTE
jb302@28 72 rcv(void) {
jb302@28 73 return getchar();
jb302@28 74 }
jb302@28 75
jb302@28 76 void
jb302@28 77 step(void) {
jb302@28 78 IR = fetch();
jb302@34 79 iset.ops[IR]();
jb302@28 80 }
jb302@28 81
jb302@34 82 void
jb302@34 83 run(void) {
jb302@34 84 while (pause != 1) {
jb302@34 85 step();
jb302@34 86 for (ac = 0; ac < 8; ac++) {
jb302@34 87 if (bp[ac] == get_wide(PC)) {
jb302@34 88 pause = 1;
jb302@34 89 }
jb302@34 90 }
jb302@34 91 }
jb302@34 92 }
jb302@34 93
jb302@34 94 void controller() {
jb302@29 95 if (free_run == 0) {
jb302@34 96 switch (rcv()) {
jb302@28 97
jb302@34 98 /* step */
jb302@34 99 case 0x00:
jb302@34 100 step();
jb302@34 101 break;
jb302@28 102
jb302@34 103 /* run for length steps*/
jb302@34 104 case 0x01:
jb302@34 105 run();
jb302@34 106 break;
jb302@28 107
jb302@34 108 /* set reg */
jb302@34 109 case 0x02:
jb302@34 110 args[0] = rcv(); /* reg */
jb302@34 111 args[1] = rcv(); /* val */
jb302@34 112 regs[args[0]] = args[1];
jb302@34 113 break;
jb302@28 114
jb302@34 115 /* get reg */
jb302@34 116 case 0x03:
jb302@34 117 args[0] = rcv(); /* reg */
jb302@34 118 snd(regs[args[0]]);
jb302@34 119 break;
jb302@28 120
jb302@34 121 /* set flag */
jb302@34 122 case 0x04:
jb302@34 123 args[0] = rcv(); /* flag */
jb302@34 124 args[1] = rcv(); /* on? */
jb302@34 125 set_flag(args[0], args[1]);
jb302@34 126 break;
jb302@34 127
jb302@34 128 /* get flag */
jb302@34 129 case 0x05:
jb302@34 130 args[0] = rcv(); /* flag */
jb302@34 131 snd(get_flag(args[0]));
jb302@34 132 break;
jb302@28 133
jb302@34 134 /* write mem block */
jb302@34 135 case 0x06:
jb302@34 136 args[0] = rcv(); /* addr high */
jb302@34 137 args[1] = rcv(); /* addr low */
jb302@34 138 args[2] = rcv(); /* length high */
jb302@34 139 args[3] = rcv(); /* length low */
jb302@34 140 tmpw = MWIDE(args[0], args[1]);
jb302@34 141 for (ac = tmpw; ac < tmpw + MWIDE(args[2], args[3]); ac++) {
jb302@34 142 if (ac >= 0xFFFF) {
jb302@34 143 break;
jb302@34 144 }
jb302@34 145 mem[ac] = rcv();
jb302@34 146 }
jb302@34 147 break;
jb302@34 148
jb302@34 149 /* read mem block */
jb302@34 150 case 0x07:
jb302@34 151 args[0] = rcv(); /* addr high */
jb302@34 152 args[1] = rcv(); /* addr low */
jb302@34 153 args[2] = rcv(); /* length high */
jb302@34 154 args[3] = rcv(); /* length low */
jb302@34 155 tmpw = MWIDE(args[0], args[1]);
jb302@34 156 for (ac = tmpw; ac < tmpw + MWIDE(args[2], args[3]); ac++) {
jb302@34 157 if (ac >= 0xFFFF) {
jb302@34 158 break;
jb302@34 159 }
jb302@34 160 snd(mem[ac]);
jb302@34 161 }
jb302@34 162 break;
jb302@34 163
jb302@34 164 /* get A */
jb302@37 165 case 0x08:
jb302@34 166 snd(A);
jb302@34 167 break;
jb302@34 168
jb302@34 169 /* get flags */
jb302@37 170 case 0x09:
jb302@34 171 snd(flags);
jb302@34 172 break;
jb302@34 173
jb302@34 174 /* get instruction register */
jb302@37 175 case 0x0A:
jb302@34 176 snd(IR);
jb302@34 177 break;
jb302@34 178
jb302@37 179 /* run for length */
jb302@37 180 case 0x0B:
jb302@34 181 args[0] = rcv(); /* length high */
jb302@34 182 args[1] = rcv(); /* length low */
jb302@39 183 for (tmpw = 0 ; tmpw < MWIDE(args[0], args[1]) ; tmpw++) {
jb302@34 184 step();
jb302@34 185 }
jb302@34 186 break;
jb302@34 187
jb302@37 188 case 0x0C:
jb302@34 189 free_run = 1;
jb302@34 190 break;
jb302@34 191
jb302@34 192 /* set break point */
jb302@37 193 case 0x0D:
jb302@34 194 args[0] = rcv(); /* bp index */
jb302@34 195 args[1] = rcv(); /* address high */
jb302@34 196 args[2] = rcv(); /* address low */
jb302@34 197 if (args[0] > 7) {
jb302@28 198 break;
jb302@28 199 }
jb302@34 200 bp[args[0]] = MWIDE(args[1], args[2]);
jb302@34 201 break;
jb302@34 202
jb302@34 203 /* test cmd */
jb302@34 204 case 0x54:
jb302@34 205 snd('A');
jb302@34 206 break;
jb302@34 207 }
jb302@34 208 }
jb302@34 209 else {
jb302@34 210 step();
jb302@28 211 }
jb302@28 212 }
jb302@28 213
jb302@28 214 void
jb302@28 215 main(void) {
jb302@29 216 /* dont go into free run on restart */
jb302@29 217 free_run = 0;
jb302@29 218 for (;;) {
jb302@34 219 controller();
jb302@28 220 }
jb302@28 221 }
jb302@28 222