home *** CD-ROM | disk | FTP | other *** search
/ Brotikasten / BROTCD01.iso / c128 / c154.d64 / lrr.doc < prev    next >
Text File  |  1995-08-09  |  67KB  |  1,809 lines

  1. =============================================================================
  2. ╠╔╘╘╠┼ ╥┼─ ╥┼┴─┼╥: ═╙-─╧╙ FILE READER FOR THE 128 AND 1571/81 DRIVES.
  3.  
  4. BY ├RAIG ┬RUCE  <CSBRUCE@NEUMANN.UWATERLOO.CA>
  5.  
  6. 1. ╔╬╘╥╧─╒├╘╔╧╬
  7.  
  8. ╘HIS ARTICLE PRESENTS A PROGRAM THAT READS ═╙-─╧╙ FILES AND THE ROOT DIRECTORY
  9. OF ═╙-─╧╙ DISKS.  ╘HE PROGRAM COPIES ONLY FROM DRIVE TO DRIVE WITHOUT
  10. BUFFERING FILE DATA INTERNALLY.  ╘HIS IS SIMPLER AND IMPOSES NO LIMITS ON THE
  11. SIZE OF THE FILES TRANSFERRED, ALTHOUGH IT REQUIRES THE USE OF TWO DISK DRIVES
  12. (OR A LOGICAL DRIVE).  ╘HE USER-INTERFACE CODE IS WRITTEN IN ┬┴╙╔├ AND
  13. PRESENTS A FULL-SCREEN FILE SELECTION MENU.  ╘HE GRUNT-WORK CODE IS WRITTEN IN
  14. ASSEMBLY LANGUAGE AND OPERATES AT MAXIMUM VELOSITY.
  15.  
  16. ╘HE ┬URST ├OMMAND ╔NSTRUCTION ╙ET OF THE 1571/81 IS USED TO READ THE ═╙-─╧╙
  17. DISK BLOCKS AND THE STANDARD KERNEL ROUTINES ARE USED FOR OUTPUTTING THE
  18. DATA.  (╔ AM AN OPERATING SYSTEMS SPECIALIST, SO ╔ CALL IT A KERN┼L!)  ╘HUS,
  19. THE ═╙-─╧╙ FILES MUST BE READ FROM A 1571 OR 1581 DISK DRIVE, BUT THE OUTPUT
  20. DEVICE MAY BE ANY DISK DRIVE TYPE, THE SCREEN OR A PRINTER, OR A VIRTUAL DRIVE
  21. TYPE SUCH AS ╥┴═╠INK, ╥┴═─RIVE, OR ╥┴═─╧╙ (FOR THE ╥┼╒).  ╔T IS INTERESTING TO
  22. NOTE THAT THE DATA CAN BE READ IN FROM AN ═╙-─╧╙ DISK FASTER THAN IT CAN BE
  23. WRITTEN OUT TO A 1571, 1581, OR EVEN A ╥┴═─╧╙ FILE.  ┴ ╥┴═╠INK CAN SWALLOW THE
  24. DATA ONLY SLIGHTLY FASTER THAN IT CAN BE READ.
  25.  
  26. ╠ITTLE ╥ED ╥EADER (╠╥╥) SUPPORTS DOUBLE DENSITY 3.5" DISKS FORMATTED WITH 80
  27. TRACKS, 9 SECTORS PER TRACK, AND 2 SIDES WITH A 1581 AND 5.25" DOUBLE DENSITY
  28. DISKS FORMATTED WITH 40 TRACKS, 9 SECTORS PER TRACK, AND 2 SIDES WITH A 1571.
  29. ┴ LIMIT OF 128 DIRECTORY ENTRIES AND 3 ╞ILE ┴LLOCATION ╘ABLE (╞┴╘) SECTORS IS
  30. IMPOSED.  ╘HERE MUST BE 2 COPIES OF THE ╞┴╘ AND THE CLUSTER SIZE MAY BE 1 OR 2
  31. SECTORS.  ╘HE SECTOR SIZE MUST BE 512 BYTES.
  32.  
  33. ╧H, ABOUT THE NAME.  ╔T IS A PLAY ON THE NAME OF ANOTHER ═╙-─╧╙ FILE COPIER
  34. AVAILABLE FOR THE ├-128.  "╠ITTLE" MEANS THAT IT IS SMALLER IN SCOPE THAN THE
  35. OTHER PROGRAM, AND "╥ED" IS A DIFFERENT PRIMARY COLOR TO AVOID ANY LEGAL
  36. COMPLICATIONS.  ╔T IS ALSO THE NON-WHITE COLOR OF THE FLAG OF THE COUNTRY OF
  37. ORIGIN OF THIS PROGRAM (NO, ╔ AM NOT ╩APANESE).  ┴LSO, THIS PROGRAM IS ╨UBLIC
  38. ─OMAIN ╙OFTWARE, AS IS ALL SOFTWARE ╔ DEVELOP FOR 8-BIT ├OMMODORE ├OMPUTERS.
  39. ╞EEL FREE TO ┼-MAIL ME IF YOU HAVE QUESTIONS OR COMMENTS ABOUT THIS ARTICLE.
  40.  
  41. 2. ╒╙┼╥ ╟╒╔─┼
  42.  
  43. ╠╧┴─ AND ╥╒╬ THE "LRR.128" ┬┴╙╔├ PROGRAM FILE.  ╫HEN THE PROGRAM IS FIRST RUN,
  44. IT WILL DISPLAY AN "INITIALIZING" MESSAGE AND WILL LOAD IN THE BINARY MACHINE
  45. LANGUAGE PACKAGE FROM THE "CURRENT" ├OMMODORE ─╧╙ DRIVE (THE CURRENT DRIVE IS
  46. OBTAINED FROM ╨┼┼╦(186) - THE LAST DEVICE ACCESSED).  ╘HE BINARY PACKAGE IS
  47. LOADED ONLY ON THE FIRST RUN AND IS NOT RELOADED ON SUBSEQUENT RUNS IF THE
  48. PACKAGE ╔─ FIELD IS IN PLACE.
  49.  
  50. 2.1. ═┴╔╬ ╙├╥┼┼╬
  51.  
  52. ╘HE MAIN SCREEN OF THE PROGRAM IS THEN DISPLAYED.  ╘HE MAIN SCREEN OF THE
  53. PROGRAM WILL LOOK SOMETHING LIKE THIS:
  54.  
  55.    ═╙-─┼╓=9    ═╙-╘┘╨┼=1581    ├┬═-─┼╓=8
  56.  
  57.    ╬╒═  ╙  ╘╥╬  ╘┘╨  ╞╔╠┼╬┴═┼  ┼╪╘  ╠┼╬╟╘╚
  58.    ---  -  ---  ---  --------  ---  ------
  59.      1  *  ┴╙├  ╙┼╤  ╚┴├╦4     ╘╪╘  120732
  60.      2     ┬╔╬  ╨╥╟  ╥┴═─╧╙    ╙╞╪   34923
  61.  
  62.    ─=─╔╥┼├╘╧╥┘  ═=═╙-─┼╓  ╞=├┬═-─┼╓ ╤=╤╒╔╘
  63.    ╘=╘╧╟╟╠┼-├╧╠╒═╬, ├=├╧╨┘-╞╔╠┼╙, +/- ╨┴╟┼
  64.  
  65. EXCEPT THAT IMMEDIATELY AFTER STARTING UP, "<NO FILES>" WILL BE DISPLAYED
  66. RATHER THAN FILENAMES.  ╘HE "═╙-─┼╓" AND "═╙-╘┘╨┼" FIELDS GIVE THE DEVICE
  67. NUMBER AND TYPE OF THE DRIVE CONTAINING THE ═╙-─╧╙ DISK TO COPY FROM, AND THE
  68. "├┬═-─┼╓" GIVES THE DEVICE NUMBER OF THE DRIVE/VIRTUAL DRIVE/CHARACTER DEVICE
  69. TO COPY FILE DATA TO.
  70.  
  71. ╔NFORMATION ABOUT ALL ═╙-─╧╙ FILES IN THE ROOT DIRECTORY OF THE ═╙-─╧╙ DISK IS
  72. DISPLAYED IN COLUMNS BELOW THE DRIVE INFORMATION.  "╬╒═" GIVES THE NUMBER OF
  73. THE ═╙-─╧╙ FILE IN THE DIRECTORY LISTING, AND "╙" INDICATES WHETHER THE FILE
  74. IS "SELECTED" OR NOT.  ╔F THE FILE IS SELECTED, AN ASTERISK (*) IS DISPLAYED;
  75. OTHERWISE, A BLANK IS DISPLAYED.  ╫HEN YOU LATER ENTER ├OPY ═ODE, ONLY THE
  76. FILES THAT HAVE BEEN "SELECTED" ARE COPIED.
  77.  
  78. ╘HE "╘╥╬" FIELD INDICATES THE CHARACTER TRANSLATION SCHEME TO BE USED WHEN THE
  79. FILE IS COPIED.  ┴ VALUE OF "┬╔╬" (BINARY) MEANS NO TRANSLATION AND A VALUE OF
  80. "┴╙├" (ASCII) MEANS THE FILE CHARACTERS ARE TO BE TRANSLATED FROM ═╙-─╧╙ ┴╙├╔╔
  81. (OR "┴╙├╔╔-├R╠F") TO ╨┼╘╙├╔╔.  ╘HE "╘┘╨" FIELD INDICATES THE TYPE OF
  82. ├OMMODORE-─╧╙ FILE TO CREATE FOR WRITING THE ═╙-─╧╙ FILE CONTENTS INTO.  ╘HE
  83. POSSIBLE VALUES ARE "╙┼╤" (SEQUENTIAL) AND "╨╥╟" (PROGRAM).  ╘HE VALUES OF THE
  84. ╘╥╬ AND ╘┘╨ FILEDS ARE SET INDEPENDENTLY, SO YOU CAN COPY BINARY DATA TO ╙┼╤
  85. FILES AND ASCII DATA TO ╨╥╟ FILES IF YOU WISH.
  86.  
  87. ╘HE "╞╔╠┼╬┴═┼" AND "┼╪╘" FIELDS GIVE THE FILENAME AND EXTENSION TYPE OF THE
  88. ═╙-─╧╙ FILES AND "╠┼╬╟╘╚" GIVES THE EXACT LENGTH OF THE FILES IN BYTES.  ╬OTE
  89. THAT IF YOU PERFORM "┴╙├" TRANSLATION ON A FILE, ITS ╨┼╘╙├╔╔ VERSION WILL HAVE
  90. A SHORTER LENGTH.
  91.  
  92. 2.2. ╒╙┼╥ ├╧══┴╬─╙
  93.  
  94. ╘HE BOTTOM OF THE SCREEN GIVES THE COMMAND SUMMARY.  ┴FTER STARTING THE
  95. PROGRAM, YOU WILL WANT TO SETUP THE ═╙-─╧╙ AND ├┬═-─╧╙ DRIVES WITH THE "═" AND
  96. "╞" COMMANDS.  ╙IMPLY PRESS THE (LETTER) KEY CORRESPONDING TO THE COMMAND
  97. NAME TO ACTIVATE THE COMMAND.  ╨RESSING ═ WILL PROMPT YOU FOR THE ═╙-─╧╙ ─RIVE
  98. ╬UMBER AND THE ═╙-─╧╙ ─RIVE ╘YPE.  ╔N BOTH CASES, TYPE THE NUMBER AND PRESS
  99. ╥┼╘╒╥╬.  (╙ORRY FOR INSULTING ALL NON-NOVICES OUT THERE, BUT ╔ WANT TO BE
  100. COMPLETE).  ╘HE ═╙-─╧╙ DRIVE NUMBER CANNOT BE THE SAME AS THE ├┬═-─╧╙ DRIVE
  101. NUMBER (SINCE THE PROGRAM COPIES FROM DRIVE-TO-DRIVE WITHOUT INTERNAL
  102. BUFFERING).  ╞OR THE DRIVE TYPE, ENTER AN "8", "81", OR "1581" FOR A 1581
  103. DRIVE OR ANYTHING ELSE FOR A 1571 DRIVE.
  104.  
  105. ╨RESSING ╞ WILL PROMPT YOU FOR THE ├┬═-─╧╙ DEVICE NUMBER.  ┘OU MAY ENTER A
  106. NUMBER FROM 0 TO 30, EXCEPT THAT IT MUST NOT BE THE ═╙-─╧╙ DRIVE NUMBER.
  107. ┼NTER A "1" FOR ├ASSETTE ─RIVE (╟OD FORBID!), A "3" FOR THE SCREEN, A "4" FOR
  108. THE PRINTER (WITH AN AUTOMATIC SECONDARY ADDRESS OF 7 (LOWERCASE)), ANY NUMBER
  109. ABOVE 7 FOR A ├OMMODORE DISK DRIVE OR SPECIAL VIRTUAL DRIVE, OR A VALUE OF "0"
  110. FOR THE SPECIAL "NULL" DRIVE.  ┴ ├┬═-─┼╓ VALUE OF 0 WILL CASE THE PROGRAM TO
  111. READ ═╙-─╧╙ FILES AND DO NOTHING WITH THE OUTPUT.  ┘OU CAN USE THIS FEATURE TO
  112. CHECK OUT THE RAW READING SPEED OF THE PROGRAM.
  113.  
  114. ┴FTER SETTING UP THE DRIVES, PRESS ─ TO READ IN THE ROOT DIRECTORY OFF THE
  115. ═╙-─╧╙ DISK.  ╘HE DATA WILL COME BLAZING IN FROM THE DISK BUT ┬┴╙╔├ WILL TAKE
  116. ITS GOOD OLE TIME SIFTING THROUGH IT.  ╞ILENAMES ARE DISPLAYED ON THE SCREEN
  117. AS THEY ARE SCANNED IN.  ╘HE PROGRAM WILL (EVENTUALLY) RETURN TO THE MAIN
  118. SCREEN AND DISPLAY THE FORMATTED FILE INFORMATION.  ╧NE NOTE: THE PROCESS OF
  119. LOGGING IN A 1581 ═╙-─╧╙ DISK TAKES ABOUT 12 SECONDS (ON MY 1581, ANYWAY), SO
  120. BE PATIENT.  ┴N ═╙-─╧╙ DISK WILL HAVE TO BE "LOGGED IN" EVERY TIME YOU CHANGE
  121. ═╙-─╧╙ DISKS.  (─ISKS ARE LOGGED IN AUTOMATICALLY).
  122.  
  123. ┴ COUPLE OF NOTES ABOUT ACCESSING ═╙-─╧╙ DISKS: DON'T TRY TO ACCESS A DEVICE
  124. THAT IS NOT PRESENT BECAUSE THE MACHINE LANGUAGE ROUTINES CANNOT HANDLE THIS
  125. ERROR FOR SOME REASON AND WILL LOCK UP, REQUIRING A ╙╘╧╨+╥┼╙╘╧╥┼.  ┴LSO, MAKE
  126. SURE THAT AN ACTUAL ═╙-─╧╙ DISK IS LOADED INTO THE DRIVE.  ╔F YOU ACCIDENTALLY
  127. PLACE ├OMMODORE-─╧╙ DISK INTO THE ═╙-─╧╙ DRIVE, THE 1581 WILL REPORT AN
  128. INVALID BOOT PARAMETERS ERROR (#60), BUT A 1571 WILL LOCK UP (SINCE ╔ DON'T
  129. CHECK THE SECTOR SIZE AND MY BURST ROUTINES ARE EXPECTING 512 BYTES TO COME
  130. OUT OF A SECTOR WHEREAS ├OMMODORE DISKS HAVE ONLY 256 BYTES PER SECTOR).
  131.  
  132. ╬OW YOU ARE READY TO PICK WHAT FILES YOU WANT COPIED AND HOW YOU WANT THEM
  133. COPIED.  ┘OU WILL NOTICE THAT A "CURSOR" APPEARS IN THE "╙" COLUMN OF THE
  134. FIRST FILE.  ┘OU MAY MOVE THE CURSOR AROUND WITH THE CURSOR KEYS: ╒╨, ─╧╫╬,
  135. ╠┼╞╘, ╥╔╟╚╘, ╚╧═┼, AND ├╠╥.  ├╠╥ (╙╚╔╞╘-╚╧═┼) WILL MOVE THE CURSOR BACK TO THE
  136. FIRST FILE ON THE FIRST SCREEN.  ┘OU CAN MOVE THE CURSOR AMONG THE SELECT,
  137. TRANSLATION, AND FILE-TYPE COLUMNS OF ALL THE FILES.  ╨RESSING A ╙╨┴├┼ OR A
  138. ╥┼╘╒╥╬ WILL TOGGLE THE VALUE OF THE FIELD THAT THE CURSOR IS ON.  ╘O TOGGLE
  139. ALL OF THE VALUES OF THE "CURSOR" COLUMN (INCLUDING FILES ON ALL OTHER
  140. SCREENS), PRESS ╘.  ┘OU WILL NOTICE THAT MOVING THE CURSOR AROUND AND TOGGLING
  141. FIELDS IS A BIT SLUGGISH, ESPECIALLY IF YOU ARE IN ╙LOW MODE ON THE 40-COLUMN
  142. SCREEN.  ─ID ╔ MENTION THAT THIS PROGRAM WILL RUN ON EITHER THE 40 OR
  143. 80-COLUMN SCREEN?  ╘OGGLING AN ENTIRE COLUMN CAN TAKE A COUPLE OF SECONDS.
  144.  
  145. ╔F THERE ARE MORE THAN 18 ═╙-─╧╙ FILES, YOU CAN PRESS THE "+" AND "-" KEYS TO
  146. MOVE AMONG ALL OF THE SCREENS OF FILES.  ╘HE CURSOR MOVEMENT KEYS WILL WRAP
  147. AROUND ON THE CURRENT SCREEN.  "+" IS PAGE FORWARD, AND "-" IS PAGE BACKWARD.
  148. ╘HE SCREENS WRAP AROUND TOO.
  149.  
  150. ┴FTER YOU HAVE SELECTED ALL OF THE FILES YOU WANT TO COPY AND THEIR TRANSLATION
  151. AND FILE-TYPE FIELDS HAVE BEEN SET, PRESS THE ├ KEY TO GO INTO ├OPY ═ODE (NEXT
  152. SECTION).  ┴FTER COPYING, YOU ARE RETURNED TO THE MAIN SCREEN WITH ALL OF THE
  153. FIELD SETTINGS STILL INTACT.  ╘O EXIT FROM THE PROGRAM, PRESS ╤.
  154.  
  155. 2.3. ├╧╨┘ ═╧─┼
  156.  
  157. ╫HEN YOU ENTER COPY MODE, THE SCREEN WILL CLEAR AND THE NAME OF EACH SELECTED
  158. FILE IS DISPLAYED AS IT IS BEING COPIED.  ╔F AN ERROR IS ENCOUNTERED ON EITHER
  159. THE ═╙-─╧╙ OR ├┬═-─╧╙ DRIVE DURING COPYING, AN ERROR MESSAGE WILL BE DISPLAYED
  160. AND COPYING WILL CONTINUE (AFTER YOU PRESS A KEY FOR ═╙-─╧╙ ERRORS).
  161.  
  162. ╘O GENERATE A ├┬═-─╧╙ FILENAME FROM AN ═╙-─╧╙ FILENAME, THE EIGHT FILENAME
  163. CHARACTERS ARE TAKEN (INCLUDING SPACES) AND A DOT (.) AND THE THREE CHARACTERS
  164. OF THE EXTENSION ARE APPENDED.  ╘HEN, ALL SPACES ARE REMOVED, AND IF THE NAME
  165. ENDS WITH A DOT (.) CHARACTER, THEN THAT DOT CHARACTER IS REMOVED AS WELL.  ╔
  166. THINK THIS IS FAIRLY REASONABLE.
  167.  
  168. ╔F THERE ALREADY IS A FILE WITH THE SAME FILENAME ON THE ├┬═-─╧╙ DISK, THEN
  169. YOU WILL BE PROMPTED IF YOU WANT TO OVERWRITE THE FILE OR NOT.  ┼NTERING AN
  170. "N" WILL ABORT THE COPYING OF THAT FILE AND GO ON TO THE NEXT FILE, AND
  171. ENTERING A "Y" (OR ANYTHING ELSE) WILL CAUSE THE ├┬═-─╧╙ FILE TO BE
  172. "SCRATCHED" AND THEN RE-WRITTEN.
  173.  
  174. ╘HE PHYSICAL COPYING OF THE FILE IS DONE COMPLETELY IN MACHINE LANGUAGE AND
  175. NOTHING IS DISPLAYED ON THE SCREEN WHILE THIS IS HAPPENING, BUT YOU CAN FOLLOW
  176. THINGS BY LOOKING AT DAS BLINKIN LICHTES AND LISTENING FOR CLICKS AND GRINDS.
  177. ┘OU WILL PROBABLY BE SURPRISED BY THE ═╙-─╧╙ FILE READING SPEED (╔ MEAN IN A
  178. GOOD WAY).  ╘HE DISK DATA IS READ IN WHOLE TRACKS AND CACHED IN MEMORY AND THE
  179. DIRECTORY INFORMATION AND THE ╞┴╘ ARE RETAINED IN MEMORY AS WELL.  ╘HE RESULT
  180. IS THAT MINIMAL TIME IS SPENT READING DISK DATA, AND NO COSTLY SEEKS ARE
  181. REQUIRED FOR OPENING A NEW ═╙-─╧╙ FILE.  ┴ RESULT IS THAT SMALL FILES ARE
  182. COPIED ONE AFTER ANOTHER VERY QUICKLY.  ┘OU WILL HAVE TO WAIT, HOWEVER, ON THE
  183. RELATIVELY SLOW STANDARD KERNEL/├OMMODORE-─╧╙ FILE WRITING.
  184.  
  185. ┴ FEW CHANGES HAD TO BE MADE TO THE PROGRAM TO ACCOMODATE THE ╥┴═─╧╙ PROGRAM.
  186. ╥┴═─╧╙ USES MEMORY FROM $2300 TO $3╞╞╞ OF ╥┴═0, WHICH IS NOT REALLY A GOOD
  187. PLACE FOR A DEVICE DRIVER, AND IT USES SOME OF THE ZERO-PAGE LOCATIONS THAT ╔
  188. WANTED TO USE.  ┬UT, DIFFICULTIES WERE OVERCOME.  ╘HE IMPORTANCE OF ╥┴═─╧╙
  189. COMPATIBILITY IS THAT IF YOU ONLY HAVE ONE DISK DRIVE BUT YOU HAVE AN ╥┼╒, YOU
  190. CAN USE ╥┴═─╧╙ TO STORE THE ═╙-─╧╙ FILES TEMPORARILY.  ╔F YOU ONLY HAVE ONE
  191. DISK DRIVE AND NO ╥┼╒, YOU ARE ╙╧╠ (╧UT OF ╠UCK) UNLESS YOU CAN GET A
  192. ╥AM─ISK-TYPE PROGRAM FOR AN UNEXPANDED 128.  ╘HE ╥┴═─╧╙ PROGRAM IS AVAILABLE
  193. FROM ╞╘╨ SITE "CCOSUN.CALTECH.EDU" IN FILE "/PUB/RKNOP/UTIL128/RAMDOSII.SFX".
  194. ╧NE NOTE ╔ FOUND OUT ABOUT ╥┴═─╧╙: YOU CANNOT USE A
  195.  
  196. ─╧╨┼╬#1,(├╞$),╒(├─),╫
  197.  
  198. WITH IT LIKE YOU ARE SUPPOSED TO BE ABLE TO; YOU HAVE TO USE A
  199.  
  200. ─╧╨┼╬#1,(├╞$+",╫"),╒(├─)
  201.  
  202. ╚ERE IS A TABLE OF COPYING SPEEDS FOR COPYING FROM 1571S AND 1581S WITH ┴╙├
  203. AND ┬╔╬ TRANSLATION MODES.  ┴LL FIGURES ARE IN BYTES/SECOND.  ╘HESE RESULTS
  204. WERE OBTAINED FROM COPYING A 127,280 BYTE TEXT FILE (THE TEXT OF ├= ╚ACKING
  205. ╔SSUE #3).
  206.  
  207.    ╞╥╧═  \ ╘╧: "NULL"     ╥┴═╠INK     ╥┴═─╧╙     ╩─1581     ╩─1571
  208.    -------+    ------     -------     ------     ------     ------
  209.    81-BIN ▄      5772        3441       2146        N/A        644
  210.    81-ASC ▄      5772        3434       2164        N/A        661
  211.    71-BIN ▄      4323        2991       1949       1821        N/A
  212.    71-ASC ▄      4323        2982       1962       1847        N/A
  213.  
  214. ╘HE "NULL" DEVICE IS THAT "0" ├┬═-─╧╙ DEVICE NUMBER, AND A COUPLE OF ENTRIES
  215. ARE "N/A" SINCE ╔ ONLY HAVE ONE 1571 AND ONE 1581.  ╬OTE THAT MY 71 AND 81 ARE
  216. ╩IFFY─╧╙-IFIED, SO THE PERFORMANCE OF A STOCK 71/81 WILL BE POORER.  ╩IFFY─╧╙
  217. GIVES ABOUT A 2X PERFORMANCE IMPROVEMENT FOR THE STANDARD FILE ACCESSING CALLS
  218. (OPEN, CLOSE, CHRIN, CHROUT).  ╥┴═─╧╙ DOESN'T SEEM TO BE AS SNAPPY AS YOU
  219. MIGHT THINK.
  220.  
  221. ╘HE "NULL" FIGURES ARE QUITE IMPRESSIVE, BUT THE RAW SECTOR READING SPEED
  222. WITHOUT THE OVERHEAD OF MUCKING AROUND WITH FILE ORGANIZATION IS 6700
  223. BYTES/SEC FOR A 1581 AND 4600 ┬/S FOR A 71.  ╘HE REASON THAT THE 1571 OPERATES
  224. SO QUICKLY IS THAT ╔ USE A SECTOR INTERLEAVE OF 4 (WHICH IS OPTIMAL) FOR
  225. READING THE TRACKS.  ╔ THINK THAT OTHER ═╙-─╧╙ FILE COPIER PROGRAM USES AN
  226. INTERLEAVE OF 1 (WHICH IS NOT OPTIMAL).  ╔ LOSE SOME OF THE RAW PERFORMANCE
  227. BECAUSE ╔ COPY THE FILE DATA INTERNALLY ONCE BEFORE OUTPUTTING IT (TO SIMPLIFY
  228. SOME OF THE CODE).
  229.  
  230. ╔N A COUPLE OF PLACES YOU WILL NOTICE THAT ┴╙├ TRANSLATION GIVES SLIGHTLY
  231. BETTER OR SLIGHTLY WORSE PERFORMANCE THAN ┬╔╬.  ╘HIS IS BECAUSE ALTHOUGH
  232. SLIGHTLY MORE WORK IS REQUIRED TO TRANSLATE THE CHARACTERS, SLIGHTLY FEWER
  233. CHARACTERS WILL HAVE TO BE WRITTEN TO THE ├┬═-─╧╙ FILE, SINCE ╨┼╘╙├╔╔ USES
  234. ONLY ├╥ WHERE ═╙-─╧╙ ┴╙├╔╔ USES ├╥ AND ╠╞ TO REPRESENT END-OF-LINE.
  235. ╘RANSLATION IS DONE BY USING A TABLE (THAT YOU CAN CHANGE IF YOU WISH).  ═ANY
  236. ENTRIES IN THIS TABLE CONTAIN A VALUE OF ZERO, WHICH MEANS THAT NO CHARACTER
  237. WILL BE OUTPUT ON TRANSLATION.  ═OST OF THE CONTROL CHARACTERS AND ALL OF THE
  238. CHARACTERS OF VALUE 128 (0X80) OR GREATER ARE THROWN AWAY ON BEING
  239. TRANSLATED.  ╘HE TABLE IS SET UP SO THAT ├╥ CHARACTERS ARE THROWN AWAY AND THE
  240. ╠╞ CHARACTER IS TRANSLATED TO A ├┬═-─╧╙ ├╥ CHARACTER.  ╘HUS, BOTH ═╙-─╧╙ ┴╙├╔╔
  241. FILES AND ╒╬╔╪ ┴╙├╔╔ FILES CAN BE TRANSLATED CORRECTLY.
  242.  
  243. 2. ┬╒╥╙╘ ├╧══┴╬─╙
  244.  
  245. ╘HREE BURST COMMANDS FROM THE 1571/81 DISK DRIVE ┬URST ├OMMAND ╔NSTRUCTION ╙ET
  246. ARE REQUIRED TO ALLOW THIS PROGRAM TO READ THE ═╙-─╧╙ DISKS: ╤UERY ─ISK
  247. ╞ORMAT, ╙ECTOR ╔NTERLEAVE, AND ╥EAD.  ╘HE GRUNGY DETAILS ABOUT ISSUING BURST
  248. COMMANDS AND BURST MODE HANDSHAKING ARE COVERED IN ├= ╚ACKING ╔SSUE #3.  ╘HE
  249. ╤UERY ─ISK ╞ORMAT COMMAND IS USED TO "LOG IN" THE ═╙-─╧╙ DISK.  ╘HE ╔NQUIRE
  250. ─ISK BURST COMMAND CANNOT BE USED WITH AN ═╙-─╧╙ DISK ON THE 1581 FOR SOME
  251. UNKNOWN REASON.  ╔ FOUND THIS OUT THE HARD WAY.  ╘HE ╤UERY ─ISK ╞ORMAT COMMAND
  252. HAS THE FOLLOWING FORMAT:
  253.  
  254.     ┬┘╘┼ \ BIT: 7     6     5     4     3     2     1     0  ▄ ╓ALUE
  255.    -------+--------+-----+-----+-----+-----+-----+-----+-----+-------
  256.      0    ▄     0  ▄  1  ▄  0  ▄  1  ▄  0  ▄  1  ▄  0  ▄  1  ▄  "╒"
  257.      1    ▄     0  ▄  0  ▄  1  ▄  1  ▄  0  ▄  0  ▄  0  ▄  0  ▄  "0"
  258.      2    ▄     ╞  ▄  ╪  ▄  ╪  ▄  ╙  ▄  1  ▄  0  ▄  1  ▄  ╬  ▄  10
  259.    -------+--------------------------------------------------+-------
  260.  
  261. WHERE THE ╞, ╙, AND ╬ BITS HAVE A VALUE OF 0 FOR OUR PURPOSES.  ┴ RESPONSE OF
  262. A BURST STATUS BYTE AND SIX OTHER THROW-AWAY BYTES IS GIVEN FROM THE DRIVE.
  263. ╘HIS COMMAND TAKES QUITE A LONG TIME TO EXECUTE ON MY 1581 BUT WORKS QUITE
  264. QUICKLY ON MY 1571.  ┘OU ONLY HAVE TO LOG IN A DISK WHENEVER YOU CHANGE
  265. DISKS.
  266.  
  267. ╘HE ╙ECTOR ╔NTERLEAVE COMMAND IS USED TO SET A SOFT INTERLEAVE FOR THE ╥EAD
  268. COMMAND.  ╔ USE AN INTERLEAVE OF 1 FOR THE 1581 AND AN INTERLEAVE OF 4 FOR THE
  269. 1571.  ╘HIS MEANS THAT THE ═╙-─╧╙ SECTORS WILL COME FROM 1571 TO THE COMPUTER
  270. IN THE FOLLOWING ORDER: 1, 5, 9, 4, 8, 3, 7, 2, 6 (THERE ARE 9 SECTORS PER
  271. TRACK ON AN ═╙-─╧╙ DISK (BOTH 3.5" AND 5.25"), NUMBERED FROM 1 TO 9).  ╠╥╥
  272. HANDLES THE DATA COMING IN IN THIS ORDER, AND IN STRAIGHT ORDER FROM THE
  273. 1581.  ╘HE ╙ECTOR ╔NTERLEAVE COMMAND HAS THE FOLLOWING FORMAT, WHERE THE ╫ AND
  274. ╬ BITS ARE 0 FOR US:
  275.  
  276.     ┬┘╘┼ \ BIT: 7     6     5     4     3     2     1     0  ▄ ╓ALUE
  277.    -------+--------+-----+-----+-----+-----+-----+-----+-----+-------
  278.      0    ▄     0  ▄  1  ▄  0  ▄  1  ▄  0  ▄  1  ▄  0  ▄  1  ▄  "╒"
  279.      1    ▄     0  ▄  0  ▄  1  ▄  1  ▄  0  ▄  0  ▄  0  ▄  0  ▄  "0"
  280.      2    ▄     ╫  ▄  ╪  ▄  ╪  ▄  0  ▄  1  ▄  0  ▄  0  ▄  ╬  ▄   8
  281.      3    ▄                   <INTERLEAVE>                   ▄ 1 OR 4
  282.    -------+--------------------------------------------------+-------
  283.  
  284. ╘HE ╥EAD COMMAND IS USED TO TRANSFER THE NINE SECTORS OF A TRACK TO THE
  285. COMPUTER IN THE ORDER SPECIFIED BY THE INTERLEAVE.  ╘HE FORMAT IS:
  286.  
  287.     ┬┘╘┼ \ BIT: 7     6     5     4     3     2     1     0  ▄ ╓ALUE
  288.    -------+--------+-----+-----+-----+-----+-----+-----+-----+-------
  289.      0    ▄     0  ▄  1  ▄  0  ▄  1  ▄  0  ▄  1  ▄  0  ▄  1  ▄  "╒"
  290.      1    ▄     0  ▄  0  ▄  1  ▄  1  ▄  0  ▄  0  ▄  0  ▄  0  ▄  "0"
  291.      2    ▄    ╘/╠ ▄  ┼  ▄ ┬/╪ ▄  ╙  ▄  0  ▄  0  ▄  0  ▄  ╬  ▄ 0 OR 16
  292.      3    ▄                      <TRACK>                     ▄  ???
  293.      4    ▄                      <SECTOR>                    ▄   1
  294.      5    ▄                <NUMBER OF SECTORS>               ▄   9
  295.    -------+--------------------------------------------------+-------
  296.  
  297. ╘HERE ARE A COUPLE OF DIFFERENCES BETWEEN THE 1571 AND 1581 VERSIONS OF THIS
  298. COMMAND.  ═OST IMPORTANT, THE ╙ BIT (╙IDE OF DISK TO USE) HAS THE OPPOSITE
  299. MEANING ON THE TWO DRIVES.  ╘HERE'S NO GOOD REASON THAT ╔ KNOW OF FOR THIS
  300. INCONSISTENCY.  ╘HIS IS THE REASON THAT ╠╥╥ NEEDS TO KNOW WHAT TYPE OF ═╙-─╧╙
  301. DRIVE IT IS DEALING WITH (PLUS INTERLEAVING).
  302.  
  303. ╘HE READ COMMAND RETURNS THE FOLLOWING DATA USING BURST MODE HANDSHAKING:
  304.  
  305.        +-------------------+
  306.      0 ▄ ┬URST ╙TATUS ┬YTE ▄
  307.        +-------------------+
  308.      1 ▄                   ▄
  309.    ... +  512 ─ATA ┬YTES   ▄
  310.    512 ▄                   ▄
  311.        +-------------------+
  312.  
  313. FOR EACH SECTOR TRANSFERRED.  ╔F THE ┬URST ╙TATUS ┬YTE INDICATES AN ERROR,
  314. THEN THE DATA IS NOT TRANSFERRED AND NONE OF THE FOLLOWING SECTORS ARE
  315. EITHER.  ╔F THE STATUS BYTE GIVES A "─ISK ├HANGED" ERROR, THEN YOU HAVE TO LOG
  316. IN THE DISK WITH THE ╤UERY ─ISK ╞ORMAT COMMAND BEFORE READ WILL WORK
  317. PROPERLY.  ╘HIS IS ACTUALLY A GOOD FEATURE SINCE IT LETS YOU KNOW ABOUT A DISK
  318. CHANGE SO YOU CAN UPDATE ANY DATA STRUCTURES YOU MAY HAVE.  ╠╥╥ SIMPLY RE-LOGS
  319. IN THE DISK WITHOUT UPDATING ANY DATA STRUCTURES AND RE-TRIES THE FAILED READ
  320. OPERATION.
  321.  
  322. 3. ═╙-─╧╙ ─╔╙╦ ╞╧╥═┴╘
  323.  
  324. ┴N ═╙-─╧╙ DISK IS SEPARATED INTO 4 DIFFERENT PARTS: THE ┬OOT ╙ECTOR, THE
  325. ╞┴╘(S), THE ╥OOT ─IRECTORY, AND THE ╞ILE ─ATA ╙ECTORS.  ╘HE LOGICAL SECTORS
  326. (BLOCKS) OF A DISK ARE NUMBERED FROM 0 TO SOME MAXIMUM NUMBER (1439 FOR A
  327. 3.5", 719 FOR A 5.25" ── DISK).  ╘HE PHYSICAL LAYOUT AND THE LOGICAL SECTOR
  328. NUMBERS TYPICALLY USED BY A 3.5" DISK ARE SHOWN HERE:
  329.  
  330.          +-------------------+
  331.        0 ▄    ┬OOT ╙ECTOR    ▄
  332.          +-------------------+
  333.     1..3 ▄    ╞┴╘ COPY #1    ▄
  334.          +-------------------+
  335.     4..6 ▄    ╞┴╘ COPY #2    ▄
  336.          +-------------------+
  337.    7..14 ▄  ╥OOT ─IRECTORY   ▄
  338.          +-------------------+
  339.       15 ▄                   ▄
  340.      ... ▄ ╞ILE ─ATA ╙ECTORS ▄
  341.     1439 ▄                   ▄
  342.          +-------------------+
  343.  
  344. 3.1. ╘╚┼ ┬╧╧╘ ╙┼├╘╧╥
  345.  
  346. ╘HE ┬OOT ╙ECTOR IS ALWAYS AT LOGICAL SECTOR NUMBER 0.  ╔T CONTAINS SOME
  347. IMPORTANT INFORMATION ABOUT THE FORMAT OF THE DISK AND IT ALSO CONTAINS CODE
  348. TO BOOT AN ═╙-─╧╙ MACHINE FROM.  ╫E AREN'T CONCERNED WITH THE BOOTSTRAPPING
  349. CODE, BUT THE IMPORTANT VALUES WE NEED TO OBTAIN FROM THE BOOT SECTOR ARE:
  350.  
  351.    ┴┬┬╥     ╧╞╞╙┼╘     1571     1581     ─┼╙├╥╔╨╘╔╧╬
  352.    ----     ------     ----     ----     -----------
  353.     ├╙        13          2        2     ├LUSTER SIZE IN SECTORS
  354.     ╬┬        14          1        1     ╬UMBER OF BOOT SECTORS
  355.     ╬╞        16          2        2     ╬UMBER OF ╞┴╘S
  356.     ╞╠        23          2        3     ╞┴╘ SIZE IN SECTORS
  357.     ─┼        17        112      112     ╬UMBER OF ROOT DIRECTORY ENTRIES
  358.     ╘╙       19,20      720     1440     ╘OTAL ╬UMBER OF SECTORS
  359.     ╬╙        24          9        9     ╬UMBER OF SECTORS PER TRACK
  360.     ╬╚        26          2        2     ╬UMBER OF SIDES
  361.  
  362. ╘HE 1571 AND 1581 COLUMNS GIVE THE TYPICAL VALUES OF THESE PARAMETERS FOR
  363. 5.25" AND 3.5" DISKS.  ╘HE ╧╞╞╙┼╘ IS THE ADDRESS OF THE PARAMETER WITHIN THE
  364. BOOT SECTOR.  ╘HE TOTAL NUMBER OF SECTORS IS GIVEN IN LOW-BYTE, HIGH-BYTE
  365. ORDER (SINCE THE 80X86 FAMILY IS LITTLE-ENDIAN LIKE THE 6502 FAMILY).  ╞ROM
  366. THE ABOVE PARAMETERS, WE CAN DERIVE THE FOLLOWING IMPORTANT PARAMETERS:
  367.  
  368.    ┴┬┬╥     ╞╧╥═╒╠┴       1571     1581     ─┼╙├╥╔╨╘╔╧╬
  369.    ----      -------      ----     ----     -----------
  370.     ╞1      ╬┬+╬╞*╞╠         5        7     ╞IRST ROOT DIRECTORY SECTOR
  371.     ╞╙     ╬┬+╬╞*╞╠+─┼      12       14     ╞IRST FILE DATA SECTOR NUMBER
  372.     ╬├     (╘╙-╞╙)/├╙      354      713     ╘OTAL NUMBER OF FILE CLUSTERS
  373.  
  374. ╠╥╥ IMPOSES A NUMBER OF LIMITS ON THESE PARAMETERS AND WILL ERROR-OUT IF YOU
  375. TRY TO USE A DISK THAT IS OUTSIDE OF ╠╥╥'S LIMITS.
  376.  
  377. 3.2. ├╚┼╫╔╬╟ ╘╚┼ ╞┴╘
  378.  
  379. ═╙-─╧╙ DISKS USE A DATA STRUCTURE CALLED A ╞ILE ┴LLOCATION ╘ABLE (╞┴╘) TO
  380. RECORD WHICH CLUSTERS BELONG TO WHICH FILE IN WHAT ORDER AND WHICH BLOCKS ARE
  381. FREE.  ┴ CLUSTER IS A SET OF CONTIGUOUS SECTORS WHICH ARE ALLOCATED TO FILES
  382. AS A GROUP.  ╠╥╥ HANDLES CLUSTER SIZES OF 1 AND 2 SECTORS, GIVING A LOGICAL
  383. FILE BLOCK SIZE OF 512 OR 1024 BYTES.  ╘YPICALLY, A CLUSTER SIZE OF 2 SECTORS
  384. IS USED.
  385.  
  386. ╘HE ╞┴╘ IS AN ARRAY OF 12-BIT NUMBERS, WITH AN ENTRY CORRESPONDING TO EACH
  387. CLUSTER THAT CAN BE ALLOCATED TO FILES.  ╞┴╘ ENTRIES 0 AND 1 ARE RESERVED.  ╔F
  388. A ╞┴╘ ENTRY CONTAINS A VALUE OF $000, THEN THE CORRESPONDING CLUSTER IS FREE
  389. AND CAN BE ALLOCATED TO A FILE; OTHERWISE, THE CLUSTER IS ALLOCATED AND THE
  390. ╞┴╘ ENTRY CONTAINS THE NUMBER OF THE ╬┼╪╘ ╞┴╘ ENTRY THAT BELONGS TO THE FILE.
  391. ╘HUS, ═╙-─╧╙ FILES ARE STORED IN A SINGLY-LINKED LIST OF CLUSTERS LIKE
  392. ├OMMODORE-─╧╙ FILES ARE, EXCEPT THAT THE LINKS ARE NOT IN THE DATA SECTORS BUT
  393. RATHER ARE IN THE ╞┴╘.  ╘HE POINTER TO THE FIRST ╞┴╘ ENTRY FOR A FILE IS GIVEN
  394. IN THE FILE'S DIRECTORY ENTRY.
  395.  
  396. ┴ SPECIAL ╬╒╠╠/╬╔╠ POINTER VALUE OF $╞╞╞ IS USED TO INDICATE THE END OF THE
  397. CHAIN OF CLUSTERS ALLOCATED TO A FILE.  ╘HIS VALUE IS STORED IN THE ╞┴╘ ENTRY
  398. OF THE LAST CLUSTER ALLOCATED TO A FILE (OF COURSE).  ├ONSIDER THE FOLLOWING
  399. EXAMPLE ╞┴╘:
  400.  
  401.    ┼╬╘╥┘       ╓┴╠╒┼
  402.    -----       -----
  403.     $000        $╞╞╞
  404.     $001        $╞╞╞
  405.     $002   ▄----$003 <------─IRECTORY ┼NTRY
  406.     $003   +--> $005----+
  407.     $004        $000    ▄
  408.     $005        $╞╞╞ <--+
  409.  
  410. ┼NTRIES 0 AND 1 ARE INSIGNIFICANT SINCE THEY ARE RESERVED.  ╙AY THAT A FILE
  411. STARTS AT ╞┴╘ ENTRY #2.  ╘HEN, IT CONSISTS OF THE FOLLOWING CHAIN OF CLUSTERS:
  412. 2, 3, AND 5.  ├LUSTER #4 IS FREE.  ├LUSTERS CAN BE ALLOCATED TO A FILE IN
  413. RANDOM ORDER, BUT IF THEY ARE ALLOCATED CONTIGUOUSLY IN FORWARD ORDER, THEN
  414. THE FILE WILL BE ABLE TO BE READ FASTER.  ╘HE ╞┴╘ IS SUCH AN IMPORTANT DATA
  415. STRUCTURE THAT TYPICALLY TWO COPIES ARE KEPT ON THE DISK INCASE ONE OF THEM
  416. SHOULD BECOME CORRUPTED.
  417.  
  418. ╘HE ═╙-─╧╙ DESIGNERS WERE A LITTLE SNEAKY IN STORING THE 12-BIT ╞┴╘ ENTRIES -
  419. THEY USED ONLY 12 REAL BITS PER ENTRY.  ╔E., THEY STORE TWO ╞┴╘ ENTRIES IN
  420. THREE BYTES, WHERE THE TWO ENTRIES SHARE THE TWO NYBBLES OF THE MIDDLE BYTE.
  421. ╘HE FOLLOWING DIAGRAM SHOWS HOW THE NYBBLES 1 (HIGH), 2 (MID), AND 3 (LOW) ARE
  422. STORED INTO ╞┴╘ ENTRIES ┴ AND ┬:
  423.  
  424.      ┬┘╘┼:       0            1            2
  425.              +---+---+    +---+---+    +---+---+
  426.     ┼╬╘╥┘:   ▄ ┴ ▄ ┴ ▄    ▄ ┬ ▄ ┴ ▄    ▄ ┬ ▄ ┬ ▄
  427.    ╬┘┬┬╠┼:   ▄ 2 ▄ 3 ▄    ▄ 3 ▄ 1 ▄    ▄ 1 ▄ 2 ▄
  428.              +---+---+    +---+---+    +---+---+
  429.  
  430. ┴NYWAY, LET'S JUST SAY IT'S A BIT TRICKY TO EXTRACT THE 12-BIT VALUES FROM
  431. THIS COMPRESSED DATA STRUCTURE.  ╧N TOP OF THAT, ╔ DON'T THINK THERE IS ANY
  432. SAVING IN DISK SPACE RESULTING FROM COMPRESSING THIS STRUCTURE; THEY MIGHT AS
  433. WELL HAVE JUST USED A 16-BIT ╞┴╘ (LIKE THEY DO NOWADAYS ON LARGER DISKS).
  434.  
  435. 3.3. ╘╚┼ ╥╧╧╘ ─╔╥┼├╘╧╥┘
  436.  
  437. ╘HE ROOT DIRECTORY HAS A FIXED SIZE, ALTHOUGH ╔ DON'T THINK THAT
  438. SUBDIRECTORIES DO.  ╠╥╥ CANNOT ACCESS SUBDIRECTORIES.  ┼ACH 512-BYTE SECTOR OF
  439. THE ROOT DIRECTORY CONTAINS SIXTEEN 32-BYTE DIRECTORY ENTRIES.  ╧NE DIRECTORY
  440. ENTRY IS REQUIRED FOR EACH FILE STORED ON THE DISK.  ┴ DIRECTORY ENTRY HAS THE
  441. FOLLOWING STRUCTURE:
  442.  
  443.    ╧╞╞╙┼╘     ╠┼╬     ─┼╙├╥╔╨╘╔╧╬
  444.    ------     ---     -----------
  445.      0..7       8     ╞ILENAME
  446.     8..10       3     ┼XTENSION
  447.        11       1     <UNUSED?>
  448.        12       1     ┴TTRIBUTES: $10=─IRECTORY, $08=╓OLUME╔D
  449.    13..21       9     <UNUSED>
  450.    22..25       4     ─ATE
  451.    26..27       2     ╙TARTING ╞┴╘ ENTRY NUMBER
  452.    28..31       4     ╞ILE LENGTH IN BYTES
  453.  
  454. ╘HE FILENAME AND EXTENSION ARE STORED WITH TRAILING PADDING SPACES.  ╔F A
  455. DIRECTORY ENTRY IS UNUSED OR DELETED, THEN THE FIRST CHARACTER OF THE FILENAME
  456. IS EITHER A $00 OR A $┼5 (229).  ╘HIS IS WHY YOU HAVE TO PROVIDE THE FIRST
  457. CHARACTER OF A FILENAME IF YOU ARE UNDELETING A FILE ON AN ═╙-─╧╙ MACHINE.
  458. ╬OTE THAT THERE IS ENOUGH UNUSED SPACE THAT ═ICROSOFT OR ╔┬═ COULD HAVE
  459. DITCHED THE ANNOYING 8+3 CHARACTER FILENAME FORMAT.
  460.  
  461. ╘HE ATTRIBUTES BITS TELL WHETHER THE DIRECTORY ENTRY IS FOR A REGULAR FILE, A
  462. SUBDIRECTORY, A DISK VOLUME NAME (IN WHICH CASE THERE IS NO FILE DATA), AND A
  463. COUPLE OF OTHER THINGS ╔ CAN'T REMEMBER.  ╔'M NOT SURE ABOUT THE EXACT
  464. POSITION OR FORMAT OF THE DATE, BUT ╠╥╥ DOESN'T USE IT ANYWAY.  ╘HE STARTING
  465. ╞┴╘ ENTRY NUMBER AND THE FILE LENGTH ARE STORED IN LOWER-BYTE-FIRST ORDER.
  466.  
  467. 3.4. ╘╚┼ ╞╔╠┼ ─┴╘┴ ╙╨┴├┼
  468.  
  469. ╘HE RAMAINDER OF THE DISK SPACE IS USED FOR STORING FILE DATA IN CLUSTERS OF 1
  470. OR 2 SECTORS EACH.  ╟IVEN A CLUSTER NUMBER (WHICH IS ALSO THE ╞┴╘ ENTRY
  471. NUMBER), THE FOLLOWING FORMULA IS USED TO CALCULATE THE STARTING LOGICAL
  472. SECTOR NUMBER OF THE CLUSTER:
  473.  
  474. (├LUSTER╬UMBER - 2) * ├LUSTER╙IZE╔N┬LOCKS + ╞IRST╞ILE─ATA╠OGICAL╙ECTOR╬UMBER
  475.  
  476. WHERE "╞IRST╞ILE─ATA╠OGICAL╙ECTOR╬UMBER" IS THE "╞╙" PARAMETER DERIVED
  477. EARLIER.  ╘HE FOLLOWING CONSECUTIVE LOGICAL SECTOR NUMBERS UP TO THE NUMBER OF
  478. SECTORS PER CLUSTER FORM THE REST OF THE CLUSTER.  ╬OTE THAT A SINGLE CLUSTER
  479. CAN SPAN SECTORS FROM ONE SIDE OF THE DISK TO ANOTHER OR FROM ONE TRACK TO
  480. ANOTHER.  ╫E PERFORM THE "(├LUSTER╬UMBER - 2)" PORTION OF THE CALCULATION
  481. SINCE THE FIRST TWO ╞┴╘ ENTRIES ARE RESERVED.
  482.  
  483. ╙INCE THE ╥EAD BURST COMMAND OF THE 1571/81 WANTS THE SIDE, TRACK, AND SECTOR
  484. NUMBER OF A SECTOR RATHER THAN ITS LOGICAL NUMBER, WE ALSO NEED FORMULAE FOR
  485. THESE CONVERSIONS:
  486.  
  487.    ╘RACK  = ╠OGICAL╙ECTOR╬UMBER / 18
  488.    ╙ECTOR = ╠OGICAL╙ECTOR╬UMBER % 9 + 1
  489.    ╙IDE   = (╠OGICAL╙ECTOR╬UMBER / 9) % 2
  490.  
  491. ╘HESE FORMULAE ARE MORE PROBLEMATIC THAN THE PREVIOUS ONE SINCE THEY REQUIRE
  492. DIVISION BY 9 AND 18.  ╠╥╥ USES THE METHOD OF REPEATED SUBTRACTION TO PERFROM
  493. THE NECESSARY DIVISION (ONLY ONE DIVISION IS NECESSARY).  ╘HE ABOVE FORMULAE
  494. IMPLY THAT SEQUENTIAL LOGICAL SECTORS ARE STORED ON THE TOP OF THE DISK
  495. FIRST AND THEN THE BOTTOM OF THE DISK OF THE SAME TRACK, AND THEN ON THE TOP
  496. OF THE NEXT TRACK, ETC.  ╘HIS IS A GOOD SECTOR NUMBERING SCHEME (UNLIKE THE
  497. ├┬═-─╧╙ SCHEME FOR 1571 SECTORS) SINCE IT IS FASTER TO SWITCH SIDES OF THE
  498. DISK THAN IT IS TO SWITCH TRACKS, SO YOU CAN READ THE DISK FASTER.
  499.  
  500. ╧H YEAH, THE WAY THAT YOU KNOW HOW MANY FILE DATA BYTES ARE IN THE LAST
  501. CLUSTER OF A FILE CHAIN (THE CLUSTER WITH THE ╬╒╠╠ ╞┴╘ ENTRY) IS TO TAKE THE
  502. FILE LENGTH FROM THE DIRECTORY ENTRY AND "MOD" (THE ├ LANGUAGE % OPERATOR) IT
  503. WITH THE CLUSTER SIZE.  ╧NE SPECIAL CASE IS IF THIS CALCULATION RESULTS IN A
  504. ZERO, THEN THE LAST CLUSTER IS COMPLETELY FULL (RATHER THAN COMPLETELY EMPTY
  505. AS THE CALCULATION WOULD SUGGEST).  ╘HIS CALCULATION IS EASILY DONE IN
  506. MACHINE LANGUAGE WITH AN ┴╬─ OPERATION SINCE THE CLUSTER SIZE IS ALWAYS A
  507. POWER OF TWO.
  508.  
  509. 4. ╞╔╠┼ ├╧╨┘╔╬╟ ╨┴├╦┴╟┼
  510.  
  511. ╘HIS SECTION DISCUSSES THE INTERFACE TO AND IMPLEMENTATION OF THE ═╙-─╧╙ FILE
  512. COPYING PACKAGE.  ╔T IS WRITTEN IN ASSEMBLY LANGUAGE AND IS LOADED INTO MEMORY
  513. AT ADDRESS $8000 ON BANK 0 AND REQUIRES ABOUT 13╦ OF MEMORY.  ╘HE PACKAGE IS
  514. LOADED AT THIS HIGH ADDRESS TO BE OUT OF THE WAY OF THE MAIN ┬┴╙╔├ PROGRAM,
  515. EVEN IF ╥┴═─╧╙ IS INSTALLED.
  516.  
  517. 4.1. ╔╬╘┼╥╞┴├┼
  518.  
  519. ╘HE SUBROUTINE CALL AND PARAMETER PASSING INTERFACE TO THE FILE COPYING
  520. PACKAGE IS SUMMARIZED AS FOLLOWS:
  521.  
  522.    ┴──╥┼╙╙     ─┼╙├╥╔╨╘╔╧╬
  523.    -------     -----------
  524.    ╨╦          ╔NIT╨ACKAGE SUBROUTINE
  525.    ╨╦+3        ╠OAD─IRECTORY SUBROUTINE
  526.    ╨╦+6        ├OPY╞ILE SUBROUTINE
  527.    ╨╦+9        TWO-BYTE PACKAGE IDENTIFICATION NUMBER
  528.    ╨╦+15       ERRNO : ERROR CODE RETURNED
  529.    ╨╦+16       ═╙-─╧╙ DEVICE NUMBER (8 TO 30)
  530.    ╨╦+17       ═╙-─╧╙ DEVICE TYPE ($00=1571, $╞╞=1581)
  531.    ╨╦+18       TWO-BYTE STARTING CLUSTER NUMBER FOR FILE COPYING
  532.    ╨╦+20       LOW AND MID BYTES OF FILE LENGTH FOR COPYING
  533.  
  534. WHERE "╨╦" IS THE LOAD ADDRESS OF THE PACKAGE.  ┴DDITIONAL SUBROUTINE
  535. PARAMETERS ARE PASSED IN THE PROCESSOR REGISTERS.
  536.  
  537. ╘HE "╔NIT╨ACKAGE" SUBROUTINE SHOULD BE CALLED WHEN THE PACKAGE IS FIRST
  538. INSTALLED, WHENEVER THE ═╙-─╧╙ DEVICE NUMBER IS CHANGED, AND WHENEVER A NEW
  539. DISK IS MOUNTED TO INVALIDATE THE INTERNAL TRACK CACHE.  ╔T REQUIRES NO
  540. PARAMETERS.
  541.  
  542. ╘HE "╠OAD─IRECTORY" SUBROUTINE WILL LOAD THE DIRECTORY, ╞┴╘, AND THE ┬OOT
  543. ╙ECTOR PARAMETERS INTO THE INTERNAL MEMORY OF THE PACKAGE FROM THE CURRENT
  544. ═╙-─╧╙ DEVICE NUMBER.  ╬O (OTHER) INPUT PARAMETERS ARE NEEDED AND THE
  545. SUBROUTINE RETURNS A POINTER TO THE DIRECTORY SPACE IN THE .┴┘ REGISTERS AND
  546. THE NUMBER OF DIRECTORY ENTRIES IN THE .╪ REGISTER.  ╔F AN ERROR OCCURS, THEN
  547. THE SUBROUTINE RETURNS WITH THE ├ARRY FLAG SET AND THE ERROR CODE IS AVAILABLE
  548. IN THE "ERRNO" INTERFACE VARIABLE.  ╘HE DIRECTORY ENTRY DATA IS IN THE
  549. DIRECTORY SPACE AS IT WAS READ IN RAW FROM THE DIRECTORY SECTORS ON THE ═╙-─╧╙
  550. DISK.
  551.  
  552. ╘HE "├OPY╞ILE" SUBROUTINE WILL COPY A SINGLE FILE FROM THE ═╙-─╧╙ DISK TO A
  553. SPECIFIED ├┬═-╦ERNAL LOGICAL FILE NUMBER (THE ├┬═ FILE MUST ALREADY BE
  554. OPENED).  ╔F THE ├┬═ LOGICAL FILE NUMBER IS ZERO, THEN THE FILE DATA IS SIMPLY
  555. DISCARDED AFTER IT IS READ FROM THE ═╙-─╧╙ FILE.  ╘HE STARTING CLUSTER NUMBER
  556. OF THE FILE TO COPY AND THE LOW AND MID BYTES OF THE FILE LENGTH ARE PASSED IN
  557. THE ╨╦+18 AND ╨╦+20 INTERFACE WORDS.  ╘HE TRANSLATION MODE TO USE IS PASSED IN
  558. THE .┴ REGISTER ($00=BINARY, $╞╞=ASCII) AND THE ├┬═ LOGICAL FILE NUMBER TO
  559. OUTPUT TO IS PASSED IN THE .╪ REGISTER.  ╔F AN ERROR OCCURS, THE ROUTINE
  560. RETURNS WITH THE ├ARRY FLAG SET AND THE ERROR CODE IN THE "ERRNO" INTERFACE
  561. VARIABLE.  ╘HERE ARE NO OTHER OUTPUT PARAMETERS.
  562.  
  563. ╬OTE THAT SINCE THE STARTING CLUSTER NUMBER AND LOW-FILE LENGTH OF THE FILE TO
  564. BE COPIED ARE REQUIRED RATHER THAN THE FILENAME, IT IS THE RESPONSIBILITY OF
  565. THE FRONT-END APPLICATION PROGRAM TO DIG THROUGH THE RAW DIRECTORY SECTOR DATA
  566. TO GET THIS INFORMATION.  ╘HE APPLICATION MUST ALSO OPEN THE ├OMMODORE-─╧╙
  567. FILE OF WHATEVER FILETYPE ON WHATEVER DEVICE IS REQUIRED; THE PACKAGE DOES NOT
  568. NEED TO KNOW THE ├OMMODORE-─╧╙ DEVICE NUMBER.
  569.  
  570. ╘HE ═╙-─╧╙ DEVICE NUMBER AND DEVICE TYPE INTERFACE VARIABLES ALLOW YOU TO SET
  571. THE ═╙-─╧╙ DRIVE AND THE PACKAGE IDENTIFICATION NUMBER ALLOWS THE APPLICATION
  572. PROGRAM TO CHECK IF THE PACKAGE IS ALREADY LOADED INTO MEMORY SO THAT IT ONLY
  573. HAS TO LOAD THE PACKAGE THE FIRST TIME THE APPLICATION IS RUN AND NOT ON
  574. RE-RUNS.  ╘HE IDENTIFICATION SEQUENCE IS A VALUE OF $├┬ FOLLOWED BY A VALUE
  575. OF 131.
  576.  
  577. 4.2. ╔═╨╠┼═┼╬╘┴╘╔╧╬
  578.  
  579. ╘HIS SECTION PRESENTS THE CODE THAT IMPLEMENTS THE ═╙-─╧╙ FILE READING
  580. PACKAGE.  ╔T IS HERE IN A SPECIAL FORM; EACH CODE LINE IS PRECEDED BY A FEW
  581. SPECIAL CHARACTERS AND THE LINE NUMBER.  ╘HE SPECIAL CHARACTERS ARE THERE TO
  582. ALLOW YOU TO EASILY EXTRACT THE ASSEMBLER CODE FROM THE REST OF THIS MAGAZINE
  583. (AND ALL OF MY UGLY COMMENTS).  ╧N A ╒NIX SYSTEM, ALL YOU HAVE TO DO IS
  584. EXECUTE THE FOLLOWING COMMAND LINE (SUBSTITUTE FILENAMES AS APPROPRIATE):
  585.  
  586. GREP '^\.%...\!' ╚ACK4 ▄ SED 'S/^.%...\!..//' ▄ SED 'S/.%...\!//' >LRR.S
  587.  
  588. ┘OU'LL NOTICE THAT THE INITIAL COMMENT LINES HERE WERE AN AFTERTHOUGHT.
  589.  
  590. .%000!  ;╠ITTLE ╥ED ╥EADER ═╙-─╧╙ FILE COPIER PROGRAM
  591. .%000!  ;WRITTEN 92/10/03 BY ├RAIG ┬RUCE FOR ├= ╚ACKING ╬ET ═AGAZINE
  592. .%000!
  593.  
  594. ╘HE CODE IS WRITTEN FOR THE ┬UDDY ASSEMBLER AND HERE ARE A COUPLE SETUP
  595. DIRECTIVES.  ╬OTE THAT MY COMMENTS COME BEFORE THE SECTION OF CODE.
  596.  
  597. .%001!  .ORG $8000
  598. .%002!  .OBJ "@:LRR.BIN"
  599. .%003!
  600. .%004!  ;====JUMP TABLE AND PARAMETERS INTERFACE ====
  601. .%005!
  602. .%006!  JMP INIT╨ACKAGE
  603. .%007!  JMP LOAD─IRECTORY
  604. .%008!  JMP COPY╞ILE
  605. .%009!
  606. .%010!  .BYTE $CB,131   ;IDENTIFICATION
  607. .%011!  .BYTE 0,0,0,0
  608. .%012!
  609.  
  610. ╘HESE VARIABLES ARE INCLUDED IN THE PACKAGE PROGRAM SPACE TO MINIMIZE UNWANTED
  611. INTERACTION WITH OTHER PROGRAMS LOADED AT THE SAME TIME, SUCH AS THE ╥┴═─╧╙
  612. DEVICE DRIVER.
  613.  
  614. .%013!  ERRNO           .BUF 1    ;(LOCATION PK+15)
  615. .%014!  SOURCE─EVICE    .BUF 1
  616. .%015!  SOURCE╘YPE      .BUF 1    ;$00=1571, $FF=1581
  617. .%016!  START├LUSTER    .BUF 2
  618. .%017!  LEN═╠           .BUF 2    ;LENGTH MEDIUM AND LOW BYTES
  619. .%018!
  620. .%019!  ;====GLOBAL DECLARAIONS====
  621. .%020!
  622. .%021!  KERNEL╠ISTEN = $FFB1
  623. .%022!  KERNEL╙ECOND = $FF93
  624. .%023!  KERNEL╒NLSN  = $FFAE
  625. .%024!  KERNEL┴CPTR  = $FFA2
  626. .%025!  KERNEL├IOUT  = $FFA8
  627. .%026!  KERNEL╙PINP  = $FF47
  628. .%027!  KERNEL├HKOUT = $FFC9
  629. .%028!  KERNEL├LRCHN = $FFCC
  630. .%029!  KERNEL├HROUT = $FFD2
  631. .%030!
  632. .%031!  ST = $D0
  633. .%032!  CIA├LOCK = $DD00
  634. .%033!  CIA╞LAGS = $DC0D
  635. .%034!  CIA─ATA  = $DC0C
  636. .%035!
  637.  
  638. ╘HESE ARE THE PARAMETERS AND DERIVED PARAMETERS FROM THE BOOT SECTOR.  ╘HEY
  639. ARE KEPT IN THE PROGRAM SPACE TO AVOID INTERACTIONS.
  640.  
  641. .%036!  CLUSTER┬LOCK├OUNT .BUF 1        ;1 OR 2
  642. .%037!  FAT┬LOCKS         .BUF 1        ;UP TO 3
  643. .%038!  ROOT─IR┬LOCKS     .BUF 1        ;UP TO 8
  644. .%039!  ROOT─IR┼NTRIES    .BUF 1        ;UP TO 128
  645. .%040!  TOTAL╙ECTORS      .BUF 2        ;UP TO 1440
  646. .%041!  FIRST╞ILE┬LOCK    .BUF 1
  647. .%042!  FIRST╥OOT─IR┬LOCK .BUF 1
  648. .%043!  FILE├LUSTER├OUNT  .BUF 2
  649. .%044!
  650.  
  651. ╘HE CYLINDER (TRACK) AND SIDE THAT IS CURRENTLY STORED IN THE TRACH CACHE.
  652.  
  653. .%045!  BUF├YLINDER     .BUF 1
  654. .%046!  BUF╙IDE         .BUF 1
  655. .%047!  FORMAT╨ARMS     .BUF 6
  656. .%048!
  657.  
  658. ╘HIS PACKAGE IS SPLIT INTO A NUMBER OF LEVELS.  ╘HIS LEVEL INTERFACES WITH THE
  659. ╦ERNAL SERIAL BUS ROUTINES AND THE BURST COMMAND PROTOCOL OF THE DISK DRIVES.
  660.  
  661. .%049!  ;====HARDWARE LEVEL====
  662. .%050!
  663.  
  664. ├ONNECT TO THE ═╙-─╧╙ DEVICE AND SEND THE "╒0" BURST COMMAND PREFIX AND THE
  665. BURST COMMAND BYTE.
  666.  
  667. .%051!  SEND╒0 = *  ;( .┴=BURST├OMMAND├ODE ) : .├╙=ERR
  668. .%052!     PHA
  669. .%053!     LDA #0
  670. .%054!     STA ST
  671. .%055!     LDA SOURCE─EVICE
  672. .%056!     JSR KERNEL╠ISTEN
  673. .%057!     LDA #$6F
  674. .%058!     JSR KERNEL╙ECOND
  675. .%059!     LDA #"U"
  676. .%060!     JSR KERNEL├IOUT
  677. .%061!     BIT ST
  678. .%062!     BMI SEND╒0┼RROR
  679. .%063!     LDA #"0"
  680. .%064!     JSR KERNEL├IOUT
  681. .%065!     PLA
  682. .%066!     JSR KERNEL├IOUT
  683. .%067!     BIT ST
  684. .%068!     BMI SEND╒0┼RROR
  685. .%069!     CLC
  686. .%070!     RTS
  687. .%071!
  688. .%072!     SEND╒0┼RROR = *
  689. .%073!     LDA #5
  690. .%074!     STA ERRNO
  691. .%075!     SEC
  692. .%076!     RTS
  693. .%077!
  694.  
  695. ╘OGGLE THE "─ATA ┴CCEPTED / ╥EADY ╞OR ═ORE" CLOCK SIGNAL FOR THE BURST
  696. TRANSFER PROTOCOL.
  697.  
  698. .%078!  TOGGLE├LOCK = *
  699. .%079!     LDA CIA├LOCK
  700. .%080!     EOR #$10
  701. .%081!     STA CIA├LOCK
  702. .%082!     RTS
  703. .%083!
  704.  
  705. ╫AIT FOR A BURST BYTE TO ARRIVE IN THE SERIAL DATA REGISTER OF ├╔┴#1 FROM THE
  706. FAST SERIAL BUS.
  707.  
  708. .%084!  SERIAL╫AIT = *
  709. .%085!     LDA #$08
  710. .%086!  -  BIT CIA╞LAGS
  711. .%087!     BEQ -
  712. .%088!     RTS
  713. .%089!
  714.  
  715. ╫AIT FOR AND GET A BURST BYTE FROM THE FAST SERIAL BUS, AND SEND THE "─ATA
  716. ┴CCEPTED" SIGNAL.
  717.  
  718. .%090!  GET┬URST┬YTE = *
  719. .%091!     JSR SERIAL╫AIT
  720. .%092!     LDX CIA─ATA
  721. .%093!     JSR TOGGLE├LOCK
  722. .%094!     TXA
  723. .%095!     RTS
  724. .%096!
  725.  
  726. ╙END THE BURST COMMANDS TO "LOG IN" THE ═╙-─╧╙ DISK AND SET THE ╥EAD SECTOR
  727. INTERLEAVE FACTOR.
  728.  
  729. .%097!  MOUNT─ISK = *  ;() : .├╙=ERR
  730. .%098!     LDA #%00011010
  731. .%099!     JSR SEND╒0
  732. .%100!     BCC +
  733. .%101!     RTS
  734. .%102!  +  JSR KERNEL╒NLSN
  735. .%103!     BIT ST
  736. .%104!     BMI SEND╒0┼RROR
  737. .%105!     CLC
  738. .%106!     JSR KERNEL╙PINP
  739. .%107!     BIT CIA╞LAGS
  740. .%108!     JSR TOGGLE├LOCK
  741. .%109!     JSR GET┬URST┬YTE
  742. .%110!     STA ERRNO
  743. .%111!     AND #$0F
  744. .%112!     CMP #2
  745. .%113!     BCS MOUNT┼XIT
  746.  
  747. ╟RAB THE THROW-AWAY PARAMETERS FROM THE MOUNT OPERATION.
  748.  
  749. .%114!     LDY #0
  750. .%115!  -  JSR GET┬URST┬YTE
  751. .%116!     STA FORMAT╨ARMS,Y
  752. .%117!     INY
  753. .%118!     CPY #6
  754. .%119!     BCC -
  755. .%120!     CLC
  756.  
  757. ╙ET THE SECTOR INTERLEAVE TO 1 FOR A 1581 OR 4 FOR A 1571.
  758.  
  759. .%121!     ;** SET INTERLEAVE
  760. .%122!     LDA #%00001000
  761. .%123!     JSR SEND╒0
  762. .%124!     BCC +
  763. .%125!     RTS
  764. .%126!  +  LDA #1            ;INTERLEAVE OF 1 FOR 1581
  765. .%127!     BIT SOURCE╘YPE
  766. .%128!     BMI +
  767. .%129!     LDA #4            ;INTERLEAVE OF 4 FOR 1571
  768. .%130!  +  JSR KERNEL├IOUT
  769. .%131!     JSR KERNEL╒NLSN
  770. .%132!     MOUNT┼XIT = *
  771. .%133!     RTS
  772. .%134!
  773.  
  774. ╥EAD ALL OF THE SECTORS OF A GIVEN TRACK INTO THE TRACK CACHE.
  775.  
  776. .%135!  BUFPTR = 2
  777. .%136!  SECNUM = 4
  778. .%137!
  779. .%138!  READ╘RACK = *  ;( .┴=CYLINDER, .╪=SIDE ) : TRACKBUF, .├╙=ERR
  780. .%139!     PHA
  781. .%140!     TXA
  782.  
  783. ╟ET THE SIDE AND PUT IT INTO THE COMMAND BYTE.  ╥EMEMBER THAT WE HAVE TO FLIP
  784. THE SIDE BIT FOR A 1581.
  785.  
  786. .%141!     AND #$01
  787. .%142!     ASL
  788. .%143!     ASL
  789. .%144!     ASL
  790. .%145!     ASL
  791. .%146!     BIT SOURCE╘YPE
  792. .%147!     BPL +
  793. .%148!     EOR #$10
  794. .%149!  +  JSR SEND╒0
  795. .%150!     BCC +
  796. .%151!     RTS
  797. .%152!  +  PLA                  ;CYLINDER NUMBER
  798. .%153!     JSR KERNEL├IOUT
  799. .%154!     LDA #1               ;START SECTOR NUMBER
  800. .%155!     JSR KERNEL├IOUT
  801. .%156!     LDA #9               ;SECTOR COUNT
  802. .%157!     JSR KERNEL├IOUT
  803. .%158!     JSR KERNEL╒NLSN
  804.  
  805. ╨REPARE TO RECEIVE THE TRACK DATA.
  806.  
  807. .%159!     SEI
  808. .%160!     CLC
  809. .%161!     JSR KERNEL╙PINP
  810. .%162!     BIT CIA╞LAGS
  811. .%163!     JSR TOGGLE├LOCK
  812. .%164!     LDA #<TRACKBUF
  813. .%165!     LDY #>TRACKBUF
  814. .%166!     STA BUFPTR
  815. .%167!     STY BUFPTR+1
  816.  
  817. ╟ET THE SECTOR DATA FOR EACH OF THE 9 SECTORS OF THE TRACK.
  818.  
  819. .%168!     LDA #0
  820. .%169!     STA SECNUM
  821. .%170!  -  BIT SOURCE╘YPE
  822. .%171!     BMI +
  823.  
  824. ╔F WE ARE DEALING WITH A 1571, WE HAVE TO SET THE BUFFER POINTER FOR THE NEXT
  825. SECTOR, TAKING INTO ACCOUNT THE SOFT INTERLEAVE OF 4.
  826.  
  827. .%172!     JSR GET1571┬UF╨TR
  828. .%173!  +  JSR READ╙ECTOR
  829. .%174!     BCS TRACK┼XIT
  830. .%175!     INC SECNUM
  831. .%176!     LDA SECNUM
  832. .%177!     CMP #9
  833. .%178!     BCC -
  834. .%179!     CLC
  835. .%180!     TRACK┼XIT = *
  836. .%181!     CLI
  837. .%182!     RTS
  838. .%183!
  839.  
  840. ╟ET THE BUFFER POINTER FOR THE NEXT 1571 SECTOR.
  841.  
  842. .%184!  GET1571┬UF╨TR = *
  843. .%185!     LDA #<TRACKBUF
  844. .%186!     STA BUFPTR
  845. .%187!     LDX SECNUM
  846. .%188!     CLC
  847. .%189!     LDA #>TRACKBUF
  848. .%190!     ADC BUFPTR1571,X
  849. .%191!     STA BUFPTR+1
  850. .%192!     RTS
  851. .%193!
  852. .%194!  BUFPTR1571 = *
  853. .%195!     .BYTE 0,8,16,6,14,4,12,2,10
  854. .%196!
  855.  
  856. ╥EAD AN INDIVIDUAL SECTOR INTO MEMORY AT THE SPECIFIED ADDRESS.
  857.  
  858. .%197!  READ╙ECTOR = *  ;( BUFPTR ) : .├╙=ERR
  859.  
  860. ╟ET AND CHECK THE BURST STATUS BYTE FOR ERRORS.
  861.  
  862. .%198!     JSR GET┬URST┬YTE
  863. .%199!     STA ERRNO
  864. .%200!     AND #$0F
  865. .%201!     CMP #2
  866. .%202!     BCC +
  867. .%203!     RTS
  868. .%204!  +  LDX #2
  869. .%205!     LDY #0
  870. .%206!
  871.  
  872. ╥ECEIVE THE 512 SECTOR DATA BYTES INTO MEMORY.
  873.  
  874. .%207!     READ┬YTE = *
  875. .%208!     LDA #$08
  876. .%209!  -  BIT CIA╞LAGS
  877. .%210!     BEQ -
  878. .%211!     LDA CIA├LOCK
  879. .%212!     EOR #$10
  880. .%213!     STA CIA├LOCK
  881. .%214!     LDA CIA─ATA
  882. .%215!     STA (BUFPTR),Y
  883. .%216!     INY
  884. .%217!     BNE READ┬YTE
  885. .%218!     INC BUFPTR+1
  886. .%219!     DEX
  887. .%220!     BNE READ┬YTE
  888. .%221!     RTS
  889. .%222!
  890.  
  891. ╘HIS NEXT LEVEL OF ROUTINES DEALS WITH LOGICAL SECTORS AND THE TRACK CACHE
  892. RATHER THAN WITH HARDWARE.
  893.  
  894. .%223!  ;====LOGICAL SECTOR LEVEL====
  895. .%224!
  896.  
  897. ╔NVALIDATE THE TRACK CACHE IF THE ═╙-─╧╙ DRIVE NUMBER IS CHANGED OR IF A NEW
  898. DISK IS INSERTED.  ╘HIS ROUTINE HAS TO ESTABLISH A ╥┴═ CONFIGURATION OF $0┼
  899. SINCE IT WILL BE CALLED FROM ╥┴═0.  ├ONFIGURATION $0┼ GIVES ╥┴═0 FROM $0000 TO
  900. $┬╞╞╞, ╦ERNAL ╥╧═ FROM $├000 TO $╞╞╞╞, AND THE ╔/╧ SPACE OVER THE ╦ERNAL FROM
  901. $─000 TO $─╞╞╞.  ╘HIS CONFIGURATION IS SET BY ALL APPLICATION INTERFACE
  902. SUBROUTINES.
  903.  
  904. .%225!  INIT╨ACKAGE = *
  905. .%226!     LDA #$0E
  906. .%227!     STA $FF00
  907. .%228!     LDA #$FF
  908. .%229!     STA BUF├YLINDER
  909. .%230!     STA BUF╙IDE
  910. .%231!     CLC
  911. .%232!     RTS
  912. .%233!
  913.  
  914. ╠OCATE A SECTOR (BLOCK) IN THE TRACK CACHE, OR READ THE CORRESPONDING PHYSICAL
  915. TRACK INTO THE TRACK CACHE IF NECESSARY.  ╘HIS ROUTINE ACCEPTS THE CYLINDER,
  916. SIDE, AND SECTOR NUMBERS OF THE BLOCK.
  917.  
  918. .%234!  SECTOR╙AVE = 5
  919. .%235!
  920. .%236!  READ┬LOCK = *  ;( .┴=CYLINDER,.╪=SIDE,.┘=SECTOR ) : .┴┘=BLK╨TR,.├╙=ERR
  921.  
  922. ├HECK IF THE CORRECT TRACK IS IN THE TRACK CACHE.
  923.  
  924. .%237!     CMP BUF├YLINDER
  925. .%238!     BNE READ┬LOCK╨HYSICAL
  926. .%239!     CPX BUF╙IDE
  927. .%240!     BNE READ┬LOCK╨HYSICAL
  928.  
  929. ╔F SO, THEN LOCATE THE SECTOR'S ADDRESS AND RETURN THAT.
  930.  
  931. .%241!     DEY
  932. .%242!     TYA
  933. .%243!     ASL
  934. .%244!     CLC
  935. .%245!     ADC #>TRACKBUF
  936. .%246!     TAY
  937. .%247!     LDA #<TRACKBUF
  938. .%248!     CLC
  939. .%249!     RTS
  940. .%250!
  941.  
  942. ╚ERE, WE HAVE TO READ THE PHYSICAL TRACK INTO THE TRACK CACHE.  ╫E SAVE THE
  943. INPUT PARAMETERS AND CALL THE HARDWARE-LEVEL TRACK-READING ROUTINE.
  944.  
  945. .%251!     READ┬LOCK╨HYSICAL = *
  946. .%252!     STA BUF├YLINDER
  947. .%253!     STX BUF╙IDE
  948. .%254!     STY SECTOR╙AVE
  949. .%255!     JSR READ╘RACK
  950.  
  951. ├HECK FOR ERRORS.
  952.  
  953. .%256!     BCC READ┬LOCK╨HYSICAL╧K
  954. .%257!     LDA ERRNO
  955. .%258!     AND #$0F
  956. .%259!     CMP #11    ;DISK CHANGE
  957. .%260!     BEQ +
  958. .%261!     SEC
  959. .%262!     RTS
  960.  
  961. ╔F THE ERROR THAT HAPPENED IS A "─ISK ├HANGE" ERROR, THEN MOUNT THE DISK AND
  962. TRY TO READ THE PHYSICAL TRACK AGAIN.
  963.  
  964. .%263!  +  JSR MOUNT─ISK
  965. .%264!     LDA BUF├YLINDER
  966. .%265!     LDX BUF╙IDE
  967. .%266!     LDY SECTOR╙AVE
  968. .%267!     BCC READ┬LOCK╨HYSICAL
  969. .%268!     RTS
  970. .%269!
  971.  
  972. ╚ERE, THE PHYSICAL TRACK HAS BEEN READ INTO THE TRACK CACHE OK, SO WE RECOVER
  973. THE ORIGINAL INPUT PARAMETERS AND TRY THE TOP OF THE ROUTINE AGAIN.
  974.  
  975. .%270!     READ┬LOCK╨HYSICAL╧K = *
  976. .%271!     LDA BUF├YLINDER
  977. .%272!     LDX BUF╙IDE
  978. .%273!     LDY SECTOR╙AVE
  979. .%274!     JMP READ┬LOCK
  980. .%275!
  981.  
  982. ─IVIDE THE GIVEN NUMBER BY 18.  ╘HIS IS NEEDED FOR THE CALCULATIONS TO CONVERT
  983. A LOGICAL SECTOR NUMBER TO THE CORRESPONDING PHYSICAL CYLINDER, SIDE, AND
  984. SECTOR NUMBERS THAT THE LOWER-LEVEL ROUTINES REQUIRE.  ╘HE METHOD OF REPEATED
  985. SUBTRACTION IS USED.  ╘HIS ROUTINE WOULD PROBABLY WORK FASTER IF WE TRIED TO
  986. REPEATEDLY SUBTRACT 360 (18*20) AT THE TOP, BUT ╔ DIDN'T BOTHER.
  987.  
  988. .%276!  DIVIDE┬Y18 = *  ;( .┴┘=NUMBER ) : .┴=QUOTIENT, .┘=REMAINDER
  989. .%277!     ;** COULD REPEATEDLY SUBTRACT 360 HERE
  990. .%278!     LDX #$FF
  991. .%279!  -  INX
  992. .%280!     SEC
  993. .%281!     SBC #18
  994. .%282!     BCS -
  995. .%283!     DEY
  996. .%284!     BPL -
  997. .%285!     CLC
  998. .%286!     ADC #18
  999. .%287!     INY
  1000. .%288!     TAY
  1001. .%289!     TXA
  1002. .%290!     RTS
  1003. .%291!
  1004.  
  1005. ├ONVERT THE GIVEN LOGICAL BLOCK NUMBER TO THE CORRESPONDING PHYSICAL CYLINDER,
  1006. SIDE, AND SECTOR NUMBERS.  ╘HIS ROUTINE FOLLOWS THE FORMULAE GIVEN EARLIER
  1007. WITH A FEW SIMPLIFYING TRICKS.
  1008.  
  1009. .%292!  CONVERT╠OGICAL┬LOCK╬UM = *  ;( .┴┘=BLOCK╬UM ) : .┴=CYL, .╪=SIDE, .┘=SEC
  1010. .%293!     JSR DIVIDE┬Y18
  1011. .%294!     LDX #0
  1012. .%295!     CPY #9
  1013. .%296!     BCC +
  1014. .%297!     PHA
  1015. .%298!     TYA
  1016. .%299!     SBC #9
  1017. .%300!     TAY
  1018. .%301!     PLA
  1019. .%302!     LDX #1
  1020. .%303!  +  INY
  1021. .%304!     RTS
  1022. .%305!
  1023.  
  1024. ├OPY A SEQUENTIAL GROUP OF LOGICAL SECTORS INTO MEMORY.  ╘HIS ROUTINE IS USED
  1025. BY THE DIRECTORY LOADING ROUTINE TO LOAD THE ╞┴╘ AND ╥OOT ─IRECTORY, AND IS
  1026. USED BY THE CLUSTER READING ROUTINE TO RETRIEVE ALL OF THE BLOCKS OF A
  1027. CLUSTER.  ┴FTER THE GIVEN STARTING LOGICAL SECTOR NUMBER IS CONVERTED INTO ITS
  1028. PHYSICAL CYLINDER, SIDE, AND SECTOR EQUIVALENT, THE PHYSICAL VALUES ARE
  1029. INCREMENTED TO GET THE ADDRESS OF SUCCESSIVE SECTORS OF THE GROUP.  ╘HIS
  1030. AVOIDS THE OVERHEAD OF THE LOGICAL TO PHYSICAL CONVERSION.  ╤UITE A NUMBER OF
  1031. TEMPORARIES ARE NEEDED.
  1032.  
  1033. .%306!  DEST╨TR = 6
  1034. .%307!  CUR├YLINDER = 8
  1035. .%308!  CUR╙IDE = 9
  1036. .%309!  CUR╙ECTOR = 10
  1037. .%310!  BLOCK├OUNTDOWN = 11
  1038. .%311!  SOURCE╨TR = 12
  1039. .%312!
  1040. .%313!  COPY┬LOCKS = *  ;( .┴┘=START┬LOCK, .╪=BLOCK├OUNT, ($6)=DEST ) : .├╙=ERR
  1041. .%314!     STX BLOCK├OUNTDOWN
  1042. .%315!     JSR CONVERT╠OGICAL┬LOCK╬UM
  1043. .%316!     STA CUR├YLINDER
  1044. .%317!     STX CUR╙IDE
  1045. .%318!     STY CUR╙ECTOR
  1046. .%319!
  1047. .%320!     COPY┬LOCK╠OOP = *
  1048. .%321!     LDA CUR├YLINDER
  1049. .%322!     LDX CUR╙IDE
  1050. .%323!     LDY CUR╙ECTOR
  1051. .%324!     JSR READ┬LOCK
  1052. .%325!     BCC +
  1053. .%326!     RTS
  1054. .%327!  +  STA SOURCE╨TR
  1055. .%328!     STY SOURCE╨TR+1
  1056. .%329!     LDX #2
  1057. .%330!     LDY #0
  1058.  
  1059. ╚ERE ╔ UNROLL THE COPYING LOOP A LITTLE BIT TO CUT THE OVERHEAD OF THE BRANCH
  1060. INSTRUCTION IN HALF.  (┴ CYCLE SAVED... YOU KNOW).
  1061.  
  1062. .%331!  -  LDA (SOURCE╨TR),Y
  1063. .%332!     STA (DEST╨TR),Y
  1064. .%333!     INY
  1065. .%334!     LDA (SOURCE╨TR),Y
  1066. .%335!     STA (DEST╨TR),Y
  1067. .%336!     INY
  1068. .%337!     BNE -
  1069. .%338!     INC SOURCE╨TR+1
  1070. .%339!     INC DEST╨TR+1
  1071. .%340!     DEX
  1072. .%341!     BNE -
  1073.  
  1074. ╔NCREMENT THE CYLINDER, SIDE, SECTOR VALUES.
  1075.  
  1076. .%342!     INC CUR╙ECTOR
  1077. .%343!     LDA CUR╙ECTOR
  1078. .%344!     CMP #10
  1079. .%345!     BCC +
  1080. .%346!     LDA #1
  1081. .%347!     STA CUR╙ECTOR
  1082. .%348!     INC CUR╙IDE
  1083. .%349!     LDA CUR╙IDE
  1084. .%350!     CMP #2
  1085. .%351!     BCC +
  1086. .%352!     LDA #0
  1087. .%353!     STA CUR╙IDE
  1088. .%354!     INC CUR├YLINDER
  1089. .%355!  +  DEC BLOCK├OUNTDOWN
  1090. .%356!     BNE COPY┬LOCK╠OOP
  1091. .%357!     CLC
  1092. .%358!     RTS
  1093. .%359!
  1094.  
  1095. ╥EAD A CLUSTER INTO THE ├LUSTER ┬UFFER, GIVEN THE CLUSTER NUMBER.  ╘HE CLUSTER
  1096. NUMBER IS CONVERTED TO A LOGICAL SECTOR NUMBER AND THEN THE SECTOR COPYING
  1097. ROUTINE IS CALLED.  ╘HE FORMULA GIVEN EARLIER IS USED FOR THE CONVERSION.
  1098.  
  1099. .%360!  READ├LUSTER = *  ;( .┴┘=CLUSTER╬UMBER ) : CLUSTER┬UF, .├╙=ERR
  1100. .%361!     ;** CONVERT CLUSTER NUMBER TO LOGICAL BLOCK NUMBER
  1101. .%362!     SEC
  1102. .%363!     SBC #2
  1103. .%364!     BCS +
  1104. .%365!     DEY
  1105. .%366!  +  LDX CLUSTER┬LOCK├OUNT
  1106. .%367!     CPX #1
  1107. .%368!     BEQ +
  1108. .%369!     ASL
  1109. .%370!     STY 7
  1110. .%371!     ROL 7
  1111. .%372!     LDY 7
  1112. .%373!  +  CLC
  1113. .%374!     ADC FIRST╞ILE┬LOCK
  1114. .%375!     BCC +
  1115. .%376!     INY
  1116. .%377!
  1117. .%378!     ;** READ LOGICAL BLOCKS COMPRISING CLUSTER
  1118. .%379!  +  LDX #<CLUSTER┬UF
  1119. .%380!     STX 6
  1120. .%381!     LDX #>CLUSTER┬UF
  1121. .%382!     STX 7
  1122. .%383!     LDX CLUSTER┬LOCK├OUNT
  1123. .%384!     JMP COPY┬LOCKS
  1124. .%385!
  1125.  
  1126. ╘HIS NEXT LEVEL OF ROUTINES DEAL WITH THE DATA STRUCTURES OF THE ═╙-─╧╙ DISK
  1127. FORMAT.
  1128.  
  1129. .%386!  ;====═╙-─╧╙ FORMAT LEVEL====
  1130. .%387!
  1131. .%388!  BOOT┬LOCK = 2
  1132. .%389!
  1133.  
  1134. ╥EAD THE DISK FORMAT PARAMETERS, DIRECTORY, AND ╞┴╘ INTO MEMORY.
  1135.  
  1136. .%390!  LOAD─IRECTORY = *  ;( ) : .┴┘=DIRBUF, .╪=DIR┼NTRIES, .├╙=ERR
  1137. .%391!     LDA #$0E
  1138. .%392!     STA $FF00
  1139. .%393!
  1140.  
  1141. ╥EAD THE BOOT SECTOR AND EXTRACT THE PARAMETERS.
  1142.  
  1143. .%394!     ;** GET PARAMETERS FROM BOOT SECTOR
  1144. .%395!     LDA #0
  1145. .%396!     LDY #0
  1146. .%397!     JSR CONVERT╠OGICAL┬LOCK╬UM
  1147. .%398!     JSR READ┬LOCK
  1148. .%399!     BCC +
  1149. .%400!     RTS
  1150. .%401!  +  STA BOOT┬LOCK
  1151. .%402!     STY BOOT┬LOCK+1
  1152. .%403!     LDY #13              ;GET CLUSTER SIZE
  1153. .%404!     LDA (BOOT┬LOCK),Y
  1154. .%405!     STA CLUSTER┬LOCK├OUNT
  1155. .%406!     CMP #3
  1156. .%407!     BCC +
  1157. .%408!
  1158.  
  1159. ╔F A DISK PARAMETER IS FOUND TO EXCEED THE LIMITS OF ╠╥╥, ERROR CODE #60 IS
  1160. RETURNED.
  1161.  
  1162. .%409!     INVALID╨ARMS = *
  1163. .%410!     LDA #60
  1164. .%411!     STA ERRNO
  1165. .%412!     SEC
  1166. .%413!     RTS
  1167. .%414!
  1168. .%415!  +  LDY #16              ;CHECK ╞┴╘ REPLICATION COUNT, MUST BE 2
  1169. .%416!     LDA (BOOT┬LOCK),Y
  1170. .%417!     CMP #2
  1171. .%418!     BNE INVALID╨ARMS
  1172. .%419!     LDY #22              ;GET ╞┴╘ SIZE IN SECTORS
  1173. .%420!     LDA (BOOT┬LOCK),Y
  1174. .%421!     STA FAT┬LOCKS
  1175. .%422!     CMP #4
  1176. .%423!     BCS INVALID╨ARMS
  1177. .%424!     LDY #17              ;GET DIRECTORY SIZE
  1178. .%425!     LDA (BOOT┬LOCK),Y
  1179. .%426!     STA ROOT─IR┼NTRIES
  1180. .%427!     CMP #129
  1181. .%428!     BCS INVALID╨ARMS
  1182. .%429!     LSR
  1183. .%430!     LSR
  1184. .%431!     LSR
  1185. .%432!     LSR
  1186. .%433!     STA ROOT─IR┬LOCKS
  1187. .%434!     LDY #19              ;GET TOTAL SECTOR COUNT
  1188. .%435!     LDA (BOOT┬LOCK),Y
  1189. .%436!     STA TOTAL╙ECTORS
  1190. .%437!     INY
  1191. .%438!     LDA (BOOT┬LOCK),Y
  1192. .%439!     STA TOTAL╙ECTORS+1
  1193. .%440!     LDY #24              ;CHECK SECTORS PER TRACK, MUST BE 9
  1194. .%441!     LDA (BOOT┬LOCK),Y
  1195. .%442!     CMP #9
  1196. .%443!     BNE INVALID╨ARMS
  1197. .%444!     LDY #26
  1198. .%445!     LDA (BOOT┬LOCK),Y
  1199. .%446!     CMP #2               ;CHECK NUMBER OF SIDES, MUST BE 2
  1200. .%447!     BNE INVALID╨ARMS
  1201. .%448!     LDY #14              ;CHECK NUMBER OF BOOT SECTORS, MUST BE 1
  1202. .%449!     LDA (BOOT┬LOCK),Y
  1203. .%450!     CMP #1
  1204. .%451!     BNE INVALID╨ARMS
  1205. .%452!
  1206.  
  1207. ├ALCULATE THE DERIVED PARAMETERS.
  1208.  
  1209. .%453!     ;** GET DERIVED PARAMETERS
  1210. .%454!     LDA FAT┬LOCKS        ;FIRST ROOT DIRECTORY SECTOR
  1211. .%455!     ASL
  1212. .%456!     CLC
  1213. .%457!     ADC #1
  1214. .%458!     STA FIRST╥OOT─IR┬LOCK
  1215. .%459!     CLC                  ;FIRST FILE SECTOR
  1216. .%460!     ADC ROOT─IR┬LOCKS
  1217. .%461!     STA FIRST╞ILE┬LOCK
  1218. .%462!     LDA TOTAL╙ECTORS     ;NUMBER OF FILE CLUSTERS
  1219. .%463!     LDY TOTAL╙ECTORS+1
  1220. .%464!     SEC
  1221. .%465!     SBC FIRST╞ILE┬LOCK
  1222. .%466!     BCS +
  1223. .%467!     DEY
  1224. .%468!  +  STA FILE├LUSTER├OUNT
  1225. .%469!     STY FILE├LUSTER├OUNT+1
  1226. .%470!     LDA CLUSTER┬LOCK├OUNT
  1227. .%471!     CMP #2
  1228. .%472!     BNE +
  1229. .%473!     LSR FILE├LUSTER├OUNT+1
  1230. .%474!     ROR FILE├LUSTER├OUNT
  1231. .%475!
  1232.  
  1233. ╟EE, ╔ HAVE MORE COMMENTS EMBEDDED IN THE CODE THAN ╔ DID LAST ISSUE.
  1234.  
  1235. .%476!     ;** LOAD ╞┴╘
  1236. .%477!  +  LDA #<FATBUF
  1237. .%478!     LDY #>FATBUF
  1238. .%479!     STA 6
  1239. .%480!     STY 7
  1240. .%481!     LDA #1
  1241. .%482!     LDY #0
  1242. .%483!     LDX FAT┬LOCKS
  1243. .%484!     JSR COPY┬LOCKS
  1244. .%485!     BCC +
  1245. .%486!     RTS
  1246. .%487!
  1247. .%488!     ;** LOAD ACTUAL DIRECTORY
  1248. .%489!  +  LDA #<DIRBUF
  1249. .%490!     LDY #>DIRBUF
  1250. .%491!     STA 6
  1251. .%492!     STY 7
  1252. .%493!     LDA FIRST╥OOT─IR┬LOCK
  1253. .%494!     LDY #0
  1254. .%495!     LDX ROOT─IR┬LOCKS
  1255. .%496!     JSR COPY┬LOCKS
  1256. .%497!     BCC +
  1257. .%498!     RTS
  1258. .%499!  +  LDA #<DIRBUF
  1259. .%500!     LDY #>DIRBUF
  1260. .%501!     LDX ROOT─IR┼NTRIES
  1261. .%502!     CLC
  1262. .%503!     RTS
  1263. .%504!
  1264.  
  1265. ╘HIS ROUTINE LOCATES THE GIVEN ╞┴╘ TABLE ENTRY NUMBER AND RETURNS THE VALUE
  1266. STORED IN IT.  ╙OME WORK IS NEEDED TO DEAL WITH THE 12-BIT COMPRESSED DATA
  1267. STRUCTURE.
  1268.  
  1269. .%505!  ENTRY┴DDR = 2
  1270. .%506!  ENTRY╫ORK = 4
  1271. .%507!  ENTRY┬ITS = 5
  1272. .%508!  ENTRY─ATA0 = 6
  1273. .%509!  ENTRY─ATA1 = 7
  1274. .%510!  ENTRY─ATA2 = 8
  1275. .%511!
  1276. .%512!  GET╞AT┼NTRY = *  ;( .┴┘=FAT┼NTRY╬UMBER ) : .┴┘=FAT┼NTRY╓ALUE
  1277. .%513!     STA ENTRY┬ITS
  1278.  
  1279. ─IVIDE THE ╞┴╘ ENTRY NUMBER BY TWO AND MULTIPLY BY THREE BECAUSE TWO ╞┴╘
  1280. ENTRIES ARE STORED IN THREE BYTES.  ╘HEN ADD THE ╞┴╘ BASE ADDRESS AND WE HAVE
  1281. THE ADDRESS OF THE THREE BYTES THAT CONTAIN THE ╞┴╘ ENTRY WE ARE INTERESTED
  1282. IN.  ╔ RETRIEVE THE THREE BYTES INTO ZERO-PAGE MEMORY FOR EASY MANIPULATION.
  1283.  
  1284. .%514!     ;** DIVIDE BY TWO
  1285. .%515!     STY ENTRY┴DDR+1
  1286. .%516!     LSR ENTRY┴DDR+1
  1287. .%517!     ROR
  1288. .%518!
  1289. .%519!     ;** TIMES THREE
  1290. .%520!     STA ENTRY╫ORK
  1291. .%521!     LDX ENTRY┴DDR+1
  1292. .%522!     ASL
  1293. .%523!     ROL ENTRY┴DDR+1
  1294. .%524!     CLC
  1295. .%525!     ADC ENTRY╫ORK
  1296. .%526!     STA ENTRY┴DDR
  1297. .%527!     TXA
  1298. .%528!     ADC ENTRY┴DDR+1
  1299. .%529!     STA ENTRY┴DDR+1
  1300. .%530!
  1301. .%531!     ;** ADD BASE, GET DATA
  1302. .%532!     CLC
  1303. .%533!     LDA ENTRY┴DDR
  1304. .%534!     ADC #<FATBUF
  1305. .%535!     STA ENTRY┴DDR
  1306. .%536!     LDA ENTRY┴DDR+1
  1307. .%537!     ADC #>FATBUF
  1308. .%538!     STA ENTRY┴DDR+1
  1309. .%539!     LDY #2
  1310. .%540!  -  LDA (ENTRY┴DDR),Y
  1311. .%541!     STA ENTRY─ATA0,Y
  1312. .%542!     DEY
  1313. .%543!     BPL -
  1314. .%544!     LDA ENTRY┬ITS
  1315. .%545!     AND #1
  1316. .%546!     BNE +
  1317. .%547!
  1318.  
  1319. ╔F THE ORIGINAL GIVEN ╞┴╘ ENTRY NUMBER IS EVEN, THEN WE WANT THE FIRST 12-BIT
  1320. COMPRESSED FIELD.  ╘HE NYBBLES ARE EXTRACTED ACCORDING TO THE DIAGRAM SHOWN
  1321. EARLIER.
  1322.  
  1323. .%548!     ;** CASE 1: FIRST 12-BIT CLUSTER
  1324. .%549!     LDA ENTRY─ATA1
  1325. .%550!     AND #$0F
  1326. .%551!     TAY
  1327. .%552!     LDA ENTRY─ATA0
  1328. .%553!     RTS
  1329. .%554!
  1330.  
  1331. ╧THERWISE, WE WANT THE SECOND 12-BIT FIELD.
  1332.  
  1333. .%555!     ;** CASE 2: SECOND 12-BIT CLUSTER
  1334. .%556!  +  LDA ENTRY─ATA1
  1335. .%557!     LDX #4
  1336. .%558!  -  LSR ENTRY─ATA2
  1337. .%559!     ROR
  1338. .%560!     DEX
  1339. .%561!     BNE -
  1340. .%562!     LDY ENTRY─ATA2
  1341. .%563!     RTS
  1342. .%564!
  1343.  
  1344. ╞INALLY, THIS IS THE FILE COPYING LEVEL.  ╔T DEALS WITH READING THE CLUSTERS
  1345. OF ═╙-─╧╙ FILES AND COPYING THE DATA THEY CONTAIN TO THE ALREADY-OPEN ├┬═
  1346. ╦ERNAL FILE, POSSIBLY WITH ┴╙├╔╔-TO-╨┼╘╙├╔╔ TRANSLATION.
  1347.  
  1348. .%565!  ;====FILE COPY LEVEL====
  1349. .%566!
  1350. .%567!  TRANS═ODE = 14
  1351. .%568!  LFN = 15
  1352. .%569!  CBM─ATA╨TR = $60
  1353. .%570!  CBM─ATA╠EN = $62
  1354. .%571!  CLUSTER = $64
  1355. .%572!
  1356.  
  1357. ├OPY THE GIVEN CLUSTER TO THE ├┬═ OUTPUT FILE.  ╘HIS ROUTINE FETCHES THE NEXT
  1358. CLUSTER OF THE FILE FOR THE NEXT TIME THIS ROUTINE IS CALLED, AND IF IT HITS
  1359. THE ╬╒╠╠ POINTER OF THE LAST CLUSTER OF A FILE, IT ADJUSTS THE NUMBER OF VALID
  1360. FILE DATA BYTES THE CURRENT CLUSTER CONTAINS TO ╞ILE╠ENGTH % ├LUSTER╠ENGTH
  1361. (SEE NOTE BELOW).
  1362.  
  1363. .%573!  COPY╞ILE├LUSTER = *  ;( CLUSTER, LFN, TRANS═ODE ) : .├╙=ERR
  1364.  
  1365. ╥EAD THE CLUSTER AND SETUP TO COPY THE WHOLE CLUSTER TO THE ├┬═ FILE.
  1366.  
  1367. .%574!     LDA CLUSTER
  1368. .%575!     LDY CLUSTER+1
  1369. .%576!     JSR READ├LUSTER
  1370. .%577!     BCC +
  1371. .%578!     RTS
  1372. .%579!  +  LDA #<CLUSTER┬UF
  1373. .%580!     LDY #>CLUSTER┬UF
  1374. .%581!     STA CBM─ATA╨TR
  1375. .%582!     STY CBM─ATA╨TR+1
  1376. .%583!     LDA #0
  1377. .%584!     STA CBM─ATA╠EN
  1378. .%585!     LDA CLUSTER┬LOCK├OUNT
  1379. .%586!     ASL
  1380. .%587!     STA CBM─ATA╠EN+1
  1381. .%588!
  1382.  
  1383. ╞ETCH THE NEXT CLUSTER NUMBER OF THE FILE, AND ADJUST THE CLUSTER DATA LENGTH
  1384. FOR THE LAST CLUSTER OF THE FILE.
  1385.  
  1386. .%589!     ;**GET NEXT CLUSTER
  1387. .%590!     LDA CLUSTER
  1388. .%591!     LDY CLUSTER+1
  1389. .%592!     JSR GET╞AT┼NTRY
  1390. .%593!     STA CLUSTER
  1391. .%594!     STY CLUSTER+1
  1392. .%595!     CMP #$FF
  1393. .%596!     BNE COPY╞ILE├LUSTER─ATA
  1394. .%597!     CPY #$0F
  1395. .%598!     BNE COPY╞ILE├LUSTER─ATA
  1396. .%599!     LDA LEN═╠
  1397. .%600!     STA CBM─ATA╠EN
  1398. .%601!     LDA #$01
  1399. .%602!     LDX CLUSTER┬LOCK├OUNT
  1400. .%603!     CPX #1
  1401. .%604!     BEQ +
  1402. .%605!     LDA #$03
  1403. .%606!  +  AND LEN═╠+1
  1404.  
  1405. ╘HE FOLLOWING THREE LINES WERE ADDED IN A LAST MINUTE PANIC AFTER REALIZING
  1406. THAT IF ╞ILE╠ENGTH % ├LUSTER╙IZE == 0, THEN THE LAST CLUSTER OF THE FILE
  1407. CONTAINS ├LUSTER╙IZE BYTES, NOT ZERO BYTES.
  1408.  
  1409. .%000!     BNE +
  1410. .%000!     LDX LEN═╠
  1411. .%000!     BEQ COPY╞ILE├LUSTER─ATA
  1412. .%607!  +  STA CBM─ATA╠EN+1
  1413. .%608!
  1414. .%609!     COPY╞ILE├LUSTER─ATA = *
  1415. .%610!     JSR COMMIE╧UT
  1416. .%611!     RTS
  1417. .%612!
  1418.  
  1419. ├OPY THE FILE DATA IN THE ═╙-─╧╙ CLUSTER BUFFER TO THE ├┬═ OUTPUT FILE.
  1420.  
  1421. .%613!  CBM─ATA╠IMIT = $66
  1422. .%614!
  1423. .%615!  COMMIE╧UT = *  ;( CBM─ATA╨TR, CBM─ATA╠EN ) : .├╙=ERR
  1424.  
  1425. ╔F THE THE LOGICAL FILE NUMBER TO COPY TO IS 0 ("NULL DEVICE"), THEN DON'T
  1426. BOTHER COPYING ANYTHING.
  1427.  
  1428. .%616!     LDX LFN
  1429. .%617!     BNE +
  1430. .%618!     CLC
  1431. .%619!     RTS
  1432.  
  1433. ╧THERWISE, PREPARE THE LOGICAL FILE NUMBER FOR OUTPUT.
  1434.  
  1435. .%620!  +  JSR KERNEL├HKOUT
  1436. .%621!     BCC COMMIE╧UT═ORE
  1437. .%622!     STA ERRNO
  1438. .%623!     RTS
  1439. .%624!
  1440. .%625!     COMMIE╧UT═ORE = *
  1441.  
  1442. ╨ROCESS THE CLUSTER DATA IN CHUNKS OF UP TO 255 BYTES OR THE NUMBER OF DATA
  1443. BYTES REMAINING IN THE CLUSTER.
  1444.  
  1445. .%626!     LDA #255
  1446. .%627!     LDX CBM─ATA╠EN+1
  1447. .%628!     BNE +
  1448. .%629!     LDA CBM─ATA╠EN
  1449. .%630!  +  STA CBM─ATA╠IMIT
  1450. .%631!     LDY #0
  1451. .%632!  -  LDA (CBM─ATA╨TR),Y
  1452. .%633!     BIT TRANS═ODE
  1453. .%634!     BPL +
  1454.  
  1455. ╔F WE HAVE TO TRANSLATE THE CURRENT ┴╙├╔╔ CHARACTER, LOOK UP THE ╨┼╘╙├╔╔ VALUE
  1456. IN THE TRANSLATION TABLE AND OUTPUT THAT VALUE.  ╔F THE TRANSLATION TABLE
  1457. ENTRY VALUE IS $00, THEN DON'T OUTPUT A CHARACTER (FILTER OUT INVALID
  1458. CHARACTER CODES).
  1459.  
  1460. .%635!     TAX
  1461. .%636!     LDA TRANS┬UF,X
  1462. .%637!     BEQ COMMIE╬EXT
  1463. .%638!  +  JSR KERNEL├HROUT
  1464. .%639!     COMMIE╬EXT = *
  1465. .%640!     INY
  1466. .%641!     CPY CBM─ATA╠IMIT
  1467. .%642!     BNE -
  1468. .%643!
  1469.  
  1470. ╔NCREMENT THE CLUSTER BUFFER POINTER AND DECREMENT THE CLUSTER BUFFER CHARACTER
  1471. COUNT ACCORDING TO THE NUMBER OF BYTES JUST PROCESSED, AND REPEAT THE ABOVE IF
  1472. MORE FILE DATA REMAINS IN THE CURRENT CLUSTER.
  1473.  
  1474. .%644!     CLC
  1475. .%645!     LDA CBM─ATA╨TR
  1476. .%646!     ADC CBM─ATA╠IMIT
  1477. .%647!     STA CBM─ATA╨TR
  1478. .%648!     BCC +
  1479. .%649!     INC CBM─ATA╨TR+1
  1480. .%650!  +  SEC
  1481. .%651!     LDA CBM─ATA╠EN
  1482. .%652!     SBC CBM─ATA╠IMIT
  1483. .%653!     STA CBM─ATA╠EN
  1484. .%654!     BCS +
  1485. .%655!     DEC CBM─ATA╠EN+1
  1486. .%656!  +  LDA CBM─ATA╠EN
  1487. .%657!     ORA CBM─ATA╠EN+1
  1488. .%658!     BNE COMMIE╧UT═ORE
  1489.  
  1490. ╔F WE ARE FINISHED WITH THE CLUSTER, THEN CLEAR THE ├┬═ ╦ERNAL OUTPUT CHANNEL.
  1491.  
  1492. .%659!     JSR KERNEL├LRCHN
  1493. .%660!     CLC
  1494. .%661!     RTS
  1495. .%662!
  1496.  
  1497. ╘HE FILE COPYING MAIN ROUTINE.  ╙ET UP FOR THE STARTING CLUSTER, AND CALL
  1498. THE CLUSTER COPYING ROUTINE UNTIL END-OF-FILE IS REACHED.  ├HECKS FOR A
  1499. ╬╒╠╠ CLUSTER POINTER IN THE DIRECTORY ENTRY TO HANDLE ZERO-LENGTH FILES.
  1500.  
  1501. .%663!  COPY╞ILE = *  ;( START├LUSTER, LEN═╠, .┴=TRANS═ODE, .╪=LFN ) : .├╙=ERR
  1502. .%664!     LDY #$0E
  1503. .%665!     STY $FF00
  1504. .%666!     STA TRANS═ODE
  1505. .%667!     STX LFN
  1506. .%668!     LDA START├LUSTER
  1507. .%669!     LDY START├LUSTER+1
  1508. .%670!     STA CLUSTER
  1509. .%671!     STY CLUSTER+1
  1510. .%672!     JMP +
  1511. .%673!  -  JSR COPY╞ILE├LUSTER
  1512. .%674!     BCC +
  1513. .%675!     RTS
  1514. .%676!  +  LDA CLUSTER
  1515. .%677!     CMP #$FF
  1516. .%678!     BNE -
  1517. .%679!     LDA CLUSTER+1
  1518. .%680!     CMP #$0F
  1519. .%681!     BNE -
  1520. .%682!     CLC
  1521. .%683!     RTS
  1522. .%684!
  1523.  
  1524. ╘HIS IS THE TRANSLATION TABLE USED TO CONVERT FROM ┴╙├╔╔ TO ╨┼╘╙├╔╔.  ┘OU CAN
  1525. MODIFY IT TO SUIT YOUR NEEDS IF YOU WISH.  ╔F YOU CANNOT REASSEMBLE THIS FILE,
  1526. THEN YOU CAN SIFT THROUGH THE BINARY FILE AND LOCATE THE TABEL AND CHANGE IT
  1527. THERE.  ┴N ENTRY OF $00 MEANS THE CORRESPONDING ┴╙├╔╔ CHARACTER WILL NOT BE
  1528. TRANSLATED.  ┘OU'LL NOTICE THAT ╔ HAVE SET UP TRANSLATIONS FOR THE FOLLOWING
  1529. ┴╙├╔╔ CONTROL CHARACTERS INTO ╨┼╘╙├╔╔: ┬ACKSPACE, ╘AB, ╠INEFEED (├╥), AND
  1530. ╞ORMFEED.  ╔ ALSO TRANSLATE THE NON-╨┼╘╙├╔╔ CHARACTERS SUCH AS █, ▄, ▐, AND _
  1531. ACCORDING TO WHAT THEY PROBABLY WOULD HAVE BEEN IF ├OMMODORE WASN'T SO
  1532. CONCERNED WITH THE GRAPHICS CHARACTERS.
  1533.  
  1534. .%685!  TRANS┬UF = *
  1535. .%686!         ;0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  1536. .%687!  .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$14,$09,$0D,$00,$93,$00,$00,$00 ;0
  1537. .%688!  .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;1
  1538. .%689!  .BYTE $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F ;2
  1539. .%690!  .BYTE $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F ;3
  1540. .%691!  .BYTE $40,$C1,$C2,$C3,$C4,$C5,$C6,$C7,$C8,$C9,$CA,$CB,$CC,$CD,$CE,$CF ;4
  1541. .%692!  .BYTE $D0,$D1,$D2,$D3,$D4,$D5,$D6,$D7,$D8,$D9,$DA,$5B,$5C,$5D,$5E,$5F ;5
  1542. .%693!  .BYTE $C0,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4A,$4B,$4C,$4D,$4E,$4F ;6
  1543. .%694!  .BYTE $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5A,$DB,$DC,$DD,$DE,$DF ;7
  1544. .%695!  .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;8
  1545. .%696!  .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;9
  1546. .%697!  .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;A
  1547. .%698!  .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;B
  1548. .%699!  .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;C
  1549. .%700!  .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;D
  1550. .%701!  .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;E
  1551. .%702!  .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;F
  1552. .%703!
  1553.  
  1554. ╘HIS IS WHERE THE TRACK CACHE, ETC. ARE STORED.  ╘HIS SECTION REQUIRES 11╦ OF
  1555. STORAGE SPACE BUT DOES NOT INCREASE THE LENGTH OF THE BINARY PROGRAM FILE
  1556. SINCE THESE STORAGE AREAS ARE ─┼╞╔╬┼─ RATHER THAN ALLOCATED WITH ".BUF"
  1557. DIRECTIVES.  ╘HE ╒NIX TERMINOLOGY FOR THIS TYPE OF UNINITIALIZED DATA IS "BSS".
  1558.  
  1559. .%704!  ;====BSS STORAGE====
  1560. .%705!
  1561. .%706!  BSS = *
  1562. .%707!  TRACKBUF   = BSS
  1563. .%708!  CLUSTER┬UF = TRACKBUF+4608  
  1564. .%709!  FATBUF     = CLUSTER┬UF+1024
  1565. .%710!  DIRBUF     = FATBUF+1536    
  1566. .%711!  END        = DIRBUF+4096
  1567.  
  1568. 5. ╒╙┼╥-╔╬╘┼╥╞┴├┼ ╨╥╧╟╥┴═
  1569.  
  1570. ╘HIS SECTION PRESENTS THE LISTING OF THE USER-INTERFACE ┬┴╙╔├ PROGRAM.  ┘OU
  1571. SHOULD BE AWARE THAT YOU CAN EASILY CHANGE SOME OF THE DEFAULTS TO YOUR OWN
  1572. PREFERENCES IF YOU WISH.  ╘HIS PROGRAM IS NOT LISTED IN THE ".%NNN!" FORMAT
  1573. THAT THE ASSEMBLER LISTING IS SINCE YOU CAN RECOVER THIS LISTING FROM THE
  1574. UUENCODED BINARY PROGRAM FILE.  ╘HIS PROGRAM SHOULD BE A LITTLE EASIER TO
  1575. FOLLOW THAN THE ASSEMBLER LISTING SINCE ┬┴╙╔├ IS A SELF-COMMENTING LANGUAGE. :-)
  1576.  
  1577. 10 REM LITTLE RED READER, BY CRAIG BRUCE, 30-SEP-92, FOR C= HACKING NETMAG
  1578. 11 :
  1579.  
  1580. ╘HESE LINES SET UP THE DEFAULT ├┬═-─╧╙ AND ═╙-─╧╙ DEVICE NUMBERS, TAKING CARE
  1581. TO DISALLOW THEM TO BE THE SAME DEVICE.  ┘OU CAN CHANGE THIS TO YOUR OWN DRIVE
  1582. CONFIGURATION.
  1583.  
  1584. 20 CD=PEEK(186)  : REM ** DEFAULT CBM-DOS DRIVE **
  1585. 25 DV=9:DT=0  :  REM ** MS-DOS DRIVE, TYPE (0=1571,255=1581)
  1586. 26 IF DV=CD THEN DV=8:DT=0 : REM ** ALTERNATE MS-DOS DRIVE
  1587. 27 :
  1588. 30 PRINT CHR$(147);"INITIALIZING..." : PRINT
  1589. 40 BANK0 : PK=DEC("8000")
  1590. 50 IF PEEK(PK+9)=DEC("CB") AND PEEK(PK+10)=131 THEN 60
  1591. 55 PRINT"LOADING MACHINE LANGUAGE ROUTINES..." : BLOAD"LRR.BIN",U(CD)
  1592. 60 POKE PK+16,DV : POKE PK+17,DT : SYS PK
  1593.  
  1594. ╔ "DIM" THE FOLLOWING VARIABLES BEFORE THE ARRAYS TO AVOID THE OVERHEAD OF
  1595. PUSHING THE ARRAYS AROUND WHEN CREATING NEW SCALAR VARIABLES.
  1596.  
  1597. 70 DIM T,R,B,I,A$,C,DT$,FL$,IL$,X,X$
  1598. 80 DIM DI$(128),CL(128),SZ(128)
  1599. 90 IF DT=255 THEN DT$="1581" :ELSE DT$="1571"
  1600. 100 FL$=CHR$(19)+CHR$(17)+CHR$(17)+CHR$(17)+CHR$(17)
  1601. 110 IL$=FL$:FORI=1TO19:IL$=IL$+CHR$(17):NEXT
  1602. 120 GOTO 500
  1603. 130 :
  1604. 131 REM ** LOAD MS-DOS DIRECTORY **
  1605. 140 PRINT"LOADING DIRECTORY..." : PRINT
  1606. 150 SYS PK : SYS PK+3
  1607. 160 DL=0
  1608.  
  1609. ╘HE "RREG" INSTRUCTION RETURNS THE RETURN VALUES OF THE .┴, .╪, .┘, AND .╙
  1610. REGISTERS FROM THE LAST "SYS" CALL.  ╔ CHECK THE 1-BIT OF THE .╙ REGISTER
  1611. (THE ├ARRY FLAG) FOR ERROR RETURNS.
  1612.  
  1613. 170 RREG BL,DC,BH,S : E=PEEK(PK+15)
  1614. 180 IF (S AND 1) THEN GOSUB 380 : RETURN
  1615. 190 PRINT"SCANNING DIRECTORY..." : PRINT
  1616. 200 DB=BL+256*BH
  1617. 210 IF DC=0 THEN 360
  1618. 220 FOR DP=DB TO DB+32*(DC-1) STEP 32
  1619. 230 IF PEEK(DP)=0 OR PEEK(DP)=229 THEN 350
  1620. 240 IF PEEK(DP+12) AND 24 THEN 350
  1621. 250 DL=DL+1
  1622.  
  1623. ╘HIS NEXT LINE IS WHERE ╔ SET THE DEFAULT SELECTION STATUS, TRANSLATION TYPE,
  1624. AND ├┬═ FILE TYPE FOR THE ═╙-─╧╙ FILES.  ┘OU CAN CHANGE THESE DEFAULTS SIMPLY
  1625. BY OVERTYPING THE STRING IN   (  ▄  ▄▄▄  ▄▄▄  ) THE "╓" LOCATIONS.
  1626.                                  ╓  ╓╓╓  ╓╓╓
  1627. 260 D$=RIGHT$(" "+STR$(DL),3)+"     ASC  SEQ  " : REM ** DEFAULT SEL/TR/FT **
  1628. 270 A$="" : FORI=0TO10 : A$=A$+CHR$(PEEK(DP+I)) : NEXT
  1629. 280 A$=LEFT$(A$,8)+"  "+RIGHT$(A$,3)
  1630. 290 PRINT DL; A$
  1631. 300 D$=D$+A$+"  "
  1632. 310 CL(DL)=PEEK(DP+26)+256*PEEK(DP+27)
  1633. 320 SZ=PEEK(DP+28)+256*PEEK(DP+29)+65536*PEEK(DP+30)
  1634. 330 DI$(DL)=D$+RIGHT$("    "+STR$(SZ),6)
  1635. 340 SZ(DL)=SZ
  1636. 350 NEXT DP
  1637. 360 RETURN
  1638. 370 :
  1639. 371 REM ** REPORT MS-DOS DISK ERROR **
  1640. 380 PRINT CHR$(18);"MS-DOS DISK ERROR #";MID$(STR$(E),2);
  1641. 390 PRINT " ($";MID$(HEX$(E),3);"), PRESS KEY.";CHR$(146)
  1642. 400 GETKEY A$ : RETURN
  1643. 410 :
  1644. 411 REM ** SCREEN HEADING **
  1645. 420 PRINTCHR$(147);"MS-DEV=";MID$(STR$(DV),2);"    MS-TYPE=";DT$;
  1646. 430 PRINT"    CBM-DEV=";MID$(STR$(CD),2):PRINT
  1647. 440 RETURN
  1648. 450 :
  1649. 451 REM ** SCREEN FOOTING **
  1650. 460 PRINT IL$;"D=DIRECTORY  M=MS-DEV  F=CBM-DEV Q=QUIT"
  1651. 470 PRINT"T=TOGGLE-COLUMN, C=COPY-FILES, +/- PAGE";
  1652. 480 RETURN
  1653. 490 :
  1654. 491 REM ** MAIN ROUTINE **
  1655. 500 T=1 : C=0
  1656. 510 R=0
  1657. 520 GOSUB 420
  1658. 530 PRINT "NUM  S  TRN  TYP  FILENAME  EXT  LENGTH"
  1659. 540 PRINT "---  -  ---  ---  --------  ---  ------"
  1660. 550 GOSUB 460
  1661. 560 B=T+17 : IF B>DL THEN B=DL
  1662. 570 PRINT FL$;: IF T>DL THEN 590
  1663. 580 FOR I=T TO B : PRINT DI$(I) : NEXT
  1664. 590 IF DL=0 THEN PRINT CHR$(18);"<NO FILES>";CHR$(146)
  1665. 600 IF DL=0 THEN 660
  1666. 610 PRINT LEFT$(IL$,R+5);CHR$(18);
  1667. 620 ON C+1 GOTO 630,640,650
  1668. 630 PRINT SPC(4);MID$(DI$(T+R),5,3) : GOTO 660
  1669. 640 PRINT SPC(7);MID$(DI$(T+R),8,5) : GOTO 660
  1670. 650 PRINT SPC(12);MID$(DI$(T+R),13,5) : GOTO 660
  1671. 660 GETKEY A$
  1672.  
  1673. ╧H SHI^╚OOT.  ╔ SCREWED UP THE FOLLOWING LINE IN THE STRING AFTER THE
  1674. "+CHR$(13)+" PART.  ┘OU'LL NOTICE THAT ╔ HAVE AVOIDED PUTTING CURSOR CONTROL
  1675. CHARACTERS INTO THE STRINGS EVERYWHERE ELSE, BUT ╔ FORGOT TO DO THAT HERE.
  1676. ╘HE "█STUFF▌" SHOULD BE ├URSOR╒P, ├URSOR─OWN, ├URSOR╠EFT, ├URSOR╥IGHT,
  1677. ├URSOR╚OME, AND ├URSOR├╠╥ CONTROL CHARACTERS, RESPECTIVELY.  ╘HESE CHARACTERS
  1678. GIVE THE INDEX FOR THE "ON" STATEMENT BELOW.
  1679.  
  1680. 670 I=INSTR("DMFTC+-Q "+CHR$(13)+"█STUFF▌",A$)
  1681. 680 PRINT LEFT$(IL$,R+5);DI$(T+R)
  1682. 690 IF I=0 THEN 600
  1683. 700 ONIGOTO760,1050,1110,950,1150,1000,1020,730,860,860,770,790,810,830,850,500
  1684. 710 STOP
  1685. 720 :
  1686. 721 REM ** VARIOUS MENU OPTIONS **
  1687. 730 PRINT CHR$(147);"HAVE AN AWESOME DAY."
  1688. 740 END
  1689. 760 GOSUB 420 : GOSUB 140 : GOTO 500
  1690. 770 R=R-1 : IF R<0 THEN R=B-T
  1691. 780 GOTO 600
  1692. 790 R=R+1 : IF T+R>B THEN R=0
  1693. 800 GOTO 600
  1694. 810 C=C-1 : IF C<0 THEN C=2
  1695. 820 GOTO 600
  1696. 830 C=C+1 : IF C>2 THEN C=0
  1697. 840 GOTO 600
  1698. 850 R=0 : C=0 : GOTO 600
  1699. 860 IF DL=0 THEN 600
  1700. 870 X=T+R : ON C+1 GOSUB 890,910,930
  1701. 880 PRINT LEFT$(IL$,R+5);DI$(X) : GOTO 600
  1702. 890 IF MID$(DI$(X),6,1)=" " THEN X$="*" :ELSE X$=" "
  1703. 900 MID$(DI$(X),6,1)=X$ : RETURN
  1704. 910 IF MID$(DI$(X),9,1)="A" THEN X$="BIN" :ELSE X$="ASC"
  1705. 920 MID$(DI$(X),9,3)=X$ : RETURN
  1706. 930 IF MID$(DI$(X),14,1)="S" THEN X$="PRG" :ELSE X$="SEQ"
  1707. 940 MID$(DI$(X),14,3)=X$ : RETURN
  1708. 950 IF DL=0 THEN 600
  1709. 960 FOR X=1 TO DL
  1710. 970 ON C+1 GOSUB 890,910,930
  1711. 980 NEXT X
  1712. 990 GOTO 520
  1713. 1000 IF B=DL THEN T=1 : GOTO 510
  1714. 1010 T=T+18 : GOTO 510
  1715. 1020 IF T=1 THEN T=DL-(DL-INT(DL/18)*18)+1 : GOTO 510
  1716. 1030 T=T-18 : IF T<1 THEN T=1
  1717. 1040 GOTO 510
  1718. 1050 PRINT IL$;CHR$(27);"@";
  1719. 1060 INPUT"MS-DOS DEVICE NUMBER (8-30)";DV
  1720. 1061 IF CD=DV THEN PRINT"MS-DOS AND CBM-DOS DEVICES MUST BE DIFFERENT!":GOTO1060
  1721. 1070 INPUT"MS-DOS DEVICE TYPE  (71/81)";X
  1722. 1080 IF X=8 OR X=81 OR X=1581 THEN DT=255:DT$="1581" :ELSE DT=0:DT$="1571"
  1723. 1090 POKE PK+16,DV : POKE PK+17,DT : SYS PK
  1724. 1100 GOTO 520
  1725. 1110 PRINT IL$;CHR$(27);"@";
  1726. 1120 INPUT "CBM-DOS DEVICE NUMBER (0-30)";CD
  1727. 1130 IF CD=DV THEN PRINT"MS-DOS AND CBM-DOS DEVICES MUST BE DIFFERENT!":GOTO1120
  1728. 1140 GOTO 520
  1729. 1141 :
  1730. 1142 REM ** COPY FILES **
  1731. 1150 PRINT CHR$(147);"COPY FILES":PRINT:PRINT
  1732. 1160 IF DL=0 THEN FC=0 : GOTO 1190
  1733. 1170 FC=0 : FOR F=1 TO DL : IF MID$(DI$(F),6,1)="*" THEN GOSUB 1200
  1734. 1180 NEXT F
  1735. 1190 PRINT : PRINT"FILES COPIED =";FC;" - PRESS KEY"
  1736. 1191 GETKEY A$ : GOTO 520
  1737. 1200 FC=FC+1
  1738. 1210 X$=MID$(DI$(F),19,8)+"."+MID$(DI$(F),29,3)
  1739. 1220 CF$="":FORI=1TOLEN(X$):IF MID$(X$,I,1)<>" " THEN CF$=CF$+MID$(X$,I,1)
  1740. 1230 NEXT
  1741. 1231 IF RIGHT$(CF$,1)="." THEN CF$=LEFT$(CF$,LEN(CF$)-1)
  1742. 1232 CF$=CF$+","+MID$(DI$(F),14,1)
  1743. 1240 PRINT STR$(FC);". ";CHR$(34);CF$;CHR$(34);TAB(20);SZ(F)"BYTES";
  1744. 1245 PRINT TAB(35);MID$(DI$(F),9,3)
  1745. 1250 CL=CL(F) : LB=SZ(F) - INT(SZ(F)/65536)*65536
  1746.  
  1747. ╔ HAD TO USE A ─╧╨┼╬ STATEMENT HERE FOR DISK FILES BECAUSE THE REGULAR ╧╨┼╬
  1748. STATMENT DOES NOT REDIRECT THE ─╙ AND ─╙$ PSEUDO-VARIABLES.  ┘OU'LL NOTICE
  1749. THAT THE NON-DISK ╧╨┼╬ STATMENT BELOW HAS A SECONDARY ADDRESS OF 7.  ╘HIS IS
  1750. TO PUT THE PRINTER INTO LOWERCASE MODE IF YOU ARE OUTPUTTING DIRECTLY TO IT.
  1751. ┘OU CAN REPLACE THIS WITH A 5 (OR WHATEVER) IF YOU HAVE A SPECIAL INTERFACE
  1752. TO AN ╔┬═-COMPATIBLE PRINTER AND YOU WANT TO PRINT DIRECTLY IN ┴╙├╔╔.  ╔N THIS
  1753. CASE, YOU WOULD SELECT THE "┬╔╬" TRANSLATION MODE FOR THE FILE YOU ARE ROUTING
  1754. DIRECTLY TO THE PRINTER.
  1755.  
  1756. 1260 IF CD>=8 THEN DOPEN#1,(CF$+",W"),U(CD) :ELSE IF CD<>0 THEN OPEN 1,CD,7
  1757. 1265 IF CD<8 THEN 1288
  1758. 1270 IF DS<>63 THEN 1288
  1759. 1275 X$="Y" : PRINT "FILE EXISTS; OVERWRITE (Y/N)";
  1760. 1280 CLOSE 1 : INPUT X$ : IF X$="N" THEN FC=FC-1 : RETURN
  1761. 1285 SCRATCH(CF$),U(CD)
  1762. 1286 DOPEN#1,(CF$+",W"),U(CD)
  1763. 1288 IF CD<8 THEN 1320
  1764. 1300 IF DS<20 THEN 1320
  1765. 1310 PRINT CHR$(18)+"CBM DISK ERROR: "+DS$ : FC=FC-1 : CLOSE1 : RETURN
  1766. 1320 POKE PK+19,CL/256 : POKE PK+18,CL-PEEK(PK+19)*256
  1767. 1330 POKE PK+21,LB/256 : POKE PK+20,LB-PEEK(PK+21)*256
  1768. 1340 TR=0 : IF MID$(DI$(F),9,1)="A" THEN TR=255
  1769. 1346 X=1 : IF CD=0 THEN X=0
  1770. 1350 SYS PK+6,TR,X
  1771. 1355 RREG X,X,X,S : E=PEEK(PK+15)
  1772. 1356 IF (S AND 1) THEN GOSUB 380 : FC=FC-1
  1773. 1360 IF CD<>0 AND CD<8 THEN CLOSE1
  1774. 1370 IF CD>=8 THEN DCLOSE#1 : IF DS>=20 THEN 1310
  1775. 1380 RETURN
  1776.  
  1777. 6. ╒╒┼╬├╧─┼─ ╞╔╠┼╙
  1778.  
  1779. ╚ERE ARE THE BINARY EXECUTABLES IN UUENCODED FORM.  ╘HE ├╥├32S OF THE TWO
  1780. FILES ARE AS FOLLOWS:
  1781.  
  1782.    "LRR.128"    1106058594
  1783.    "LRR.BIN"     460671650
  1784.  
  1785. ╘HE "LRR.128" FILE IS THE MAIN ┬┴╙╔├ PROGRAM AND THE "LRR.BIN" FILE CONTAINS
  1786. THE MACHINE LANUGAGE DISK-ACCESSING ROUTINES.
  1787.  
  1788. [╠╥╥.128 AND ╠╥╥.┬╔╬ ARE INCLUDED IN THIS ARCHIVE. -╥╫]
  1789.  
  1790. 7. ┬╔┬╠╔╧╟╥┴╨╚┘
  1791.  
  1792. ╘HE FOLLOWING WORKS WERE CONSULTED IN CREATING THIS ARTICLE:
  1793.  
  1794. [1] ╩IM ┬UTTERFIELD, "╩IM ┬UTTERFIELD'S ├OMPLETE ├128 ═EMORY ═AP",
  1795.     _╘HE_╘RANSACTOR_, ╓OLUME 7, ╔SSUE 01, ╩ULY 1986 (┴ ═UST!).
  1796.  
  1797. [2] ├OMMODORE ┬USINESS ═ACHINES, _├OMMODORE_1571_─ISK_─RIVE_╒SER'S_╟UIDE_,
  1798.     ├┬═, 1985.
  1799.  
  1800. [3] ╙OME PROGRAM CALLED "MSDOS-TO-128" INCLUDED WITH "CS-DOS" BY
  1801.     ═. ╟-SOMETHING.  ╧RIGINALLY PUBLISHED IN ├╧═╨╒╘┼!'S ╟AZZETTE, ╔ THINK.
  1802.  
  1803. [4] ├OMMODORE ┬USINESS ═ACHINES, _├OMMODORE_128_╨ROGRAMMER'S_╥EFERENCE_╟UIDE_,
  1804.     ┬ANTAM ┬OOKS, 1986.
  1805.  
  1806. [5] _╘HE_╘RANSACTOR_, ╓OLUME 4, ╔SSUE 05 ("╘HE ╥EFERENCE ╔SSUE"), ═AY 1983.
  1807.  
  1808. =============================================================================
  1809.