-
Notifications
You must be signed in to change notification settings - Fork 0
/
emu86.ino
138 lines (114 loc) · 3.3 KB
/
emu86.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
emu86, 86 emulator for arduino,
Microcomputer systems: the 8088/8086 family, 2nd Ed, Prentice-Hall
used as a refrence.
Murray Smith, 4/4/14
*/
#include "regs.h"
#include "cpu.h"
#include "opcodes.h"
#include "memory.h"
#include "bc.h"
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,4,5,6,7);
void setFlagPSW( byte &psw, byte flag){
psw |= flag;
}
//Decode and return true if a flag is set.
boolean decodePSW( byte psw, byte flag ){
byte temp = psw;
if( flag == FLAG_CF ){
return temp & 1;
}
return (( temp >> flag ) & 1);
}
/*
Reset the cpu to a known state.
CS, DS, SS, ES need to point to a valid segment ie ROM_SEGMENT
SP, BP, SI, DI, IP need the correct values for the cpu to find
data/code/stack at start up
*/
void cpu_reset(){
//clear registers, program status word. ie flags
//cpu86.flags = 0;
//general purpose registers, in reality these would be random values
cpu86.regs.ax = 0; //Accumulator, AH+AL, and,or,xor,shl,shr etc
cpu86.regs.bx = 0; //Base BH+BL, translate
cpu86.regs.cx = 0; //Count CH+CL, string and loop operations
cpu86.regs.dx = 0; //Data DH+DL
//segments
cpu86.regs.cs = 0xffff; //current code segment, ip,mov?
cpu86.regs.ss = 0x03ff; //current stack segment
cpu86.regs.ds = 0xffff; //current data segment, mov,
cpu86.regs.es = 0xffff; //current extra segment
//ponters
//Stack operations
cpu86.regs.sp = 0; //stack pointer
cpu86.regs.bp = 0; //base pointer
//String operations
cpu86.regs.si = 0; //source index
cpu86.regs.di = 0; //destination index
//Instruction pointer
cpu86.regs.ip = 0; //offset from cs, so physical address is ((cs << 4) + ip)?
//data in i_q
cpu86.i_q[0] = 100; //should equate to a noop, temp value?
cpu86.i_q[1] = 0;
cpu86.i_q[2] = 0;
cpu86.i_q[3] = 0;
cpu86.i_q[4] = 0;
cpu86.i_q[5] = 0;
}
/*
Initalise a section of ram to a known state.
*/
void init_ram( byte *ram, int len ){
int i = 0;
for( i = 0; i < len; i++ ){
ram[i] = 22; // 22 is an op code for?
}
}
void setup(){
//Startup the lcd driver.
lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print("emu86 V0.07");
lcd.setCursor(0,1);
//resetCpu to a known state.
cpu_reset();
lcd.print("cpu86 reset");
delay(600);
//reset code ram to a known state. 256 bytes starting at address 0
init_ram( mem_ram256, 255);
lcd.setCursor(0,1);
lcd.print("ram 256b init");
delay(600);
//reset IVT ram to a known state, not needed unless above is rom
init_ram( mem_low1024, 1023);
lcd.setCursor(0,1);
lcd.print("IVT ram 1024b set");
delay(1200);
//Inform the user that the processor is running
lcd.setCursor(0,1);
lcd.print("cpu86 started");
delay(1200);
}
void loop(){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("OC IP MEM");
lcd.setCursor(0,1);
lcd.print( (unsigned int)cpu86.i_q[0] );
lcd.setCursor(4,1);
lcd.print( cpu86.regs.ip );
lcd.setCursor(9,1);
unsigned long mem = ( unsigned long )cpu86.regs.cs;
mem = (mem << 4);
mem += (unsigned long)cpu86.regs.ip;
lcd.print( (unsigned long)mem );
//get 6 bytes of code into cpu86.i_q
set_cpu_opcodes();
cpuloop((unsigned int)cpu86.i_q[0]);
//shift data via data/address/status pins
delay(750);
}