home *** CD-ROM | disk | FTP | other *** search
/ 8bitfiles.net/archives / archives.tar / archives / genie-commodore-file-library / Information / HACK4-4OF5.SFX / hack4.4-5
Encoding:
Text File  |  1990-02-12  |  19.5 KB  |  781 lines

  1. .%083!
  2.  
  3. ╫AIT FOR A BURST BYTE TO ARRIVE IN THE SERIAL DATA REGISTER OF ├╔┴#1 FROM THE
  4. FAST SERIAL BUS.
  5.  
  6. .%084!  SERIAL╫AIT = *
  7. .%085!     LDA #$08
  8. .%086!  -  BIT CIA╞LAGS
  9. .%087!     BEQ -
  10. .%088!     RTS
  11. .%089!
  12.  
  13. ╫AIT FOR AND GET A BURST BYTE FROM THE FAST SERIAL BUS, AND SEND THE "─ATA
  14. ┴CCEPTED" SIGNAL.
  15.  
  16. .%090!  GET┬URST┬YTE = *
  17. .%091!     JSR SERIAL╫AIT
  18. .%092!     LDX CIA─ATA
  19. .%093!     JSR TOGGLE├LOCK
  20. .%094!     TXA
  21. .%095!     RTS
  22. .%096!
  23.  
  24. ╙END THE BURST COMMANDS TO "LOG IN" THE ═╙-─╧╙ DISK AND SET THE ╥EAD SECTOR
  25. INTERLEAVE FACTOR.
  26.  
  27. .%097!  MOUNT─ISK = *  ;() : .├╙=ERR
  28. .%098!     LDA #%00011010
  29. .%099!     JSR SEND╒0
  30. .%100!     BCC +
  31. .%101!     RTS
  32. .%102!  +  JSR KERNEL╒NLSN
  33. .%103!     BIT ST
  34. .%104!     BMI SEND╒0┼RROR
  35. .%105!     CLC
  36. .%106!     JSR KERNEL╙PINP
  37. .%107!     BIT CIA╞LAGS
  38. .%108!     JSR TOGGLE├LOCK
  39. .%109!     JSR GET┬URST┬YTE
  40. .%110!     STA ERRNO
  41. .%111!     AND #$0F
  42. .%112!     CMP #2
  43. .%113!     BCS MOUNT┼XIT
  44.  
  45. ╟RAB THE THROW-AWAY PARAMETERS FROM THE MOUNT OPERATION.
  46.  
  47. .%114!     LDY #0
  48. .%115!  -  JSR GET┬URST┬YTE
  49. .%116!     STA FORMAT╨ARMS,Y
  50. .%117!     INY
  51. .%118!     CPY #6
  52. .%119!     BCC -
  53. .%120!     CLC
  54.  
  55. ╙ET THE SECTOR INTERLEAVE TO 1 FOR A 1581 OR 4 FOR A 1571.
  56.  
  57. .%121!     ;** SET INTERLEAVE
  58. .%122!     LDA #%00001000
  59. .%123!     JSR SEND╒0
  60. .%124!     BCC +
  61. .%125!     RTS
  62. .%126!  +  LDA #1            ;INTERLEAVE OF 1 FOR 1581
  63. .%127!     BIT SOURCE╘YPE
  64. .%128!     BMI +
  65. .%129!     LDA #4            ;INTERLEAVE OF 4 FOR 1571
  66. .%130!  +  JSR KERNEL├IOUT
  67. .%131!     JSR KERNEL╒NLSN
  68. .%132!     MOUNT┼XIT = *
  69. .%133!     RTS
  70. .%134!
  71.  
  72. ╥EAD ALL OF THE SECTORS OF A GIVEN TRACK INTO THE TRACK CACHE.
  73.  
  74. .%135!  BUFPTR = 2
  75. .%136!  SECNUM = 4
  76. .%137!
  77. .%138!  READ╘RACK = *  ;( .┴=CYLINDER, .╪=SIDE ) : TRACKBUF, .├╙=ERR
  78. .%139!     PHA
  79. .%140!     TXA
  80.  
  81. ╟ET THE SIDE AND PUT IT INTO THE COMMAND BYTE.  ╥EMEMBER THAT WE HAVE TO FLIP
  82. THE SIDE BIT FOR A 1581.
  83.  
  84. .%141!     AND #$01
  85. .%142!     ASL
  86. .%143!     ASL
  87. .%144!     ASL
  88. .%145!     ASL
  89. .%146!     BIT SOURCE╘YPE
  90. .%147!     BPL +
  91. .%148!     EOR #$10
  92. .%149!  +  JSR SEND╒0
  93. .%150!     BCC +
  94. .%151!     RTS
  95. .%152!  +  PLA                  ;CYLINDER NUMBER
  96. .%153!     JSR KERNEL├IOUT
  97. .%154!     LDA #1               ;START SECTOR NUMBER
  98. .%155!     JSR KERNEL├IOUT
  99. .%156!     LDA #9               ;SECTOR COUNT
  100. .%157!     JSR KERNEL├IOUT
  101. .%158!     JSR KERNEL╒NLSN
  102.  
  103. ╨REPARE TO RECEIVE THE TRACK DATA.
  104.  
  105. .%159!     SEI
  106. .%160!     CLC
  107. .%161!     JSR KERNEL╙PINP
  108. .%162!     BIT CIA╞LAGS
  109. .%163!     JSR TOGGLE├LOCK
  110. .%164!     LDA #<TRACKBUF
  111. .%165!     LDY #>TRACKBUF
  112. .%166!     STA BUFPTR
  113. .%167!     STY BUFPTR+1
  114.  
  115. ╟ET THE SECTOR DATA FOR EACH OF THE 9 SECTORS OF THE TRACK.
  116.  
  117. .%168!     LDA #0
  118. .%169!     STA SECNUM
  119. .%170!  -  BIT SOURCE╘YPE
  120. .%171!     BMI +
  121.  
  122. ╔F WE ARE DEALING WITH A 1571, WE HAVE TO SET THE BUFFER POINTER FOR THE NEXT
  123. SECTOR, TAKING INTO ACCOUNT THE SOFT INTERLEAVE OF 4.
  124.  
  125. .%172!     JSR GET1571┬UF╨TR
  126. .%173!  +  JSR READ╙ECTOR
  127. .%174!     BCS TRACK┼XIT
  128. .%175!     INC SECNUM
  129. .%176!     LDA SECNUM
  130. .%177!     CMP #9
  131. .%178!     BCC -
  132. .%179!     CLC
  133. .%180!     TRACK┼XIT = *
  134. .%181!     CLI
  135. .%182!     RTS
  136. .%183!
  137.  
  138. ╟ET THE BUFFER POINTER FOR THE NEXT 1571 SECTOR.
  139.  
  140. .%184!  GET1571┬UF╨TR = *
  141. .%185!     LDA #<TRACKBUF
  142. .%186!     STA BUFPTR
  143. .%187!     LDX SECNUM
  144. .%188!     CLC
  145. .%189!     LDA #>TRACKBUF
  146. .%190!     ADC BUFPTR1571,X
  147. .%191!     STA BUFPTR+1
  148. .%192!     RTS
  149. .%193!
  150. .%194!  BUFPTR1571 = *
  151. .%195!     .BYTE 0,8,16,6,14,4,12,2,10
  152. .%196!
  153.  
  154. ╥EAD AN INDIVIDUAL SECTOR INTO MEMORY AT THE SPECIFIED ADDRESS.
  155.  
  156. .%197!  READ╙ECTOR = *  ;( BUFPTR ) : .├╙=ERR
  157.  
  158. ╟ET AND CHECK THE BURST STATUS BYTE FOR ERRORS.
  159.  
  160. .%198!     JSR GET┬URST┬YTE
  161. .%199!     STA ERRNO
  162. .%200!     AND #$0F
  163. .%201!     CMP #2
  164. .%202!     BCC +
  165. .%203!     RTS
  166. .%204!  +  LDX #2
  167. .%205!     LDY #0
  168. .%206!
  169.  
  170. ╥ECEIVE THE 512 SECTOR DATA BYTES INTO MEMORY.
  171.  
  172. .%207!     READ┬YTE = *
  173. .%208!     LDA #$08
  174. .%209!  -  BIT CIA╞LAGS
  175. .%210!     BEQ -
  176. .%211!     LDA CIA├LOCK
  177. .%212!     EOR #$10
  178. .%213!     STA CIA├LOCK
  179. .%214!     LDA CIA─ATA
  180. .%215!     STA (BUFPTR),Y
  181. .%216!     INY
  182. .%217!     BNE READ┬YTE
  183. .%218!     INC BUFPTR+1
  184. .%219!     DEX
  185. .%220!     BNE READ┬YTE
  186. .%221!     RTS
  187. .%222!
  188.  
  189. ╘HIS NEXT LEVEL OF ROUTINES DEALS WITH LOGICAL SECTORS AND THE TRACK CACHE
  190. RATHER THAN WITH HARDWARE.
  191.  
  192. .%223!  ;====LOGICAL SECTOR LEVEL====
  193. .%224!
  194.  
  195. ╔NVALIDATE THE TRACK CACHE IF THE ═╙-─╧╙ DRIVE NUMBER IS CHANGED OR IF A NEW
  196. DISK IS INSERTED.  ╘HIS ROUTINE HAS TO ESTABLISH A ╥┴═ CONFIGURATION OF $0┼
  197. SINCE IT WILL BE CALLED FROM ╥┴═0.  ├ONFIGURATION $0┼ GIVES ╥┴═0 FROM $0000 TO
  198. $┬╞╞╞, ╦ERNAL ╥╧═ FROM $├000 TO $╞╞╞╞, AND THE ╔/╧ SPACE OVER THE ╦ERNAL FROM
  199. $─000 TO $─╞╞╞.  ╘HIS CONFIGURATION IS SET BY ALL APPLICATION INTERFACE
  200. SUBROUTINES.
  201.  
  202. .%225!  INIT╨ACKAGE = *
  203. .%226!     LDA #$0E
  204. .%227!     STA $FF00
  205. .%228!     LDA #$FF
  206. .%229!     STA BUF├YLINDER
  207. .%230!     STA BUF╙IDE
  208. .%231!     CLC
  209. .%232!     RTS
  210. .%233!
  211.  
  212. ╠OCATE A SECTOR (BLOCK) IN THE TRACK CACHE, OR READ THE CORRESPONDING PHYSICAL
  213. TRACK INTO THE TRACK CACHE IF NECESSARY.  ╘HIS ROUTINE ACCEPTS THE CYLINDER,
  214. SIDE, AND SECTOR NUMBERS OF THE BLOCK.
  215.  
  216. .%234!  SECTOR╙AVE = 5
  217. .%235!
  218. .%236!  READ┬LOCK = *  ;( .┴=CYLINDER,.╪=SIDE,.┘=SECTOR ) : .┴┘=BLK╨TR,.├╙=ERR
  219.  
  220. ├HECK IF THE CORRECT TRACK IS IN THE TRACK CACHE.
  221.  
  222. .%237!     CMP BUF├YLINDER
  223. .%238!     BNE READ┬LOCK╨HYSICAL
  224. .%239!     CPX BUF╙IDE
  225. .%240!     BNE READ┬LOCK╨HYSICAL
  226.  
  227. ╔F SO, THEN LOCATE THE SECTOR'S ADDRESS AND RETURN THAT.
  228.  
  229. .%241!     DEY
  230. .%242!     TYA
  231. .%243!     ASL
  232. .%244!     CLC
  233. .%245!     ADC #>TRACKBUF
  234. .%246!     TAY
  235. .%247!     LDA #<TRACKBUF
  236. .%248!     CLC
  237. .%249!     RTS
  238. .%250!
  239.  
  240. ╚ERE, WE HAVE TO READ THE PHYSICAL TRACK INTO THE TRACK CACHE.  ╫E SAVE THE
  241. INPUT PARAMETERS AND CALL THE HARDWARE-LEVEL TRACK-READING ROUTINE.
  242.  
  243. .%251!     READ┬LOCK╨HYSICAL = *
  244. .%252!     STA BUF├YLINDER
  245. .%253!     STX BUF╙IDE
  246. .%254!     STY SECTOR╙AVE
  247. .%255!     JSR READ╘RACK
  248.  
  249. ├HECK FOR ERRORS.
  250.  
  251. .%256!     BCC READ┬LOCK╨HYSICAL╧K
  252. .%257!     LDA ERRNO
  253. .%258!     AND #$0F
  254. .%259!     CMP #11    ;DISK CHANGE
  255. .%260!     BEQ +
  256. .%261!     SEC
  257. .%262!     RTS
  258.  
  259. ╔F THE ERROR THAT HAPPENED IS A "─ISK ├HANGE" ERROR, THEN MOUNT THE DISK AND
  260. TRY TO READ THE PHYSICAL TRACK AGAIN.
  261.  
  262. .%263!  +  JSR MOUNT─ISK
  263. .%264!     LDA BUF├YLINDER
  264. .%265!     LDX BUF╙IDE
  265. .%266!     LDY SECTOR╙AVE
  266. .%267!     BCC READ┬LOCK╨HYSICAL
  267. .%268!     RTS
  268. .%269!
  269.  
  270. ╚ERE, THE PHYSICAL TRACK HAS BEEN READ INTO THE TRACK CACHE OK, SO WE RECOVER
  271. THE ORIGINAL INPUT PARAMETERS AND TRY THE TOP OF THE ROUTINE AGAIN.
  272.  
  273. .%270!     READ┬LOCK╨HYSICAL╧K = *
  274. .%271!     LDA BUF├YLINDER
  275. .%272!     LDX BUF╙IDE
  276. .%273!     LDY SECTOR╙AVE
  277. .%274!     JMP READ┬LOCK
  278. .%275!
  279.  
  280. ─IVIDE THE GIVEN NUMBER BY 18.  ╘HIS IS NEEDED FOR THE CALCULATIONS TO CONVERT
  281. A LOGICAL SECTOR NUMBER TO THE CORRESPONDING PHYSICAL CYLINDER, SIDE, AND
  282. SECTOR NUMBERS THAT THE LOWER-LEVEL ROUTINES REQUIRE.  ╘HE METHOD OF REPEATED
  283. SUBTRACTION IS USED.  ╘HIS ROUTINE WOULD PROBABLY WORK FASTER IF WE TRIED TO
  284. REPEATEDLY SUBTRACT 360 (18*20) AT THE TOP, BUT ╔ DIDN'T BOTHER.
  285.  
  286. .%276!  DIVIDE┬Y18 = *  ;( .┴┘=NUMBER ) : .┴=QUOTIENT, .┘=REMAINDER
  287. .%277!     ;** COULD REPEATEDLY SUBTRACT 360 HERE
  288. .%278!     LDX #$FF
  289. .%279!  -  INX
  290. .%280!     SEC
  291. .%281!     SBC #18
  292. .%282!     BCS -
  293. .%283!     DEY
  294. .%284!     BPL -
  295. .%285!     CLC
  296. .%286!     ADC #18
  297. .%287!     INY
  298. .%288!     TAY
  299. .%289!     TXA
  300. .%290!     RTS
  301. .%291!
  302.  
  303. ├ONVERT THE GIVEN LOGICAL BLOCK NUMBER TO THE CORRESPONDING PHYSICAL CYLINDER,
  304. SIDE, AND SECTOR NUMBERS.  ╘HIS ROUTINE FOLLOWS THE FORMULAE GIVEN EARLIER
  305. WITH A FEW SIMPLIFYING TRICKS.
  306.  
  307. .%292!  CONVERT╠OGICAL┬LOCK╬UM = *  ;( .┴┘=BLOCK╬UM ) : .┴=CYL, .╪=SIDE, .┘=SEC
  308. .%293!     JSR DIVIDE┬Y18
  309. .%294!     LDX #0
  310. .%295!     CPY #9
  311. .%296!     BCC +
  312. .%297!     PHA
  313. .%298!     TYA
  314. .%299!     SBC #9
  315. .%300!     TAY
  316. .%301!     PLA
  317. .%302!     LDX #1
  318. .%303!  +  INY
  319. .%304!     RTS
  320. .%305!
  321.  
  322. ├OPY A SEQUENTIAL GROUP OF LOGICAL SECTORS INTO MEMORY.  ╘HIS ROUTINE IS USED
  323. BY THE DIRECTORY LOADING ROUTINE TO LOAD THE ╞┴╘ AND ╥OOT ─IRECTORY, AND IS
  324. USED BY THE CLUSTER READING ROUTINE TO RETRIEVE ALL OF THE BLOCKS OF A
  325. CLUSTER.  ┴FTER THE GIVEN STARTING LOGICAL SECTOR NUMBER IS CONVERTED INTO ITS
  326. PHYSICAL CYLINDER, SIDE, AND SECTOR EQUIVALENT, THE PHYSICAL VALUES ARE
  327. INCREMENTED TO GET THE ADDRESS OF SUCCESSIVE SECTORS OF THE GROUP.  ╘HIS
  328. AVOIDS THE OVERHEAD OF THE LOGICAL TO PHYSICAL CONVERSION.  ╤UITE A NUMBER OF
  329. TEMPORARIES ARE NEEDED.
  330.  
  331. .%306!  DEST╨TR = 6
  332. .%307!  CUR├YLINDER = 8
  333. .%308!  CUR╙IDE = 9
  334. .%309!  CUR╙ECTOR = 10
  335. .%310!  BLOCK├OUNTDOWN = 11
  336. .%311!  SOURCE╨TR = 12
  337. .%312!
  338. .%313!  COPY┬LOCKS = *  ;( .┴┘=START┬LOCK, .╪=BLOCK├OUNT, ($6)=DEST ) : .├╙=ERR
  339. .%314!     STX BLOCK├OUNTDOWN
  340. .%315!     JSR CONVERT╠OGICAL┬LOCK╬UM
  341. .%316!     STA CUR├YLINDER
  342. .%317!     STX CUR╙IDE
  343. .%318!     STY CUR╙ECTOR
  344. .%319!
  345. .%320!     COPY┬LOCK╠OOP = *
  346. .%321!     LDA CUR├YLINDER
  347. .%322!     LDX CUR╙IDE
  348. .%323!     LDY CUR╙ECTOR
  349. .%324!     JSR READ┬LOCK
  350. .%325!     BCC +
  351. .%326!     RTS
  352. .%327!  +  STA SOURCE╨TR
  353. .%328!     STY SOURCE╨TR+1
  354. .%329!     LDX #2
  355. .%330!     LDY #0
  356.  
  357. ╚ERE ╔ UNROLL THE COPYING LOOP A LITTLE BIT TO CUT THE OVERHEAD OF THE BRANCH
  358. INSTRUCTION IN HALF.  (┴ CYCLE SAVED... YOU KNOW).
  359.  
  360. .%331!  -  LDA (SOURCE╨TR),Y
  361. .%332!     STA (DEST╨TR),Y
  362. .%333!     INY
  363. .%334!     LDA (SOURCE╨TR),Y
  364. .%335!     STA (DEST╨TR),Y
  365. .%336!     INY
  366. .%337!     BNE -
  367. .%338!     INC SOURCE╨TR+1
  368. .%339!     INC DEST╨TR+1
  369. .%340!     DEX
  370. .%341!     BNE -
  371.  
  372. ╔NCREMENT THE CYLINDER, SIDE, SECTOR VALUES.
  373.  
  374. .%342!     INC CUR╙ECTOR
  375. .%343!     LDA CUR╙ECTOR
  376. .%344!     CMP #10
  377. .%345!     BCC +
  378. .%346!     LDA #1
  379. .%347!     STA CUR╙ECTOR
  380. .%348!     INC CUR╙IDE
  381. .%349!     LDA CUR╙IDE
  382. .%350!     CMP #2
  383. .%351!     BCC +
  384. .%352!     LDA #0
  385. .%353!     STA CUR╙IDE
  386. .%354!     INC CUR├YLINDER
  387. .%355!  +  DEC BLOCK├OUNTDOWN
  388. .%356!     BNE COPY┬LOCK╠OOP
  389. .%357!     CLC
  390. .%358!     RTS
  391. .%359!
  392.  
  393. ╥EAD A CLUSTER INTO THE ├LUSTER ┬UFFER, GIVEN THE CLUSTER NUMBER.  ╘HE CLUSTER
  394. NUMBER IS CONVERTED TO A LOGICAL SECTOR NUMBER AND THEN THE SECTOR COPYING
  395. ROUTINE IS CALLED.  ╘HE FORMULA GIVEN EARLIER IS USED FOR THE CONVERSION.
  396.  
  397. .%360!  READ├LUSTER = *  ;( .┴┘=CLUSTER╬UMBER ) : CLUSTER┬UF, .├╙=ERR
  398. .%361!     ;** CONVERT CLUSTER NUMBER TO LOGICAL BLOCK NUMBER
  399. .%362!     SEC
  400. .%363!     SBC #2
  401. .%364!     BCS +
  402. .%365!     DEY
  403. .%366!  +  LDX CLUSTER┬LOCK├OUNT
  404. .%367!     CPX #1
  405. .%368!     BEQ +
  406. .%369!     ASL
  407. .%370!     STY 7
  408. .%371!     ROL 7
  409. .%372!     LDY 7
  410. .%373!  +  CLC
  411. .%374!     ADC FIRST╞ILE┬LOCK
  412. .%375!     BCC +
  413. .%376!     INY
  414. .%377!
  415. .%378!     ;** READ LOGICAL BLOCKS COMPRISING CLUSTER
  416. .%379!  +  LDX #<CLUSTER┬UF
  417. .%380!     STX 6
  418. .%381!     LDX #>CLUSTER┬UF
  419. .%382!     STX 7
  420. .%383!     LDX CLUSTER┬LOCK├OUNT
  421. .%384!     JMP COPY┬LOCKS
  422. .%385!
  423.  
  424. ╘HIS NEXT LEVEL OF ROUTINES DEAL WITH THE DATA STRUCTURES OF THE ═╙-─╧╙ DISK
  425. FORMAT.
  426.  
  427. .%386!  ;====═╙-─╧╙ FORMAT LEVEL====
  428. .%387!
  429. .%388!  BOOT┬LOCK = 2
  430. .%389!
  431.  
  432. ╥EAD THE DISK FORMAT PARAMETERS, DIRECTORY, AND ╞┴╘ INTO MEMORY.
  433.  
  434. .%390!  LOAD─IRECTORY = *  ;( ) : .┴┘=DIRBUF, .╪=DIR┼NTRIES, .├╙=ERR
  435. .%391!     LDA #$0E
  436. .%392!     STA $FF00
  437. .%393!
  438.  
  439. ╥EAD THE BOOT SECTOR AND EXTRACT THE PARAMETERS.
  440.  
  441. .%394!     ;** GET PARAMETERS FROM BOOT SECTOR
  442. .%395!     LDA #0
  443. .%396!     LDY #0
  444. .%397!     JSR CONVERT╠OGICAL┬LOCK╬UM
  445. .%398!     JSR READ┬LOCK
  446. .%399!     BCC +
  447. .%400!     RTS
  448. .%401!  +  STA BOOT┬LOCK
  449. .%402!     STY BOOT┬LOCK+1
  450. .%403!     LDY #13              ;GET CLUSTER SIZE
  451. .%404!     LDA (BOOT┬LOCK),Y
  452. .%405!     STA CLUSTER┬LOCK├OUNT
  453. .%406!     CMP #3
  454. .%407!     BCC +
  455. .%408!
  456.  
  457. ╔F A DISK PARAMETER IS FOUND TO EXCEED THE LIMITS OF ╠╥╥, ERROR CODE #60 IS
  458. RETURNED.
  459.  
  460. .%409!     INVALID╨ARMS = *
  461. .%410!     LDA #60
  462. .%411!     STA ERRNO
  463. .%412!     SEC
  464. .%413!     RTS
  465. .%414!
  466. .%415!  +  LDY #16              ;CHECK ╞┴╘ REPLICATION COUNT, MUST BE 2
  467. .%416!     LDA (BOOT┬LOCK),Y
  468. .%417!     CMP #2
  469. .%418!     BNE INVALID╨ARMS
  470. .%419!     LDY #22              ;GET ╞┴╘ SIZE IN SECTORS
  471. .%420!     LDA (BOOT┬LOCK),Y
  472. .%421!     STA FAT┬LOCKS
  473. .%422!     CMP #4
  474. .%423!     BCS INVALID╨ARMS
  475. .%424!     LDY #17              ;GET DIRECTORY SIZE
  476. .%425!     LDA (BOOT┬LOCK),Y
  477. .%426!     STA ROOT─IR┼NTRIES
  478. .%427!     CMP #129
  479. .%428!     BCS INVALID╨ARMS
  480. .%429!     LSR
  481. .%430!     LSR
  482. .%431!     LSR
  483. .%432!     LSR
  484. .%433!     STA ROOT─IR┬LOCKS
  485. .%434!     LDY #19              ;GET TOTAL SECTOR COUNT
  486. .%435!     LDA (BOOT┬LOCK),Y
  487. .%436!     STA TOTAL╙ECTORS
  488. .%437!     INY
  489. .%438!     LDA (BOOT┬LOCK),Y
  490. .%439!     STA TOTAL╙ECTORS+1
  491. .%440!     LDY #24              ;CHECK SECTORS PER TRACK, MUST BE 9
  492. .%441!     LDA (BOOT┬LOCK),Y
  493. .%442!     CMP #9
  494. .%443!     BNE INVALID╨ARMS
  495. .%444!     LDY #26
  496. .%445!     LDA (BOOT┬LOCK),Y
  497. .%446!     CMP #2               ;CHECK NUMBER OF SIDES, MUST BE 2
  498. .%447!     BNE INVALID╨ARMS
  499. .%448!     LDY #14              ;CHECK NUMBER OF BOOT SECTORS, MUST BE 1
  500. .%449!     LDA (BOOT┬LOCK),Y
  501. .%450!     CMP #1
  502. .%451!     BNE INVALID╨ARMS
  503. .%452!
  504.  
  505. ├ALCULATE THE DERIVED PARAMETERS.
  506.  
  507. .%453!     ;** GET DERIVED PARAMETERS
  508. .%454!     LDA FAT┬LOCKS        ;FIRST ROOT DIRECTORY SECTOR
  509. .%455!     ASL
  510. .%456!     CLC
  511. .%457!     ADC #1
  512. .%458!     STA FIRST╥OOT─IR┬LOCK
  513. .%459!     CLC                  ;FIRST FILE SECTOR
  514. .%460!     ADC ROOT─IR┬LOCKS
  515. .%461!     STA FIRST╞ILE┬LOCK
  516. .%462!     LDA TOTAL╙ECTORS     ;NUMBER OF FILE CLUSTERS
  517. .%463!     LDY TOTAL╙ECTORS+1
  518. .%464!     SEC
  519. .%465!     SBC FIRST╞ILE┬LOCK
  520. .%466!     BCS +
  521. .%467!     DEY
  522. .%468!  +  STA FILE├LUSTER├OUNT
  523. .%469!     STY FILE├LUSTER├OUNT+1
  524. .%470!     LDA CLUSTER┬LOCK├OUNT
  525. .%471!     CMP #2
  526. .%472!     BNE +
  527. .%473!     LSR FILE├LUSTER├OUNT+1
  528. .%474!     ROR FILE├LUSTER├OUNT
  529. .%475!
  530.  
  531. ╟EE, ╔ HAVE MORE COMMENTS EMBEDDED IN THE CODE THAN ╔ DID LAST ISSUE.
  532.  
  533. .%476!     ;** LOAD ╞┴╘
  534. .%477!  +  LDA #<FATBUF
  535. .%478!     LDY #>FATBUF
  536. .%479!     STA 6
  537. .%480!     STY 7
  538. .%481!     LDA #1
  539. .%482!     LDY #0
  540. .%483!     LDX FAT┬LOCKS
  541. .%484!     JSR COPY┬LOCKS
  542. .%485!     BCC +
  543. .%486!     RTS
  544. .%487!
  545. .%488!     ;** LOAD ACTUAL DIRECTORY
  546. .%489!  +  LDA #<DIRBUF
  547. .%490!     LDY #>DIRBUF
  548. .%491!     STA 6
  549. .%492!     STY 7
  550. .%493!     LDA FIRST╥OOT─IR┬LOCK
  551. .%494!     LDY #0
  552. .%495!     LDX ROOT─IR┬LOCKS
  553. .%496!     JSR COPY┬LOCKS
  554. .%497!     BCC +
  555. .%498!     RTS
  556. .%499!  +  LDA #<DIRBUF
  557. .%500!     LDY #>DIRBUF
  558. .%501!     LDX ROOT─IR┼NTRIES
  559. .%502!     CLC
  560. .%503!     RTS
  561. .%504!
  562.  
  563. ╘HIS ROUTINE LOCATES THE GIVEN ╞┴╘ TABLE ENTRY NUMBER AND RETURNS THE VALUE
  564. STORED IN IT.  ╙OME WORK IS NEEDED TO DEAL WITH THE 12-BIT COMPRESSED DATA
  565. STRUCTURE.
  566.  
  567. .%505!  ENTRY┴DDR = 2
  568. .%506!  ENTRY╫ORK = 4
  569. .%507!  ENTRY┬ITS = 5
  570. .%508!  ENTRY─ATA0 = 6
  571. .%509!  ENTRY─ATA1 = 7
  572. .%510!  ENTRY─ATA2 = 8
  573. .%511!
  574. .%512!  GET╞AT┼NTRY = *  ;( .┴┘=FAT┼NTRY╬UMBER ) : .┴┘=FAT┼NTRY╓ALUE
  575. .%513!     STA ENTRY┬ITS
  576.  
  577. ─IVIDE THE ╞┴╘ ENTRY NUMBER BY TWO AND MULTIPLY BY THREE BECAUSE TWO ╞┴╘
  578. ENTRIES ARE STORED IN THREE BYTES.  ╘HEN ADD THE ╞┴╘ BASE ADDRESS AND WE HAVE
  579. THE ADDRESS OF THE THREE BYTES THAT CONTAIN THE ╞┴╘ ENTRY WE ARE INTERESTED
  580. IN.  ╔ RETRIEVE THE THREE BYTES INTO ZERO-PAGE MEMORY FOR EASY MANIPULATION.
  581.  
  582. .%514!     ;** DIVIDE BY TWO
  583. .%515!     STY ENTRY┴DDR+1
  584. .%516!     LSR ENTRY┴DDR+1
  585. .%517!     ROR
  586. .%518!
  587. .%519!     ;** TIMES THREE
  588. .%520!     STA ENTRY╫ORK
  589. .%521!     LDX ENTRY┴DDR+1
  590. .%522!     ASL
  591. .%523!     ROL ENTRY┴DDR+1
  592. .%524!     CLC
  593. .%525!     ADC ENTRY╫ORK
  594. .%526!     STA ENTRY┴DDR
  595. .%527!     TXA
  596. .%528!     ADC ENTRY┴DDR+1
  597. .%529!     STA ENTRY┴DDR+1
  598. .%530!
  599. .%531!     ;** ADD BASE, GET DATA
  600. .%532!     CLC
  601. .%533!     LDA ENTRY┴DDR
  602. .%534!     ADC #<FATBUF
  603. .%535!     STA ENTRY┴DDR
  604. .%536!     LDA ENTRY┴DDR+1
  605. .%537!     ADC #>FATBUF
  606. .%538!     STA ENTRY┴DDR+1
  607. .%539!     LDY #2
  608. .%540!  -  LDA (ENTRY┴DDR),Y
  609. .%541!     STA ENTRY─ATA0,Y
  610. .%542!     DEY
  611. .%543!     BPL -
  612. .%544!     LDA ENTRY┬ITS
  613. .%545!     AND #1
  614. .%546!     BNE +
  615. .%547!
  616.  
  617. ╔F THE ORIGINAL GIVEN ╞┴╘ ENTRY NUMBER IS EVEN, THEN WE WANT THE FIRST 12-BIT
  618. COMPRESSED FIELD.  ╘HE NYBBLES ARE EXTRACTED ACCORDING TO THE DIAGRAM SHOWN
  619. EARLIER.
  620.  
  621. .%548!     ;** CASE 1: FIRST 12-BIT CLUSTER
  622. .%549!     LDA ENTRY─ATA1
  623. .%550!     AND #$0F
  624. .%551!     TAY
  625. .%552!     LDA ENTRY─ATA0
  626. .%553!     RTS
  627. .%554!
  628.  
  629. ╧THERWISE, WE WANT THE SECOND 12-BIT FIELD.
  630.  
  631. .%555!     ;** CASE 2: SECOND 12-BIT CLUSTER
  632. .%556!  +  LDA ENTRY─ATA1
  633. .%557!     LDX #4
  634. .%558!  -  LSR ENTRY─ATA2
  635. .%559!     ROR
  636. .%560!     DEX
  637. .%561!     BNE -
  638. .%562!     LDY ENTRY─ATA2
  639. .%563!     RTS
  640. .%564!
  641.  
  642. ╞INALLY, THIS IS THE FILE COPYING LEVEL.  ╔T DEALS WITH READING THE CLUSTERS
  643. OF ═╙-─╧╙ FILES AND COPYING THE DATA THEY CONTAIN TO THE ALREADY-OPEN ├┬═
  644. ╦ERNAL FILE, POSSIBLY WITH ┴╙├╔╔-TO-╨┼╘╙├╔╔ TRANSLATION.
  645.  
  646. .%565!  ;====FILE COPY LEVEL====
  647. .%566!
  648. .%567!  TRANS═ODE = 14
  649. .%568!  LFN = 15
  650. .%569!  CBM─ATA╨TR = $60
  651. .%570!  CBM─ATA╠EN = $62
  652. .%571!  CLUSTER = $64
  653. .%572!
  654.  
  655. ├OPY THE GIVEN CLUSTER TO THE ├┬═ OUTPUT FILE.  ╘HIS ROUTINE FETCHES THE NEXT
  656. CLUSTER OF THE FILE FOR THE NEXT TIME THIS ROUTINE IS CALLED, AND IF IT HITS
  657. THE ╬╒╠╠ POINTER OF THE LAST CLUSTER OF A FILE, IT ADJUSTS THE NUMBER OF VALID
  658. FILE DATA BYTES THE CURRENT CLUSTER CONTAINS TO ╞ILE╠ENGTH % ├LUSTER╠ENGTH
  659. (SEE NOTE BELOW).
  660.  
  661. .%573!  COPY╞ILE├LUSTER = *  ;( CLUSTER, LFN, TRANS═ODE ) : .├╙=ERR
  662.  
  663. ╥EAD THE CLUSTER AND SETUP TO COPY THE WHOLE CLUSTER TO THE ├┬═ FILE.
  664.  
  665. .%574!     LDA CLUSTER
  666. .%575!     LDY CLUSTER+1
  667. .%576!     JSR READ├LUSTER
  668. .%577!     BCC +
  669. .%578!     RTS
  670. .%579!  +  LDA #<CLUSTER┬UF
  671. .%580!     LDY #>CLUSTER┬UF
  672. .%581!     STA CBM─ATA╨TR
  673. .%582!     STY CBM─ATA╨TR+1
  674. .%583!     LDA #0
  675. .%584!     STA CBM─ATA╠EN
  676. .%585!     LDA CLUSTER┬LOCK├OUNT
  677. .%586!     ASL
  678. .%587!     STA CBM─ATA╠EN+1
  679. .%588!
  680.  
  681. ╞ETCH THE NEXT CLUSTER NUMBER OF THE FILE, AND ADJUST THE CLUSTER DATA LENGTH
  682. FOR THE LAST CLUSTER OF THE FILE.
  683.  
  684. .%589!     ;**GET NEXT CLUSTER
  685. .%590!     LDA CLUSTER
  686. .%591!     LDY CLUSTER+1
  687. .%592!     JSR GET╞AT┼NTRY
  688. .%593!     STA CLUSTER
  689. .%594!     STY CLUSTER+1
  690. .%595!     CMP #$FF
  691. .%596!     BNE COPY╞ILE├LUSTER─ATA
  692. .%597!     CPY #$0F
  693. .%598!     BNE COPY╞ILE├LUSTER─ATA
  694. .%599!     LDA LEN═╠
  695. .%600!     STA CBM─ATA╠EN
  696. .%601!     LDA #$01
  697. .%602!     LDX CLUSTER┬LOCK├OUNT
  698. .%603!     CPX #1
  699. .%604!     BEQ +
  700. .%605!     LDA #$03
  701. .%606!  +  AND LEN═╠+1
  702.  
  703. ╘HE FOLLOWING THREE LINES WERE ADDED IN A LAST MINUTE PANIC AFTER REALIZING
  704. THAT IF ╞ILE╠ENGTH % ├LUSTER╙IZE == 0, THEN THE LAST CLUSTER OF THE FILE
  705. CONTAINS ├LUSTER╙IZE BYTES, NOT ZERO BYTES.
  706.  
  707. .%000!     BNE +
  708. .%000!     LDX LEN═╠
  709. .%000!     BEQ COPY╞ILE├LUSTER─ATA
  710. .%607!  +  STA CBM─ATA╠EN+1
  711. .%608!
  712. .%609!     COPY╞ILE├LUSTER─ATA = *
  713. .%610!     JSR COMMIE╧UT
  714. .%611!     RTS
  715. .%612!
  716.  
  717. ├OPY THE FILE DATA IN THE ═╙-─╧╙ CLUSTER BUFFER TO THE ├┬═ OUTPUT FILE.
  718.  
  719. .%613!  CBM─ATA╠IMIT = $66
  720. .%614!
  721. .%615!  COMMIE╧UT = *  ;( CBM─ATA╨TR, CBM─ATA╠EN ) : .├╙=ERR
  722.  
  723. ╔F THE THE LOGICAL FILE NUMBER TO COPY TO IS 0 ("NULL DEVICE"), THEN DON'T
  724. BOTHER COPYING ANYTHING.
  725.  
  726. .%616!     LDX LFN
  727. .%617!     BNE +
  728. .%618!     CLC
  729. .%619!     RTS
  730.  
  731. ╧THERWISE, PREPARE THE LOGICAL FILE NUMBER FOR OUTPUT.
  732.  
  733. .%620!  +  JSR KERNEL├HKOUT
  734. .%621!     BCC COMMIE╧UT═ORE
  735. .%622!     STA ERRNO
  736. .%623!     RTS
  737. .%624!
  738. .%625!     COMMIE╧UT═ORE = *
  739.  
  740. ╨ROCESS THE CLUSTER DATA IN CHUNKS OF UP TO 255 BYTES OR THE NUMBER OF DATA
  741. BYTES REMAINING IN THE CLUSTER.
  742.  
  743. .%626!     LDA #255
  744. .%627!     LDX CBM─ATA╠EN+1
  745. .%628!     BNE +
  746. .%629!     LDA CBM─ATA╠EN
  747. .%630!  +  STA CBM─ATA╠IMIT
  748. .%631!     LDY #0
  749. .%632!  -  LDA (CBM─ATA╨TR),Y
  750. .%633!     BIT TRANS═ODE
  751. .%634!     BPL +
  752.  
  753. ╔F WE HAVE TO TRANSLATE THE CURRENT ┴╙├╔╔ CHARACTER, LOOK UP THE ╨┼╘╙├╔╔ VALUE
  754. IN THE TRANSLATION TABLE AND OUTPUT THAT VALUE.  ╔F THE TRANSLATION TABLE
  755. ENTRY VALUE IS $00, THEN DON'T OUTPUT A CHARACTER (FILTER OUT INVALID
  756. CHARACTER CODES).
  757.  
  758. .%635!     TAX
  759. .%636!     LDA TRANS┬UF,X
  760. .%637!     BEQ COMMIE╬EXT
  761. .%638!  +  JSR KERNEL├HROUT
  762. .%639!     COMMIE╬EXT = *
  763. .%640!     INY
  764. .%641!     CPY CBM─ATA╠IMIT
  765. .%642!     BNE -
  766. .%643!
  767.  
  768. ╔NCREMENT THE CLUSTER BUFFER POINTER AND DECREMENT THE CLUSTER BUFFER CHARACTER
  769. COUNT ACCORDING TO THE NUMBER OF BYTES JUST PROCESSED, AND REPEAT THE ABOVE IF
  770. MORE FILE DATA REMAINS IN THE CURRENT CLUSTER.
  771.  
  772. .%644!     CLC
  773. .%645!     LDA CBM─ATA╨TR
  774. .%646!     ADC CBM─ATA╠IMIT
  775. .%647!     STA CBM─ATA╨TR
  776. .%648!     BCC +
  777. .%649!     INC CBM─ATA╨TR+1
  778. .%650!  +  SEC
  779. .%651!     LDA CBM─ATA╠EN
  780. .%652!     SBC CBM─ATA╠IMIT
  781.