; TfsA.Asm -- assembly-language code ; Copyright Xerox Corporation 1979, 1980, 1981 ; Last modified May 1, 1981 3:28 PM by Taft .ent TFSRealDA, TFSVirtualDA, TFSIncrement .ent TFSModShift, TFSModShiftA, TFSSilentBoot ; offsets in TFSDSK structure defined in Tfs.d nHeads = 26. nSectors = 27. firstVTrack = 48. nVTracks = 49. .srel TFSRealDA: .TFSRealDA TFSVirtualDA: .TFSVirtualDA TFSIncrement: .TFSIncrement TFSModShift: .TFSModShift TFSModShiftA: .TFSModShiftA TFSSilentBoot: .TFSSilentBoot .nrel ; TFSIncrement(lvCounter) ; Increments a double-precision counter .TFSIncrement: inc 0 0 ; point to low-order word sta 0 2 2 isz @2 2 ; increment it jmp 1 3 ; no overflow dsz 2 2 ; overflow, point to high-order word isz @2 2 ; increment it jmp 1 3 jmp 1 3 ; TFSModShift(num, ref) ; Calls microcode to assist with ECC correction .TFSModShift: sta 0 1 2 sta 1 2 2 inc 2 0 ; lv num lda 1 c21 ; ram address of microcode routine #61010 ; jmpram jmp 1 3 c21: 21 ; TFSModShiftA(num, ref) ; Assembly-language version -- for D-machines where there is no ; microcoded routine. .TFSModShiftA: sta 3 1 2 mkzero 3 3 sta 3 2 2 ; init result to zero modsh1: sne 0 1 ; num eq ref? jmp modsh3 ; yes movzl 0 0 ; num = num lshift 1 lda 3 c4000 ; if (num & 4000B) ne 0 then... and# 3 0 snr jmp modsh2 lda 3 c4005 ; ... num = num xor 4005B andzl 0 3 sub 3 0 lda 3 c4005 add 3 0 modsh2: isz 2 2 ; count = count+1 jmp modsh1 dsz 2 2 ; return -1 if infinite loop modsh3: lda 0 2 2 lda 3 1 2 jmp 1 3 c4000: 4000 c4005: 4005 ; TFSRealDA(disk, virtualDA, lvRealDA) ; Converts virtualDA to a real DA and stores it in @lvRealDA. ; Returns true iff the virtual DA appears to be legal. ; A virtual DA of eofDA (-1) results in a real DA of zero. .TFSRealDA: sta 3 1 2 com 1 3 snr ; eofDA? jmp eofDA ; yes, return real DA of zero sta 0 2 2 ; save disk in frame mov 2 3 ; keep frame in ac3 ; Compute sector lda 2 2 3 ; disk lda 2 nSectors 2 ; get sectors per track mkzero 0 0 div ; ac0 ← remainder, ac1 ← quotient #77400 sta 0 @3 3 ; store sector number here temporarily ; Compute head lda 2 2 3 ; disk lda 2 nHeads 2 ; get heads per cylinder mkzero 0 0 div ; ac0 ← remainder, ac1 ← quotient #77400 movs 0 0 ; put head number in left byte lda 2 @3 3 ; combine with sector add 2 0 lda 2 3 3 ; get realDA pointer sta 0 1 2 ; store head and sector in second word ; Compute cylinder lda 2 2 3 ; disk lda 0 firstVTrack 2 ; first cylinder used in file system add 1 0 sta 0 @3 3 ; store cylinder number in real DA ; Check legality of virtual disk address lda 0 nVTracks 2 ; number of cylinders used in file system mov 3 2 ; recover frame sge 1 0 ; cylinder number in bounds? rtrue: mkminusone 0 0 skp ; yes, return true mkzero 0 0 ; no, return false lda 3 1 2 jmp 1 3 eofDA: sta 3 @3 2 ; set real DA to zero isz 3 2 sta 3 @3 2 jmp rtrue ; TFSVirtualDA(disk, lvRealDA) ; Returns virtual DA corresponding to real DA at @lvRealDA. ; Returns fillInDA if the real DA is not contained in this file system. ; Returns eofDA for physical page zero (this facilitates EOF detection). .TFSVirtualDA: sta 3 1 2 sta 0 2 2 ; disk mov 2 3 ; keep frame in ac3 mov 1 2 ; lvRealDA ; Check for physical page zero lda 1 0 2 ; lvRealDA>>DA.track lda 0 1 2 ; lvRealDA>>DA.head and sector add# 0 1 snr ; sum will be zero iff both words are zero, ; because legal DAs have both words positive jmp reofDA ; go return eofDA ; Offset track by start of file system, and check for track in bounds sta 0 3 3 ; save head and sector for later lda 2 2 3 ; disk lda 0 firstVTrack 2 sub 0 1 ; ac1 ← file system relative track lda 0 nVTracks 2 ; in bounds? sltu 1 0 jmp fillInDA ; no ; Check for head in bounds, and compute track*nHeads + head lda 0 3 3 ; recover head and sector lda 2 c377 and 0 2 ; ac2 ← sector subs 2 0 ; ac0 ← head sta 2 3 3 ; save sector for later lda 2 2 3 ; head in bounds? lda 2 nHeads 2 sltu 0 2 jmp fillInDA ; no mul ; ac1 ← ac1*ac2 + ac0 ; Check for sector in bounds, and compute (previous result)*nSectors + sector lda 0 3 3 ; recover sector lda 2 2 3 ; sector in bounds? lda 2 nSectors 2 sltu 0 2 jmp fillInDA mul ; ac1 ← ac1*ac2 + ac0 mov 1 0 ; this is the result tfsvdr: mov 3 2 ; restore frame lda 3 1 2 jmp 1 3 reofDA: adc 0 0 skp ; return eofDA = -1 fillInDA: adczl 0 0 ; return fillInDA = -2 jmp tfsvdr c377: 377 ; TFSSilentBoot() ; Does a silent boot to get Trident tasks out of the Ram .TFSSilentBoot: adczl 0 0 ; AC0 ← #177776 lda 1 c22 #61010 ; jmpram(22) sets BLV ← AC0 subzr 0 0 ; AC0 ← #100000 sio ; boot the machine jmp 1 3 c22: 22 .end