Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #define ax ((ah<<8)+al)
- #define bx ((bh<<8)+bl)
- #define cx ((ch<<8)+cl)
- #define dx ((dh<<8)+dl)
- #define stepip ip=(ip+1)%0x10000
- unsigned char *RAM = NULL;
- unsigned char al, ah, bl, bh, cl, ch, dl, dh; //general purpose registers
- unsigned sp, bp, si, di; //stack pointer, base pointer, index registers
- unsigned cs, ds, ss, es; //segment registers
- unsigned ip; //instruction pointer
- char cf, pf, af, zf, sf, tf, ifl, df, of; //flags
- unsigned datasize, opcode, adrmode, tempval, savecs, saveip, disp, oper1, oper2;
- unsigned char mod, reg, rmnum;
- unsigned long templong;
- char useseg;
- extern char running;
- extern const unsigned char *opdesc[256];
- extern void vgahandler();
- FILE *binfile = NULL;
- long bytesread = 0;
- unsigned read86(long addr) {
- if (addr>655359) return 0;
- return RAM[addr];
- }
- unsigned write86(long addr, unsigned char value) {
- if (addr>6553659) return 0;
- RAM[addr] = value;
- }
- void push16(unsigned pushval) {
- sp = (sp-2)%0x10000;
- templong = (ss<<4)+sp;
- RAM[templong++] = pushval&0xFF;
- RAM[templong] = pushval>>8;
- }
- void push8(unsigned char pushval) {
- sp = (sp-1)%0x10000;
- RAM[(ss<<4)+sp] = pushval;
- }
- unsigned pop16() {
- templong = (ss<<4)+sp;
- tempval = RAM[templong++] + (RAM[templong]<<8);
- sp = (sp+2)%0x10000;
- return tempval;
- }
- unsigned char pop8() {
- tempval = RAM[(ss<<4)+sp];
- sp = (sp-1)%0x10000;
- return tempval;
- }
- void calcmodregrm() {
- tempval = RAM[(cs<<4)+ip]; stepip; disp = 0;
- mod = tempval>>6; reg = (tempval>>3)&7; rmnum = tempval&7;
- if (mod==1) { disp = RAM[(cs<<4)+ip]; stepip; }
- else if (mod==2) { disp = RAM[(cs<<4)+ip]; stepip; disp += RAM[(cs<<4)+ip]<<8; stepip; }
- }
- unsigned makeflagsword() {
- return cf+(pf<<2)+(af<<4)+(zf<<6)+(sf<<7)+(tf<<8)+(ifl<<9)+(df<<10)+(of<<1);
- }
- void decodeflagsword(unsigned flagsval) {
- cf = flagsval&1; pf = (flagsval>>2)&1; af = (flagsval>>4)&1; zf = (flagsval>>6)&1; sf = (sf>>7)&1;
- tf = (flagsval>>8)&1; ifl = (flagsval>>9)&1; df = (flagsval>>10)&1; of = (flagsval>>11)&1;
- }
- unsigned readsreg(char regval) {
- switch (regval) {
- case 0: return es;
- case 1: return cs;
- case 2: return ss;
- case 6: return ds;
- }
- }
- unsigned readreg(char regval) {
- switch (regval) {
- case 0: if (datasize==0) return al; else return ax;
- case 1: if (datasize==0) return cl; else return cx;
- case 2: if (datasize==0) return dl; else return dx;
- case 3: if (datasize==0) return bl; else return bx;
- case 4: if (datasize==0) return ah; else return sp;
- case 5: if (datasize==0) return ch; else return bp;
- case 6: if (datasize==0) return dh; else return si;
- case 7: if (datasize==0) return bh; else return di;
- }
- }
- unsigned readrm(char rmval) {
- if (mod==3) return readreg(rmval);
- switch (useseg) {
- case 0: templong = cs<<4; break;
- case 1: templong = ds<<4; break;
- case 2: templong = es<<4; break;
- case 3: templong = ss<<4; break;
- }
- if (mod==0) { //using R/M table 1
- switch (rmval) {
- case 0: templong += bx+si; break;
- case 1: templong += bx+di; break;
- case 2: templong += bp+si; break;
- case 3: templong += bp+di; break;
- case 4: templong += si; break;
- case 5: templong += di; break;
- case 6: templong += disp; break;
- case 7: templong += bx; break;
- }
- } else { //using R/M table 2
- switch (rmval) {
- case 0: templong += bx+si; break;
- case 1: templong += bx+di; break;
- case 2: templong += bp+si; break;
- case 3: templong += bp+di; break;
- case 4: templong += si; break;
- case 5: templong += di; break;
- case 6: templong += bp; break;
- case 7: templong += bx; break;
- }
- templong += disp;
- }
- tempval = RAM[templong];
- if (datasize==1) tempval += RAM[templong+1]<<8;
- return tempval;
- }
- void writesreg(char regval, unsigned value) {
- switch (regval) {
- case 0: es = value; break;
- case 1: cs = value; break;
- case 2: ss = value; break;
- case 3: ds = value; break;
- }
- }
- void writereg(char regval, unsigned value) {
- switch (regval) {
- case 0: if (datasize==0) al = value; else { al = value&0xFF; ah = value>>8; } break;
- case 1: if (datasize==0) cl = value; else { cl = value&0xFF; ch = value>>8; } break;
- case 2: if (datasize==0) dl = value; else { dl = value&0xFF; dh = value>>8; } break;
- case 3: if (datasize==0) bl = value; else { bl = value&0xFF; bh = value>>8; } break;
- case 4: if (datasize==0) ah = value; else sp = value; break;
- case 5: if (datasize==0) ch = value; else bp = value; break;
- case 6: if (datasize==0) dh = value; else si = value; break;
- case 7: if (datasize==0) bh = value; else di = value; break;
- }
- }
- void writerm(char rmval, unsigned value) {
- if (mod==3) { writereg(rmval, value); return; }
- switch (useseg) {
- case 0: templong = cs<<4; break;
- case 1: templong = ds<<4; break;
- case 2: templong = es<<4; break;
- case 3: templong = ss<<4; break;
- }
- if (mod==0) { //using R/M table 1
- switch (rmval) {
- case 0: templong += bx+si; break;
- case 1: templong += bx+di; break;
- case 2: templong += bp+si; break;
- case 3: templong += bp+di; break;
- case 4: templong += si; break;
- case 5: templong += di; break;
- case 6: templong += disp; break;
- case 7: templong += bx; break;
- }
- } else { //using R/M table 2
- switch (rmval) {
- case 0: templong += bx+si; break;
- case 1: templong += bx+di; break;
- case 2: templong += bp+si; break;
- case 3: templong += bp+di; break;
- case 4: templong += si; break;
- case 5: templong += di; break;
- case 6: templong += bp; break;
- case 7: templong += bx; break;
- }
- templong += disp;
- }
- RAM[templong] = value&0xFF;
- if (datasize==1) RAM[templong+1] = value>>8;
- }
- void loadbin(char *filename, long loadpoint) {
- long i;
- binfile = fopen(filename, "rb");
- if (binfile==NULL) { printf("Unable to load %s into RAM.\n", filename); running = 0; return; }
- bytesread = fread(&RAM[loadpoint], 1, 961, binfile);
- fclose(binfile);
- printf("%u bytes read from %s\n", bytesread, filename);
- }
- void reset86() {
- //cs = 0xf000; ip = 0xfff0;
- cs = 0x0800; ip = 0x0100;
- al = 0; ah = 0; bl = 0; bh = 0; cl = 0; dl = 0; dh = 0;
- sp = 0x3fe; bp = 0; si = 0x7c02; di = 0;
- ds = 0x800; ss = 0x7c0; es = 0x800;
- cf = 0; pf = 0; af = 0; zf = 0; sf = 0; tf = 0; ifl = 1; df = 0; of = 0;
- //RAM[(cs<<4)+ip] = 0xEA; RAM[(cs<<4)+ip+1] = 0x08; RAM[(cs<<4)+ip+2] = 0x00; RAM[(cs<<4)+ip+3] = 0x00; RAM[(cs<<4)+ip+4] = 0x00;
- running = 1;
- }
- void intcall86(unsigned char intnum) {
- switch (intnum) {
- case 0x10: //VGA BIOS call
- vgahandler(); return;
- }
- push16(makeflagsword()); push16(cs); push16(ip);
- templong = intnum<<2;
- cs = RAM[templong++] + (RAM[templong++]<<8);
- ip = RAM[templong++] + (RAM[templong]<<8);
- return;
- //ip = pop16(); cs = pop16(); decodeflagsword(pop16());
- }
- void exec86() {
- savecs = cs; saveip = ip; opcode = RAM[(cs<<4)+ip]; stepip;
- printf("Exec: %s @ %x:%x\n", opdesc[opcode], savecs, saveip);
- useseg = 1; //default segment is DS
- if (opcode==0x2e) { useseg = 0; savecs = cs; saveip = ip; opcode = RAM[(cs<<4)+ip]; stepip; }
- else if (opcode==0x3e) { useseg = 1; savecs = cs; saveip = ip; opcode = RAM[(cs<<4)+ip]; stepip; }
- else if (opcode==0x26) { useseg = 2; savecs = cs; saveip = ip; opcode = RAM[(cs<<4)+ip]; stepip; }
- else if (opcode==0x36) { useseg = 3; savecs = cs; saveip = ip; opcode = RAM[(cs<<4)+ip]; stepip; }
- switch (opcode) {
- case 0x06: //PUSH ES
- push16(es); break;
- case 0x07: //POP ES
- es = pop16(); break;
- case 0x0e: //PUSH CS
- push16(cs); break;
- case 0x16: //PUSH SS
- push16(ss); break;
- case 0x17: //POP SS
- ss = pop16(); break;
- case 0x1e: //PUSH DS
- push16(ds); break;
- case 0x1f: //POP DS
- ds = pop16(); break;
- case 0x50: //PUSH eAX
- push16(ax); break;
- case 0x51: //PUSH eCX
- push16(cx); break;
- case 0x52: //PUSH eDX
- push16(dx); break;
- case 0x53: //PUSH eBX
- push16(bx); break;
- case 0x54: //PUSH eSP
- push16(sp); break;
- case 0x55: //PUSH eBP
- push16(bp); break;
- case 0x56: //PUSH eSI
- push16(si); break;
- case 0x57: //PUSH eDI
- push16(di); break;
- case 0x58: //POP eAX
- tempval = pop16(); al = tempval&0xFF; ah = tempval>>8; break;
- case 0x59: //POP eCX
- tempval = pop16(); cl = tempval&0xFF; ch = tempval>>8; break;
- case 0x5A: //POP eDX
- tempval = pop16(); dl = tempval&0xFF; dh = tempval>>8; break;
- case 0x5B: //POP eBX
- tempval = pop16(); bl = tempval&0xFF; bh = tempval>>8; break;
- case 0x5C: //POP eSP
- sp = pop16(); break;
- case 0x5D: //POP eBP
- bp = pop16(); break;
- case 0x5E: //POP eSI
- si = pop16(); break;
- case 0x5F: //POP eDI
- di = pop16(); break;
- // case 0x80: //CMP Eb, Ib
- // calcmodregrm(); datasize = 0;
- case 0x8e: //MOV Sw, Ew
- calcmodregrm(); datasize = 1; writesreg(reg, readrm(rmnum)); break;
- case 0xb0: //MOV AL, Ib
- al = RAM[(cs<<4)+ip]; stepip; break;
- case 0xb1: //MOV CL, Ib
- cl = RAM[(cs<<4)+ip]; stepip; break;
- case 0xb2: //MOV DL, Ib
- dl = RAM[(cs<<4)+ip]; stepip; break;
- case 0xb3: //MOV BL, Ib
- bl = RAM[(cs<<4)+ip]; stepip; break;
- case 0xb4: //MOV AH, Ib
- ah = RAM[(cs<<4)+ip]; stepip; break;
- case 0xb5: //MOV CH, Ib
- ch = RAM[(cs<<4)+ip]; stepip; break;
- case 0xb6: //MOV DH, Ib
- dh = RAM[(cs<<4)+ip]; stepip; break;
- case 0xb7: //MOV BH, Ib
- bh = RAM[(cs<<4)+ip]; stepip; break;
- case 0xb8: //MOV AX, Iv
- al = RAM[(cs<<4)+ip]; stepip;
- ah = RAM[(cs<<4)+ip]; stepip; break;
- case 0xb9: //MOV CX, Iv
- cl = RAM[(cs<<4)+ip]; stepip;
- ch = RAM[(cs<<4)+ip]; stepip; break;
- case 0xba: //MOV DX, Iv
- dl = RAM[(cs<<4)+ip]; stepip;
- dh = RAM[(cs<<4)+ip]; stepip; break;
- case 0xbb: //MOV BX, Iv
- bl = RAM[(cs<<4)+ip]; stepip;
- bh = RAM[(cs<<4)+ip]; stepip; break;
- case 0xbc: //MOV SP, Iv
- sp = RAM[(cs<<4)+ip]; stepip;
- sp += RAM[(cs<<4)+ip]<<8; stepip; break;
- case 0xbd: //MOV BP, Iv
- bp = RAM[(cs<<4)+ip]; stepip;
- bp += RAM[(cs<<4)+ip]<<8; stepip; break;
- case 0xbe: //MOV SI, Iv
- si = RAM[(cs<<4)+ip]; stepip;
- si += RAM[(cs<<4)+ip]<<8; stepip; break;
- case 0xbf: //MOV DI, Iv
- di = RAM[(cs<<4)+ip]; stepip;
- di += RAM[(cs<<4)+ip]<<8; stepip; break;
- case 0xc6: //MOV Eb, Ib
- calcmodregrm(); datasize = 0; templong = RAM[(cs<<4)+ip]; stepip; printf("POOP\n"); writerm(rmnum, templong); break;
- case 0xcd: //INT Ib
- tempval = RAM[(cs<<4)+ip]; stepip;
- intcall86((unsigned char)tempval); break;
- case 0xe9: //JMP Jv
- ip = (RAM[(cs<<4)+ip]+(RAM[(cs<<4)+ip+1]<<8)+3) % 0xFFFF; break;
- default:
- running = 0;
- printf("UNKNOWN OPCODE EXCEPTION: %s @ %x:%x\n", opdesc[opcode], savecs, saveip);
- printf("AX: %x BX: %x CX: %x DX: %x\n", ax, bx, cx, dx);
- printf("CS: %x IP: %x SS: %x SP: %x\n", savecs, saveip, ss, sp);
- printf("SI: %x DI: %x DS: %x ES: %x\n", si, di, ds, es);
- return;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement