; DDTapeWriteTask.mu -- Tape Microcode for the Alto Double Density Tape Controller ; Copyright Xerox Corporation 1980 ; Body of Tape Controller write task microcode -- requires definitions in DDTapeDefs.mu ; ; Last modified by Tim Diebert, March 4, 1981 11:32 AM ; ; Branch Conditionals !1, 2, EraseDataOp, WriteData; !1, 2, WriteByte, WriteAlmostLastByte; !1, 2, WriteTwo, WriteOne; !1, 2, EraseData, EraseDone; !1, 2, Write, Write1; ; Write loop ; Task 5 ; ; Write expects the following registers to be loaded. ; ByteCnt should contain the number of bytes to be written. ; WordCnt must not contain any usefull data. ; WrtPtr points to the first word to be transfered - 1. WriteTask: NOP; Write: GoCmd← ZeroCmd; Tell the read task we understand and are reset. TASK; NOP; THIS IS WHERE THE WRITE TASK SHOULD BE AFTER THE RESET. T← ResetWriteTask; Wait for write task to reset. L← TStatus AND T; TASK, SH=0; :Write; [Write, Write1] Write1: T← IErase; L← Command AND T; L← WriteByteCnt, SH=0; Build the word count and the low order bit of the byte count. WriteWordCnt← LRSH1, :EraseDataOp; [EraseDataOp, WriteData] WriteData: T← ByteCountOffset; MAR← TCBBase + T; TASK; MD← WriteByteCnt; T← WriteByteCnt; L← WriteWordCnt - 1; Decrement the word count by 1. WriteWordCnt← L; L← 1 AND T; WriteByteCnt← L; ; The write loop works as follows. The main loop is executed until 4 or 5 bytes ; remain. Then WriteAlmostLastByte is entered. The last word known not to contain the ; last byte is written. The first byte of the word that may contain the last byte is written ; while a check for odd byte is done. At this point the last byte is written or the last 2 ; bytes are written so the hardware can be told when to send LastWord to the formatter. WriteLoop: T← MAR← WritePtr + 1; Start memory reference L← WriteWordCnt - 1; Decrement the byte count WriteWordCnt← L, L← T, SH=0; WritePtr← L, :WriteByte; [WriteByte, WriteAlmostLastByte] WriteByte: L← TWrite← MD, TASK; WriteTapeData← LLCY8; TWrite← WriteTapeData, TASK; :WriteLoop; WriteAlmostLastByte: L← TWrite← MD, TASK; Write byte n-4 or n-3 WriteTapeData← LLCY8; TWrite← WriteTapeData, TASK; NOP; L← MAR← WritePtr + 1; Start memory reference WritePtr← L; SINK← WriteByteCnt, BUS=0; L← TWrite← MD, :WriteTwo; [WriteTwo, WriteOne] Write byte n-2 or n-1 WriteOne: TASK; WriteTapeData← LLCY8; TLastByte← WriteTapeData; Write byte n. :WriteDone; WriteTwo: TASK; WriteTapeData← LLCY8; TWrite← WriteTapeData, TASK; NOP; L← MAR← WritePtr + 1; Start memory reference NOP; TLastByte← MD; Write byte n. L← ALLONES; MAR← TCBBase; TASK; MD← M, :WriteDone; EraseDataOp: WriteTapeData← 0; EraseData: TASK; NOP; L← WriteByteCnt - 1; WriteByteCnt← L, SH=0; TWrite← WriteTapeData, :EraseData; [EraseData, EraseDone] EraseDone: TASK; NOP; TLastByte← WriteTapeData; :WriteDone; WriteDone: :Write;