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