; GateDisplay.mu -- Display and cursor tasks with 2 R-registers bummed out ; Last modified September 16, 1978 7:14 PM ; This microcode is entirely compatible with the standard Alto microcode, ; but does not use R-registers HTAB and CURDATA. ; **** DVT, DHT, DWT, and CURT must all be run in the Ram ; (these are tasks 14B, 13B, 11B, and 12B respectively). ; **** MRT must also be modified to remove cursor processing (in particular, ; the code that updates YPOS and sets CURDATA). ;The Display Controller ; its R-Registers: $CBA $R22; $AECL $R23; $SLC $R24; ; $HTAB $R26; Required by standard microcode but not by this $YPOS $R27; $DWA $R30; $CURX $R20; ; $CURDATA $R21; Required by standard microcode but not by this ; its task specific functions: $EVENFIELD $L024010,000000,000000; F2 = 10 DHT DVT $SETMODE $L024011,000000,000000; F2 = 11 DHT $DDR $L026010,000000,124100; F2 = 10 DWT $NWW $R4; $400 $400; !1,2,DVT1,DVT11; !1,2,MOREB,NOMORE; !1,2,NORMX,HALFX; !1,2,NODD,NEVEN; !1,2,DHT0,DHT1; !1,2,NORMODE,HALFMODE; !1,2,DoTab,NoTab; !1,2,2Tab,1Tab; !1,1,NoTab1; !1,2,NWgr0,NWeq0; !1,2,NWgr2,NWeq2; !1,2,XNOMORE,DOMORE; !1,1,NWeq0a; ;Display Vertical Task DVT: MAR_ L_ DASTART+1; CBA_ L, L_ 0; SLC_ L; T_ NWW; CAUSE A VERTICAL FIELD INTERRUPT L_ MD OR T; MAR_ CURLOC; SET UP THE CURSOR NWW_ L, T_ 0-1; L_ MD XOR T; HARDWARE EXPECTS X COMPLEMENTED T_ MD, EVENFIELD; CURX_ L, :DVT1; DVT1: L_ 177677-T-1, TASK, :DVT2; BIAS THE Y COORDINATE DVT11: L_ 177677-T, TASK; DVT2: YPOS_ L, :DVT; ;Display Horizontal Task. ;11 cycles if no block change, 17 if new control block. DHT: MAR_ CBA-1; L_ SLC -1, BUS=0; SLC_ L, :DHT0; DHT0: T_ 37777; MORE TO DO IN THIS BLOCK SINK_ MD; T_ MD . T, SETMODE; L_ 177400+T, :NORMODE; HTab-1 in left half NORMODE: T_ 377 . T, :REST; HALFMODE: T_ 0; REST: AECL_ L; L_ DWA + T,TASK; INCREMENT DWA BY 0 OR NWRDS NDNX: DWA_ L, :DHT; DHT1: L_ T_ MD+1, BUS=0; CBA_ L, MAR_ T, :MOREB; NOMORE: BLOCK, :DNX; MOREB: T_ 37777; T_ MD . T, SETMODE; MAR_ CBA+1, :NORMX, EVENFIELD; NORMX: L_ 177400+T, :NODD; HTab-1 in left half HALFX: L_ 177400+T, :NEVEN; NODD: T_ 377 . T, :XREST; ODD FIELD, FULL RESOLUTION NEVEN: T_0; EVEN FIELD OR HALF RESOLUTION XREST: AECL_ L; L_ MD+T; T_MD-1; DNX: DWA_L, L_T, TASK; SLC_L, :DHT; ;Display Word Task ; Enters with DWA = address of first word of scan line ; AECL = HTab-1 ,, NWords ; Caution: must not execute DDR_ in a microinstruction that stops the clock ; (e.g., _MD before the memory is ready). Count instructions carefully! ; Horizontal tab loop -- outputs 2 tabs per iteration (except maybe the last) DWT: L_ T_ AECL-1; L_ T_ 177400+T+1, SH<0; T_ current HTab-1, test for none L_ 177400+T, SH<0, :DoTab; [DoTab, NoTab] L_ current HTab-2 DoTab: AECL_ L, L_ T, DDR_ 0, TASK, :2Tab; [2Tab, 1Tab] Output first tab word 2Tab: DDR_ 0, :DWT; Output second tab word ; There was only one tab word left 1Tab: NOP; TASK pending T_ AECL; ; Set up for data word loop -- T has garbage ,, NWords NoTab: L_ T_ 377 . T; [NoTab1] Extract NWords NoTab1: L_ T_ -3+T+1, SH=0; T_ NWords-2, test for NWords=0 L_ DWA+T, SH=0, :NWgr0; [NWgr0, NWeq0] L_ DWA+NWords-2 ; There are at least two words. Start fetch of first doubleword NWgr0: MAR_ T_ DWA, :NWgr2; [NWgr2, NWeq2] Branch if only 2 words NWgr2: AECL_ L, L_ 0; More than 2, AECL_ last doubleword adr L_ 2+T, SH=0, :DWTLp2; Advance DWT, force branch ; Exactly two words -- output them and block NWeq2: L_ 0, :DWTLp1; Force carry=0 at DWTLp1 ; Main data word loop DWTLp: MAR_T_DWA; L_AECL-T-1; DWTLp1: ALUCY, L_2+T; DWTLp2: DWA_L, :XNOMORE; [XNOMORE, DOMORE] DOMORE: DDR_MD, TASK; DDR_MD, :DWTLp; XNOMORE:DDR_ MD, BLOCK; DDR_ MD, TASK, :DWTF; ; Exit sequences NWeq0: BLOCK; [NWeq0a] NWeq0a: TASK; DWTF: :DWT; ;CURSOR TASK ;Cursor task specific functions $XPREG $L026010,000000,124000; F2 = 10 $CSR $L026011,000000,124000; F2 = 11 !1,2,ShowC,WaitC; !1,2,~CLast,CLast; !1,1,WaitC1; CURT: L_ T_ YPOS-1; Check cursor Y counter L_ 16-T-1, SH<0; Reached cursor top? L_ 3+T, SH<0, :ShowC; [ShowC, WaitC] Reached cursor bottom? ; Within cursor, output a word of cursor data ShowC: MAR_ CLOCKLOC+T+1, :~CLast; [~CLast, CLast] Fetch the right word CLast: BLOCK; Last line, block until next field ~CLast: XPREG_ CURX; Output cursor X YPOS_ L, TASK; Update cursor Y counter CSR_ MD, :CURT; Output cursor data ; Haven't reached cursor yet WaitC: YPOS_ L, TASK; [WaitC1] Update cursor Y counte WaitC1: CSR_ 0, :CURT; Blank cursor during this scan line