; Alto1822.mu -- Alto 1822 Interface microcode
; (Derived from AINCode.mu in [Indigo]<Alto-1822>PupTestSources.dm)
; Larry Stewart
; Special version for scatter/gather
; Last modified July 18, 1978 4:03 PM by Stewart
; Last modified August 20, 1983 2:24 PM by Taft
; This file contains only the 1822 interface microcode itself. It must be
; included (by #) in a top-level microcode file that includes the following
; statements:
; #AltoConsts23.mu;
; $START $L004020,000000,000000 ; Start of emulator main loop
; !17,20,LOC0,,,,,IMLOOP,,,,,,,,,,;
; LOC0:SWMODE;
; :START;
; Task Specific Function Definitions
$IREAD $L000000,070017,000100 ; F1-17Input data
$IWRITE$L020016,000000,124000 ; F1-16Output data
$IOCLR $L016015,000000,000000 ; F1-15Clear hardware output wakeup
$IPOSTF$L016014,066014,000100 ; F1-14Post (gate status to bus)
$ISWAKC$L024014,000000,000000 ; F2-14Clear SIO generated wakeup
$IBRNCH$L024013,000000,000000 ; F2-134-way branch on wakeup
$IIENBL$L024012,000000,000000 ; F2-12Start read (turn on RFNIB)
$ISETCS$L024011,000000,000000 ; F2-11Set control functions from bus
$IPTMOD$L024010,000000,000000 ; F2-102-way branch on throwaway mode
;(now misnamed, indicates last chunk of
;output packet)
;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
$ISFUL $1377;buffer full (input only)
$ISIBLZ$1777;block length zero (input only)
$ISFDON$2377;input full and end of packet
;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
;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 IREAD)
%4,4,0,IIDCON,IIDLST;
; another 2-way branch using NEXT7 (Caused by IREAD)
%4,4,0,IIFINS,IIBFDN;
IIDATA:MAR← L← 2+T;Start fetch
MTEMP← L;save cb ptr
T← MD;get pointer
L← MD-T-1;at end of buffer?
MAR← T;start data store
L← ONE+T,SH=0;
MD← IREAD,:IIDMOR;[IIDMOR,IIDFUL]
;Read and branch on last word.
;Except on the last word, this
;clears the wakeup
IIDMOR: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
IIDPST:L← ISDON;
IIWCLR:SINK← IREAD;clear wakeup (again)
IIFINS:T← 10,:IPOST;
IIDFUL:L← ISFUL,:IIFINS;[IIFINS,IIBFDN]
IIBFDN: TASK;
NOP;
L← ISFDON,:IIWCLR;
;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
;IPTMOD gates the state of the Throwaway mode flop to NEXT7
; The branch is taken if the flop was set (by an ISETCS)
; 2-way branches using NEXT9 (both caused by SH=0)
!1,2,IODMOR,IODEND;
!1,2,IONLST,IOLST;
; 2-way branch using NEXT7 (Caused by IPTMOD)
%4,4,0,IOBFUL,IOBEND;
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:SH=0;Last word?
IWRITE← MD,:IONLST;send data [IONLST,IOLST]
IONLST:MAR← MTEMP;clear wakeup
IOBFUL:L← ONE+T,TASK,:IDCON;go around
IOLST:MAR← MTEMP,IPTMOD;start update
L← ONE+T,:IOBFUL;[IOBFUL,IOBEND]
IOBEND:SINK← 2,ISETCS;do last bit function,(if IPT)
MD← M,TASK;update pointer
NOP,:IMLOOP;restart
IODEND:T← 11+1,:INEND;offset of post loc