'The following is an FSMC code fragment. You must complete the specification. 'CLK /MARCAR F2 GOSYNC F1 F0 FLAG 'RAMLREG NC NC NC GND NC NC 'Q0 Q1 Q2 /MARLOAD /MARCNT /DOWNCNT /REGLOAD '/WE NC VCC '/MARCAR F2 GOSYNC F1 F0 FLAG RAMLREG '/MARCNT Q0 Q1 Q2 GND NC NC 'NC /MARCNT3 /MARCNT2 /REGTORAM /SWTTORAM CLRFLAG SETFLAG 'NC NC VCC begin_p negative MARLOAD@18, MARCNT@19, DOWNCNT@20, MARCAR@2, REGLOAD@21, WE@22, negative REGTORAM@118, SWTTORAM@119, MARCNT2@117, MARCNT3@116, REGLOAD2@115; positive CLRFLAG@120, SETFLAG@121; device 20v8; MARCNT3 = MARCNT + MARCNT2; end_p 'This is the Idle state, where the machine sits when it isn't doing anything. 'Note that if FLAG is set and the switches indicate that we have just done 'a FindMax, we write the swap register to RAM and back to the compare 'register. Then, we clear the flag. Idle: if (/F2 * F1 * F0) { 'Findmax routine selected if (GOSYNC) then goto ClearMar; 'Clear MAR and start FindMax. else if (FLAG) { 'Max in swap reg REGTORAM, WE; 'Send to ram REGLOAD; 'Write back to compare register CLRFLAG; 'Clear flag } else stay; } else if (GOSYNC * /F2 * /F1 * /F0) { 'Load Address selected. MARLOAD; 'Load MAR stay; } else if (GOSYNC * /F2 * /F1 * F0) { 'Examine Memory selected. REGLOAD; 'Load Register MARCNT; 'Increase MAR stay; } else if (GOSYNC * /F2 * F1 * /F0) { 'Store Selected. SWTTORAM; 'Drive Switches WE; 'Enable Writes MARCNT; 'Increase MAR stay; } else if (GOSYNC * F2) { 'No-Op Selected. goto ClearMar; 'Go To the Bubble Sort routine } else stay; 'This state is used to clear the MAR to zero before starting the FindMax 'routine. We have to do this, since the 'LS169 doesn't have a clear input. 'Note that, when we count down, MARCAR is true when MAR=0. ClearMar:DOWNCNT; 'We want the counter to count down if (/MARCAR) { 'Not at zero, MARCNT; ' so count down. stay; } else { CLRFLAG; REGLOAD; if (F2) goto StartSort; else goto FindMax; } 'Following is the FindMax routine. Note that the flag is used to maintain 'the end-of-ram condition. It is set when the mar=15. Then, the mar is 'allowed to wrap around to zero. When the flag is set, the maximum value 'will be in the compare register. Thus, we assert 'REGLOAD' to place this 'value in the swap register, then return to the idle state with the 'flag still set. The idle state will complete the process by writing 'this value back to RAM location zero and clearing the flag. 'Use of the flag is not necessary (why??). However, we are attempting 'to test all of our hardware. FindMax:if (/FLAG) { if (/RAMLREG) then REGLOAD; 'load new register value if (MARCAR) then SETFLAG; 'All done MARCNT; 'Next location stay; } else { REGLOAD; 'Send max value to swap register goto Idle; 'Will finish in idle state. } StartSort:if (RAMLREG) { '(i+1) < (i) ? REGLOAD2; 'Get (i) ready and load (i+1) goto Swap; } else if (MARCAR) { if (FLAG) { 'We Swapped something goto ClearMar; } else { goto Idle; } } else { REGLOAD2; 'Load (i+1) into Register MARCNT2; stay; } Swap: WE; 'Enable Writes REGTORAM; 'Drive Register (i) into i+1 REGLOAD2; 'Load Register with (i) DOWNCNT; 'Count Down on MAR; MARCNT2; goto Swap2; Swap2: WE; 'Enable Writes REGTORAM; 'Drive Register (i+1) into i MARCNT2; 'Count Up on MAR SETFLAG; goto StartSort;