Advertisement
Guest User

Untitled

a guest
Jun 23rd, 2017
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.11 KB | None | 0 0
  1. #include <stdio.h>
  2.  
  3. #define ax ((ah<<8)+al)
  4. #define bx ((bh<<8)+bl)
  5. #define cx ((ch<<8)+cl)
  6. #define dx ((dh<<8)+dl)
  7. #define stepip ip=(ip+1)%0x10000
  8.  
  9. unsigned char *RAM = NULL;
  10. unsigned char al, ah, bl, bh, cl, ch, dl, dh; //general purpose registers
  11. unsigned sp, bp, si, di; //stack pointer, base pointer, index registers
  12. unsigned cs, ds, ss, es; //segment registers
  13. unsigned ip; //instruction pointer
  14. char cf, pf, af, zf, sf, tf, ifl, df, of; //flags
  15. unsigned datasize, opcode, adrmode, tempval, savecs, saveip, disp, oper1, oper2;
  16. unsigned char mod, reg, rmnum;
  17. unsigned long templong;
  18. char useseg;
  19.  
  20. extern char running;
  21. extern const unsigned char *opdesc[256];
  22.  
  23. extern void vgahandler();
  24.  
  25. FILE *binfile = NULL;
  26. long bytesread = 0;
  27.  
  28. unsigned read86(long addr) {
  29.          if (addr>655359) return 0;
  30.          return RAM[addr];
  31. }
  32.  
  33. unsigned write86(long addr, unsigned char value) {
  34.          if (addr>6553659) return 0;
  35.          RAM[addr] = value;
  36. }
  37.  
  38. void push16(unsigned pushval) {
  39.      sp = (sp-2)%0x10000;
  40.      templong = (ss<<4)+sp;
  41.      RAM[templong++] = pushval&0xFF;
  42.      RAM[templong] = pushval>>8;
  43. }
  44.  
  45. void push8(unsigned char pushval) {
  46.      sp = (sp-1)%0x10000;
  47.      RAM[(ss<<4)+sp] = pushval;
  48. }
  49.  
  50. unsigned pop16() {
  51.          templong = (ss<<4)+sp;
  52.          tempval = RAM[templong++] + (RAM[templong]<<8);
  53.          sp = (sp+2)%0x10000;
  54.          return tempval;
  55. }
  56.  
  57. unsigned char pop8() {
  58.          tempval = RAM[(ss<<4)+sp];
  59.          sp = (sp-1)%0x10000;
  60.          return tempval;
  61. }
  62.  
  63. void calcmodregrm() {
  64.      tempval = RAM[(cs<<4)+ip]; stepip; disp = 0;
  65.      mod = tempval>>6; reg = (tempval>>3)&7; rmnum = tempval&7;
  66.      if (mod==1) { disp = RAM[(cs<<4)+ip]; stepip; }
  67.        else if (mod==2) { disp = RAM[(cs<<4)+ip]; stepip; disp += RAM[(cs<<4)+ip]<<8; stepip; }
  68. }
  69.  
  70. unsigned makeflagsword() {
  71.          return cf+(pf<<2)+(af<<4)+(zf<<6)+(sf<<7)+(tf<<8)+(ifl<<9)+(df<<10)+(of<<1);
  72. }
  73.  
  74. void decodeflagsword(unsigned flagsval) {
  75.      cf = flagsval&1; pf = (flagsval>>2)&1; af = (flagsval>>4)&1; zf = (flagsval>>6)&1; sf = (sf>>7)&1;
  76.      tf = (flagsval>>8)&1; ifl = (flagsval>>9)&1; df = (flagsval>>10)&1; of = (flagsval>>11)&1;
  77. }
  78.  
  79. unsigned readsreg(char regval) {
  80.      switch (regval) {
  81.            case 0: return es;
  82.            case 1: return cs;
  83.            case 2: return ss;
  84.            case 6: return ds;
  85.      }
  86. }
  87.  
  88. unsigned readreg(char regval) {
  89.      switch (regval) {
  90.            case 0: if (datasize==0) return al; else return ax;
  91.            case 1: if (datasize==0) return cl; else return cx;
  92.            case 2: if (datasize==0) return dl; else return dx;
  93.            case 3: if (datasize==0) return bl; else return bx;
  94.            case 4: if (datasize==0) return ah; else return sp;
  95.            case 5: if (datasize==0) return ch; else return bp;
  96.            case 6: if (datasize==0) return dh; else return si;
  97.            case 7: if (datasize==0) return bh; else return di;
  98.      }
  99. }
  100.  
  101. unsigned readrm(char rmval) {
  102.      if (mod==3) return readreg(rmval);
  103.      switch (useseg) {
  104.             case 0: templong = cs<<4; break;
  105.             case 1: templong = ds<<4; break;
  106.             case 2: templong = es<<4; break;
  107.             case 3: templong = ss<<4; break;
  108.      }
  109.      if (mod==0) { //using R/M table 1
  110.         switch (rmval) {
  111.             case 0: templong += bx+si; break;
  112.             case 1: templong += bx+di; break;
  113.             case 2: templong += bp+si; break;
  114.             case 3: templong += bp+di; break;
  115.             case 4: templong += si; break;
  116.             case 5: templong += di; break;
  117.             case 6: templong += disp; break;
  118.             case 7: templong += bx; break;
  119.         }
  120.      } else { //using R/M table 2
  121.         switch (rmval) {
  122.             case 0: templong += bx+si; break;
  123.             case 1: templong += bx+di; break;
  124.             case 2: templong += bp+si; break;
  125.             case 3: templong += bp+di; break;
  126.             case 4: templong += si; break;
  127.             case 5: templong += di; break;
  128.             case 6: templong += bp; break;
  129.             case 7: templong += bx; break;
  130.         }
  131.         templong += disp;
  132.      }
  133.      tempval = RAM[templong];
  134.      if (datasize==1) tempval += RAM[templong+1]<<8;
  135.      return tempval;
  136. }
  137.  
  138. void writesreg(char regval, unsigned value) {
  139.      switch (regval) {
  140.            case 0: es = value; break;
  141.            case 1: cs = value; break;
  142.            case 2: ss = value; break;
  143.            case 3: ds = value; break;
  144.      }
  145. }
  146.  
  147. void writereg(char regval, unsigned value) {
  148.      switch (regval) {
  149.            case 0: if (datasize==0) al = value; else { al = value&0xFF; ah = value>>8; } break;
  150.            case 1: if (datasize==0) cl = value; else { cl = value&0xFF; ch = value>>8; } break;
  151.            case 2: if (datasize==0) dl = value; else { dl = value&0xFF; dh = value>>8; } break;
  152.            case 3: if (datasize==0) bl = value; else { bl = value&0xFF; bh = value>>8; } break;
  153.            case 4: if (datasize==0) ah = value; else sp = value; break;
  154.            case 5: if (datasize==0) ch = value; else bp = value; break;
  155.            case 6: if (datasize==0) dh = value; else si = value; break;
  156.            case 7: if (datasize==0) bh = value; else di = value; break;
  157.      }
  158. }
  159.  
  160. void writerm(char rmval, unsigned value) {
  161.      if (mod==3) { writereg(rmval, value); return; }
  162.      switch (useseg) {
  163.             case 0: templong = cs<<4; break;
  164.             case 1: templong = ds<<4; break;
  165.             case 2: templong = es<<4; break;
  166.             case 3: templong = ss<<4; break;
  167.      }
  168.      if (mod==0) { //using R/M table 1
  169.         switch (rmval) {
  170.             case 0: templong += bx+si; break;
  171.             case 1: templong += bx+di; break;
  172.             case 2: templong += bp+si; break;
  173.             case 3: templong += bp+di; break;
  174.             case 4: templong += si; break;
  175.             case 5: templong += di; break;
  176.             case 6: templong += disp; break;
  177.             case 7: templong += bx; break;
  178.         }
  179.      } else { //using R/M table 2
  180.         switch (rmval) {
  181.             case 0: templong += bx+si; break;
  182.             case 1: templong += bx+di; break;
  183.             case 2: templong += bp+si; break;
  184.             case 3: templong += bp+di; break;
  185.             case 4: templong += si; break;
  186.             case 5: templong += di; break;
  187.             case 6: templong += bp; break;
  188.             case 7: templong += bx; break;
  189.         }
  190.         templong += disp;
  191.      }
  192.      RAM[templong] = value&0xFF;
  193.      if (datasize==1) RAM[templong+1] = value>>8;
  194. }
  195.  
  196. void loadbin(char *filename, long loadpoint) {
  197.      long i;
  198.      binfile = fopen(filename, "rb");
  199.      if (binfile==NULL) { printf("Unable to load %s into RAM.\n", filename); running = 0; return; }
  200.      bytesread = fread(&RAM[loadpoint], 1, 961, binfile);    
  201.      fclose(binfile);
  202.      printf("%u bytes read from %s\n", bytesread, filename);
  203. }
  204.  
  205. void reset86() {
  206.      //cs = 0xf000; ip = 0xfff0;
  207.      cs = 0x0800; ip = 0x0100;
  208.      al = 0; ah = 0; bl = 0; bh = 0; cl = 0; dl = 0; dh = 0;
  209.      sp = 0x3fe; bp = 0; si = 0x7c02; di = 0;
  210.      ds = 0x800; ss = 0x7c0; es = 0x800;
  211.      cf = 0; pf = 0; af = 0; zf = 0; sf = 0; tf = 0; ifl = 1; df = 0; of = 0;
  212.      
  213.      //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;
  214.      running = 1;
  215. }
  216.  
  217. void intcall86(unsigned char intnum) {
  218.      switch (intnum) {
  219.             case 0x10: //VGA BIOS call
  220.                  vgahandler(); return;
  221.      }
  222.      push16(makeflagsword()); push16(cs); push16(ip);
  223.      templong = intnum<<2;
  224.      cs = RAM[templong++] + (RAM[templong++]<<8);
  225.      ip = RAM[templong++] + (RAM[templong]<<8);
  226.      return;
  227.      //ip = pop16(); cs = pop16(); decodeflagsword(pop16());
  228. }
  229.  
  230. void exec86() {
  231.      savecs = cs; saveip = ip; opcode = RAM[(cs<<4)+ip]; stepip;
  232.     printf("Exec: %s @ %x:%x\n", opdesc[opcode], savecs, saveip);
  233.      
  234.      useseg = 1; //default segment is DS
  235.      if (opcode==0x2e) { useseg = 0; savecs = cs; saveip = ip; opcode = RAM[(cs<<4)+ip]; stepip; }
  236.         else if (opcode==0x3e) { useseg = 1; savecs = cs; saveip = ip; opcode = RAM[(cs<<4)+ip]; stepip; }
  237.         else if (opcode==0x26) { useseg = 2; savecs = cs; saveip = ip; opcode = RAM[(cs<<4)+ip]; stepip; }
  238.         else if (opcode==0x36) { useseg = 3; savecs = cs; saveip = ip; opcode = RAM[(cs<<4)+ip]; stepip; }
  239.  
  240.      switch (opcode) {
  241.             case 0x06: //PUSH ES
  242.                  push16(es); break;
  243.             case 0x07: //POP ES
  244.                  es = pop16(); break;
  245.             case 0x0e: //PUSH CS                
  246.                  push16(cs); break;
  247.             case 0x16: //PUSH SS                
  248.                  push16(ss); break;
  249.             case 0x17: //POP SS
  250.                  ss = pop16(); break;
  251.             case 0x1e: //PUSH DS                
  252.                  push16(ds); break;
  253.             case 0x1f: //POP DS
  254.                  ds = pop16(); break;
  255.             case 0x50: //PUSH eAX
  256.                  push16(ax); break;                
  257.             case 0x51: //PUSH eCX
  258.                  push16(cx); break;                
  259.             case 0x52: //PUSH eDX
  260.                  push16(dx); break;
  261.             case 0x53: //PUSH eBX
  262.                  push16(bx); break;
  263.             case 0x54: //PUSH eSP
  264.                  push16(sp); break;
  265.             case 0x55: //PUSH eBP
  266.                  push16(bp); break;
  267.             case 0x56: //PUSH eSI
  268.                  push16(si); break;
  269.             case 0x57: //PUSH eDI
  270.                  push16(di); break;
  271.             case 0x58: //POP eAX
  272.                  tempval = pop16(); al = tempval&0xFF; ah = tempval>>8; break;
  273.             case 0x59: //POP eCX
  274.                  tempval = pop16(); cl = tempval&0xFF; ch = tempval>>8; break;
  275.             case 0x5A: //POP eDX
  276.                  tempval = pop16(); dl = tempval&0xFF; dh = tempval>>8; break;
  277.             case 0x5B: //POP eBX
  278.                  tempval = pop16(); bl = tempval&0xFF; bh = tempval>>8; break;
  279.             case 0x5C: //POP eSP
  280.                  sp = pop16(); break;
  281.             case 0x5D: //POP eBP
  282.                  bp = pop16(); break;
  283.             case 0x5E: //POP eSI
  284.                  si = pop16(); break;
  285.             case 0x5F: //POP eDI
  286.                  di = pop16(); break;
  287.   //          case 0x80: //CMP Eb, Ib
  288. //                 calcmodregrm(); datasize = 0;
  289.             case 0x8e: //MOV Sw, Ew
  290.                  calcmodregrm(); datasize = 1; writesreg(reg, readrm(rmnum)); break;
  291.             case 0xb0: //MOV AL, Ib
  292.                  al = RAM[(cs<<4)+ip]; stepip; break;
  293.             case 0xb1: //MOV CL, Ib
  294.                  cl = RAM[(cs<<4)+ip]; stepip; break;
  295.             case 0xb2: //MOV DL, Ib
  296.                  dl = RAM[(cs<<4)+ip]; stepip; break;
  297.             case 0xb3: //MOV BL, Ib
  298.                  bl = RAM[(cs<<4)+ip]; stepip; break;
  299.             case 0xb4: //MOV AH, Ib
  300.                  ah = RAM[(cs<<4)+ip]; stepip; break;
  301.             case 0xb5: //MOV CH, Ib
  302.                  ch = RAM[(cs<<4)+ip]; stepip; break;
  303.             case 0xb6: //MOV DH, Ib
  304.                  dh = RAM[(cs<<4)+ip]; stepip; break;
  305.             case 0xb7: //MOV BH, Ib
  306.                  bh = RAM[(cs<<4)+ip]; stepip; break;
  307.             case 0xb8: //MOV AX, Iv
  308.                  al = RAM[(cs<<4)+ip]; stepip;
  309.                  ah = RAM[(cs<<4)+ip]; stepip; break;
  310.             case 0xb9: //MOV CX, Iv
  311.                  cl = RAM[(cs<<4)+ip]; stepip;
  312.                  ch = RAM[(cs<<4)+ip]; stepip; break;
  313.             case 0xba: //MOV DX, Iv
  314.                  dl = RAM[(cs<<4)+ip]; stepip;
  315.                  dh = RAM[(cs<<4)+ip]; stepip; break;
  316.             case 0xbb: //MOV BX, Iv
  317.                  bl = RAM[(cs<<4)+ip]; stepip;
  318.                  bh = RAM[(cs<<4)+ip]; stepip; break;
  319.             case 0xbc: //MOV SP, Iv
  320.                  sp = RAM[(cs<<4)+ip]; stepip;
  321.                  sp += RAM[(cs<<4)+ip]<<8; stepip; break;
  322.             case 0xbd: //MOV BP, Iv
  323.                  bp = RAM[(cs<<4)+ip]; stepip;
  324.                  bp += RAM[(cs<<4)+ip]<<8; stepip; break;
  325.             case 0xbe: //MOV SI, Iv
  326.                  si = RAM[(cs<<4)+ip]; stepip;
  327.                  si += RAM[(cs<<4)+ip]<<8; stepip; break;
  328.             case 0xbf: //MOV DI, Iv
  329.                  di = RAM[(cs<<4)+ip]; stepip;
  330.                  di += RAM[(cs<<4)+ip]<<8; stepip; break;
  331.             case 0xc6: //MOV Eb, Ib
  332.                  calcmodregrm(); datasize = 0; templong = RAM[(cs<<4)+ip]; stepip; printf("POOP\n"); writerm(rmnum, templong); break;
  333.             case 0xcd: //INT Ib
  334.                  tempval = RAM[(cs<<4)+ip]; stepip;
  335.                  intcall86((unsigned char)tempval); break;
  336.             case 0xe9: //JMP Jv
  337.                  ip = (RAM[(cs<<4)+ip]+(RAM[(cs<<4)+ip+1]<<8)+3) % 0xFFFF; break;
  338.             default:
  339.                     running = 0;
  340.                     printf("UNKNOWN OPCODE EXCEPTION: %s @ %x:%x\n", opdesc[opcode], savecs, saveip);
  341.                     printf("AX: %x    BX: %x    CX: %x    DX: %x\n", ax, bx, cx, dx);
  342.                     printf("CS: %x    IP: %x    SS: %x    SP: %x\n", savecs, saveip, ss, sp);
  343.                     printf("SI: %x    DI: %x    DS: %x    ES: %x\n", si, di, ds, es);
  344.                     return;
  345.      }
  346. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement