; MesaSlotMc.mu - Microcode for Slot, TriCon to be used with the Mesa System ; last modified by GWilliams January 13, 1982 2:10 PM ; trying the 8k option instead of 64K at InitBuffers, uCode hasn't been able to exit from that routine lately. ; last modified by GWilliams January 12, 1982 2:22 PM ; writing values microcode uses back into scan control block to verify that the uCode ; got them correctly ; last modified by GWilliams November 13, 1981 4:37 PM ; changed calculation of # of zero's to write into buffer@ InitZero ; last modified by GWilliams November 11, 1981 10:57 AM ; Changed to store the servo count in a separate word. Before it had only 13 bits. ; For now, this version of the microcode is incompatible with BCPL Press. ; Had to add FLAGS register & change the code somewhat ; last modified by GWilliams September 8, 1981 11:29 AM ; This SLOT microcode now uses bank 1 of the S registers because of conflict with MESA. ;This code runs ok with the BCPL Press ; last modified by GWilliams August 18, 1981 2:14 PM ; -- no longer assemble TriConmc.mu, instead, assemble TriConDriver.mu in order to get ; XMesaoverflow stuff into the ram. Also patched out the LOC1 predef because I now ; have it predefed in TriconDriver.mu ; last modified by Butterfield, October 8, 1980 4:55 PM ; - added invert bit - 10/6 ; - changed SUB to InitBuffers - 10/3 ; - predefined LOC1 - 7/22/80 ;MICROCODE FOR SLOT 3100 CONTROLLER February 29, 1976 ; ; This stuff uses task 1; BLV 177775 (bit 14) ; (disk uses 3,15; BLV 77767 (bits 0, 12)) ; Auto-Boot feature means start emulator in RAM BLV 177776 ; "and" all these together to get 77764 ;Put in packed RAM format with BLV as version: ; PackMu SlotMc.Mb SlotMc.Br 77764 ; ; ;;;%0, 1777, 1, LOC1; Slot start THIS IS NOW DEF'D IN TriconDriver.mu $LREG $R40; #TriconDriver.Mu; --I changed this from TriConMc.mu on August 18, 1981 2:14 PM ; Location 720 points to a control block: ; ;0 blank bit 14; COM bit 2 ; COM: BeamOn=0, Status=1, Reset=2, Print=3 ;1 BlowUp bit -- for factor of 2 increase in each direction ; LastPage bit -- marks this command as the last page ; invert bit -- inverts the page ; moreBlank bit 13 -- used to be bitsPerLine ; ;2 bottomMargin word -- # bits at bottom margin: divides by 8 ;3 scanLineWc word -- # words in scan line /2 ;4 leftMargin word -- # bits at left of portrait page ;5 scansPerPage word -- total number of scan lines of data ;6 bufferPtr word -- pointer to first buffer -- must be even ; buffers are linked by next=current!-1 ;7 scanLineWcInc -- how far (in words) to advance within buffer to find ; next scan line -- must be even ;10 scansPerBuf word -- number of scan lines in each buffer ;11 bitsPerLine word -- for servoing the scan motor ;12 currentBuff word -- points to current buffer ;13 currentLine -- counts up to scansPerPage ;14 status: ; blank bit 9 ; Wait bit -- 0 true ; PaperJam bit -- 0 true ; AddPaper bit -- 0 true ; SelectB bit ; Ready bit ; LineSync bit ; PageSync bit -- 0 true ;So processing of buffer pointed to by b is: ; currentBuff=b ; for i=0 to scansPerBuff-1 do ; Send data starting at b+i*scanLineWcInc for scanLineWc*2 words ; b=b!-1 ; REGISTER DEFINITIONS FOR SLOT ; SLOT DEVICE DEFINITIONS ;F1's $SLOTSTOP $L16016, 00000, 000000; non-data $SLOTBEAM $L16017, 00000, 000000; non-data ;F2's $SLOTBLOCK $L24010, 00000, 000000; non-data $SLOTDATA $L26011, 00000, 124000; non-data $SLOTADDR $L26012, 00000, 124000; destination $SLOTSERVO $L26013, 00000, 124000; destination $SLOTPRINT $L24014, 00000, 000000; non-data $SLOTRESET $L24015, 00000, 000000; non-data $SLOTDISABLE $L24016, 00000, 000000; non-data $SLOTSTATUS $L24017, 00000, 000000; non-data $DCBADDR$R41; Normally points to currentLine entry $PBM $R42; Bottom margin $PDWC $R43; scanLineWc (in double words) $LM $R44; Left margin $MSL $R45; scansPerPage $PBBA $R46; Current print buffer address $PBSLI $R47; scanLineWcInc $PBL $R50; Scan lines/buffer $InitOnesPairs $R51; How many pairs of ones to init the buffers with $CSA $R53; CURRENT SCAN ADDRESS $CRC $R54; FIRST SERVO COUNT THEN CURRENT RING COUNT $CLA $R55; CURRENT LAST ADDRESS $CSBA $R52; CURRENT SCAN BASE ADDRESS $InitReturn $R52; Init return BUS byte with sign bit for which buffer $Command $R56; $InitPairs $R56; InitBuffers' pair counter ;$FLAGS $R57 $FLAGS $R61 ; Constants known elsewhere by other names: $600 $600; $12 $12; ; PREDEFINITIONS !3,4,BEAMON,SLOTSTAT,RESETSLOT,PRINT; !1,2,Invert,InitBuffers; !1,2,LOC1+1,CKPAGE; !1,2,STARTPG,PAGESYNC; !1,2,MARWAIT,MARDONE; !1,2,STOPPRINT,KEEPPRINT; !1,2,MOREWORDS,LASTWORDS; !1,2,InvertNextWord,NEXTWORD; !1,2,InvertMoreWords,InvertLastWords; !1,2,BUFFEROK,RESETBUFFER; !1,2,NEXTLINE,LINESDONE; !1,2,InitZeroLoop,InitBufferDone; !1,2,InitDone,InitSecond; !1,2,PAGEWAIT,PAGEDONE; !1,2,RET0,RET1; !1,2,InitOnes,InitZero; ; THE CODE LOC1: ;new code added to use bank 1 of the S registers. This is because Mesa hogs the bank ;zero registers. SRB_2; SRB is loaded from BUS[12-14] T_600; TASK STARTS HERE AFTER SIO LOC1+1: L_100+T,TASK; DCBADDR_L; MANUFACTURE #720 ; T_20; MAR_L_DCBADDR+T; GET CONTENTS OF DCB FROM @(720) NOP; L_MD,TASK; DCBADDR_L; ; MAR_DCBADDR; T_3; L_MD AND T; MASK COMMAND TO 2 BITS T_MD; Command_L,L_T,TASK; GET COMMAND FLAGS_L; GET FLAGS ; MAR_T_DCBADDR; CLEAR COMMAND L_2+T; DCBADDR_L,TASK; MD_0; ; MAR_T_DCBADDR; @(#720)+2 L_2+T; DCBADDR_L; T_MD; GET PRINT BOTTOM MARGN L_MD; GET PRINT DBL WORD CNT PDWC_L; L_177777-T,TASK; PBM_L; ; T_2; L_PDWC-T,TASK; PDWC_L; ; MAR_T_DCBADDR; @(#720)+4 L_2+T; DCBADDR_L; L_MD; GET LEFT MARGIN (BITS) T_MD; GET TOTAL SCAN LINES LM_L,L_T,TASK; MSL_L; ; MAR_T_DCBADDR; @(#720)+6 L_2+T; DCBADDR_L; L_MD; GET ADDR TO PRINT BUFF T_MD; GET WORDS PER SCAN LINE PBBA_L,L_T,TASK; PBSLI_L; ; MAR_DCBADDR; @(#720)+10 L_DCBADDR+1; DCBADDR_L; L_MD, TASK; GET SCAN LINES PER BUFF PBL_L; MAR_T_DCBADDR; @(#720)+11 L_2+T; DCBADDR_L; L_MD, TASK; ; Get CRC (servo count for scan motor) ; PBL_L;L_T,TASK; CRC _ L; --later to become the Current Ring Count ; T_DCBADDR; @(#720)+10 ; L_3+T, TASK; ;we want DCBADDR to point to currentLine so as to permit ; DCBADDR_L; either +1 or -1 to get to status and currentBuf easily. ; ;DEBUGGING CODE HERE ## T_DCBADDR; ## PUT PBSLI into scb for Mesa to see MAR_3+T; NOP; TASK; ## MAY NEED A NOP BEFORE THIS TASK AS CLOCK STOPS FOR MEMORY REF MD_PBSLI; ## T_DCBADDR; ## PUT PBL into scb for Mesa to see MAR_4+T; NOP; TASK; ## MAY NEED A NOP BEFORE THIS TASK AS CLOCK STOPS FOR MEMORY REF MD_PBL; ## T_DCBADDR; ## PUT CRC into scb for Mesa to see MAR_5+T; NOP; TASK; ## MAY NEED A NOP BEFORE THIS TASK AS CLOCK STOPS FOR MEMORY REF MD_CRC; ## SINK_Command,BUS; BRANCH ON COMMAND TO: T_ FLAGS, :BEAMON; OR SLOTSTAT OR RESETSLOT OR PRINT ; (T_ FLAGS is for PRINT - reduces time between TASKs) ; ; BEAMON: SLOTSERVO_CRC; SLOTBEAM,:SLOTSTAT; ; RESETSLOT: SLOTRESET; SLOTSTOP,:SLOTSTAT; STOP PRINTING ; SLOTSTAT: MAR_DCBADDR+1,SLOTDISABLE; RETURN STATUS L_377,SLOTSTATUS; TASK; SLOTRESET,TASK; MD_LREG,:LOC1; MC STOPS HERE UNTILL NEW SIO ; PRINT: L_ 20000 ANDT; T has FLAGS, Test the Invert bit SLOTBEAM, SH=0; InitOnesPairs_ L, SLOTPRINT, TASK, :Invert; [Invert, InitBuffers] Invert: NOP; ;NB THAT THE FOLLOWING 2 LINES COULD CAUSE A PROBLEM WHEN SCAN LINES ARE > 32K. AT THAT ;POINT, TRYING TO AD 177577 WILL CAUSE HAVOC. AN ALTERNATE WAY TO HANDLE THIS IS TO ;DO THE DIVISION BY 32 BY SHIFTING, THEN SUBTRACTING 4 FROM InitOnesPairs ; -Implemented above comment November 13, 1981 3:47 PM ; T_ CRC; ; L_ 177577 +T+1; i.e. T_ CRC - 128 (changed sink to L rather than T) ; L_ 17777 ANDT; Just bitsPerLine - 128 --don't need now that CRC = 16 bits L_CRC; ### MTEMP_ L RSH 1; divide by 32, truncating L_ MTEMP, TASK; InitOnesPairs_ L; L_ InitOnesPairs; MTEMP_ L RSH 1; L_ MTEMP; MTEMP_ L RSH 1; L_ MTEMP, TASK; InitOnesPairs_ L; L_ InitOnesPairs; MTEMP_ L RSH 1; L_ MTEMP; MTEMP_ L RSH 1; the T_0 is to get it to L L_ MTEMP, TASK; InitOnesPairs_ L; now have BitsPerLine/32 T_4; Subtract 128 bits worth from InitOnesPairs ### L_InitOnesPairs-T; i.e., InitOnesPairs-4 ### InitOnesPairs_L; ### L_0, TASK, :InitBuffers; (L_ 0) ### ; RET0: SLOTSERVO_CRC; T_DCBADDR; ## PUT Buffer base address into scb for Mesa to see MAR_6+T; NOP; TASK; ## MAY NEED A NOP BEFORE THIS TASK AS CLOCK STOPS FOR MEMORY REF MD_41023; ##put this number into debuggingSpace4 to see if we ever get here ; PAGESYNC: T_13,SLOTBLOCK; MAR_DCBADDR-T; WAIT FOR PAGE SYNC & MARGIN T_ONE; L_ONE AND T,SLOTSTATUS; SINK_MD,BUS=0; TEST FOR NO NEW COMMAND T_600,:LOC1+1; IFSO GOTO CKPAGE ; CKPAGE: SH=0,TASK; CHECK PAGE NOT STARTED :STARTPG; IFSO GOTO PAGESYNC ; STARTPG: NOP; MARWAIT: L_LM-1,SLOTBLOCK; WAIT FOR MARGIN NOP; LM_L,TASK,SH<0; TEST FOR MARGIN SENT :MARWAIT; IFSO GOTO MARDONE ; MARDONE: T_40000; ISSUE STOPPRINT IF REQUIRED L_FLAGS AND T; L_PBBA,SH=0; TEST FOR NOT LAST PAGE CSBA_L,:STOPPRINT;IFSO GOTO KEEPPRINT ; ALSO INITIALIZE CURRENT SCAN BASE ADDRESS ; STOPPRINT: SLOTSTOP,:KEEPPRINT; STOP PRINTING KEEPPRINT: L_PBL,TASK; CRC_L; INITIALIZE CURRENT RING COUNT ; NEXTLINE: SLOTADDR_PBM; RESET LEFT MARGIN L_CSBA; RESET CURRENT SCAN ADDRESS CSA_L; T_PDWC; RESET LAST ADDRESS L_PDWC+T; CLA_L; T_CLA; L_CSA+T,TASK; CLA_L; SINK_ InitOnesPairs, BUS=0, TASK; Check if we're inverting :InvertNextWord; [InvertNextWord, NEXTWORD] ; ; MAIN WORD TRANSFER LOOP ; NEXTWORD: MAR_T_CSA; **SLOT HDWARE REQUIRES 3 INS. AFTER MAR_ L_CLA-T; L_2+T,SH<0; TEST FOR WORDS SENT CSA_L,:MOREWORDS;IFSO GOTO LASTWORDS ; MOREWORDS: SLOTDATA_MD,TASK; SINK_MD,:NEXTWORD ; ; Inverting Word Transfer Loop ; InvertNextWord: MAR_ T_ CSA; **SLOT HDWARE REQUIRES 3 INS. AFTER MAR_ ; I take the previous comment to mean that the clock cannot stop ; for the two cycles following the SLOTDATA - Butterfield - 10/6 L_ CLA -T; L_ 2 +T, SH<0; TEST FOR WORDS SENT CSA_ L, :InvertMoreWords; [InvertMoreWords, InvertLastWords] ; InvertMoreWords: T_ MD; L_ MD; L_ 0 -T-1, MTEMP_ L; T_ MTEMP; L_ 0 -T-1, MTEMP_ L; SLOTDATA_ MTEMP, TASK; SINK_ LREG, :InvertNextWord; ; InvertLastWords: T_ MD; L_ MD; L_ 0 -T-1, MTEMP_ L; T_ MTEMP; L_ 0 -T-1, MTEMP_ L; SLOTDATA_ MTEMP, TASK; SINK_ LREG, :FinishScanLine; ; ; LASTWORDS: SLOTDATA_MD,TASK; SINK_MD; ; ; ; FINISH SCANLINE ; FinishScanLine: T_PBSLI; INC CURRENT SCAN BASE ADDR L_CSBA+T; CSBA_L; L_CRC-1; CRC_L,SH=0,TASK; CHECK FOR BUFFER COMPLETED :BUFFEROK,SLOTBLOCK; IFSO GOTO RESETBUFFER ; RESETBUFFER: MAR_PBBA-1; GET POINTER FOR NEXT BUFF ADDR L_PBL; AND GET FIRST BUFFER ADDR CRC_L; L_MD; MAR_DCBADDR-1; PBBA_L; CSBA_L; MD_PBBA; ; BUFFEROK:L_MSL-1; MSL_L,TASK,SH=0; TEST FOR LAST SCAN LINE OF PAGE :NEXTLINE; IFSO GOTO LINESDONE ; LINESDONE: L_ONE,:InitBuffers,TASK; ZERO BOTH BUFFERS ; RET1: NOP; T_DCBADDR; ## show that we got this far, stick 37400 into dbguggingSpace6 MAR_11+T; NOP; TASK; ## MAY NEED A NOP BEFORE THIS TASK AS CLOCK STOPS FOR MEMORY REF MD_37400; ##AT debuggingSpace7 PAGEWAIT: T_ONE,SLOTBLOCK; L_ONE AND T,SLOTSTATUS; SH=0,TASK; TEST FOR END OF PAGE :PAGEWAIT; IFSO GOTO PAGEDONE ; PAGEDONE: :SLOTSTAT; ; ; Subroutine to initialize the buffers. Returns to RET0 or RET1 ; InitBuffers: ;there is a TASK just before we get here, so store L away InitReturn_ L; Save return index and initialize buffer bit InitSecond: SLOTADDR_ 177777; Start at the beginning SLOTDATA_ 0; with 64 zero bits SINK_ 0; SLOTDATA_ 0; SINK_ 0; L_ InitOnesPairs, TASK; Now for InitOnesPairs pair of ones InitPairs_ L; ;DEBUGGING CODE HERE ## ;## T_DCBADDR; ## PUT InitOnesPairs into scb for Mesa to see ;## MAR_2+T; ;## NOP; ;## TASK; ## MAY NEED A NOP BEFORE THIS TASK AS CLOCK STOPS FOR MEMORY REF ;## MD_InitOnesPairs; ## InitOnesLoop: L_ InitPairs -1, BUS=0, TASK; InitPairs_ L, :InitOnes; [InitOnes, InitZero] InitOnes: L_ 177777; see if using L helps put in the ones SLOTDATA_ LREG; SINK_ LREG, :InitOnesLoop; InitZero: T _ InitOnesPairs +1; L_ 377 -T-1, TASK; i.e. 253 - InitOnesPairs(for 8K slot card) ; L_ 3777 -T-1, TASK; i.e. 2045 - InitOnesPairs (for 64K Slot Card) InitPairs_ L; (this can get squeezed out if necessary) ;DEBUGGING CODE HERE ## T_DCBADDR; ## PUT InitOnesPairs into scb for Mesa to see MAR_2+T; ## at location debuggingSpace0 NOP; TASK; ## MAY NEED A NOP BEFORE THIS TASK AS CLOCK STOPS FOR MEMORY REF MD_InitPairs; ## InitZeroLoop: SLOTDATA_ 0; SINK_ 0; L_ InitPairs -1, BUS=0, TASK; InitPairs_ L, :InitZeroLoop; [InitZeroLoop, InitBufferDone] InitBufferDone: T_ 100000, SLOTBLOCK; L_ InitReturn XORT; InitReturn_ L, SH<0, TASK; Test for last buffer :InitDone; [InitDone, InitSecond] InitDone: T_DCBADDR; ## PUT NUMBER 34104 into scb for Mesa to see MAR_7+T; NOP; TASK; ## MAY NEED A NOP BEFORE THIS TASK AS CLOCK STOPS FOR MEMORY REF MD_34104; ##AT debuggingSpace5 T_DCBADDR; ## PUT NUMBER InitReturn into scb for Mesa to see MAR_10+T; NOP; TASK; ## MAY NEED A NOP BEFORE THIS TASK AS CLOCK STOPS FOR MEMORY REF MD_InitReturn; ##AT debuggingSpace6 SINK_ InitReturn, BUS, TASK; :RET0; [RET0, RET1] (706)\f3 1846i62I4273f0 2f3 23f0 2f3 73f0 2f3 96f0 1f3 50f0 1f3 9f0 1f3 5f0 1f3 71f0 1f3 14f0 1f3 48f0 1f3 9f0 1f3 5f0 1f3 71f0 1f3 12f0 1f3 48f0 1f3 9f0 1f3 5f0 1f3 71f0 1f3 1630f0 1f3 9f0 1f3 5f0 1f3 71f0 1f3 2562f0 1f3 10f0 1f3 5f0 1f3 71f0 1f3 596f0 4f3 58f0 4f3 9f0 4f3 5f0 4f3 71f0 4f3 231f0 1f3 22f0 1f3 213f0 1f3 58f0 1f3 9f0 32f3 5f0 1f3 71f0 1f3