; Alto 1822 Interface microcode ; Larry Stewart ; Last modified April 19, 1978 9:41 PM #AltoConsts23.mu; ; Address definition for Emulator main loop in ROM $START $L004020,000000,000000 ; Start of emulator main loop ; Task Specific Function Definitions $IREAD $L000000,070017,000100 ; F1-17 Input data $IWRITE$L020016,000000,124000 ; F1-16 Output data $IOCLR $L016015,000000,000000 ; F1-15 Clear hardware output wakeup $IPOSTF$L016014,066014,000100 ; F1-14 Post (gate status to bus) $ISWAKC$L024014,000000,000000 ; F2-14 Clear SIO generated wakeup $IBRNCH$L024013,000000,000000 ; F2-13 4-way branch on wakeup $IIENBL$L024012,000000,000000 ; F2-12 Start read (turn on RFNIB) $ISETCS$L024011,000000,000000 ; F2-11 Set control functions from bus $IPTMOD$L024010,000000,000000 ; F2-10 2-way branch on throwaway mode ;R (S) registers $ICBPTR$R76; Control Block Pointer $MTEMP $R25; Temporary storage $AC1 $R2; Emulator register $NWW $R4; Interrupt system reg ; Task constants $ISDON $777; done $ISOVF $1377; buffer overflow (input only) $ISIBLZ$1777; block length zero (input only) ; Initialization for putting this code in the RAM, including ; 'silent boot' code !17,20,LOC0,,,,,IMLOOP,,,,,,,,,,; ;Silent Boot code, branches to ROM immediately LOC0: SWMODE; :START; ;Main loop. Task waits here when not processing anything. ;IBRNCH gates two bits onto NEXT6 and NEXT7 ; 00 - Start input 01 - Set Control ; 10 - Output data wakup 10 - Input data wakeup ; 4-way branch using NEXT6,NEXT7 (Caused by IBRNCH) %14,14,0,IISTRT,ICTST,IODATA,IIDATA; IMLOOP: T_ ICBPTR,IBRNCH; test wakeup conditions L_ ISDON,:IISTRT; [IISTRT,ICTST,IODATA,IIDATA] ;Common Post routine ; Expects offset of post location in T ; and task status in M ;IPOSTF gates hardware status bits to the bus ; 2-way branch using NEXT9 (Caused by SH=0) !1,2,IIBLOK,IPOST; IPOST: MAR_ ICBPTR+T; Start double reference T_ NWW; MD_ M,IPOSTF; Bus AND hardware status L_ MD OR T,TASK; NWW OR interrupt bits INXT: NWW_ L,:IMLOOP; ;Read status and set control register ;ISWAKC clears a wakeup caused by an SIO instruction ;ISETCS loads hardware control flops from the bus ICTST: MAR_ L_ AC1; Start fetch of args ICBPTR_ L; Save ctl block pointer T_ 6,ISWAKC; post location offset SINK_ MD,ISETCS; Control function INEND: L_ ISDON,:IPOST; Set control flops ;Input initialization ;IIENBL enables the hardware to receive a 16 bit word (turns it on) IISTRT: MAR_ 2+T; ISWAKC; clear wakeup T_ MD; read data pointer L_ MD-T; L_ ISIBLZ,SH=0; T_10,:IIBLOK; [IIBLOK,IPOST] IIBLOK: L_ NWW,IIENBL,TASK,:INXT; length ok,start reader ;Input Main loop ;IPTMOD gates the state of the Throwaway mode flop to NEXT7 ; The branch is taken if the flop was set (by an ISETCS) ;IREAD gates the receiver shift register to the bus ; and the PAD flop to NEXT7 ; If the branch is taken (which happens when the last word of ; a packet is read), the wakeup will not be cleared, otherwise ; the wakeup will be cleared ; 2-way branch using NEXT9 (Caused by SH=0) !1,2,IIDMOR,IIDFUL; ; 2-way branch using NEXT7 (Caused by IPTMOD) %4,4,0,IIACPT,IIDISC; ; 2-way branch using NEXT7 (Caused by IREAD) %4,4,0,IIDCON,IIDLST; ; another 2-way branch using NEXT7 (Caused by IREAD) %4,4,0,IIFINS,IIDPST; IIDATA: MAR_ L_ 2+T; Start fetch MTEMP_ L,IPTMOD; save cb ptr,test mode T_ MD; get pointer [IIACPT,IIDISC] IIACPT: L_ MD-T; past end of buffer? MAR_ T,SH=0; start data fetch L_ ONE+T,:IIDMOR; [IIDMOR,IIDFUL] IIDMOR: MD_ IREAD; Read and branch on last word. ; Except on the last word, this ; clears the wakeup IICLNU: MAR_ MTEMP,:IIDCON; [IIDCON,IIDLST] IIDCON: IIENBL,TASK; enable receiver IDCON: MD_ M,:IMLOOP; update ptr,restart IIDLST: TASK; this TASK only works ; because the hardware doesn't really clear the ; wakeup until the next IREAD in this case MD_ M; update pointer L_ ISDON; IIDPST: SINK_ IREAD; clear wakeup (again) IIFINS: T_ 10,:IPOST; IIDISC: L_ T, T_ IREAD,:IICLNU; throwaway word,branch if last IIDFUL: SINK_ IREAD; overflow status L_ ISOVF,:IIFINS; [IIFINS,IIDPST] ;Main output loop ;IWRITE loads the output shift register from the bus, ; clears the (hardware generated) wakeup if there was one, ; and starts the output hardware ;IOCLR resets the output hardware. This is how you clear the ; wakeups without restarting the output hardware ; 2-way branches using NEXT9 (both caused by SH=0) !1,2,IODMOR,IODEND; !1,2,IONLST,IOLST; IODATA: MAR_ L_ 4+T; start pointer fetch MTEMP_ L; save cb ptr T_ MD,IOCLR; get pointer, clear wakeup L_ MD-T; past end of buffer? MAR_ T,SH=0; start data fetch L_ M-1,:IODMOR; [IODMOR,IODEND] IODMOR: IWRITE_ MD,SH=0; send data,last? MAR_ MTEMP,:IONLST; start update [IONLST,IOLST] IOLST: SINK_ 2,ISETCS; set last word function IONLST: L_ ONE+T,TASK,:IDCON; finish IODEND: T_ 11+1,:INEND; offset of post loc (0,4798)(1,11959)\2b29B1150b1B105b59B198b1B36b7B92b21B162b1B19b5B151b38B105b5B183b22B70b6B175b17B424b1B66b1B67b1B75b1B22b6B550i4I256b18B327b1B19b1B19b6B