home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 July / macformat-026.iso / mac / Shareware City / Science / µSim 1.0 folder / source / Microprogram_Ed.c < prev    next >
Encoding:
Text File  |  1995-01-21  |  25.0 KB  |  942 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    "UtilsSys7.h"
  13. #include    "Globals.h"
  14. #include    "Animation.h"
  15. #include    "ControlStore.h"
  16. #include    "CursorBalloon.h"
  17. #include    "DoMenu.h"
  18. #include    "Main.h"
  19. #include    "Microprogram_Ed.h"
  20. #include    "SimAsm.h"
  21. #include    "SoundHandling.h"
  22. #include    "Independents.h"
  23.  
  24. #if defined(FabSystem7orlater)
  25.  
  26.  
  27. enum {
  28. kLEN_MIR = 4
  29. };
  30.  
  31. /* Cursor keys */
  32. enum cursorkeys {
  33. kcursLeft = 0x1c,
  34. kcursRight,
  35. kcursUp,
  36. kcursDown
  37. };
  38.  
  39. enum microedstrs {
  40. kSTR_ALUINPUT = 1,
  41. kSTR_TO
  42. };
  43.  
  44. enum {
  45. kW_STRINGS = 259
  46. };
  47.  
  48. enum busrequests {
  49. kREQ_NO = 1,
  50. kREQ_READ,
  51. kREQ_WRITE
  52. };
  53.  
  54. TEHandle TEs[2];
  55. ListHandle    Lists[2];
  56.  
  57. RectPtr    keyrects[kN_RECTS];
  58. ControlHandle    controls[kNUM_CONTROLS];
  59. ControlHandle    RadioSelected;
  60. short    keyDownDest;
  61. short    theSelection[2] = { 0, 0 };
  62. short    maxLLine[2];
  63.  
  64. static union u_mir editmir;
  65. Boolean    arrowDrawn = false;
  66. Boolean    draggedOnComments = false;
  67.  
  68. void ChangeAnim_mar(short);
  69. void ChangeAnim_mbr(short);
  70. void ChangeAnim_map(short);
  71. void ChangeAnim_amux(short);
  72. void ChangeAnim_alu(short new, short old);
  73. void ChangeAnim_cond(short new, short old);
  74. void ChangeAnim_sh(short new, short old);
  75. void ChangeAnim_busreq(short new, short old);
  76. void ChangeAnim_cbus(Boolean new, Boolean old);
  77.  
  78. /* ===============static prototypes=============== */
  79. static void SettheInputTo(TEHandle thisHandle);
  80. #define    Frame()    UnFrame()
  81. static void UnFrame(void);
  82. static void DoChar(short which, unsigned char theChar);
  83. static short StartsWith(short which, unsigned char c);
  84. static void HandleClick(TEHandle theTE, short obj);
  85. static void ChangedComment(void);
  86. static void ChangedBranchTo(void);
  87. static void ResetMirAndComment(void);
  88. static void GotDragOnComments(void);
  89.  
  90. /* =============================================== */
  91.  
  92. /* EraseArrowRect: erases the rectangle containing the arrow */
  93.  
  94. void EraseArrowRect(void)
  95. {
  96. Rect    tempRect;
  97.  
  98. tempRect.right = keyrects[kKEY_LIST]->left - klateralCellTweek + 1;
  99. tempRect.top = PRCT_T(gWPtr_Microprogram_Ed);
  100. tempRect.left = tempRect.right - karrowDistFromList - 1;
  101. tempRect.bottom = PRCT_B(gWPtr_Microprogram_Ed);
  102. EraseRect(&tempRect);
  103. arrowDrawn = false;
  104. }
  105.  
  106. /* RefreshTE: refreshes a textedit field in the window */
  107.  
  108. void RefreshTE(short whichTE)
  109. {
  110. Rect    tempRect = *keyrects[whichTE];
  111. GrafPtr    savePort;
  112.  
  113. GetPort(&savePort);
  114. SetPort(gWPtr_Microprogram_Ed);
  115. InsetRect(&tempRect, 1, 1);
  116. EraseRect(&tempRect);
  117. TEUpdate(keyrects[whichTE], TEs[whichTE]);
  118. SetPort(savePort);
  119. }
  120.  
  121. /* SetControlsFromMir: sets up the controls to reflect the
  122. micro instruction register */
  123.  
  124. void SetControlsFromMir(union u_mir oldmir)
  125. {
  126. Str255 tempS;
  127. GrafPtr    savePort;
  128.  
  129. lastCommand = kST_STOPPED;
  130. GetPort(&savePort);
  131. SetPort(gWPtr_Microprogram_Ed);
  132. SetControlValue(controls[kPOPUP_ABUS], editmir.bits.a + 1);
  133. SetControlValue(controls[kPOPUP_BBUS], editmir.bits.b + 1);
  134. if (editmir.bits.c != oldmir.bits.c) {
  135.     SetControlValue(controls[kPOPUP_CBUS], (editmir.bits.dsc ? 0 : editmir.bits.c + 2));
  136.     ChangeAnim_cbus(editmir.bits.dsc, oldmir.bits.dsc);
  137.     }
  138. if (editmir.bits.mar != oldmir.bits.mar) {
  139.     SetControlValue(controls[kCHECK_MAR], editmir.bits.mar);
  140.     ChangeAnim_mar(editmir.bits.mar);
  141.     }
  142. if (editmir.bits.mbr != oldmir.bits.mbr) {
  143.     SetControlValue(controls[kCHECK_MBR], editmir.bits.mbr);
  144.     ChangeAnim_mbr(editmir.bits.mbr);
  145.     }
  146. if ((1 + editmir.bits.rd + (editmir.bits.wr << 1)) !=
  147.     (1 + oldmir.bits.rd + (oldmir.bits.wr << 1))) {
  148.     SetControlValue(controls[kPOPUP_BUSREQ], 1 + editmir.bits.rd + (editmir.bits.wr << 1));
  149.     ChangeAnim_busreq(1 + editmir.bits.rd + (editmir.bits.wr << 1),
  150.                         1 + oldmir.bits.rd + (oldmir.bits.wr << 1));
  151.     }
  152. if (editmir.bits.shift != oldmir.bits.shift) {
  153.     SetControlValue(controls[kPOPUP_SHIFTER], editmir.bits.shift + 1);
  154.     ChangeAnim_sh(editmir.bits.shift, oldmir.bits.shift);
  155.     }
  156. if (editmir.bits.cond != oldmir.bits.cond) {
  157.     SetControlValue(controls[kPOPUP_BRANCH], editmir.bits.cond + 1);
  158.     ChangeAnim_cond(editmir.bits.cond, oldmir.bits.cond);
  159.     }
  160. if (editmir.bits.alu != oldmir.bits.alu) {
  161.     SetControlValue(controls[kPOPUP_ALU], editmir.bits.alu + 1);
  162.     ChangeAnim_alu(editmir.bits.alu, oldmir.bits.alu);
  163.     }
  164. if (editmir.bits.amux != oldmir.bits.amux) {
  165.     SetControlValue(controls[kRADIO_ABUS], 1 - editmir.bits.amux);
  166.     SetControlValue(controls[kRADIO_MBR], editmir.bits.amux);
  167.     RadioSelected = controls[kRADIO_ABUS + editmir.bits.amux];
  168.     ChangeAnim_amux(editmir.bits.amux);
  169.     }
  170. if (editmir.bits.map != oldmir.bits.map) {
  171.     SetControlValue(controls[kCHECK_ACTMAP], editmir.bits.map);
  172.     ChangeAnim_map(editmir.bits.map);
  173.     }
  174. //if (editmir.bits.addr != oldmir.bits.addr) {
  175.     MyNumToString(editmir.bits.addr, tempS);
  176.     TESetText(&tempS[1], StrLength(tempS), TEs[kKEY_BRTO]);
  177.     RefreshTE(kKEY_BRTO);
  178. //    }
  179. SetPort(savePort);
  180. }
  181.  
  182. /* da schiaffare dentro la routine successiva */
  183. const short martoActDeact[] = { kC_MAR1, kC_MAR2, kC_MAR3, kC_MAR4, 0 };
  184. const short marifnotSubc[] = { kP_MAR, kP_BLTCH2MAR1, kP_BLTCH2MAR2, 0 };
  185.  
  186. void ChangeAnim_mar(short curVal)
  187. {
  188. if (curVal) {
  189.     ActivateObjs(martoActDeact);
  190.     if (gRstatus < kST_STEPSUBCYC)
  191.         ActivateObjs(marifnotSubc);
  192.     }
  193. else {
  194.     DeactivateObjs(martoActDeact);
  195.     if (gRstatus < kST_STEPSUBCYC)
  196.         DeactivateObjs(marifnotSubc);
  197.     }
  198. }
  199.  
  200. /* da schiaffare dentro la routine successiva */
  201. const short mbrtoActDeact[] = { kC_MBR1, kC_MBR2, kC_MBR3, 0 };
  202. const short mbrifnotSubc[] = { kP_MBR, kP_SH2MBR1, kP_SH2MBR2, 0 };
  203.  
  204. void ChangeAnim_mbr(short curVal)
  205. {
  206. if (curVal) {
  207.     ActivateObjs(mbrtoActDeact);
  208.     if (gRstatus < kST_STEPSUBCYC)
  209.         ActivateObjs(mbrifnotSubc);
  210.     }
  211. else {
  212.     DeactivateObjs(mbrtoActDeact);
  213.     if (gRstatus < kST_STEPSUBCYC)
  214.         DeactivateObjs(mbrifnotSubc);
  215.     }
  216. }
  217.  
  218. /* da schiaffare dentro la routine successiva */
  219. const short maptoActDeact[] = { kP_MAP, kP_MAPREGS, 0 };
  220.  
  221. void ChangeAnim_map(short curVal)
  222. {
  223. if (gRstatus < kST_STEPSUBCYC)
  224.     if (curVal)
  225.         ActivateObjs(maptoActDeact);
  226.     else
  227.         DeactivateObjs(maptoActDeact);
  228. }
  229.  
  230. /* da schiaffare dentro la routine successiva */
  231. const short amuxtoActDeact[] = { kC_AMUX1, kC_AMUX2, kC_AMUX3, 0 };
  232. const short amuxifnotSubc[] = { kP_AMUX, kP_MBR2AMUX, 0 };    
  233. const short amuxtoDeact[] = { kP_ALTCH2AMUX, 0 };
  234. const short amux2ifnotSubc[] = { kP_MBR2AMUX, 0 };
  235. const short amuxtoAct[] = { kP_ALTCH2AMUX, kP_AMUX, 0 };
  236.  
  237. void ChangeAnim_amux(short curVal)
  238. {
  239. if (curVal) {
  240.     ActivateObjs(amuxtoActDeact);
  241.     if (gRstatus < kST_STEPSUBCYC) {
  242.         DeactivateObjs(amuxtoDeact);
  243.         ActivateObjs(amuxifnotSubc);
  244.         }
  245.     }
  246. else {
  247.     DeactivateObjs(amuxtoActDeact);
  248.     if (gRstatus < kST_STEPSUBCYC) {
  249.         ActivateObjs(amuxtoAct);
  250.         DeactivateObjs(amux2ifnotSubc);
  251.         }
  252.     }
  253. }
  254.  
  255. /* da schiaffare dentro la routine successiva */
  256. const short alutoActDeact[] = { kC_ALU1, kC_ALU2, 0 };
  257. const short aluifnotSubc[] = { kP_ALU, 0 };
  258.  
  259. void ChangeAnim_alu(short curVal, short oldVal)
  260. {
  261. if (curVal) {
  262.     if (oldVal == 0) {
  263.         ActivateObjs(alutoActDeact);
  264.         if (gRstatus < kST_STEPSUBCYC)
  265.             ActivateObjs(aluifnotSubc);
  266.         }
  267.     }
  268. else {
  269.     DeactivateObjs(alutoActDeact);
  270.     if (gRstatus < kST_STEPSUBCYC)
  271.         DeactivateObjs(aluifnotSubc);
  272.     }
  273. }
  274.  
  275. /* da schiaffare dentro la routine successiva */
  276. const short condtoActDeact[] = { kP_MSL, kC_COND1, kC_COND2, kC_MSL2MMUX1, kC_MSL2MMUX2, 0 };
  277.  
  278. void ChangeAnim_cond(short curVal, short oldVal)
  279. {
  280. if (curVal) {
  281.     if (oldVal == 0)
  282.         ActivateObjs(condtoActDeact);
  283.     }
  284. else
  285.     DeactivateObjs(condtoActDeact);
  286. }
  287.  
  288. /* da schiaffare dentro la routine successiva */
  289. const short shtoActDeact[] = { kC_SHFT1, kC_SHFT2, 0 };
  290. const short shifnotSubc[] = { kP_SHIFTER, 0 };
  291.  
  292. void ChangeAnim_sh(short curVal, short oldVal)
  293. {
  294. if (curVal) {
  295.     if (oldVal == 0) {
  296.         ActivateObjs(shtoActDeact);
  297.         if (gRstatus < kST_STEPSUBCYC)
  298.             ActivateObjs(shifnotSubc);
  299.         }
  300.     }
  301. else {
  302.     DeactivateObjs(shtoActDeact);
  303.     if (gRstatus < kST_STEPSUBCYC)
  304.         DeactivateObjs(shifnotSubc);
  305.     }
  306. }
  307.  
  308. /* da schiaffare dentro la routine successiva */
  309. const short busreqNOtoActDeact[] = { kP_MAR2MEM, kP_MBRMEM, 0 };
  310. const short busreqREADtoActDeact[] = { kC_READ1, kC_READ2, kC_READ3, 0 };
  311. const short busreqWRITEtoActDeact[] = { kC_WRITE1, kC_WRITE2, kC_WRITE3, 0 };
  312.  
  313. void ChangeAnim_busreq(short curVal, short oldVal)
  314. {
  315. switch(oldVal) {
  316.     case kREQ_NO:
  317.         if (gRstatus < kST_STEPSUBCYC)
  318.             ActivateObjs(busreqNOtoActDeact);
  319.         break;
  320.     case kREQ_READ:
  321.         DeactivateObjs(busreqREADtoActDeact);
  322.         break;
  323.     case kREQ_WRITE:
  324.         DeactivateObjs(busreqWRITEtoActDeact);
  325.     }
  326. switch(curVal) {
  327.     case kREQ_NO:
  328.         if (gRstatus < kST_STEPSUBCYC)
  329.             DeactivateObjs(busreqNOtoActDeact);
  330.         break;
  331.     case kREQ_READ:
  332.         ActivateObjs(busreqREADtoActDeact);
  333.         break;
  334.     case kREQ_WRITE:
  335.         ActivateObjs(busreqWRITEtoActDeact);
  336.     }
  337. }
  338.  
  339. /* da schiaffare dentro la routine successiva */
  340. const short cbustoActDeact3[] = { kP_SH2REGS1, kP_SH2REGS2, kP_SH2REGS3, 0 };
  341. const short cbustoActDeact1[] = { kC_DSC, 0 };
  342.  
  343. void ChangeAnim_cbus(Boolean curVal, Boolean oldVal)
  344. {
  345. if (curVal) {
  346.     if (oldVal == false) {
  347.         if (gRstatus < kST_STEPSUBCYC)
  348.             DeactivateObjs(cbustoActDeact3);
  349.         ActivateObjs(cbustoActDeact1);
  350.         }
  351.     }
  352. else if (oldVal) {
  353.     if (gRstatus < kST_STEPSUBCYC)
  354.         ActivateObjs(cbustoActDeact3);
  355.     DeactivateObjs(cbustoActDeact1);
  356.     }
  357. }
  358.  
  359. /* SettheInputTo: the input TextEdit field has changed */
  360.  
  361. static void SettheInputTo(TEHandle thisHandle)
  362. {
  363. if (gTheInput)
  364.     TEDeactivate(gTheInput);
  365. if (gTheInput = thisHandle)
  366.     TEActivate(gTheInput);
  367. }
  368.  
  369. /* UnFrame: handles the standard bordering for active lists */
  370.  
  371. static void UnFrame(void)
  372. {
  373. Rect    selectRect;
  374. RgnHandle    insideRgn, outsideRgn;
  375.  
  376. selectRect = *keyrects[keyDownDest];
  377. insideRgn = NewRgn();
  378. if (insideRgn) {
  379.     outsideRgn = NewRgn();
  380.     if (outsideRgn) {
  381.         RectRgn(insideRgn, &selectRect);
  382.         InsetRect(&selectRect, -4, -4);
  383.         RectRgn(outsideRgn, &selectRect);
  384.         DiffRgn(outsideRgn, insideRgn, outsideRgn);
  385.         InvalRgn(outsideRgn);
  386.         DisposeRgn(outsideRgn);
  387.         }
  388.     DisposeRgn(insideRgn);
  389.     }
  390. }
  391.  
  392. /* HandleClick: the user has clicked in a list or editable text */
  393.  
  394. static void HandleClick(TEHandle theTE, short obj)
  395. {
  396. if (keyDownDest != obj) {
  397.     if (keyDownDest >= kKEY_LIST)
  398.         UnFrame();
  399.     SettheInputTo(theTE);
  400.     if ((keyDownDest = obj) >= kKEY_LIST)
  401.         Frame();
  402.     }
  403. }
  404.  
  405. void Update_Microprogram_Ed(WindowPtr w)
  406. {
  407. PenState    curPen;
  408. Rect    tempRect;
  409. Rect    tempRectInstr;
  410. WindowPtr    f = FrontWindow();
  411. register Handle    tempH;
  412.  
  413. TextFont(systemFont);
  414. TextSize(12);
  415. HLock(tempH = Get1Resource('STR#', kW_STRINGS));
  416. MoveTo(keyrects[kKEY_STRINGS]->left, keyrects[kKEY_STRINGS]->top);
  417. DrawString((ConstStr255Param)GetPtrIndHString(tempH, kSTR_ALUINPUT - 1));
  418. MoveTo(keyrects[kKEY_STRINGS]->right, keyrects[kKEY_STRINGS]->bottom);
  419. DrawString((ConstStr255Param)GetPtrIndHString(tempH, kSTR_TO - 1));
  420. HUnlock(tempH);
  421. FrameRect(keyrects[kKEY_COMMENT]);
  422. FrameRect(keyrects[kKEY_BRTO]);
  423. tempRect = *keyrects[kKEY_LIST];
  424. tempRect.right -= kScrollbarAdjust;
  425. InsetRect(&tempRect, -1, -1);
  426. FrameRect(&tempRect);
  427. tempRectInstr = *keyrects[kKEY_INSTR];
  428. tempRectInstr.right -= kScrollbarAdjust;
  429. InsetRect(&tempRectInstr, -1, -1);
  430. FrameRect(&tempRectInstr);
  431.  
  432. GetPenState(&curPen);
  433. PenNormal();
  434. PenSize(2, 2);
  435. if (keyDownDest != kKEY_INSTR || w != f)
  436.     PenMode(patBic);
  437. tempRectInstr.right += kScrollbarAdjust;
  438. InsetRect(&tempRectInstr, -3, -3);
  439. FrameRect(&tempRectInstr);
  440. PenMode(keyDownDest == kKEY_LIST && w == f ? patCopy : patBic);
  441. tempRect.right += kScrollbarAdjust;
  442. InsetRect(&tempRect, -3, -3);
  443. FrameRect(&tempRect);
  444. SetPenState(&curPen);
  445.  
  446. TextFont(geneva);
  447. TextSize(9);
  448. LUpdate(w->visRgn, Lists[kL_INSTR]);
  449. LUpdate(w->visRgn, Lists[kL_COMMENTS]);
  450. RefreshTE(kKEY_BRTO);
  451. RefreshTE(kKEY_COMMENT);
  452. UpdateControls(w, w->visRgn);
  453. }
  454.  
  455. /* PrepareOpenMicroprogram: we hilite some objects before
  456. showing up the window */
  457.  
  458. /* da schiaffare dentro la routine successiva */
  459. const short toBeMoreClear[] = { kP_AMUX2ALU, kP_ALU2SH, kP_REG2LTCH1, kP_REG2LTCH2,
  460.                     kP_BLTCH2ALU, kP_CST2MIR, kC_ABC1, kC_ABC2, kC_ABC3, kC_ABC4, 0 };
  461.  
  462. void PrepareOpenMicroprogram(void)
  463. {
  464. if (((WindowPeek)gWPtr_Microprogram_Ed)->visible == false)
  465.     ActivateObjs(toBeMoreClear);
  466. }
  467.  
  468. void Activate_Microprogram_Ed(EventRecord *, WindowPtr , Boolean Do_An_Activate)
  469. {
  470.  
  471. LActivate(Do_An_Activate, Lists[kL_COMMENTS]);
  472. LActivate(Do_An_Activate, Lists[kL_INSTR]);
  473. if (Do_An_Activate) {
  474.     if (keyDownDest < kKEY_LIST)
  475.         SettheInputTo(TEs[keyDownDest]);
  476.     else
  477.         Frame();
  478.     }
  479. else {
  480.     if (keyDownDest >= kKEY_LIST)
  481.         UnFrame();
  482.     else
  483.         SettheInputTo(nil);
  484.     }
  485. }
  486.  
  487. /* Microprog_TextWasModified: tells us that a text field has been modified */
  488.  
  489. void Microprog_TextWasModified(void)
  490. {
  491. if (gTheInput == TEs[kKEY_COMMENT])
  492.     ChangedComment();
  493. else if (gTheInput == TEs[kKEY_BRTO])
  494.     ChangedBranchTo();
  495. DocumentIsDirty(true);
  496. }
  497.  
  498. /* ChangedComment: the comment field has changed */
  499.  
  500. static void ChangedComment(void)
  501. {
  502. register Handle    typedText;
  503. register Point    tempCell;
  504. register SignedByte    savedState;
  505.  
  506. tempCell.h = 0;
  507. tempCell.v = theSelection[kL_COMMENTS];
  508. savedState = WantThisHandleSafe(typedText = (Handle)TEGetText(TEs[kKEY_COMMENT]));
  509. LSetCell(*typedText, InlineGetHandleSize(typedText), tempCell, Lists[kL_COMMENTS]);
  510. HSetState(typedText, savedState);
  511. }
  512.  
  513. /* ChangedBranchTo: the branch to… field has changed */
  514.  
  515. static void ChangedBranchTo(void)
  516. {
  517. Str255    tempS;
  518. Size    tSize = 0L;
  519. register union u_mir    tempMir;
  520.  
  521. GetDialogItemText(TEGetText(TEs[kKEY_BRTO]), tempS);
  522. if (tempS[0] != 0)
  523.     StringToNum(tempS, &tSize);
  524. /* …stuff it into the micro instruction */
  525. tempMir = editmir;
  526. tempMir.bits.addr = tSize;
  527. SetMir(tempMir.cstore);
  528. }
  529.  
  530. /* ChangedListSelection: the selection in a list has changed */
  531.  
  532. void ChangedListSelection(Point newCell, short which, Boolean inCkLoop)
  533. {
  534. Str255    tempS;
  535. GrafPtr    savePort;
  536. register ROpcodePtr    myOpcodePtr;
  537. Point instr;
  538. short    length;
  539.  
  540. GetPort(&savePort);
  541. SetPort(gWPtr_Microprogram_Ed);
  542. if (which == kL_COMMENTS) {
  543.     if (inCkLoop) {
  544. /* we must update the associative memory… */
  545.         *(long *)&instr = 0L;
  546.         if (LGetSelect(true, &instr, Lists[kL_INSTR])) {
  547.             register Byte i;
  548.  
  549.             myOpcodePtr = ((ROpcodePtr)(((short *)*Get1Resource(krInstructions, kOPCODES)) + 1))
  550.                             + instr.v;
  551.             for (i = myOpcodePtr->offsetHB; i <= myOpcodePtr->lastHB; i++)
  552.                 *(gAssMemory + i) = newCell.v;
  553.             }
  554.         }
  555. /* …and update the control store memory */
  556. /*    *(csMemory + theSelection[kL_COMMENTS]) = editmir;*/
  557. /* get cell contents and put into TextEdit field */
  558.     length = 255;    /* maximum length of text */
  559.     LGetCell(&tempS, &length, newCell, Lists[kL_COMMENTS]);
  560.     TESetText(&tempS, length, TEs[kKEY_COMMENT]);
  561.     RefreshTE(kKEY_COMMENT);
  562.     theSelection[which] = newCell.v;
  563. /* load the micro instruction we must edit from control store memory */
  564.     SetMir((*(gCsMemory + newCell.v)).cstore);
  565.     }
  566. else {    /* instruction list */
  567.     myOpcodePtr = ((ROpcodePtr)(((short *)*Get1Resource(krInstructions, kOPCODES))+1))
  568.                     + newCell.v;
  569.     if (*(gAssMemory + myOpcodePtr->offsetHB) != theSelection[kL_COMMENTS])
  570. /* the selected instruction is associated to a "comment" not selected */
  571.         SelectLLine(kL_COMMENTS, *(gAssMemory + myOpcodePtr->offsetHB));
  572.     }
  573. theSelection[which] = newCell.v;
  574. SetPort(savePort);
  575. }
  576.  
  577. void Do_Microprogram_Ed(WindowPtr w, EventRecord *theEvent)
  578. {
  579. Rect    tempRect;
  580. union u_mir    oldmir;
  581. Point    myPt;
  582. ControlHandle    theControl;
  583. register Boolean    DoubleClick, selectionFound;
  584.  
  585. myPt = theEvent->where;
  586. GlobalToLocal(&myPt);
  587. /* click in comment TE */
  588. if (PtInRect(myPt, keyrects[kKEY_COMMENT])) {
  589.     HandleClick(TEs[kKEY_COMMENT], kKEY_COMMENT);
  590.     TEClick(myPt, (theEvent->modifiers & shiftKey) != 0, TEs[kKEY_COMMENT]);
  591.     }
  592. /* click in branch to line TE */
  593. else if (PtInRect(myPt, keyrects[kKEY_BRTO])) {
  594.     HandleClick(TEs[kKEY_BRTO], kKEY_BRTO);
  595.     TEClick(myPt, (theEvent->modifiers & shiftKey) != 0, TEs[kKEY_BRTO]);
  596.     }
  597. else {
  598.     tempRect = *keyrects[kKEY_LIST];
  599.     InsetRect(&tempRect, -1, -1);
  600. /* click in comment list */
  601.     if (PtInRect(myPt, &tempRect)) {
  602.         HandleClick(nil, kKEY_LIST);
  603.         if (theEvent->modifiers & cmdKey)
  604.             SetCursor(*GetCursor(plusCursor));
  605.         DoubleClick = LClick(myPt, theEvent->modifiers, Lists[kL_COMMENTS]);
  606.         EraseArrowRect();
  607.         *(long *)(&myPt) = 0L;
  608.         selectionFound = LGetSelect(true, &myPt, Lists[kL_COMMENTS]);
  609.         if (theEvent->modifiers & cmdKey) {
  610.             oldmir = editmir;
  611.             oldmir.bits.addr = myPt.v;
  612.             SetMir(oldmir.cstore);
  613.             DocumentIsDirty(true);
  614.             InitCursor();
  615.             }
  616.         if (DoubleClick) {
  617.             if (editmir.bits.cond)
  618.                 SelectLLine(kL_COMMENTS, editmir.bits.addr);
  619.             }
  620.         else {
  621.             if (selectionFound) {
  622.                 if (myPt.v != theSelection[kL_COMMENTS])
  623.                     /* new item has been selected */
  624.                     ChangedListSelection(myPt, kL_COMMENTS, false);
  625.                 }
  626.             }
  627.         }
  628.     else {
  629.         tempRect = *keyrects[kKEY_INSTR];
  630.         InsetRect(&tempRect, -1, -1);
  631. /* click in instruction list */
  632.         if (PtInRect(myPt, &tempRect)) {
  633.             HandleClick(nil, kKEY_INSTR);
  634.             (void)LClick(myPt, theEvent->modifiers, Lists[kL_INSTR]);
  635.             if (draggedOnComments) {
  636.                 GotDragOnComments();
  637.                 }
  638.             tempRect = *keyrects[kKEY_INSTR];
  639.             tempRect.right -= kScrollbarAdjust;
  640.             if (PtInRect(myPt, &tempRect)) {
  641.                 *(long *)(&myPt) = 0L;
  642.                 if (LGetSelect(true, &myPt, Lists[kL_INSTR]))
  643.                     /* new item has been selected */
  644.                     ChangedListSelection(myPt, kL_INSTR, draggedOnComments);
  645.                 }
  646.             draggedOnComments = false;
  647.             ForceMouseMovedEvent();
  648.             }
  649.         else {
  650. /* click in controls */
  651.             if (FindControl(myPt, w, &theControl)) {
  652.                 oldmir = editmir;
  653.                 switch(TrackControl(theControl, myPt, (ControlActionUPP)-1L)) {
  654.                     register short newval;
  655.         
  656.                     case kInLabelControlPart:
  657.                         if (theControl == controls[kPOPUP_ABUS])
  658.                             editmir.bits.a = GetControlValue(theControl) - 1;
  659.                         else if (theControl == controls[kPOPUP_BBUS])
  660.                             editmir.bits.b = GetControlValue(theControl) - 1;
  661.                         else if (theControl == controls[kPOPUP_CBUS]) {
  662.                             if (editmir.bits.c != (newval = (GetControlValue(theControl)-2))) {
  663.                                 ChangeAnim_cbus(newval < 0, editmir.bits.dsc);
  664.                                 editmir.bits.c = newval;
  665.                                 editmir.bits.dsc = newval < 0;
  666.                                 }
  667.                             }
  668.                         else if (theControl == controls[kPOPUP_BUSREQ]) {
  669.                             register short newvalrd, newvalwr;
  670.         
  671.                             newvalrd = ((newval = GetControlValue(theControl)) == kREQ_READ);
  672.                             newvalwr = (newval == kREQ_WRITE);
  673.                             if ((editmir.bits.rd != newvalrd)||(editmir.bits.wr != newvalwr)) {
  674.                                 ChangeAnim_busreq(newval, 1 + editmir.bits.rd + (editmir.bits.wr << 1));
  675.                                 editmir.bits.rd = newvalrd;
  676.                                 editmir.bits.wr = newvalwr;
  677.                                 }
  678.                             }
  679.                         else if (theControl == controls[kPOPUP_SHIFTER]) {
  680.                             if (editmir.bits.shift != (newval = (GetControlValue(theControl)-1))) {
  681.                                 ChangeAnim_sh(newval, editmir.bits.shift);
  682.                                 editmir.bits.shift = newval;
  683.                                 }
  684.                             }
  685.                         else if (theControl == controls[kPOPUP_BRANCH]) {
  686.                             if (editmir.bits.cond != (newval = (GetControlValue(theControl)-1))) {
  687.                                 ChangeAnim_cond(newval, editmir.bits.cond);
  688.                                 editmir.bits.cond = newval;
  689.                                 }
  690.                             }
  691.                         else if (theControl == controls[kPOPUP_ALU]) {
  692.                             if (editmir.bits.alu != (newval = (GetControlValue(theControl)-1))) {
  693.                                 ChangeAnim_alu(newval, editmir.bits.alu);
  694.                                 editmir.bits.alu = newval;
  695.                                 }
  696.                             }
  697.                         break;
  698.                     case kInCheckBoxControlPart:
  699.                         if (theControl == controls[kRADIO_ABUS] || theControl == controls[kRADIO_MBR]) {
  700.                             if (RadioSelected != theControl) {
  701.                                 SetControlValue(RadioSelected, 0);
  702.                                 SetControlValue(theControl, 1);
  703.                                 RadioSelected = theControl;
  704.                                 ChangeAnim_amux(editmir.bits.amux = GetControlValue(controls[kRADIO_MBR]));
  705.                                 }
  706.                             }
  707.                         else {    
  708.                             SetControlValue(theControl, newval = (1 - GetControlValue(theControl)));
  709.                             if (theControl == controls[kCHECK_MAR]) {
  710.                                 editmir.bits.mar = newval;
  711.                                 ChangeAnim_mar(newval);
  712.                                 }
  713.                             else if (theControl == controls[kCHECK_MBR]) {
  714.                                 editmir.bits.mbr = newval;
  715.                                 ChangeAnim_mbr(newval);
  716.                                 }
  717.                             else if (theControl == controls[kCHECK_ACTMAP]) {
  718.                                 editmir.bits.map = newval;
  719.                                 ChangeAnim_map(newval);
  720.                                 }
  721.                             }
  722.                     }
  723.                 if (editmir.cstore != oldmir.cstore) {
  724.                     UpdateMir(editmir);
  725.                     /* …and update the control store memory */
  726.                     *(gCsMemory + theSelection[kL_COMMENTS]) = editmir;
  727.                     DocumentIsDirty(true);
  728.                     }
  729.                 }
  730.             }
  731.         }
  732.     }
  733. }
  734.  
  735. void Key_Microprogram_Ed(EventRecord *theEvent, Boolean ignoreChar)
  736. {
  737. enum {
  738. kTabKey = 9
  739. };
  740.  
  741. GrafPtr    savePort;
  742. register unsigned char    ch;
  743.  
  744. GetPort(&savePort);
  745. SetPort(gWPtr_Microprogram_Ed);
  746. if ((ch = CHARFROMMESSAGE(theEvent->message)) == kTabKey) {
  747.     if (keyDownDest >= kKEY_LIST)
  748.         UnFrame();
  749.     keyDownDest = (theEvent->modifiers & shiftKey ?
  750.                     (keyDownDest == kKEY_INSTR ? kKEY_BRTO : keyDownDest + 1) :
  751.                     (keyDownDest == kKEY_BRTO ? kKEY_INSTR : keyDownDest - 1));
  752.     if (keyDownDest < kKEY_LIST) {
  753.         SettheInputTo(TEs[keyDownDest]);
  754.         TESetSelect(0, SHRT_MAX, gTheInput);
  755.         }
  756.     else {
  757.         SettheInputTo(nil);
  758.         Frame();
  759.         }
  760.     }
  761. else if (gTheInput) {
  762.     if (ignoreChar == false)
  763.         TEKey(ch, gTheInput);
  764.     if ((ch < kcursLeft)||(ch > kcursDown))
  765.         Microprog_TextWasModified();
  766.     }
  767. else if (keyDownDest >= kKEY_LIST)
  768.     DoChar(keyDownDest - 2, ch);
  769. SetPort(savePort);
  770. }
  771.  
  772. static void DoChar(short item, unsigned char theChar)
  773. {
  774. register short    newSelect;
  775.  
  776. /* Take the char, and find the first line that starts with this char. */
  777. if ((newSelect = StartsWith(item, theChar)) != theSelection[item])
  778.     /* We've moved. Unhighlight the old. */
  779.     SelectLLine(item, newSelect);
  780. }
  781.  
  782. static short StartsWith(short elem, unsigned char c)
  783. {
  784. /* Check for cursor up, down. */
  785. if (c == kcursDown) {
  786.     /* Go up one, clamp at the end. */
  787.     return ((theSelection[elem] == maxLLine[elem]) ? theSelection[elem] :
  788.                 theSelection[elem] + 1);
  789.     }
  790. if (c == kcursUp) {
  791.     /* Go down one, clamp at the bottom. */
  792.     return((theSelection[elem] == 0) ? 0 : theSelection[elem] - 1);
  793.     }
  794. return (maxLLine[elem]);
  795. }
  796.  
  797. /* ResetMirAndComment: reset the micro instruction register and comment field */
  798.  
  799. static void ResetMirAndComment(void)
  800. {
  801. short    null = 0;
  802.  
  803. TESetText(&null, 0, TEs[kKEY_COMMENT]);
  804. RefreshTE(kKEY_COMMENT);
  805. ChangedComment();
  806. SetMir(0L);
  807. DocumentIsDirty(true);
  808. }
  809.  
  810. /* SendClipMsg: handle a clipboard request from the user */
  811.  
  812. OSErr SendClipMsg(short msg)
  813. {
  814. unsigned long    dataOffset;
  815. register long    length;
  816. register Handle    typedText;
  817. register SignedByte    savedState;
  818.  
  819. switch (msg) {
  820.     case kCLIPMSG_CUT:
  821.         if ((length = ZeroScrap()) == noErr)
  822.             if ((length = PutScrap(kLEN_MIR, kFCR_MINE, (Ptr)&editmir)) == noErr) {
  823.                 savedState = WantThisHandleSafe(typedText = (Handle)TEGetText(TEs[kKEY_COMMENT]));
  824.                 length = PutScrap(InlineGetHandleSize(typedText), 'TEXT', *typedText);
  825.                 HSetState(typedText, savedState);
  826.                 if (length == noErr) {
  827.                     (void)TEFromScrap();
  828.                     ResetMirAndComment();
  829.                     }
  830.                 }
  831.         break;
  832.     case kCLIPMSG_COPY:
  833.         if ((length = ZeroScrap()) == noErr)
  834.             if ((length = PutScrap(kLEN_MIR, kFCR_MINE, (Ptr)&editmir)) == noErr) {
  835.                 savedState = WantThisHandleSafe(typedText = (Handle)TEGetText(TEs[kKEY_COMMENT]));
  836.                 length = PutScrap(InlineGetHandleSize(typedText), 'TEXT', *typedText);
  837.                 HSetState(typedText, savedState);
  838.                 (void)TEFromScrap();
  839.                 }
  840.         break;
  841.     case kCLIPMSG_PASTE:
  842.         typedText = NewHandle(0);
  843.         if ((length = GetScrap(typedText, kFCR_MINE, (long *)&dataOffset)) == kLEN_MIR) {
  844.             SetMir(*(unsigned long *)*typedText);
  845.             DocumentIsDirty(true);
  846.             if ((length = GetScrap(typedText, 'TEXT', (long *)&dataOffset)) >= 0L) {
  847.                 savedState = WantThisHandleSafe(typedText);
  848.                 TESetText(*typedText, length, TEs[kKEY_COMMENT]);
  849.                 HSetState(typedText, savedState);
  850.                 RefreshTE(kKEY_COMMENT);
  851.                 ChangedComment();
  852.                 }
  853.             }
  854.         DisposeHandle(typedText);
  855.         break;
  856.     case kCLIPMSG_CLEAR:
  857.         ResetMirAndComment();
  858.         length = 0L;
  859.         break;
  860.     }
  861. return(((length < 0) && (length != noTypeErr)) ? length : noErr);
  862. }
  863.  
  864. /* SelectLLine: selects a specified line in a list */
  865.  
  866. void SelectLLine(short whichList, short newSelect)
  867. {
  868. Point    cell;
  869.  
  870. cell.h = 0;
  871. cell.v = theSelection[whichList];
  872. LSetSelect(false, cell, Lists[whichList]);
  873. cell.v = newSelect;
  874. LSetSelect(true, cell, Lists[whichList]);
  875. LAutoScroll(Lists[whichList]);
  876. ChangedListSelection(cell, whichList, false);
  877. }
  878.  
  879. /* SetMir: calls UpdateMir and updates the document (Microprogram Editor) window */
  880.  
  881. void SetMir(unsigned long newmir)
  882. {
  883. union u_mir    oldmir;
  884.  
  885. oldmir = editmir;
  886. editmir.cstore = newmir;
  887. UpdateMir(editmir);
  888. /* …and update the control store memory */
  889. *(gCsMemory + theSelection[kL_COMMENTS]) = editmir;
  890. SetControlsFromMir(oldmir);
  891. }
  892.  
  893.  
  894. /* procedure called when closing the MPrg window */
  895.  
  896. void CloseMicroProg(WindowPtr w)
  897. {
  898. DoCloseWindow(w, kMItem_Microprogram);
  899. }
  900.  
  901. void GotDragOnComments(void)
  902. {
  903. Rect    tempRect;
  904. Point    curMouse;
  905. register ListHandle    theList;
  906. register ListClickLoopUPP    savedLCkLoopUPP;
  907. register Boolean    wasLinked;
  908.  
  909. tempRect = *keyrects[kKEY_LIST];
  910. tempRect.right -= kScrollbarAdjust;
  911. SetCursor(*GetCursor(kSheetsCursor));
  912. GetMouse(&curMouse);
  913. theList = Lists[kL_COMMENTS];
  914. savedLCkLoopUPP = (*theList)->lClickLoop;
  915. (*theList)->lClickLoop = gSwitchCursClikLoopUPP;
  916.  
  917. (void)LClick(curMouse, gMyEvent.modifiers, theList);
  918. (*theList)->lClickLoop = savedLCkLoopUPP;
  919. GetMouse(&curMouse);
  920. wasLinked = PtInRect(curMouse, &tempRect);
  921. *(long *)&curMouse = 0L;
  922. if(LGetSelect(true, &curMouse, theList)) {
  923.     if (wasLinked) {
  924.         SetCursor(*GetCursor(kLinkedSheetsCursor));
  925.         DoSound(kSndPinzatrice);
  926.         DocumentIsDirty(true);
  927.         ChangedListSelection(curMouse, kL_COMMENTS, true);
  928.         }
  929.     else {
  930.         LSetSelect(false, curMouse, theList);
  931.         curMouse.h = 0;
  932.         curMouse.v = theSelection[kL_COMMENTS];
  933.         LSetSelect(true, curMouse, theList);
  934.         SysBeep(30);
  935.         }
  936.     }
  937. InitCursor();
  938. }
  939.  
  940. #endif
  941.  
  942.