; DDTapeUtilA.asm ; Copyright Xerox Corporation 1981 ; Last modified by Tim Diebert, February 12, 1981 4:15 PM .ent UBlockEq .ent BlockEq .ent UPupChecksum .ent AsciiXlate .ent EbcdicXlate .ent TapeTfsSwatProc .bext DDTapeVertIntCode .bext DDTapeVertIntFlag .srel DDTapeVertIntCode: .DDTapeVertIntCode DDTapeVertIntFlag: 0 UBlockEq: .UBlockEq BlockEq: .BlockEq UPupChecksum: .UPupChecksum AsciiXlate: .AsciiXlate EbcdicXlate: .EbcdicXlate TapeTfsSwatProc: .TapeTfsSwatProc .zrel .tabA: Atab .tabE: Etab .point: 0 .len: 0 .nrel ; DDTapeVertIntCode ; Sets DDTapeVertIntFlag on vertical interupt .DDTapeVertIntCode: sta 0 A0 adc 0 0 ; make true sta 0 @lvVertIntFlag lda 0 A0 bri A0: 0 lvVertIntFlag: DDTapeVertIntFlag ; UBlockEq(adr1,adr2,count) - Microcode version ; Compare the count words starting at adr1 with the corresponding ; words starting at adr2, and return true iff all the corresponding ; words are equal. .UBlockEq: sta 3 1,2 lda 3 3,2 ; get count 63000 ; call microcode mov 3 3 szr ; ac3 = 0 if all is well sub 0 0 skp adc 0 0 lda 3 1,2 jmp 1,3 ; BlockEq(adr1,adr2,count) - Assembly language version ; Compare the count words starting at adr1 with the corresponding ; words starting at adr2, and return true iff all the corresponding ; words are equal. .BlockEq: sta 3 1,2 sta 0 2,2 ; Store adr1 mov 1 3 ; ac3 ← adr2 ; Compare the first (count mod 8) words one at a time bleq1: lda 0 3,2 ; See if count mod 8 = 0 lda 1 c7 and# 0 1 snr jmp bleq2 ; Yes, go to fast loop lda 0 @2,2 ; No, do slow compare of one word lda 1 0,3 se 0 1 jmp bleq5 ; Not equal, return false isz 2 2 ; Equal, increment addresses inc 3 3 dsz 3,2 ; Decrement and test count jmp bleq1 ; Set up for fast loop bleq2: lda 0 3,2 ; Compute count/8 movzr 0 0 movzr 0 0 movzr 0 0 snr jmp bleq4 ; Less than 8 words in block sta 0 3,2 ; Store count/8 lda 0 2,2 ; Get current adr1 ; Fast loop. ac0/ adr1, ac3/ adr2, count in frame temp 3. ; The portion inside dir...eir is non-reentrant due to the use ; of save2. bleq3: dir ; Interlock non-reentrant portion sta 2 save2 ; Save frame pointer mov 0 2 ; ac2 ← adr1 lda 0 0,2 ; Compare 8 words, to bleq6 if fail lda 1 0,3 se 0 1 jmp bleq6 lda 0 1,2 lda 1 1,3 se 0 1 jmp bleq6 lda 0 2,2 lda 1 2,3 se 0 1 jmp bleq6 lda 0 3,2 lda 1 3,3 se 0 1 jmp bleq6 lda 0 4,2 lda 1 4,3 se 0 1 jmp bleq6 lda 0 5,2 lda 1 5,3 se 0 1 jmp bleq6 lda 0 6,2 lda 1 6,3 se 0 1 jmp bleq6 lda 0 7,2 lda 1 7,3 se 0 1 jmp bleq6 lda 0 c10 add 0 3 ; Increment adr2 by 8 add 2 0 ; Increment adr1 by 8, move to ac0 lda 2 save2 ; Recover frame pointer eir ; Now reentrant dsz 3,2 ; Decrement and test count jmp bleq3 ; More to do bleq4: mkminusone 0 0 skp ; Here to return true bleq5: mkzero 0 0 ; Here to return false lda 3 1,2 jmp 1,3 bleq6: lda 2 save2 ; Here to return false when eir ; inside fast loop jmp bleq5 c7: 7 c10: 10 save2: 0 ; PupChecksum microcode interface ; microcoded replacement for PupChecksum procedure in PupAl1a.asm .UPupChecksum: sta 3 1,2 mov 0 1 ; address in AC1 for microcode mov 0 3 lda 3 0,3 ; get pup length in bytes neg 3 3 ; compute # words exclusive of checksum comzr 3 3 ; = (# bytes -1)/2 mkzero 0 0 ; init checksum 63400 ; call microcode lda 3 1,2 jmp 1,3 ; translates the buffer pointed to by the first parm in place, two bytes per word ; second parameter is buffer length ; two 8-bit EBCDIC bytes of the argument (word packed) ; into two 7-bit ASCII bytes (word packed). ** NON REENTRANT ** ; AsciiXlate(buffer, len) .AsciiXlate: sta 3 1 2 ;save away ac3 in BCPL provided rat-hole sta 0 .point ;arg1 arg represents the buffer pointer sta 1 .len ;arg2 represents the buffer length mov 1 1 snr ;skip if length is non-zero jmp axend ;length is zero, quit axloop: lda 0 @.point ;get first (nth) word in ac0 movs 0 1 ;move (while swapping) ac0 (wordArg) to ac1 lda 3 .MaskA ;load 8-bit mask value and 3 0 ;mask low byte and 3 1 ;mask high byte lda 3 .tabA ;table base add 0 3 ;add offset in ac3 lda 0 0 3 ;translated char in ac0 lda 3 .tabA ;table base add 1 3 ;add offset in ac3 lda 1 0 3 ;translated char in ac1 movs 1 1 ;swap it into the high byte add 1 0 ;OR together sta 0 @.point ;and put it back ; isz .point ;bump the pointer (should never skip, unless pointer = 0) dsz .len ;decrement remaining word count, skip if zero (done) jmp axloop ;not done, do some more axend: lda 3 1 2 ;restore original value of ac3 jmp 1 3 ;return to the caller .MaskA: #377 Atab: 000. ; nul 001. ; soh 002. ; stx 003. ; etx 004. ; eot 009. ; ht 006. ; ack 007. ; bel 008. ; bs 005. ; enq 021. ; nak 011. ; vt 012. ; ff 013. ; cr 014. ; so 015. ; si ; 016. ; dle 017. ; dc one 018. ; dc two 019. ; dc three 020. ; dc four 010. ; lf 022. ; syn 023. ; etb 024. ; can 025. ; em 026. ; sub 027. ; esc 028. ; fs 029. ; gs 030. ; rs 031. ; us ; 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null ; 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null ; 032. ; sp 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 096. ; cent sign // becomes an accent grave 046. ; period 060. ; < 040. ; ( 043. ; + 124. ; | ; 038. ; & 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 033. ; ! 036. ; $ 042. ; * 041. ; ) 059. ; ; 126. ; not sign // becomes a ~ (tilde) ; 045. ; - 047. ; slash 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 094. ; circumflex ↑ 044. ; , 037. ; % 095. ; underscore 062. ; > 063. ; ? ; 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 058. ; : 035. ; # 064. ; @ 039. ; ' 061. ; = 034. ; " ; 000. ;null 097. ; a 098. ; b 099. ; c 100. ; d 101. ; e 102. ; f 103. ; g 104. ; h 105. ; i 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null ; 000. ;null 106. ; j 107. ; k 108. ; l 109. ; m 110. ; n 111. ; o 112. ; p 113. ; q 114. ; r 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null ; 000. ;null 000. ;null 115. ; s 116. ; t 117. ; u 118. ; v 119. ; w 120. ; x 121. ; y 122. ; z 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null ; 000. ;null 092. ; back slash \ 123. ; left curly bracket { 125. ; right curly bracket } 091. ; left square bracket [ 093. ; right square bracket ] 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null ; 000. ;null 065. ; A 066. ; B 067. ; C 068. ; D 069. ; E 070. ; F 071. ; G 072. ; H 073. ; I 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null ; 000. ;null 074. ; J 075. ; K 076. ; L 077. ; M 078. ; N 079. ; O 080. ; P 081. ; Q 082. ; R 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null ; 000. ;null 000. ;null 083. ; S 084. ; T 085. ; U 086. ; V 087. ; W 088. ; X 089. ; Y 090. ; Z 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null ; 048. ; zero 049. ; one 050. ; two 051. ; three 052. ; four 053. ; five 054. ; six 055. ; seven 056. ; eight 057. ; nine 000. ;null 000. ;null 000. ;null 000. ;null 000. ;null 127. ; del ; EbcdicXlate.asm -- Assembly code to translate INTO EBCDIC ; translates the two 7-bit ASCII bytes of the argument (word packed) ; into two 8-bit EBCDIC bytes (word packed). ** NON REENTRANT ** ; EbcdicXlate(wordArg,length) .EbcdicXlate: sta 3 1 2 ;save away ac3 in BCPL provided rat-hole sta 0 .point ;arg1 arg represents the buffer pointer sta 1 .len ;arg2 represents the buffer length mov 1 1 snr ;skip if length is non-zero jmp exend ;length is zero, quit exloop: lda 0 @.point ;get first (nth) word in ac0 movs 0 1 ;move (while swapping) ac0 (wordArg) to ac1 lda 3 .MaskE ;load 7-bit mask value and 3 0 ;mask low byte and 3 1 ;mask high byte lda 3 .tabE ;table base add 0 3 ;add offset in ac3 lda 0 0 3 ;translated char in ac0 lda 3 .tabE ;table base add 1 3 ;add offset in ac3 lda 1 0 3 ;translated char in ac1 movs 1 1 ;swap it into the high byte add 1 0 ;OR together sta 0 @.point ;and put it back ; isz .point ;bump the pointer (should never skip, unless pointer = 0) dsz .len ;decrement remaining word count, skip if zero (done) jmp exloop ;not done, do some more exend: lda 3 1 2 ;restore original value of ac3 jmp 1 3 ;return to the caller .MaskE: #177 Etab: 0. 1. 2. 3. 4. 9. 6. 7. 8. 5. 21. 11. 12. 13. 14. 15. ; 16. 17. 18. 19. 20. 10. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. ; 64. 90. 127. 123. 91. 108. 80. 125. 77. 93. 92. 78. 107. 96. 75. 97. ; 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 122. 94. 76. 126. 110. 111. ; 124. 193. 194. 195. 196. 197. 198. 199. 200. 201. 209. 210. 211. 212. 213. 214. ; 215. 216. 217. 226. 227. 228. 229. 230. 231. 232. 233. 180. 177. 181. 106. 109. ; 74. 129. 130. 131. 132. 133. 134. 135. 136. 137. 145. 146. 147. 148. 149. 150. ; 151. 152. 153. 162. 163. 164. 165. 166. 167. 168. 169. 178. 79. 179. 95. 255. .TapeTfsSwatProc: snz 0 0 ; entering Swat? kwait: inc 0 0 snr ; yes, wait for no Trident commands pending jmp 1 3 lda 1 @.KBLK sz 1 1 jmp kwait inc 1 1 szr ; wait a while longer for things to settle jmp .-1 ; Now let the tape drive settle, wait ~.5 secs. ; in the future, more elegant techniques ought to be substituted for the code below subz 1 1 ;zero ac1 and carry tloop: lda 0 @1,3 ;waste some time lda 0 @1,3 lda 0 @1,3 lda 0 @1,3 isz 1 ;increment ac1, skip if zero jmp tloop jmp 1 3 .KBLK: 640 .end