home *** CD-ROM | disk | FTP | other *** search
/ ftp.whtech.com / ftp.whtech.com.tar / ftp.whtech.com / ti-990 / TI990_10_old.txt < prev    next >
Text File  |  2006-10-19  |  33KB  |  832 lines

  1. ; TI990/10 LOAD ROMs disassembly
  2. ;
  3. ;General background :
  4. ; These ROMs contain the handler for the LOAD/RESTART interrupt.  This
  5. interrupt is called at
  6. ; start-up (instead of RESET, which is used for "warm reset", I think), so
  7. that the boot loader in
  8. ; ROMs can be executed.
  9. ;
  10. ; This interrupt can also be triggered by the programmer panel, and there
  11. is code to handle the
  12. ; panel functions.
  13. ;
  14. ;Description :
  15. ; We have 1kb of ROMs (4 256*8 ROMs).
  16. ;
  17. ; If you want a starting point, you can have a look at the LOAD vector
  18. located at >FFFC.
  19. ; The LOAD routine starts at >FC00.
  20. ;
  21. ; The ROMs basically do the following :
  22. ; * handle programmer panel functions if applicable
  23. ; * look for a MDU, and boot from it if present
  24. ; * if programmer panel enabled, boot from the unit designated in RO/R1/R2
  25. (either ASR tape,
  26. ;  Card Reader, or tape/disk based on a MT3200/WD900 controller or equivalent)
  27. ;
  28. ; by default, it boots from disk unit 0, using controller base address >F800.
  29. ;
  30. ;Conventions used :
  31. ; TMS9900 assembly conventions should have been respected.  Particularily :
  32. ; * bit are numbered from MSB to LSB (unlike almost every other CPU)
  33. ;
  34. ; Raphael Nabet, 2000/04/30
  35. ;
  36. ; revision history :
  37. ; 2000/04/30 : initial release
  38.  
  39. ; LOAD vector entry point
  40. FC00: 020C 1FE0      LI   R12,>1FE0     ; programmer panel CRU base
  41. FC04: 0221 6700      AI   R1,>6700        ; look for magical value
  42. (>9900)
  43. FC08: 1602           JNE  >FC0E            ; continue with normal
  44. vector if not found
  45. FC0A: 1D0A           SBO  >000A            ; switch "Run" light on
  46. FC0C: 0450           B    *R0            ; branch to routine if found
  47.  
  48. FC0E: 0209 00A0      LI   R9,>00A0        ; R9 points to free area in
  49. RAM ?
  50. FC12: 0700           SETO R0            ; R0 < 0 : use TILINE unit
  51. (tape, FD1000, hard disk) by default
  52. FC14: 0201 F800      LI   R1,>F800        ; TILINE address for
  53. default disk controller
  54. FC18: 0202 0800      LI   R2,>0800        ; if programmer panel
  55. enabled, boot from drive unit 0 by default
  56. FC1C: 1F0B           TB   >000B
  57. FC1E: 133B           JEQ  >FC96            ; if programmer panel
  58. disabled, jump to boot routine
  59.  
  60. FC20: C10E           MOV  R14,R4        ; load old PC to display it
  61.  
  62. ; programmer panel scan : we have 4 rows of 8 switches
  63. ; 16 switches allow to toggle the display in R4.
  64. ; the 16 other switches allow to access programmer panel functions.
  65. ;
  66. ; register conventions here :
  67. ; R4 = data register
  68. ; R7 = memory address register
  69. ; R13 = WP
  70. ; R14 = PC
  71. ; R15 = ST
  72.  
  73. ; keyscan loop start
  74. FC22: 3204           LDCR R4,8            ; display data register MSB
  75. FC24: 3220 0089      LDCR @>0089,8        ; display data register LSB
  76.  
  77. FC28: 0205 FC8C      LI   R5,>FC8C
  78. FC2C: 0695           BL   *R5            ; read current 8 switches
  79. from programmer panel to R3 MSB
  80. FC2E: 16FE           JNE  >FC2C            ; wait for all switches to
  81. be released
  82. FC30: 0695           BL   *R5
  83. FC32: 16FC           JNE  >FC2C            ; test again to fix switch
  84. bounce problems
  85. FC34: 0695           BL   *R5
  86. FC36: 16FA           JNE  >FC2C            ; again
  87.  
  88. FC38: 04C3           CLR  R3
  89. FC3A: 1D08           SBO  >0008            ; "Increment scan" bit ->
  90. select another row of switches
  91. FC3C: 0695           BL   *R5
  92. FC3E: 13FD           JEQ  >FC3A            ; if no switch pressed,
  93. scan next row
  94. FC40: 0695           BL   *R5
  95. FC42: 13FB           JEQ  >FC3A            ; fixes switch bounce problems
  96. FC44: 0695           BL   *R5
  97. FC46: 13F9           JEQ  >FC3A            ; again
  98.  
  99. FC48: 1F09           TB   >0009            ; scan count bit 0 -> is
  100. current switch row number odd or even ?
  101. FC4A: 1601           JNE  >FC4E
  102. FC4C: 06C3           SWPB R3            ; if odd, we read last 8
  103. switches in 16 switches, so we rotate 8 bits
  104. FC4E: 1F08           TB   >0008            ; scan count bit 1 -> is
  105. this command switches or data switches ?
  106. FC50: 1302           JEQ  >FC56            ; command switches -> jump
  107. to interpret command
  108. FC52: 2903           XOR  R3,R4            ; data switches -> toggle
  109. the data displayed as requested
  110. FC54: 10E6           JMP  >FC22            ; update display and go
  111. back to scan routine
  112.  
  113. FC56: 04C5           CLR  R5
  114. FC58: 05C5           INCT R5
  115. FC5A: 0A13           SLA  R3,1
  116. FC5C: 17FD           JNC  >FC58            ; count first bit set to 1
  117. in R3, i.e. first switch pressed
  118. FC5E: 04A5 FC62      X    @>FC62(R5)    ; execute command as needed
  119. FC62: 10DF           JMP  >FC22            ; jump to display value if
  120. the X instruction did not jump
  121.  
  122. ; Programmer panel instruction table.
  123. ; All jump offsets must be relative to >FC62, since this is the value of PC
  124. when X
  125. ; executes the instruction in the table.
  126. FC64: 1013           JMP  *+>FC88->FC62    ; "Halt/SIE" switch
  127. FC66: 1011           JMP  *+>FC84->FC62 ; "Run" switch
  128. FC68: 0360           RSET               ; "Reset" switch
  129. FC6A: 101A           JMP  *+>FC96->FC62 ; "Load" switch
  130. FC6C: C10D           MOV  R13,R4        ; "Display WP" switch
  131. FC6E: C10E           MOV  R14,R4        ; "Display PC" switch
  132. FC70: C10F           MOV  R15,R4        ; "Display ST" switch
  133. FC72: C107           MOV  R7,R4         ; "Display MA" switch
  134. FC74: C344           MOV  R4,R13        ; "Enter WP" switch
  135. FC76: C384           MOV  R4,R14        ; "Enter PC" switch
  136. FC78: C3C4           MOV  R4,R15        ; "Enter ST" switch
  137. FC7A: C1C4           MOV  R4,R7         ; "Enter MA" switch
  138. FC7C: C117           MOV  *R7,R4        ; "MDD" switch ("Memory Data Display")
  139. FC7E: 05C7           INCT R7            ; "MAI" switch ("Memory Address
  140. Increment")
  141. FC80: C5C4           MOV  R4,*R7        ; "MDE" switch ("Memory Data Enter")
  142. FC82: 04C4           CLR  R4            ; "CLR" switch
  143.  
  144. ; Code for run switch
  145. FC84: 1D0A           SBO  >000A         ; switch "Run" light on
  146. FC86: 0380           RTWP               ; return to interrupt point
  147.  
  148. ; code for "Halt/SIE" switch
  149. FC88: 1D0E           SBO  >000E         ; set "Single Instruction Execute"
  150. FC8A: 0380           RTWP               ; Restart trap will occur after 2
  151. instructions
  152. ; The second instruction executed will be an instruction from the program
  153. we interrupted.
  154. ; Pressing the HALT/SIE switch repetitively, you will trace the current
  155. program.
  156.  
  157. ; this routine reads a row of 8 switches from the programmer panel
  158. FC8C: 1D0D           SBO  >000D         ; start panel timer
  159. FC8E: 1F0A           TB   >000A         ; wait for timer active bit to be set
  160. FC90: 16FE           JNE  >FC8E
  161. FC92: 3603           STCR R3,8          ; retrieve value
  162. FC94: 045B           B    *R11
  163.  
  164.  
  165. ; Real boot routine
  166. ;
  167. ; We can load from several devices : MDU (Maintenance Diagnostics Unit,
  168. with a tape reader),
  169. ; ASR (a data terminal with optionnal tape reader), card reader, a tape
  170. unit with MT3200 controller,
  171. ; a double-sided floppy disk or a hard disk with WD900 controller
  172. (intelligent controllers on TI-LINE
  173. ; memory bus).
  174. ;
  175. ; tape units (MDU, ASR and MT3200) and card reader use some object code
  176. encoded with alphanumeric and
  177. ; hexadecimal characters.
  178. ; disks (double-sided floppies and hard-disk) use binary code.
  179. ;
  180. FC96: 0360           RSET               ; RESET external peripherals
  181. FC98: 0203 FDFE      LI   R3,>FDFE      ; address of the start-up routine
  182. we jump to - defaults to error routine
  183. FC9C: 0205 F7FE      LI   R5,>F7FE      ; last word before system memory space
  184. FCA0: 020B FDFC      LI   R11,>FDFC     ; pointer to the read routine used
  185. by the object code interpreter
  186. FCA4: C381           MOV  R1,R14        ; if programmer panel enabled,
  187. TILINE peripheral to boot from
  188. FCA6: C3C2           MOV  R2,R15        ; if programmer panel enabled, unit
  189. to load from
  190.  
  191. ; simple memory test >F7FE -> >0000
  192. FCA8: C555           MOV  *R5,*R5       ; try to read and write current word
  193. FCAA: 0645           DECT R5
  194. FCAC: 18FD           JOC  >FCA8         ; loop until we wrap around to >FFFE
  195.  
  196. ; now real boot
  197. FCAE: 1D0A           SBO  >000A         ; switch "Run" light on
  198. FCB0: 1F0E           TB   >000E         ; this bit must tell a MDU is present
  199. FCB2: 1302           JEQ  >FCB8         ; jump if not present
  200. FCB4: 04C0           CLR  R0
  201. FCB6: 102B           JMP  >FD0E         ; boot from the MDU ?
  202.  
  203. FCB8: C000           MOV  R0,R0         ; read boot device type (defaults
  204. to -1)
  205. FCBA: 1139           JLT  >FD2E         ; boot from TILINE tape or disk
  206. device (FD1000, hard disk...)
  207. FCBC: 020C 0040      LI   R12,>0040     ; device address >020 : card reader
  208. FCC0: C000           MOV  R0,R0
  209. FCC2: 1605           JNE  >FCCE         ; skip if card reader
  210. FCC4: 04CC           CLR  R12           ; device address >000 : 733 ASR
  211. FCC6: 1D09           SBO  >0009
  212. FCC8: 1D0A           SBO  >000A
  213. FCCA: 3220 FDF4      LDCR @>FDF4,8      ; effectively writes >11
  214.  
  215.  
  216. FCCE: C000           MOV  R0,R0
  217. FCD0: 131E           JEQ  >FD0E         ; skip if ASR
  218. FCD2: 1109           JLT  >FCE6         ; skip if TILINE tape unit
  219. FCD4: 1F07           TB   >0007         ; set up card reader at CRU address
  220. >020
  221. FCD6: 13FE           JEQ  >FCD4
  222. FCD8: 1F01           TB   >0001
  223. FCDA: 13FE           JEQ  >FCD8
  224. FCDC: 1E0F           SBZ  >000F
  225. FCDE: 1F07           TB   >0007
  226. FCE0: 16FE           JNE  >FCDE
  227. FCE2: 1D0F           SBO  >000F
  228. FCE4: 1014           JMP  >FD0E
  229.  
  230. ; entry point to boot from TILINE tape unit (MT3200 controller or equivalent)
  231. FCE6: C183           MOV  R3,R6         ; save R3, R5
  232. FCE8: C285           MOV  R5,R10
  233. FCEA: 04C0           CLR  R0            ; meaningless
  234. FCEC: 04C1           CLR  R1            ; meaningless
  235. FCEE: 04C2           CLR  R2            ; read offset = 0 (read record from
  236. the beginning)
  237. FCF0: 0203 0050      LI   R3,>0050      ; char count = >0050 (max record
  238. lenght = 80 chars)
  239.                                         ; It seems that we cannot have more
  240. than 80 bytes of code !
  241. FCF4: 04C4           CLR  R4            ; load at address 0
  242. FCF6: 0205 0400      LI   R5,>0400      ; >4 : read binary forward command
  243. FCFA: E14F           SOC  R15,R5        ; set unit ID
  244. FCFC: 06A0 FF32      BL   @>FF32        ; execute command on tape unit
  245. FD00: D920 FDD9 0050 MOVB @>FDD9,@>0050(R4) ; append carriage return after
  246. the data we read (@>FDD9 = >0D)
  247. FD06: C0C6           MOV  R6,R3         ; restore R3, R5
  248. FD08: C14A           MOV  R10,R5
  249. FD0A: 020B FDFC      LI   R11,>FDFC     ; pointer to the read routine used
  250. by the object code interpreter
  251.  
  252. ; entry point to boot from MDU
  253. FD0E: 04C7           CLR  R7            ; clear checksum
  254.  
  255. ; object code interpreter
  256. ;
  257. ; ASR, MDU, MT3200 tapes and cards use object code, as described in the
  258. Model 990 Computer Programming
  259. ; Card.
  260. ;
  261. ; We receive characters from the boot device.  These are interpreted as
  262. commands or as hexadecimal
  263. ; immediate operands.  Note that we actually only use hexadecimal
  264. characters, and 'G','H',':'.
  265. ;
  266. ; Commands with 16-bit immediate (encoded in hexadecimal) :
  267. ; * '1' : Absolute Entry Address : boot routine address = IMM
  268. ; * '2' : Relocatable Entry Address : boot routine address = offset + IMM
  269. ; * '7' : Checksum : stops the machine if (sum of all data received since
  270. start of record) + IMM != 0
  271. ; * '9' : Absolute Load Address : memory address pointer = IMM
  272. ; * 'A' : Relocatable Load Address : memory address pointer = offset + IMM
  273. ; * 'B' : Absolute Data : * (memory address pointer ++) = IMM
  274. ; * 'C' : Relocatable Data : * (memory address pointer ++) = offset + IMM
  275. ; * 'D' : Load Bias Or Offset : offset = IMM
  276. ; * 'E' : (no reference) : stop the machine
  277. ;
  278. ; Control commands (parameter-less) :
  279. ; * ':' : (no reference) : branch to boot routine address
  280. ; * 'F' : End Of Record : wait for next card to be inserted (does not
  281. really work)
  282. ;
  283. ; Unsupported commands with 16-bit immediate (encoded in hexadecimal) :
  284. ; * '8' : Ignore Checksum Value : does nothing
  285. ; * 'J' : (no reference)
  286. ; Unsupported commands with 16-bit immediate (encoded in hexadecimal) and
  287. 6-char symbol name :
  288. ; * '3', '4', '5', '6', 'G', 'H' (symbol-related commands)
  289. ; Unsupported commands with 16-bit immediate (encoded in hexadecimal) and
  290. 8-char program name :
  291. ; * '0' : Program Start
  292. ; * 'I' : (no reference)
  293. ;
  294. FD10: 069B           BL   *R11          ; read command number in R10 from
  295. tape (range 0-19)
  296. FD12: D0AA FE18      MOVB @>FE18(R10),R2    ; read offset to routine in table
  297. FD16: 132C           JEQ  >FD70         ; handle 'F' command separately
  298. because it is parameter-less
  299. FD18: 0882           SRA  R2,8          ; convert to signed 16-bit offset
  300. FD1A: C207           MOV  R7,R8         ; save checksum
  301. FD1C: 0201 0004      LI   R1,>0004      ; 4*4 = 16 bits to read
  302. FD20: 069B           BL   *R11          ; read hex digit (4 bits)
  303. FD22: 0A46           SLA  R6,4          ; shift digits we have already read
  304. FD24: A18A           A    R10,R6        ; and insert new digit in R6
  305. FD26: 0601           DEC  R1
  306. FD28: 16FB           JNE  >FD20         ; loop until we have read a 16-bit
  307. hex value
  308. FD2A: 0462 FD2A      B    @>FD2A(R2)    ; jump to routine
  309.  
  310.  
  311. ; Boot from a tape/disk unit using MD900/MT3200 controller or equivalent on
  312. the TILINE bus
  313. ;
  314. ; The routine expects the unit mask to be in R15.
  315.  
  316. FD2E: C10F           MOV  R15,R4        ; current unit mask : 1 (and only
  317. 1) bit must be set
  318. FD30: 0A44           SLA  R4,4
  319. FD32: 13D9           JEQ  >FCE6         ; routine for tape unit
  320. FD34: 0460 FE86      B    @>FE86        ; routine for disk unit
  321.  
  322.  
  323. ; entry point for '3', '4', '5', '6','G','H'
  324. ; read 6 additional characters and ignore them
  325. FD38: 0201 0006      LI   R1,>0006      ; read 6 chars
  326. FD3C: 1015           JMP  >FD68
  327.  
  328. ; entry point for 'A'
  329. ; add offset to R6, set address pointer
  330. FD3E: A189           A    R9,R6         ; add offset to R6 (R9 set by 'D'
  331. command, defaults to >00A0)
  332. ; entry point for '9'
  333. ; set address pointer
  334. FD40: C146           MOV  R6,R5
  335. FD42: 10E6           JMP  >FD10         ; next command
  336.  
  337. ; entry point for 'C'
  338. ; add offset to R6, write two bytes
  339. FD44: A189           A    R9,R6
  340. ; entry point for 'B'
  341. ; write two bytes
  342. FD46: DD46           MOVB R6,*R5+
  343. FD48: 06C6           SWPB R6
  344. FD4A: DD46           MOVB R6,*R5+
  345. FD4C: 10E1           JMP  >FD10
  346.  
  347. ; entry point for '7'
  348. ; check checksum
  349. FD4E: A206           A    R6,R8
  350. FD50: 13DF           JEQ  >FD10         ; continue on if value matches checksum
  351. ; entry point for 'E'
  352. ; boot failure
  353. FD52: 046B 0002      B    @>0002(R11)   ; jump to >FDFE (IDLE)
  354.  
  355. ; entry point for 'D'
  356. ; set bias/offset
  357. FD56: C246           MOV  R6,R9         ; set bias/offset value
  358. FD58: 0249 FFFE      ANDI R9,>FFFE      ; convert to word address
  359. FD5C: 10D9           JMP  >FD10
  360.  
  361. ; entry point for '2'
  362. ; add offset to R6, set boot routine address
  363. FD5E: A189           A    R9,R6
  364. ; entry point for '1'
  365. ; set boot routine address
  366. FD60: C0C6           MOV  R6,R3         ; set boot routine address
  367. FD62: 10D6           JMP  >FD10
  368.  
  369. ; entry point for '0','I'
  370. ; read 8 additionnal characters and ignore them
  371. FD64: 0201 0008      LI   R1,>0008      ; read 8 chars
  372. FD68: 069B           BL   *R11
  373. FD6A: 0601           DEC  R1
  374. FD6C: 16FD           JNE  >FD68
  375. FD6E: 10D0           JMP  >FD10
  376.  
  377. ; entry point for 'F' command (parameter-less)
  378. ; wait for next card to be inserted
  379. FD70: 069B           BL   *R11
  380. FD72: 16FE           JNE  >FD70         ; wait for next card
  381. FD74: 10AC           JMP  >FCCE
  382.  
  383. ; read routine
  384. ; Read ASCII character from 733 ASR located at >000, a MDU unit located at
  385. >FF0, a MT3200 tape unit
  386. ; on TILINE bus, or a card reader located at >020, and translate it to one
  387. hexadecimal number.
  388. ; The routine for the card reader includes Hollerith->ASCII code conversion.
  389. FD76: C000           MOV  R0,R0            ; test device type flag
  390. FD78: 1327           JEQ  >FDC8            ; jump if ASR
  391. FD7A: 112B           JLT  >FDD2            ; jump if MT3200
  392.  
  393. ; card reader located at >020
  394. ;
  395. ; Read Hollerith code, and translate it to ASCII code, then hexadecimal number.
  396. ; Seems to set EQ flag if the card is not inserted and R10 contains 0.
  397. FD7C: 1F07           TB   >0007         ; test whether card is inserted ?
  398. FD7E: 1622           JNE  >FDC4
  399. FD80: 1F0F           TB   >000F         ; wait for next row of punch holes ?
  400. FD82: 16FC           JNE  >FD7C
  401. FD84: 340A           STCR R10,16        ; read code
  402. ;
  403. ; Encoding :
  404. ;
  405. ; We use Hollerith code.  It uses 12 lines (0-9 and 11-12), plus one
  406. synchro line.
  407. ;
  408. ; Line map :
  409. ;                          MSB                       LSB
  410. ; CRU bit :      15 14 13 12 11 10  9  8    7  6  5  4  3  2  1  0
  411. ; register bit :  0  1  2  3  4  5  6  7    8  9 10 11 12 13 14 15
  412. ; card line :     ?  1  2  3  4  5  6  7    | 12 11  0  9  8  ? synchro
  413. ;
  414. ; line | may be a card sensor.
  415. ;
  416. ; Hollerith character codes (source : Model 990 Computer Programming Card) :
  417. ;
  418. ; Space : Blank & : 12          - : 11          0 : 0
  419. ; 1 : 1         A/a : 12-1      J/j : 11-1      / : 0-1
  420. ; 2 : 2         B/b : 12-2      K/k : 11-2      S/s : 0-2
  421. ; 3 : 3         C/c : 12-3      L/l : 11-3      T/t : 0-3
  422. ; 4 : 4         D/d : 12-4      M/m : 11-4      U/u : 0-4
  423. ; 5 : 5         E/e : 12-5      N/n : 11-5      V/v : 0-5
  424. ; 6 : 6         F/f : 12-6      O/o : 11-6      W/w : 0-6
  425. ; 7 : 7         G/g : 12-7      P/p : 11-7      X/x : 0-7
  426. ; 8 : 8         H/h : 12-8      Q/q : 11-8      Y/y : 0-8
  427. ; 9 : 9         I/i : 12-9      R/r : 11-9      Z/z : 0-9
  428. ; : : 2-8       [ : 12-2-8      ] : 11-2-8      \ : 0-2-8
  429. ; # : 3-8       . : 12-3-8      $ : 11-3-8      , : 0-3-8
  430. ; @ : 4-8       < : 12-4-8      * : 11-4-8      % : 0-4-8
  431. ; ' : 5-8       ( : 12-5-8      ) : 11-5-8      _ : 0-5-8
  432. ; = : 6-8       + : 12-6-8      ; : 11-6-8      > : 0-6-8
  433. ; " : 7-8       ! : 12-7-8      ^ : 11-7-8      ? : 0-7-8
  434.  
  435. FD86: 04C0           CLR  R0
  436. FD88: 04CC           CLR  R12
  437. FD8A: 092A           SRL  R10,2
  438.  
  439. FD8C: 04CD           CLR  R13
  440. FD8E: 0204 000D      LI   R4,>000D        ; 13 lines to test
  441. FD92: 091A           SRL  R10,1            ; test line
  442. FD94: 170B           JNC  >FDAC            ; skip if line not punched
  443.  
  444. FD96: D024 FE6B      MOVB @>FE6B(R4),R0    ; read compatibility mask
  445. FD9A: 2700           CZC  R0,R12        ; test ((R0 & ~R12) == R0)
  446. - this checks that the current line
  447. FD9C: 1304           JEQ  >FDA6            ; is not incompatible with
  448. the lines we have interpreted so far
  449. FD9E: 0203 C001      LI   R3,>C001        ; error code
  450. FDA2: 0460 FF9E      B    @>FF9E        ; abort boot in error
  451.  
  452. FDA6: B364 FE78      AB   @>FE78(R4),R13    ; else, add offset
  453. associated with line
  454. FDAA: E300           SOC  R0,R12        ; and update mask in R12
  455.  
  456. FDAC: 0604           DEC  R4
  457. FDAE: 15F1           JGT  >FD92            ; test next line
  458.  
  459. FDB0: 098D           SRL  R13,8            ; 8-bit -> 16-bit offset
  460. FDB2: D2AD FE2C      MOVB @>FE2C(R13),R10    ; read ascii code in table
  461. FDB6: 098A           SRL  R10,8            ; convert to 16-bit value
  462. FDB8: C00A           MOV  R10,R0
  463.  
  464. FDBA: 020C 0040      LI   R12,>0040
  465. FDBE: 1F0F           TB   >000F
  466. FDC0: 13FE           JEQ  >FDBE         ; wait for device ready ?
  467. FDC2: 1012           JMP  >FDE8         ; goto character decode routine
  468.  
  469. ; we jump there if no card is inserted (?) when reading from the card
  470. reader located at >020
  471. FDC4: 828A           C    R10,R10
  472. FDC6: 1019           JMP  >FDFA
  473.  
  474. ; read routine
  475. ; Read ASCII character from 733 ASR located at >000 or MDU unit located at
  476. >FF0, and translate it to
  477. ; one hexadecimal number.
  478. FDC8: 1F0C           TB   >000C         ; wait for incoming character ?
  479. FDCA: 16FE           JNE  >FDC8
  480. FDCC: 1E0C           SBZ  >000C
  481. FDCE: 35CA           STCR R10,7         ; read 7-bit ASCII character
  482. FDD0: 1001           JMP  >FDD4
  483.  
  484. FDD2: D2B4           MOVB *R4+,R10      ; read byte from memory (MT3200 is
  485. DMA driven)
  486.  
  487. FDD4: 098A           SRL  R10,8         ; move MSB to LSB
  488. FDD6: 028A 000D      CI   R10,>000D     ; carriage return ? (appended at
  489. end of MT3200 record)
  490. FDDA: 130F           JEQ  >FDFA         ; if so return
  491. FDDC: 028A 005A      CI   R10,>005A     ; greater than 'Z' ?
  492. FDE0: 15CA           JGT  >FD76         ; if so, ignore current char and
  493. read next char
  494. FDE2: 028A 0020      CI   R10,>0020     ; control character (lower than ' ') ?
  495. FDE6: 11C7           JLT  >FD76         ; if so, ignore current char and
  496. read next char
  497. FDE8: A1CA           A    R10,R7        ; update checksum
  498. FDEA: 022A FFD0      AI   R10,>FFD0     ; substract >30 (numeric character
  499. -> numeric value)
  500. FDEE: 028A 000A      CI   R10,>000A
  501. FDF2: 1306           JEQ  >FE00         ; jump to handler if it is ':'
  502. FDF4: 1102           JLT  >FDFA         ; if greater, it must be 'A'-'F'
  503. (or 'G', 'H'...)
  504. FDF6: 022A FFF9      AI   R10,>FFF9     ; convert to hex value
  505. FDFA: 069B           BL   *R11          ; trick : return to the caller AND
  506. restore R11 to be >FDFC
  507.  
  508. ; entry point for the routine which reads data from the boot device
  509. FDFC: 10BC           JMP  >FD76
  510.  
  511. FDFE: 0340           IDLE               ; stop the machine
  512.  
  513. ; entry point for the ':' command (parameter-less command)
  514. ; jump to external boot routine
  515. FE00: C000           MOV  R0,R0
  516. FE02: 1608           JNE  >FE14
  517. FE04: 1E0B           SBZ  >000B         ; clean up the ASR status ?
  518. FE06: 1E0C           SBZ  >000C
  519. FE08: 0581           INC  R1
  520. FE0A: 16FE           JNE  >FE08
  521. FE0C: 1F0C           TB   >000C
  522. FE0E: 13F8           JEQ  >FE00
  523. FE10: 1E09           SBZ  >0009
  524. FE12: 1E0D           SBZ  >000D
  525.  
  526. FE14: 0360           RSET               ; reset peripherals
  527. FE16: 0453           B    *R3           ; jumps to boot routine specified
  528. by >1 or >2 command
  529.                                         ; (jumps to >FDFE if no routine was
  530. specified)
  531.  
  532.  
  533. ; offset table for jumps in object code interpreter, used on >FD2A (offsets
  534. relative to >FD2A)
  535. FE18: 3A36 340E      BYTE >FD64->FD2A,>FD60->FD2A,>FD5E->FD2A,>FD38->FD2A
  536. FE1C: 0E0E 0E22      BYTE >FD38->FD2A,>FD38->FD2A,>FD38->FD2A,>FD4E->FD2A
  537. FE20: E616 141C      BYTE >FD10->FD2A,>FD40->FD2A,>FD3E->FD2A,>FD46->FD2A
  538. FE24: 1A2C 2E00      BYTE >FD44->FD2A,>FD56->FD2A,>FD52->FD2A,>00
  539. FE28: 0E0E 3AE6      BYTE >FD38->FD2A,>FD38->FD2A,>FD64->FD2A,>FD10->FD2A
  540.  
  541.  
  542. ; table used for the 2nd step of the hollerith->ascii code conversion
  543. ; blank, 1, 2, 3, ..., 7
  544. FE2C: 2031 3233      BYTE ' ','1','2','3'
  545. FE30: 3435 3637      BYTE '4','5','6','7'
  546. ; 0, 0-1, 0-2, ..., 0-7
  547. FE34: 302F 5354      BYTE '0','/','S','T'
  548. FE38: 5556 5758      BYTE 'U','V','W','X'
  549. ; 11, 11-1, ..., 11-7
  550. FE3C: 2D4A 4B4C      BYTE '-','J','K','L'
  551. FE40: 4D4E 4F50      BYTE 'M','N','O','P'
  552. ; 12, 12-1, ..., 12-7
  553. FE44: 2641 4243      BYTE '&','A','B','C'
  554. FE48: 4445 4647      BYTE 'D','E','F','G'
  555. ; 8, 9, 2-8, 3-8, ..., 7-8
  556. FE4C: 3839 3A23      BYTE '8','9',':','#'
  557. FE50: 4027 3D22      BYTE '@',''','=','"'
  558. ; 0-8, 0-9, 0-2-8, 0-3-8, ..., 0-7-8
  559. FE54: 595A 5C2C      BYTE 'Y','Z','\',','
  560. FE58: 255F 3E3F      BYTE '%','_','>','?'
  561. ; 11-8, 11-9, 11-2-8, 11-3-8, ..., 11-7-8
  562. FE5C: 5152 5D24      BYTE 'Q','R',']','$'
  563. FE60: 2A29 3B5E      BYTE '*',')',';','^'
  564. ; 12-8, 12-9, 12-2-8, 12-3-8, ..., 12-7-8
  565. FE64: 4849 5B2E      BYTE 'H','I','[','.'
  566. FE68: 3C28 2B21      BYTE '<','(','+','!'
  567.  
  568. ; table used for hollerith->ascii code conversion :
  569. ; it allows to detect impossible superposition.
  570. ; line order : 1  2  3  4  5  6  7  | 12 11  0  9  8
  571. ;
  572. ; rules :
  573. ; * at most one punch in lines 1 2 3 4 5 6 7 and 9 (>01 mask)
  574. ; * lines 8 and 1 cannot be punched simulteanously (line 9 must be used
  575. instead) (>02 mask)
  576. ; * at most one punch in lines 0 11 12 (>04 mask)
  577. ;
  578. ; Note that the >08 mask is needed to prevent the program from rejecting
  579. character when the | line is
  580. ; punched.
  581. ;
  582. FE6C: 0301 0101      BYTE >03,>01,>01,>01
  583. FE70: 0101 0108      BYTE >01,>01,>01,>08
  584. FE74: 0404 0403      BYTE >04,>04,>04,>03
  585. FE78: 02             BYTE >02
  586.  
  587. ; table used for the 1st step of the hollerith->ascii code conversion :
  588. ; it provides an offset associated with each line.
  589. ; line order : 1  2  3  4  5  6  7  | 12 11  0  9  8
  590. FE79:   01 0203      BYTE >01,>02,>03
  591. FE7C: 0405 0607      BYTE >04,>05,>06,>07
  592. FE80: 0018 1008      BYTE >00,>18,>10,>08
  593. FE84: 2120           BYTE >21,>20
  594.  
  595.  
  596. ; boot from a disk unit attached to a WD900 disk controller (or equivalent)
  597. whose address is in R14
  598. FE86: C14F           MOV  R15,R5        ; unit ID
  599. FE88: 020C FF32      LI   R12,>FF32
  600.  
  601. FE8C: 0200 0700      LI   R0,>0700        ; restore command
  602. FE90: 04C1           CLR  R1
  603. FE92: 069C           BL   *R12            ; execute command
  604.  
  605. FE94: 04C0           CLR  R0            ; store register command
  606. FE96: 04C1           CLR  R1
  607. FE98: 0203 0006      LI   R3,>0006        ; command returns 6 bytes
  608. FE9C: 0204 0200      LI   R4,>0200        ; free area in RAM
  609. FEA0: 069C           BL   *R12
  610. FEA2: C2A4 0004      MOV  @>0004(R4),R10
  611. FEA6: 09BA           SRL  R10,11        ; keep number of track per
  612. cylinder (i.e. number of heads)
  613.  
  614. FEA8: 0200 0400      LI   R0,>0400        ; read unformatted
  615. FEAC: 04C1           CLR  R1            ; cylinder 0
  616. FEAE: 04C2           CLR  R2
  617. FEB0: 069C           BL   *R12            ; read current
  618. track/cylinder address, # of sectors per record, and sector length
  619.  
  620. FEB2: C004           MOV  R4,R0            ; >0200 : read data
  621. FEB4: D064 0002      MOVB @>0002(R4),R1    ; set the "sectors per records" field
  622. FEB8: C0E4 0004      MOV  @>0004(R4),R3    ; count = sector lenght
  623. FEBC: 0A13           SLA  R3,1            ; word count -> byte count
  624. FEBE: 069C           BL   *R12            ; (reads record #0)
  625. FEC0: C3E4 000E      MOV  @>000E(R4),R15    ; alternate boot program
  626. track address
  627. FEC4: 890F 0024      C    R15,@>0024(R4)    ; compare with normal
  628. program track address
  629. FEC8: 130D           JEQ  >FEE4
  630.  
  631. FECA: C924 0024 000E MOV  @>0024(R4),@>000E(R4)    ; replace alternate boot
  632. program, with normal one
  633.                                         ; so alternate program will be
  634. loaded only once
  635. FED0: 0200 0300      LI   R0,>0300        ; write data
  636. FED4: 069C           BL   *R12            ; write record back
  637. FED6: C824 001C 00A0 MOV  @>001C(R4),@>00A0    ; use alternate load point
  638. FEDC: C824 001E 00A2 MOV  @>001E(R4),@>00A2    ; and alternate length
  639. FEE2: 1006           JMP  >FEF0
  640.  
  641. FEE4: C824 0018 00A0 MOV  @>0018(R4),@>00A0    ; use normal load point
  642. FEEA: C824 001A 00A2 MOV  @>001A(R4),@>00A2    ; use normal length
  643.  
  644. FEF0: 0200 0400      LI   R0,>0400        ; read unformatted
  645. FEF4: 0203 0006      LI   R3,>0006        ; command returns 6 bytes
  646. FEF8: 06A0 FF26      BL   @>FF26        ; compute cylinder/head
  647. address from track address in R15
  648. FEFC: 069C           BL   *R12
  649.  
  650. FEFE: C064 0002      MOV  @>0002(R4),R1    ; set format & sector according to
  651. value returned by controller
  652. FF02: 0200 0200      LI   R0,>0200        ; >0200 : read data
  653. FF06: C0E0 00A2      MOV  @>00A2,R3        ; program length
  654. FF0A: 0204 00A0      LI   R4,>00A0        ; free area in RAM ?
  655. FF0E: 06A0 FF26      BL   @>FF26
  656. FF12: C3E0 00A0      MOV  @>00A0,R15    ; program load point
  657. FF16: 069C           BL   *R12            ; read boot program
  658.  
  659. FF18: 0200 ABC0      LI   R0,>ABC0        ; magical value ?
  660. FF1C: C04E           MOV  R14,R1        ; boot device address
  661. FF1E: 04C2           CLR  R2
  662. FF20: D085           MOVB R5,R2            ; unit ID
  663. FF22: 0360           RSET                ; Reset for things
  664. to be cleaner
  665. FF24: 045F           B    *R15            ; jump to boot program
  666.  
  667. ; compute cylinder & head address from "flat" track address
  668. ; input :
  669. ; R10 = number of heads
  670. ; R15 = track address
  671. ; returns :
  672. ; R2 = cylinder address
  673. ; R0 |= head address
  674. FF26: C24F           MOV  R15,R9
  675. FF28: 04C8           CLR  R8
  676. FF2A: 3E0A           DIV  R10,R8        ; compute R15/R10
  677. FF2C: C088           MOV  R8,R2            ; R2 = quotient : cylinder
  678. address
  679. FF2E: E009           SOC  R9,R0            ; R0 LSB = remainder : head
  680. address
  681. FF30: 045B           B    *R11
  682.  
  683.  
  684. ; execute some command on a WD900/WT3200 controller
  685. ; R0 -> W1 : command and surface register (WD900)
  686. ; R1 -> W2 : format and sector (MSByte : sectors per record ; LSByte :
  687. sector number) (WD900)
  688. ; R2 -> W3 : cylinder address (cylinder number) (WD900) / read offset (WT3200)
  689. ; R3 -> W4 : count (length to read/write)
  690. ; R4 -> W5 : address (destination/source address to read/write from, 16 LSBits)
  691. ; R5 -> W6 : WD900 : select and address (unit selection, 1 bit per unit, in
  692. LOW nibble of MSByte, and
  693. ;           4 MSBits of address in low nibble of LSByte)
  694. ;            WT3200 : command and transport select (unit selection, 1 bit
  695. per unit, in HIGH nibble
  696. ;           of MSByte, command in high nibble of LSByte, and 4 MSBits of
  697. address in low nibble of
  698. ;           LSByte)
  699. ;
  700. ; R14 = controller address
  701. ;
  702. ; cf 990 Handbook, 5-23, page 188, and WD900/MT3200 general description,
  703. chapter 3
  704. ;
  705. FF32: 020D 0005      LI   R13,>0005        ; retry count
  706. FF36: C1CE           MOV  R14,R7        ; TILINE device address
  707. FF38: C227 000E      MOV  @>000E(R7),R8
  708. FF3C: 1101           JLT  >FF40
  709. FF3E: 10FB           JMP  >FF36            ; wait for IDLE controller
  710. status bit to be cleared
  711.  
  712. FF40: C9C5 000C      MOV  R5,@>000C(R7)
  713. FF44: C5D7           MOV  *R7,*R7
  714. FF46: 11FC           JLT  >FF40
  715.  
  716. FF48: 04F7           CLR  *R7+            ; disc status
  717. FF4A: CDC0           MOV  R0,*R7+
  718. FF4C: CDC1           MOV  R1,*R7+
  719. FF4E: CDC2           MOV  R2,*R7+
  720. FF50: CDC3           MOV  R3,*R7+
  721. FF52: CDC4           MOV  R4,*R7+
  722. FF54: CDC5           MOV  R5,*R7+
  723. FF56: 04D7           CLR  *R7
  724.  
  725. FF58: C217           MOV  *R7,R8
  726. FF5A: 1101           JLT  >FF5E
  727. FF5C: 10FD           JMP  >FF58            ; wait for IDLE controller
  728. status bit to be cleared
  729.  
  730. FF5E: C1C5           MOV  R5,R7
  731. FF60: 0247 F000      ANDI R7,>F000        ; 4 MSBits select unit on WT3200,
  732. and are unused on WD900
  733. FF64: 1604           JNE  >FF6E            ; skip if we are using a
  734. tape unit
  735.  
  736. FF66: C1DE           MOV  *R14,R7        ; disk status
  737. FF68: 0247 4000      ANDI R7,>4000
  738. FF6C: 16FC           JNE  >FF66            ; wait for NR (Not Ready)
  739. status bit to be cleared
  740.  
  741. FF6E: 0248 01FF      ANDI R8,>01FF        ; test all individual error
  742. bits in controller status
  743. FF72: 1602           JNE  >FF78            ; jump on error
  744.  
  745. FF74: 0700           SETO R0
  746. FF76: 045B           B    *R11            ; normal return
  747.  
  748. ; error handler :
  749. FF78: C1C5           MOV  R5,R7
  750. FF7A: 0247 F000      ANDI R7,>F000
  751. FF7E: 1303           JEQ  >FF86            ; jump if disk unit
  752.  
  753. FF80: 0203 D001      LI   R3,>D001        ; error code
  754. FF84: 100C           JMP  >FF9E            ; stop in error
  755.  
  756. FF86: 0288 0001      CI   R8,>0001        ; check unit error in
  757. controller status
  758. FF8A: 1604           JNE  >FF94            ; if set, means an error
  759. condition is set in disk status
  760.  
  761. FF8C: C21E           MOV  *R14,R8        ; read disk status
  762. FF8E: 0248 E000      ANDI R8,>E000        ; test bits OL, NR, WP
  763. (Off-line, not-ready, write-protect)
  764. FF92: 16CF           JNE  >FF32            ; restarts everything !
  765. (must be a bug...)
  766.  
  767. FF94: 060D           DEC  R13            ; decrement retry count
  768. FF96: 15CF           JGT  >FF36            ; try again
  769.  
  770. FF98: 0203 D002      LI   R3,>D002        ; error code
  771. FF9C: 1000           JMP  >FF9E            ; stop in error
  772.  
  773. ; error stop
  774. ; we jump to this routine when boot fails
  775. ; display R3 for diagnostics purpose, light the fail LED, and stop.
  776. FF9E: 020C 1FE0      LI   R12,>1FE0
  777. FFA2: 1D0B           SBO  >000B
  778. FFA4: 3203           LDCR R3,8
  779. FFA6: 3220 0087      LDCR @>0087,8
  780. FFAA: 0340           IDLE
  781.  
  782.  
  783. ; spare room
  784. FFAC: 0000           DATA >0000
  785. FFAE: 0000           DATA >0000
  786. FFB0: 0000           DATA >0000
  787. FFB2: 0000           DATA >0000
  788. FFB4: 0000           DATA >0000
  789. FFB6: 0000           DATA >0000
  790. FFB8: 0000           DATA >0000
  791. FFBA: 0000           DATA >0000
  792. FFBC: 0000           DATA >0000
  793. FFBE: 0000           DATA >0000
  794. FFC0: 0000           DATA >0000
  795. FFC2: 0000           DATA >0000
  796. FFC4: 0000           DATA >0000
  797. FFC6: 0000           DATA >0000
  798. FFC8: 0000           DATA >0000
  799. FFCA: 0000           DATA >0000
  800. FFCC: 0000           DATA >0000
  801. FFCE: 0000           DATA >0000
  802. FFD0: 0000           DATA >0000
  803. FFD2: 0000           DATA >0000
  804. FFD4: 0000           DATA >0000
  805. FFD6: 0000           DATA >0000
  806. FFD8: 0000           DATA >0000
  807. FFDA: 0000           DATA >0000
  808. FFDC: 0000           DATA >0000
  809. FFDE: 0000           DATA >0000
  810. FFE0: 0000           DATA >0000
  811. FFE2: 0000           DATA >0000
  812. FFE4: 0000           DATA >0000
  813. FFE6: 0000           DATA >0000
  814. FFE8: 0000           DATA >0000
  815. FFEA: 0000           DATA >0000
  816. FFEC: 0000           DATA >0000
  817. FFEE: 0000           DATA >0000
  818. FFF0: 0000           DATA >0000
  819. FFF2: 0000           DATA >0000
  820. FFF4: 0000           DATA >0000
  821.  
  822.  
  823. ; pointers to routines
  824. FFF6: FC9C           DATA >FC9C            ; boot loader
  825. FFF8: FC96           DATA >FC96            ; ditto
  826. FFFA: FD0E           DATA >FD0E            ; boot loader for MDU (?)
  827.  
  828. ; LOAD vector
  829. FFFC: 0080 FC00      DATA >0080,>FC00
  830.  
  831.  
  832.