-- The Main State Machine -- Woo-Hoo! INPUTS : HSE ZEROFLAG NEG ERROR RESTART INST0 INST1 INST2 INST3; OUTPUTS : ADWR3 ADWR2 ADWR1 ADWR0 ADRE3 ADRE2 ADRE1 ADRE0 ALUINST2 ALUINST1 ALUINST0 ROMA1 ROMA0 ACCW ACCEN SBWR INWR INEN RFWR RFRE IRWR OUTW ROMR COLWR ALWR MEMWRITE SCENG HSI FLIPW; -- Yes, folks...that's 29 output signals and 9 input signals! RESET on RESTART to IDLE; IDLE : CASE (HSE) 1 => RCOM1(HSI INWR); ENDCASE => IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); RCOM1 : CASE (HSE) 0 => IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); ENDCASE => RCOM2(INEN IRWR); RCOM2 : GOTO RCOM3; RCOM3 : CASE (INST3 INST2 INST1 INST0) 0 0 0 0 => IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); 1 1 0 0 => IN1(HSI INWR); 1 1 0 1 => OUT1(RFRE OUTW); 1 0 0 0 => TRNN1(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); 1 0 0 1 => TRNS1(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST2=0 ALUINST1=0); 1 0 1 0 => TRNE1(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); 1 0 1 1 => TRNW1(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); 1 1 1 0 => CLR1(ROMA1=0 ROMA0=0 ROMR COLWR); 1 1 1 1 => DRW1(ADRE3=0 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); ENDCASE => IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); IN1 : CASE (HSE) 0 => IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); ENDCASE => IN2(INEN RFWR); IN2 : GOTO IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); OUT1 : CASE (HSE) 0 => LOOP; ENDCASE => IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); -- Initialize loop variables CLR1 : GOTO CLR2(ROMA1=1 ROMA0=1 ROMR RFWR ADWR3=1 ADWR2=0 ADWR1=0 ADWR0=0); CLR2 : GOTO CLR3(ROMA1=1 ROMA0=1 ROMR RFWR ADWR3=1 ADWR2=0 ADWR1=0 ADWR0=1); CLR3 : GOTO CLR4(RFRE OUTW ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=0); -- setup address values CLR4 : GOTO CLR5(ALWR); CLR5 : GOTO CLR6(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=1 RFRE OUTW); CLR6 : GOTO CLR7(MEMWRITE ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); -- write to external memory, check for termination of inside loop CLR7 : CASE (ZEROFLAG) 1 => CLRA1(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); ENDCASE => CLR8(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=1 ALUINST0=1); -- loop not terminated, lcv--, jump back to top CLR8 : GOTO CLR9(RFWR ACCEN ADWR3=1 ADWR2=0 ADWR1=0 ADWR0=1); CLR9 : GOTO CLR6(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=1 RFRE OUTW); -- inside loop terminated, check for outside loop termination CLRA1 : GOTO CLRA2; CLRA2 : CASE (ZEROFLAG) 1 => IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); ENDCASE => CLRA3(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=1 ALUINST0=1); -- outside loop not terminated, lcv--, jump to top, reinit inner loop CLRA3 : GOTO CLRA4(ACCEN RFWR ADWR3=1 ADWR2=0 ADWR1=0 ADWR0=0); CLRA4 : GOTO CLR3(ROMA1=1 ROMA0=1 ROMR RFWR ADWR3=1 ADWR2=0 ADWR1=0 ADWR0=1); -- Translate instructions. One opcode per direction. translated by value stored in ARG -- translate north (Y1=Y1+ARG, Y2=Y2+ARG) TRNN1 : GOTO TRNN2(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=0); TRNN2 : GOTO TRNN3; TRNN3 : CASE (ERROR) 1 => TRNER1(ADRE3=0 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); ENDCASE => TRNN4(ADWR3=0 ADWR2=0 ADWR1=0 ADWR0=1 RFWR ACCEN); TRNN4 : GOTO TRNN5(ADRE3=0 ADRE2=0 ADRE1=1 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); TRNN5 : GOTO TRNN6(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=0); TRNN6 : GOTO TRNN7; TRNN7 : CASE (ERROR) 1 => TRNER1(ADRE3=0 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); ENDCASE => TRNN8(ADWR3=0 ADWR2=0 ADWR1=1 ADWR0=1 RFWR ACCEN); TRNN8 : GOTO IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); -- translate south (Y1=Y1-ARG, Y2=Y2-ARG) TRNS1 : GOTO TRNS2(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=1); TRNS2 : GOTO TRNS3; TRNS3 : CASE (ERROR) 1 => TRNER1(ADRE3=0 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); ENDCASE => TRNS4(ADWR3=0 ADWR2=0 ADWR1=0 ADWR0=1 RFWR ACCEN); TRNS4 : GOTO TRNS5(ADRE3=0 ADRE2=0 ADRE1=1 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); TRNS5 : GOTO TRNS6(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=1); TRNS6 : GOTO TRNS7; TRNS7 : CASE (ERROR) 1 => TRNER1(ADRE3=0 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); ENDCASE => TRNS8(ADWR3=0 ADWR2=0 ADWR1=1 ADWR0=1 RFWR ACCEN); TRNS8 : GOTO IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); -- translate east (X1=X1+ARG, X2=X2+ARG) TRNE1 : GOTO TRNE2(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=0); TRNE2 : GOTO TRNE3; TRNE3 : CASE (ERROR) 1 => TRNER1(ADRE3=0 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); ENDCASE => TRNE4(ADWR3=0 ADWR2=0 ADWR1=0 ADWR0=0 RFWR ACCEN); TRNE4 : GOTO TRNE5(ADRE3=0 ADRE2=0 ADRE1=1 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); TRNE5 : GOTO TRNE6(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=0); TRNE6 : GOTO TRNE7; TRNE7 : CASE (ERROR) 1 => TRNER1(ADRE3=0 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); ENDCASE => TRNE8(ADWR3=0 ADWR2=0 ADWR1=1 ADWR0=0 RFWR ACCEN); TRNE8 : GOTO IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); -- translate west (X1=X1-ARG, X2=X2-ARG) TRNW1 : GOTO TRNW2(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=1); TRNW2 : GOTO TRNW3; TRNW3 : CASE (ERROR) 1 => TRNER1(ADRE3=0 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); ENDCASE => TRNW4(ADWR3=0 ADWR2=0 ADWR1=0 ADWR0=0 RFWR ACCEN); TRNW4 : GOTO TRNW5(ADRE3=0 ADRE2=0 ADRE1=1 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); TRNW5 : GOTO TRNW6(ADRE3=1 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=1); TRNW6 : GOTO TRNW7; TRNW7 : CASE (ERROR) 1 => TRNER1(ADRE3=0 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); ENDCASE => TRNW8(ADWR3=0 ADWR2=0 ADWR1=1 ADWR0=0 RFWR ACCEN); TRNW8 : GOTO IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); -- Handle errors by marking error flag on object TRNER1 : GOTO TRNER2(ROMA1=1 ROMA0=0 ROMR ACCW ALUINST2=1 ALUINST1=0 ALUINST0=0); TRNER2 : GOTO TRNER3(ADWR3=0 ADWR2=1 ADWR1=0 ADWR0=0 RFWR ACCEN); TRNER3 : GOTO IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); -------------------- -- Line Draw Unit -- -------------------- -- check whether object drawable. if not, abort. DRW1 : GOTO DRW2(ADRE3=0 ADRE2=1 ADRE1=0 ADRE0=0 RFRE COLWR ALUINST2=0 ALUINST1=0 ALUINST0=0); DRW2 : GOTO DRW3(ROMA1=1 ROMA0=0 ROMR ALUINST2=1 ALUINST1=1 ALUINST0=0); DRW3 : GOTO DRW4; DRW4 : CASE (ZEROFLAG) 0 => IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); ENDCASE => DRW5(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); -- Calculate DX DRW5 : GOTO DRW6(ADRE3=0 ADRE2=0 ADRE1=1 ADRE0=0 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=1); DRW6 : GOTO DRW7(RFWR ACCEN SBWR ADWR3=1 ADWR2=1 ADWR1=0 ADWR0=0); DRW7 : GOTO DRW8(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST0=0 ALUINST1=0 ALUINST0=0); -- Calculate DY DRW8 : GOTO DRW9(ADRE3=0 ADRE2=0 ADRE1=1 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); DRW9 : GOTO DRW10(ACCEN RFWR SBWR ADWR3=1 ADWR2=1 ADWR1=0 ADWR0=1); DRW10 : GOTO DRW11(ADRE3=1 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=1); -- Decide whether X or Y is to be iterated across (set FLIP bit) DRW11 : GOTO DRW12; DRW12 : CASE (NEG) 1 => DRWF1(FLIPW ROMR ROMA1=0 ROMA0=1); ENDCASE => DRW13(ADRE3=1 ADRE2=1 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=1); -- Proceed with line draw initialization DRW13 : GOTO DRW14(ACCEN RFWR SBWR ADWR3=1 ADWR2=1 ADWR1=0 ADWR0=1); DRW14 : GOTO DRW15(ADRE3=1 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=1); DRW15 : GOTO DRW16(ACCEN SBWR RFWR ADWR3=1 ADWR2=1 ADWR1=1 ADWR0=0); DRW16 : GOTO DRW17(ADRE3=1 ADRE2=1 ADRE1=0 ADRE0=0 RFRE RFWR ADWR3=1 ADWR2=1 ADWR1=1 ADWR0=1); DRW17 : GOTO DRW18(ADRE3=1 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=1); DRW18 : GOTO DRW19(ACCEN SBWR RFWR ADWR3=1 ADWR2=1 ADWR1=0 ADWR0=0); DRW19 : GOTO DRW20(ADRE3=1 ADRE2=1 ADRE1=1 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); -- Check terminate condition for linedraw DRW20 : GOTO DRW21; DRW21 : CASE (ZEROFLAG) 1 => IDLE(SCENG FLIPW ROMR ROMA1=0 ROMA0=0); ENDCASE => DRW22(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=0 RFRE OUTW); -- Plot value at (x1, y1) DRW22 : GOTO DRW23(ALWR); DRW23 : GOTO DRW24(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=1 RFRE OUTW); DRW24 : GOTO DRW25(MEMWRITE); DRW25 : GOTO DRW26(ADRE3=1 ADRE2=1 ADRE1=1 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); -- Check accumulated error, inc/decrement values DRW26 : GOTO DRW27; DRW27 : CASE (NEG) 1 => DRW37(ADRE3=1 ADRE2=1 ADRE1=1 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); ENDCASE => DRW28(ADRE3=1 ADRE2=1 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); -- Path One (E > 0) DRW28 : GOTO DRW29; DRW29 : CASE (NEG) 1 => DRW31(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=1 ALUINST0=1); ENDCASE => DRW30(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=1 ALUINST0=0); DRW30 : GOTO DRW31(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=1 ALUINST0=1); DRW31 : GOTO DRW32(ACCEN RFWR ADWR3=0 ADWR2=0 ADWR1=0 ADWR0=1); DRW32 : GOTO DRW33(ADRE3=1 ADRE2=1 ADRE1=1 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=0); DRW33 : GOTO DRW34(ADRE3=1 ADRE2=1 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=0); DRW34 : GOTO DRW35(ADRE3=1 ADRE2=1 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=1); DRW35 : GOTO DRW36(ACCEN RFWR SBWR ADWR3=1 ADWR2=1 ADWR1=1 ADWR0=0); DRW36 : GOTO DRW40(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=1 ALUINST0=0); -- Path Two (E < 0) DRW37 : GOTO DRW38(ADRE3=1 ADRE2=1 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST2=1 ALUINST1=0 ALUINST0=0); DRW38 : GOTO DRW39(ACCEN RFWR SBWR ADWR3=1 ADWR2=1 ADWR1=0 ADWR0=1); DRW39 : GOTO DRW40(ADRE3=0 ADRE2=0 ADRE1=0 ADRE0=0 RFRE ACCW ALUINST2=0 ALUINST1=1 ALUINST0=0); -- Branches One and Two rejoin. End of loop increment DRW40 : GOTO DRW41(ACCEN RFWR ADWR3=0 ADWR2=0 ADWR1=0 ADWR0=0); DRW41 : GOTO DRW42(ADRE3=1 ADRE2=1 ADRE1=1 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=1 ALUINST0=1); DRW42 : GOTO DRW43(ACCEN RFWR SBWR ADWR3=1 ADWR2=1 ADWR1=1 ADWR0=1); -- Return to end-of-draw test condition DRW43 : GOTO DRW20(ADRE3=1 ADRE2=1 ADRE1=1 ADRE0=1 ACCW RFRE ALUINST2=0 ALUINST1=0 ALUINST0=0); -- Enable address flip. DRWF1 : GOTO DRWF2; DRWF2 : GOTO DRW13(ADRE3=1 ADRE2=1 ADRE1=0 ADRE0=1 RFRE ACCW ALUINST2=0 ALUINST1=0 ALUINST0=1);