; 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