home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / µSim 1.0.5 / source / Microprogram_Ed.c < prev    next >
Encoding:
Text File  |  1995-12-06  |  25.0 KB  |  944 lines  |  [TEXT/CWIE]

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