home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Science / µSim 1.0b5 folder / source / Simulator.c < prev    next >
Encoding:
Text File  |  1994-09-01  |  12.0 KB  |  447 lines  |  [TEXT/MMCC]

  1. /*
  2. Copyright © 1993,1994 by Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware: you can copy, exchange, modify this
  5. code as you wish. You may include this code in any kind of application: freeware,
  6. shareware, or commercial, provided that full credits are given.
  7. You may not sell or distribute this code for profit.
  8. */
  9.  
  10. //#pragma load "MacDump"
  11.  
  12. #include    <stdlib.h>
  13.  
  14. #include    "UtilsSys7.h"
  15. #include    "Globals.h"
  16. #include    "AEHandlers.h"
  17. #include    "Animation.h"
  18. #include    "Dump.h"
  19. #include    "Input.h"
  20. #include    "Microprogram_Ed.h"
  21. #include    "Registers.h"
  22. #include    "Simulator.h"
  23. #include    "SimUtils.h"
  24.  
  25. #if defined(FabSystem7orlater)
  26.  
  27. //#pragma segment Main
  28.  
  29. enum conditions {
  30. kCOND_NEVER = 0,
  31. kCOND_N,
  32. kCOND_Z,
  33. kCOND_ALWAYS
  34. };
  35.  
  36. const short read[] = { kP_MBR, kP_MBRMEM, 0};
  37. const short readstart[] = { kP_MAR2MEM, 0};
  38. const short writestart[] = { kP_MBRMEM, kP_MAR2MEM, 0};
  39.  
  40. static short    Abus, Bbus, Cbus;
  41. static union u_mir mir;
  42.  
  43. static short alu(void);
  44. static void shifter(void);
  45. static Boolean memory(void);
  46. static int compareOpc(const void *opc1, const void *opc2);
  47. static void ZoomEffectMap2MPC(void);
  48.  
  49. /* MSL: models the Micro Sequencing Logic */
  50. #define MSL()    ((mir.bits.cond == kCOND_ALWAYS) || ((mir.bits.cond == kCOND_Z) && \
  51.                 (gParts[kP_ALU - kFIRST_PICT] == 0)) || ((mir.bits.cond == kCOND_N) \
  52.                 && (gParts[kP_ALU - kFIRST_PICT] < 0)))
  53.  
  54. /* AMUX: models the A multiplexer */
  55. #define    AMUX()    (mir.bits.amux ? gParts[kP_MBR - kFIRST_PICT] : \
  56.                     gParts[kP_ALATCH - kFIRST_PICT])
  57.  
  58. /* MMUX: models the M multiplexer */
  59. #define    MMUX()    ((mslflag = MSL()) ? mir.bits.addr : gParts[kP_INCR - kFIRST_PICT])
  60.  
  61. /* alu: models the Arithmetic Logical Unit */
  62.  
  63. static short alu(void)
  64. {
  65. register short value;
  66.  
  67. value = AMUX();
  68. gParts[kP_AMUX - kFIRST_PICT] = value;
  69. switch(mir.bits.alu) {
  70.     case 1:    value += Bbus;
  71.         break;
  72.     case 2:    value &= Bbus;
  73.         break;
  74.     case 3:    value = ~value;
  75.         break;
  76.     }
  77. gParts[kP_ALU - kFIRST_PICT] = value;
  78. if (gRstatus > kST_STEPASM) {
  79.     ChangedBox(kP_AMUX - kFIRST_PICT);
  80.     ChangedBox(kP_ALU - kFIRST_PICT);
  81.     }
  82. return value;
  83. }
  84.  
  85. /* shifter: models the (!) shifter */
  86.  
  87. static void shifter(void)
  88. {
  89. register short value;
  90.  
  91. value = alu();
  92. switch(mir.bits.shift) {
  93.     case 1: value <<= 1;
  94.         break;
  95.     case 2: value = (unsigned short)value >> 1;
  96.         break;
  97.     case 3: value >>= 1;
  98.     }
  99. gParts[kP_SHIFTER - kFIRST_PICT] = value;
  100. if (gRstatus > kST_STEPASM) {
  101.     ChangedBox(kP_SHIFTER - kFIRST_PICT);
  102.     }
  103. Cbus = value;
  104. }
  105.  
  106. /* MAR: models the Memory Address Register */
  107.  
  108. #define MAR()    \
  109. {    \
  110. if (mir.bits.mar) {    \
  111.     gParts[kP_MAR - kFIRST_PICT] = gParts[kP_BLATCH - kFIRST_PICT];    \
  112.     if (gRstatus > kST_STEPASM) {    \
  113.         ChangedBox(kP_MAR - kFIRST_PICT);    \
  114.         if (gRstatus == kST_STEPSUBCYC)    \
  115.             ActivateObjs(marobjs);    \
  116.         }    \
  117.     }    \
  118. }
  119.  
  120. /* MAR: models the Memory Buffer Register */
  121.  
  122. #define MBR()    \
  123. {    \
  124. if (mir.bits.mbr) {    \
  125.     gParts[kP_MBR - kFIRST_PICT] = Cbus;    \
  126.     if (gRstatus > kST_STEPASM) {    \
  127.         ChangedBox(kP_MBR - kFIRST_PICT);    \
  128.         if (gRstatus == kST_STEPSUBCYC)    \
  129.             ActivateObjs(mbrobjs);    \
  130.         }    \
  131.     }    \
  132. }
  133.  
  134. /* ExecuteInstructions: executes instructions for a clock subcycle,
  135. taking care of the necessary user interface updates */
  136.  
  137. /* da schiaffare dentro la routine successiva */
  138. const short subc0[] = { kP_MPC2INC, kP_INCR, kP_MPC2CST, kP_CST2MIR, kP_REG2LTCH1, kP_REG2LTCH2, 0 };
  139. const short subc1[] = { kP_ALATCH, kP_BLATCH, 0 };
  140. const short shftaluamux[] = { kP_AMUX2ALU, kP_BLTCH2ALU, kP_ALU, kP_ALU2SH, kP_SHIFTER, 0};
  141. const short shftoregs[] = { kP_SH2REGS1, kP_SH2REGS2, kP_SH2REGS3, 0 };
  142. const short marobjs[] = { kP_MAR, kP_BLTCH2MAR1, kP_BLTCH2MAR2, 0 };
  143. const short mbrobjs[] = { kP_MBR, kP_SH2MBR1, kP_SH2MBR2, 0 };
  144. const short mapobjs[] = { kP_MAP, kP_MAPREGS, 0 };
  145. const short fromabus[] = { kP_ALTCH2AMUX, kP_AMUX, 0 };
  146. const short frommbr[] = { kP_MBR2AMUX, kP_AMUX, 0 };
  147. const short fromincr[] = { kP_INC2MMUX1, kP_INC2MMUX2, kP_MMUX, kP_MPC, 0};
  148. const short frommir[] = { kC_ADDR1, kC_ADDR2, kP_MMUX, kP_MPC, 0 };
  149. const short mmux2mpc[] = { kP_MMUX2MPC, 0 };
  150.  
  151. void ExecuteInstructions(short subclock)
  152. {
  153. register Handle    tempH;
  154. register Ptr    base;
  155. static unsigned short    mapLine;
  156. static Boolean    mslflag;
  157.  
  158. switch (subclock) {
  159.     case 0:
  160.         gParts[kP_INCR - kFIRST_PICT] = gParts[kP_MPC - kFIRST_PICT] + 1;
  161.         if (gRstatus > kST_STEPASM) {
  162.             ChangedBox(kP_INCR - kFIRST_PICT);
  163.             if (gRstatus == kST_STEPSUBCYC) {
  164.                 DeactivateObjs(shftoregs);
  165.                 DeactivateObjs(mbrobjs);
  166.                 DeactivateObjs(mapobjs);
  167.                 DeactivateObjs(writestart);
  168.                 if (mslflag)
  169.                     DeactivateObjs(frommir);
  170.                 else
  171.                     DeactivateObjs(fromincr);
  172.                 ActivateObjs(subc0);
  173.                 if (mir.bits.map)
  174.                     SelectLLine(kL_INSTR, mapLine);
  175.                 else {
  176.                     DeactivateObjs(mmux2mpc);
  177.                     SelectLLine(kL_COMMENTS, gParts[kP_MPC - kFIRST_PICT]);
  178.                     }
  179.                 }
  180.             }
  181.         mir = gCsMemory[gParts[kP_MPC - kFIRST_PICT]];
  182.         Abus = gRegs[mir.bits.a];
  183.         Bbus = gRegs[mir.bits.b];
  184.         break;
  185.     case 1:
  186.         gParts[kP_ALATCH - kFIRST_PICT] = Abus;
  187.         gParts[kP_BLATCH - kFIRST_PICT] = Bbus;
  188.         if (gRstatus > kST_STEPASM) {
  189.             ChangedBox(kP_ALATCH - kFIRST_PICT);
  190.             ChangedBox(kP_BLATCH - kFIRST_PICT);
  191.             if (gRstatus == kST_STEPSUBCYC) {
  192.                 DeactivateObjs(subc0);
  193.                 ActivateObjs(subc1);
  194.                 }
  195.             }
  196.         break;
  197.     case 2:
  198.         shifter();
  199.         MAR()
  200.         if (gRstatus == kST_STEPSUBCYC) {
  201.             DeactivateObjs(subc1);
  202.             ActivateObjs(shftaluamux);
  203.             if (mir.bits.amux)
  204.                 ActivateObjs(frommbr);
  205.             else
  206.                 ActivateObjs(fromabus);
  207.             }
  208.         break;
  209.     case 3:
  210.         if (mir.bits.dsc == 0) {
  211.             gRegs[mir.bits.c] = Cbus;
  212.             if (gRstatus > kST_STEPASM) {
  213.                 ChangedRegister(mir.bits.c);
  214.                 if (gRstatus == kST_STEPSUBCYC)
  215.                     ActivateObjs(shftoregs);
  216.                 }
  217.             }
  218.         MBR()
  219.         gParts[kP_MPC - kFIRST_PICT] = gParts[kP_MMUX - kFIRST_PICT] = MMUX();
  220.         (void)memory();
  221.         if (mir.bits.map) {
  222. //#define    Ext12(x)    (((x) << 4) >> 4)
  223. //#define    Ext11(x)    (((x) << 5) >> 5)
  224.             gRegs[kREG_EXT12] = gRegs[kREG_IR] << 4;
  225.             gRegs[kREG_EXT12] >>= 4;
  226.             gRegs[kREG_EXT11] = gRegs[kREG_IR] << 5;
  227.             gRegs[kREG_EXT11] >>= 5;
  228.             gRegs[kREG_LOW8] = gRegs[kREG_IR] & 0x00FF;
  229.             gParts[kP_MPC - kFIRST_PICT] = *(gAssMemory + *(Byte *)&gRegs[kREG_IR]);
  230.             if (gRstatus > kST_STEPASM) {
  231.                 ChangedRegister(kREG_EXT12);
  232.                 ChangedRegister(kREG_EXT11);
  233.                 ChangedRegister(kREG_LOW8);
  234.                 tempH = Get1Resource(krInstructions, kOPCODES);
  235.                 base = StripAddress(&((ROpcodePtr)*tempH)->offsetHB) + 2;
  236.                 mapLine = (unsigned long)(StripAddress(bsearch(&gRegs[kREG_IR], base,
  237.                     *(unsigned short *)*tempH + 1, sizeof(ROpcode), compareOpc))
  238.                     - base) / sizeof(ROpcode);
  239.                 ZoomEffectMap2MPC();
  240.                 if (gRstatus == kST_STEPSUBCYC)
  241.                     ActivateObjs(mapobjs);
  242.                 else
  243.                     SelectLLine(kL_INSTR, mapLine);
  244.                 }
  245.             }
  246.         if (gRstatus > kST_STEPASM) {
  247.             ChangedBox(kP_MMUX - kFIRST_PICT);
  248.             ChangedBox(kP_MPC - kFIRST_PICT);
  249.             if (gRstatus == kST_STEPSUBCYC) {
  250.                 DeactivateObjs(shftaluamux);
  251.                 DeactivateObjs(marobjs);
  252.                 if (mir.bits.amux)
  253.                     DeactivateObjs(frommbr);
  254.                 else
  255.                     DeactivateObjs(fromabus);
  256.                 if (mslflag)
  257.                     ActivateObjs(frommir);
  258.                 else
  259.                     ActivateObjs(fromincr);
  260.                 if (mir.bits.map == 0)
  261.                     ActivateObjs(mmux2mpc);
  262.                 }
  263.             else
  264.                 SelectLLine(kL_COMMENTS, gParts[kP_MPC - kFIRST_PICT]);
  265.             }
  266.         break;
  267.     }
  268. }
  269.  
  270. /* memory: models the external RAM memory */
  271.  
  272. static Boolean memory(void)
  273. {
  274. register short *tempP;
  275. register unsigned short    firstWordinWind;
  276. static Boolean rdInitiated = false, wrInitiated = false;
  277. register Boolean    stoppedForIO = false;
  278.  
  279. if (mir.bits.rd) {
  280.     if (rdInitiated) {
  281.         tempP = ((short *)gMMemory + (unsigned short)gParts[kP_MAR - kFIRST_PICT]);
  282.         gParts[kP_MBR - kFIRST_PICT] = *tempP;
  283.         if (gRstatus > kST_STEPASM) {
  284.             ChangedBox(kP_MBR - kFIRST_PICT);
  285.             if (gRstatus == kST_STEPSUBCYC)
  286.                 ActivateObjs(read);
  287.             }
  288.         /* handle memory mapped input */
  289.         if ((Ptr)tempP == (gMMemory + kSIZE_RAM - 4)) {
  290.             if ((gInTheForeground == false)||(gWPtr_IO != FrontWindow())) {
  291.                 SendmyAE(kFCR_MINE, kAEmySignalIO, myIdleFunct, kAENoReply | kAEAlwaysInteract | kAECanSwitchLayer);
  292.                 stoppedForIO = true;
  293.                 }
  294.             }
  295.         rdInitiated = false;
  296.         }
  297.     else {
  298.         rdInitiated = true;
  299.         if (gRstatus == kST_STEPSUBCYC)
  300.             ActivateObjs(readstart);
  301.         }
  302.     }
  303. if (mir.bits.wr) {
  304.     if (wrInitiated) {
  305.         tempP = ((short *)gMMemory + (unsigned short)gParts[kP_MAR - kFIRST_PICT]);
  306.         *tempP = gParts[kP_MBR - kFIRST_PICT];
  307.         wrInitiated = false;
  308.         /* update Dump Window only if necessary */
  309.         if (EmptyRgn(gWPtr_Dump->visRgn) == false)
  310.             if ((firstWordinWind = (unsigned short)GetCtlValue(dumpVScroll) << 4)
  311.                                 <= (unsigned short)gParts[kP_MAR - kFIRST_PICT])
  312.                 if (((firstWordinWind - 1) + 
  313.                         ((PRCT_B(gWPtr_Dump) - PRCT_T(gWPtr_Dump)) / dumpLineHeight) << 3)
  314.                         >= (unsigned short)gParts[kP_MAR - kFIRST_PICT])
  315.                     InvalDump();
  316.         /* handle memory mapped output */
  317.         if ((Ptr)tempP == (gMMemory + kSIZE_RAM - 2)) {
  318.             DoKeyDown(gWPtr_IO, ((unsigned char *)tempP)[1], false);
  319.             if ((gInTheForeground == false)||(gWPtr_IO != FrontWindow()))
  320.                 SendmyAE(kFCR_MINE, kAEmySignalIO, myIdleFunct, kAENoReply | kAEAlwaysInteract | kAECanSwitchLayer);
  321.             *tempP = 0;
  322.             }
  323.         }
  324.     else {
  325.         wrInitiated = true;
  326.         if (gRstatus == kST_STEPSUBCYC)
  327.             ActivateObjs(writestart);
  328.         }
  329.     }
  330. return stoppedForIO;
  331. }
  332.  
  333. /* compareOpc: compare function to search for the instruction
  334. currently executing */
  335.  
  336. static int compareOpc(const void *opc1, const void *opc2)
  337. {
  338. register unsigned short *pntr;
  339. register unsigned short    a, b, c;
  340.  
  341. a = *(unsigned short *)opc1;
  342. pntr = (unsigned short *)opc2;
  343. b = *pntr++;
  344. c = *pntr;
  345. return ((c < a ? (int)1L : (int)0L) - (a < b ? (int)1L : (int)0L));
  346. }
  347.  
  348. /* ExecuteInstructionsGO: executes a conventional instruction of the
  349. simulated program, updating only the Dump window */
  350.  
  351. void ExecuteInstructionsGO(void)
  352. {
  353. enum {
  354. kMAX_COMPUTE = 120L
  355. };
  356.  
  357. register unsigned long    tickc;
  358. register unsigned long    interval;
  359. register short value;
  360. register Boolean    mslflag, hasPaused;
  361.  
  362. tickc = TickCount();
  363. do {
  364.     gParts[kP_INCR - kFIRST_PICT] = gParts[kP_MPC - kFIRST_PICT] + 1;
  365.     mir = gCsMemory[gParts[kP_MPC - kFIRST_PICT]];
  366.     gParts[kP_ALATCH - kFIRST_PICT] = gRegs[mir.bits.a];
  367.     gParts[kP_BLATCH - kFIRST_PICT] = gRegs[mir.bits.b];
  368.     value = AMUX();
  369.     gParts[kP_AMUX - kFIRST_PICT] = value;
  370.     switch(mir.bits.alu) {
  371.         case 1:    value += gParts[kP_BLATCH - kFIRST_PICT];
  372.             break;
  373.         case 2:    value &= gParts[kP_BLATCH - kFIRST_PICT];
  374.             break;
  375.         case 3:    value = ~value;
  376.             break;
  377.         }
  378.     gParts[kP_ALU - kFIRST_PICT] = value;
  379.     switch(mir.bits.shift) {
  380.         case 1: value <<= 1;
  381.             break;
  382.         case 2: value = (unsigned short)value >> 1;
  383.             break;
  384.         case 3: value >>= 1;
  385.         }
  386.     gParts[kP_SHIFTER - kFIRST_PICT] = value;
  387.     if (mir.bits.mar)
  388.         gParts[kP_MAR - kFIRST_PICT] = gParts[kP_BLATCH - kFIRST_PICT];
  389.     if (mir.bits.dsc == 0)
  390.         gRegs[mir.bits.c] = value;
  391.     if (mir.bits.mbr)
  392.         gParts[kP_MBR - kFIRST_PICT] = value;
  393.     gParts[kP_MPC - kFIRST_PICT] = gParts[kP_MMUX - kFIRST_PICT] = MMUX();
  394.     hasPaused = memory();
  395.     if (mir.bits.map) {
  396.         gRegs[kREG_EXT12] = gRegs[kREG_IR] << 4;
  397.         gRegs[kREG_EXT12] >>= 4;
  398.         gRegs[kREG_EXT11] = gRegs[kREG_IR] << 5;
  399.         gRegs[kREG_EXT11] >>= 5;
  400.         gRegs[kREG_LOW8] = gRegs[kREG_IR] & 0x00FF;
  401.         gParts[kP_MPC - kFIRST_PICT] = *(gAssMemory + *(Byte *)&gRegs[kREG_IR]);
  402.         }
  403.     interval = TickCount() - tickc;
  404.     }
  405. while ((gParts[kP_MPC - kFIRST_PICT]) && (interval < kMAX_COMPUTE));
  406. if (gPrefs.infLoopsDetect && (hasPaused == false) && (interval >= kMAX_COMPUTE) && gParts[kP_MPC - kFIRST_PICT]) {
  407.     (void)StopAlert_AE(kALRT_INFLOOP, myStdFilterProcNoCancel, myIdleFunct);
  408.     StopIt();
  409.     }
  410. }
  411.  
  412. /* ZoomEffectMap2MPC: the hardware decoding unit is modifying
  413. the Micro Program Counter; let the user have a visual feedback */
  414.  
  415. static void ZoomEffectMap2MPC(void)
  416. {
  417. GrafPtr    savePort;
  418. Rect    mapRect, mpcRect;
  419. register PicHandle    tempPH;
  420.  
  421. GetPort(&savePort);
  422. SetPort(gWPtr_Animation);
  423. tempPH = images[kP_MAP - kFIRST_PICT];
  424. if (*tempPH == nil)
  425.     LoadResource((Handle)tempPH);
  426. mapRect = (*tempPH)->picFrame;
  427. tempPH = images[kP_MPC - kFIRST_PICT];
  428. if (*tempPH == nil)
  429.     LoadResource((Handle)tempPH);
  430. mpcRect = (*tempPH)->picFrame;
  431. /* zoomFactor: 5 good on a Plus, 8 on a Quadra 700 */
  432. ZoomRectToRect(&mapRect, &mpcRect, gZoomFactor);
  433. SetPort(savePort);
  434. }
  435.  
  436. /* StopIt: stops the processing */
  437.  
  438. void StopIt(void)
  439. {
  440. gRstatus = kST_STOPPED;
  441. ChangedAllRegisters();
  442. ChangedAllBoxes();
  443. }
  444.  
  445. #endif
  446.  
  447.