Advertisement
NovaYoshi

Doritos16

Jan 27th, 2013
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 17.35 KB | None | 0 0
  1. /* DoritoCPU, a DCPU-16 emulator
  2.    by NovaSquirrel, 2013
  3.  
  4.    http://dcpu.com/dcpu-16/
  5. */
  6.  
  7. #include "SDL/SDL.h"
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdarg.h>
  11. #include <stdlib.h>
  12. #include <time.h>
  13. #include <ctype.h>
  14. #include <malloc.h>
  15. #define MASK_16(x) ((x)&0xffff)
  16. const int SCREEN_WIDTH = 32*4*2;
  17. const int SCREEN_HEIGHT = 8*12*2;
  18. const int SCREEN_BPP = 32;
  19. const int MONITOR_WIDTH = 32;
  20. const int MONITOR_HEIGHT = 12;
  21.  
  22. SDL_Surface *screen = NULL;
  23. SDL_Surface *MonitorScreen = NULL;
  24. #define DELAY_TIME 17
  25. #define CYCLES_PER_DELAY 1666
  26. int Retraces = 0, quit = 0;
  27. typedef unsigned short u16;
  28. typedef unsigned long u32;
  29.  
  30. void inline rectfillwh(SDL_Surface *Bmp, int X1, int Y1, int W, int H, int  Color) {
  31.   SDL_Rect A = {X1, Y1, W, H};
  32.   SDL_FillRect(Bmp,  &A, Color);
  33. }
  34. void inline blit(SDL_Surface* SrcBmp, SDL_Surface* DstBmp, int SourceX, int SourceY, int DestX, int DestY, int Width, int Height) {
  35.   SDL_Rect A = {SourceX, SourceY, Width, Height};
  36.   SDL_Rect B = {DestX, DestY};
  37.   SDL_BlitSurface(SrcBmp, &A, DstBmp, &B);
  38. }
  39. void inline clear_to_color(SDL_Surface *Bmp, int Color) {
  40.   SDL_FillRect(Bmp, NULL, Color);
  41. }
  42.  
  43. enum DataRegister {
  44.   REG_A, REG_B, REG_C, REG_X, REG_Y, REG_Z, REG_I, REG_J
  45. };
  46.  
  47. typedef struct DCPU {
  48.   u16 DataRegister[8]; // A, B, C, X, Y, Z, I or J
  49.   u16 PC, SP, EX, IA, IAQ;
  50.   u32 Cycles;
  51.   u16 RAM[0x10000];
  52.   u16 WriteConst; // where writes to constants go
  53.   int HardwareCount;
  54.   void *Hardware[8];
  55. } DCPU;
  56. void DCPU_IRQ(DCPU *VM, u16 Message);
  57. typedef struct Hardware {
  58.   u32 Id;
  59.   u16 Version;
  60.   u32 Manufacturer;
  61.   int (*Update)(DCPU *VM, struct Hardware *Hard);
  62.   int (*Interrupt)(DCPU *VM, struct Hardware *Hard);
  63.   int (*WriteRAM)(DCPU *VM, u16 Location, u16 Value);
  64.   int (*Create)(DCPU *VM);
  65.   int (*Destroy)(DCPU *VM);
  66.   void *Storage;
  67. } Hardware;
  68.  
  69. // until I put in multiple screen support or multiple keyboard support this will do
  70. u16 ClockRate = 0;
  71. u16 ClockRealticks = 0;
  72. u16 ClockTicks = 0;
  73. u16 ClockInterrupt = 0;
  74.  
  75. u16 MonitorTilemap = 0;
  76. u16 MonitorFont = 0;
  77. u16 MonitorPalette = 0;
  78. u16 MonitorBorder = 0;
  79.  
  80. //u16 Keyboard
  81.  
  82. const u16 DefaultFont[] = {
  83.   0xff9e, 0xff8e, 0x722c, 0xfff4, 0xffbb, 0xff8f, 0xfff9, 0xb158, 0x242e, 0x2400, 0x082a, 0x0800,
  84.   0x0008, 0x0000, 0x0808, 0x0808, 0xffff, 0x0000, 0xfff8, 0x0808, 0xfff8, 0x0000, 0x080f, 0x0000,
  85.   0x000f, 0x0808, 0xffff, 0x0808, 0xfff8, 0x0808, 0xffff, 0x0000, 0x080f, 0x0808, 0xffff, 0x0808,
  86.   0x6633, 0xffcc, 0x9933, 0xffcc, 0xfff8, 0xff80, 0x7f1f, 0x0701, 0x0107, 0x1f7f, 0xffe0, 0xfffe,
  87.   0x5500, 0xaa00, 0xffaa, 0xffaa, 0xffaa, 0xff55, 0x0f0f, 0x0f0f, 0xfff0, 0xfff0, 0x0000, 0xffff,
  88.   0xffff, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0x005f, 0x0000, 0x0300, 0x0300, 0x3e14, 0x3e00,
  89.   0x266b, 0x3200, 0x611c, 0x4300, 0x3629, 0x7650, 0x0002, 0x0100, 0x1c22, 0x4100, 0x4122, 0x1c00,
  90.   0x1408, 0x1400, 0x081c, 0x0800, 0x4020, 0x0000, 0x0808, 0x0800, 0x0040, 0x0000, 0x601c, 0x0300,
  91.   0x3e49, 0x3e00, 0x427f, 0x4000, 0x6259, 0x4600, 0x2249, 0x3600, 0x0f08, 0x7f00, 0x2745, 0x3900,
  92.   0x3e49, 0x3200, 0x6119, 0x0700, 0x3649, 0x3600, 0x2649, 0x3e00, 0x0024, 0x0000, 0x4024, 0x0000,
  93.   0x0814, 0x2200, 0x1414, 0x1400, 0x2214, 0x0800, 0x0259, 0x0600, 0x3e59, 0x5e00, 0x7e09, 0x7e00,
  94.   0x7f49, 0x3600, 0x3e41, 0x2200, 0x7f41, 0x3e00, 0x7f49, 0x4100, 0x7f09, 0x0100, 0x3e41, 0x7a00,
  95.   0x7f08, 0x7f00, 0x417f, 0x4100, 0x2040, 0x3f00, 0x7f08, 0x7700, 0x7f40, 0x4000, 0x7f06, 0x7f00,
  96.   0x7f01, 0x7e00, 0x3e41, 0x3e00, 0x7f09, 0x0600, 0x3e61, 0x7e00, 0x7f09, 0x7600, 0x2649, 0x3200,
  97.   0x017f, 0x0100, 0x3f40, 0x7f00, 0x1f60, 0x1f00, 0x7f30, 0x7f00, 0x7708, 0x7700, 0x0778, 0x0700,
  98.   0x7149, 0x4700, 0x007f, 0x4100, 0x031c, 0x6000, 0x417f, 0x0000, 0x0201, 0x0200, 0xff80, 0x8000,
  99.   0x0001, 0x0200, 0x2454, 0x7800, 0x7f44, 0x3800, 0x3844, 0x2800, 0x3844, 0x7f00, 0x3854, 0x5800,
  100.   0x087e, 0x0900, 0x4854, 0x3c00, 0x7f04, 0x7800, 0x047d, 0x0000, 0x2040, 0x3d00, 0x7f10, 0x6c00,
  101.   0x017f, 0x0000, 0x7c18, 0x7c00, 0x7c04, 0x7800, 0x3844, 0x3800, 0x7c14, 0x0800, 0x0814, 0x7c00,
  102.   0x7c04, 0x0800, 0x4854, 0x2400, 0x043e, 0x4400, 0x3c40, 0x7c00, 0x1c60, 0x1c00, 0x7c30, 0x7c00,
  103.   0x6c10, 0x6c00, 0x4c50, 0x3c00, 0x6454, 0x4c00, 0x0836, 0x4100, 0x0077, 0x0000, 0x4136, 0x0800,
  104.   0x0201, 0x0201, 0x0205, 0x0200,
  105. };
  106. const u16 DefaultPalette[] = {
  107.   0x0000, 0x000a, 0x00a0, 0x00aa, 0x0a00, 0x0a0a, 0x0a50, 0x0aaa,
  108.   0x0555, 0x055f, 0x05f5, 0x05ff, 0x0f55, 0x0f5f, 0x0ff5, 0x0fff,
  109. };
  110.  
  111. int TextMonitorUpdate(DCPU *VM, Hardware *Hard) {
  112.   int cx, cy, px, py, i;
  113.   int Colors[16];
  114.   if(!MonitorTilemap)
  115.     return 0;
  116.   const u16 *Tilemap = &VM->RAM[MonitorTilemap];
  117.  
  118.   const u16 *Palette = DefaultPalette;
  119.   if(MonitorPalette)
  120.     Palette = &VM->RAM[MonitorPalette];
  121.   for(i=0;i<16;i++) // prerender palette
  122.     Colors[i] = SDL_MapRGB(screen->format, ((Palette[i]>>8)&15)<<4, ((Palette[i]>>4)&15)<<4, (Palette[i]&15)<<4);
  123.  
  124.   const u16 *Font = DefaultFont;
  125.   if(MonitorFont)
  126.     Font = &VM->RAM[MonitorFont];
  127.  
  128.   for(cy=0;cy<12;cy++)
  129.     for(cx=0;cx<32;cx++) {
  130.       u16 Char = Tilemap[cy*32+cx];
  131.       u16 FG = (Char >> 12) & 15; // seems to be backwards when I don't do this?
  132.       u16 BG = (Char >> 8) & 15;
  133.       u16 T = Char & 127;
  134.       const u16 *Ptr = Font+T*2;
  135.       char Col[4] = {Ptr[0]>>8, Ptr[0]&255, Ptr[1]>>8, Ptr[1]&255};
  136.       for(px=0;px<4;px++)
  137.         for(py=0;py<8;py++)
  138.           rectfillwh(screen, (cx*4+px)*2, (cy*8+py)*2, 2, 2, ((Col[px]<<(7-py))&0x80)?Colors[FG]:Colors[BG]);
  139.     }
  140.   return 1;
  141. }
  142.  
  143. int TextMonitorIRQ(DCPU *VM, Hardware *Hard) {
  144.   int i;
  145.   switch(VM->DataRegister[REG_A]) {
  146.     case 0:
  147.       MonitorTilemap = VM->DataRegister[REG_B];
  148.       break;
  149.     case 1:
  150.       MonitorFont = VM->DataRegister[REG_B];
  151.       break;
  152.     case 2:
  153.       MonitorPalette = VM->DataRegister[REG_B];
  154.       break;
  155.     case 3:
  156.       MonitorBorder = VM->DataRegister[REG_B];
  157.       break;
  158.     case 4:
  159.       VM->Cycles+=256;
  160.       for(i=0;i<256;i++)
  161.         VM->RAM[(i+VM->DataRegister[REG_B]) & 0xffff] = DefaultFont[i];
  162.       break;
  163.     case 5:
  164.       VM->Cycles+=16;
  165.       for(i=0;i<16;i++)
  166.         VM->RAM[(i+VM->DataRegister[REG_B]) & 0xffff] = DefaultPalette[i];
  167.       break;
  168.   }
  169.   return 1;
  170. }
  171. int GenericKeyboardIRQ(DCPU *VM, Hardware *Hard) {
  172.   switch(VM->DataRegister[REG_A]) {
  173.  
  174.   }
  175.   return 1;
  176. }
  177. int GenericClockUpdate(DCPU *VM, Hardware *Hard) {
  178.   if(!ClockRate)
  179.     return 0;
  180.   ClockRealticks++;
  181.   if(ClockRate == ClockRealticks) {
  182.      ClockRealticks = 0;
  183.      ClockTicks = 0;
  184.      if(ClockInterrupt)
  185.        DCPU_IRQ(VM, ClockInterrupt);
  186.   }
  187.   return 1;
  188. }
  189. int GenericClockIRQ(DCPU *VM, Hardware *Hard) {
  190.   switch(VM->DataRegister[REG_A]) {
  191.     case 0:
  192.       ClockRate = VM->DataRegister[REG_B];
  193.       ClockTicks = 0;
  194.       ClockRealticks = 0;
  195.       break;
  196.     case 1:
  197.       VM->DataRegister[REG_C] = ClockTicks;
  198.       break;
  199.     case 2:
  200.       ClockInterrupt = VM->DataRegister[REG_B];
  201.       break;
  202.   }
  203.   return 1;
  204. }
  205. Hardware TextMonitor = {
  206.   0x7349f615, 0x1802, 0x1c6c8b36,
  207.   TextMonitorUpdate,
  208.   TextMonitorIRQ,
  209.   NULL,
  210.   NULL, NULL,
  211. };
  212.  
  213. Hardware GenericKeyboard = {
  214.   0x30cf7406, 0x0001, 0x00000000,
  215.   NULL,
  216.   GenericKeyboardIRQ,
  217.   NULL,
  218.   NULL, NULL,
  219. };
  220.  
  221. Hardware GenericClock = {
  222.   0x12d0b402, 0x0001, 0x00000000,
  223.   GenericClockUpdate,
  224.   GenericClockIRQ,
  225.   NULL,
  226.   NULL, NULL,
  227. };
  228.  
  229. struct DCPU VM = {
  230.   {0,0,0,0,0,0,0,0}, // registers
  231.   0, 0xffff, 0, 0, 0,       // more registers
  232.   0,   // cycles
  233.   {0}, // ram
  234.   0,   // constant
  235.   3,   // hardware
  236.   {&GenericKeyboard,&TextMonitor,&GenericClock,NULL}
  237. };
  238.  
  239. u16 DCPU_NextWord(DCPU *VM) {
  240.   return VM->RAM[++VM->PC];
  241. }
  242. u16 DCPU_ReadWord(DCPU *VM, u16 Address) {
  243.   return VM->RAM[Address&0xffff];
  244. }
  245.  
  246. u16 DCPU_ValParam(DCPU *VM, u16 Param) {
  247.   switch(Param) {
  248.     case 0x00 ... 0x07:
  249.       return VM->DataRegister[Param&7];
  250.     case 0x08 ... 0x0f:
  251.       return VM->RAM[MASK_16(VM->DataRegister[Param&7])];
  252.     case 0x10 ... 0x17: {
  253.       VM->Cycles++;
  254.       return VM->RAM[MASK_16(DCPU_NextWord(VM)+VM->DataRegister[Param&7])];
  255.     }
  256.     case 0x18: // pop
  257.       return VM->RAM[MASK_16(VM->SP++)];
  258.     case 0x19:
  259.       return VM->RAM[MASK_16(VM->SP)];
  260.     case 0x1a: {
  261.       VM->Cycles++;
  262.       return VM->RAM[MASK_16(VM->SP+DCPU_NextWord(VM))];
  263.     }
  264.     case 0x1b:
  265.       return VM->SP;
  266.     case 0x1c:
  267.       return VM->PC;
  268.     case 0x1d:
  269.       return VM->EX;
  270.     case 0x1e: {
  271.       VM->Cycles++;
  272.       return VM->RAM[MASK_16(DCPU_NextWord(VM))];
  273.     }
  274.     case 0x1f: {
  275.       VM->Cycles++;
  276.       return DCPU_NextWord(VM);
  277.     }
  278.     default:
  279.       return Param-32-1;
  280.   }
  281. }
  282.  
  283. u16 *DCPU_PtrParam(DCPU *VM, u16 Param) {
  284.   switch(Param) {
  285.     case 0x00 ... 0x07:
  286.       return &VM->DataRegister[Param&7];
  287.     case 0x08 ... 0x0f:
  288.       return &VM->RAM[MASK_16(VM->DataRegister[Param&7])];
  289.     case 0x10 ... 0x17: {
  290.       VM->Cycles++;
  291.       return &VM->RAM[MASK_16(DCPU_NextWord(VM)+VM->DataRegister[Param&7])];
  292.     }
  293.     case 0x18: // push
  294.       return &VM->RAM[MASK_16(--VM->SP)];
  295.     case 0x19:
  296.       return &VM->RAM[MASK_16(VM->SP)];
  297.     case 0x1a: {
  298.       VM->Cycles++;
  299.       return &VM->RAM[MASK_16(VM->SP+DCPU_NextWord(VM))];
  300.     }
  301.     case 0x1b:
  302.       return &VM->SP;
  303.     case 0x1c:
  304.       return &VM->PC;
  305.     case 0x1d:
  306.       return &VM->EX;
  307.     case 0x1e: {
  308.       VM->Cycles++;
  309.       return &VM->RAM[MASK_16(DCPU_NextWord(VM))];
  310.     }
  311.     case 0x1f: {
  312.       VM->Cycles++;
  313.       VM->WriteConst = DCPU_NextWord(VM);
  314.       return &VM->WriteConst;
  315.     }
  316.     default: // should not happen
  317.       return NULL;
  318.   }
  319. }
  320.  
  321. void DCPU_IRQ(DCPU *VM, u16 Message) {
  322.   VM->RAM[--VM->SP] = VM->PC + 1;
  323.   VM->RAM[--VM->SP] = VM->DataRegister[REG_A];
  324.   VM->PC = VM->IA - 1;
  325.   VM->DataRegister[REG_A] = Message;
  326. };
  327.  
  328. int DCPU_OpSize(u16 Opcode) {
  329.   int Size = 1;
  330.   u16 Func = Opcode & 31;
  331.   u16 ParA = (Opcode>>10) & 63;
  332.   u16 ParB = (Opcode>>5)  & 31;
  333.   const char Increase[] = {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1, 0,0,1,0,0,0,1,1};
  334.   if((ParA < 0x20) && Increase[ParA]) Size++;
  335.   if(Func)
  336.     if((ParB < 0x20) && Increase[ParB]) Size++;
  337. //  printf("size %i\n", Size);
  338.   return Size;
  339. }
  340.  
  341. void DCPU_Step(DCPU *VM) {
  342.   // aaaaaabbbbbooooo
  343.   u16 Op = VM->RAM[VM->PC];
  344.   u16 Func = Op & 31;
  345.   u16 ParA, ParB;
  346.   ParA = (Op>>10) & 63;
  347.   ParB = (Op>>5)  & 31;
  348.   // both the source and destination can add another word, so order matters
  349. //  printf("PC %.3i, AC %.4x - %.2x: %.2x %.2x \n", VM->PC, VM->DataRegister[REG_A], Func, ParA, ParB);
  350.   u16 Val, *Dst;
  351.   if(Func) {
  352.     Val = DCPU_ValParam(VM, ParA);
  353.     Dst = DCPU_PtrParam(VM, ParB);
  354.   } else {
  355.     Val = 0;
  356.     Dst = DCPU_PtrParam(VM, ParA);
  357.   }
  358.   Hardware *Hard;
  359.   signed short TempUnsigned;
  360.   signed short TempSigned, TempSigned2;
  361.   int Skipped = 0;
  362.   switch(Func) {
  363.     case 0x00: // extended opcode
  364.       switch(ParB) {
  365.         case 0x00:
  366.           puts("Invalid opcode");
  367.           exit(0);
  368.         default:
  369.           printf("Unsupported extended opcode 0x%.2x", ParB);
  370.           exit(0);
  371.         case 0x01: // jsr
  372.           VM->Cycles+=3;
  373.           VM->RAM[--VM->SP] = VM->PC + 1;
  374.           VM->PC = (*Dst) - 1;
  375.           break;
  376.         case 0x08: // int, software interrupt with message a
  377.           VM->Cycles+=4;
  378.           DCPU_IRQ(VM, *Dst);
  379.           break;
  380.         case 0x09: // iag
  381.           VM->Cycles++;
  382.           *Dst = VM->IA;
  383.           break;
  384.         case 0x0a: // ias
  385.           VM->Cycles++;
  386.           VM->IA = *Dst;
  387.           break;
  388.         case 0x0b: // rfi
  389.           VM->Cycles+=3;
  390.           VM->DataRegister[REG_A] = VM->RAM[VM->SP++];
  391.           VM->PC = VM->RAM[VM->SP++];
  392.           VM->IAQ = 0;
  393.           break;
  394.         case 0x0c: // iaq
  395.           VM->Cycles+=2;
  396.           VM->IAQ = 1;
  397.           break;
  398.         case 0x10: // hwn
  399.           VM->Cycles+=2;
  400.           TempUnsigned = 0;
  401.           *Dst = VM->HardwareCount;
  402.           break;
  403.         case 0x11: // hwq
  404.           VM->Cycles+=4;
  405.           Hard = (Hardware*)VM->Hardware[*Dst];
  406.           VM->DataRegister[REG_A] = Hard->Id&0xffff;
  407.           VM->DataRegister[REG_B] = Hard->Id>>16;
  408.           VM->DataRegister[REG_C] = Hard->Version;
  409.           VM->DataRegister[REG_X] = Hard->Manufacturer&0xffff;
  410.           VM->DataRegister[REG_Y] = Hard->Manufacturer>>16;
  411.           break;
  412.         case 0x12: // hwi
  413.           VM->Cycles+=4;
  414.           Hard = (Hardware*)VM->Hardware[*Dst];
  415.           Hard->Interrupt(VM, Hard);
  416.           break;
  417.       }
  418.       break;
  419.     case 0x01: // set b,a
  420.       VM->Cycles++;
  421.       *Dst = Val;
  422.       if(Dst == &VM->PC) (*Dst)--;
  423.       break;
  424.     case 0x02: // add b,a
  425.       VM->Cycles+=2;
  426.       *Dst += Val;
  427.       break;
  428.     case 0x03: // sub b,a
  429.       VM->Cycles+=2;
  430.       *Dst -= Val;
  431.       break;
  432.     case 0x04: // mul b,a
  433.       VM->Cycles+=2;
  434.       *Dst *= Val;
  435.       break;
  436.     case 0x05: // mli b,a <--- signed
  437.       VM->Cycles+=2;
  438.       TempSigned = (signed)*Dst;
  439.       TempSigned *= (signed)Val;
  440.       *Dst = (unsigned)TempSigned;
  441.       break;
  442.     case 0x06: // div b,a
  443.       VM->Cycles+=3;
  444.       *Dst /= (signed)Val;
  445.       break;
  446.     case 0x07: // dvi b,a <--- signed
  447.       VM->Cycles+=3;
  448.       TempSigned = (signed)*Dst;
  449.       TempSigned /= (signed)Val;
  450.       *Dst = (unsigned)TempSigned;
  451.       break;
  452.     case 0x08: // mod b,a
  453.       VM->Cycles+=3;
  454.       *Dst %= (signed)Val;
  455.       break;
  456.     case 0x09: // mdi b,a <--- signed
  457.       VM->Cycles+=3;
  458.       TempSigned = (signed)*Dst;
  459.       TempSigned %= (signed)Val;
  460.       *Dst = (unsigned)TempSigned;
  461.       break;
  462.     case 0x0a: // and b,a
  463.       VM->Cycles++;
  464.       *Dst &= Val;
  465.       break;
  466.     case 0x0b: // bor b,a
  467.       VM->Cycles++;
  468.       *Dst |= Val;
  469.       break;
  470.     case 0x0c: // xor b,a
  471.       VM->Cycles++;
  472.       *Dst ^= Val;
  473.       break;
  474.     case 0x0d: // shr b,a
  475.       VM->Cycles++;
  476.       *Dst >>= Val;
  477.       break;
  478.     case 0x0e: // asr b,a
  479.       VM->Cycles++;
  480.       TempUnsigned = *Dst;
  481.       *Dst >>= Val;
  482.       *Dst |= TempUnsigned & 0x8000;
  483.       break;
  484.     case 0x0f: // shl b,a
  485.       VM->Cycles++;
  486.       *Dst <<= Val;
  487.       break;
  488.     case 0x10: // ifb b,a
  489.       VM->Cycles+=2;
  490.       Skipped = !((*Dst&Val)!=0);
  491.       break;
  492.     case 0x11: // ifc b,a
  493.       VM->Cycles+=2;
  494.       Skipped = !((*Dst&Val)==0);
  495.       break;
  496.     case 0x12: // ife b,a
  497.       VM->Cycles+=2;
  498.       Skipped = (*Dst!=Val);
  499.       break;
  500.     case 0x13: // ifn b,a
  501.       VM->Cycles+=2;
  502.       Skipped = (*Dst==Val);
  503.       break;
  504.     case 0x14: // ifg b,a
  505.       VM->Cycles+=2;
  506.       Skipped = (*Dst<=Val);
  507.       break;
  508.     case 0x15: // ifa b,a <--- signed
  509.       VM->Cycles+=2;
  510.       TempSigned = *Dst;
  511.       TempSigned2 = Val;
  512.       Skipped = (TempSigned<=TempSigned2);
  513.       break;
  514.     case 0x16: // ifl b,a
  515.       VM->Cycles+=2;
  516.       Skipped = (*Dst>=Val);
  517.       break;
  518.     case 0x17: // ifu b,a <--- signed
  519.       VM->Cycles+=2;
  520.       TempSigned = *Dst;
  521.       TempSigned2 = Val;
  522.       Skipped = (TempSigned>=TempSigned2);
  523.       break;
  524.     case 0x1a: // adx b,a
  525.       VM->Cycles+=3;
  526.       *Dst = *Dst + Val + VM->EX;
  527.       break;
  528.     case 0x1b: // sbx b,a
  529.       VM->Cycles+=3;
  530.       *Dst = *Dst - Val + VM->EX;
  531.       break;
  532.     case 0x1e: // sti b,a
  533.       VM->DataRegister[REG_I]++;
  534.       VM->DataRegister[REG_J]++;
  535.       VM->Cycles+=2;
  536.       *Dst = Val;
  537.       break;
  538.     case 0x1f: // std b,a
  539.       VM->DataRegister[REG_I]--;
  540.       VM->DataRegister[REG_J]--;
  541.       VM->Cycles+=2;
  542.       *Dst = Val;
  543.       break;
  544.     default:
  545.       break;
  546.   }
  547.   if(Skipped) {
  548.     VM->PC++;
  549.     VM->Cycles++;
  550.     // skip if "if" opcodes found
  551. //    printf("skipped onto %.4x \n", VM->RAM[VM->PC]);
  552.     while(((VM->RAM[VM->PC]&31) >= 0x10) && ((VM->RAM[VM->PC]&31) <= 0x17)) {
  553.       VM->Cycles++;
  554.       VM->PC+= DCPU_OpSize(VM->RAM[VM->PC]);
  555. //      printf("leaving off on %.4x \n", VM->RAM[VM->PC]);
  556.     }
  557.     VM->PC+= DCPU_OpSize(VM->RAM[VM->PC]); // skip the next opcode, after IFs or not
  558.   } else {
  559.     VM->PC++;
  560.   }
  561. }
  562.  
  563. void EndFrame() {
  564.   SDL_Event event;
  565.   while(SDL_PollEvent(&event)) {
  566.     if(event.type == SDL_QUIT)
  567.       quit=1;
  568.   }
  569.   SDL_Flip(screen);
  570.   SDL_Delay(DELAY_TIME);
  571.   Retraces++;
  572. }
  573.  
  574. int main( int argc, char* args[] ) {
  575.   char TestFile[512] = "hello.bin";
  576.   if(argc>=2)
  577.     strcpy(TestFile, args[1]);
  578.   if(SDL_Init(SDL_INIT_EVERYTHING)==-1) {
  579.     puts("failed to init");
  580.     return -1;
  581.   }
  582.   freopen("CON", "w", stdout);
  583.   freopen("CON", "w", stderr);
  584.  
  585.   screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
  586.   MonitorScreen = SDL_CreateRGBSurface(SDL_SWSURFACE, 128,96, SCREEN_BPP, 0,0,0,0);
  587.  
  588.   SDL_WM_SetCaption("Doritos16", NULL);
  589.  
  590.   FILE *ProgramFile = fopen(TestFile,"rb");
  591.   int Fill = 0;
  592.   if(ProgramFile == NULL) {
  593.     puts("Can't open the file");
  594.     return 0;
  595.   }
  596.   while(!feof(ProgramFile)) {
  597.     unsigned char k = fgetc(ProgramFile);
  598.     VM.RAM[Fill++] = (k<<8) | fgetc(ProgramFile);
  599.     //printf("%.4x\n", VM.RAM[Fill-1]);
  600.   }
  601.   fclose(ProgramFile);
  602.  
  603.   int i;
  604.   int OpsRun = 0;
  605.   while(!quit) {
  606.     while(VM.Cycles < CYCLES_PER_DELAY) { // ends up running about 99960 cycles/second instead of 100khz
  607.       DCPU_Step(&VM);
  608.       OpsRun++;
  609. //      if(OpsRun == 30)
  610. //        return 0;
  611.     }
  612.     EndFrame();
  613.     VM.Cycles -= CYCLES_PER_DELAY;
  614.     for(i=0;i<VM.HardwareCount;i++) {
  615.       Hardware *Hard = (Hardware*)VM.Hardware[i];
  616.       if(Hard->Update)
  617.         Hard->Update(&VM, Hard);
  618. //      printf("%i\n", VM.PC);
  619.     }
  620.   }
  621.   SDL_Quit();
  622.   return 0;
  623. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement