home *** CD-ROM | disk | FTP | other *** search
/ 8bitfiles.net/archives / archives.tar / archives / genie-commodore-file-library / Information / HACKING5.LZH / hacking.5
Encoding:
Text File  |  1990-02-12  |  204.1 KB  |  6,093 lines

  1.  
  2.                    @@@@@@@@
  3.              @@@@@@@@@@@@@@@@@@
  4.          @@@@@@            @@@@@@
  5.       @@@@@
  6.     @@@@@  @@@@  @@@@      @@      @@@@@   @@@@  @@@@  @@@@  @@@@  @@@@   @@@@@
  7.   @@@@@    @@    @@      @@@@    @@   @@   @@  @@@     @@    @@@@  @@   @@   @@
  8.  @@@@@    @@@@@@@@     @@  @@   @@        @@@@@       @@    @@ @@ @@   @@
  9. @@@@@    @@    @@    @@@@@@@@  @@   @@   @@  @@@     @@    @@  @@@@   @@   @@
  10. @@@@@  @@@@  @@@@  @@@@  @@@@  @@@@@   @@@@  @@@@  @@@@  @@@@  @@@@   @@@@@@
  11. @@@@@                                                                     @@
  12.  @@@@@@            @@@@@@             ╔SSUE #5
  13.    @@@@@@@@@@@@@@@@@@              ═ARCH 7, 1993
  14.        @@@@@@@@
  15.  
  16. -----------------------------------------------------------------------------
  17. ┼DITOR'S ╬OTES:
  18. BY ├RAIG ╘AYLOR
  19.  
  20.   ╔T SEEMS THAT EACH ISSUE OF ├= ╚ACKING HAS ALWAYS BEGAN WITH A "╙ORRY, ╔T'S
  21.   LATE BUT HERE IT IS MESSAGE." - ╫ELL, THIS ONE WILL START OUT AGAIN LIKE 
  22.   THAT - ╘HIS ISSUE WAS ORIGINALLY SCHEDULED TO BE OUT THE MIDDLE OF ╩ANUARY
  23.   BUT DUE TO SEVERAL DELAYS IN OBTAINING ARTICLES AND MY DELAYING TRYING TO
  24.   DEBUG THE MULTI-TASKING SOURCE CODE IT'S BEEN HELD UP UNTIL NOW. 
  25.   
  26.   ═Y APOLOGIES TO THE AUTHORS WHO HAVE HAD THEIR ARTICLES INTO ME ON TIME -
  27.   SCHOOL IS COMING FIRST FOR ME AND HAVING TO DO A LOT OF CODING FOR SEVERAL
  28.   CLASSES WAS THE MAJOR CONTRIBUTING FACTOR TO THE DELAYS. 
  29.  
  30.   ╬OW, AFTER THE APOLOGIES ARE OUT OF THE WAY - ╠ET'S TAKE A LOOK AT WHAT HAS
  31.   HAPPENED SINCE LAST TIME ╔ WROTE.
  32.  
  33.   - ╥╒╬ MAGAZINE IS NO LONGER WITH US.
  34.  
  35.   ┴S ONE OF THE LAST HOLD-OUTS ╔ WAS EXPECTING ╥╒╬ MAGAZINE TO KEEP ON PRINTING
  36.   UNTIL THE ├OMMODORE 64/128'S REALLY DID DIE OUT BUT APPARENTLY THE PUBLISHERS
  37.   DECIDED IT WOULDN'T BE SO. ╘HIS LEAVES THE ╘WIN ├ITIES MAGAZINE AS THE ONLY
  38.   ╒╙ MAGAZINE IN PUBLICATION FOR THE ├OMMODORE (6502 BASED) COMPUTERS THAT ╔ AM
  39.   AWARE OF. ╙PEAKING OF ╘WIN ├ITIES (NOT SURE IF HE'S COMBINING THE 64/128 OR
  40.   JUST COMING OUT WITH SEPERATE ╘WIN ├ITIES MAGAZINES) DOES ANYBODY KNOW OR
  41.   HAVE ANY INFORMATION ON WHEN THE NEXT ISSUE WILL BE OUT? ╧R HAS MY 
  42.   LASTEST ISSUE JUST NOT BEEN SENT OUT?
  43.  
  44.   ┴S ╔ WAS WRITING THIS ╔ GOT THE LATEST ISSUE OF ╘WIN ├ITIES WHICH HAS
  45.   EXPANDED TO ├=64 COVERAGE ALSO. ╘HE NEW ISSUE LOOKS VERY NICE, ABOUT 53
  46.   PAGES OF SO OF GOOD DECENT MATERIAL. ╔'D RECOMMEND GET A SUBSCRIPTION FOR
  47.   THOSE OF YOU WHO ARE LOOKING TO STILL HEAR ABOUT NEW ├OMMODORE PRODUCTS.
  48.  
  49.   ╔'D LIKE TO GET PEOPLE'S REACTIONS ON THE DEMISE OF ╥╒╬ AND WHAT WILL
  50.   PEOPLE WILL THINK WILL PROBABLY BE THE MAIN SOURCE OF INFORMATION FOR ├=
  51.   OWNERS.  ┴ LOT OF PEOPLE READING THIS MAGAZINE ARE ON THE COMP.SYS.CBM
  52.   NEWSGROUP BUT ╔'M WONDERING ABOUT INDIVIDUALS WHO DO NOT HAVE ACCESS TO
  53.   SUCH A NEWSGROUP AND DO NOT HAVE ACCESS TO THE INTERNET. ╠ET ME KNOW WHAT
  54.   YOU THINK - HOPEFULLY THROUGH A FRIEND W/ ACCESS TO THE INTERNET. ╙ORT OF
  55.   A CATCH-22 ╔ GUESS.
  56.  
  57.   - ┴ ═AIL-╙ERVER HAS BEEN SETUP TO AUTOMATE SENDING ISSUE REQUESTS.
  58.  
  59.   ╘HE FULL DETAILS OF HOW TO USE THE ═AIL-╙ERVER IS IN A DOCUMENTATION FILE
  60.   CONTAINED WITHIN BUT THIS MAIL-SERVER (WHOSE SOURCE CODE IS AVAILABLE FOR
  61.   ANYONE WHO WISHES TO SEE IT WRITTEN IN ╓┴╪ ─├╠ CODE) ALSO ALLOWS FILE
  62.   REQUESTS WHICH WILL BE UUENCODED AND SENT TO YOU. ╔ AM TRYING TO HAVE ALL OF
  63.   THE PROGRAMS IN EACH ISSUE AVAILABLE VIA REQUEST AS FOR SOME PEOPLE IT IS
  64.   A MINOR PAIN TRYING TO EXTRACT AND COMPILE THE PROGRAMS CONTAINED WITHIN.
  65.  
  66.   - ╔ SAW A NOTE RECENTLY THAT THE SPEED-UP BOARD WORK WAS STILL BEING DONE.
  67.  
  68.   ─OES ANYBODY KNOW ANYTHING FURTHER ABOUT THIS? ╔'M INTERESTED IN THIS AND
  69.   HOW IT WOULD BE CARRIED OUT / DONE BUT ASIDE FROM AN OCCASIONAL POST HERE
  70.   AND THERE ABOUT IT ╔ ACTUALLY HEAR VERY LITTLE. 
  71.  
  72.   - ╘HERE IS ALSO WORK ON AN ┴NSI ├ COMPILER BEING DONE.
  73.  
  74.   ╥ECENTLY A GROUP OF PEOPLE (ABOUT 9 CURRENTLY) ARE WORKING ON A ├ COMPILER
  75.   FOR THE ├=64 AND ├=128 WHICH WILL EVENTUALLY SUPPORT THE FULL ┴╬╙╔ ├
  76.   LIBRARY. ┴ LARGE LIST OF EXTENSIONS HAVE BEEN PROPOSED AND THE COMPILER
  77.   WILL PROBABLY BE RELEASED AS EITHER SHAREWARE OR POSSIBLY, PUBLIC DOMAIN.
  78.  
  79.   ┴CK! - ╘HIS MAGAZINE KEEPS GROWING. ╘HE LAST ISSUE WAS APPROX.
  80.   SOMEWHERE AROUND 3000 LINES, THIS ONE IS JUST A TAD OVER 6000. ╔'M
  81.   SURE THAT WE'RE NOT SUFFERING THE QUALITY JUST BECAUSE OF THE
  82.   QUANTITY. :-) ┬E SURE TO TAKE A LOOK AT THE PREVIOUS BACK ISSUES
  83.   AVAILABLE VIA THE ═AIL-╙ERVER AND DON'T BE AFRAID TO SUGGEST COMMENTS
  84.   OR SUGGESTIONS. ╫HILE USUALLY THE AUTHORS ARE TOO BUSY TO TAKE IDEAS
  85.   FOR NEW PROGRAMS WE ALWAYS WELCOME TO HEAR HOW USEFUL YOU FIND CERTAIN
  86.   PROGRAMS INCLUDED HEREIN ETC.
  87.  
  88.   ┴LSO ╔ AM LOOKING FOR ARTICLES ON ANY TYPE OF SOFTWARE PROJECT, HARDWARE
  89.   PROJECT OR GENERAL THEORY ARTICLES THAT YOU WOULD LIKE TO SUBMIT. ╩UST
  90.   LEAVE ME A MESSAGE VIA EMAIL AT "DUCK@PEMBVAX1.PEMBROKE.EDU". ╬OTE ALSO
  91.   THAT ╔'VE JUST SIGNED UP FOR A ╟┼╬╔┼ ACCOUNT AND CAN BE REACHED THERE VIA
  92.   ├.╘┴┘╠╧╥37 ONCE MY ACCOUNT IS APPROVED.
  93.  
  94. =============================================================================
  95.  
  96.   ╨LEASE NOTE THAT THIS ISSUE AND PRIOR ONES ARE AVAILABLE VIA ANONYMOUS
  97.   ╞╘╨ FROM CCOSUN.CALTECH.EDU UNDER PUB/RKNOP/HACKING.MAG IN ADDITION TO THE
  98.   MAILSERVER WHICH IS DOCUMENTED IN THIS ISSUE.
  99.  
  100. =============================================================================
  101.   
  102.   ╬╧╘╔├┼: ╨ERMISSION IS GRANTED TO RE-DISTRIBUTE THIS "NET-MAGAZINE", IN 
  103.   WHOLE, FREELY FOR NON-PROFIT USE. ╚OWEVER, PLEASE CONTACT INDIVIDUAL
  104.   AUTHORS FOR PERMISSION TO PUBLISH OR RE-DISTRIBUTE ARTICLES SEPERATELY.
  105.   ┴ CHARGE OF NO GREATER THAN 5 ╒╙. ─OLLARS OR EQUIVLENT MAY BE CHARGED FOR
  106.   LIBRARY SERVICE / DISKETTE COSTS FOR THIS "NET-MAGAZINE." 
  107.  
  108. =============================================================================
  109. ╔N THIS ╔SSUE:
  110.  
  111. ═AIL-╙ERVER ─OCUMENTATION
  112.  
  113. ╘HIS ARTICLES DESCRIBES HOW TO ACCESS THE MAIL-SERVER FOR ├OMMODORE ╚ACKING
  114. AND INCLUDES A LIST OF CURRENTLY AVAILABLE FILES AND BACK-ISSUES.
  115.  
  116. ╙TRETCHING ╙PRITES
  117.  
  118. ╔T'S POSSIBLE TO EXPAND SPRITES TO MORE THAN TWICE THEIR ORIGINAL SIZE, BUT 
  119. THERE IS NO NEED TO EXPAND ALL OF THEM EQUALLY. ╘HIS ARTICLE EXAMINS HOW TO
  120. EXPAND THEM 2,3, OR MORE MULTIPLES OF THEIR ORIGINAL SIZE.
  121.  
  122. ╥OB ╚UBBARD'S ═USIC: ─ISASSEMBLED, ├OMMENTED AND ┼XPLAINED
  123.  
  124. ╘HIS ARTICLE WRITTEN BY ┴NTHONY ═C╙WEENEY, PRESENTS THE VALUABLE SOURCE TO
  125. ╥OB ╚UBBARD'S FIRST MUSIC ROUTINE. ╘HIS ROUTINE WAS USED IN ╥OB'S FIRST 20
  126. OR 30 MUSICS, INCLUDING SUCH CLASSICS AS ╘HING ON A ╙PRING (╟REMLIN ╟RAPHICS),
  127. ├OMMANDO (┼LITE), ╘HRUST (╞IREBIRD), ╔NTERNATIONAL ╦ARATE (╙YSTEM 3), AND
  128. ╨ROTEUS (ALSO KNOWN AS ╫ARHAWK, BY ╞IREBIRD). 
  129.  
  130. ┌╨═3 AND ┌├├╨ ┼NHANCEMENTS FOR ├╨/═ ╨LUS FROM ╙IMEON ├RAN
  131.  
  132. ┴LTHOUGH ALL THE ARTICLES TO DATE IN ├= ╚ACKING HAVE FOCUSED ON 6510/ 8502
  133. PROGRAMMING, THERE HAVE BEEN SOME INTERESTING DEVELOPMENTS ON THE ┌80 FRONT.
  134. ├128 ├╨/═ USERS SHOULD BE AWARE OF THE BENEFITS OF A NEW SET OF ENHANCEMENTS
  135. TO THE OPERATING SYSTEM THAT OFFERS INREASED SPEED AND FLEXIBILITY AS WELL
  136. AS NEW FEATURES. ╔F THAT ISN'T ENOUGH, THIS PACKAGE WILL ALSO RUN ┌├╨╥ 3.3
  137. UTILITIES AND APPLICATIONS THAT WON'T RUN UNDER STANDARD ├╨/═ ╨LUS.
  138.  
  139. ═ULTI-╘ASKING ON THE ├=128 - ╨ART 1
  140.  
  141. ╘HIS ARTICLE EXAMINES THE RUDIMENTS OF ═ULTI-╘ASKING AND ALSO DETAILS THE
  142. SYSTEM CALLS IN THE ═ULTI-╘ASKING PACKAGE TO BE RELEASED IN THE NEXT ISSUE
  143. OF ├= ╚ACKING.
  144.  
  145. ╠╔╘╘╠┼ ╥┼─ ╫╥╔╘┼╥: ═╙-─╧╙ FILE READER/WRITER FOR THE ├128 AND 1571/81.
  146.  
  147. ╘HIS ARTICLE IS AN EXTENSION ON ╠ITTLE ╥ED ╥EADER WHICH WAS PRESENTED IN THE
  148. LAST ISSUE AND ALLOWS FOR READING AND WRITING OF ═╙-─OS DISKETTES FROM AND TO
  149. 1571/81 DRIVES. 
  150.  
  151. =============================================================================
  152. ═AIL-╙ERVER ─OCUMENTATION
  153. BY ├RAIG ╘AYLOR (DUCK@PEMBVAX1.PEMBROKE.EDU)
  154.  
  155. ╫HAT IS A MAIL-SERVER?
  156.  
  157.    ┴ MAILSERVER IS AN AUTOMATED JOB THAT WILL SCAN MY MAIL FILE FOR MESSAGES
  158.    WITH A SUBJECT LINE OF "═┴╔╠╙┼╥╓" AND WILL THEN AUTOMATICALLY CARRY OUT
  159.    CERTAIN OPERATIONS WITHIN THE BODY OF THE MAIL MESSAGE. ╘HIS MAKES IT EASIER
  160.    ON ME AND YOU. ┼ASIER FOR ME SO THAT ╔ DON'T HAVE TO DEAL WITH 50+ MESSAGES
  161.    EACH MONTH ASKING FOR FILES TO BE SENT OUT AND ALSO INSURES THAT YOUR FILES
  162.    THAT YOU REQUESTED WILL BE SENT WITHIN 24 HOURS. ╔N ADDITION IT ALLOWS 
  163.    FILES TO BE MORE EASILY SENT AND ACCESSED IN CASE YOU ARE NOT ABLE TO 
  164.    EXTRACT THE SOURCE FILES FROM ├= ╚ACKING. 
  165.  
  166.    ╔F YOU HAVE ╞╘╨ ACCESS PLEASE SEE THE ┼DITOR'S ╬OTES AT THE START FOR
  167.    INFORMATION ON ╥. ╦NOP'S ╞╘╨ SITE AND HOW TO ACCESS IT AS YOU MAY FIND
  168.    USING THAT SOMEWHAT QUICKER TO USE.
  169.  
  170. ╚OW TO USE THE MAIL-SERVER / ╫HAT IT IS.
  171.  
  172.    ╘HIS MAIL-SERVER IS INTENDED TO HELP ME KEEP TRACK / MORE EASILY UPDATE MY
  173.    MAILING LIST OF INDIVIDUALS WHO WISH TO SUB-SCRIBE OR GET BACK-ISSUES OF
  174.    ├= ╚ACKING MAILED TO THEM. 
  175.  
  176.    ╘O USE IT SIMPLY SEND A MESSAGE TO "DUCK@PEMBVAX1.PEMBROKE.EDU" (ME) WITH A
  177.    SUBJECT LINE OF "═┴╔╠╙┼╥╓" AND THEN WITH ONE OF THE FOLLOWING COMMANDS IN THE
  178.    BODY OF THE MAIL MESSAGE:
  179.  
  180. ├URRENTLY THE FOLLOWING COMMANDS ARE SUPPORTED:
  181.  
  182.   HELP              - SENDS CURRENT DOCUMENTATION F FILE LIST
  183.   SEND ISS<NUMBER>. - SENDS ISSUE # (1-4 CURRENTLY). ╥EMEMBER THE PERIOD!!
  184.   SUBSCRIBE         - SUBSCRIBE TO THE MAILING LIST AUTOMATICALLY
  185.  *SUBSCRIBE CATALOG - SUBSCRIBES TO A LIST THAT WILL BE SENT OUT 
  186.                       EVERYTIME THE CATALOG CHANGES.
  187.   CATALOG           - SHOW LIST OF AVAILABLE SOURCE /UUENCODED BINARIES
  188.   PSEND NAME        - SEND UUENCODED BINARY.
  189.  
  190. ├OMMANDS NO LONGER SUPPORTED:
  191.  
  192.   STATUS            - RETURNS THE CURRENT COMMANDS (THIS LIST)
  193.                       (USE THE HELP FILE)
  194.  
  195. ╨LEASE NOTE THAT THE MAILSERVER IS ONLY RUN AT 2:00 ┴═ ┼╙╘.
  196.  
  197. ├ATALOG ╠IST - ╠AST UPDATE ╞EBRUARY 27, 1993.
  198.  
  199.   ISS1.                 - ├= ╚ACKING, ╔SSUE #1
  200.   ISS2.                 - ├= ╚ACKING, ╔SSUE #2
  201.   ISS3.                 - ├= ╚ACKING, ╔SSUE #3
  202.   ISS4.                 - ├= ╚ACKING, ╔SSUE #4
  203.   ISS5.                 - ├= ╚ACKING, ╔SSUE #5
  204.   CONTENTS.LIS          - ├ONTENT ╠ISTING OF ╔SSUES #1-4
  205.   MAILSERV.012493       - ╓┴╪/─├╠ ═AILSERVER .SHARE FILE
  206.  
  207.  *INVASION1.SFX         - ╙PACE ╔NVASION ╙OURCE (╙TARTING WITH ╔SSUE 4)
  208.  *BMOVER.SFX            - ╟EOS 128 ┬ANKING WITH ┬ANKS 2F3 (╔SSUE #2)
  209.  *VDC-BG.SFX            - ╒SE OF 64╦ ╓─├ ╥┴═ IN ╟EOS (╔SSUE #3)
  210.  *C64.ZIP               - ├64 ┼MULATOR FOR ╔┬═
  211.  *LRR.SFX               - ╠ITTLE ╥ED ╥EADER (FROM ├= ╚ACKING #4)
  212.  
  213.   -- ╘EMPORARY ╞ILES -> ╧R FILES THAT WILL BE DELETED AS NEEDED FOR SPACE
  214.  
  215.  *ZEDV075.SFX           - ┌ED-128 ╘EXT ┼DITOR 
  216.  *RAMDOSII.SFX          - ╥┼╒ ─OS FOR THE ├=128 ┴LLOWS > 512K ╥┼╒.
  217.  
  218.   ╬╧╘┼: ╞ILES MARKED WITH "*" SHOULD BE REQUESTED VIA ╨╙┼╬─ - THEY WILL BE
  219.         SENT TO YOU IN UUENCODED FORM. ╘HEY MAY _NOT_ BE REQUESTED VIA ╙┼╬─.
  220.  
  221. =============================================================================
  222. ╘HE ─EMO ├ORNER: ╙TRETCHING ╙PRITES
  223. BY ╨ASI '┴LBERT' ╧JALA (PO87553@CS.TUT.FI)
  224.         ╫RITTEN: 16-═AY-91  ╘RANSLATION/╥EVISION 01-╩UN-92, ─EC-92
  225.  
  226. (┴LL TIMINGS ARE IN ╨┴╠, PRINCIPLES WILL APPLY TO ╬╘╙├ TOO)
  227.  
  228. ┘OU MIGHT HAVE HEARD THAT IT IS POSSIBLE TO EXPAND SPRITES TO MORE THAN
  229. TWICE THEIR ORIGINAL SIZE. ╔MAGINE A SPRITE SCROLLER WITH 6-TIMES EXPANDED
  230. SPRITES. ╚OWEVER, THERE IS NO NEED TO EXPAND ALL OF THEM EQUALLY. ╒SING
  231. THIS TECHNIQUE, IT IS POSSIBLE TO MAKE EASY SINUS EFFECTS AND CONSTANTLY
  232. EXPANDING AND SHRINKING LETTERS.
  233.  
  234. ╘HE ╓╔├ (VIDEO INTERFACE CONTROLLER) MAY BE FOOLED IN MANY THINGS. ╧NE OF
  235. THEM IS THE VERTICAL EXPANSION OF SPRITES. ╔F YOU CLEAR THE EXPAND FLAG AND
  236. THEN SET IT BACK STRAIGHT AWAY, ╓╔├ WILL THINK IT HAS ONLY DISPLAYED THE
  237. FIRST ONE OF THE EXPANDED LINES. ╔F WE DO THE TRICK AGAIN, ╓╔├ WILL CONTINUE
  238. TO DISPLAY THE SAME DATA AGAIN AND AGAIN. ┬UT WHY DOES ╓╔├ BEHAVE LIKE THIS ?
  239.  
  240.  
  241. _╠OGIC GATES WILL TELL THE TRUTH_
  242.  
  243. ╔T IS NOT REALLY A BUG, BUT A FEATURE. ╘HE HARDWARE DESIGN TO IMPLEMENT THE
  244. VERTICAL ENLARGEMENT WAS JUST AS SIMPLE AS POSSIBLE. ╘HOSE, WHO DO NOT CARE
  245. ABOUT HARDWARE SHOULD SKIP THIS PART... ╘HE WHOLE Y-ENLARGEMENT IS HANDLED
  246. WITH FIVE SIMPLE LOGICAL PORTS. ┼ACH SPRITE HAS AN ASSOCIATED ╙ET-╥ESET
  247. FLIP-FLOP TO TELL WHETHER TO JUMP TO THE NEXT SPRITE LINE (ADD THREE BYTES
  248. TO THE DATA COUNTER) OR NOT.
  249.  
  250. ╠ET'S CALL THE STATE OF THE FLIP-FLOP ╤ AND THE INPUTS ╥ (RESET) AND ╙ (SET).
  251. ╘HE FUNCTION OF A ╙╥ FLIP-FLOP IS QUITE SIMPLE: IF ╥ IS ONE, ╤ GOES TO ZERO,
  252. IF ╙ IS ONE, ╤ GOES TO ONE. ╧THERWISE THE STATE OF THE FLIP-FLOP DOES NOT
  253. CHANGE. ╔N THIS CASE THE FLIP-FLOP IS ╙ET, IF EITHER THE ┘-ENLARGEMENT BIT
  254. IS ZERO OR THE STATE OF THE FLIP-FLOP IS ZERO AT THE END OF A SCAN LINE. ╘HE
  255. FLIP-FLOP IS RESET, IF BOTH THE STATE AND THE ┘-ENLARGEMENT ARE ONES AT THE
  256. END OF THE LINE.
  257.  
  258. ╫HEN YOU CLEAR THE BIT IN THE VERTICAL EXPANSION REGISTER, THE FLIP-FLOP WILL
  259. BE SET REGARDLESS OF THE ELECTRON BEAM POSITION ON THE SCAN LINE. ╔F YOU
  260. SET THE BIT AGAIN BEFORE THE END OF THE LINE, THE FLIP-FLOP WILL BE CLEARED
  261. AND ╓╔├ WILL BE DISPLAYING THE SAME SPRITE LINE AGAIN. ╔N OTHER WORDS, ╓╔├
  262. WILL THINK THAT IT IS STARTING TO DISPLAY THE SECOND LINE OF THE EXPANDED
  263. SPRITE ROW. ╘HIS WAY ANY OF THE LINES IN ANY OF THE SPRITES MAY BE STRETCHED
  264. AS WANTED.
  265.  
  266.  .---- ├URRENT FLIPFLOP STATE (IF ONE, ENABLES ADD TO SPRITE POINTER)
  267.  |  .---- ┘-EXPANSION BIT.
  268.  |  |  .--- ┼ND OF LINE PULSE (BRIEFLY ONE AT END OF LINE)
  269.  |  |  |  .--- ╬EXT STATE (╫HAT STATE WILL BECOME UNDER THESE CONDITIONS)
  270.  |  |  |  |
  271.  0  0  0  1
  272.  0  0  1  1
  273.  0  1  0  NO CHANGE
  274.  0  1  1  1
  275.  1  0  0  1             ├LEAR $─017 -> FLIP-FLOP IS SET
  276.  1  0  1  1
  277.  1  1  0  NO CHANGE     ╙ET $─017   -> FLIP-FLOP RESETS AT THE END OF LINE
  278.  1  1  1  0
  279.  
  280. ╙O, SIMPLY, AT ANY TIME, IF VERTICAL EXPAND IS ZERO, THE ADD ENABLE IS SET
  281. TO ONE. ┴T THE END OF THE LINE - BEFORE ADDING - THE STATE IS CLEARED IF
  282. VERTICAL EXPAND IS ONE.
  283.  
  284.  
  285. _┼VEN ODDER ?_
  286.  
  287. ╙OMETHING VERY WEIRD HAPPENS WHEN WE CLEAR THE EXPANSION BIT RIGHT WHEN ╓╔├
  288. IS ADDING THREE TO THE SPRITE IMAGE COUNTERS. ╘HE VALUES IN THE COUNTERS WILL
  289. BE INCREASED ONLY BY TWO, AND THE DATA IS THEN READ FROM THE WRONG PLACE.
  290.  
  291. ╬ORMALLY THE DISPLAY OF A SPRITE ENDS WHEN ╓╔├ HAS SHOWN ALL OF THE 21
  292. LINES OF THE SPRITE (THE COUNTER WILL END UP TO $3F). ╔F THERE HAS BEEN A
  293. COUNTER MIXUP, $3F IS NOT REACHED AFTER 21 LINES AND ╓╔├ WILL GO ON COUNTING
  294. AND WILL DISPLAY THE SPRITE AGAIN, NOW NORMALLY. ╔F WE FOOL THE COUNTER ONLY
  295. ONCE, THE COUNTER VALUE $3F IS REACHED WHEN THE SPRITE IS DISPLAYED TWICE.
  296.  
  297.  
  298. _╞IDDLING_
  299.  
  300. ╔ DON'T THINK THE DISTORTED COUNTER EFFECT CAN BE USED FOR ANYTHING, BUT
  301. THERE IS MANY THINGS WHERE THE VARIABLE STRETCHING COULD BE USED. ╫HEN YOU
  302. OPEN THE BORDERS, YOU CAN BE SURE THAT THERE IS A CONSTANT AMOUNT OF TIME,
  303. IF YOU STRETCH THE SPRITES TO THE WHOLE LENGHT OF THE AREA. ┘OU MAY STRETCH
  304. ONLY THE FIRST AND LAST LINES, STRETCH THE OTHER LINES BY A CONSTANT OR
  305. USING A TABLE, OR USING A VARIABLE TABLE OR ANY OF THE COMBINATIONS POSSIBLE.
  306.  
  307.  
  308. _┴ RASTER ROUTINE IS A MUST_
  309.  
  310. ┬ECAUSE YOU HAVE TO ACCESS THE ╓╔├ REGISTERS ON EACH LINE DURING THE STRETCH,
  311. YOU NEED SOME KIND OF ROUTINE WHICH CAN DO OTHER KINDS OF TRICKS BESIDES THE
  312. STRETCH. ┘OU CAN OPEN THE SIDE BORDERS AND CHANGE THE BACKGROUND COLOR AND
  313. MAYBE YOU HAVE TO SHIFT THE SCREEN (AND THE BAD LINES WITH IT) DOWNWARDS.
  314. [╙EE PREVIOUS ├=╚ACKING ╔SSUES FOR TALK ABOUT RASTER INTERRUPTS.]
  315.  
  316. ╠OOK AT THE DEMO PROGRAM. ╔N THE BEGINNING OF THE RASTER ROUTINE THERE IS
  317. FIRST SOME TIMING, THEN A LOOP THAT LASTS EXACTLY 46 CLOCK CYCLES. ╔T TAKES
  318. EXACTLY ONE SCAN LINE TO EXECUTE. ╔NSIDE THE LOOP WE FIRST DO THE NECASSARY
  319. MODIFICATIONS TO THE VERTICAL SCROLL REGISTER, THEN WE CHANGE THE BACKGROUND
  320. COLOR AND THEN WE OPEN THE SIDE BORDERS. ┴ND FINALLY WE HANDLE THE STRETCHING
  321. USING THE STRETCH DATA, WHERE A ZERO-BIT MEANS THAT THE CORRESPONDING SPRITE
  322. WILL BE STRETCHED. ┴ ONE-BIT MEANS THAT ╓╔├ IS ALLOWED TO GO TO THE NEXT LINE
  323. OF THE SPRITE DATA.
  324.  
  325.  
  326. _╙TRETCHING TAKES TIME_
  327.  
  328. ┬ESIDES SHOWING THE STRETCHED SPRITES WE NEED TIME TO GENERATE THE STRETCHING
  329. DATA, UNLESS OF COURSE, THE STRETCH IS CONSTANT. ╫E HAVE TO HAVE 20
  330. ONE-BITS FOR EACH SPRITE IN OUR TABLE. ╔T IS NOT FEASIBLE TO DETERMINE THE
  331. STATE OF EACH BYTE IN THE TABLE, INSTEAD YOU CLEAR THE TABLE AND PLOT THE
  332. NEEDED BITS.
  333.  
  334. ╘HE ROUTINE IS QUITE STRAIGHTFORWARD, BUT MANY OPTIMIZATIONS MAY BE APPLIED
  335. TO MAKE IT FASTER. ╞IRST WE LOAD ┘ WITH THE STRETCH OF THE FIRST LINE (THE
  336. Y-COORDINATE OF THE DATA). ╘HEN WE USE IT AS AN INDEX TO THE TABLE AND PLOT
  337. THE RIGHT BIT AND INCREASE ┘ WITH THE EXPANSION VALUE. ╘HEN WE DO IT AGAIN
  338. UNTIL WE HAVE ALL OF THE 20 BITS SCATTERED TO THE TABLE. ╘HE LAST SPRITE LINE
  339. WILL THEN STRETCH UNTIL WE STOP THE STRETCHING, BECAUSE THE LAST LINE IS
  340. NOT ALLOWED TO BE DRAWN.
  341.  
  342.  
  343. _╙PEED IS EVERYTHING_
  344.  
  345. ╘HE CALCULATION ITSELF IS EASY, BUT OPTIMIZING THE ROUTINE IS NOT. ╔F ALL
  346. OF THE SPRITES ARE STRETCHED EQUALLY (BY INTEGER AMOUNTS) AND FROM THE SAME
  347. POSITION, THE ROUTINE IS THE FASTEST POSSIBLE.  ┘OU CAN ALSO HAVE VARIABLE
  348. AND SMOOTH STRETCH.  ╙MOOTH STRETCH USES OTHER THAN INTEGER EXPANSION VALUES
  349. AND THUS ALSO NEEDS MORE PROCESSOR TIME.  ╔F EACH SPRITE HAS TO BE STRETCHED
  350. INDIVIDUALLY, YOU NEED MUCH MORE TIME TO DO IT.
  351.  
  352. ╘HE FASTEST ROUTINE ╔ HAVE EVER WRITTEN USES SOME SERIOUS SELFMODIFICATION
  353. TRICKS. ╘HERE ARE ALSO SOME OTHER TRICKS TO SPEED UP THE STRETCH, BUT THEY
  354. ARE ALL SECRET ONES.. :-)  ╫ELL, WHAT THE H*CK, ╔ WILL INCLUDE IT ANYWAY.
  355. ┬Y THE TIME YOU READ THIS ╔ HAVE ALREADY MADE A FASTER ROUTINE..
  356.  
  357. ┘OU CAN SPEED UP THAT ROUTINE (BY 17%) BY UNROLLING THE INNER LOOP, BUT YOU
  358. HAVE TO USE A DIFFERENT ADDRESSING MODE FOR ╧╥┴ (ZERO-PAGE). ┘OU ALSO NEED
  359. TO PLACE SOME RESTRICTIONS TO THE TABLES USED.. ╔F YOU UNROLL BOTH LOOPS,
  360. YOU CAN GET ~25% FASTER ROUTINE THAN THE ╞ORE!-VERSION.
  361.  
  362.  
  363. _─EMO PROGRAM_
  364.  
  365. ╔ TRIED TO COLLECT ALL OF THE MAIN PRINCIPLES OF STRETCHING AND RASTER
  366. ROUTINES TO THE DEMO PROGRAM. ╔ USE THE TERM "RASTER ROUTINE" WHEN THE
  367. EXECUTION IS TIGHTLY SYNCHRONIZED TO THE ELECTRON BEAM AND TO THE SCREEN
  368. DISPLAY. ╘HE PROGRAM MAY BE UNCLEAR IN PLACES, BUT ╔ WANTED TO KEEP IT AS
  369. SHORT AS POSSIBLE. ╘HE ROUTINE OPENS THE SIDE BORDERS, SCROLLS THE SCREEN
  370. VERTICALLY, CHANGES THE BACKGROUND COLOR AND STRETCHES THE SPRITES.
  371.  
  372. ╘HE STRETCHER ROUTINE ALLOWS DIFFERENT Y-POSITION AND AMOUNT OF EXPANSION
  373. FOR EACH SPRITE. ╘HIS ROUTINE USES 1/8 FRACTIONS TO DO THE COUNTING, AND SO
  374. IT IS MUCH TOO SLOW TO USE IN A REAL DEMO.  ╓╔├ REGISTERS ARE INITIALIZED
  375. FROM A TABLE, INSTEAD OF SETTING THEM SEPARATELY. ╔NTERRUPT POSITION IS ONE
  376. LINE ABOVE THE SPRITES. ╘HE PROGRAM DOES NOT OPEN THE TOP OR BOTTOM BORDERS.
  377. (╔ USUALLY USE A ╬═╔ TO OPEN THE VERTICAL BORDERS, SO THAT ╔ ONLY NEED TO
  378.  USE ONE RASTER-╔╥╤ POSITION.)
  379.  
  380. ╔ TRIED TO MAKE A ╬╘╙├ VERSION, BUT ╔ COULDN'T GET IT TO SYNCHRONIZE.
  381. ╘HERE ARE ALSO LESS CYCLES AVAILABLE SO YOU CAN'T STRETCH ALL OF THE SPRITES
  382. INDIVIDUALLY IN ╬╘╙├ (WITH THIS ROUTINE THAT IS..).
  383.  
  384. --------------------------------------------------------------------------
  385. ╞AST-STRETCH FROM ═EGADEMO92 (PART: ╞ORE!)
  386.  
  387. ╙╔╬╨╧╙          ╙TRETCH SINUS INDEX
  388. ╙╔╬╙╨┼┼─        ╙TRETCH SINUS INDEX SPEED
  389. ┘╙╔╬╨╧╙         ┘-SINUS INDEX
  390. ┘╙╔╬╙╨┼┼─       ┘-SINUS INDEX SPEED
  391. ═┴╙╦            ┬IT MASK FOR PASSESS (USUALLY $01,$02,$04,$08,$10..)
  392.  
  393. ┘╙╔╬╒╙          ┘-SINUS TABLE
  394. ╙╘╥┼╘├╚         ╙PRITE LINE SIZES   (╠╙┬ OF THE ADDRESS MUST BE 0)
  395. ╙╔┌┼╘           ╙PRITE SIZE/2 TABLE (╠╙┬ OF THE ADDRESS MUST BE 0)
  396. ─┴╘┴            ╙TRETCH DATA TABLE (CLEARED BEFORE THIS ROUTINE)
  397.  
  398. [XX] MARKS SELFMODIFICATION. ╞OR EXAMPLE LOOP COUNTER, BIT MASK AND
  399. INDEX TO THE STRETCH AND SIZE DATA TABLES ARE STORED STRAIGHT IN THE
  400. CODE.
  401.  
  402. 0B90    LDA #$06        ; ╬UMBER OF SPRITES-1 (HERE ╔ USED ONLY 7 SPRITES)
  403. 0B92    STA $0B96
  404. 0B95    LDX #$[FF]      ; ╠OAD COUNTER
  405. 0B97    CLC             ; ├LEAR CARRY FOR ADC
  406. 0B98    LDA ╙╔╬╨╧╙,X    ; ╙TRETCH SINUS POSITION
  407. 0B9B    STA $0BD1       ; ╙ET LOW BYTES OF INDICES
  408. 0B9E    STA $0BB8
  409. 0BA1    ADC ╙╔╬╙╨┼┼─,X  ; ┴DD STRETCH SINUS SPEED (CARRY IS NOT SET)
  410. 0BA4    AND #$7F        ; ╘ABLE IS 128 BYTES (TWICE)
  411. 0BA6    STA ╙╔╬╨╧╙,X    ; ╙AVE NEW SINUS POSITION
  412. 0BA9    LDA ┘╙╔╬╨╧╙,X   ; ╟ET THE ┘ SINUS POSITION
  413. 0BAC    ADC ┘╙╔╬╙╨┼┼─,X ; ┴DD ┘ SINUS SPEED
  414. 0BAF    STA ┘╙╔╬╨╧╙,X   ; ╙AVE NEW ┘ SINUS POSITION
  415. 0BB2    TAY             ; ╨OSITION TO INDEX REGISTER
  416. 0BB3    LDA ┘╙╔╬╒╙,Y    ; ╟ET ┘-POSITION FROM TABLE (CAN BE 256 BYTES LONG)
  417. 0BB6    SEC             ; ADC EITHER SETS OR CLEARS CARRY, WE HAVE TO SET IT
  418. 0BB7    SBC ╙╔┌┼╘[1E]   ; ╙UBTRACT SIZE OF THE SPRITE/2 TO GET THE SPRITE
  419. 0BBA    CLC             ;  TO STRETCH FROM THE MIDDLE.
  420. 0BBB    TAY             ; ═AX╙IZE/2 < ┘-SINUS < ┴REA╚EIGHT-═AX╙IZE/2
  421. 0BBC    LDA ═┴╙╦,X      ; ╟ET THE ORA-MASK FOR THIS PASS
  422. 0BBF    STA $0BCB       ; ╙TORE MASK
  423. 0BC2    STA $0BDB
  424. 0BC5    LDX #$13        ; 19 LINES HERE + 1 AFTER
  425. 0BC7    LDA ─┴╘┴,Y      ; ╠OAD & ORA-MASK & STORE
  426. 0BCA    ORA #[$01]
  427. 0BCC    STA ─┴╘┴,Y
  428. 0BCF    TYA
  429. 0BD0    ADC ╙╘╥┼╘├╚[1E],X ; ┴DD THE STRETCH FROM THE TABLE (CARRY IS NOT SET)
  430. 0BD3    TAY
  431. 0BD4    DEX             ; DECREASE COUNTER
  432. 0BD5    BNE $0BC7       ; ─O THE 19 LINES
  433. 0BD7    LDA ─┴╘┴,Y      ; ╠OAD & ORA-MASK & STORE THE 20TH LINE
  434. 0BDA    ORA #[$01]
  435. 0BDC    STA ─┴╘┴,Y
  436. 0BDF    DEC $0B96       ; ╬EXT SPRITE(S)
  437. 0BE2    BPL $0B95
  438. 0BE4    RTS
  439.  
  440. ╘IMINGS:
  441. -------
  442. CLEAR 128 BYTES: 514  + 12 CYCLES       8.16 LINES
  443. 7 PASSES       : 3820 + 12 CYCLES       60.6 LINES = 8.66 LINES/PASS
  444.  
  445. ╘HE UNROLLED CLEAR ROUTINE CONSISTS OF ONE LOAD (LDA #$00) AND 128
  446. STORE INSTRUCTIONS (STA $NNNN). 12 CYCLES ARE COUNTED FOR ╩╙╥/╥╘╙.
  447.  
  448. ╙TRETCHING OF 8 SPRITES WOULD TAKE SLIGHTLY LESS THAN 80 LINES, WHICH IS ONE
  449. FOURTH OF THE TOTAL RASTER TIME. ─ISPLAYING A 128-LINE HIGH STRETCHER TAKES
  450. ABOUT 130 LINES (COUNTING SPRITE SETUP AND SYNCHRONIZATION), SCROLLER COUPLE
  451. OF LINES MORE. ╘OTAL 212 LINES LEAVES 100 LINES (6300 CYCLES) FREE FOR OTHER
  452. ACTIVITIES IN A ╨┴╠ SYSTEM. ╔N A ╬╘╙├ SYSTEM YOU WOULD HAVE ONLY 50 LINES
  453. LEFT.
  454.  
  455.  
  456. ┴ SIMPLE BASIC ROUTINE TO CREATE THE STRETCH DATA:
  457. -------------------------------------------------
  458. A=0:FOR F=0 TO 127:A=A+╚EIGHT*(2+SIN(F*╨╔/64)):POKE ╘ABLE+F,A:
  459. POKE ╘ABLE+F+128,A:A=A-INT(A):NEXT F
  460.  
  461. ╘HIS WILL ALSO HANDLE THE 'ROUNDING'. ┬ECAUSE OF THIS WE DON'T HAVE TO
  462. HANDLE FRACTIONS IN THE STRETCHER ROUTINE. ╘HE USE OF A TABLE ALSO GIVES THE
  463. OPPORTUNITY TO HAVE A SEPARATE SIZE FOR EACH SPRITE LINE. ╘HE TABLE DOES
  464. NOT NEED TO BE A SINUS, IT COULD HAVE TRIANGLE OR ANY OTHER 'WAVEFORM' AS
  465. LONG AS THE MINIMUM VALUE IN THE TABLE (SPRITE LINE SIZE) IS 1.
  466.  
  467.  
  468. ┴ BASIC ROUTINE TO DO THE SIZE/2 TABLE:
  469. --------------------------------------
  470. A=0:FOR F=0 TO 19:A=A+PEEK(╘ABLE+F):NEXT F: REM GET THE SIZE IN POSITION 0
  471. FOR F=0 TO 127:POKE ╙╘ABLE+F,A/2:A=A-PEEK(╘ABLE+F)+PEEK(╘ABLE+F+20):NEXT F
  472.  
  473. --------------------------------------------------------------------------
  474. _╙TRETCHER PROGRAM_
  475.  
  476. ┘╙├╥╧╠╠= $├╞00 ; ╓ERTICAL SCROLL TABLE (MOVES BAD LINES)
  477. ╙╘╥┼╘├╚= $├╞80 ; ╙TRETCH TABLE
  478. ├╧╠╧╥╙=  $├┼80 ; ╘ABLE FOR BACKGROUND COLORS
  479. ┘├╧╧╥─=  $0380 ; ╙PRITE Y-POSITIONS (EIGHT BYTES)
  480. ╚┼╔╟╚╘=  $0388 ; ╙PRITE STRETCHES   (EIGHT BYTES)
  481. ┘╨╧╙=    52    ; ╙PRITE Y-COORDINATE
  482. ╙╨╥├╧╠=  2     ; ╙PRITE COLORS
  483.  
  484.  
  485. *= $├000
  486.  
  487.         ╙┼╔             ; ─ISABLE INTERRUPTS
  488.         ╠─┴ #$7╞
  489.         ╙╘┴ $─├0─       ; ─ISABLE TIMER INTERRUPTS
  490.         ╠─┴ #<╔╥╤       ; ╧UR OWN INTERRUPT HANDLER
  491.         ╙╘┴ $0314
  492.         ╠─┴ #>╔╥╤
  493.         ╙╘┴ $0315
  494.         ╠─╪ #$3┼        ; ╫E CREATE A SPRITE TO CASSETTE BUFFER
  495. ╠╧╧╨    ╠─┴ ╙╨╥╔╘┼,╪
  496.         ╙╘┴ $0340,╪
  497.         ─┼╪
  498.         ┬╨╠ ╠╧╧╨
  499.         ╠─╪ #7
  500. ╠╧╧╨2   ╠─┴ #$─         ; ╙ET THE SPRITE IMAGE POINTERS
  501.         ╙╘┴ $07╞8,╪
  502.         ╠─┴ #╙╨╥├╧╠     ; ╙ET SPRITE COLORS
  503.         ╙╘┴ $─027,╪
  504.         ─┼╪
  505.         ┬╨╠ ╠╧╧╨2
  506.         ╠─╪ #$26
  507. ╠╧╧╨3   ╠─┴ ╓╔─┼╧,╪     ; ╔NIT ╓╔├
  508.         ╙╘┴ $─000,╪
  509.         ─┼╪
  510.         ┬╨╠ ╠╧╧╨3
  511.         ╠─╪ #$7╞        ; ├REATE THE Y-SCROLL TABLE
  512. ╠╧╧╨4   ╘╪┴             ;  AND CLEAR THE COLOR TABLE
  513.         ┴╬─ #$07
  514.         ╧╥┴ #$10        ; ╬ON-BLANK SCREEN
  515.         ╙╘┴ ┘╙├╥╧╠╠,╪
  516.         ╠─┴ #$00
  517.         ╙╘┴ ├╧╠╧╥╙,╪
  518.         ─┼╪
  519.         ┬╨╠ ╠╧╧╨4
  520.         ╙╘┴ $3╞╞╞
  521.         ╠─╪ #23         ; ├REATE A COLOR TABLE
  522. ╠╧╧╨5   ╠─┴ ┬┴├╦,╪
  523.         ╙╘┴ ├╧╠╧╥╙+8,╪
  524.         ╙╘┴ ├╧╠╧╥╙+32,╪
  525.         ╙╘┴ ├╧╠╧╥╙+56,╪
  526.         ╙╘┴ ├╧╠╧╥╙+80,╪
  527.         ╙╘┴ ├╧╠╧╥╙+96,╪
  528.         ─┼╪
  529.         ┬╨╠ ╠╧╧╨5
  530.         ╩╙╥ ├╚┴╬╟┼      ; ╔NIT SPRITE SIZES AND Y-POSITIONS
  531.         ├╠╔             ; ┼NABLE INTERRUPTS
  532.         ╥╘╙
  533.  
  534. ╔╥╤     ╠─╪ #$01
  535.         ╠─┘ #$08        ; 'NORMAL' $─016
  536.         ╬╧╨             ; ╘IMING
  537.         ╬╧╨
  538.         ╬╧╨
  539.         ┬╔╘ $┼┴         ; (┴DD ╬╧╨'S ETC. FOR ╬╘╙├)
  540. ╠╧╧╨6   ╠─┴ ┘╙├╥╧╠╠-1,╪ ; ═OVE THE SCREEN (BAD LINES)      5
  541.         ╙╘┴ $─011                                          4
  542.         ╠─┴ ├╧╠╧╥╙,╪    ; ╠OAD THE BACKGROUND COLOR        4
  543.         ─┼├ $─016       ; ╧PEN THE BORDER                  6
  544.         ╙╘┴ $─021       ; ╙ET THE BACKGROUND COLOR         4
  545.         ╙╘┘ $─016       ; ╙CREEN TO NORMAL                 4
  546.         ╠─┴ ╙╘╥┼╘├╚,╪   ; ╙TRETCH THE SPRITES              4
  547.         ╙╘┴ $─017                                          4
  548.         ┼╧╥ #$╞╞                                           2
  549.         ╙╘┴ $─017                                          4
  550.                         ; (┴DD ╬╧╨ FOR ╬╘╙├     +2)
  551.         ╔╬╪             ; ╔NCREASE COUNTER                 2
  552.         ┬╨╠ ╠╧╧╨6       ; ╠OOP 127 TIMES                 + 3
  553.                                                          ---
  554.         ╠─┴ #1          ; ┴CK THE RASTER INTERRUPT       =46
  555.         ╙╘┴ $─019                                        +17(SPRITES)
  556.                                                          ---
  557.         ╩╙╥ ─╧╙╘╥┼╘├╚   ; ╬EW STRETCH                    =63(WHOLE)
  558.  
  559.         ╩═╨ $┼┴31
  560.  
  561. ╙╨╥╔╘┼  ┬┘╘ 0,0,0,3,$╞┬,0,7,$7┼          ; ┴N ┼XAMPLE SPRITE
  562.         ┬┘╘ 0,$35,$─╞,0,$1─,$77,0,$┬7
  563.         ┬┘╘ $5─,0,$┬─,$83,$7┼,$┼╞,1,$─┼
  564.         ┬┘╘ $┬┬,1,$78,$┴┼,3,$70,$┼┬,0
  565.         ┬┘╘ 0,$┬┴,3,$60,$┼┼,3,$─8,$╞┬
  566.         ┬┘╘ 2,$╞6,$╞┼,$83,$┬─,$9╞,$┬┴,0
  567.         ┬┘╘ $37,$┼┼,0,$3─,$╞┬,0,7,$7┼
  568.         ┬┘╘ 0,3,$─╞,0,0,0,0
  569.  
  570. ╓╔─┼╧   ┬┘╘ $┼8,┘╨╧╙,$20,┘╨╧╙,$50,┘╨╧╙,$80,┘╨╧╙,$┬0,┘╨╧╙
  571.         ┬┘╘ $┼0,┘╨╧╙,$10.┘╨╧╙,$40,┘╨╧╙,$├1,$18,┘╨╧╙-1,0,0
  572.         ┬┘╘ $╞╞,8,$╞╞,$15,1,1,$╞╞,$╞╞,$╞╞,0,0,0,0,0,0,0,1,10
  573.         ; ╔NIT VALUES FOR ╓╔├ - SPRITES, INTERRUPTS, COLORS
  574.  
  575. ┬┴├╦    ┬┘╘ 0,$┬,$├,$╞,1,$╞,$├,$┬   ; ┼XAMPLE COLOR BARS
  576.         ┬┘╘ 0,6,$┼,$─,1,$─,$┼,6
  577.         ┬┘╘ 0,9,2,$┴,1,$┴,2,9
  578.  
  579. ─╧╙╘╥┼╘├╚
  580.         ╠─╪ #31            ; ├LEAR THE TABLE
  581.         ╠─┴ #0             ; (╒NROLLING WILL HELP THE SPEED,
  582. ╠╧╧╨7   ╙╘┴ ╙╘╥┼╘├╚,╪      ;  BECAUSE ╙╘┴ NNNN,╪ IS 5 CYCLES
  583.         ╙╘┴ ╙╘╥┼╘├╚+32,╪   ;  AND ╙╘┴ NNNX IS ONLY 4 CYCLES.)
  584.         ╙╘┴ ╙╘╥┼╘├╚+64,╪
  585.         ╙╘┴ ╙╘╥┼╘├╚+96,╪
  586.         ─┼╪
  587.         ┬╨╠ ╠╧╧╨7
  588.         ╙╘┴ ╥┼═┴╔╬─+1      ; ├LEAR THE REMAINDER
  589.         ╠─┴ #7
  590.         ╙╘┴ ├╧╒╬╘┼╥+1      ; ╔NIT COUNTER FOR 8 LOOPS
  591.         ╠─┴ #$80
  592.         ╙╘┴ ═┴╙╦+1         ; ╞IRST SPRITE 7, MASK IS $80
  593. ├╧╒╬╘┼╥ ╠─╪ #$00           ; ╘HE ARGUMENT IS THE COUNTER
  594.         ╠─┘ ┘├╧╧╥─,╪       ; Y-POSITION
  595.         ╠─┴ ╚┼╔╟╚╘,╪       ; ╚EIGHT OF ONE LINE (5 BIT INTEGER PART)
  596.         ╙╘┴ ┴──+1
  597.         ╠─╪ #20            ; ╚ANDLE 20 LINES
  598. ╠╧╧╨8   ╠─┴ ╙╘╥┼╘├╚+2,┘
  599. ═┴╙╦    ╧╥┴ #$00
  600.         ╙╘┴ ╙╘╥┼╘├╚+2,┘    ; ╙ET A ONE-BIT
  601.         ╙╘┘ ┘┴──+1
  602. ╥┼═┴╔╬─ ╠─┴ #0
  603.         ┴╬─ #7             ; ╨REVIOUS REMAINDER
  604. ┴──     ┴─├ #0             ;  ADD TO THE HEIGHT
  605.         ╙╘┴ ╥┼═┴╔╬─+1      ; ╙AVE THE NEW VALUE
  606.         ╠╙╥
  607.         ╠╙╥
  608.         ╠╙╥
  609.         ├╠├                ; ╘AKE THE INTEGER PART
  610. ┘┴──    ┴─├ #0
  611.         ╘┴┘                ; ╬EW VALUE TO Y-REGISTER
  612.         ─┼╪
  613.         ┬╬┼ ╠╧╧╨8
  614.         ╠╙╥ ═┴╙╦+1         ; ╒SE NEW MASK
  615.         ─┼├ ├╧╒╬╘┼╥+1      ; ╬EXT SPRITE
  616.         ┬╨╠ ├╧╒╬╘┼╥
  617.  
  618. ├╚┴╬╟┼  ╠─┴ #$00
  619.         ┴╙╠                ; ╙PRITE HEIGHT CHANGES WITH 2X SPEED
  620.         ┴╬─ #$3╞
  621.         ╘┴┘                ; 64 BYTES LONG TABLE
  622.         ╔╬├ ├╚┴╬╟┼+1       ; ╔NCREASE THE COUNTER
  623.         ╠─╪ #7             ; ─O EIGHT SPRITES
  624. ╠╧╧╨9   ╠─┴ ╙╔╬╒╙,┘
  625.         ╠╙╥
  626.         ╠╙╥
  627.         ├╠├                ; ╒SE THE SAME SINUS AS Y-DATA
  628.         ┴─├ #8
  629.         ╙╘┴ ╚┼╔╟╚╘,╪       ; ╙PRITE HEIGHT WILL BE FROM 1 TO 3 LINES
  630.         ╘┘┴
  631.         ┴─├ #10            ; ╬EXT SPRITE ENLARGEMENT WILL BE 10 ENTRIES
  632.         ┴╬─ #$3╞           ;  FROM THIS
  633.         ╘┴┘
  634.         ─┼╪
  635.         ┬╨╠ ╠╧╧╨9
  636.         ╠─╪ #7
  637.         ╠─┴ ├╚┴╬╟┼+1
  638.         ┴╬─ #$3╞
  639.         ╘┴┘
  640. ╠╧╧╨10  ╠─┴ ╙╔╬╒╙,┘        ; ┘-POSITION
  641.         ╙╘┴ ┘├╧╧╥─,╪
  642.         ╘┘┴
  643.         ┴─├ #10            ; ╬EXT SPRITE POSITION IS 10 ENTRIES FROM THIS ONE
  644.         ┴╬─ #$3╞
  645.         ╘┴┘
  646.         ─┼╪
  647.         ┬╨╠ ╠╧╧╨10
  648.         ╥╘╙
  649.  
  650. ╙╔╬╒╙   ┬┘╘ $20,$23,$26,$29,$2├,$2╞,$31,$34 ; ┴ PART OF A SINUS TABLE
  651.         ┬┘╘ $36,$38,$3┴,$3├,$3─,$3┼,$3╞,$3╞
  652.         ┬┘╘ $3╞,$3╞,$3╞,$3┼,$3─,$3├,$3┴,$38
  653.         ┬┘╘ $36,$34,$31,$2╞,$2├,$29,$26,$23
  654.         ┬┘╘ $20,$1├,$19,$16,$13,$10,$┼,$┬
  655.         ┬┘╘ 9,7,5,3,2,1,0,0,0,0,0,1,2,3,5,7
  656.         ┬┘╘ 9,$┬,$┼,$10,$13,$16,$19,$1├
  657.  
  658. --------------------------------------------------------------------------
  659. ╙TRETCHING SPRITES DEMO PROGRAM BASIC LOADER (╨┴╠)
  660.  
  661. 1 ╙=49152
  662. 2 ─┼╞╞╬╚(├)=├-48+7*(├>64)
  663. 3 ├╚=0:╥┼┴─┴$,┴:╨╥╔╬╘┴$:╔╞┴$="┼╬─"╘╚┼╬╨╥╔╬╘"<CLR>":╙┘╙49152:┼╬─
  664. 4 ╞╧╥╞=0╘╧31:╤=╞╬╚(┴╙├(═╔─$(┴$,╞*2+1)))*16+╞╬╚(┴╙├(═╔─$(┴$,╞*2+2)))
  665. 5 ├╚=├╚+╤:╨╧╦┼╙,╤:╙=╙+1:╬┼╪╘:╔╞├╚=┴╘╚┼╬3
  666. 6 ╨╥╔╬╘"├╚┼├╦╙╒═ ┼╥╥╧╥":┼╬─
  667. 100 ─┴╘┴ 78┴9648─1403┴9├08─1503┴23┼┬─96├09─4003├┴10╞7┴207┴90─9─╞807┴9029─, 3614
  668. 101 ─┴╘┴ 27─0├┴10╞3┴226┬──5├09─00─0├┴10╞7┴27╞8┼0──├8┴290709109─00├╞┴9009─, 3897
  669. 102 ─┴╘┴ 80├┼├┴10╞08─╞╞3╞┴217┬─╞├├09─88├┼9─┴0├┼9─┬8├┼9──0├┼9─┼0├┼├┴10┼┬20, 5281
  670. 103 ─┴╘┴ 67├15860┴201┴008┼┴┼┴┼┴24┼┴┬─╞╞├┼8─11─0┬─80├┼├┼16─08─21─08├16─0┬─, 4699
  671. 104 ─┴╘┴ 80├╞8─17─049╞╞8─17─0┼810┼0┼┼19─02014├14├31┼┴00000003╞┬00077┼0035, 3394
  672. 105 ─┴╘┴ ─╞001─7700┬75─00┬─837┼┼╞01─┼┬┬0178┴┼0370┼┬0000┬┴0360┼┼03─8╞┬02╞6, 3628
  673. 106 ─┴╘┴ ╞┼83┬─9╞┬┴0037┼┼003─╞┬00077┼0003─╞00000000┼834203450348034┬034┼0, 3015
  674. 107 ─┴╘┴ 3410344034├118330000╞╞08╞╞150101╞╞╞╞╞╞00000000000000010┴000┬0├0╞, 1859
  675. 108 ─┴╘┴ 010╞0├0┬00060┼0─010─0┼060009020┴010┴0209┴21╞┴9009─80├╞9─┴0├╞9─├0, 1876
  676. 109 ─┴╘┴ ├╞9─┼0├╞├┴10╞18─4─├1┴9078─35├1┴9808─45├1┴200┬├8003┬─88038─51├1┴2, 4314
  677. 110 ─┴╘┴ 14┬982├╞09009982├╞8├5┴├1┴900290769008─4─├14┴4┴4┴186900┴8├┴─0┼24┼, 3430
  678. 111 ─┴╘┴ 45├1├┼35├110├─┴9000┴293╞┴8┼┼68├1┴207┬99┼├14┴4┴1869089─880398690┴, 3474
  679. 112 ─┴╘┴ 293╞┴8├┴10┼├┴207┴─68├1293╞┴8┬99┼├19─800398690┴293╞┴8├┴10╞1602023, 3622
  680. 113 ─┴╘┴ 26292├2╞313436383┴3├3─3┼3╞3╞3╞3╞3╞3┼3─3├3┴383634312╞2├292623201├, 1654
  681. 114 ─┴╘┴ 191613100┼0┬09070503020100000000000102030507090┬0┼101316191├0000, 296
  682. 200 ─┴╘┴ ┼╬─,0
  683.  
  684. --------------------------------------------------------------------------
  685. ╒UENCODED ├64 EXUTABLE FOR STRETCHING SPRITES (╨┴╠)
  686.  
  687. BEGIN 644 STRETCH.64
  688. ═`0@-"`$`4[(╘.3$╒,@`╞"`(`┼╩5(*$,╔╠─.╦-#┬╩-┌╨╚0[$╓-"─`40@#`$-(?
  689. ═╠├`┌┴╘$─+$$┌╞4$─.╚═!)+(┬14┘$(╩>9(╔,┬.╔╪╘.3$╒,├╩``(@(!`"!1╦(╨/
  690. ═╔#,╤.┼&╥╔4@╚╤┬├**$$─+$:╠,╩╚╤*2─╔╦#$╓╩╩5(*,8╚╥┬┴!)"╤&╦#*╩,┬─╔:
  691. ═*0"╔"`4`0╘┬╥0╘┬╩43╩74╥╤1.┼.╥4┌╚╤.╚(┌┬╘-(╠─&╟,╨#!"`8`╞2)#2$5#╞
  692. ═2╒-532!%4┼)/4┬(┌@``."60`@╥`╫.$$┘-├0╪1#$╘,#-!.4,╨.$0╤-3`╙03(╙3
  693. ═14)$.39#,#┼$-#`╨,╘-!,3!&-╘$╥,#=!.3!$.41&.#`╫03─╨,├┼$+"`╙-├$╘╨
  694. ═`%╠)90"#(#(╫1#!#03$╨1├-!,├(╓0─1$-4,╨.40╨,$0╨0╘$╤,$8╫03(╫1├┴%4
  695. ═,$1$0╙┴!,├─╨-╙`┘,3`┘1#`╨0╘9!.3`╨.40╠(#,╪.3<`╩`┼╞`(,@.#!#14-!┬
  696. ═,3!&,#┴$1─8╙1─$╥,3="1$9#0╙`┘1#@╪0╘4┘1$$╨0╘4┘1$(╪0╘4┘1$0╨0╘4┘1
  697. ═1$4╨0╘5#03$╨14(╥,"╨@-3(╪,0#╒"6<`@╥`╓-╘,╤-3@╓,$$╥,#%!,#`╪14%%?
  698. ═045!,├1%04)$1─9#13┴$,3%$,$)$.#!#14-%,39$,#┴$,├%$,#┴#,39$,$)$╟
  699. ═+"`╘-├─┘`$(*:`"#(#@╨0╘8╪1#$╫1#`╘.49&.$0╤-╘0╨13@╤,$4╨144╤.40╨4
  700. ═,├`╤-$,╤-$,╙,45!,#`╨,#`╨,#-&0├`╨,#<╫13`╨,╙4╠(#,╙.30`├╨╔╔`(,@╓
  701. ═1$8╨,#%$-╙<╨,$(╫-40╨,$)$.#,╫145&,#%$14)",#$╫.$%%,#,╫,$5",#`╨<
  702. ═,$)!,#,╓,$5%,#-$.$9",#)&-┬╨@,╙8╥.`#<"╞╚`@╥!&13@╙0─0┘1─)!,#`╙╬
  703. ═-╘5%,#`╙1$9",#`╨-╙=%,#`╨,╘1&,#`╨,#`╨,#!%.#,╘,├`╙-#4╨,╙0╪,#,╘╪
  704. ═0├`╙-$4╨+"`╙,#$╒`"─+:╨"#(#,╘,3`╙-#0╨,╙1#,3$╪,╙,╨,#`╨1─8╨.$9&┬
  705. ═,34╨,3`╤1─9&1─9&,#`╨,#`╨,#`╨,#`╨,#`╨,3!!,#`╨0├!#,$8╠(#$╪-3─`<
  706. ═=@═╠`(,@,#$╨1├!#,$(╨,#`╓,$4╨1#`╤,$0╨13`╓,#`╨.3`╥,$$╨,3!!,#(╨╦
  707. ═.4$╥,49!.3`╨.40╪,$-&.41!,$-&.41#,"╨@,3@╫-@##"╓╘`@╥!#1├┼$13!#0
  708. ═1─-!,3!&,3┴$-$1#,4$┘,#<╪1#,╒0╙%!.3@╨.$0╘-4,╤03(╨,$)#.#`╨,╘)$╟
  709. ═.#@╨,╙┴$-3%#,4$╥+"`╘,╙$╘`!`,;@"#(#$╘0├─╪,─-&,#─╨,#─┘.#)#1├┴#=
  710. ═-4%#,4$┘,#`╥.3`╫-├─╨,#┴$-$1#,31!-$$╘03$╪-├─╨,$$╪0╘%$,$4╥-$4╠╤
  711. ═(#,╘,╙``70╤╧`(,@-#5#,4-%,╙5#,3$╨0╘1!.3`╨,$$╥.3-&03┴%138╪0╙%!├
  712. ═,├`╫0├─┘14,╤-$$╘03$╪-├─╨.#┼$.#@╨,╙─╪-├─╨02╨@,╙0╫-`"╩#'``@╥`╥╩
  713. ═.3-&03┴#03$╨14-!,├`╫040╓.$,╤,├─╙1─$╪0├─┘14,╤.40╪,#`╙.3@╓.3!!\
  714. ═,├─╙1─$╪0╘$╤,$8╤-├`╥,#(╙+"`╙-├(╥`/<,<0"#(#(╓,├─╥0╙)&,╙$╙-#,╓*
  715. ═,╙@╙03-#,╘0╙13-&,╘8╙1├-&,╘8╙13-$,╘,╙03,╪,╙8╙-#,╤,─8╥0╙(┘,├8╥+
  716. ═,╙(╨,4,╠(#$╓-30`0╨╒╥`(,@,3─╤-├$╙,3`╨13!",#─╨-╙`╒,#,╨,├`╤,#`╨╥
  717. ═,#`╨,#`╨,#`╤,#(╨,╙`╒,#<╨.3!",$4╤,#$╙,38╤.3%#,#`╨,"╨@,├─╓`$\-┼
  718. ,╥`"#($5.1"╨╨````>
  719. ``
  720. END
  721. SIZE 1362
  722.  
  723. =============================================================================
  724. ╥OB ╚UBBARD'S ═USIC: ─ISASSEMBLED, ├OMMENTED AND ┼XPLAINED
  725. BY ┴NTHONY ═C╙WEENEY (U882859@POSTOFFICE.UTAS.EDU.AU)
  726.  
  727. [┼D'S ╬OTE: ╔ QUESTIONED THIS ARTICLE CONCERNING COPYRIGHT PROBLEMS AND HE
  728. HAS ASSURED ME THAT IT IS LEGAL TO PRESENT IT IN ENTIRITY LIKE THIS AS IT IS
  729. PAST A CERTAIN # OF YEARS. ┴CCORDINGLY ╔'M PRESENTING IT AND ANY CONCERNS
  730. SHOULD BE TAKEN UP WITH HIM AND NOT MYSELF.]
  731.  
  732. ╔NTRODUCTION:
  733. ************
  734.  
  735.   ╚OW DO YOU INTRODUCE SOMEONE LIKE ╥OB ╚UBBARD?? ╚E CAME, HE SAW AND HE
  736. CONQUERED THE '64 WORLD. ╔N MY ESTIMATION, THIS ONE MAN WAS RESPOSIBLE FOR
  737. SELLING MORE '64 SOFTWARE THAN ANY OTHER SINGLE PERSON. ╚ELL! ╔ THINK THAT ╥OB
  738. ╚UBBARD WAS RESPONSIBLE FOR SELLING MORE ├╧══╧─╧╥┼ 64'S THAN ANY OTHER PERSON!
  739. ╔ CERTAINLY BOUGHT MY '64 AFTER BEING BLOWN AWAY BY THE ═ONTY ON THE ╥UN MUSIC
  740. IN ─ECEMBER 1985. ╔N THE NEXT FEW YEARS, ╥OB WOULD TOTALLY DOMINATE THE '64
  741. MUSIC SCENE, RELEASING ONE HIT AFTER ANOTHER. ╔ WILL EVEN SAY THAT SOME REALLY
  742. TERRIBLE GAMES SOLD WELL ONLY ON THE STRENGTH OF THEIR BRILLIANT ╥OB ╚UBBARD
  743. MUSIC (EG. ╦NUCKLE┬USTERS AND ╫.┴.╥.).
  744.  
  745.   ╙O HOW DID ╥OB ACHIEVE THIS SUCCESS? ╞IRSTLY (OF COURSE) HE IS A SUPERB
  746. COMPOSER AND MUSICIAN, ABLE TO MAKE THE TUNES THAT BRING JOY TO OUR HEARTS
  747. EVERYTIME WE HEAR THEM! (ALSO CONSIDER THE AMAZING DIVERSITY OF STYLES OF
  748. MUSIC THAT ╥OB COMPOSED). ╙ECONDLY, HE WAS ABLE TO MAKE MUSIC WHICH WAS SUITED
  749. TO THE STRENGTHS AND LIMITATIONS OF THE ╙╔─ CHIP. ╩UST RECALL THE SOUNDFX USED
  750. AT THE BEGINNING OF ╘HRUST, OR IN THE ─ELTA IN-GAME MUSIC. ╨ERHAPS THE BIGGEST
  751. LIMITATION OF ╙╔─ MUST BE THE MEAGRE 3 CHANNELS THAT CAN BE USED, BUT MOST
  752. ╚UBBARD SONGS APPEAR TO HAVE FOUR, FIVE OR EVEN MORE INSTRUMENTS GOING (JUST
  753. LISTEN TO THE BEGINNING OF ╨HANTOMS OF THE ┴STERIODS FOR EXAMPLE... THAT'S
  754. ONLY ONE CHANNEL USED!!). ╔ COULD REALLY GO ON FOR (P)AGES IDENTIFYING THE
  755. OUTSTANDING THINGS THAT ╥OB ╚UBBARD DID, SO ╔ WILL FINALLY MENTION THAT ╥OB'S
  756. CODING SKILLS AND HIS MUSIC ROUTINES WERE A MAJOR FACTOR IN HIS SUCCESS.
  757.  
  758.  
  759. ╘HE ╞IRST ╥OB ╚UBBARD ╥OUTINE:
  760. *****************************
  761.  
  762.   ╥OB ╚UBBARD CREATED A SUPERB MUSIC ROUTINE FROM THE VERY FIRST TUNE WHICH
  763. WAS RELEASED (├ONFUZION). ╞URTHERMORE, ╥OB USED THIS ROUTINE TO MAKE MUSIC
  764. FOR A VERY LONG TIME, ONLY CHANGING IT _SLIGHTLY_ OVER TIME. ╘HE SOURCECODE
  765. THAT ╔ PRESENT HERE WAS USED (WITH SLIGHT MODIFICATIONS) IN: ├ONFUZION, ╘HING
  766. ON A ╙PRING, ═ONTY ON THE ╥UN, ┴CTION ┬IKER, ├RAZY ├OMETS, ├OMMANDO, ╚UNTER
  767. ╨ATROL, ├HRIMERA, ╘HE ╠AST ╓8, ┬ATTLE OF ┬RITAIN, ╚UMAN ╥ACE, ┌OIDS, ╥ASPUTIN,
  768. ═ASTER OF ═AGIC, ╧NE ═AN & ╚IS ─ROID, ╟AME ╦ILLER, ╟ERRY THE ╟ERM, ╟EOFF ├APES
  769. ╙TRONGMAN ├HALLENGE, ╨HANTOMS OF THE ┴STEROIDS, ╦ENTILLA, ╘HRUST,
  770. ╔NTERNATIONAL ╦ARATE, ╙PELLBOUND, ┬UMP ╙ET AND ╙PIKE, ╞ORMULA 1 ╙IMULATOR,
  771. ╓IDEO ╨OKER, ╫ARHAWK OR ╨ROTEUS AND MANY, MANY MORE! ┴LL YOU WOULD NEED TO DO
  772. TO PLAY A DIFFERENT MUSIC IS TO CHANGE THE MUSIC DATA AT THE BOTTOM, AND A FEW
  773. LINES OF THE CODE.
  774.  
  775.   ╘HIS PARTICULAR ROUTINE HAS BEEN RIPPED OFF BY MANY FAMOUS GROUPS AND
  776. PEOPLE OVER THE YEARS, BUT ╔ DON'T THINK THAT THEY WERE EVER GENEROUS ENOUGH
  777. TO SHARE IT AROUND. ├AN YOU REMEMBER ╘HE ╩UDGES AND ╥ED ╙OFTWARE?? ╘HEY MADE
  778. THE FAMOUS ╥ED-╚UBBARD DEMO, AND USED IT IN ╥HAA-╠OVELY AND MANY OF THEIR
  779. OTHER PRODUCTIONS. ╔'M SURE THAT THE (┴TARI) ╙╘ FREAKS READING THIS WILL LOVE
  780. ═AD ═AX (AKA ╩OCHEN ╚IPPEL), AND REMEMBER THE ┬╔╟ DEMO WHICH FEATURED APPROX
  781. 100 ╥OB ╚UBBARD TUNES CONVERTED TO THE ╙╘. ┴LTHOUGH ╔ HATE TO ADMIT IT, ╔
  782. DECIDED TO START SHARING AROUND MY OWN SOURCECODE AFTER RECEIVING THE AMAZING
  783. ╨ROTRACKER SOURCECODE (340╦!) ON THE ┴MIGA (THANKS ╠ARS ╚AMRE). ╘HAT MADE ME
  784. SHAMEFUL TO BE SELFISH, ESPECIALLY AFTER ╔ LEARNED ALOT OF FROM IT. ╫HY DON'T
  785. ┘╧╒ SHARE AROUND YOUR OLD SOURCECODES TOO!
  786.  
  787.   ╘HE PARTICULAR ROUTINE THAT IS INCLUDED BELOW WAS RIPPED FROM ═ONTY ON THE
  788. ╥UN, AND IT APPEARED IN MEMORY FROM $8000 TO ABOUT $9554. ╘HE COMPLETE
  789. ROUTINE HAD CODE FOR SOUNDFX IN IT, WHICH ╔ HAVE TAKEN OUT FOR THE SAKE OF
  790. CLARITY. ┴LTHOUGH THE ROUTINE IS REALLY TINY - A MERE 900 OR 1000 BYTES OF
  791. CODE, THERE ARE SOME AMAZINGLY COMPLEX CONCEPTS IN IT WHICH REQUIRE ALOT OF
  792. EXPLANATION IF YOU DON'T KNOW MUCH ABOUT COMPUTER MUSIC OR ╙╔─. ╞ORTUNATELY
  793. FOR YOU, ╔ HAVE PUT IN EXCELLENT LABEL NAMES FOR YOU, AND ALSO ALOT OF REALLY
  794. HELPFUL AND AMAZING COMMENTS. ╔N FACT, ╔ THINK THIS SOURCECODE MUST HAVE A
  795. MUCH BETTER STRUCTURE AND COMMENTS THAN ╥OB ╚UBBARD'S ORIGINAL!!! ╔ THINK THAT
  796. THE BEST WAY TO UNDERSTAND THE SOURCECODE IS TO STUDY IT, AND FIGURE OUT WHAT
  797. IS GOING ON USING THE COMMENTS.
  798.  
  799.   ╔N ADDITION TO THE COMMENTS IN THE SOURCE, THERE ARE *3* DESCRIPTIONS OF
  800. THE ROUTINE IN THIS ARTICLE. ╘HE FIRST TELLS YOU HOW TO USE THE MUSIC ROUTINE
  801. WHEN IT'S VIEWED AS AN ALREADY ASSEMBLED 'MODULE'. ╘HE SECOND GOES THROUGH AN
  802. OVERVIEW OF THE MUSIC AND INSTRUMENT DATA FORMAT, AND IS GREAT FOR GETTING AN
  803. OVERALL FEEL FOR WHAT THE CODE IS DOING. ╘HE THIRD DESCRIPTION LOOKS AT THE
  804. VARIOUS SECTIONS OF THE CODE, AND HOW THEY COME TOGETHER.
  805.  
  806.  
  807. ╚OW TO USE THE SOURCECODE:
  808. *************************
  809.  
  810.     JSR    MUSIC+0 TO INITIALIZE THE MUSIC NUMBER IN THE ACCUMULATOR
  811.     JSR    MUSIC+3 TO PLAY THE MUSIC
  812.     JSR    MUSIC+6 TO STOP THE MUSIC AND QUIETEN ╙╔─
  813.  
  814.   ╘HE MUSIC IS SUPPOSED TO RUN AT 50╚Z, OR 50 TIMES PER SECOND. ╘HEREFORE
  815. ╨┴╠ USERS CAN RUN THE MUSIC ROUTINE OFF THE ╔╥╤ LIKE THIS:
  816.  
  817.     LDA    #$00     ; INIT MUSIC NUMBER 0
  818.     JSR    MUSIC+0
  819.     SEI             ; INSTALL THE IRQ AND A RASTER COMPARE
  820.     LDA    #<IRQ
  821.     LDX    #>IRQ
  822.     STA    $314
  823.     STX    $315
  824.     LDA    #$1B
  825.     STA    $D011
  826.     LDA    #$01
  827.     STA    $D01A
  828.     LDA    #$7F
  829.     STA    $DC0D
  830.     CLI
  831. LOOP =*
  832.     JMP    LOOP     ; ENDLESS LOOP (MUSIC IS NOW PLAYING OFF INTERRUPT :-)
  833.  
  834. IRQ =*
  835.     LDA    #$01
  836.     STA    $D019
  837.     LDA    #$3C
  838.     STA    $D012
  839.  
  840.     INC    $D020    ; PLAY MUSIC, AND SHOW A RASTER FOR THE TIME IT TAKES
  841.     JSR    MUSIC+3
  842.     DEC    $D020
  843.  
  844.     LDA    #$14
  845.     STA    $D018
  846.     JMP    $EA31
  847.  
  848.   ╔F THIS METHOD IS USED ON ╬╘╙├ MACHINES, THEN THE MUSIC WILL BE RUNNING AT
  849. 60╚Z AND WILL SOUND MUCH TO FAST - POSSIBLY IT MIGHT SOUND TERRIBLE. ╔'M
  850. AFRAID YOU'LL HAVE TO PUT UP WITH THIS UNLESS ┘╧╒ ARE GOOD ENOUGH TO MAKE A
  851. ├╔┴ INTERRUPT AT 50╚Z. ┴S ╔ HAVN'T HAD TO WORRY ABOUT ╬╘╙├ USERS BEFORE,
  852. PERHAPS SOMEONE WILL SEND ME THE BEST WAY TO DO THIS...
  853.  
  854. [┼D. ╬OTE: ┘OU COULD ALSO KEEP A COUNTER FOR THE ╔╥╤ AND DON'T EXECUTE IT
  855. EVERY 6 INTERRUPT. ╘HIS WILL MAKE IT THE RIGHT SPEED ALTHOUGH THE BEST
  856. SOLUTION IS FOR MODIFYING THE ├╔┴ TO 50╚Z LIKE HE MENTIONS ABOVE.]
  857.  
  858. ╚OW THE MUSIC DATA IS ARRANGED:
  859. ******************************
  860.  
  861. 1. ╘HE MUSIC 'MODULE' CONTAINS ONE OR MORE SONGS.
  862.  
  863.   ┼ACH ╥╚ MUSIC IS MADE UP OF A 'BUNCH' OF SONGS IN A SINGLE MODULE. ╘HUS
  864. THE 'MODULE' CAN HAVE THE TITLE MUSIC, IN-GAME MUSIC, AND THE GAME-OVER MUSIC
  865. ALL USING THE SAME PLAYROUTINE (AND EVEN THE SAME INSTRUMENTS :). ╘HE SOURCE
  866. THAT APPEARS BELOW ONLY HAS THE ONE SONG IN IT, AND THE MUSIC NUMBER IS
  867. AUTOMATICALLY SET TO 0 AS A RESULT (LINE 20). ╘HE LABEL 'SONGS' IS WHERE YOU
  868. WANT TO LOOK FOR THE POINTERS TO THE SONGS IF YOU WANT TO CHANGE THIS.
  869.  
  870. 2. ┼ACH SONG IS MADE UP OF THREE TRACKS.
  871.  
  872.   ╫E ALL KNOW THAT THERE ARE ONLY 3 CHANNELS ON THE ╙╔─ CHIP, SO THERE ARE
  873. ALSO 3 TRACKS - ONE FOR EACH CHANNEL. ╫HEN ╔ SAID 'POINTERS TO THE SONGS'
  874. ABOVE, ╔ WAS THEREFORE REFERRING TO 'POINTERS TO THE THREE TRACKS THAT MAKE UP
  875. THE SONG'...HENCE WE ARE LOOKING AT THE LABEL 'SONGS' AGAIN. ┼ACH TRACK NEEDS
  876. A HIGH AND LOW POINTER, SO THERE ARE 6 BYTES NEEDED TO POINT TO A SONG.
  877.  
  878. 3. ┼ACH TRACK IS MADE UP OF A LIST OF PATTERN NUMBERS
  879.  
  880.   ┼ACH TRACK CONSISTS OF A LIST OF THE PATTERN NUMBERS IN THE ORDER IN WHICH
  881. THEY ARE TO BE PLAYED. ╚ERE WE ARE LOOKING AT THE LABELS 'MONTYMAINTR1' AND
  882. 'MONTYMAINTR2'AND 'MONTYMAINTR3'. ╘HEREFORE ╔ CAN TELL YOU THAT THE INITIAL
  883. PATTERNS PLAYED IN THIS SONG ARE $11, $12 AND $13 ON CHANNELS 1,2 AND 3
  884. RESPECTIVELY. ╘HE TRACK IS EITHER ENDED WITH A $FF OR $FE BYTE. ┴ $FF MEANS
  885. THAT THE SONG NEEDS TO BE LOOPED WHEN THE END OF THE TRACK IS REACHED (LIKE
  886. THE MONTY MAIN TUNE), WHILE A $FE MEANS THAT THE SONG IS ONLY TO BE PLAYED
  887. ONCE. ╘HE CURRENT OFFSET INTO THE TRACK IS OFTEN CALLED THE CURRENT ╨╧╙╔╘╔╧╬
  888. FOR THAT TRACK.
  889.  
  890. 4. ┴ PATTERN CONSISTS OF A SEQUENCE OF NOTES.
  891.  
  892.   ┴ PATTERN CONTAINS THE DATA THAT SAYS WHEN THE NOTES SHOULD BE PLAYED, HOW
  893. LONG THEY SHOULD BE PLAYED FOR, AT WHAT PITCH, WITH WHAT INSTRUMENT, SHOULD
  894. THERE BE ┴─╙╥, SHOULD THERE BE BENDING (PORTAMENTO) OF THE NOTES ETC. ┼ACH
  895. PATTERN IS ENDED WITH A $FF BYTE, AND WHEN THIS IS ENCOUNTERED, THE NEXT
  896. PATTERN IN THE TRACK WILL BE PLAYED. ┼ACH NOTE HAS UP TO A 4 BYTE
  897. SPECIFICATION.
  898.  
  899. - ╘HE FIRST BYTE IS ALWAYS THE LENGTH OF THE NOTE FROM 0-31 OR 0-$1F IN HEX.
  900.   ┘OU WILL NOTICE THAT THE TOP THREE BITS ARE NOT USED FOR THE LENGTH OF THE
  901.   NOTE, SO THEY ARE USED FOR OTHER THINGS.
  902. - ┬IT#5 SIGNALS NO RELEASE NEEDED. - ┬IT#6 SIGNALS THAT THIS NOTE IS
  903.   APPENDED TO THE LAST ONE (NO ATTACK/ETC). - ┬IT#7 SIGNALS THAT A NEW
  904.   INSTRUMENT OR PORTAMENTO IS COMING UP.
  905.  
  906. - ╘HE SECOND BYTE IS AN OPTIONAL BYTE, AND IT HOLDS THE INSTUMENT NUMBER TO
  907.   USE OR THE PORTAMENTO VALUE (IE A BENDED NOTE). ╘HIS BYTE WILL BE NEEDED
  908.   ACCORDING TO WHETHER BIT#7 OF THE FIRST BYTE IS SET OR NOT...IE IF THE 1ST
  909.   BYTE WAS NEGATIVE, THEN THIS BYTE IS NEEDED.
  910.   - ╔F THE SECOND BYTE IS POSITIVE, THEN THIS IS THE NEW INSTRUMENT NUMBER.
  911.   - ╔F THE SECOND BYTE IS NEGATIVE, THEN THIS IS A BENDED NOTE (PORTAMENTO).
  912.     AND THE VALUE IS THE SPEED OF THE PORTAMENTO (EXCEPT FOR BITS #7 AND #0)
  913.     ┬IT #0 OF THE PORTAMENTO BYTE DETERMINES THE DIRECTION OF THE BEND.
  914.     - ┬IT#0 = 0 THEN PORTAMENTO IS UP.
  915.     - ┬IT#0 = 1 THEN PORTAMENTO IS DOWN.
  916.  
  917. - ╘HE THIRD BYTE OF THE SPECIFICATION IS THE PITCH OF THE NOTE. ┴ PITCH OF
  918.   0 IS THE LOWEST ├ POSSIBLE. ┴ PITCH OF 12 OR $├(HEX) IS THE NEXT HIGHEST
  919.   ├ ABOVE THAT. ╘HESE PITCHES ARE DENOTED FAIRLY UNIVERSALLY AS EG. '├-1' AND
  920.   FOR SHARPS EG. '─#3'. ╬OTICE THAT THIS ROUTINE USES PITCHES OF HIGHER THAN
  921.   72 ($48) WHICH IS C-6 :-)
  922.  
  923. - ╘HE FOURTH BYTE IF IT EXISTS WILL DENOTE THE END OF THE PATTERN.
  924.   IE. ╔F THE NEXT BYTE IS A $FF, THEN THIS IS THE END OF THE PATTERN.
  925.  
  926. ╬╧╘┼: ╔ HAVE LABELLED THE VARIOUS BYTES WITH NUMBERS FOR CONVENIENCE. ┬EAR
  927. IN MIND THAT SOME OF THESE ARE OPTIONAL, SO IF THE SECOND BYTE IS NOT NEEDED,
  928. THEN ╔ WILL SAY THAT THE PITCH OF THE NOTE COMING UP IS THE 'THIRD BYTE',
  929. EVEN THOUGH IT ISN'T REALLY.
  930.  
  931. ╧KAY, HERE ARE SOME EXAMPLES:
  932.  
  933. EG. $84,$04,$24 MEANS THAT THE LENGTH OF THE NOTE IS 4 (FROM THE LOWER 5 BITS
  934.     OF THE FIRST BYTE), THAT THE INSTRUMENT TO USE IS INSTRUMENT NUMBER 4
  935.     (THE SECOND BYTE, AS INDICATED BY BIT #7 OF THE FIRST BYTE), AND THAT THE
  936.     PITCH OF THE NOTE IS $24 OR C-3.
  937. EG. $─6,$98,$25,$╞╞ MEANS THAT THE LENGTH OF THE NOTE IS 22 ($16), THAT THIS
  938.     NOTE SHOULD BE APPENDED TO THE LAST, THAT THE SECOND BYTE IS A PORTAMENTO
  939.     (AS BOTH 1ST AND 2ND BYTES -VE!), THAT THE PORTAMENTO IS GOING UP (AS
  940.     BIT#0 = 0) WITH A SPEED OF 24 ($18), THAT THE PITCH OF THE NOTE IS $25
  941.     OR C#3, AND THAT THIS IS THE END OF THE PATTERN.
  942.  
  943. ╔T DOESN'T GET ANY HARDER THAN THAT!! ─ID YOU REALISE THAT THIS IS EXACTLY
  944. THE WAY THAT ╥OB ╚UBBARD MADE THE MUSIC!! ╚E WORKED OUT SOME MUSICAL IDEAS
  945. ON HIS CHEAP (MUSICAL) KEYBOARD, AND TYPED THE NOTES INTO HIS ASSEMBLER IN
  946. HEX, JUST LIKE THIS.
  947.  
  948.  
  949. 5. ╘HE INSTRUMENTS ARE AN 8 BYTE DATA STRUCTURE.
  950.  
  951.   ┘OU ARE LOOKING AT THE LABEL 'INSTR' AT THE BOTTOM OF THE SOURCECODE. ╘HE
  952. 8 BYTES WHICH COME ALONG FIRST ARE INSTRUMENT NUMNBER 0, THE NEXT 8 DEFINE
  953. INSTRUMENT NUMBER 1, ETC. ╚ERE ARE THE MEANINGS OF THE BYTES, BUT ╔ SUGGEST
  954. THAT YOU CHECK OUT YOUR PROGRAMMING MANUALS IF YOU ARE UNFAMILIAR WITH THESE:
  955.  
  956. - ┬YTE 0 IS THE PULSE WIDTH LOW BYTE, AND
  957. - ┬YTE 1 IS THE PULSE WIDTH HIGH BYTE. (ALSO SEE BYTE 7).
  958.  
  959. - ┬YTE 2 IS THE CONTROL REGISTER BYTE.
  960.   ╘HIS SPECIFIES WHICH TYPE OF SOUND SHOULD BE USED; SINE, SAWTOOTH ETC.
  961.  
  962. - ┬YTE 3 IS THE ATTACK AND DECAY VALUES, AND
  963. - ┬YTE 4 IS THE SUSTAIN AND RELEASE VALUES.
  964.   ╘HE NOTE'S VOLUME IS ALTERED ACCORDING TO THESE VALUES. ╫HEN THE ATTACK AND
  965.   DECAY ARE OVER, THE VOLUME OF THE NOTE IS HELD AT THE SUSTAIN LEVEL. ╫HEN
  966.   LENGTH OF A NOTE IS OVER, A RELEASE IS DONE THROUGH THE 'GATE' BIT IN ╙╔─.
  967.  
  968. - ┬YTE 5 IS THE VIBRATO DEPTH FOR THE INSTRUMENT.
  969.  
  970. - ┬YTE 6 IS THE PULSE SPEED.
  971.   ╘IMBRE IS CREATED BY CHANGING THE SHAPE OF THE WAVEFORM EACH 50TH OF A
  972.   SECOND, AND THIS IS THE MOST COMMON WAY OF ACHIEVING IT. ╘HE SHAPE OF
  973.   THE PULSE WAVEFORM CHANGES FROM SQUARE TO A VERY RECTANGULAR AT A SPEED
  974.   ACCORDING TO THIS BYTE.
  975.   ╬.┬. IF YOU ARE INTERESTED IN HOW THE PULSE VALUE NUMBER WORKS, THEN
  976.   E-MAIL ME SOMETIME, AS ╔ FOUND THIS OUT (EXHAUSTIVELY) A FEW DAYS AGO!
  977.  
  978. - ┬YTE 7 IS THE INSTRUMENT FX BYTE, AND IS THE MAJOR THING WHICH CHANGES
  979.   BETWEEN DIFFERENT MUSIC ROUTINES. ┼ACH BIT IN THIS BYTE DETERMINES WHETHER
  980.   THIS INSTRUMENT WILL HAVE A CERTAIN EFFECT IN IT.
  981.   - ┬IT#0 SIGNALS THAT THIS IS A DRUM. ─RUMS ARE MADE FROM A NOISE CHANNEL
  982.     AND ALSO A FAST FREQUENCY DOWN, WITH FAST DECAY. ┬ASS DRUMS USE A SQUARE
  983.     WAVE, AND ONLY THE FIRST 50TH OF A SECOND IS A NOISE CHANNEL. ╘HIS IS
  984.     THE TELL-TALE INSTRUMENT THAT GIVES AWAY A ╥OB ╚UBBARD ROUTINE! ╚IHATS
  985.     AND OTHER DRUMS USE NOISE ALL THE TIME.
  986.   - ┬IT#1 SIGNALS A 'SKYDIVE'. ╘HIS IS A SLOWER FREQUENCY DOWN, THAT ╔ THINK
  987.     SOUNDS LIKE SOMEBODY YELLING AS THEY FALL OUT OF A PLANE .. ┴╚╚╚╚HHHHGH..
  988.     ..HENCE ╔ CALL IT A SKYDIVE!!
  989.   - ┬IT#2 SIGNALS AN OCTAVE ARPEGGIO. ╔T'S A VERY LIMITED ARPEGGIO ROUTINE IN
  990.     THIS SONG. ╠ISTEN FOR THE ARPEGGIO AND THE SKYDIVE WHEN COMBINED, WHICH
  991.     IS USED ALOT IN ╚UBBARD SONGS.
  992.   - ┴LL THE OTHER BITS HAVE NO MEANING IN THIS MUSIC, BUT WERE USED ALOT IN
  993.     LATER MUSIC FOR THE FX.
  994.  
  995. ┴ BIG REASON THAT ╔ PRESENTED THIS EARLY ROUTINE, WAS BECAUSE THERE WAS NOT
  996. TOO MUCH IN THE WAY OF SPECIAL FX TO CONFUSE YOU. ┴S A RESULT, YOU CAN
  997. CONCENTRATE ON THE GUTS OF THE CODE INSTEAD OF THE SPECIAL FX :-)
  998.  
  999.  
  1000. ╚OW THE SOURCECODE WORKS:
  1001. ************************
  1002.  
  1003.   ╘HE ROUTINES AT THE TOP OF THE SOURCECODE ARE CONCERNED WITH TURNING THE
  1004. MUSIC ON AND OFF, AND YOU WILL SEE THAT THIS IS DONE THROUGH A VARIABLE CALLED
  1005. 'MSTATUS' (OR MUSIC STATUS). ╔F MSTATUS IS SET TO $├0, THEN THE MUSIC IS
  1006. TURNED OFF AND ╙╔─ IS QUIETENED, THEREAFTER MSTATUS IS SET TO $80 WHICH MEANS
  1007. THAT THE MUSIC IS STILL OFF, BUT ╙╔─ DOESN'T NEED TO BE QUIETENED AGAIN. ╫HEN
  1008. THE MUSIC IS INITIALIZED, THEN MSTATUS IS GIVEN A VALUE OF $40 WHICH KICKS IN
  1009. THE FURTHER INITIALIZATION STUFF. ╔F MSTATUS IS ANY OTHER VALUE, THEN THE
  1010. MUSIC IS BEING PLAYED. ╞OR ANY OF THE INITIALIZATION STUFF TO HAVE ANY MEANING
  1011. TO YOU, YOU OFCOURSE HAVE TO UNDERSTAND THE REST OF THE PLAYROUTINE :-)
  1012.  
  1013.   ┴FTER WE HAVE GOT PAST THE ON/OFF/INIT STUFF, WE ARE AT THE LABEL CALLED
  1014. 'CONTPLAY' AT AROUND LINE 100. ╘HE FIRST THING YOU SHOULD NOTICE IS THAT THIS
  1015. IS THE START OF A HUGE LOOP THAT IS DONE *3* TIMES - ONCE FOR EACH CHANNEL.
  1016. ╘HE LOOP REALLY *IS* HUGE, AS IT ENDS RIGHT ON THE LAST FEW LINES OF THE CODE
  1017. :-)
  1018.  
  1019.   ╬OW THAT WE ARE TALKING ABOUT ROUTINES WITHIN THE LOOP, WE ARE TALKING ABOUT
  1020. THESE ROUTINES BEING APPLIED TO THE CHANNELS INDEPENDANTLY. ╘HERE ARE 2 MAIN
  1021. ROUTINES WITHIN THE LOOP, ONE IS CALLED ╬OTE╫ORK, AND THE OTHER IS CALLED
  1022. ╙OUND╫ORK. ╬OTE╫ORK CHECKS TO SEE WHETHER A NEW NOTE IS NEEDED ON THIS
  1023. CHANNEL, AND IF IT IS, THEN THE NOTEDATA IS FETCHED AND STUFF IS INITIALIZED.
  1024. ╔F NO NOTE IS NEEDED, THEN ╙OUND╫ORK IS CALLED WHICH PROCESSES THE INSTRUMENTS
  1025. AND DOES THE PORTAMENTO.
  1026.  
  1027.   ╬OTE╫ORK FIRST CHECKS THE SPEED AT WHICH THE NOTES ARE FETCHED. ╔F THE DELAY
  1028. IS STILL OCCURRING, THEN NEW NOTES ARE NOT NEEDED AND SOUNDWORK IS CALLED.
  1029. ╬.┬. THAT THE SPEED FOR ═ONTY ON THE ╥UN IS 1, WHICH MEANS THAT A NOTE OF
  1030. LENGTH $1F WILL LAST FOR 64 CALLS TO THE ROUTINE (IE JUST OVER A SECOND). ╔F
  1031. THE SPEED OF THE SONG IS RESET, THEN ╬OTE╫ORK DECREMENTS THE LENGTH OF THE
  1032. CURRENT NOTE. ╫HEN THE LENGTH OF THE CURRENT NOTE HITS $FF (-1) THEN A NEW
  1033. NOTE IS NEEDED, OTHERWISE ╙OUND╫ORK IS JUMPED TO.
  1034.  
  1035.   ╘HE DATA FOR A NEW NOTE IS COLLECTED AT THE LABEL 'GETNEWNOTE'. ╔N THE
  1036. SIMPLEST CASE, THIS INVOLVES GETTING THE NEXT BYTES OF DATA FROM THE CURRENT
  1037. PATTERN ON THIS CHANNEL, BUT IF THE END OF THE PATTERN IS REACHED, THEN THE
  1038. NEXT PATTERN NUMBER IS FETCHED BY REFERENCE TO THE CURRENT POSITION WITHIN
  1039. THIS CHANNEL'S TRACK. ╔N AN EVEN MORE COMPLEX SITUATION, THE END OF A TRACK IS
  1040. REACHED, AND THE CURRENT POSITION NEEDS TO BE RESET TO 0 BEFORE THE NEXT
  1041. PATTERN NUMBER CAN BE FOUND.
  1042.  
  1043.   ┘OU CAN SEE QUITE CLEARLY IN THIS PART OF THE ROUTINE WHERE THE LENGTH OF
  1044. THE NOTE IS COLLECTED, AND IT IS DETERMINED WHETHER A 2ND BYTE IS NEEDED,
  1045. WHERE THE PITCH IS COLLECTED, AND THE END OF THE SONG CHECKED. ┘OU CAN ALSO
  1046. SEE WHERE SOME OF THE DATA IS COLLECTED FROM THE CURRENT INSTRUMENT AND JAMMED
  1047. INTO THE ╙╔─ REGISTERS.
  1048.  
  1049.   ╙OUND╫ORK IS CALLED IF NO NEW NOTES ARE NEEDED, AND IT PROCESSES THE
  1050. INSTRUMENTS AND DOES THE PORTAMENTO ETC. ╘HIS PART OF THE ROUTINE IS NEATLY
  1051. EXPRESSED IN SECTIONS WHICH ARE REALLY WELL COMMENTED AND QUITE EASY TO
  1052. UNDERSTAND.
  1053.  
  1054. - ╘HE FIRST THING THAT OCCURS IN ╙OUND╫ORK IS THAT THE 'GATE BIT' OF ╙╔─ IS
  1055.   SET WHEN THE LENGTH OF THE NOTE IS OVER - THIS CAUSES A RELEASE OF THE NOTE.
  1056.  
  1057. - ╘HE VIBRATO ROUTINE IS QUITE INEFFICIENT, BUT IT'S PRETTY GOOD FOR 1985!
  1058.   ╧FCOURSE VIBRATO IS IMPLEMENTED BY RAISING AND LOWERING THE PITCH OF THE
  1059.   NOTE EVER-SO-SLIGHTLY CAUSING THE NOTE TO 'FLOAT'. ╘HE AMOUNT OF THE
  1060.   VIBRATO IS DETERMINED IN THE CURRENT INSTRUMENT.
  1061.  
  1062. - ╘HE PULSEWORK ROUTINE CHANGES THE PULSEWIDTH BETWEEN SQUARE WAVE AND VERY
  1063.   RECTANGULAR WAVE ACCORDING TO THE PULSESPEED IN THE CURRENT INSTRUMENT.
  1064.   (IE. IT CHANGES THE SOUND OF THE INSTRUMENT AND THUS ALTERS THE 'TIMBRE')
  1065.   ╘HE ROUTINE GOES BACKWARDS AND FORWARDS BETWEEN THE TWO; AND SWITCHES
  1066.   WHEN ONE EXTREMITY IS REACHED. ╔T'S INTERESTING TO NOTE THAT THE CURRENT
  1067.   VALUES OF THE PULSE WIDTH ARE ACTUALLY STORED IN THE INSTRUMENT :-)
  1068.  
  1069. - ╨ORTAMENTO IS ACHIEVED BY ADDING/SUBTRACTING AN AMOUNT OF FREQUENCY TO
  1070.   THE CURRENT FREQUENCY EACH TIME THIS PART OF THE ROUTINE IS CALLED.
  1071.  
  1072. - ╘HE INSTRUMENT FX ROUTINES ARE ALSO REALLY EASY TO FIGURE OUT, AS THEY ARE
  1073.   WELL COMMENTED. ┬OTH THE DRUMS AND THE SKYDIVE DO A VERY FAST FREQUENCY
  1074.   DOWN, SO IT IS THE MOST SIGNIFICANT BYTE OF THE FREQUENCY WHICH IS REDUCED
  1075.   .. AND NOT 16-BIT MATHS (MATH?!) ╘HE ARPEGGIO IS ONLY AN OCTAVE ARPEGGIO,
  1076.   SO FOR THE FIRST 50TH OF A SECOND, THE CURRENT NOTE IS PLAYED, AND FOR
  1077.   THE NEXT 50TH OF A SECOND, CURRENT NOTE+12 IS PLAYED, FOLLOWED BY THE
  1078.   CURRENT NOTE AGAIN ETC.
  1079.   ( ╔F YOU DON'T KNOW WHAT AN ARPEGGIO IS..IT'S GENERALLY WHEN THE NOTES OF )
  1080.   ( A CHORD ARE PLAYED INDIVIDUALLY IN A RAPID SUCCESSION. ╔T PRODUCES A    )
  1081.   ( 'FULL' SOUND DEPENDING ON THE SPEED OF THE ARPEGGIO. ╔N MOST CASES THE  )
  1082.   ( NOTE IS CHANGED 50 TIMES PER SECOND, WHICH GIVES A VERY NICE SOUND. ╔F  )
  1083.   ( YOU HAVE LISTENED TO SOME COMPUTER MUSIC, THEN YOU WILL HAVE DEFINATELY )
  1084.   ( LISTENED TO AN ARPEGGIOS ALL THE TIME, EVEN IF YOU DON'T REALIZE IT!    )
  1085.  
  1086.  
  1087. ╞INAL ╘HOUGHTS:
  1088. **************
  1089.  
  1090.   *┬OUNCE* ╔'M FINALLY NEAR THE END OF THIS ARTICLE! ╔T HAS BEEN ALOT OF WORK
  1091. TO TRY TO EXPLAIN THIS ROUTINE, BUT ╔'M GLAD THAT ╔'VE DONE IT *GRIN* ╔F YOU
  1092. HAVE ANY QUESTIONS THEN PLEASE FEEL FREE TO E-MAIL ME, OR EVEN E-MAIL ├RAIG IF
  1093. IT'S AFTER ┴UGUST 1993 AND ╔'LL MAKE SURE THAT ╔ LEAVE A FORWARDING ADDRESS
  1094. WITH HIM. ┴LSO, PLEASE FEEL FREE TO E-MAIL ME AND TELL ME WHAT YOU THINK OF
  1095. THIS ARTICLE. ╔ WILL ONLY BE BOTHERED WRITING MORE OF THE SAME IF ╔ KNOW THAT
  1096. SOMEONE IS FINDING THEM USEFUL/INTERESTING. ┴LSO E-MAIL ME IF YOU ARE
  1097. INTERESTED IN ┴MIGA OR ╙╘ MUSIC TOO, AS ╔'VE DONE ALOT ON BOTH OF THOSE
  1098. MACHINES.
  1099.  
  1100.   ╔'M NOT SURE WHETHER ├RAIG WILL BE PUTTING THE ACTUAL SOURCECODE BELOW THIS
  1101. TEXT, OR IN SOME KIND OF ┴PPENDIX. ╔N EITHER CASE, ╔ ╙╚┴╠╠ TAKE ALL LEGAL
  1102. RESPONSIBILTY FOR PUBLISHING ╥OB ╚UBBARD'S ROUTINE. ├RAIG WAS QUITE RELUCTANT
  1103. TO PUBLISH THE ROUTINE IN HIS NET-MAG BECAUSE OF COPYRIGHT REASONS. ┴S A
  1104. POST-GRADUATE LAW STUDENT THAT WILL BE WORKING AS A COMMERCIAL LAWYER
  1105. (ATTOURNEY FOR ┴MERICANS :) SPECIALIZING IN COPYRIGHT/PATENTS FOR COMPUTER
  1106. SOFTWARE/HARDWARE STARTING ┴UGUST THIS YEAR, ╔ DON'T BELIEVE THAT THERE ARE
  1107. ANY PRACTICAL LEGAL CONSEQUENCES FOR ME.
  1108.  
  1109.   ╔ WOULD HAVE GIVEN AN ARM OR A LEG FOR A COMMENTED ╥OB ╚UBBARD SOURCECODE IN
  1110. THE PAST, SO ╔ HOPE YOU ENJOY THIS VALUABLE OFFERING.
  1111. -----------------------------------------------------------------------------
  1112. ;ROB HUBBARD
  1113. ;MONTY ON THE RUN MUSIC DRIVER
  1114.  
  1115. ;THIS PLAYER WAS USED (WITH SMALL MODS)
  1116. ;FOR HIS FIRST APPROX 30 MUSIX
  1117.  
  1118. .ORG $8000
  1119. .OBJ MOTR
  1120.  
  1121.  JMP INITMUSIC
  1122.  JMP PLAYMUSIC
  1123.  JMP MUSICOFF
  1124.  
  1125.  
  1126. ;====================================
  1127. ;INIT MUSIC
  1128.  
  1129. INITMUSIC =*
  1130.  
  1131.   LDA #$00         ;MUSIC NUM
  1132.   LDY #$00
  1133.   ASL
  1134.   STA TEMPSTORE
  1135.   ASL
  1136.   CLC
  1137.   ADC TEMPSTORE    ;NOW MUSIC NUM*6
  1138.   TAX
  1139.  
  1140. - LDA SONGS,X      ;COPY PTRS TO THIS
  1141.   STA CURRTRKHI,Y  ;MUSIC'S TRACKS TO
  1142.   INX              ;CURRENT TRACKS
  1143.   INY
  1144.   CPY #$06
  1145.   BNE -
  1146.  
  1147.   LDA #$00         ;CLEAR CONTROL REGS
  1148.   STA $D404
  1149.   STA $D40B
  1150.   STA $D412
  1151.   STA $D417
  1152.  
  1153.   LDA #$0F         ;FULL VOLUME
  1154.   STA $D418
  1155.  
  1156.   LDA #$40         ;FLAG INIT MUSIC
  1157.   STA MSTATUS
  1158.  
  1159.   RTS
  1160.  
  1161.  
  1162. ;====================================
  1163. ;MUSIC OFF
  1164.  
  1165. MUSICOFF =*
  1166.  
  1167.   LDA #$C0         ;FLAG MUSIC OFF
  1168.   STA MSTATUS
  1169.   RTS
  1170.  
  1171.  
  1172. ;====================================
  1173. ;PLAY MUSIC
  1174.  
  1175. PLAYMUSIC =*
  1176.  
  1177.   INC COUNTER
  1178.  
  1179.   BIT MSTATUS      ;TEST MUSIC STATUS
  1180.   BMI MOFF         ;$80 AND $C0 IS OFF
  1181.   BVC CONTPLAY     ;$40 INIT, ELSE PLAY
  1182.  
  1183.  
  1184. ;==========
  1185. ;INIT THE SONG (MSTATUS $40)
  1186.  
  1187.   LDA #$00         ;INIT COUNTER
  1188.   STA COUNTER
  1189.  
  1190.   LDX #3-1
  1191. - STA POSOFFSET,X  ;INIT POS OFFSETS
  1192.   STA PATOFFSET,X  ;INIT PAT OFFSETS
  1193.   STA LENGTHLEFT,X ;GET NOTE RIGHT AWAY
  1194.   STA NOTENUM,X
  1195.   DEX
  1196.   BPL -
  1197.  
  1198.   STA MSTATUS      ;SIGNAL MUSIC PLAY
  1199.   JMP CONTPLAY
  1200.  
  1201.  
  1202. ;==========
  1203. ;MUSIC IS OFF (MSTATUS $80 OR $C0)
  1204.  
  1205. MOFF =*
  1206.  
  1207.   BVC +            ;IF MSTATUS $C0 THEN
  1208.   LDA #$00
  1209.   STA $D404        ;KILL VOICE 1,2,3
  1210.   STA $D40B        ;CONTROL REGISTERS
  1211.   STA $D412
  1212.  
  1213.   LDA #$0F         ;FULL VOLUME STILL
  1214.   STA $D418
  1215.  
  1216.   LDA #$80         ;FLAG NO NEED TO KILL
  1217.   STA MSTATUS      ;SOUND NEXT TIME
  1218.  
  1219. + JMP MUSICEND     ;END
  1220.  
  1221.  
  1222. ;==========
  1223. ;MUSIC IS PLAYING (MSTATUS OTHERWISE)
  1224.  
  1225. CONTPLAY =*
  1226.  
  1227.   LDX #3-1         ;NUMBER OF CHANELS
  1228.  
  1229.   DEC SPEED        ;CHECK THE SPEED
  1230.   BPL MAINLOOP
  1231.  
  1232.   LDA RESETSPD     ;RESET SPEED IF NEEDED
  1233.   STA SPEED
  1234.  
  1235.  
  1236. MAINLOOP =*
  1237.  
  1238.   LDA REGOFFSETS,X ;SAVE OFFSET TO REGS
  1239.   STA TMPREGOFST   ;FOR THIS CHANNEL
  1240.   TAY
  1241.  
  1242.  
  1243. ;CHECK WHETHER A NEW NOTE IS NEEDED
  1244.  
  1245.   LDA SPEED        ;IF SPEED NOT RESET
  1246.   CMP RESETSPD     ;THEN SKIP NOTEWORK
  1247.   BEQ CHECKNEWNOTE
  1248.   JMP VIBRATO
  1249.  
  1250. CHECKNEWNOTE =*
  1251.  
  1252.   LDA CURRTRKHI,X  ;PUT BASE ADDR.W OF
  1253.   STA $02          ;THIS TRACK IN $2
  1254.   LDA CURRTRKLO,X
  1255.   STA $03
  1256.  
  1257.   DEC LENGTHLEFT,X ;CHECK WHETHER A NEW
  1258.   BMI GETNEWNOTE   ;NOTE IS NEEDED
  1259.  
  1260.   JMP SOUNDWORK    ;NO NEW NOTE NEEDED
  1261.  
  1262.  
  1263. ;==========
  1264. ;NOTEWORK
  1265. ;A NEW NOTE IS NEEDED. GET THE PATTERN
  1266. ;NUMBER/CC FROM THIS POSITION
  1267.  
  1268. GETNEWNOTE =*
  1269.  
  1270.   LDY POSOFFSET,X  ;GET THE DATA FROM
  1271.   LDA ($02),Y      ;THE CURRENT POSITION
  1272.  
  1273.   CMP #$FF         ;POS $FF RESTARTS
  1274.   BEQ RESTART
  1275.  
  1276.   CMP #$FE         ;POS $FE STOPS MUSIC
  1277.   BNE GETNOTEDATA  ;ON ALL CHANNELS
  1278.   JMP MUSICEND
  1279.  
  1280. ;CC OF $FF RESTARTS THIS TRACK FROM THE
  1281. ;FIRST POSITION
  1282.  
  1283. RESTART =*
  1284.  
  1285.   LDA #$00         ;GET NOTE IMMEDIATELY
  1286.   STA LENGTHLEFT,X ;AND RESET PAT,POS
  1287.   STA POSOFFSET,X
  1288.   STA PATOFFSET,X
  1289.   JMP GETNEWNOTE
  1290.  
  1291.  
  1292. ;GET THE NOTE DATA FROM THIS PATTERN
  1293.  
  1294. GETNOTEDATA =*
  1295.  
  1296.   TAY
  1297.   LDA PATPTL,Y     ;PUT BASE ADDR.W OF
  1298.   STA $04          ;THE PATTERN IN $4
  1299.   LDA PATPTH,Y
  1300.   STA $05
  1301.  
  1302.   LDA #$00         ;DEFAULT NO PORTAMENTO
  1303.   STA PORTAVAL,X
  1304.  
  1305.   LDY PATOFFSET,X  ;GET OFFSET INTO PTN
  1306.  
  1307.   LDA #$FF         ;DEFAULT NO APPEND
  1308.   STA APPENDFL
  1309.  
  1310. ;1ST BYTE IS THE LENGTH OF THE NOTE 0-31
  1311. ;BIT5 SIGNALS NO RELEASE (SEE SNDWORK)
  1312. ;BIT6 SIGNALS APPENDED NOTE
  1313. ;BIT7 SIGNALS A NEW INSTRUMENT
  1314. ;     OR PORTAMENTO COMING UP
  1315.  
  1316.   LDA ($04),Y      ;GET LENGTH OF NOTE
  1317.   STA SAVELNTHCC,X
  1318.   STA TEMPLNTHCC
  1319.   AND #$1F
  1320.   STA LENGTHLEFT,X
  1321.  
  1322.   BIT TEMPLNTHCC   ;TEST FOR APPEND
  1323.   BVS APPENDNOTE
  1324.  
  1325.   INC PATOFFSET,X  ;PT TO NEXT DATA
  1326.  
  1327.   LDA TEMPLNTHCC   ;2ND BYTE NEEDED?
  1328.   BPL GETPITCH
  1329.  
  1330. ;2ND BYTE NEEDED AS 1ST BYTE NEGATIVE
  1331. ;2ND BYTE IS THE INSTRUMENT NUMBER(+VE)
  1332. ;OR PORTAMENTO SPEED(-VE)
  1333.  
  1334.   INY
  1335.   LDA ($04),Y      ;GET INSTR/PORTAMENTO
  1336.   BPL +
  1337.  
  1338.   STA PORTAVAL,X   ;SAVE PORTAMENTO VAL
  1339.   JMP ++
  1340.  
  1341. + STA INSTRNR,X    ;SAVE INSTR NR
  1342.  
  1343. + INC PATOFFSET,X
  1344.  
  1345. ;3RD BYTE IS THE PITCH OF THE NOTE
  1346. ;GET THE 'BASE FREQUENCY' HERE
  1347.  
  1348. GETPITCH =*
  1349.  
  1350.   INY
  1351.   LDA ($04),Y      ;GET PITCH OF NOTE
  1352.   STA NOTENUM,X
  1353.   ASL              ;PITCH*2
  1354.   TAY
  1355.   LDA FREQUENZLO,Y ;SAVE THE APPROPRIATE
  1356.   STA TEMPFREQ     ;BASE FREQUENCY
  1357.   LDA FREQUENZHI,Y
  1358.   LDY TMPREGOFST
  1359.   STA $D401,Y
  1360.   STA SAVEFREQHI,X
  1361.   LDA TEMPFREQ
  1362.   STA $D400,Y
  1363.   STA SAVEFREQLO,X
  1364.   JMP +
  1365.  
  1366. APPENDNOTE =*
  1367.  
  1368.   DEC APPENDFL     ;CLEVER EH?
  1369.  
  1370.  
  1371. ;FETCH ALL THE INITIAL VALUES FROM THE
  1372. ;INSTRUMENT DATA STRUCTURE
  1373.  
  1374. + LDY TMPREGOFST
  1375.   LDA INSTRNR,X    ;INSTR NUM
  1376.   STX TEMPSTORE
  1377.   ASL              ;INSTR NUM*8
  1378.   ASL
  1379.   ASL
  1380.   TAX
  1381.  
  1382.   LDA INSTR+2,X    ;GET CONTROL REG VAL
  1383.   STA TEMPCTRL
  1384.   LDA INSTR+2,X
  1385.   AND APPENDFL     ;IMPLEMENT APPEND
  1386.   STA $D404,Y
  1387.  
  1388.   LDA INSTR+0,X    ;GET PULSE WIDTH LO
  1389.   STA $D402,Y
  1390.  
  1391.   LDA INSTR+1,X    ;GET PULSE WIDTH HI
  1392.   STA $D403,Y
  1393.  
  1394.   LDA INSTR+3,X    ;GET ATTACK/DECAY
  1395.   STA $D405,Y
  1396.  
  1397.   LDA INSTR+4,X    ;GET SUSTAIN/RELEASE
  1398.   STA $D406,Y
  1399.  
  1400.   LDX TEMPSTORE    ;SAVE CONTROL REG VAL
  1401.   LDA TEMPCTRL
  1402.   STA VOICECTRL,X
  1403.  
  1404.  
  1405. ;4TH BYTE CHECKS FOR THE END OF PATTERN
  1406. ;IF EOP FOUND, INC THE POSITION AND
  1407. ;RESET PATOFFSET FOR NEW PATTERN
  1408.  
  1409.   INC PATOFFSET,X  ;PREVIEW 4TH BYTE
  1410.   LDY PATOFFSET,X
  1411.   LDA ($04),Y
  1412.  
  1413.   CMP #$FF         ;CHECK FOR EOP
  1414.   BNE +
  1415.  
  1416.   LDA #$00         ;END OF PAT REACHED
  1417.   STA PATOFFSET,X  ;INC POSITION FOR
  1418.   INC POSOFFSET,X  ;THE NEXT TIME
  1419.  
  1420. + JMP LOOPCONT
  1421.  
  1422.  
  1423. ;==========
  1424. ;SOUNDWORK
  1425. ;THE INSTRUMENT AND EFFECTS PROCESSING
  1426. ;ROUTINE WHEN NO NEW NOTE WAS NEEDED
  1427.  
  1428. SOUNDWORK =*
  1429.  
  1430. ;RELEASE ROUTINE
  1431. ;SET OFF A RELEASE WHEN THE LENGTH OF
  1432. ;THE NOTE IS EXCEEDED
  1433. ;BIT4 OF THE 1ST NOTE-BYTE CAN SPECIFY
  1434. ;FOR NO RELEASE
  1435.  
  1436.   LDY TMPREGOFST
  1437.  
  1438.   LDA SAVELNTHCC,X ;CHECK FOR NO RELEASE
  1439.   AND #$20         ;SPECIFIED
  1440.   BNE VIBRATO
  1441.  
  1442.   LDA LENGTHLEFT,X ;CHECK FOR LENGTH OF
  1443.   BNE VIBRATO      ;EXCEEDED
  1444.  
  1445.   LDA VOICECTRL,X  ;LENGTH EXCEEDED SO
  1446.   AND #$FE         ;START THE RELEASE
  1447.   STA $D404,Y      ;AND KILL ADSR
  1448.   LDA #$00
  1449.   STA $D405,Y
  1450.   STA $D406,Y
  1451.  
  1452.  
  1453. ;VIBRATO ROUTINE
  1454. ;(DOES ALOT OF WORK)
  1455.  
  1456. VIBRATO =*
  1457.  
  1458.   LDA INSTRNR,X    ;INSTR NUM
  1459.   ASL
  1460.   ASL
  1461.   ASL              ;INSTR NUM*8
  1462.   TAY
  1463.   STY INSTNUMBY8   ;SAVE INSTR NUM*8
  1464.  
  1465.   LDA INSTR+7,Y    ;GET INSTR FX BYTE
  1466.   STA INSTRFX
  1467.  
  1468.   LDA INSTR+6,Y    ;GET PULSE SPEED
  1469.   STA PULSEVALUE
  1470.  
  1471.   LDA INSTR+5,Y    ;GET VIBRATO DEPTH
  1472.   STA VIBRDEPTH
  1473.   BEQ PULSEWORK    ;CHECK FOR NO VIBRATO
  1474.  
  1475.   LDA COUNTER      ;THIS IS CLEVER!!
  1476.   AND #7           ;THE COUNTER'S TURNED
  1477.   CMP #4           ;INTO AN OSCILLATING
  1478.   BCC +            ;VALUE (01233210)
  1479.   EOR #7
  1480. + STA OSCILATVAL
  1481.  
  1482.   LDA NOTENUM,X    ;GET BASE NOTE
  1483.   ASL              ;NOTE*2
  1484.   TAY              ;GET DIFF BTW NOTE
  1485.   SEC              ;AND NOTE+1 FREQUENCY
  1486.   LDA FREQUENZLO+2,Y
  1487.   SBC FREQUENZLO,Y
  1488.   STA TMPVDIFLO
  1489.   LDA FREQUENZHI+2,Y
  1490.   SBC FREQUENZHI,Y
  1491.  
  1492. - LSR              ;DIVIDE DIFFERENCE BY
  1493.   ROR TMPVDIFLO    ;2 FOR EACH VIBRDEPTH
  1494.   DEC VIBRDEPTH
  1495.   BPL -
  1496.   STA TMPVDIFHI
  1497.  
  1498.   LDA FREQUENZLO,Y ;SAVE NOTE FREQUENCY
  1499.   STA TMPVFRQLO
  1500.   LDA FREQUENZHI,Y
  1501.   STA TMPVFRQHI
  1502.  
  1503.   LDA SAVELNTHCC,X ;NO VIBRATO IF NOTE
  1504.   AND #$1F         ;LENGTH LESS THAN 8
  1505.   CMP #8
  1506.   BCC +
  1507.  
  1508.   LDY OSCILATVAL
  1509.  
  1510. - DEY              ;DEPENDING ON THE OSC
  1511.   BMI +            ;VALUE, ADD THE VIBR
  1512.   CLC              ;FREQ THAT MANY TIMES
  1513.   LDA TMPVFRQLO    ;TO THE BASE FREQ
  1514.   ADC TMPVDIFLO
  1515.   STA TMPVFRQLO
  1516.   LDA TMPVFRQHI
  1517.   ADC TMPVDIFHI
  1518.   STA TMPVFRQHI
  1519.   JMP -
  1520.  
  1521. + LDY TMPREGOFST   ;SAVE THE FINAL
  1522.   LDA TMPVFRQLO    ;FREQUENCIES
  1523.   STA $D400,Y
  1524.   LDA TMPVFRQHI
  1525.   STA $D401,Y
  1526.  
  1527.  
  1528. ;PULSE-WIDTH TIMBRE ROUTINE
  1529. ;DEPENDING ON THE CONTROL/SPEED BYTE IN
  1530. ;THE INSTRUMENT DATASTRUCTURE, THE PULSE
  1531. ;WIDTH IS OF COURSE INC/DECREMENTED TO
  1532. ;PRODUCE TIMBRE
  1533.  
  1534. ;STRANGELY THE DELAY VALUE IS ALSO THE
  1535. ;SIZE OF THE INC/DECREMENTS
  1536.  
  1537. PULSEWORK =*
  1538.  
  1539.   LDA PULSEVALUE   ;CHECK FOR PULSEWORK
  1540.   BEQ PORTAMENTO   ;NEEDED THIS INSTR
  1541.  
  1542.   LDY INSTNUMBY8
  1543.   AND #$1F
  1544.   DEC PULSEDELAY,X ;PULSEDELAY-1
  1545.   BPL PORTAMENTO
  1546.  
  1547.   STA PULSEDELAY,X ;RESET PULSEDELAY
  1548.  
  1549.   LDA PULSEVALUE   ;RESTRICT PULSE SPEED
  1550.   AND #$E0         ;FROM $00-$1F
  1551.   STA PULSESPEED
  1552.  
  1553.   LDA PULSEDIR,X   ;PULSEDIR 0 IS UP AND
  1554.   BNE PULSEDOWN    ;1 IS DOWN
  1555.  
  1556.   LDA PULSESPEED   ;PULSE WIDTH UP
  1557.   CLC
  1558.   ADC INSTR+0,Y    ;ADD THE PULSESPEED
  1559.   PHA              ;TO THE PULSE WIDTH
  1560.   LDA INSTR+1,Y
  1561.   ADC #$00
  1562.   AND #$0F
  1563.   PHA
  1564.   CMP #$0E         ;GO PULSEDOWN WHEN
  1565.   BNE DUMPULSE     ;THE PULSE VALUE
  1566.   INC PULSEDIR,X   ;REACHES MAX ($0EXX)
  1567.   JMP DUMPULSE
  1568.  
  1569. PULSEDOWN =*
  1570.  
  1571.   SEC              ;PULSE WIDTH DOWN
  1572.   LDA INSTR+0,Y
  1573.   SBC PULSESPEED   ;SUB THE PULSESPEED
  1574.   PHA              ;FROM THE PULSE WIDTH
  1575.   LDA INSTR+1,Y
  1576.   SBC #$00
  1577.   AND #$0F
  1578.   PHA
  1579.   CMP #$08         ;GO PULSEUP WHEN
  1580.   BNE DUMPULSE     ;THE PULSE VALUE
  1581.   DEC PULSEDIR,X   ;REACHES MIN ($08XX)
  1582.  
  1583. DUMPULSE =*
  1584.  
  1585.   STX TEMPSTORE    ;DUMP PULSE WIDTH TO
  1586.   LDX TMPREGOFST   ;CHIP AND BACK INTO
  1587.   PLA              ;THE INSTR DATA STR
  1588.   STA INSTR+1,Y
  1589.   STA $D403,X
  1590.   PLA
  1591.   STA INSTR+0,Y
  1592.   STA $D402,X
  1593.   LDX TEMPSTORE
  1594.  
  1595.  
  1596. ;PORTAMENTO ROUTINE
  1597. ;PORTAMENTO COMES FROM THE SECOND BYTE
  1598. ;IF IT'S A NEGATIVE VALUE
  1599.  
  1600. PORTAMENTO =*
  1601.  
  1602.   LDY TMPREGOFST
  1603.   LDA PORTAVAL,X   ;CHECK FOR PORTAMENTO
  1604.   BEQ DRUMS        ;NONE
  1605.  
  1606.   AND #$7E         ;TOAD UNWANTED BITS
  1607.   STA TEMPSTORE
  1608.  
  1609.   LDA PORTAVAL,X   ;BIT0 SIGNALS UP/DOWN
  1610.   AND #$01
  1611.   BEQ PORTUP
  1612.  
  1613.   SEC              ;PORTAMENTO DOWN
  1614.   LDA SAVEFREQLO,X ;SUB PORTAVAL FROM
  1615.   SBC TEMPSTORE    ;CURRENT FREQUENCY
  1616.   STA SAVEFREQLO,X
  1617.   STA $D400,Y
  1618.   LDA SAVEFREQHI,X
  1619.   SBC #$00         ;(WORD ARITHMETIC)
  1620.   STA SAVEFREQHI,X
  1621.   STA $D401,Y
  1622.   JMP DRUMS
  1623.  
  1624. PORTUP =*
  1625.  
  1626.   CLC              ;PORTAMENTO UP
  1627.   LDA SAVEFREQLO,X ;ADD PORTVAL TO
  1628.   ADC TEMPSTORE    ;CURRENT FREQUENCY
  1629.   STA SAVEFREQLO,X
  1630.   STA $D400,Y
  1631.   LDA SAVEFREQHI,X
  1632.   ADC #$00
  1633.   STA SAVEFREQHI,X
  1634.   STA $D401,Y
  1635.  
  1636.  
  1637. ;BIT0 INSTRFX ARE THE DRUM ROUTINES
  1638. ;THE ACTUAL DRUM TIMBRE DEPENDS ON THE
  1639. ;CRTL REGISTER VALUE FOR THE INSTRUMENT:
  1640. ;CTRLREG 0 IS ALWAYS NOISE
  1641. ;CTRLREG X IS NOISE FOR 1ST VBL AND X
  1642. ;FROM THEN ON
  1643.  
  1644. ;SEE THAT THE DRUM IS MADE BY RAPID HI
  1645. ;TO LOW FREQUENCY SLIDE WITH FAST ATTACK
  1646. ;AND DECAY
  1647.  
  1648. DRUMS =*
  1649.  
  1650.   LDA INSTRFX      ;CHECK IF DRUMS
  1651.   AND #$01         ;NEEDED THIS INSTR
  1652.   BEQ SKYDIVE
  1653.  
  1654.   LDA SAVEFREQHI,X ;DON'T BOTHER IF FREQ
  1655.   BEQ SKYDIVE      ;CAN'T GO ANY LOWER
  1656.  
  1657.   LDA LENGTHLEFT,X ;OR IF THE NOTE HAS
  1658.   BEQ SKYDIVE      ;FINISHED
  1659.  
  1660.   LDA SAVELNTHCC,X ;CHECK IF THIS IS THE
  1661.   AND #$1F         ;FIRST VBL FOR THIS
  1662.   SEC              ;INSTRUMENT-NOTE
  1663.   SBC #$01
  1664.   CMP LENGTHLEFT,X
  1665.   LDY TMPREGOFST
  1666.   BCC FIRSTIME
  1667.  
  1668.   LDA SAVEFREQHI,X ;NOT THE FIRST TIME
  1669.   DEC SAVEFREQHI,X ;SO DEC FREQHI FOR
  1670.   STA $D401,Y      ;DRUM SOUND
  1671.  
  1672.   LDA VOICECTRL,X  ;IF CTRLREG IS 0 THEN
  1673.   AND #$FE         ;NOISE IS USED ALWAYS
  1674.   BNE DUMPCTRL
  1675.  
  1676. FIRSTIME =*
  1677.  
  1678.   LDA SAVEFREQHI,X ;NOISE IS USED FOR
  1679.   STA $D401,Y      ;THE FIRST VBL ALSO
  1680.   LDA #$80         ;(SET NOISE)
  1681.  
  1682. DUMPCTRL =*
  1683.  
  1684.   STA $D404,Y
  1685.  
  1686.  
  1687. ;BIT1 INSTRFX IS THE SKYDIVE
  1688. ;A LONG PORTAMENTO-DOWN FROM THE NOTE
  1689. ;TO ZEROFREQ
  1690.  
  1691. SKYDIVE =*
  1692.  
  1693.   LDA INSTRFX      ;CHECK IF SKYDIVE
  1694.   AND #$02         ;NEEDED THIS INSTR
  1695.   BEQ OCTARP
  1696.  
  1697.   LDA COUNTER      ;EVERY 2ND VBL
  1698.   AND #$01
  1699.   BEQ OCTARP
  1700.  
  1701.   LDA SAVEFREQHI,X ;CHECK IF SKYDIVE
  1702.   BEQ OCTARP        ;ALREADY COMPLETE
  1703.  
  1704.   DEC SAVEFREQHI,X ;DECR AND SAVE THE
  1705.   LDY TMPREGOFST   ;HIGH BYTE FREQ
  1706.   STA $D401,Y
  1707.  
  1708.  
  1709. ;BIT2 INSTRFX IS AN OCTAVE ARPEGGIO
  1710. ;PRETTY TAME HUH?
  1711.  
  1712. OCTARP =*
  1713.  
  1714.   LDA INSTRFX      ;CHECK IF ARPT NEEDED
  1715.   AND #$04
  1716.   BEQ LOOPCONT
  1717.  
  1718.   LDA COUNTER      ;ONLY 2 ARPT VALUES
  1719.   AND #$01
  1720.   BEQ +
  1721.  
  1722.   LDA NOTENUM,X    ;ODD, NOTE+12
  1723.   CLC
  1724.   ADC #$0C
  1725.   JMP ++
  1726.  
  1727. + LDA NOTENUM,X    ;EVEN, NOTE
  1728.  
  1729. + ASL              ;DUMP THE CORRESPONDING
  1730.   TAY              ;FREQUENCIES
  1731.   LDA FREQUENZLO,Y
  1732.   STA TEMPFREQ
  1733.   LDA FREQUENZHI,Y
  1734.   LDY TMPREGOFST
  1735.   STA $D401,Y
  1736.   LDA TEMPFREQ
  1737.   STA $D400,Y
  1738.  
  1739.  
  1740. ;==========
  1741. ;END OF DBF LOOP
  1742.  
  1743. LOOPCONT =*
  1744.  
  1745.   DEX              ;DBF MAINLOOP
  1746.   BMI MUSICEND
  1747.   JMP MAINLOOP
  1748.  
  1749. MUSICEND =*
  1750.  
  1751.   RTS
  1752.  
  1753.  
  1754. ;====================================
  1755. ;FREQUENZ DATA
  1756. ;====================================
  1757.  
  1758. FREQUENZLO .BYT $16
  1759. FREQUENZHI .BYT $01
  1760.  .BYT $27,$01,$38,$01,$4B,$01
  1761.  .BYT $5F,$01,$73,$01,$8A,$01,$A1,$01
  1762.  .BYT $BA,$01,$D4,$01,$F0,$01,$0E,$02
  1763.  .BYT $2D,$02,$4E,$02,$71,$02,$96,$02
  1764.  .BYT $BD,$02,$E7,$02,$13,$03,$42,$03
  1765.  .BYT $74,$03,$A9,$03,$E0,$03,$1B,$04
  1766.  .BYT $5A,$04,$9B,$04,$E2,$04,$2C,$05
  1767.  .BYT $7B,$05,$CE,$05,$27,$06,$85,$06
  1768.  .BYT $E8,$06,$51,$07,$C1,$07,$37,$08
  1769.  .BYT $B4,$08,$37,$09,$C4,$09,$57,$0A
  1770.  .BYT $F5,$0A,$9C,$0B,$4E,$0C,$09,$0D
  1771.  .BYT $D0,$0D,$A3,$0E,$82,$0F,$6E,$10
  1772.  .BYT $68,$11,$6E,$12,$88,$13,$AF,$14
  1773.  .BYT $EB,$15,$39,$17,$9C,$18,$13,$1A
  1774.  .BYT $A1,$1B,$46,$1D,$04,$1F,$DC,$20
  1775.  .BYT $D0,$22,$DC,$24,$10,$27,$5E,$29
  1776.  .BYT $D6,$2B,$72,$2E,$38,$31,$26,$34
  1777.  .BYT $42,$37,$8C,$3A,$08,$3E,$B8,$41
  1778.  .BYT $A0,$45,$B8,$49,$20,$4E,$BC,$52
  1779.  .BYT $AC,$57,$E4,$5C,$70,$62,$4C,$68
  1780.  .BYT $84,$6E,$18,$75,$10,$7C,$70,$83
  1781.  .BYT $40,$8B,$70,$93,$40,$9C,$78,$A5
  1782.  .BYT $58,$AF,$C8,$B9,$E0,$C4,$98,$D0
  1783.  .BYT $08,$DD,$30,$EA,$20,$F8,$2E,$FD
  1784.  
  1785.  
  1786. REGOFFSETS .BYT $00,$07,$0E
  1787. TMPREGOFST .BYT $00
  1788. POSOFFSET  .BYT $00,$00,$00
  1789. PATOFFSET  .BYT $00,$00,$00
  1790. LENGTHLEFT .BYT $00,$00,$00
  1791. SAVELNTHCC .BYT $00,$00,$00
  1792. VOICECTRL  .BYT $00,$00,$00
  1793. NOTENUM    .BYT $00,$00,$00
  1794. INSTRNR    .BYT $00,$00,$00
  1795. APPENDFL   .BYT $00
  1796. TEMPLNTHCC .BYT $00
  1797. TEMPFREQ   .BYT $00
  1798. TEMPSTORE  .BYT $00
  1799. TEMPCTRL   .BYT $00
  1800. VIBRDEPTH  .BYT $00
  1801. PULSEVALUE .BYT $00
  1802. TMPVDIFLO  .BYT $00
  1803. TMPVDIFHI  .BYT $00
  1804. TMPVFRQLO  .BYT $00
  1805. TMPVFRQHI  .BYT $00
  1806. OSCILATVAL .BYT $00
  1807. PULSEDELAY .BYT $00,$00,$00
  1808. PULSEDIR   .BYT $00,$00,$00
  1809. SPEED      .BYT $00
  1810. RESETSPD   .BYT $01
  1811. INSTNUMBY8 .BYT $00
  1812. MSTATUS    .BYT $C0
  1813. SAVEFREQHI .BYT $00,$00,$00
  1814. SAVEFREQLO .BYT $00,$00,$00
  1815. PORTAVAL   .BYT $00,$00,$00
  1816. INSTRFX    .BYT $00
  1817. PULSESPEED .BYT $00
  1818. COUNTER    .BYT $00
  1819. CURRTRKHI  .BYT $00,$00,$00
  1820. CURRTRKLO  .BYT $00,$00,$00
  1821.  
  1822.  
  1823. ;====================================
  1824. ;MONTY ON THE RUN MAIN THEME
  1825. ;====================================
  1826.  
  1827. SONGS =*
  1828.  .BYT <MONTYMAINTR1
  1829.  .BYT <MONTYMAINTR2
  1830.  .BYT <MONTYMAINTR3
  1831.  .BYT >MONTYMAINTR1
  1832.  .BYT >MONTYMAINTR2
  1833.  .BYT >MONTYMAINTR3
  1834.  
  1835.  
  1836. ;====================================
  1837. ;POINTERS TO THE PATTERNS
  1838.  
  1839. ;LOW POINTERS
  1840. PATPTL =*
  1841.  .BYT <PTN00
  1842.  .BYT <PTN01
  1843.  .BYT <PTN02
  1844.  .BYT <PTN03
  1845.  .BYT <PTN04
  1846.  .BYT <PTN05
  1847.  .BYT <PTN06
  1848.  .BYT <PTN07
  1849.  .BYT <PTN08
  1850.  .BYT <PTN09
  1851.  .BYT <PTN0A
  1852.  .BYT <PTN0B
  1853.  .BYT <PTN0C
  1854.  .BYT <PTN0D
  1855.  .BYT <PTN0E
  1856.  .BYT <PTN0F
  1857.  .BYT <PTN10
  1858.  .BYT <PTN11
  1859.  .BYT <PTN12
  1860.  .BYT <PTN13
  1861.  .BYT <PTN14
  1862.  .BYT <PTN15
  1863.  .BYT <PTN16
  1864.  .BYT <PTN17
  1865.  .BYT <PTN18
  1866.  .BYT <PTN19
  1867.  .BYT <PTN1A
  1868.  .BYT <PTN1B
  1869.  .BYT <PTN1C
  1870.  .BYT <PTN1D
  1871.  .BYT <PTN1E
  1872.  .BYT <PTN1F
  1873.  .BYT <PTN20
  1874.  .BYT <PTN21
  1875.  .BYT <PTN22
  1876.  .BYT <PTN23
  1877.  .BYT <PTN24
  1878.  .BYT <PTN25
  1879.  .BYT <PTN26
  1880.  .BYT <PTN27
  1881.  .BYT <PTN28
  1882.  .BYT <PTN29
  1883.  .BYT <PTN2A
  1884.  .BYT <PTN2B
  1885.  .BYT <PTN2C
  1886.  .BYT <PTN2D
  1887.  .BYT 0
  1888.  .BYT <PTN2F
  1889.  .BYT <PTN30
  1890.  .BYT <PTN31
  1891.  .BYT <PTN32
  1892.  .BYT <PTN33
  1893.  .BYT <PTN34
  1894.  .BYT <PTN35
  1895.  .BYT <PTN36
  1896.  .BYT <PTN37
  1897.  .BYT <PTN38
  1898.  .BYT <PTN39
  1899.  .BYT <PTN3A
  1900.  .BYT <PTN3B
  1901.  
  1902. ;HIGH POINTERS
  1903. PATPTH =*
  1904.  .BYT >PTN00
  1905.  .BYT >PTN01
  1906.  .BYT >PTN02
  1907.  .BYT >PTN03
  1908.  .BYT >PTN04
  1909.  .BYT >PTN05
  1910.  .BYT >PTN06
  1911.  .BYT >PTN07
  1912.  .BYT >PTN08
  1913.  .BYT >PTN09
  1914.  .BYT >PTN0A
  1915.  .BYT >PTN0B
  1916.  .BYT >PTN0C
  1917.  .BYT >PTN0D
  1918.  .BYT >PTN0E
  1919.  .BYT >PTN0F
  1920.  .BYT >PTN10
  1921.  .BYT >PTN11
  1922.  .BYT >PTN12
  1923.  .BYT >PTN13
  1924.  .BYT >PTN14
  1925.  .BYT >PTN15
  1926.  .BYT >PTN16
  1927.  .BYT >PTN17
  1928.  .BYT >PTN18
  1929.  .BYT >PTN19
  1930.  .BYT >PTN1A
  1931.  .BYT >PTN1B
  1932.  .BYT >PTN1C
  1933.  .BYT >PTN1D
  1934.  .BYT >PTN1E
  1935.  .BYT >PTN1F
  1936.  .BYT >PTN20
  1937.  .BYT >PTN21
  1938.  .BYT >PTN22
  1939.  .BYT >PTN23
  1940.  .BYT >PTN24
  1941.  .BYT >PTN25
  1942.  .BYT >PTN26
  1943.  .BYT >PTN27
  1944.  .BYT >PTN28
  1945.  .BYT >PTN29
  1946.  .BYT >PTN2A
  1947.  .BYT >PTN2B
  1948.  .BYT >PTN2C
  1949.  .BYT >PTN2D
  1950.  .BYT 0
  1951.  .BYT >PTN2F
  1952.  .BYT >PTN30
  1953.  .BYT >PTN31
  1954.  .BYT >PTN32
  1955.  .BYT >PTN33
  1956.  .BYT >PTN34
  1957.  .BYT >PTN35
  1958.  .BYT >PTN36
  1959.  .BYT >PTN37
  1960.  .BYT >PTN38
  1961.  .BYT >PTN39
  1962.  .BYT >PTN3A
  1963.  .BYT >PTN3B
  1964.  
  1965.  
  1966. ;====================================
  1967. ;TRACKS
  1968. ;====================================
  1969.  
  1970. ;TRACK1
  1971. MONTYMAINTR1 =*
  1972.  .BYT $11,$14,$17,$1A,$00,$27,$00,$28
  1973.  .BYT $03,$05,$00,$27,$00,$28,$03,$05
  1974.  .BYT $07,$3A,$14,$17,$00,$27,$00,$28
  1975.  .BYT $2F,$30,$31,$31,$32,$33,$33,$34
  1976.  .BYT $34,$34,$34,$34,$34,$34,$34,$35
  1977.  .BYT $35,$35,$35,$35,$35,$36,$12,$37
  1978.  .BYT $38,$09,$2A,$09,$2B,$09,$0A,$09
  1979.  .BYT $2A,$09,$2B,$09,$0A,$0D,$0D,$0F
  1980.  .BYT $FF
  1981.  
  1982. ;TRACK2
  1983. MONTYMAINTR2 =*
  1984.  .BYT $12,$15,$18,$1B,$2D,$39,$39
  1985.  .BYT $39,$39,$39,$39,$2C,$39,$39,$39
  1986.  .BYT $39,$39,$39,$2C,$39,$39,$39,$01
  1987.  .BYT $01,$29,$29,$2C,$15,$18,$39,$39
  1988.  .BYT $39,$39,$39,$39,$39,$39,$39,$39
  1989.  .BYT $39,$39,$39,$39,$39,$39,$39,$39
  1990.  .BYT $39,$39,$39,$39,$39,$39,$39,$39
  1991.  .BYT $39,$39,$39,$39,$39,$01,$01,$01
  1992.  .BYT $29,$39,$39,$39,$01,$01,$01,$29
  1993.  .BYT $39,$39,$39,$39,$FF
  1994.  
  1995. ;TRACK3
  1996. MONTYMAINTR3 =*
  1997.  .BYT $13,$16,$19
  1998.  .BYT $1C,$02,$02,$1D,$1E,$02,$02,$1D
  1999.  .BYT $1F,$04,$04,$20,$20,$06,$02,$02
  2000.  .BYT $1D,$1E,$02,$02,$1D,$1F,$04,$04
  2001.  .BYT $20,$20,$06,$08,$08,$08,$08,$21
  2002.  .BYT $21,$21,$21,$22,$22,$22,$23,$22
  2003.  .BYT $24,$25,$3B,$26,$26,$26,$26,$26
  2004.  .BYT $26,$26,$26,$26,$26,$26,$26,$26
  2005.  .BYT $26,$26,$26,$02,$02,$1D,$1E,$02
  2006.  .BYT $02,$1D,$1F,$2F,$2F,$2F,$2F,$2F
  2007.  .BYT $2F,$2F,$2F,$2F,$2F,$2F,$2F,$2F
  2008.  .BYT $0B,$0B,$1D,$1D,$0B,$0B,$1D,$0B
  2009.  .BYT $0B,$0B,$0C,$0C,$1D,$1D,$1D,$10
  2010.  .BYT $0B,$0B,$1D,$1D,$0B,$0B,$1D,$0B
  2011.  .BYT $0B,$0B,$0C,$0C,$1D,$1D,$1D,$10
  2012.  .BYT $0B,$1D,$0B,$1D,$0B,$1D,$0B,$1D
  2013.  .BYT $0B,$0C,$1D,$0B,$0C,$23,$0B,$0B
  2014.  .BYT $FF
  2015.  
  2016.  
  2017. ;====================================
  2018. ;PATTERNS
  2019. ;====================================
  2020.  
  2021. PTN00 =*
  2022.  .BYT $83,$00,$37,$01,$3E,$01,$3E,$03
  2023.  .BYT $3D,$03,$3E,$03,$43,$03,$3E,$03
  2024.  .BYT $3D,$03,$3E,$03,$37,$01,$3E,$01
  2025.  .BYT $3E,$03,$3D,$03,$3E,$03,$43,$03
  2026.  .BYT $42,$03,$43,$03,$45,$03,$46,$01
  2027.  .BYT $48,$01,$46,$03,$45,$03,$43,$03
  2028.  .BYT $4B,$01,$4D,$01,$4B,$03,$4A,$03
  2029.  .BYT $48,$FF
  2030.  
  2031. PTN27 =*
  2032.  .BYT $1F,$4A,$FF
  2033.  
  2034. PTN28 =*
  2035.  .BYT $03,$46,$01,$48,$01,$46,$03,$45
  2036.  .BYT $03,$4A,$0F,$43,$FF
  2037.  
  2038. PTN03 =*
  2039.  .BYT $BF,$06
  2040.  .BYT $48,$07,$48,$01,$4B,$01,$4A,$01
  2041.  .BYT $4B,$01,$4A,$03,$4B,$03,$4D,$03
  2042.  .BYT $4B,$03,$4A,$3F,$48,$07,$48,$01
  2043.  .BYT $4B,$01,$4A,$01,$4B,$01,$4A,$03
  2044.  .BYT $4B,$03,$4D,$03,$4B,$03,$48,$3F
  2045.  .BYT $4C,$07,$4C,$01,$4F,$01,$4E,$01
  2046.  .BYT $4F,$01,$4E,$03,$4F,$03,$51,$03
  2047.  .BYT $4F,$03,$4E,$3F,$4C,$07,$4C,$01
  2048.  .BYT $4F,$01,$4E,$01,$4F,$01,$4E,$03
  2049.  .BYT $4F,$03,$51,$03,$4F,$03,$4C,$FF
  2050.  
  2051. PTN05 =*
  2052.  .BYT $83,$04,$26,$03,$29,$03,$28,$03
  2053.  .BYT $29,$03,$26,$03,$35,$03,$34,$03
  2054.  .BYT $32,$03,$2D,$03,$30,$03,$2F,$03
  2055.  .BYT $30,$03,$2D,$03,$3C,$03,$3B,$03
  2056.  .BYT $39,$03,$30,$03,$33,$03,$32,$03
  2057.  .BYT $33,$03,$30,$03,$3F,$03,$3E,$03
  2058.  .BYT $3C,$03,$46,$03,$45,$03,$43,$03
  2059.  .BYT $3A,$03,$39,$03,$37,$03,$2E,$03
  2060.  .BYT $2D,$03,$26,$03,$29,$03,$28,$03
  2061.  .BYT $29,$03,$26,$03,$35,$03,$34,$03
  2062.  .BYT $32,$03,$2D,$03,$30,$03,$2F,$03
  2063.  .BYT $30,$03,$2D,$03,$3C,$03,$3B,$03
  2064.  .BYT $39,$03,$30,$03,$33,$03,$32,$03
  2065.  .BYT $33,$03,$30,$03,$3F,$03,$3E,$03
  2066.  .BYT $3C,$03,$34,$03,$37,$03,$36,$03
  2067.  .BYT $37,$03,$34,$03,$37,$03,$3A,$03
  2068.  .BYT $3D
  2069.  
  2070. PTN3A =*
  2071.  .BYT $03,$3E,$07,$3E,$07,$3F,$07
  2072.  .BYT $3E,$03,$3C,$07,$3E,$57,$FF
  2073.  
  2074. PTN07 =*
  2075.  .BYT $8B
  2076.  .BYT $00,$3A,$01,$3A,$01,$3C,$03,$3D
  2077.  .BYT $03,$3F,$03,$3D,$03,$3C,$0B,$3A
  2078.  .BYT $03,$39,$07,$3A,$81,$06,$4B,$01
  2079.  .BYT $4D,$01,$4E,$01,$4D,$01,$4E,$01
  2080.  .BYT $4D,$05,$4B,$81,$00,$3A,$01,$3C
  2081.  .BYT $01,$3D,$03,$3F,$03,$3D,$03,$3C
  2082.  .BYT $03,$3A,$03,$39,$1B,$3A,$0B,$3B
  2083.  .BYT $01,$3B,$01,$3D,$03,$3E,$03,$40
  2084.  .BYT $03,$3E,$03,$3D,$0B,$3B,$03,$3A
  2085.  .BYT $07,$3B,$81,$06,$4C,$01,$4E,$01
  2086.  .BYT $4F,$01,$4E,$01,$4F,$01,$4E,$05
  2087.  .BYT $4C,$81,$00,$3B,$01,$3D,$01,$3E
  2088.  .BYT $03,$40,$03,$3E,$03,$3D,$03,$3B
  2089.  .BYT $03,$3A,$1B,$3B,$8B,$05,$35,$03
  2090.  .BYT $33,$07,$32,$03,$30,$03,$2F,$0B
  2091.  .BYT $30,$03,$32,$0F,$30,$0B,$35,$03
  2092.  .BYT $33,$07,$32,$03,$30,$03,$2F,$1F
  2093.  .BYT $30,$8B,$00,$3C,$01,$3C,$01,$3E
  2094.  .BYT $03,$3F,$03,$41,$03,$3F,$03,$3E
  2095.  .BYT $0B,$3D,$01,$3D,$01,$3F,$03,$40
  2096.  .BYT $03,$42,$03,$40,$03,$3F,$03,$3E
  2097.  .BYT $01,$3E,$01,$40,$03,$41,$03,$40
  2098.  .BYT $03,$3E,$03,$3D,$03,$3E,$03,$3C
  2099.  .BYT $03,$3A,$01,$3A,$01,$3C,$03,$3D
  2100.  .BYT $03,$3C,$03,$3A,$03,$39,$03,$3A
  2101.  .BYT $03,$3C,$FF
  2102.  
  2103. PTN09 =*
  2104.  .BYT $83,$00,$32,$01,$35,$01,$34,$03
  2105.  .BYT $32,$03,$35,$03,$34,$03,$32,$03
  2106.  .BYT $35,$01,$34,$01,$32,$03,$32,$03
  2107.  .BYT $3A,$03,$39,$03,$3A,$03,$32,$03
  2108.  .BYT $3A,$03,$39,$03,$3A,$FF
  2109.  
  2110. PTN2A =*
  2111.  .BYT $03,$34,$01,$37,$01,$35,$03,$34
  2112.  .BYT $03,$37,$03,$35,$03,$34,$03,$37
  2113.  .BYT $01,$35,$01,$34,$03,$34,$03,$3A
  2114.  .BYT $03,$39,$03,$3A,$03,$34,$03,$3A
  2115.  .BYT $03,$39,$03,$3A,$FF
  2116.  
  2117. PTN2B =*
  2118.  .BYT $03,$39,$03,$38,$03,$39,$03,$3A
  2119.  .BYT $03,$39,$03,$37,$03,$35,$03,$34
  2120.  .BYT $03,$35,$03,$34,$03,$35,$03,$37
  2121.  .BYT $03,$35,$03,$34,$03,$32,$03,$31
  2122.  .BYT $FF
  2123.  
  2124. PTN0A =*
  2125.  .BYT $03
  2126.  .BYT $37,$01,$3A,$01,$39,$03,$37,$03
  2127.  .BYT $3A,$03,$39,$03,$37,$03,$3A,$01
  2128.  .BYT $39,$01,$37,$03,$37,$03,$3E,$03
  2129.  .BYT $3D,$03,$3E,$03,$37,$03,$3E,$03
  2130.  .BYT $3D,$03,$3E,$03,$3D,$01,$40,$01
  2131.  .BYT $3E,$03,$3D,$03,$40,$01,$3E,$01
  2132.  .BYT $3D,$03,$40,$03,$3E,$03,$40,$03
  2133.  .BYT $40,$01,$43,$01,$41,$03,$40,$03
  2134.  .BYT $43,$01,$41,$01,$40,$03,$43,$03
  2135.  .BYT $41,$03,$43,$03,$43,$01,$46,$01
  2136.  .BYT $45,$03,$43,$03,$46,$01,$45,$01
  2137.  .BYT $43,$03,$46,$03,$45,$03,$43,$01
  2138.  .BYT $48,$01,$49,$01,$48,$01,$46,$01
  2139.  .BYT $45,$01,$46,$01,$45,$01,$43,$01
  2140.  .BYT $41,$01,$43,$01,$41,$01,$40,$01
  2141.  .BYT $3D,$01,$39,$01,$3B,$01,$3D,$FF
  2142.  
  2143. PTN0D =*
  2144.  .BYT $01,$3E,$01,$39,$01,$35,$01,$39
  2145.  .BYT $01,$3E,$01,$39,$01,$35,$01,$39
  2146.  .BYT $03,$3E,$01,$41,$01,$40,$03,$40
  2147.  .BYT $01,$3D,$01,$3E,$01,$40,$01,$3D
  2148.  .BYT $01,$39,$01,$3D,$01,$40,$01,$3D
  2149.  .BYT $01,$39,$01,$3D,$03,$40,$01,$43
  2150.  .BYT $01,$41,$03,$41,$01,$3E,$01,$40
  2151.  .BYT $01,$41,$01,$3E,$01,$39,$01,$3E
  2152.  .BYT $01,$41,$01,$3E,$01,$39,$01,$3E
  2153.  .BYT $03,$41,$01,$45,$01,$43,$03,$43
  2154.  .BYT $01,$40,$01,$41,$01,$43,$01,$40
  2155.  .BYT $01,$3D,$01,$40,$01,$43,$01,$40
  2156.  .BYT $01,$3D,$01,$40,$01,$46,$01,$43
  2157.  .BYT $01,$45,$01,$46,$01,$44,$01,$43
  2158.  .BYT $01,$40,$01,$3D,$FF
  2159.  
  2160. PTN0F =*
  2161.  .BYT $01,$3E,$01
  2162.  .BYT $39,$01,$35,$01,$39,$01,$3E,$01
  2163.  .BYT $39,$01,$35,$01,$39,$01,$3E,$01
  2164.  .BYT $39,$01,$35,$01,$39,$01,$3E,$01
  2165.  .BYT $39,$01,$35,$01,$39,$01,$3E,$01
  2166.  .BYT $3A,$01,$37,$01,$3A,$01,$3E,$01
  2167.  .BYT $3A,$01,$37,$01,$3A,$01,$3E,$01
  2168.  .BYT $3A,$01,$37,$01,$3A,$01,$3E,$01
  2169.  .BYT $3A,$01,$37,$01,$3A,$01,$40,$01
  2170.  .BYT $3D,$01,$39,$01,$3D,$01,$40,$01
  2171.  .BYT $3D,$01,$39,$01,$3D,$01,$40,$01
  2172.  .BYT $3D,$01,$39,$01,$3D,$01,$40,$01
  2173.  .BYT $3D,$01,$39,$01,$3D,$01,$41,$01
  2174.  .BYT $3E,$01,$39,$01,$3E,$01,$41,$01
  2175.  .BYT $3E,$01,$39,$01,$3E,$01,$41,$01
  2176.  .BYT $3E,$01,$39,$01,$3E,$01,$41,$01
  2177.  .BYT $3E,$01,$39,$01,$3E,$01,$43,$01
  2178.  .BYT $3E,$01,$3A,$01,$3E,$01,$43,$01
  2179.  .BYT $3E,$01,$3A,$01,$3E,$01,$43,$01
  2180.  .BYT $3E,$01,$3A,$01,$3E,$01,$43,$01
  2181.  .BYT $3E,$01,$3A,$01,$3E,$01,$43,$01
  2182.  .BYT $3F,$01,$3C,$01,$3F,$01,$43,$01
  2183.  .BYT $3F,$01,$3C,$01,$3F,$01,$43,$01
  2184.  .BYT $3F,$01,$3C,$01,$3F,$01,$43,$01
  2185.  .BYT $3F,$01,$3C,$01,$3F,$01,$45,$01
  2186.  .BYT $42,$01,$3C,$01,$42,$01,$45,$01
  2187.  .BYT $42,$01,$3C,$01,$42,$01,$48,$01
  2188.  .BYT $45,$01,$42,$01,$45,$01,$4B,$01
  2189.  .BYT $48,$01,$45,$01,$48,$01,$4B,$01
  2190.  .BYT $4A,$01,$48,$01,$4A,$01,$4B,$01
  2191.  .BYT $4A,$01,$48,$01,$4A,$01,$4B,$01
  2192.  .BYT $4A,$01,$48,$01,$4A,$01,$4C,$01
  2193.  .BYT $4E,$03,$4F,$FF
  2194.  
  2195. PTN11 =*
  2196.  .BYT $BF,$06,$56,$1F,$57,$1F,$56,$1F
  2197.  .BYT $5B,$1F,$56,$1F,$57,$1F,$56,$1F
  2198.  .BYT $4F,$FF
  2199.  
  2200. PTN12 =*
  2201.  .BYT $BF,$0C,$68,$7F,$7F,$7F,$7F,$7F
  2202.  .BYT $7F,$7F,$FF
  2203.  
  2204. PTN13 =*
  2205.  .BYT $BF,$08,$13,$3F,$13,$3F,$13,$3F
  2206.  .BYT $13,$3F,$13,$3F,$13,$3F,$13,$1F
  2207.  .BYT $13,$FF
  2208.  
  2209. PTN14 =*
  2210.  .BYT $97,$09,$2E,$03,$2E,$1B,$32,$03
  2211.  .BYT $32,$1B,$31,$03,$31,$1F,$34,$43
  2212.  .BYT $17,$32,$03,$32,$1B,$35,$03,$35
  2213.  .BYT $1B,$34,$03,$34,$0F,$37,$8F,$0A
  2214.  .BYT $37,$43,$FF
  2215.  
  2216. PTN15 =*
  2217.  .BYT $97,$09,$2B,$03,$2B,$1B,$2E,$03
  2218.  .BYT $2E,$1B,$2D,$03,$2D,$1F,$30,$43
  2219.  .BYT $17,$2E,$03,$2E,$1B,$32,$03,$32
  2220.  .BYT $1B,$31,$03,$31,$0F,$34,$8F,$0A
  2221.  .BYT $34,$43,$FF
  2222.  
  2223. PTN16 =*
  2224.  .BYT $0F,$1F,$0F,$1F,$0F,$1F,$0F,$1F
  2225.  .BYT $0F,$1F,$0F,$1F,$0F,$1F,$0F,$1F
  2226.  .BYT $0F,$1F,$0F,$1F,$0F,$1F,$0F,$1F
  2227.  .BYT $0F,$1F,$0F,$1F,$0F,$1F,$0F,$1F
  2228.  .BYT $FF
  2229.  
  2230. PTN17 =*
  2231.  .BYT $97,$09,$33,$03,$33,$1B,$37,$03
  2232.  .BYT $37,$1B,$36,$03,$36,$1F,$39,$43
  2233.  .BYT $17,$37,$03,$37,$1B,$3A,$03,$3A
  2234.  .BYT $1B,$39,$03,$39,$2F,$3C,$21,$3C
  2235.  .BYT $21,$3D,$21,$3E,$21,$3F,$21,$40
  2236.  .BYT $21,$41,$21,$42,$21,$43,$21,$44
  2237.  .BYT $01,$45,$FF
  2238.  
  2239. PTN18 =*
  2240.  .BYT $97,$09,$30,$03,$30,$1B,$33,$03
  2241.  .BYT $33,$1B,$32,$03,$32,$1F,$36,$43
  2242.  .BYT $17,$33,$03,$33,$1B,$37,$03,$37
  2243.  .BYT $1B,$36,$03,$36,$2F,$39,$21,$39
  2244.  .BYT $21,$3A,$21,$3B,$21,$3C,$21,$3D
  2245.  .BYT $21,$3E,$21,$3F,$21,$40,$21,$41
  2246.  .BYT $01,$42,$FF
  2247.  
  2248. PTN19 =*
  2249.  .BYT $0F,$1A,$0F,$1A,$0F,$1A,$0F,$1A
  2250.  .BYT $0F,$1A,$0F,$1A,$0F,$1A,$0F,$1A
  2251.  .BYT $0F,$1A,$0F,$1A,$0F,$1A,$0F,$1A
  2252.  .BYT $0F,$1A,$0F,$1A,$0F,$1A,$0F,$1A
  2253.  .BYT $FF
  2254.  
  2255. PTN1A =*
  2256.  .BYT $1F,$46,$BF,$0A,$46,$7F,$7F,$FF
  2257.  
  2258. PTN1B =*
  2259.  .BYT $1F,$43,$BF,$0A,$43,$7F,$FF
  2260.  
  2261. PTN1C =*
  2262.  .BYT $83,$02,$13,$03,$13,$03,$1E,$03
  2263.  .BYT $1F,$03,$13,$03,$13,$03,$1E,$03
  2264.  .BYT $1F,$03,$13,$03,$13,$03,$1E,$03
  2265.  .BYT $1F,$03,$13,$03,$13,$03,$1E,$03
  2266.  .BYT $1F,$03,$13,$03,$13,$03,$1E,$03
  2267.  .BYT $1F,$03,$13,$03,$13,$03,$1E,$03
  2268.  .BYT $1F,$03,$13,$03,$13,$03,$1E,$03
  2269.  .BYT $1F,$03,$13,$03,$13,$03,$1E,$03
  2270.  .BYT $1F,$FF
  2271.  
  2272. PTN29 =*
  2273.  .BYT $8F,$0B,$38,$4F,$FF
  2274.  
  2275. PTN2C =*
  2276.  .BYT $83,$0E,$32,$07,$32,$07,$2F,$07
  2277.  .BYT $2F,$03,$2B,$87,$0B,$46,$83,$0E
  2278.  .BYT $2C,$03,$2C,$8F,$0B,$32,$FF
  2279.  
  2280. PTN2D =*
  2281.  .BYT $43,$83,$0E,$32,$03,$32,$03,$2F
  2282.  .BYT $03,$2F,$03,$2C,$87,$0B,$38,$FF
  2283.  
  2284. PTN39 =*
  2285.  .BYT $83,$01
  2286.  .BYT $43,$01,$4F,$01,$5B,$87,$03,$2F
  2287.  .BYT $83,$01,$43,$01,$4F,$01,$5B,$87
  2288.  .BYT $03,$2F,$83,$01,$43,$01,$4F,$01
  2289.  .BYT $5B,$87,$03,$2F,$83,$01,$43,$01
  2290.  .BYT $4F,$01,$5B,$87,$03,$2F,$83,$01
  2291.  .BYT $43,$01,$4F,$01,$5B,$87,$03,$2F
  2292.  .BYT $83,$01,$43,$01,$4F,$01,$5B,$87
  2293.  .BYT $03,$2F
  2294.  
  2295. PTN01 =*
  2296.  .BYT $83,$01,$43,$01,$4F,$01,$5B,$87
  2297.  .BYT $03,$2F,$83,$01,$43,$01,$4F,$01
  2298.  .BYT $5B,$87,$03,$2F,$FF
  2299.  
  2300. PTN02 =*
  2301.  .BYT $83,$02,$13,$03,$13,$03,$1F,$03
  2302.  .BYT $1F,$03,$13,$03,$13,$03,$1F,$03
  2303.  .BYT $1F,$FF
  2304.  
  2305. PTN1D =*
  2306.  .BYT $03,$15,$03,$15,$03,$1F,$03,$21
  2307.  .BYT $03,$15,$03,$15,$03,$1F,$03,$21
  2308.  .BYT $FF
  2309.  
  2310. PTN1E =*
  2311.  .BYT $03,$1A,$03,$1A,$03,$1C,$03,$1C
  2312.  .BYT $03,$1D,$03,$1D,$03,$1E,$03,$1E
  2313.  .BYT $FF
  2314.  
  2315. PTN1F =*
  2316.  .BYT $03,$1A,$03,$1A,$03,$24,$03,$26
  2317.  .BYT $03,$13,$03,$13,$07,$1F,$FF
  2318.  
  2319. PTN04 =*
  2320.  .BYT $03,$18,$03,$18,$03,$24,$03,$24
  2321.  .BYT $03,$18,$03,$18,$03,$24,$03,$24
  2322.  .BYT $03,$20,$03,$20,$03,$2C,$03,$2C
  2323.  .BYT $03,$20,$03,$20,$03,$2C,$03,$2C
  2324.  .BYT $FF
  2325.  
  2326. PTN20 =*
  2327.  .BYT $03,$19,$03,$19,$03
  2328.  .BYT $25,$03,$25,$03,$19,$03,$19,$03
  2329.  .BYT $25,$03,$25,$03,$21,$03,$21,$03
  2330.  .BYT $2D,$03,$2D,$03,$21,$03,$21,$03
  2331.  .BYT $2D,$03,$2D,$FF
  2332.  
  2333. PTN06 =*
  2334.  .BYT $03,$1A,$03,$1A
  2335.  .BYT $03,$26,$03,$26,$03,$1A,$03,$1A
  2336.  .BYT $03,$26,$03,$26,$03,$15,$03,$15
  2337.  .BYT $03,$21,$03,$21,$03,$15,$03,$15
  2338.  .BYT $03,$21,$03,$21,$03,$18,$03,$18
  2339.  .BYT $03,$24,$03,$24,$03,$18,$03,$18
  2340.  .BYT $03,$24,$03,$24,$03,$1F,$03,$1F
  2341.  .BYT $03,$2B,$03,$2B,$03,$1F,$03,$1F
  2342.  .BYT $03,$2B,$03,$2B,$03,$1A,$03,$1A
  2343.  .BYT $03,$26,$03,$26,$03,$1A,$03,$1A
  2344.  .BYT $03,$26,$03,$26,$03,$15,$03,$15
  2345.  .BYT $03,$21,$03,$21,$03,$15,$03,$15
  2346.  .BYT $03,$21,$03,$21,$03,$18,$03,$18
  2347.  .BYT $03,$24,$03,$24,$03,$18,$03,$18
  2348.  .BYT $03,$24,$03,$24,$03,$1C,$03,$1C
  2349.  .BYT $03,$28,$03,$28,$03,$1C,$03,$1C
  2350.  .BYT $03,$28,$03,$28
  2351.  
  2352. PTN3B =*
  2353.  .BYT $83,$04,$36,$07
  2354.  .BYT $36,$07,$37,$07,$36,$03,$33,$07
  2355.  .BYT $32,$57,$FF
  2356.  
  2357. PTN08 =*
  2358.  .BYT $83,$02,$1B,$03,$1B,$03,$27,$03
  2359.  .BYT $27,$03,$1B,$03,$1B,$03,$27,$03
  2360.  .BYT $27,$FF
  2361.  
  2362. PTN21 =*
  2363.  .BYT $03,$1C,$03,$1C,$03,$28,$03,$28
  2364.  .BYT $03,$1C,$03,$1C,$03,$28,$03,$28
  2365.  .BYT $FF
  2366.  
  2367. PTN22 =*
  2368.  .BYT $03,$1D,$03,$1D,$03,$29,$03,$29
  2369.  .BYT $03,$1D,$03,$1D,$03,$29,$03,$29
  2370.  .BYT $FF
  2371.  
  2372. PTN23 =*
  2373.  .BYT $03,$18,$03,$18,$03,$24,$03,$24
  2374.  .BYT $03,$18,$03,$18,$03,$24,$03,$24
  2375.  .BYT $FF
  2376.  
  2377. PTN24 =*
  2378.  .BYT $03,$1E,$03,$1E,$03,$2A,$03,$2A
  2379.  .BYT $03,$1E,$03,$1E,$03,$2A,$03,$2A
  2380.  .BYT $FF
  2381.  
  2382. PTN25 =*
  2383.  .BYT $83,$05,$26,$01,$4A,$01,$34,$03
  2384.  .BYT $29,$03,$4C,$03,$4A,$03,$31,$03
  2385.  .BYT $4A,$03,$24,$03,$22,$01,$46,$01
  2386.  .BYT $30,$03,$25,$03,$48,$03,$46,$03
  2387.  .BYT $2D,$03,$46,$03,$24,$FF
  2388.  
  2389. PTN0B =*
  2390.  .BYT $83,$02,$1A,$03,$1A,$03,$26,$03
  2391.  .BYT $26,$03,$1A,$03,$1A,$03,$26,$03
  2392.  .BYT $26,$FF
  2393.  
  2394. PTN0C =*
  2395.  .BYT $03,$13,$03,$13,$03,$1D,$03,$1F
  2396.  .BYT $03,$13,$03,$13,$03,$1D,$03,$1F
  2397.  .BYT $FF
  2398.  
  2399. PTN26 =*
  2400.  .BYT $87,$02,$1A,$87,$03,$2F,$83,$02
  2401.  .BYT $26,$03,$26,$87,$03,$2F,$FF
  2402.  
  2403. PTN10 =*
  2404.  .BYT $07,$1A,$4F,$47,$FF
  2405.  
  2406. PTN0E =*
  2407.  .BYT $03,$1F,$03,$1F,$03,$24,$03,$26
  2408.  .BYT $07,$13,$47,$FF
  2409.  
  2410. PTN30 =*
  2411.  .BYT $BF,$0F,$32,$0F,$32,$8F,$90,$30
  2412.  .BYT $3F,$32,$13,$32,$03,$32,$03,$35
  2413.  .BYT $03,$37,$3F,$37,$0F,$37,$8F,$90
  2414.  .BYT $30,$3F,$32,$13,$32,$03,$2D,$03
  2415.  .BYT $30,$03,$32,$FF
  2416.  
  2417. PTN31 =*
  2418.  .BYT $0F,$32
  2419.  .BYT $AF,$90,$35,$0F,$37,$A7,$99,$37
  2420.  .BYT $07,$35,$3F,$32,$13,$32,$03,$32
  2421.  .BYT $A3,$E8,$35,$03,$37,$0F,$35,$AF
  2422.  .BYT $90,$37,$0F,$37,$A7,$99,$37,$07
  2423.  .BYT $35,$3F,$32,$13,$32,$03,$2D,$A3
  2424.  .BYT $E8,$30,$03,$32,$FF
  2425.  
  2426. PTN32 =*
  2427.  .BYT $07,$32,$03
  2428.  .BYT $39,$13,$3C,$A7,$9A,$37,$A7,$9B
  2429.  .BYT $38,$07,$37,$03,$35,$03,$32,$03
  2430.  .BYT $39,$1B,$3C,$A7,$9A,$37,$A7,$9B
  2431.  .BYT $38,$07,$37,$03,$35,$03,$32,$03
  2432.  .BYT $39,$03,$3C,$03,$3E,$03,$3C,$07
  2433.  .BYT $3E,$03,$3C,$03,$39,$A7,$9A,$37
  2434.  .BYT $A7,$9B,$38,$07,$37,$03,$35,$03
  2435.  .BYT $32,$AF,$90,$3C,$1F,$3E,$43,$03
  2436.  .BYT $3E,$03,$3C,$03,$3E,$FF
  2437.  
  2438. PTN33 =*
  2439.  .BYT $03,$3E
  2440.  .BYT $03,$3E,$A3,$E8,$3C,$03,$3E,$03
  2441.  .BYT $3E,$03,$3E,$A3,$E8,$3C,$03,$3E
  2442.  .BYT $03,$3E,$03,$3E,$A3,$E8,$3C,$03
  2443.  .BYT $3E,$03,$3E,$03,$3E,$A3,$E8,$3C
  2444.  .BYT $03,$3E,$AF,$91,$43,$1F,$41,$43
  2445.  .BYT $03,$3E,$03,$41,$03,$43,$03,$43
  2446.  .BYT $03,$43,$A3,$E8,$41,$03,$43,$03
  2447.  .BYT $43,$03,$43,$A3,$E8,$41,$03,$43
  2448.  .BYT $03,$45,$03,$48,$A3,$FD,$45,$03
  2449.  .BYT $44,$01,$43,$01,$41,$03,$3E,$03
  2450.  .BYT $3C,$03,$3E,$2F,$3E,$BF,$98,$3E
  2451.  .BYT $43,$03,$3E,$03,$3C,$03,$3E,$FF
  2452.  
  2453. PTN34 =*
  2454.  .BYT $03,$4A,$03,$4A,$A3,$F8,$48,$03
  2455.  .BYT $4A,$03,$4A,$03,$4A,$A3,$F8,$48
  2456.  .BYT $03,$4A,$FF
  2457.  
  2458. PTN35 =*
  2459.  .BYT $01,$51,$01,$54,$01
  2460.  .BYT $51,$01,$54,$01,$51,$01,$54,$01
  2461.  .BYT $51,$01,$54,$01,$51,$01,$54,$01
  2462.  .BYT $51,$01,$54,$01,$51,$01,$54,$01
  2463.  .BYT $51,$01,$54,$FF
  2464.  
  2465. PTN36 =*
  2466.  .BYT $01,$50,$01,$4F
  2467.  .BYT $01,$4D,$01,$4A,$01,$4F,$01,$4D
  2468.  .BYT $01,$4A,$01,$48,$01,$4A,$01,$48
  2469.  .BYT $01,$45,$01,$43,$01,$44,$01,$43
  2470.  .BYT $01,$41,$01,$3E,$01,$43,$01,$41
  2471.  .BYT $01,$3E,$01,$3C,$01,$3E,$01,$3C
  2472.  .BYT $01,$39,$01,$37,$01,$38,$01,$37
  2473.  .BYT $01,$35,$01,$32,$01,$37,$01,$35
  2474.  .BYT $01,$32,$01,$30,$FF
  2475.  
  2476. PTN37 =*
  2477.  .BYT $5F,$5F,$5F
  2478.  .BYT $47,$83,$0E,$32,$07,$32,$07,$2F
  2479.  .BYT $03,$2F,$07,$2F,$97,$0B,$3A,$5F
  2480.  .BYT $5F,$47,$8B,$0E,$32,$03,$32,$03
  2481.  .BYT $2F,$03,$2F,$47,$97,$0B,$3A,$5F
  2482.  .BYT $5F,$47,$83,$0E,$2F,$0B,$2F,$03
  2483.  .BYT $2F,$03,$2F,$87,$0B,$30,$17,$3A
  2484.  .BYT $5F,$8B,$0E,$32,$0B,$32,$0B,$2F
  2485.  .BYT $0B,$2F,$07,$2C,$07,$2C,$FF
  2486.  
  2487. PTN38 =*
  2488.  .BYT $87
  2489.  .BYT $0B,$34,$17,$3A,$5F,$5F,$84,$0E
  2490.  .BYT $32,$04,$32,$05,$32,$04,$2F,$04
  2491.  .BYT $2F,$05,$2F,$47,$97,$0B,$3A,$5F
  2492.  .BYT $5F,$84,$0E,$32,$04,$32,$05,$32
  2493.  .BYT $04,$2F,$04,$2F,$05,$2F,$FF
  2494.  
  2495. PTN2F =*
  2496.  .BYT $03,$1A,$03,$1A,$03
  2497.  .BYT $24,$03,$26,$03,$1A,$03,$1A,$03
  2498.  .BYT $18,$03,$19,$03,$1A,$03,$1A,$03
  2499.  .BYT $24,$03,$26,$03,$1A,$03,$1A,$03
  2500.  .BYT $18,$03,$19,$03,$18,$03,$18,$03
  2501.  .BYT $22,$03,$24,$03,$18,$03,$18,$03
  2502.  .BYT $16,$03,$17,$03,$18,$03,$18,$03
  2503.  .BYT $22,$03,$24,$03,$18,$03,$18,$03
  2504.  .BYT $16,$03,$17,$03,$13,$03,$13,$03
  2505.  .BYT $1D,$03,$1F,$03,$13,$03,$13,$03
  2506.  .BYT $1D,$03,$1E,$03,$13,$03,$13,$03
  2507.  .BYT $1D,$03,$1F,$03,$13,$03,$13,$03
  2508.  .BYT $1D,$03,$1E,$03,$1A,$03,$1A,$03
  2509.  .BYT $24,$03,$26,$03,$1A,$03,$1A,$03
  2510.  .BYT $18,$03,$19,$03,$1A,$03,$1A,$03
  2511.  .BYT $24,$03,$26,$03,$1A,$03,$1A,$03
  2512.  .BYT $18,$03,$19,$FF
  2513.  
  2514.  
  2515. ;====================================
  2516. ;INSTRUMENTS
  2517. ;====================================
  2518.  
  2519. INSTR =*
  2520.  .BYT $80,$09,$41,$48,$60,$03,$81,$00
  2521.  .BYT $00,$08,$81,$02,$08,$00,$00,$01
  2522.  .BYT $A0,$02,$41,$09,$80,$00,$00,$00
  2523.  .BYT $00,$02,$81,$09,$09,$00,$00,$05
  2524.  .BYT $00,$08,$41,$08,$50,$02,$00,$04
  2525.  .BYT $00,$01,$41,$3F,$C0,$02,$00,$00
  2526.  .BYT $00,$08,$41,$04,$40,$02,$00,$00
  2527.  .BYT $00,$08,$41,$09,$00,$02,$00,$00
  2528.  .BYT $00,$09,$41,$09,$70,$02,$5F,$04
  2529.  .BYT $00,$09,$41,$4A,$69,$02,$81,$00
  2530.  .BYT $00,$09,$41,$40,$6F,$00,$81,$02
  2531.  .BYT $80,$07,$81,$0A,$0A,$00,$00,$01
  2532.  .BYT $00,$09,$41,$3F,$FF,$01,$E7,$02
  2533.  .BYT $00,$08,$41,$90,$F0,$01,$E8,$02
  2534.  .BYT $00,$08,$41,$06,$0A,$00,$00,$01
  2535.  .BYT $00,$09,$41,$19,$70,$02,$A8,$00
  2536.  .BYT $00,$02,$41,$09,$90,$02,$00,$00
  2537.  .BYT $00,$00,$11,$0A,$FA,$00,$00,$05
  2538.  .BYT $00,$08,$41,$37,$40,$02,$00,$00
  2539.  .BYT $00,$08,$11,$07,$70,$02,$00,$00
  2540.  
  2541. .END
  2542.  
  2543. =============================================================================
  2544. ┌╨═3 AND ┌├├╨ ┼NHANCEMENTS FOR ├╨/═ ╨LUS FROM ╙IMEON ├RAN
  2545. BY ╥ANDY ╫INCHESTER (RANDY@MIT.EDU)
  2546.  
  2547. ╧PERATING ╙YSTEM ├OMPONENTS
  2548.  
  2549. ╘HE ├╨/═ ╨LUS OPERATING SYSTEM CONSISTS OF THREE MODULES.  ╘HE ├├╨ (├ONSOLE
  2550. ├OMMAND ╨ROCESSOR), IS THE PART OF ├╨/═ THAT YOU SEE WHEN YOU FIRST BOOT THE
  2551. SYSTEM.  ╘HE ├├╨ PRINTS THE ┴> DISK PROMPT, ACCEPTS USER INPUT, AND LOADS
  2552. COMMANDS FROM DISK.
  2553.  
  2554. ╘HE ┬─╧╙ (┬ASIC ─ISK ╧PERATING ╙YSTEM) HANDLES THE ├╨/═ FUNCTIONS OF DISK,
  2555. CONSOLE, AND PRINTER INPUT/OUTPUT, AND THE TASKS OF FILE MANAGEMENT.
  2556.  
  2557. ╘HE ┬╔╧╙ (┬ASIC ╔NPUT ╧UTPUT ╙YSTEM) DOES THE REAL INPUT/OUTPUT WORK FOR THE
  2558. ┬─╧╙. ╘HE ┬╔╧╙ CONTAINS THE CODE CUSTOMIZED FOR THE ├╨/═ HARDWARE THAT YOU'RE
  2559. USING. ╧N THE ├128, THE ┬╔╧╙ CONTAINS THE ROUTINES FOR DRIVING THE 40 AND 80
  2560. COLUMN SCREENS, USING THE ╥┼╒ AS A ╥┴═ DRIVE, AND READING/WRITING SEVERAL
  2561. DIFFERENT DISK FORMATS ON 1571 AND 1581 DRIVES.  ╘HE ┬╔╧╙ CAN BE THOUGHT OF AS
  2562. A COLLECTION OF DEVICE DRIVERS THAT ARE SPECIFIC TO YOUR COMPUTER.
  2563.  
  2564.  
  2565. ╫HAT'S ╬EW - ┬╔╧╙-╥6
  2566.  
  2567. ┬╔╧╙-╥6 (├128 ┬╔╧╙ MODIFIED BY ╥ANDY ╫INCHESTER AND OTHERS) IS THE LATEST OF
  2568. THE MODIFIED VERSIONS OF THE ├128 ├╨/═ ┬╔╧╙.  ═OST OF THE CHANGES TO THE ┬╔╧╙
  2569. RESULT IN FASTER PROCESSING SPEED. ╞OR EXAMPLE, ALL THE CODE FOR DRIVING A 40
  2570. COLUMN SCREEN HAS BEEN REMOVED.  ┴LMOST EVERYONE USING ├╨/═ IS GOING TO BE
  2571. USING IT IN 80 COLUMNS ANYWAY.  ├UTTING THIS CODE TAKES A BIG LOAD OFF THE
  2572. SYSTEM AND INCREASES OVERALL SPEED BY ABOUT 15%.  ╙IMILARLY, THE INTERRUPT
  2573. DRIVEN ╥╙232 HAS BEEN SET FROM 300 TO 75 BAUD.  ╘HE HIGHER THE BAUD RATE, THE
  2574. MORE PROCESSOR TIME IS REQUIRED TO SERVICE ╥╙232.  ╙INCE THE ╥╙232 CODE IS
  2575. ALWAYS RUNNING, DECREASING THE BAUD RATE FREES UP CYCLES THAT THE PROCESSOR
  2576. NEEDS TO SERVICE ╥╙232.  ╘HIS DOESN'T AFFECT THE OPERATION OF TERMINAL PROGRAMS
  2577. WHICH EXPLICITLY SET THE BAUD RATE WHEN THEY START UP.
  2578.  
  2579. ╧THER FEATURES OF ┬╔╧╙-╥6 INCLUDE A SCREEN DUMP FUNCTION, COMMENTED SOURCE TO
  2580. ASSIST THE PROGRAMMER IN PRODUCING CUSTOMIZED SYSTEMS, AND SUPPORT FOR
  2581. ADDITIONAL DISK FORMATS.  ╙OME OF THE NEW DISK FORMATS INCLUDE ├OMMODORE'S
  2582. STANDARD 1581 ├╨/═ FORMAT, ═┴╪╔ 71 (398╦ ON 5.25" DISKS), AND ╟╨ 1581 (796╦ ON
  2583. 3.5" DISKS).
  2584.  
  2585. ├128 ├╨/═ PROGRAMMERS WHO WANT TO ADD OR CHANGE OPERATING SYSTEM FEATURES
  2586. SHOULD TRY TO MAKE CHANGES TO THE ┬╔╧╙.  ╞OR ONE THING, ┬╔╧╙ SOURCE CODE IS
  2587. AVAILABLE, BUT NOT AVAILABLE FOR THE ┬─╧╙ OR ├├╨.  (╙OURCE CODE IS NOT
  2588. AVAILABLE FOR THE ┬─╧╙ AND ├├╨ REPLACEMENTS MENTIONED IN THIS ARTICLE EITHER). 
  2589. ┴NOTHER REASON IS THAT THE ┬─╧╙ AND ├├╨ ARE INTENDED TO BE "INVARIABLE"
  2590. OPERATING SYSTEM COMPONENTS - THAT IS, THEY ARE IDENTICAL FOR DIFFERENT
  2591. COMPUTERS THAT RUN ├╨/═ ╨LUS.  ┴ STUDY OF THE ┬╔╧╙ SOURCE CODE WILL REVEAL
  2592. SEGMENTS OF CODE THAT CAN BE REMOVED IF THEY AREN'T NEEDED, AND WILL PROVIDE
  2593. HINTS AS TO NEW FEATURES THAT CAN BE ADDED.
  2594.  
  2595. ╘HE DISTRIBUTION PACKAGE, ┬╔╧╙-╥6.╠┬╥ INCLUDES DOCUMENTATION, SOURCE CODE,
  2596. UTILITIES, AND SUPPORT FILES.  ┬╔╧╙-╥6.╠┬╥ ALSO CONTAINS THE LATEST VERSION OF
  2597. ┌╨═3. [┼D. ╬OTE: ╘HE FILES MENTIONED IN THIS ARTICLE CAN BE FOUND VIA
  2598. ANONYMOUS ╞╘╨ OR VIA THE MAILSERVER THROUGH THE "PSEND" COMMAND.]
  2599.  
  2600.  
  2601. ┌╨═3 ╞EATURES
  2602.  
  2603. ┌╨═3 IS A REPLACEMENT ┬─╧╙ BY ╙IMEON ├RAN.  ╙INCE THE ┬─╧╙ IS SUPPOSED TO BE
  2604. "INVARIABLE," WHY WOULD ANYONE WANT TO REPLACE IT? ╘HE ANSWERS TO THAT ARE
  2605. PRETTY TYPICAL - BUG FIXES, SPEED ENHANCEMENTS, AND NEW FEATURES!  ┌╨═3
  2606. INTERACTS WITH THE ┬╔╧╙ AND ├├╨ IN MOST OF THE SAME WAYS AS THE STANDARD
  2607. ─IGITAL ╥ESEARCH ┬─╧╙, AND FOR THE MOST PART APPEARS TO BE A CLONE OF THE
  2608. STANDARD ┬─╧╙.  ╘HE STANDARD ┬─╧╙ WAS CODED IN 8080 ASSEMBLY TO MAKE IT
  2609. COMPATIBLE WITH MACHINES THAT USE THE OLDER SLOWER 8080 PROCESSOR.  ╓ERY FEW
  2610. (IF ANY) ├╨/═ ╨LUS MACHINES USED THE 8080. ┌╨═3 IS CODED IN FASTER, COMPACT ┌80
  2611. ASSEMBLY LANGUAGE, FOR THE ┌80 PROCESSOR THAT IS AT THE HEART OF MOST ├╨/═ ╨LUS
  2612. COMPUTERS (INCLUDING THE ├128).
  2613.  
  2614. ╘HE ┌╨═3 DOCUMENTATION DETAILS FIXES TO SEVERAL BUGS THAT HAVE PLAGUED ├╨/═
  2615. ╨LUS SINCE DAY ONE.  ┴LTHOUGH THE BUGS SOUND SOMEWHAT OBSCURE, THERE'S NO
  2616. TELLING WHEN ONE MIGHT CAUSE PROBLEMS.
  2617.  
  2618. ┌╨═3 IS MUCH FASTER THAN STANDARD ├╨/═ ╨LUS.  ╘HE INCREASED SPEED SHOULD BE
  2619. OBVIOUS AFTER USING IT FOR A SHORT TIME.
  2620.  
  2621. ╘HE NEW FEATURES OFFERED BY ┌╨═3 ARE REMARKABLE.  ╘HREE CLOSELY RELATED
  2622. FEATURES ARE ENHANCED COMMAND LINE EDITING, A HISTORY BUFFER THAT STORES AND
  2623. RECALLS MULTIPLE COMMANDS, AND ┴UTOMATIC ├OMMAND ╨ROMPTING.  ╘HESE FEATURES
  2624. WORK IN CONCERT TO PROVIDE A FLEXIBLE AND CONVENIENT COMMAND LINE INTERFACE. 
  2625. ├OMMAND LINE EDITING NOW HAS 20 CONTROL KEY FUNCTIONS FOR MOVING OR DELETING BY
  2626. CHARACTERS OR WHOLE WORDS.  ╘HE MOST RECENT COMMAND LINES (UP TO 250
  2627. CHARACTERS) ARE STORED IN THE HISTORY BUFFER, AND CAN BE RECALLED AND REUSED,
  2628. OR REEDITED IF NECESSARY.  ┴UTOMATIC ├OMMAND ╨ROMPTING IS BEST APPRECIATED IF
  2629. SEEN IN ACTION.  ╔T'S SIMILAR TO COMMAND LINE COMPLETION IN ╒NIX, EXCEPT THAT
  2630. IT'S AUTOMATIC, WITH MATCHING RESPONSES COMING DIRECTLY FROM THE HISTORY
  2631. BUFFER.  ╔F YOU'VE RECENTLY ENTERED A LONG COMMAND LINE WITH LOTS OF OPTIONS,
  2632. AND NEED TO REUSE IT (OR EDIT IT SLIGHTLY FIRST), TYPING THE FIRST FEW UNIQUE
  2633. CHARACTERS WILL BRING BACK THE ENTIRE COMMAND FROM THE HISTORY BUFFER IF IT'S
  2634. STILL INTACT.  ┴UTOMATIC ├OMMAND ╨ROMPTING IS SO RADICAL THAT IT MIGHT TAKE
  2635. SOME GETTING USED TO. ╔F YOU DON'T THINK YOU CAN GET USED TO IT, IT CAN BE SHUT
  2636. OFF.
  2637.  
  2638. ╘HE LATEST VERSION OF ┌╨═3, ┌╨═3╬08.┴╥╦, IS INCLUDED INSIDE ┬╔╧╙-╥6.╠┬╥, AND
  2639. CAN ALSO BE FOUND AS A SEPARATE FILE.
  2640.  
  2641.  
  2642.  
  2643. ┌├├╨ ─OCUMENTATION, ╓ERSION 1.0
  2644.  
  2645. ╘HE REMAINDER OF THIS ARTICLE WILL DESCRIBE ┌├├╨ AND HOW TO CONFIGURE A SYSTEM
  2646. DISK TO GET A FULLY FUNCTIONAL ┌╨═3/┌├├╨ SYSTEM UP AND RUNNING.  ┬╔╧╙-╥6 AND
  2647. ┌╨═3 BOTH COME WITH ENOUGH DOCUMENTATION TO KEEP YOU BUSY FOR HOURS, BUT ┌├├╨
  2648. HAS NEVER BEEN DISTRIBUTED BY ITSELF, BECAUSE UP UNTIL THIS ARTICLE, THERE HAS
  2649. NOT BEEN ANY DOCUMENTATION FOR IT.  ═OST OF THE DOCUMENTATION THAT FOLLOWS WAS
  2650. FIGURED OUT THROUGH EXPERIMENTATION AND LATER VERIFIED BY ╙IMEON ├RAN.
  2651.  
  2652. ┌├├╨ ╞EATURES
  2653.  
  2654. ╘HIS DOCUMENTATION IS PROVIDED TO ASSIST THE USER IN GETTING A ┌├├╨ SYSTEM UP
  2655. AND RUNNING.  ╔T IS NOT AN EXHAUSTIVE COURSE ON ┌- ╙YSTEM OR ┌├╨╥.  ╘HE
  2656. FOLLOWING LIST DETAILS WHICH ┌├╨╥ FEATURES ARE PROVIDED WITH ┌├├╨, AND WHICH
  2657. ONES AREN'T.
  2658.  
  2659.     * ┌├╨╥ 3.3 COMPATIBILITY.  ┌├├╨ CAN RUN A WIDE RANGE OF UTILITIES AN
  2660.     APPLICATIONS CREATED FOR ┌├╨╥ 3.3 AND ┌├╨╥ 3.4.
  2661.  
  2662.     * ╘├┴╨.  ┴ ┌3╘ TERMCAP FILE DESCRIBING TERMINAL CHARACTERISTICS CAN BE
  2663.     LOADED INTO THE SYSTEM.  ┌-╙YSTEM PROGRAMS MAKE USE OF THE ╘├┴╨ FOR OUTPUT
  2664.     TO THE SCREEN - A BIG IMPROVEMENT OVER THE OLD METHOD OF PATCHING
  2665.     INDIVIDUAL PROGRAMS WITH TERMINAL CONTROL CODES.  ╘├┴╨ FILES ARE LOADED BY
  2666.     THE ┌├├╨ ╠╧┴─╙┼╟ COMMAND.
  2667.  
  2668.     * ╬AMED DIRECTORIES.  ╒SER AREAS CAN BE ASSIGNED NAMES.  ╒P TO 12 USER
  2669.     AREAS CAN BE ASSIGNED NAMES.  ╬AMED ─IRECTORY ╥EGISTERS (*.╬─╥ FILES) ARE
  2670.     LOADED BY THE ┌├├╨ ╠╧┴─╙┼╟ COMMAND.
  2671.  
  2672.     * ├OMMAND ╙EARCH ╨ATH.  ┌├├╨ WILL SEARCH FOR COMMANDS ALONG A USER DEFINED
  2673.     SEARCH PATH.  ╒P TO SIX PATH ELEMENTS (DIRECTORIES) CAN BE DEFINED.
  2674.  
  2675.     * ┼NVIRONMENT BLOCK.  ├ONTAINS ╘├┴╨, ╬AMED ─IRECTORY, AND ╨ATH INFORMATION. 
  2676.     ┴LSO INCLUDES A MAP OF ACTIVE DISK DRIVES AND OTHER SYSTEM INFORMATION. 
  2677.     ╘HE ENVIRONMENT BLOCK CAN BE VIEWED WITH THE ┌-╙YSTEM ╙╚╧╫ UTILITY.
  2678.  
  2679.     * ╞LOW CONTROL.  ├ONDITIONAL PROCESSING FOR BATCH FILES.  ╥ELIES ON
  2680.     ┌-╙YSTEM ╔╞.├╧═ FOR SETTING THE FLOW STATE.  ╧THER FLOW CONTROL COMMANDS
  2681.     (╞╔, ┼╠╙┼, ╪╔╞, ╧╥, ┴╬─) ARE RESIDENT.
  2682.  
  2683.     * ═ULTIPLE COMMANDS CAN BE ENTERED ON THE COMMAND LINE.  ╘HE COMMAND LINE
  2684.     BUFFER WILL HOLD UP TO 225 CHARACTERS.  ├OMMANDS SHOULD BE SEPARATED BY
  2685.     SEMICOLONS.
  2686.  
  2687.     * ┼XTENDED ├OMMAND ╨ROCESSOR.  ╔F A COMMAND IS NOT A BUILT-IN FLOW COMMAND,
  2688.     RESIDENT COMMAND, OR LOCATED ON DISK ALONG THE SEARCH PATH, THE COMMAND
  2689.     LINE IS PASSED TO AN EXTENDED COMMAND PROCESSOR.  ┴ TYPICAL EXTENDED
  2690.     COMMAND PROCESSOR IS ┴╥╒╬┌, A SOPHISTICATED BATCH FILE EXECUTOR WITH ALIAS
  2691.     FEATURES.  ╘O USE A PROGRAM AS AN EXTENDED COMMAND PROCESSOR, RENAME IT TO
  2692.     ├═─╥╒╬.├╧═ AND PLACE IT IN THE ╥╧╧╘ DIRECTORY OF YOUR BOOT DISK.
  2693.  
  2694.     * ┼RROR HANDLER.  ╔N THE EVENT THAT THE EXTENDED COMMAND PROCESSOR CAN'T
  2695.     HANDLE A COMMAND, CONTROL IS PASSED TO AN ERROR HANDLER.  ┼RROR HANDLERS
  2696.     GIVE INFORMATION ABOUT THE ERROR (INSTEAD OF THE USELESS ├╨/═ "?" MESSAGE)
  2697.     AND ALLOW THE COMMAND LINE TO BE EDITED AND REUSED.
  2698.  
  2699.     * ╥ESIDENT COMMANDS.  ╘HE FOLLOWING COMMANDS ARE BUILT IN: 
  2700.       ├╠╙  - CLEARS THE SCREEN 
  2701.       ╬╧╘┼ - TEXT FOLLOWING THE ╬╧╘┼ COMMAND IS TREATED AS A COMMENT.
  2702.       ╞╔   - ╞LOW CONTROL:  TERMINATE THE CURRENT 
  2703.       ╔╞ LEVEL ┼╠╙┼ - ╞LOW CONTROL:  TOGGLE THE FLOW STATE
  2704.       ╪╔╞  - ╞LOW CONTROL:  EXIT ALL PENDING ╔╞ LEVELS 
  2705.       ╧╥   - ╞LOW CONTROL:  ╧╥ ╔╞ TESTS TO SET FLOW STATE 
  2706.       ┴╬─  - ╞LOW CONTROL:  ┴╬─ ╔╞ TESTS TO SET FLOW STATE
  2707.  
  2708.     * ╙HELL STACK.  ╒P TO FOUR SHELL LEVELS CAN BE DEFINED.  ┌-╙YSTEM PROVIDES
  2709.     A CHOICE OF SEVERAL DIFFERENT SHELLS.  ┴PPLICATIONS SUCH AS TERMINAL
  2710.     PROGRAMS AND WORD PROCESSORS CAN ALSO BE ASSIGNED SHELL STATUS.
  2711.  
  2712.     * ┌├├╨ USES THE ╠╧┴─╙┼╟ COMMAND FOR DIRECT LOADING OF ╥╙╪ FILES THAT HAVE
  2713.     NOT BEEN ╟┼╬├╧═ED.  ┼XAMPLE: ╠╧┴─╙┼╟ ╙┴╓┼.╥╙╪ LOADS ╙┴╓┼.╥╙╪.
  2714.  
  2715.     ╘HERE ARE SOME THINGS THAT ┌3╨LUS WILL DO THAT ┌├├╨ WON'T DO.
  2716.  
  2717.     - ┌├├╨ DOES NOT SUPPORT A ╞LOW ├OMMAND ╨ACKAGE (╞├╨).  ╔T RELIES ON THE
  2718.     TRANSIENT ╔╞ COMMAND.  ╧THER FLOW COMMANDS (╞╔, ┼╠╙┼, ╪╔╞, ╧╥, ┴╬─) ARE
  2719.     RESIDENT IN ┌├├╨.
  2720.  
  2721.     - ┴ ╥ESIDENT ├OMMAND ╨ACKAGE (╥├╨) IS NOT IMPLEMENTED.  ├╠╙ AND ╬╧╘┼ ARE
  2722.     RESIDENT IN ┌├├╨.  ┴LL OTHER COMMANDS MUST BE LOADED FROM DISK.  ╘HIS ISN'T
  2723.     AS MUCH OF A HANDICAP AS IT MIGHT SOUND IF YOU HAVE A FAST ╥┴═ DRIVE, SUCH
  2724.     AS A ├┬═ 17XX ╥┼╒, ╤UICK ┬ROWN ┬OX, OR ╥┴═╠INK.
  2725.  
  2726.     - ┌├├╨ CAN NOT LOAD TYPE 4 PROGRAMS (USED WITH ┌├╨╥ 3.4).  ╔T LOADS
  2727.     STANDARD ├╧═ FILES AT 100╚, AND TYPE 3 PROGRAMS THAT LOAD HIGHER IN MEMORY. 
  2728.     ═OST TYPE 4 PROGRAMS HAVE TYPE 3 OR ├╧═ EQUIVALENTS.
  2729.  
  2730.     - ┌├├╨ CAN NOT REEXECUTE LOADED PROGRAMS.  ╘HIS TRICK IS USUALLY PERFORMED
  2731.     ON ┌-╙YSTEMS WITH A ╟╧ COMMAND THAT JUMPS TO 100╚. ╙INCE ┌├├╨ ALSO LOADS AT
  2732.     100╚, A ╟╧ COMMAND WOULD ONLY RESTART ┌├├╨.
  2733.  
  2734.  
  2735. ╘HE ╞ILES
  2736.  
  2737. ╘HREE FILES ARE INCLUDED IN ┌├├╨.┴╥╦:
  2738.  
  2739.  ╞ILE NAME      ╙IZE  ─ESCRIPTION
  2740.  ============   ====  ==========================================
  2741.  ├├╨     .├╧═   3K    ┌├├╨ REPLACEMENT FOR ├├╨.├╧═
  2742.  ╠╧┴─╙┼╟ .├╧═   3K    ╠OADER FOR NAMED DIRECTORIES AND TERMCAPS
  2743.  ┌╔╬╙╘┴╠ .┌╨═   1K    ╙EGMENT CONTAINING ENVIRONMENT INFORMATION
  2744.  
  2745.  
  2746. ╟ETTING ╙TARTED - ╨REPARING A ┬OOT ─ISK
  2747.  
  2748. ╞ORMAT A ├OMMODORE ├╨/═ FORMAT 5.25 OR 3.5 INCH DISK.  ┌├├╨ MUST BE BOOTED FROM
  2749. DEVICE 8 (├╨/═ DRIVE ┴).
  2750.  
  2751. ├OPY THE FILES FROM ┌├├╨.┴╥╦ TO USER AREA 0 OF THE NEWLY FORMATTED DISK.
  2752.  
  2753. ├OPY ├╨═+.╙┘╙ TO USER 0 OF THE BOOT DISK.  ╘HE ├╨═+.╙┘╙ MUST HAVE BEEN
  2754. GENERATED USING THE ┬─╧╙ SEGMENTS FROM ┌╨═3.
  2755.  
  2756. ╠OCATE A COPY OF A ┌-╙YSTEM ALIAS UTILITY.  ┴ GOOD ONE IS ╙┴╠╔┴╙16, ALTHOUGH
  2757. OTHERS SHOULD WORK ALSO.  ├OPY IT TO USER 0 OF THE BOOT DISK.
  2758.  
  2759. ┴T THIS POINT, HIT THE RESET SWITCH AND BOOT THE SYSTEM WITH THE NEW DISK. 
  2760. ┴FTER THE SYSTEM BOOTS, YOU WON'T BE ABLE TO DO MUCH WITH IT.  ╘HE ONLY
  2761. RESIDENT COMMANDS ARE ├╠╙ AND ╬╧╘┼, AND ┌├├╨ CAN ONLY LOCATE COMMANDS IF THEY
  2762. ARE PREFIXED WITH THE DRIVE AND USER NUMBER.
  2763.  
  2764. ╘HE NEXT STEP IS TO CREATE A STARTUP ALIAS.  ╫HEN ┌├├╨ BOOTS, IT LOOKS FOR A
  2765. FILE NAMED ╙╘┴╥╘┌╨═.├╧═ AND EXECUTES COMMANDS FROM IT.  ╙╘┴╥╘┌╨═.├╧═ IS CREATED
  2766. WITH A ┌├╨╥ ALIAS UTILITY.  ╚ERE IS A LISTING OF A ╙╘┴╥╘┌╨═.├╧═ CREATED WITH
  2767. ╙┴╠╔┴╙:
  2768.  
  2769.      =============================================================
  2770.  
  2771.      ┴0>╙┴╠╔┴╙ ╙╘┴╥╘┌╨═
  2772.  
  2773.      15:                ; ╠OGS THE ╥╧╧╘ DIRECTORY (┴15) ON THE
  2774.                         ; CURRENT DRIVE.
  2775.  
  2776.      ╤─ ╞/╞             ; ╔NSTALLS ╤UICK ┬ROWN ┬OX RAMDISK DRIVER.
  2777.  
  2778.      ╠╧┴─╙┼╟ ╬┴═┼╙.╬─╥ ├128-╪┬╥.┌3╘
  2779.                         ; ╠╧┴─╙┼╟ LOADS THE ╬AMED ─IRECTORY ╥EGISTER
  2780.                         ; AND ╘├┴╨.
  2781.                         ; ─IRECTORIES CAN NOW BE REFERRED TO BY
  2782.                         ; NAME, AS IN THE NEXT COMMAND:
  2783.  
  2784.      ╙┼╘╨╘╚10 /├ ├╧══┴╬─╙ ╥┼╒ 1581 $$$$ $$0 ╥╧╧╘
  2785.                         ; ╙┼╘╨╘╚ SETS THE COMMAND SEARCH PATH.
  2786.                         ; ╘HE /C OPTION FIRST CLEARS ANY EXISTING PATH.
  2787.                         ; ─IRECTORIES ARE THEN LISTED IN THE
  2788.                         ; ORDER SEARCHED.  ╔N THIS CASE, ├╧══┴╬─╙
  2789.                         ; IS A 64╦ ╤┬┬ RAMDISK (DRIVE/USER ╞0) WHERE
  2790.                         ; FREQUENTLY USED COMMANDS ARE STORED.  ╥┼╒ IS
  2791.                         ; A 1750 ╥┼╒ (DRIVE/USER ═0).  1581 IS A 1581
  2792.                         ; DRIVE, (DRIVE/USER ├15) WHERE SOME 700╦
  2793.                         ; OF UTILITIES AND APPLICATIONS ARE
  2794.                         ; LOCATED.  $$$$ REFERS TO THE CURRENTLY
  2795.                         ; LOGGED DRIVE AND USER AREA.  $$0 REFERS
  2796.                         ; TO USER AREA 0 OF THE CURRENT DRIVE.
  2797.                         ; ╘HE ╥╧╧╘ DIRECTORY IS ON DRIVE ┴, USER
  2798.                         ; 15, WHERE STARTUP UTILITIES AND SYSTEM
  2799.                         ; FILES CAN BE FOUND.
  2800.  
  2801.      1571 [┴┬           ; ╘HIS SPEEDS UP 1571 DISK DRIVES ┴ AND ┬
  2802.                         ; BY SHUTTING OFF THE REDUNDANT WRITE VERIFY.
  2803.  
  2804.      ┴╒╘╧╘╧╟ ╧╬         ; ╘URNS ON KEYBOARD CONTROL OF ┌╨═3 ┴UTO
  2805.                         ; ├OMMAND ╨ROMPTING.  ┴UTO ├OMMAND
  2806.                         ; ╨ROMPTING IS TOGGLED BY ENTERING ├╘╥╠-╤.
  2807.  
  2808.      ├╧══┴╬─╙:          ; ╠OGS THE COMMANDS DIRECTORY.
  2809.  
  2810.      ╔╞ ~┼╪╔╙╘ ├╨.*     ; ╘EST TO SEE IF COMMANDS ARE LOADED.
  2811.                         ; ╘HIS LINE READS:  "╔F THE ├╨ COMMAND
  2812.                         ; DOES NOT EXIST . . ." AND SETS THE FLOW
  2813.                         ; STATE TO TRUE IF THE FILE DOESN'T EXIST.
  2814.         ╤─ ╔/╞          ; ". . . THEN INITIALIZE THE ╤┬┬ . . ."
  2815.         ├1:├╨ ├1:*.* ╞0:
  2816.                         ; ". . . COPY ALL OF THE COMMANDS IN
  2817.                         ; DRIVE/USER ├1 TO THE COMMANDS (╞0)
  2818.                         ; DIRECTORY . . ."
  2819.      ╞╔                 ; ". . . END IF."
  2820.  
  2821.      ╥╧╧╘:              ; ╠OG THE ROOT DIRECTORY (┴15).
  2822.  
  2823.      ├╨ ├:┌╞*.* ═0:     ; ├OPY ┌╞╔╠┼╥.├╧═ AND ┌╞╔╠┼╥.├═─ TO THE
  2824.                         ; ╥┼╒ DIRECTORY (═0).
  2825.  
  2826.      ╓┼╥╥╧╥             ; ╔NSTALL ╓┼╥╥╧╥ ERROR HANDLER.
  2827.  
  2828.      ─┴╘┼ ╙             ; ╙ET THE SYSTEM TIME AND DATE.
  2829.  
  2830.      ┌╞                 ; ╔NVOKE ┌╞╔╠┼╥ AS A SHELL.
  2831.  
  2832.      =============================================================
  2833.  
  2834. ╧F COURSE, YOUR ╙╘┴╥╘┌╨═ ALIAS WILL VARY DEPENDING ON THE HARDWARE YOU NEED TO
  2835. SUPPORT, YOUR SOFTWARE PREFERENCES, AND YOUR WORK HABITS.  ╘HIS ALIAS IS CLOSE
  2836. TO THE UPWARD SIZE LIMIT THAT ┌├├╨ CAN HANDLE BASED ON THE CAPACITY OF THE
  2837. MULTIPLE COMMAND BUFFER.  ┴T THE VERY LEAST, ╔ RECOMMEND AN ALIAS THAT WILL SET
  2838. UP A SEARCH PATH AND LOAD A ╘├┴╨.
  2839.  
  2840. ┴CTUALLY, ╔ PUT THE CART BEFORE THE HORSE IN THIS EXAMPLE.  ╔F YOU TRY TO
  2841. REBOOT YOUR SYSTEM WITH THE ╠╧┴─╙┼╟ COMMAND AS LISTED, YOU'LL NOTICE THAT YOU
  2842. DON'T HAVE A ╬┴═┼╙.╬─╥ FILE.  ╘HERE ISN'T ONE DISTRIBUTED WITH ┌├├╨ EITHER. 
  2843. ┌-╙YSTEM UTILITIES WON'T LET YOU EDIT THE ╬─╥ EITHER, SINCE THE BUFFER FOR IT
  2844. HASN'T BEEN CREATED YET.  ╘HIS TURNED OUT TO BE A NASTY CHICKEN/EGG SITUATION,
  2845. HOPEFULLY SOLVED BY THE INCLUSION OF A SAMPLE ╬┴═┼╙.╬─╥ FILE CONTAINING SIMPLY
  2846. ┴0:╙┘╙╘┼═ AND ┴15:╥╧╧╘.
  2847.  
  2848. ┴T THIS POINT, YOU SHOULD HAVE A MOSTLY FUNCTIONING ┌├├╨ SYSTEM DISK.  ╨RESS
  2849. RESET AND BOOT IT UP.  ┘OU MIGHT WANT TO CORRECT ANY PROBLEMS WITH IT OR TWEAK
  2850. IT TO PERFECTION BEFORE MOVING ON.
  2851.  
  2852.  
  2853. ╠IST OF ┌-╙YSTEM ╒TILITIES FOR ┌├├╨
  2854.  
  2855. ╙OME OF THE FOLLOWING UTILITIES ARE ESSENTIAL, OTHERS ARE NICE TO HAVE.  ╘HE
  2856. VERSION NUMBERS LISTED ARE THE LATEST KNOWN VERSIONS AT THE TIME THAT THIS
  2857. DOCUMENTATION WAS WRITTEN.  ╒TILITIES CAN BE FOUND ON ┌╬ODE ┬┬╙S, AND SOME OF
  2858. THEM ARE AVAILABLE ON ╙IMTEL20 OR ITS MIRROR SITES.  ╙OME OF THE MORE IMPORTANT
  2859. UTILITIES WILL BE UPLOADED TO CCO.CALTECH.EDU.
  2860.  
  2861.          ╙┴╠╔┴╙16  - ALREADY MENTIONED IN THE EXAMPLE ABOVE.  ╙┴╠╔┴╙ (OR ONE OF
  2862.          THE OTHER ┌├╨╥ ALIAS UTILITIES) ARE ESSENTIAL.
  2863.  
  2864.          ┴╥├╧╨┘    - NOT A ┌├╨╥ UTILITY, BUT ONE OF THE BEST ├╨/═ FILE COPIERS
  2865.          EVER.
  2866.  
  2867.          ╙─138┬    - EXCELLENT ─╔╥ECTORY UTILITY.  ╙─ OFFERS MANY DIFFERENT
  2868.          TYPES OF SORTS, LIST FORMATS, ETC., DISPLAYS DATE STAMPS, AND SUPPORTS
  2869.          OUTPUT TO A FILE.
  2870.  
  2871.          ═╦─╔╥32   - UTILITY FOR MANIPULATING DIRECTORY NAMES AND ╬AMED
  2872.          ─IRECTORY ╥EGISTER (*.╬─╥) FILES.
  2873.  
  2874.          ┼╥┴╙┼57   - ERASES FILES.
  2875.  
  2876.          ┌╞╔╠┼╥10  - A FILE MANAGEMENT SHELL THAT CAN LAUNCH APPLICATIONS. ╔T
  2877.          IS PROGRAMMABLE IN THAT IT CAN EXECUTE USER DEFINED MACROS FROM A
  2878.          FILE.  ═ULTIPLE FILES CAN BE "TAGGED" AND OPERATED ON BY OTHER
  2879.          PROGRAMS.  ┌╞╔╠┼╥ IS AN EXCELLENT PROGRAM, SORT OF A ╟╒╔ DESKTOP
  2880.          WITHOUT THE SLOW GRAPHICS.
  2881.  
  2882.          ├128-╪╟╥  - A LIBRARY OF E╪TENDED ╟╥APHICS TERMCAPS FOR THE ├128. ╘HIS
  2883.          FILE IS ESSENTIAL IF YOU WANT TO USE ANY ┌├╨╥ PROGRAMS THAT NEED A
  2884.          ╘├┴╨.  ╘HESE TERMCAPS ARE THE FIRST FOR THE ├128 THAT IMPLEMENT
  2885.          CHARACTER GRAPHICS, STANDOUT MODE, AND CONTROL OF BLINKING REVERSE,
  2886.          AND UNDERLINE MODES.
  2887.  
  2888.          ╙┼╘╨╘╚10  - USED TO SET THE COMMAND SEARCH PATH.  ┼SSENTIAL!
  2889.  
  2890.          ╓┼╥╥╧╥17  - ERROR HANDLER THAT DISPLAYS THE COMMAND LINE FOR
  2891.          REEDITING.  ╓┼╥╥╧╥17 IS THE ONLY ERROR HANDLER THAT ╔ FOUND THAT WORKS
  2892.          WITH ┌├├╨.
  2893.  
  2894.          ┌┼╪50     - ┌-╙YSTEM ┼╪ECUTIVE IS A POWERFUL BATCH FILE PROCESSOR THAT
  2895.          REPLACES THE ├╨/═ ╙╒┬═╔╘ COMMAND.
  2896.  
  2897.          ╠┬╥╚╠╨22  - ┌-╙YSTEM ╚ELP UTILITY DISPLAYS HELP FILES.  ╚ELP FILES CAN
  2898.          BE CRUNCHED (*.╚┌╨), AND/OR LOADED FROM A ╚┼╠╨.╠┬╥ LIBRARY.
  2899.  
  2900.          ┴╥╒╬┌09   - RUNS AN ALIAS SCRIPT FROM A TEXT FILE.  ┴╥╒╬┌ IS
  2901.          FREQUENTLY USED AS AN EXTENDED COMMAND PROCESSOR.  ╘O USE ┴╥╒╬┌ (OR
  2902.          ANY OTHER EXECUTABLE UTILITY) AS AN EXTENDED COMMAND PROCESSOR, RENAME
  2903.          IT TO ├═─╥╒╬.├╧═.
  2904.  
  2905.          ╓╠╒102    - ╓IDEO ╠IBRARY ╒TILITY VIEWS OR EXTRACTS FILES FROM
  2906.          LIBRARIES.  ╓ERSIONS OF ╓╠╒ ABOVE 1.02 DO NOT WORK RELIABLY WITH
  2907.          ┌╨═3/┌├├╨.
  2908.  
  2909.          ┌33╔╞16   - IS THE ╔╞.├╧═ DISCUSSED IN THE SECTION ON FLOW CONTROL.
  2910.  
  2911.          ╙╚╧╫14    - DISPLAYS AN IMMENSE AMOUNT OF INFORMATION ABOUT YOUR
  2912.          ┌-╙YSTEM.  ╙╚╧╫ ALSO INCLUDES A MEMORY PATCHING FUNCTION.
  2913.  
  2914.          ┌├╬╞╟24   - CONFIGURES ┌-╙YSTEM PROGRAM OPTIONS.  ═OST ┌-╙YSTEM
  2915.          PROGRAMS ARE DISTRIBUTED WITH A CONFIGURATION (*.├╞╟) FILE THAT
  2916.          PRODUCES A MENU OF CONFIGURATION OPTIONS WHEN RUN WITH ┌├╬╞╟.
  2917.  
  2918.          ┌╨17      - ┌-╙YSTEM ╨ATCH UTILITY EDITS FILES, DISK SECTORS, OR
  2919.          MEMORY, AND INCLUDES A BUILT-IN ╥╨╬ CALCULATOR AND NUMBER BASE
  2920.          CONVERTER.
  2921.  
  2922.          ┌═┴╬-╬┼╫  - ╘HIS IS A MANUAL DESCRIBING ┌-╙YSTEM FEATURES IN DEPTH. 
  2923.          ╔T IS BASED ON EARLIER VERSIONS OF ┌-╙YSTEM, AND IS A LITTLE DATED,
  2924.          BUT OTHERWISE CONTAINS INFORMATION THAT YOU WON'T FIND ANYWHERE ELSE. 
  2925.          ╬OT EVERYTHING IN THE MANUAL APPLIES TO OPERATION OF ┌╨═3/┌├├╨, BUT
  2926.          WITH THE DOCUMENTATION PRESENTED HERE, YOU SHOULD BE ABLE TO GET A
  2927.          GOOD IDEA OF WHAT WORKS AND WHAT DOESN'T.
  2928.  
  2929.  
  2930. ┌├├╨ ╘ECHNICAL ╬OTES
  2931.  
  2932. ┌├├╨ IS A REPLACEMENT ├├╨ THAT IMPLEMENTS ┌├╨╥ 3.3.  ╔T LOADS AT 100╚ AND IS
  2933. STORED IN THE BANK 0 ├├╨ BUFFER FOR FAST RELOADING AS DOES THE STANDARD ├├╨. 
  2934. ┬Y CONTRAST, ┌3╨LUS LOADS INTO HIGH MEMORY AND CAN BE OVERWRITTEN BY TRANSIENT
  2935. COMMANDS, REQUIRING RELOADING ┌3╨LUS FROM DISK.  ┬ECAUSE ┌├├╨ REPLACES THE ├├╨,
  2936. A ┌├├╨ SYSTEM HAS MORE ╘╨┴ (TRANSIENT PROGRAM AREA) THAN A ┌3╨LUS SYSTEM.  ┴
  2937. ┌├├╨ SYSTEM ON THE ├128 HAS MORE THAN 57╦ OF ╘╨┴, ALMOST THE SAME AMOUNT AS A
  2938. STANDARD ├128 ├╨/═ SYSTEM.
  2939.          
  2940. ╘HIS SHOULD BE ENOUGH INFORMATION TO GET STARTED WITH ┌╨═3/┌├├╨. ╙ET UP A BOOT
  2941. DISK, EXPERIMENT WITH SOME ┌-╙YSTEM UTILITIES, READ ┌═┴╬-╬┼╫, AND GET SOME
  2942. APPLICATIONS RUNNING.  ┘OU'LL AGREE THAT ┌╨═3/┌├├╨ BREATHS NEW LIFE INTO ├╨/═.
  2943.  
  2944. =============================================================================
  2945. ═ULTI-╘ASKING ON THE ├=128 - ╨ART 1
  2946. BY ├RAIG ╘AYLOR (DUCK@PEMBVAX1.PEMBROKE.EDU)
  2947.  
  2948. ╔.    ╔NTRODUCTION / ╨ACKAGE ╧VER-VIEW..
  2949.  
  2950.  ╘HIS ARTICLE WILL DETAIL THE MULTI-TASKING KERNAL WHICH ╔ HAVE WRITTEN BUTT
  2951.  IS STILL IN THE DEBUGGING STAGE . ╘HE DOCUMENTATION IS BEING RELEASED NOW AS
  2952.  ├= ╚ACKING HAS BEEN DELAYED FOR A MONTH WHILE THIS ARTICLE AND A FEW OTHERS
  2953.  WERE IN THE PROCESS OF BEING SHAPED. ╘HE SOURCE CODE LISTINGS, BINARIES, AND
  2954.  A FEW SAMPLE PROGRAMS WILL BE IN THE NEXT ISSUE OF ├= ╚ACKING AS WELL AS
  2955.  AVAILABLE ON THE MAILSERVER AND ON ╥. ╦NOP'S ╞╘╨ SITE WHEN THEY ARE
  2956.  AVAILABLE..
  2957.  
  2958.  ╘HE ├OMMODORE 128 DOES NOT SUPPORT ╘╥╒┼ MULTI-TASKING IN THAT THE PROCESSOR
  2959.  HANDLES SWAPPING FROM TASK TO TASK. ╥ATHER THE PACKAGE WILL MAKE USE OF THE
  2960.  INTERRUPTS OCCURING SIXTY TIMES A SECOND TO DETERMINE WHEN TO SWITCH TASKS..
  2961.  ╘HE ├OMMODORE 128 GREATLY SIMPLIFIES THINGS AS IN ADDATION TO THE INTERRUPTS
  2962.  IT ALSO HAS THE PROVISION TO RELOCATE ZERO PAGE AND THE STACK PAGE. ╙O THE
  2963.  PACKAGE BASICALLY WORKS BY INTERCEPTING THE ╔╥╤ VECTOR, TAKING A LOOK AT THE
  2964.  CURRENT JOB, SAVING THE STACK POINTER, FINDING THE NEXT ACTIVE JOB, LOADING
  2965.  THE STACK PAGE AND REGISTERS AND RESUMING THE NORMAL ╔╥╤ AS IF NOTHING HAD
  2966.  EVER HAPPENED.
  2967.  
  2968.  ╒NFORTUNATLY ├OMMODORE NEVER THOUGHT OF HAVING MULTIPLE PROGRAMS IN MEMORY
  2969.  EXECUTING AT ANY GIVEN TIME. ╚ENCE, PROBLEMS WILL OCCUR WITH FILE ACCESSES,
  2970.  WITH MEMORY CONTENTION, AND WITH AN OVER-ALL SLOWDOWN IN SPEED. ╘HE PACKAGE
  2971.  WILL DETAIL HOW TO HANDLE DEVICE CONTENTIONS, BUT IT'S RECOMMENDED THAT
  2972.  PROGRAMMERS MAKE USE OF THE ├= 128 KERNAL CALL ╠╦╒╨╠┴ $FF59 CONTAINING THE
  2973.  LOGICAL FILE NUMBER THEY WISH TO USE IN .┴; IF THE CARRY FLAG IS SET UPON
  2974.  RETURN THEN IT IS SAFE TO USE, ELSE FIND ANOTHER ONE AS ANOTHER PROGRAM IS
  2975.  USING IT. ╚OWEVER, NOTE THAT IF YOU HAVE MULTIPLE PROGRAMS DOING THIS THEN
  2976.  YOU MAY HAVE PROBLEMS WITH ONE GRABBING A LOGICAL FILE NUMBER AFTER THE
  2977.  OTHER PROCESS HAS CHECKED FOR IT. ═ULTI-TASKING IS FUN 'EH?  ╨ROBLEMS LIKE
  2978.  THIS WILL BE EXAMINED WHEN WE GET INTO SEMAPHORES LATER IN THIS ARTICLE..
  2979.  
  2980.  ├RAIG ┬RUCE'S ─YNAMIC ═EMORY ┴LLOCATION ARTICLE IN THE SECOND ISSUE OF ├=
  2981.  ╚ACKING SHOULD PROVIDE A VERY STRONG BASIS FOR A FULL-BLOWN MEMORYY MANAGER.
  2982.  ╫ITH MINOR MODIFICATIONS (BASICALLY JUST CHANGING THE INITIAL ALLOCATIONS SO
  2983.  THAT THE PACKAGE IS NOT KILLED) IT SHOULD BE ABLE TO WORK.  ┴LSO IT WILL NEED
  2984.  CHANGES TO MAKE SURE THAT PROCESSES DON'T TRY TO ALLOCATE AT THE SAME TIME.
  2985.  ╙O A MEMORY MANAGER IS NOT TOO MUCH OF A PROBLEM. ─ETAILS OF WHAT CHANGES
  2986.  WILL BE NECESSARY SHALL BE IN THE NEXT ISSUE.
  2987.  
  2988.  ╫HAT IS A PROCESS? ╫HAT IS A PROGRAM? ╔'VE BEEN USING THE TERMS ALMOST
  2989.  INTER-CHANGEBLY THROUGHOUT THIS ARTICLE AT THIS POINT. ┬ASICALLY ╔'M CALLING
  2990.  THEM THE SAME. ┴ PROCESS, OR PROGRAM IS DEFINED AS A PROGRAM WITH IT'S OWN
  2991.  EXECUTABLE SECTION, IT'S OWN DATA SECTIONS, AND IT'S OWN STACK AND ZERO PAGE.
  2992.  (╬OTE, HOWEVER, THAT THE MULTI-TASKING PACKAGE DOES NOT SUPPORT RELOCATION OF
  2993.  THE ZERO PAGE ALTHOUGH THIS IS LIKELY TO CHANGE).  ╘HE "KERNAL" OF THE
  2994.  MULTI-TASKER IS BASICALLY THAT PART OF THE PACKAGE WHICH GOVERNS WHICH
  2995.  PROCESS IS EXECUTED OR SWITCHED TO NEXT. ╙EMAPHORES WILL BE EXAMINED IN
  2996.  DETAIL LATER; THEY FUNCTION AS FLAGS FOR PROCESSES TOO KNOW WHEN IT IS SAFE
  2997.  TO EXECUTE SOMETHING, AND SERVE AS SIGNALS BETWEENN THEM.
  2998.  
  2999.  ╞UTURE VERSIONS OF THE PACKAGE, (EVEN THOUGH ╔ KNOW IT DOES NOT EXIST OUT
  3000.  SIDE OF MY HOUSE YET), WILL SUPPORT PIPES AND A MORE STRONGLY TYPED KERNAL
  3001.  SO THAT PROCESSES MAY BE PRIORITIZED.
  3002.  
  3003. ╔╔.   ┴ ╠OOK ┴T ═ULTI-╘ASKING
  3004.  
  3005.  ╘HE INTRODUCTION INTRODUCED SOME BASIC ELEMENTS OF MULTI-TASKING BUT ╔'LL
  3006.  REPEAT THEM HERE, DEFINING THEM SO THAT THIS ARTICLE CAN BE CLEAR AS SOME OF
  3007.  THE CONCEPTS CAN GET A BIT CONFUSING.
  3008.  
  3009.     ┬ACKGROUND - ┴ PROCESS IS SAID TO BE IN THE "BACKGR OUND" IF IT IS NOT
  3010.     THE FOREGROUND TASK AND MAY OR MAY NOT HAVE INPUT DEVI CES ASSOCIATED
  3011.     WITH IT.
  3012.  
  3013.     ╞OREGROUND - ┴ PROCESS IS SAID TO BE "FOREGROUND" IF IT IS THE MAIN
  3014.     ACTIVE PROCESS AND IS HOLDING THE KEYBOARD AND SCREEN DISPLAY CAPTIVE
  3015.     (IE: THE USER IS ACTUALLY WORKING WITHIN IT).
  3016.   
  3017.     ╦ERNAL  - ┴ SMALL SECTION OF CODE THAT PERFORMS LOW-LEVAL WORK THAT IS 
  3018.     NEEDED BY ANY PROGRAMS IN MEMORY..
  3019.  
  3020.     ═ULTI-╘ASKING - ┼XECUTION OF MORE THAN ONE PROCESS AT ANY GIVEN
  3021.     TIME.
  3022.  
  3023.     ╨RIORITY - ┴ VALUE ASSOCIATED WITH EACH PROCESS THAT DETERMINES HOW
  3024.     OFTEN, AND POSSIBLY WHEN A PROCESS IS EXECUTED.
  3025.  
  3026.     ╨ROCESS - ╘HE SPACE IN MEMORY TAKEN UP BY EXECUTABLE PROGRAM CODE, ANY
  3027.     ASSOCIATED DATA, THE STACK AND THE REGISTERS ASSOCIATED AND CURRENTLY IN
  3028.     USE BY IT, INCLUDING THE CURRENT ╨├ (PROGRAM COUNTER)..
  3029.  
  3030.     ╙EMAPHORES - ╓ALUES THAT ARE GLOBALLY ACCESSED BY PROCESSES TO SHARE AND
  3031.     COMMUNICATE INFORMATION BETWEEN EACH OTHER AND THE KERNAL.
  3032.  
  3033.  ╙OME ├╨╒'S HAVE AVAILABLE A MULTI- TASKING MODE (THE 386 AND 486 ARE THE
  3034.  MOST FAMALIAR ONES THAT COME TO MIND), Y ET THE 8502 CHIP CONTAINED INSIDE
  3035.  THE ├OMMODORE 128 WAS FIRST DESIGNED BEFORE 1985 AND LACKS MULTI-TASKING. ╔T
  3036.  WOULD BE NICE IF SUCH A MULTI-TASKING ├╨╒ IN THE 6502 FAMILY DID EXIST BUT
  3037.  IT WOULD ALSO CREATE PROBLEMS WITH THE 6502 STYLE ARCHITECTURE AND WOULDD
  3038.  PRODUCE SEVERE COMPATIBILITY PROBLEMS.
  3039.  
  3040.  ╙O HOW IS THE ├=128 SUPPOSED TO DO MULTI-TASKING? ╫ELL, WE'LL "SIMULATE"
  3041.  IT..
  3042.  
  3043.  ┬ASICALLY IF WE HAD TWO PROGRAMS IN MACHINE LANGUAGE:
  3044.  
  3045.             ╨ROGRAM 1:                            ╨ROGRAM 2:
  3046.           - LDA #65    ; THE "┴" CHARACTER     - LDA #64    ; THE "@" CHARACTER
  3047.             JSR $FFD2  ; PRINT IT                JSR $FFD2  ; PRINT IT
  3048.             JMP -                                JMP --
  3049.  
  3050.  ┴ND WE WANTED THEM TO MULTI-TASK WE'D EXPECT SOMETHING LIKE THE FOLLOWING:
  3051.  
  3052. @┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴@┴┴
  3053.  
  3054.  ╔T'S UNLIKELY THAT YOU'LL GET THAT IN MANY MULTI-TASKING ENVIRONMENTS,
  3055.  EVEN NON-SIMULATED ONES. ╙INCE WE'RE ONLY GOING TO BE SWITCHING TASKS EVERY
  3056.  1/60 OF A SECOND THEN WE'RE MORE LIKELY TO SEE AN OUTPUT SIMILAIR TO THIS:
  3057.  
  3058. @@@@@@┴┴┴┴┴┴┴@@@@@@@┴┴┴┴┴┴┴@@@@@@@@┴┴┴┴┴┴┴@@@@@@@┴┴┴┴┴┴┴┴@@@@@@@@┴┴┴┴┴┴@@@@@@@
  3059.  
  3060.  ╙O THAT IT SEEMS A PROCESS WILL RUN FOR ABOUT 1/60 OF A SECOND BEFOREE
  3061.  SWITCHING TO THE NEXT ONE.
  3062.   
  3063.  ╫E RUN INTO PROBLEMS HOWEVER. ╘HE ╦┼╥╬┴╠ IN THE ├128 THAT CONTAINS MOST
  3064.  OFF THE FILE HANDLING, SCREEN MANIPULATIONS, AND KEYBOARD INPUT ROUTINES. ╔T
  3065.  WAS NEVER DESIGNED WITH THE IDEA OF MULTI-TASKING IN MIND. ╙O WE'RE GONNA
  3066.  HAVE CODE RUNNING IN THE ╦┼╥╬┴╠ IN TWO SPOTS FOR THE TWO DIFFERANT PROCESSES
  3067.  AND IT'S MORE THAN LIKELY WE'LL END UP WITH SOMETHING LIKE:
  3068.  
  3069. @@@@@@@@<AND THEN A ┬╥╦ OR SOME STRANGE ERROR OR NEVER-NEVER-LAND>>
  3070.  
  3071.   ╘HERE'S GOT TO BE SOME WAY TO FIX IT - ╘HERE IS - ╔T'S CALLED A SEMAPHORE..
  3072.  
  3073.  ┴ SEMAPHORE IS A VALUE THAT IS CHECKED BEFORE ACCESS IS GRANTED TO ANOTHER
  3074.  GROUP OF MEMORY LOCATIONS. ╘HE SEMAPHORE IS BASICALLY REQUESTED VIA THE
  3075.  FOLLOWING:
  3076.  
  3077.         REQUEST_SEMAPHORE       SEI
  3078.                                 LDX SEMAPHORE
  3079.                                 DEX
  3080.                                 BEQ +
  3081.                                 CLI
  3082.                               - LDY #$FF
  3083.                                 DEY 
  3084.                                 BNE -
  3085.                               + INC SEMAPHORE
  3086.                                 CLI
  3087.  
  3088.  ╬OW THE REQUEST_SEMAPHORE HAS TO DISABLE INTERRUPTS TO PREVENT ANOTHER TASK
  3089.  FROM CHANGING THE SEMAPHORE VALUE BEFORE THIS ROUTINE HAS HAD A CHANCE. ╘HE
  3090.  ACTUAL CODE FOR THE REQUEST_SEMAPHORE WILL BE VERY SIMILAIR TO THE ABOVE.
  3091.  
  3092.  ╒SING A SIMILAIR ROUTINE THAT PERFORMS THE OPPOSITE - SETTING THE SEMAPHORE
  3093.  TO A ZERO VALUE WHEN FINISHED WE CAN DICTATE WHAT PROGRAM HAS CONTROL OVER
  3094.  WHAT DEVICE OR WHAT MEMORY AREAS.
  3095.  
  3096.  ╘HE SEMAPHORES WILL BE USED TO GOVERN ACCESS TO THE ╦┼╥╬┴╠ ROUTINES WHICH
  3097.  MANIPULATE THE LOCATIONS IN ZERO PAGE ETC, THEY'LL ALSO BE USED TO MANAGE THE
  3098.  MEMORY MANAGER WHEN IT IS IMPLEMENTED AS IT'D BE AWKWARD FOR IT TO ALLOCATE
  3099.  THE SAME BLOCK OF MEMORY TO TWO OR MORE PROCESSES.
  3100.  
  3101. ╔╔╔.  ═ULTI-╘ASKING ╞UNCTION ├ALLS (╨ACKAGE ├ALLS)
  3102.  
  3103.   ╧FF╙ET | ╬AME          | ╬OTES
  3104.   -------+---------------+--------------------------------------------------
  3105.    $00   | ╙ET╒P         | .├=0 ╔NIT ╨ACKAGE, .├=1 ╒NINSTALL ╨ACKAGE
  3106.          |               |      (INCLUDING ╦ERNAL RE-DIRECTION).
  3107.    $03   | ╙PAWN╨ROCESS  | ╧N RETURN: .├=0 PARENT, .├ = 1 CHILD
  3108.    $06   | ├HANGE╨RIORITY| .┴ = NEW FOREGROUND PRIORITY, .╪ = NEW BACKGROUND
  3109.    $09   | ╦ILL╘HIS╨ROC  | ╦ILLS ├ALLING ╨ROCESS (NO RETURN)
  3110.    $0C   | ╦ILL╧THER╨ROC | ╦ILLS ╨ROCESS # .┴
  3111.    $0F   | ╥EQUEST╙EMAPH | ╥EQUESTS ╙EMAPHORE #.╪
  3112.    $12   | ╥ELEASE╙EMAPH | ╥ELEASES ╙EMAPHORE #.╪
  3113.    $14   | ╟ET╨ROC╔NFO   | ╥ETURNS ╨ROCESS ╔NFORMATION, ╔NPUT=#┴
  3114.          |               |   OF 0: ╨ROCESS ╔D
  3115.          |               |   OF 1: ╨ROCESS ╞OREGROUND ╨RIORITY
  3116.          |               |   OF 2: ╨ROCESS ┬ACKGROUND ╨RIORITY
  3117.          |               |   OF 3+ ╧THER ╔NFORMATION ╘O ┬E ─ECIDED ╠ATER
  3118.    $17   | ╨IPE╔NIT      | .┴┘ - ┴DDRESS OF ╨IPE, .╪ = ╙IZE/8
  3119.          |               |    ╥ETURN: .╪ - ╨IPE #
  3120.    $1A   | ╫RITE╨IPE     | .┴┘ - ┴DDRESS OF ╬ULL ╘ERM. ─ATA, .╪ = ╨IPE #
  3121.    $1D   | ╥EAD╨IPE      | .┴┘ - ┴DDRESS TO ╨UT ─ATA .╪=╨IPE #
  3122.    $20   | ....          |  \
  3123.    $2E   | ....          |   \ ═ORE ╥OUTINES FOR THE FUTURE.
  3124.   -------+---------------+--------------------------------------------------
  3125.  
  3126. ╔╓.   ┴VAILIBILITY OF THE ╨ACKAGEE
  3127.  
  3128. ╘HE PACKAGE SHOULD BE AVAILABLE AT THE TIME OF THE NEXT ISSUE. ┴ FURTHER
  3129. EXAMINATION OF HOW THE ROUTINES WORK SHALL BE EXAMINED ALONG WITH THE SOURCE
  3130. CODE.
  3131.  
  3132. ┼RRORS POPPED UP IN DEVELOPING IT AND RATHER THAN DELAY ├= ╚ACKING ANY
  3133. FURTHER ╔ DECIDED TO GO AHEAD AND RELEASE THE ABOVE INFORMATION SO THAT
  3134. INDIVIDUALS CAN START DEVELOPING APPROPRIATE ROUTINES. ╔N ADDITION,
  3135. PLEASE NOTE THAT ╨╔╨┼S _MAY_ OR MAY NOT BE SUPPORTED IN THE NEXT ISSUE.
  3136. ╔ HAVE NOT FULLY MADE UP MY MIND YET ON THEM.
  3137.  
  3138. ╓.    ╥EFERENCESS
  3139.  
  3140.   ┬ORN TO ├ODE IN ├, ╚ERBERT ╙CHILDT, ╧SBORNE-═C╟RAW ╚ILL, P.203-252.
  3141.  
  3142.   ╬OTES FROM ╧PERATING ╙YSTEMS ├OURSE, ╨EMBROKE ╙TATE ╒NIV, ╞ALL '92.
  3143.  
  3144. =============================================================================
  3145. ╠╔╘╘╠┼ ╥┼─ ╥┼┴─┼╥: ═╙-─╧╙ FILE READER/╫╥╔╘┼╥ FOR THE ├128 AND 1571/81.
  3146. BY ├RAIG ┬RUCE  (CSBRUCE@NEUMANN.UWATERLOO.CA)
  3147.  
  3148. 1. ╔╬╘╥╧─╒├╘╔╧╬
  3149.  
  3150. ╘HIS ARTICLE IS A CONTINUATION OF THE ╠ITTLE ╥ED ╥EADER ARTICLE FROM LAST
  3151. ISSUE.  ╘HE PROGRAM HAS BEEN EXTENDED TO WRITE ═╙-─╧╙ FILES, IN ADDITION TO
  3152. READING THEM.  ╘HE PROGRAM STILL WORKS DRIVE-TO-DRIVE SO YOU'LL STILL NEED TWO
  3153. DISK DRIVES (EITHER PHYSICAL OR LOGICAL) TO USE IT.  ╘HE PROGRAM HAS ALSO BEEN
  3154. EXTENDED TO ALLOW ═╙-─╧╙ FILES TO BE DELETED AND TO ALLOW THE COPYING OF
  3155. ├OMMODORE-─╧╙ FILES BETWEEN ├┬═-─╧╙ DISKS (THIS MAKES IT MORE CONVENIENT TO
  3156. USE THE PROGRAM WITH A TEMPORARY LOGICAL DRIVE LIKE ╥┴═─╧╙).  ┴LSO, SINCE ╔
  3157. HAVE RECENTLY ACQUIRED A ├═─ ╞─-4000 FLOPPY DISK DRIVE, ╔ KNOW THAT THIS
  3158. PROGRAM WORKS WITH ═╙-─╧╙ DISKS WITH THIS DRIVE (BUT ONLY FOR THE 720╦
  3159. FORMAT).
  3160.  
  3161. ╘HE PROGRAM STILL HAS THE SAME ORGANIZATION AS LAST TIME: A MENU-ORIENTED
  3162. USER-INTERFACE PROGRAM WRITTEN IN ┬┴╙╔├ THAT MAKES USE OF A PACKAGE OF ═╙-─╧╙
  3163. DISK ACCESSING ROUTINES WRITTEN IN MACHINE LANGUAGE.  ╧H, THIS PROGRAM IS
  3164. ╨UBLIC ─OMAIN ╙OFTWARE, SO FEEL FREE TO DISTRIBUTE AND/OR MANGLE IT AS YOU
  3165. WISH.  ╩UST NOTE ANY MANGLINGS ON THE "INITIALIZING" SCREEN SO PEOPLE DON'T
  3166. BLAME ME.
  3167.  
  3168. ╘HE PROGRAM RUNS ON EITHER THE 40 OR 80-COLUMN SCREENS, BUT YOU WILL GET
  3169. MUCH BETTER PERFORMANCE FROM THE ┬┴╙╔├ PORTION OF THE PROGRAM BY BEING
  3170. IN 80-COLUMN MODE AND ╞┴╙╘ MODE.  ┴ MODIFICATION THAT SOMEONE MIGHT WANT
  3171. TO MAKE WOULD BE TO SPREAD-OUT THE DISPLAY FOR THE 80-COLUMN SCREEN AND ADD
  3172. COLOR TO THE RATHER BLAND DISPLAY.
  3173.  
  3174. 2. ╒╙┼╥ ╟╒╔─┼
  3175.  
  3176. ╠╧┴─ AND ╥╒╬ THE "LRR.128" ┬┴╙╔├ PROGRAM FILE.  ╫HEN THE PROGRAM IS FIRST RUN,
  3177. IT WILL DISPLAY AN "INITIALIZING" MESSAGE AND WILL LOAD IN THE BINARY MACHINE
  3178. LANGUAGE PACKAGE FROM THE "CURRENT" ├OMMODORE ─╧╙ DRIVE (THE CURRENT DRIVE IS
  3179. OBTAINED FROM ╨┼┼╦(186) - THE LAST DEVICE ACCESSED).  ╘HE BINARY PACKAGE IS
  3180. LOADED ONLY ON THE FIRST RUN AND IS NOT RELOADED ON SUBSEQUENT RUNS IF THE
  3181. PACKAGE ╔─ FIELD IS IN PLACE.
  3182.  
  3183. ╘HE SYSTEM IS DESIGNED TO HAVE TWO FILE SELECTION MENUS: ONE FOR THE ═╙-─╧╙
  3184. DISK DRIVE, AND ONE FOR THE ├OMMODORE-─╧╙ DISK DRIVE (WHICH MAY BE A LOGICAL
  3185. DISK DRIVE).  ╘HE IDEA FOR COPYING IS THAT YOU SELECT THE FILES IN ONE OF
  3186. THESE MENUS, AND THEN PROGRAM KNOWS TO COPY THEM TO THE DISK FOR THE OTHER
  3187. MENU.  ╘HIS IDEA OF HAVING TWO SELECTION MENUS IS ALSO VERY CONSISTENT WITH
  3188. THE ORIGINAL PROGRAM.
  3189.  
  3190. 2.1. ═╙-─╧╙ ═┼╬╒
  3191.  
  3192. ╫HEN THE PROGRAM STARTS, THE ═╙-─╧╙ MENU OF THE PROGRAM IS DISPLAYED.  ╔T
  3193. LOOKS LIKE:
  3194.  
  3195.    ═╙-─╧╙  ═╙=10:1581  ├┬═=8  ╞╥┼┼=715000
  3196.  
  3197.    ╬╒═  ╙  ╘╥╬  ╘┘╨  ╞╔╠┼╬┴═┼  ┼╪╘  ╠┼╬╟╘╚
  3198.    ---  -  ---  ---  --------  ---  ------
  3199.      1  *  ┴╙├  ╙┼╤  ╚┴├╦4     ╘╪╘  120732
  3200.      2     ┬╔╬  ╨╥╟  ╥┴═─╧╙    ╙╞╪   34923
  3201.  
  3202.    ─=─╔╥ ═=═╙─┼╓ ╞=├┬═─┼╓ ├=├╧╨┘ ╤=╤╒╔╘
  3203.    ╘=╘╧╟╟╠┼ ╥=╥┼═╧╓┼ ╪=├┬═├╨┘ /=═┼╬╒ +-=╨╟
  3204.  
  3205. EXCEPT THAT IMMEDIATELY AFTER STARTING UP, "<DIRECTORY NOT LOADED>" WILL BE
  3206. DISPLAYED RATHER THAN FILENAMES.  ╘HE MENU LOOKS AND OPERATES PRETTY MUCH AS
  3207. IT DID IN THE LAST ISSUE OF ├= ╚ACKING.  ╘HE ONLY DIFFERENCES ARE THAT THE
  3208. NUMBER OF BYTES FREE ON THE DRIVE ARE DISPLAYED (WHICH IS USEFUL TO KNOW WHEN
  3209. WRITING FILES) AND THERE ARE SOME MORE COMMANDS.
  3210.  
  3211. ╘HE DIRECTORY ("─"), CHANGE MS-DOS DEVICE ("═"), CHANGE COMMODORE FILE DEVICE
  3212. ("╞"), TOGGLE COLUMN CONTENTS ("╘"), COPY MS-DOS FILES TO CBM-DOS DISK ("├"),
  3213. QUIT ("╤"), PAGING ("+" AND "-"), COLUMN CHANGE (╙╨┴├┼ OR ╥┼╘╒╥╬), AND THE
  3214. CURSOR MOVEMENT COMMANDS ALL WORK THE SAME AS BEFORE.  ╘HEY ARE ALL STICKS TO
  3215. USE TO FLOG THE BEAST INTO SUBMISSION.  ╘HE NEW COMMANDS ARE: "╥" (REMOVE ==
  3216. DELETE), "/" (CHANGE MENU), AND "╪" (COPY ├┬═ FILES == "╪EROX").
  3217.  
  3218. ╘HE REMOVE COMMAND IS USED TO DELETE SELECTED FILES FROM THE ═╙-─╧╙ DISK.
  3219. ┴FTER SELECTING THIS OPTION, YOU WILL GET AN ANNOYING "ARE YOU SURE" QUESTION
  3220. AND THE THE SELECTED FILES WILL QUICKLY DISAPPEAR AND THE CHANGES WILL FINALLY
  3221. BE WRITTEN TO DISK.  ─ELETING A BATCH OF ═╙-─╧╙ FILES IS MUCH QUICKER THAN
  3222. DELETING ├OMMODORE-─╧╙ FILES SINCE ═╙-─╧╙ DISKS USE A ╞ILE ┴LLOCATION ╘ABLE
  3223. RATHER THAN THE LINKED LIST OF BLOCKS ORGANIZATION THAT ├┬═ USES.  ╔N ORDER TO
  3224. MAKE THE ┬┴╙╔├ PROGRAM EXECUTE QUICKER, AFTER DELETING, THE ORIGINAL ORDER OF
  3225. THE FILENAMES IN THE DIRECTORY LISTING WILL BE CHANGED.  ┬E FOREWARNED THAT
  3226. THE DELETE OPERATION IS NON-RECOVERABLE.
  3227.  
  3228. ╘HE CHANGE MENU COMMAND IS USED TO MOVE BACK AND FORTH BETWEEN THE ├OMMODORE-
  3229. ─╧╙ AND ═╙-─╧╙ MENUS.
  3230.  
  3231. 2.2. ├╧══╧─╧╥┼-─╧╙ ═┼╬╒
  3232.  
  3233. ╘HE ├OMMODORE-─╧╙ MENU, WHICH DISPLAYS THE NAMES OF THE ├OMMODORE FILES
  3234. SELECTED FOR VARIOUS OPERATIONS, LOOKS AND WORKS PRETTY MUCH THE SAME AS
  3235. THE ═╙-─╧╙ MENU:
  3236.  
  3237.    ├┬═─╧╙  ═╙=10:1581  ├┬═=8  ╞╥┼┼=3211476
  3238.  
  3239.    ╬╒═  ╙  ╘╥╬  ╞╔╠┼╬┴═┼         ╘  ╠┼╬╟╘╚
  3240.    ---  -  ---  ---------------- -  ------
  3241.      1  *  ┬╔╬  ╠╥╥-128          ╨    9876
  3242.      2     ┴╙├  ├╧═-╚┴├╦╔╬╟-005  ╙  175412
  3243.  
  3244.    ─=─╔╥ ═=═╙─┼╓ ╞=├┬═─┼╓ ├=├╧╨┘ ╤=╤╒╔╘
  3245.    ╘=╘╧╟╟╠┼ ╥=╥┼═╧╓┼ ╪=├┬═├╨┘ /=═┼╬╒ +-=╨╟
  3246.  
  3247. ┘OU'LL NOTICE, HOWEVER, THAT THE FILETYPE FIELD ("╘" HERE) IS MOVED AND IS
  3248. UNCHANGABLE.  ┴LSO, THE FILE LENGTHS ARE NOT EXACT; THEY ARE REPORTED AS THE
  3249. BLOCK COUNT OF THE FILE MULTIPLIED BY 254.  ╘HIS MENU IS NOT MAINTAINED FOR
  3250. FILES BEING COPIED TO THE ├┬═-─╧╙ DISK FROM AN ═╙-─╧╙ DISK.  ┘OU'LL
  3251. HAVE TO RE-EXECUTE THE ─IRECTORY INSTRUCTION TO GET AN UPDATED LISTING.
  3252.  
  3253. ╘HE "─" (DIRECTORY) COMMAND HAS LOCAL EFFECT WHEN IN THIS MENU.  ╘HE
  3254. ├OMMODORE-─╧╙ DIRECTORY WILL BE LOADED FROM THE CURRENT ├┬═ DEVICE NUMBER.
  3255. ╬OTE THAT IN ORDER FOR THIS TO WORK, THE ├┬═ DEVICE MUST BE NUMBER EIGHT
  3256. OR GREATER (A DISK DRIVE).  ╧RIGINALLY, THE SUBROUTINE FOR THIS COMMAND WAS
  3257. WRITTEN USING ONLY ╟┼╘#'S FROM THE DISK AND WAS VERY SLOW.  ╔T WAS MODIFIED,
  3258. HOWEVER, TO CALL A MACHINE LANGUAGE SUBROUTINE TO READ THE INFORMATION FOR
  3259. A DIRECTORY ENTRY FROM THE DIRECTORY LISTING, AND HENCE THE SUBROUTINE NOW
  3260. OPERATES AT A TOLERABLE SPEED.
  3261.  
  3262. ╘HE "├" (COPY) COMMAND ALSO HAS A DIFFERENT MEANING WHEN IN THIS MENU.  ╔T
  3263. MEANS TO COPY THE SELECTED ├┬═ FILES TO THE ═╙-─╧╙ DISK.  ╙EE DETAILS BELOW.
  3264.  
  3265. ╘HE COPY ├┬═ FILES ("╪") COMMAND IS USED TO COPY THE FILES IN THE ├┬═-─╧╙ MENU
  3266. TO ANOTHER ├┬═-─╧╙ DISK UNIT.  ╙ELECT THE FILES YOU WANT TO COPY AND THEN
  3267. PRESS ╪.  ┘OU WILL THEN BE ASKED WHAT DEVICE NUMBER YOU WANT TO COPY THE FILES
  3268. TO.  ╘HE DEVICE CAN BE ANOTHER DISK DRIVE OR ANY OTHER DEVICE (EXCEPT THE
  3269. KEYBOARD).  ╒SING DEVICE NUMBER 0 DOES NOT MEAN THE "NULL" DEVICE AS IT DOES
  3270. WITH COPYING ═╙-─╧╙ TO ├┬═.  ╔F YOU ARE COPYING TO A DISK DEVICE AND THE FILE
  3271. ALREADY EXISTS, THEN YOU WILL BE ASKED IF YOU WISH TO OVERWRITE THE FILE.  ┘OU
  3272. CANNOT COPY TO THE SAME DISK UNIT.  ┴LSO, ALL FILES ARE COPIED IN BINARY MODE
  3273. (REGARDLESS OF WHAT TRANSLATION YOU HAVE SELECTED FOR A FILE).
  3274.  
  3275. ╘HE COPY ├┬═ FILES COMMAND WAS INCLUDED SINCE ALL OF THE LOW-LEVEL GEAR
  3276. NEEDED TO IMPLEMENT IT (SPECIFICALLY "COMMIE╔N" AND "COMMIE╧UT" BELOW) WAS
  3277. ALSO REQUIRED BY OTHER FUNCTIONS.  ╘HIS COMMAND CAN BE VERY CONVENIENT WHEN
  3278. WORKING WITH ╥┴═─╧╙.  ╞OR EXAMPLE, IF YOU ONLY HAD A 1571 AS DEVICE 8 BUT YOU
  3279. HAVE A ╥┴═ EXPANDER AND HAVE INSTALLED ╥┴═─╧╙ AS DEVICE 9, THEN YOU WOULD
  3280. COPY ═╙-─╧╙ FILES TO ╥┴═─╧╙ USING THE ═╙-─╧╙ MENU, AND THEN YOU WOULD GO TO
  3281. THE ├OMMODORE-─╧╙ MENU ("/"), READ THE DIRECTORY, SELECT ALL FILES, INSERT AN
  3282. ├OMMODORE-─╧╙ DISKETTE INTO YOUR 1571, AND THEN USE "╪" TO COPY FROM THE
  3283. ╥┴═─╧╙ DEVICE TO THE 1571.
  3284.  
  3285. ╘HE REMOVE COMMAND ("╥") DOES NOT WORK FOR THIS DIRECTORY.  ┘OU CAN ╙├╥┴╘├╚
  3286. YOUR ├┬═-─╧╙ FILES YOUR DAMN SELF.
  3287.  
  3288. 2.3. ├╧╨┘ ├┬═-─╧╙ ╘╧ ═╙-─╧╙
  3289.  
  3290. ┬EFORE YOU CAN COPY SELECTED ├┬═-─╧╙ FILES TO AN ═╙-─╧╙ DISK, THE ═╙-─╧╙ DISK
  3291. DIRECTORY MUST BE ALREADY LOADED (FROM THE ═╙-─╧╙ MENU).  ╘HIS IS REQUIRED
  3292. SINCE THE DIRECTORY AND ╞┴╘ INFORMATION ARE KEPT IN MEMORY AT ALL TIMES DURING
  3293. THE EXECUTION OF THIS PROGRAM.
  3294.  
  3295. ╫HEN YOU ENTER COPY MODE, THE SCREEN WILL CLEAR AND THE NAME OF EACH SELECTED
  3296. FILE IS DISPLAYED AS IT IS BEING COPIED.  ╔F AN ERROR IS ENCOUNTERED ON EITHER
  3297. THE ═╙-─╧╙ OR ├┬═-─╧╙ DRIVE DURING COPYING, AN ERROR MESSAGE WILL BE DISPLAYED
  3298. AND COPYING WILL CONTINUE (AFTER YOU PRESS A KEY FOR ═╙-─╧╙ ERRORS).  ╨LEASE
  3299. NOTE THAT NOT A WHOLE LOT OF EFFORT WAS PUT INTO ERROR RECOVERY.
  3300.  
  3301. ╘O GENERATE AN ═╙-─╧╙ FILENAME FROM AN ├┬═-─╧╙ FILENAME, THE FOLLOWING
  3302. ALGORITHM IS USED.  ╘HE FILENAME IS SEARCHED FROM RIGHT TO LEFT FOR THE LAST
  3303. "." CHARACTER.  ╔F THERE IS NO "." CHARACTER, THEN THE ENTIRE FILENAME, UP TO
  3304. 11 CHARACTERS, IS USED AS THE ═╙-─╧╙ FILENAME.  ├HARACTERS 9 TO 11 WILL BE
  3305. USED AS THE EXTENSION.  ╔F THERE IS A "." CHARACTER, THE ALL CHARACTERS BEFORE
  3306. IT, UP TO EIGHT, WILL BE USED AS THE ═╙-─╧╙ FILENAME AND ALL CHARACTERS AFTER
  3307. THE FINAL ".", UP TO THREE, WILL BE USED AS THE ═╙-─╧╙ EXTENSION.
  3308.  
  3309. ╘HEN, THE NEWLY GENERATED ═╙-─╧╙ FILENAME IS SCANNED FOR ANY EXTRA "."
  3310. CHARACTERS OR EMBEDDED SPACES.  ╔F ANY ARE FOUND, THEY ARE REPLACED BY THE
  3311. UNDERSCORE CHARACTER ("_", WHICH IS THE BACKARROW CHARACTER ON A ├OMMODORE
  3312. DISPLAY).  ╞INALLY, ALL TRAILING UNDERSCORES ARE REMOVED FROM THE END OF BOTH
  3313. THE FILENAME AND EXTENSION PORTIONS OF THE ═╙-─╧╙ FILENAME.  ┴LSO, ALL
  3314. CHARACTERS ARE CONVERTED TO LOWERCASE ╨┼╘╙├╔╔ (WHICH IS UPPERCASE ┴╙├╔╔) WHEN
  3315. THEY ARE COPIED INTO THE ═╙-─╧╙ FILENAME.  ╬OTE THAT IF THE ├OMMODORE FILENAME
  3316. IS NOT IN THE 8/3 FORMAT OF ═╙-─╧╙, THEN SOMETHING IN THE NAME MAY BE LOST.
  3317. ╙OME EXAMPLES OF FILENAME CONVERSION FOLLOW:
  3318.  
  3319. ├┬═-─╧╙ ╞╔╠┼╬┴═┼       ═╙-─╧╙ ╞╔╠┼╬┴═┼
  3320. ----------------       ---------------
  3321. "LRR.BIN"              "LRR.BIN"
  3322. "LRR.128.BIN"          "LRR_128.BIN"
  3323. "HELLO THERE.TEXT"     "HELLO_TH.TEX"
  3324. "LONG_FILENAME"        "LONG_FIL.ENA"
  3325. "FILE 1..3.S__5"       "FILE_1.S"
  3326.  
  3327. ╔T WOULD HAVE BEEN TIME-CONSUMING TO HAVE THE PROGRAM SCAN THE ═╙-─╧╙
  3328. DIRECTORY FOR A FILENAME ALREADY EXISTING ON THE DISK, SO ╠╥╥ WILL PUT
  3329. MULTIPLE FILES ON A DISK WITH THE SAME FILENAME WITHOUT COMPLAINING.  ╘HIS
  3330. ALSO GETS RID OF THE PROBLEM OF ASKING YOU IF YOU WANT TO OVERWRITE THE OLD
  3331. FILE OR GENERATE A NEW NAME.  ╚OWEVER, IN ORDER TO RETRIEVE THE FILE FROM
  3332. DISK ON AN ═╙-─╧╙ MACHINE, YOU WILL PROBABLY HAVE TO USE THE ╥┼╬┴═┼ COMMAND TO
  3333. RENAME THE FIRST VERSIONS OF THE FILE ON THE DISK TO SOMETHING ELSE SO ═╙-─╧╙
  3334. WILL SCAN FURTHER IN THE DIRECTORY FOR THE LAST VERSION OF THE FILE WITH THE
  3335. SAME FILENAME.  ╘HERE IS NO RENAME COMMAND IN ╠╥╥ BECAUSE ╔ NEVER THOUGHT OF
  3336. IT IN TIME.  ╔T WOULD HAVE BEEN FAIRLY EASY TO PUT IN.
  3337.  
  3338. ╘HE DATE GENERATED FOR A NEW ═╙-─╧╙ FILE WILL BE ALL ZEROS.  ╙OME SYSTEMS
  3339. INTERPRET THIS AS 12:00 AM, 01-╩AN-80 AND OTHERS DON'T DISPLAY A DATE AT ALL
  3340. FOR THIS VALUE.
  3341.  
  3342. ╘HE PHYSICAL COPYING OF THE FILE IS DONE COMPLETELY IN MACHINE LANGUAGE AND
  3343. NOTHING IS DISPLAYED ON THE SCREEN WHILE THIS IS HAPPENING, BUT YOU CAN FOLLOW
  3344. THINGS BY LOOKING AT THE BLINKING LIGHTS AND LISTENING FOR CLICKS AND GRINDS.
  3345.  
  3346. ╙INCE THE ╞┴╘ AND DIRECTORY ARE MAINTAINED IN ╥┴═ DURING THE ENTIRE COPYING
  3347. PROCESS AND ARE ONLY FLUSHED TO DISK AFTER THE ENTIRE BATCH OF FILES ARE
  3348. COPIED, COPYING IS MADE MORE EFFICIENT, SINCE THERE WILL BE NO COSTLY SEEK
  3349. BACK TO TRACK 0 AFTER WRITING EACH FILE (LIKE ═╙-─╧╙ DOES).  ╔F YOU HAVE A
  3350. NUMBER OF SMALL FILES TO COPY, THEN THEY WILL BE KNOCKED OFF IN QUICK
  3351. SUCCESSION, FASTER THAN MANY ═╙-─╧╙ MACHINES WILL COPY THEM.
  3352.  
  3353. ╘O SIMPLIFY THE IMPLEMENTATION, THE CURRENT TRACK OF DISK BLOCKS FOR WRITING
  3354. IS NOT MAINTAINED LIKE IT IS FOR READING.  ┴LSO, A WRITING INTERLEAVE OF 1:1
  3355. IS USED FOR A 1571, WHICH IS NOT OPTIMAL.  ╚OWEVER, SINCE WRITING IS SUCH A
  3356. SLOW OPERATION ANYWAY, AND SINCE THE 1571 IS PARTICULARLY BAD BY INSISTING ON
  3357. VERIFYING BLOCKS, NOT MUCH MORE OVERHEAD IS INTRODUCED THAN IS ALREADY
  3358. PRESENT.
  3359.  
  3360. ┴N INTERESTING NOTE ABOUT WRITING ═╙-─╧╙ DISKS IS THAT YOU CAN TERMINATE ╠╥╥
  3361. IN THE MIDDLE OF A COPY (WITH ╙╘╧╨+╥┼╙╘╧╥┼) OR IN THE MIDDLE OF COPYING A
  3362. BATCH OF FILES, AND THE ═╙-─╧╙ DISK WILL REMAIN IN A PERFECTLY CONSISTENT
  3363. STATE AFTERWARDS.  ╘HE STATE WILL BE AS IF NONE OF THE FILES WERE COPIED.  ╘HE
  3364. REASON IS THAT THE CONTROL INFORMATION (THE ╞┴╘ AND DIRECTORY) IS MAINTAINED
  3365. INTERNALLY AND IS FLUSHED ONLY AFTER COPYING IS ALL COMPLETED.  ┬UT DON'T
  3366. TERMINATE ╠╥╥ WHILE IT IS FLUSHING THE CONTROL INFORMATION.
  3367.  
  3368. ╚ERE IS A TABLE OF COPYING SPEEDS FOR COPYING TO 1571, 1581, AND ├═─ ╞─-4000
  3369. DISK UNITS WITH ┴╙├ AND ┬╔╬ TRANSLATION MODES.  ┴LL FIGURES ARE IN BYTES/
  3370. SECOND, WHICH INCLUDES BOTH READING THE BYTE FROM A ├= DISK AND WRITING IT TO
  3371. THE ═╙-─╧╙ DISK.  ╘HE AVERAGE SPEED FOR EITHER THE READ OR WRITE OPERATION
  3372. INDIVIDUALLY WILL BE TWICE THE SPEED GIVEN BELOW.  ╘HESE RESULTS WERE OBTAINED
  3373. FROM COPYING A 156,273 BYTE TEXT FILE (THE TEXT OF ├= ╚ACKING ╔SSUE #4).
  3374.  
  3375.    ╞╥╧═   \ ╘╧: ╞─-BIN     ╞─-ASC     81-BIN     81-ASC     71-BIN     71-ASC
  3376.    --------+    ------     ------     ------     ------     ------     ------
  3377.    ╥┴═╠INK |     2,332      2,200      2,332      2,200      1,594      1,559
  3378.    ╥┴═─╧╙  |     1,070      1,053      1,604      1,600      1,561      1,510
  3379.    ╞─4000  |         -          -      1,645      1,597      1,499      1,464
  3380.    ╩─1581  |     1,662      1,619          -          -      1,474      1,440
  3381.    ╩─1571  |     1,050      1,024        953        933          -          -
  3382.  
  3383. ╘HESE FIGURES ARE FOR TRANSFER SPEED ONLY, NOT COUNTING THE COUPLE OF SECONDS
  3384. OF OPENING FILES AND FLUSHING THE DIRECTORY.  ╬OTE THAT ALL MY PHYSICAL DRIVES
  3385. ARE ╩IFFY─╧╙-IFIED, SO YOUR PERFORMANCE MAY BE SLOWER.  ╔ AM AT A LOSS TO
  3386. EXPLAIN WHY AN ╞─-4000 IS SO MUCH SLOWER THAN A 1581 FOR COPYING FROM A
  3387. ╥┴═─╧╙ FILE, BUT THE SAME SPEED OR BETTER FOR COPYING FROM ANYTHING ELSE.
  3388.  
  3389. ╙INCE ╔ DON'T HAVE ACCESS TO AN ACTUAL ═╙-─╧╙ MACHINE, ╔ HAVE NOT TESTED THE
  3390. FILES WRITTEN ONTO AN ═╙-─╧╙ DISK BY ╠╥╥, EXCEPT BY READING THEM BACK WITH ╠╥╥
  3391. AND ┬┬╥.  ╔ DO KNOW, HOWEVER, THAT EARLIER ENCARNATIONS OF THIS PROGRAM DID
  3392. WORK FINE WITH ═╙-─╧╙ MACHINES.
  3393.  
  3394. 3. ═╙-─╧╙ ╥╧╧╘ ─╔╥┼├╘╧╥┘
  3395.  
  3396. ╔T WAS BROUGHT TO MY ATTENTION THAT ╔ MADE A MISTAKE IN THE PERVIOUS ARTICLE.
  3397. ╔ WAS WRONG ABOUT THE OFFSET OF THE ATTRIBUTES FIELD IN A DIRECTORY ENTRY.
  3398. ╘HE LAYOUT SHOULD HAVE BEEN AS FOLLOWS:
  3399.  
  3400.    ╧╞╞╙┼╘     ╠┼╬     ─┼╙├╥╔╨╘╔╧╬
  3401.    ------     ---     -----------
  3402.      0..7       8     ╞ILENAME
  3403.     8..10       3     ┼XTENSION
  3404.        11       1     ┴TTRIBUTES: $10=─IRECTORY, $08=╓OLUME╔D
  3405.    12..21      10     <UNUSED>
  3406.    22..25       4     ─ATE
  3407.    26..27       2     ╙TARTING ╞┴╘ ENTRY NUMBER
  3408.    28..31       4     ╞ILE LENGTH IN BYTES
  3409.  
  3410. 4. ╞╔╠┼ ├╧╨┘╔╬╟ ╨┴├╦┴╟┼
  3411.  
  3412. ┴S WAS MENTIONED ABOVE, ╠ITTLE ╥ED ╥EADER IS SPLIT INTO TWO PIECES: A ┬┴╙╔├
  3413. FRONT-END USER INTERFACE PROGRAM AND A PACKAGE OF MACHINE LANGUAGE SUBROUTINES
  3414. FOR DISK ACCESSING.  ╘HE ┬┴╙╔├ PROGRAM HANDLES THE MENU, USER INTERACTION, AND
  3415. MOST OF THE ═╙-─╧╙ DIRECTORY SEARCHING/MODIFYING.  ╘HE MACHINE LANGUAGE
  3416. PACKAGE HANDLES THE HARDWARE INPUT/OUTPUT, ╞ILE ┴LLOCATION ╘ABLE AND FILE
  3417. STRUCTURE MANIPULATIONS.
  3418.  
  3419. ╘HE FILE COPYING PACKAGE IS WRITTEN IN ASSEMBLY LANGUAGE AND IS LOADED INTO
  3420. MEMORY AT ADDRESS $8000 ON BANK 0 AND REQUIRES ABOUT 13╦ OF MEMORY.  ╘HE
  3421. PACKAGE IS LOADED AT THIS HIGH ADDRESS TO BE OUT OF THE WAY OF THE MAIN ┬┴╙╔├
  3422. PROGRAM, EVEN IF ╥┴═─╧╙ IS INSTALLED.
  3423.  
  3424. ╘HIS SECTION OF THE ARTICLE IS PRESENTED IN ITS ENTIRETY, INCLUDING ALL OF THE
  3425. INFORMATION GIVEN LAST TIME.
  3426.  
  3427. 4.1. ╔╬╘┼╥╞┴├┼
  3428.  
  3429. ╘HE SUBROUTINE CALL INTERFACE TO THE FILE COPYING PACKAGE IS SUMMARIZED AS
  3430. FOLLOWS:
  3431.  
  3432.    ┴──╥┼╙╙     ─┼╙├╥╔╨╘╔╧╬
  3433.    -------     -----------
  3434.    ╨╦          INIT╨ACKAGE SUBROUTINE
  3435.    ╨╦+3        MS─IR    (LOAD ═╙-─╧╙ DIRECTORY/╞┴╘) SUBROUTINE
  3436.    ╨╦+6        MS╥EAD   (COPY ═╙-─╧╙ TO ├┬═-─╧╙) SUBROUTINE
  3437.    ╨╦+9        MS╫RITE  (COPY ├┬═-─╧╙ TO ═╙-─╧╙) SUBROUTINE
  3438.    ╨╦+12       MS╞LUSH  SUBROUTINE
  3439.    ╨╦+15       MS─ELETE SUBROUTINE
  3440.    ╨╦+18       MS╞ORMAT SUBROUTINE [NOT IMPLEMENTED]
  3441.    ╨╦+21       MS┬YTES╞REE SUBROUTINE
  3442.    ╨╦+24       CBM├OPY  (COPY ├┬═-─╧╙ TO ├┬═-─╧╙) SUBROUTINE
  3443.    ╨╦+27       CBM─IRENT (READ ├┬═-─╧╙ DIRECTORY ENTRY) SUBROUTINE
  3444.  
  3445. WHERE "╨╦" IS THE LOAD ADDRESS OF THE PACKAGE ($8000).
  3446.  
  3447. ╘HE PARAMETER PASSING INTERFACE IS SUMMARIZED AS FOLLOWS:
  3448.  
  3449.    ┴──╥┼╙╙     ─┼╙├╥╔╨╘╔╧╬
  3450.    -------     -----------
  3451.    ╨╓          TWO-BYTE PACKAGE IDENTIFICATION NUMBER ($├┬, 132)
  3452.    ╨╓+2        ERRNO : ERROR CODE RETURNED
  3453.    ╨╓+3        ═╙-─╧╙ DEVICE NUMBER (8 TO 30)
  3454.    ╨╓+4        ═╙-─╧╙ DEVICE TYPE ($00=1571, $╞╞=1581)
  3455.    ╨╓+5        TWO-BYTE STARTING CLUSTER NUMBER FOR FILE COPYING
  3456.    ╨╓+7        LOW AND MID BYTES OF FILE LENGTH FOR COPYING
  3457.    ╨╓+9        POINTER TO ═╙-─╧╙ DIRECTORY ENTRY FOR WRITING
  3458.    ╨╓+11       ├┬═-─╧╙ FILE BLOCK COUNT
  3459.    ╨╓+13       ├┬═-─╧╙ FILE TYPE ("╙"=SEQ, "╨"=PRG, ETC.)
  3460.    ╨╓+14       ├┬═-─╧╙ FILENAME LENGTH
  3461.    ╨╓+15       ├┬═-─╧╙ FILENAME CHARACTERS (MAX 16 CHARS)
  3462.  
  3463. ╫HERE "╨╓" IS EQUAL TO ╨╦+30.  ┴DDITIONAL SUBROUTINE PARAMETERS ARE PASSED IN
  3464. THE PROCESSOR REGISTERS.
  3465.  
  3466. ╘HE ═╙-─╧╙ DEVICE NUMBER AND DEVICE TYPE INTERFACE VARIABLES ALLOW YOU TO SET
  3467. THE ═╙-─╧╙ DRIVE AND THE PACKAGE IDENTIFICATION NUMBER ALLOWS THE APPLICATION
  3468. PROGRAM TO CHECK IF THE PACKAGE IS ALREADY LOADED INTO MEMORY SO THAT IT ONLY
  3469. HAS TO LOAD THE PACKAGE THE FIRST TIME THE APPLICATION IS RUN AND NOT ON
  3470. RE-RUNS.  ╘HE IDENTIFICATION SEQUENCE IS A VALUE OF $├┬ FOLLOWED BY A VALUE OF
  3471. 132.
  3472.  
  3473. 4.1.1. ╔╬╔╘_╨┴├╦┴╟┼ ╙╒┬╥╧╒╘╔╬┼
  3474.  
  3475. ╘HE "INIT╨ACKAGE" SUBROUTINE SHOULD BE CALLED WHEN THE PACKAGE IS FIRST
  3476. INSTALLED, WHENEVER THE ═╙-─╧╙ DEVICE NUMBER IS CHANGED, AND WHENEVER A NEW
  3477. DISK IS MOUNTED TO INVALIDATE THE INTERNAL TRACK CACHE.  ╔T REQUIRES NO
  3478. PARAMETERS.
  3479.  
  3480. 4.1.2. ═╙_─╔╥ ╙╒┬╥╧╒╘╔╬┼
  3481.  
  3482. ╘HE "MS─IR" SUBROUTINE WILL LOAD THE DIRECTORY, ╞┴╘, AND THE ┬OOT ╙ECTOR
  3483. PARAMETERS INTO THE INTERNAL MEMORY OF THE PACKAGE FROM THE CURRENT ═╙-─╧╙
  3484. DEVICE NUMBER.  ╬O (OTHER) INPUT PARAMETERS ARE NEEDED AND THE SUBROUTINE
  3485. RETURNS A POINTER TO THE DIRECTORY SPACE IN THE .┴┘ REGISTERS AND THE NUMBER
  3486. OF DIRECTORY ENTRIES IN THE .╪ REGISTER.  ╔F AN ERROR OCCURS, THEN THE
  3487. SUBROUTINE RETURNS WITH THE ├ARRY FLAG SET AND THE ERROR CODE IS AVAILABLE IN
  3488. THE "ERRNO" INTERFACE VARIABLE.  ╘HE DIRECTORY ENTRY DATA IS IN THE DIRECTORY
  3489. SPACE AS IT WAS READ IN RAW FROM THE DIRECTORY SECTORS ON THE ═╙-─╧╙ DISK.
  3490.  
  3491. 4.1.3. ═╙_╥┼┴─ ╙╒┬╥╧╒╘╔╬┼
  3492.  
  3493. ╘HE "MS╥EAD" SUBROUTINE WILL COPY A SINGLE FILE FROM THE ═╙-─╧╙ DISK TO A
  3494. SPECIFIED ├┬═-╦ERNAL LOGICAL FILE NUMBER (THE ├┬═ FILE MUST ALREADY BE
  3495. OPENED).  ╔F THE ├┬═ LOGICAL FILE NUMBER IS ZERO, THEN THE FILE DATA IS SIMPLY
  3496. DISCARDED AFTER IT IS READ FROM THE ═╙-─╧╙ FILE.  ╘HE STARTING CLUSTER NUMBER
  3497. OF THE FILE TO COPY AND THE LOW AND MID BYTES OF THE FILE LENGTH ARE PASSED IN
  3498. THE ╨╓+5 AND ╨╓+7 INTERFACE WORDS.  ╘HE TRANSLATION MODE TO USE IS PASSED IN
  3499. THE .┴ REGISTER ($00=BINARY, $╞╞=ASCII) AND THE ├┬═ LOGICAL FILE NUMBER TO
  3500. OUTPUT TO IS PASSED IN THE .╪ REGISTER.  ╔F AN ERROR OCCURS, THE ROUTINE
  3501. RETURNS WITH THE ├ARRY FLAG SET AND THE ERROR CODE IN THE "ERRNO" INTERFACE
  3502. VARIABLE.  ╘HERE ARE NO OTHER OUTPUT PARAMETERS.
  3503.  
  3504. ╬OTE THAT SINCE THE STARTING CLUSTER NUMBER AND LOW-FILE LENGTH OF THE FILE TO
  3505. BE COPIED ARE REQUIRED RATHER THAN THE FILENAME, IT IS THE RESPONSIBILITY OF
  3506. THE FRONT-END APPLICATION PROGRAM TO DIG THROUGH THE RAW DIRECTORY SECTOR DATA
  3507. TO GET THIS INFORMATION.  ╘HE APPLICATION MUST ALSO OPEN THE ├OMMODORE-─╧╙
  3508. FILE OF WHATEVER FILETYPE ON WHATEVER DEVICE IS REQUIRED; THE PACKAGE DOES NOT
  3509. NEED TO KNOW THE ├OMMODORE-─╧╙ DEVICE NUMBER.
  3510.  
  3511. 4.1.4. ═╙_╫╥╔╘┼ ╙╒┬╥╧╒╘╔╬┼
  3512.  
  3513. ╘HE "MS╫RITE" SUBROUTINE COPIES A SINGLE FILE FROM A SPECIFIED ├┬═-╦ERNAL
  3514. LOGICAL FILE NUMBER TO A ═╙-─╧╙ FILE.  ╘HE ═╙-─╧╙ DEVICE NUMBER AND TYPE ARE
  3515. SET ABOVE.  ┴ POINTER TO THE ═╙-─╧╙ DIRECTORY ENTRY IN THE BUFFER RETURNED BY
  3516. THE "MS─IR" CALL MUST BE GIVEN IN INTERFACE WORD ╨╓+9 AND THE TRANSLATION MODE
  3517. AND ├┬═ LFN ARE PASSED IN THE .┴ AND .╪ REGISTERS AS IN THE "MS╥EAD" ROUTINE.
  3518. ┴N ERROR RETURN IS GIVEN IN THE USUAL WAY (.├╙, ERRNO).  ╧THERWISE, THERE ARE
  3519. NO RETURN VALUES.
  3520.  
  3521. ╔T IS THE RESPONSIBILITY OF THE CALLING PROGRAM TO INITIALIZE THE ═╙-─╧╙
  3522. DIRECTORY ENTRY TO ALL ZEROS AND THEN SET THE FILENAME AND SET THE STARTING
  3523. CLUSTER POINTER TO $0╞╞╞.  ╘HIS ROUTINE WILL UPDATE THE STARTING CLUSTER AND
  3524. FILE LENGTH FIELDS OF THE DIRECTORY ENTRY WHEN IT FINISHES.  ╘HE INTERNAL
  3525. "DIRTY FLAGS" ARE MODIFIED SO THAT THE DIRECTORY AND ╞┴╘ WILL BE FLUSHED ON
  3526. THE NEXT CALL TO "MS╞LUSH".
  3527.  
  3528. 4.1.5. ═╙_╞╠╒╙╚ ╙╒┬╥╧╒╘╔╬┼
  3529.  
  3530. ╘HE "MS╞LUSH" SUBROUTINE TAKES NO INPUT PARAMETERS OTHER THAN THE IMPLICIT
  3531. MS─EVICE AND MS╘YPE.  ╔F "DIRTY" (MODIFIED), THE ╞┴╘ WILL BE WRITTEN TO THE
  3532. ═╙-─╧╙ DISK, TO BOTH PHYSICAL REPLICAS OF THE DISK ╞┴╘.  ╘HEN, EACH DIRECTORY
  3533. SECTOR THAT IS DIRTY WILL BE WRITTEN TO DISK.  ┴FTER FLUSHING, THE INTERNAL
  3534. DIRTY FLAGS WILL BE CLEARED.  ┴N ERROR RETURN IS GIVEN IN THE USUAL WAY.
  3535. ╘HERE ARE NO OTHER OUTPUT PARAMETERS.  ╔F YOU CALL THIS ROUTINE AND THERE ARE
  3536. NO DIRTY FLAGS SET, THEN IT WILL RETURN IMMEDIATELY, WITHOUT ANY WRITING TO
  3537. DISK.
  3538.  
  3539. 4.1.6. ═╙_─┼╠┼╘┼ ╙╒┬╥╧╒╘╔╬┼
  3540.  
  3541. ╘HE "MS─ELETE" SUBROUTINE WILL DEALLOCATE ALL ╞ILE ┴LLOCATION ╘ABLE ENTRIES
  3542. (AND HENCE, DATA CLUSTERS) ALLOCATED TO A FILE AND MARK THE DIRECTORY ENTRY AS
  3543. BEING DELETED (BY PUTTING AN $┼5 INTO THE FIRST CHARACTER OF THE FILENAME).
  3544. ╘HE FILE IS SPECIFIED BY GIVING THE POINTER TO THE DIRECTORY ENTRY IN
  3545. INTERFACE WORD AT ╨╓+9.  ┴FTER DEALLOCATING THE FILE DATA, THE INTERNAL
  3546. "DIRTY" FLAG WILL BE SET FOR THE ╞┴╘ AND THE SECTOR THAT THE DIRECTORY ENTRY
  3547. IS ON, BUT NOTHING WILL BE WRITTEN TO DISK.  ╘HERE IS NO ERROR RETURN FROM
  3548. THIS ROUTINE.  ╔T IS THE RESPONSIBILITY OF THE CALLING ROUTINE TO EVENTUALLY
  3549. CALL THE "MS╞LUSH" ROUTINE.
  3550.  
  3551. 4.1.7. ═╙_╞╧╥═┴╘ ╙╒┬╥╧╒╘╔╬┼
  3552.  
  3553. ╘HE "MS╞ORMAT" SUBROUTINE IS NOT IMPLEMENTED.  ╔T'S INTENDED FUNCTION WAS TO
  3554. FORMAT THE ═╙-─╧╙ DISK AND GENERATE AND WRITE THE BOOT SECTOR, INITIAL ╞┴╘,
  3555. AND INITIAL DIRECTORY ENTRY DATA.
  3556.  
  3557. 4.1.8. ═╙_┬┘╘┼╙_╞╥┼┼ ╙╒┬╥╧╒╘╔╬┼
  3558.  
  3559. ╘HE "MS┬YTES╞REE" SUBROUTINE WILL SCAN THE CURRENTLY LOADED ═╙-─╧╙ ╞ILE
  3560. ┴LLOCATION ╘ABLE, COUNT THE NUMBER OF CLUSTERS FREE, AND RETURN THE NUMBER OF
  3561. BYTES FREE FOR FILE STORAGE ON THE DISK.  ╘HERE ARE NO INPUT PARAMETERS AND
  3562. THE BYTES FREE ARE RETURNED IN THE .┴┘╪ REGISTERS (.┴=LOW, .┘=MID, .╪=HIGH
  3563. BYTE).  ╘HE SUBROUTINE HAS NO ERROR RETURNS AND DOES NOT CHECK IF AN ═╙-─╧╙
  3564. DIRECTORY IS ACTUALLY LOADED.
  3565.  
  3566. 4.1.9. ├┬═_├╧╨┘ ╙╒┬╥╧╒╘╔╬┼
  3567.  
  3568. ╘HE "CBM├OPY" SUBROUTINE WILL COPY FROM AN INPUT ├┬═-╦ERNAL LOGICAL FILE
  3569. NUMBER GIVEN IN THE .┴ REGISTER TO AN OUTPUT ├┬═-╦ERNAL LFN GIVEN IN THE .╪
  3570. REGISTER, IN UP TO 1024 BYTE CHUNKS.  ╞ILE CONTENTS ARE COPIED EXACTLY (NO
  3571. TRANSLATION).  ╘HIS ROUTINE DOES NOT CARE IF THE LFN'S ARE ON THE SAME DEVICE
  3572. OR NOT, BUT THE INPUT DEVICE MUST BE A DISK UNIT (EITHER LOGICAL OR PHYSICAL).
  3573. ┴N ERROR RETURN IS GIVEN IN THE USUAL WAY.
  3574.  
  3575. 4.1.10. ├┬═_─╔╥┼╬╘ ╙╒┬╥╧╒╘╔╬┼
  3576.  
  3577. ╘HE "CBM─IRENT" SUBROUTINE READS THE NEXT DIRECTORY ENTRY FROM THE ├┬═-╦ERNAL
  3578. LFN GIVEN IN .┴ AND PUTS THE DATA INTO INTERFACE VARIABLES.  ╧F COURSE, THE
  3579. LFN IS ASSUMED TO BE OPEN FOR READING A DIRECTORY ("$").  ╘HE BLOCK COUNT IS
  3580. RETURNED IN THE WORD AT ╨╓+11, THE FIRST CHARACTER OF THE FILETYPE IS RETURNED
  3581. AT ╨╓+13, THE NUMBER OF CHARACTERS IN THE FILENAME IS RETURNED IN ╨╓+14, AND
  3582. THE FILENAME CHARACTERS ARE RETURNED IN BYTES ╨╓+15 TO ╨╓+30.  ┴N ERROR RETURN
  3583. IS GIVEN IN THE USUAL WAY.
  3584.  
  3585. ╘HIS ROUTINE ASSUMES THAT THE FIRST TWO BYTES OF THE DIRECTORY FILE HAVE
  3586. ALREADY BEEN READ.  ╘HE FIRST CALL TO THIS ROUTINE WILL RETURN THE NAME OF THE
  3587. DISK.  ╘HE END OF A DIRECTORY IS SIGNALLED BY A FILENAME LENGTH OF ZERO.  ╔N
  3588. THIS CASE, THE BLOCK COUNT RETURNED WILL BE THE NUMBER OF BLOCKS FREE ON THE
  3589. DISK.
  3590.  
  3591. 4.2. ╔═╨╠┼═┼╬╘┴╘╔╧╬
  3592.  
  3593. ╘HIS SECTION PRESENTS THE CODE THAT IMPLEMENTS THE ═╙-─╧╙ FILE READING AND
  3594. WRITING PACKAGE.  ╔T IS HERE IN A SPECIAL FORM; EACH CODE LINE IS PRECEDED BY
  3595. THE % SYMBOL.  ╘HE % SIGN IS THERE TO ALLOW YOU TO EASILY EXTRACT THE
  3596. ASSEMBLER CODE FROM THE REST OF THIS MAGAZINE (AND ALL OF MY UGLY COMMENTS).
  3597. ╧N A ╒NIX SYSTEM, ALL YOU HAVE TO DO IS EXECUTE THE FOLLOWING COMMAND LINE
  3598. (SUBSTITUTE FILENAMES AS APPROPRIATE):
  3599.  
  3600. GREP '^%' ╚ACK5 | SED 'S/^% //' | SED 'S/^%//' >LRR.S
  3601.  
  3602. % ; ╠ITTLE ╥ED ╥EADER/╫RITER UTILITY PACKAGE BY ├RAIG ┬RUCE, 31-╩AN-92
  3603. % ; ╫RITTEN FOR ├= ╚ACKING ╬ET-═AGAZINE; FOR ├-128, 1571, 1581
  3604. %
  3605.  
  3606. ╘HE CODE IS WRITTEN FOR THE ┬UDDY ASSEMBLER AND HERE ARE A COUPLE SETUP
  3607. DIRECTIVES.  ╬OTE THAT MY COMMENTS COME BEFORE THE SECTION OF CODE.
  3608.  
  3609. % .ORG $8000
  3610. % .OBJ "LRR.BIN"
  3611. %
  3612. % ;====JUMP TABLE AND PARAMETERS INTERFACE ====
  3613. %
  3614. % JMP INIT╨ACKAGE ;()
  3615. % JMP MS─IR       ;( MS─EVICE, MS╘YPE ) : .┴┘=DIR┴DDR, .╪=DIRENT├OUNT
  3616. % JMP MS╥EAD      ;( MS─EVICE, MS╘YPE, START├LUSTER, LEN═╠,.┴=TRANS,.╪=CBM╠FN )
  3617. % JMP MS╫RITE     ;( MS─EVICE, MS╘YPE, WRITE─IRENT, .┴=TRANS, .╪=CBM╠FN )
  3618. % JMP MS╞LUSH     ;( MS─EVICE, MS╘YPE )
  3619. % JMP MS─ELETE    ;( WRITE─IRENT )
  3620. % JMP MS╞ORMAT    ;( MS─EVICE, MS╘YPE )
  3621. % JMP MS┬YTES╞REE ;( ) : .┴┘╪=BYTES╞REE
  3622. % JMP CBM├OPY     ;( .┴=IN╠FN, .╪=OUT╠FN )
  3623. % JMP CBM─IRENT   ;( .┴=LFN )
  3624. %
  3625. % .BYTE $CB,132   ;IDENTIFICATION (LOCATION PK+30)
  3626.  
  3627. ╘HESE INTERFACE VARIABLES ARE INCLUDED IN THE PACKAGE PROGRAM SPACE TO
  3628. MINIMIZE UNWANTED INTERACTION WITH OTHER PROGRAMS LOADED AT THE SAME TIME,
  3629. SUCH AS THE ╥┴═─╧╙ DEVICE DRIVER.
  3630.  
  3631. % ERRNO           .BUF 1
  3632. % MS─EVICE        .BUF 1
  3633. % MS╘YPE          .BUF 1    ;$00=1571, $FF=1581
  3634. % START├LUSTER    .BUF 2
  3635. % LEN═╠           .BUF 2    ;LENGTH MEDIUM AND LOW BYTES
  3636. % WRITE─IRENT     .BUF 2    ;POINTER TO DIRENT
  3637. % CDIR┬LOCKS      .BUF 2    ;CBM DIRENT BLOCKS
  3638. % CDIR╘YPE        .BUF 1    ;CBM DIRENT FILETYPE
  3639. % CDIR╞LEN        .BUF 1    ;CBM DIRENT FILENAME LENGTH
  3640. % CDIR╬AME        .BUF 16   ;CBM DIRENT FILENAME
  3641. %
  3642.  
  3643. ╘HIS COMMAND IS NOT CURRENTLY IMPLEMENTED.  ╔TS STUB APPEARS HERE.
  3644.  
  3645. % MS╞ORMAT = *
  3646. %    BRK
  3647. %
  3648. % ;====GLOBAL DECLARAIONS====
  3649. %
  3650. % KERNEL╠ISTEN = $FFB1
  3651. % KERNEL╙ECOND = $FF93
  3652. % KERNEL╒NLSN  = $FFAE
  3653. % KERNEL┴CPTR  = $FFA2
  3654. % KERNEL├IOUT  = $FFA8
  3655. % KERNEL╙PINP  = $FF47
  3656. % KERNEL├HKIN  = $FFC6
  3657. % KERNEL├HKOUT = $FFC9
  3658. % KERNEL├LRCHN = $FFCC
  3659. % KERNEL├HRIN  = $FFCF
  3660. % KERNEL├HROUT = $FFD2
  3661. %
  3662. % ST = $90
  3663. % CIA├LOCK = $DD00
  3664. % CIA╞LAGS = $DC0D
  3665. % CIA─ATA  = $DC0C
  3666. %
  3667.  
  3668. ╘HESE ARE THE PARAMETERS AND DERIVED PARAMETERS FROM THE BOOT SECTOR.  ╘HEY
  3669. ARE KEPT IN THE PROGRAM SPACE TO AVOID INTERACTIONS.
  3670.  
  3671. % CLUSTER┬LOCK├OUNT .BUF 1        ;1 OR 2
  3672. % FAT┬LOCKS         .BUF 1        ;UP TO 3
  3673. % ROOT─IR┬LOCKS     .BUF 1        ;UP TO 8
  3674. % ROOT─IR┼NTRIES    .BUF 1        ;UP TO 128
  3675. % TOTAL╙ECTORS      .BUF 2        ;UP TO 1440
  3676. % FIRST╞ILE┬LOCK    .BUF 1
  3677. % FIRST╥OOT─IR┬LOCK .BUF 1
  3678. % FILE├LUSTER├OUNT  .BUF 2
  3679. % LAST╞AT┼NTRY      .BUF 2
  3680. %
  3681.  
  3682. ╘HE CYLINDER (TRACK) AND SIDE THAT IS CURRENTLY STORED IN THE TRACK CACHE
  3683. FOR READING.
  3684.  
  3685. % BUF├YLINDER     .BUF 1
  3686. % BUF╙IDE         .BUF 1
  3687.  
  3688. ╘HESE "DIRTY" FLAGS RECORD WHAT HAS TO BE WRITTEN OUT FOR A FLUSH OPERATION.
  3689.  
  3690. % FAT─IRTY        .BUF 1
  3691. % DIR─IRTY        .BUF 8  ;FLAG FOR EACH DIRECTORY BLOCK
  3692. % FORMAT╨ARMS     .BUF 6
  3693. %
  3694.  
  3695. ╘HIS PACKAGE IS SPLIT INTO A NUMBER OF LEVELS.  ╘HIS LEVEL INTERFACES WITH THE
  3696. ╦ERNAL SERIAL BUS ROUTINES AND THE BURST COMMAND PROTOCOL OF THE DISK DRIVES.
  3697.  
  3698. % ;====HARDWARE LEVEL====
  3699. %
  3700.  
  3701. ├ONNECT TO THE ═╙-─╧╙ DEVICE AND SEND THE "╒0" BURST COMMAND PREFIX AND THE
  3702. BURST COMMAND BYTE.
  3703.  
  3704. % SEND╒0 = *  ;( .┴=BURST├OMMAND├ODE ) : .├╙=ERR
  3705. %    PHA
  3706. %    LDA #0
  3707. %    STA ST
  3708. %    LDA MS─EVICE
  3709. %    JSR KERNEL╠ISTEN
  3710. %    LDA #$6F
  3711. %    JSR KERNEL╙ECOND
  3712. %    LDA #"U"
  3713. %    JSR KERNEL├IOUT
  3714. %    BIT ST
  3715. %    BMI SEND╒0┼RROR
  3716. %    LDA #"0"
  3717. %    JSR KERNEL├IOUT
  3718. %    PLA
  3719. %    JSR KERNEL├IOUT
  3720. %    BIT ST
  3721. %    BMI SEND╒0┼RROR
  3722. %    CLC
  3723. %    RTS
  3724. %
  3725. %    SEND╒0┼RROR = *
  3726. %    LDA #5
  3727. %    STA ERRNO
  3728. %    SEC
  3729. %    RTS
  3730. %
  3731.  
  3732. ╘OGGLE THE "─ATA ┴CCEPTED / ╥EADY ╞OR ═ORE" CLOCK SIGNAL FOR THE BURST
  3733. TRANSFER PROTOCOL.
  3734.  
  3735. % TOGGLE├LOCK = *
  3736. %    LDA CIA├LOCK
  3737. %    EOR #$10
  3738. %    STA CIA├LOCK
  3739. %    RTS
  3740. %
  3741.  
  3742. ╫AIT FOR A BURST BYTE TO ARRIVE IN THE SERIAL DATA REGISTER OF ├╔┴#1 FROM THE
  3743. FAST SERIAL BUS.
  3744.  
  3745. % SERIAL╫AIT = *
  3746. %    LDA #$08
  3747. % -  BIT CIA╞LAGS
  3748. %    BEQ -
  3749. %    RTS
  3750. %
  3751.  
  3752. ╫AIT FOR AND GET A BURST BYTE FROM THE FAST SERIAL BUS, AND SEND THE "─ATA
  3753. ┴CCEPTED" SIGNAL.
  3754.  
  3755. % GET┬URST┬YTE = *
  3756. %    JSR SERIAL╫AIT
  3757. %    LDX CIA─ATA
  3758. %    JSR TOGGLE├LOCK
  3759. %    TXA
  3760. %    RTS
  3761. %
  3762.  
  3763. ╙END THE BURST COMMANDS TO "LOG IN" THE ═╙-─╧╙ DISK AND SET THE ╥EAD SECTOR
  3764. INTERLEAVE FACTOR.
  3765.  
  3766. % MOUNT─ISK = *  ;() : .├╙=ERR
  3767. %    LDA #%00011010
  3768. %    JSR SEND╒0
  3769. %    BCC +
  3770. %    RTS
  3771. % +  JSR KERNEL╒NLSN
  3772. %    BIT ST
  3773. %    BMI SEND╒0┼RROR
  3774. %    CLC
  3775. %    JSR KERNEL╙PINP
  3776. %    BIT CIA╞LAGS
  3777. %    JSR TOGGLE├LOCK
  3778. %    JSR GET┬URST┬YTE
  3779. %    STA ERRNO
  3780. %    AND #$0F
  3781. %    CMP #2
  3782. %    BCS MOUNT┼XIT
  3783.  
  3784. ╟RAB THE THROW-AWAY PARAMETERS FROM THE MOUNT OPERATION.
  3785.  
  3786. %    LDY #0
  3787. % -  JSR GET┬URST┬YTE
  3788. %    STA FORMAT╨ARMS,Y
  3789. %    INY
  3790. %    CPY #6
  3791. %    BCC -
  3792. %    CLC
  3793.  
  3794. ╙ET THE ╥EAD SECTOR INTERLEAVE TO 1 FOR A 1581 OR 4 FOR A 1571.
  3795.  
  3796. %    ;** SET INTERLEAVE
  3797. %    LDA #%00001000
  3798. %    JSR SEND╒0
  3799. %    BCC +
  3800. %    RTS
  3801. % +  LDA #1            ;INTERLEAVE OF 1 FOR 1581
  3802. %    BIT MS╘YPE
  3803. %    BMI +
  3804. %    LDA #4            ;INTERLEAVE OF 4 FOR 1571
  3805. % +  JSR KERNEL├IOUT
  3806. %    JSR KERNEL╒NLSN
  3807. %    MOUNT┼XIT = *
  3808. %    RTS
  3809. %
  3810.  
  3811. ╥EAD ALL OF THE SECTORS OF A GIVEN TRACK INTO THE TRACK CACHE.
  3812.  
  3813. % BUFPTR = 2
  3814. % SECNUM = 4
  3815. %
  3816. % READ╘RACK = *  ;( .┴=CYLINDER, .╪=SIDE ) : TRACKBUF, .├╙=ERR
  3817. %    PHA
  3818. %    TXA
  3819.  
  3820. ╟ET THE SIDE AND PUT IT INTO THE COMMAND BYTE.  ╥EMEMBER THAT WE HAVE TO FLIP
  3821. THE SIDE BIT FOR A 1581.
  3822.  
  3823. %    AND #$01
  3824. %    ASL
  3825. %    ASL
  3826. %    ASL
  3827. %    ASL
  3828. %    BIT MS╘YPE
  3829. %    BPL +
  3830. %    EOR #$10
  3831. % +  JSR SEND╒0
  3832. %    PLA
  3833. %    BCC +
  3834. %    RTS
  3835. % +  JSR KERNEL├IOUT      ;CYLINDER NUMBER
  3836. %    LDA #1               ;START SECTOR NUMBER
  3837. %    JSR KERNEL├IOUT
  3838. %    LDA #9               ;SECTOR COUNT
  3839. %    JSR KERNEL├IOUT
  3840. %    JSR KERNEL╒NLSN
  3841.  
  3842. ╨REPARE TO RECEIVE THE TRACK DATA.
  3843.  
  3844. %    SEI
  3845. %    CLC
  3846. %    JSR KERNEL╙PINP
  3847. %    BIT CIA╞LAGS
  3848. %    JSR TOGGLE├LOCK
  3849. %    LDA #<TRACKBUF
  3850. %    LDY #>TRACKBUF
  3851. %    STA BUFPTR
  3852. %    STY BUFPTR+1
  3853.  
  3854. ╟ET THE SECTOR DATA FOR EACH OF THE 9 SECTORS OF THE TRACK.
  3855.  
  3856. %    LDA #0
  3857. %    STA SECNUM
  3858. % -  BIT MS╘YPE
  3859. %    BMI +
  3860.  
  3861. ╔F WE ARE DEALING WITH A 1571, WE HAVE TO SET THE BUFFER POINTER FOR THE NEXT
  3862. SECTOR, TAKING INTO ACCOUNT THE SOFT INTERLEAVE OF 4.
  3863.  
  3864. %    JSR GET1571┬UF╨TR
  3865. % +  JSR READ╙ECTOR
  3866. %    BCS TRACK┼XIT
  3867. %    INC SECNUM
  3868. %    LDA SECNUM
  3869. %    CMP #9
  3870. %    BCC -
  3871. %    CLC
  3872. %    TRACK┼XIT = *
  3873. %    CLI
  3874. %    RTS
  3875. %
  3876.  
  3877. ╟ET THE BUFFER POINTER FOR THE NEXT 1571 SECTOR.
  3878.  
  3879. % GET1571┬UF╨TR = *
  3880. %    LDA #<TRACKBUF
  3881. %    STA BUFPTR
  3882. %    LDX SECNUM
  3883. %    CLC
  3884. %    LDA #>TRACKBUF
  3885. %    ADC BUFPTR1571,X
  3886. %    STA BUFPTR+1
  3887. %    RTS
  3888. %
  3889. % BUFPTR1571 = *
  3890. %    .BYTE 0,8,16,6,14,4,12,2,10
  3891. %
  3892.  
  3893. ╥EAD AN INDIVIDUAL SECTOR INTO MEMORY AT THE SPECIFIED ADDRESS.
  3894.  
  3895. % READ╙ECTOR = *  ;( BUFPTR ) : .├╙=ERR
  3896.  
  3897. ╟ET AND CHECK THE BURST STATUS BYTE FOR ERRORS.
  3898.  
  3899. %    JSR GET┬URST┬YTE
  3900. %    STA ERRNO
  3901. %    AND #$0F
  3902. %    CMP #2
  3903. %    BCC +
  3904. %    RTS
  3905. % +  LDX #2
  3906. %    LDY #0
  3907. %
  3908.  
  3909. ╥ECEIVE THE 512 SECTOR DATA BYTES INTO MEMORY.
  3910.  
  3911. %    READ┬YTE = *
  3912. %    LDA #$08
  3913. % -  BIT CIA╞LAGS
  3914. %    BEQ -
  3915. %    LDA CIA├LOCK
  3916. %    EOR #$10
  3917. %    STA CIA├LOCK
  3918. %    LDA CIA─ATA
  3919. %    STA (BUFPTR),Y
  3920. %    INY
  3921. %    BNE READ┬YTE
  3922. %    INC BUFPTR+1
  3923. %    DEX
  3924. %    BNE READ┬YTE
  3925. %    RTS
  3926. %
  3927. % OLD├LOCK = 5
  3928. %
  3929.  
  3930. ╫RITE AN INDIVIDUAL SECTOR TO DISK, FROM A SPECIFIED MEMORY ADDRESS.
  3931.  
  3932. % WRITE╙ECTOR = *  ;( BUFPTR, .┴=TRACK, .╪=SIDE, .┘=SECTOR ) : .├╙=ERR
  3933. %    PHA
  3934. %    STY SECNUM
  3935.  
  3936. ╟ET THE SIDE INTO THE BURST COMMAND BYTE
  3937.  
  3938. %    TXA
  3939. %    AND #$01
  3940. %    ASL
  3941. %    ASL
  3942. %    ASL
  3943. %    ASL
  3944. %    ORA #$02
  3945. %    BIT MS╘YPE
  3946. %    BPL +
  3947. %    EOR #$10
  3948. % +  JSR SEND╒0
  3949. %    PLA
  3950. %    BCC +
  3951. %    RTS
  3952.  
  3953. ╙END REST OF PARAMETERS FOR BURST COMMAND.
  3954.  
  3955. % +  JSR KERNEL├IOUT      ;TRACK NUMBER
  3956. %    LDA SECNUM           ;SECTOR NUMBER
  3957. %    JSR KERNEL├IOUT
  3958. %    LDA #1               ;SECTOR COUNT
  3959. %    JSR KERNEL├IOUT
  3960. %    JSR KERNEL╒NLSN
  3961. %    SEI
  3962. %    LDA #$40
  3963. %    STA OLD├LOCK
  3964. %    SEC
  3965. %    JSR KERNEL╙PINP      ;SET FOR BURST OUTPUT
  3966. %    SEI
  3967. %    BIT CIA╞LAGS
  3968. %    LDX #2
  3969. %    LDY #0
  3970. %
  3971.  
  3972. ╫RITE THE 512 BYTES FOR THE SECTOR.
  3973.  
  3974. %    WRITE┬YTE = *
  3975. %    LDA CIA├LOCK
  3976. %    CMP CIA├LOCK
  3977. %    BNE WRITE┬YTE
  3978. %    EOR OLD├LOCK
  3979. %    AND #$40
  3980. %    BEQ WRITE┬YTE
  3981. %    LDA (BUFPTR),Y
  3982. %    STA CIA─ATA
  3983. %    LDA OLD├LOCK
  3984. %    EOR #$40
  3985. %    STA OLD├LOCK
  3986. %    LDA #8
  3987. % -  BIT CIA╞LAGS
  3988. %    BEQ -
  3989. %    INY
  3990. %    BNE WRITE┬YTE
  3991. %    INC BUFPTR+1
  3992. %    DEX
  3993. %    BNE WRITE┬YTE
  3994. %
  3995.  
  3996. ╥EAD BACK THE BURST STATUS BYTE TO SEE IF ANYTHING WENT WRONG WITH THE WRITE.
  3997.  
  3998. %    CLC
  3999. %    JSR KERNEL╙PINP
  4000. %    BIT CIA╞LAGS
  4001. %    JSR TOGGLE├LOCK
  4002. %    JSR SERIAL╫AIT
  4003. %    LDX CIA─ATA
  4004. %    JSR TOGGLE├LOCK
  4005. %    TXA
  4006. %    STA ERRNO
  4007. %    AND #$0F
  4008. %    CMP #2
  4009. %    CLI
  4010. %    RTS
  4011. %
  4012.  
  4013. ╘HIS NEXT LEVEL OF ROUTINES DEALS WITH LOGICAL SECTORS AND THE TRACK CACHE
  4014. RATHER THAN WITH HARDWARE.
  4015.  
  4016. % ;====LOGICAL SECTOR LEVEL====
  4017. %
  4018.  
  4019. ╔NVALIDATE THE TRACK CACHE IF THE ═╙-─╧╙ DRIVE NUMBER IS CHANGED OR IF A NEW
  4020. DISK IS INSERTED.  ╘HIS ROUTINE HAS TO ESTABLISH A ╥┴═ CONFIGURATION OF $0┼
  4021. SINCE IT WILL BE CALLED FROM ╥┴═0.  ├ONFIGURATION $0┼ GIVES ╥┴═0 FROM $0000 TO
  4022. $┬╞╞╞, ╦ERNAL ╥╧═ FROM $├000 TO $╞╞╞╞, AND THE ╔/╧ SPACE OVER THE ╦ERNAL FROM
  4023. $─000 TO $─╞╞╞.  ╘HIS CONFIGURATION IS SET BY ALL APPLICATION INTERFACE
  4024. SUBROUTINES.
  4025.  
  4026. % INIT╨ACKAGE = *
  4027. %    LDA #$0E
  4028. %    STA $FF00
  4029. %    LDA #$FF
  4030. %    STA BUF├YLINDER
  4031. %    STA BUF╙IDE
  4032. %    LDX #7
  4033. % -  STA DIR─IRTY,X
  4034. %    DEX
  4035. %    BPL -
  4036. %    STA FAT─IRTY
  4037. %    CLC
  4038. %    RTS
  4039. %
  4040.  
  4041. ╠OCATE A SECTOR (BLOCK) IN THE TRACK CACHE, OR READ THE CORRESPONDING PHYSICAL
  4042. TRACK INTO THE TRACK CACHE IF NECESSARY.  ╘HIS ROUTINE ACCEPTS THE CYLINDER,
  4043. SIDE, AND SECTOR NUMBERS OF THE BLOCK.
  4044.  
  4045. % SECTOR╙AVE = 5
  4046. %
  4047. % READ┬LOCK = *  ;( .┴=CYLINDER,.╪=SIDE,.┘=SECTOR ) : .┴┘=BLK╨TR,.├╙=ERR
  4048.  
  4049. ├HECK IF THE CORRECT TRACK IS IN THE TRACK CACHE.
  4050.  
  4051. %    CMP BUF├YLINDER
  4052. %    BNE READ┬LOCK╨HYSICAL
  4053. %    CPX BUF╙IDE
  4054. %    BNE READ┬LOCK╨HYSICAL
  4055.  
  4056. ╔F SO, THEN LOCATE THE SECTOR'S ADDRESS AND RETURN THAT.
  4057.  
  4058. %    DEY
  4059. %    TYA
  4060. %    ASL
  4061. %    CLC
  4062. %    ADC #>TRACKBUF
  4063. %    TAY
  4064. %    LDA #<TRACKBUF
  4065. %    CLC
  4066. %    RTS
  4067. %
  4068.  
  4069. ╚ERE, WE HAVE TO READ THE PHYSICAL TRACK INTO THE TRACK CACHE.  ╫E SAVE THE
  4070. INPUT PARAMETERS AND CALL THE HARDWARE-LEVEL TRACK-READING ROUTINE.
  4071.  
  4072. %    READ┬LOCK╨HYSICAL = *
  4073. %    STA BUF├YLINDER
  4074. %    STX BUF╙IDE
  4075. %    STY SECTOR╙AVE
  4076. %    JSR READ╘RACK
  4077.  
  4078. ├HECK FOR ERRORS.
  4079.  
  4080. %    BCC READ┬LOCK╨HYSICAL╧K
  4081. %    LDA ERRNO
  4082. %    AND #$0F
  4083. %    CMP #11    ;DISK CHANGE
  4084. %    BEQ +
  4085. %    SEC
  4086. %    RTS
  4087.  
  4088. ╔F THE ERROR THAT HAPPENED IS A "─ISK ├HANGE" ERROR, THEN MOUNT THE DISK AND
  4089. TRY TO READ THE PHYSICAL TRACK AGAIN.
  4090.  
  4091. % +  JSR MOUNT─ISK
  4092. %    LDA BUF├YLINDER
  4093. %    LDX BUF╙IDE
  4094. %    LDY SECTOR╙AVE
  4095. %    BCC READ┬LOCK╨HYSICAL
  4096. %    RTS
  4097. %
  4098.  
  4099. ╚ERE, THE PHYSICAL TRACK HAS BEEN READ INTO THE TRACK CACHE OK, SO WE RECOVER
  4100. THE ORIGINAL INPUT PARAMETERS AND TRY THE TOP OF THE ROUTINE AGAIN.
  4101.  
  4102. %    READ┬LOCK╨HYSICAL╧K = *
  4103. %    LDA BUF├YLINDER
  4104. %    LDX BUF╙IDE
  4105. %    LDY SECTOR╙AVE
  4106. %    JMP READ┬LOCK
  4107. %
  4108.  
  4109. ─IVIDE THE GIVEN NUMBER BY 18.  ╘HIS IS NEEDED FOR THE CALCULATIONS TO CONVERT
  4110. A LOGICAL SECTOR NUMBER TO THE CORRESPONDING PHYSICAL CYLINDER, SIDE, AND
  4111. SECTOR NUMBERS THAT THE LOWER-LEVEL ROUTINES REQUIRE.  ╘HE METHOD OF REPEATED
  4112. SUBTRACTION IS USED.  ╘HIS ROUTINE WOULD PROBABLY WORK FASTER IF WE TRIED TO
  4113. REPEATEDLY SUBTRACT 360 (18*20) AT THE TOP, BUT ╔ DIDN'T BOTHER.
  4114.  
  4115. % DIVIDE┬Y18 = *  ;( .┴┘=NUMBER ) : .┴=QUOTIENT, .┘=REMAINDER
  4116. %    ;** COULD REPEATEDLY SUBTRACT 360 HERE
  4117. %    LDX #$FF
  4118. % -  INX
  4119. %    SEC
  4120. %    SBC #18
  4121. %    BCS -
  4122. %    DEY
  4123. %    BPL -
  4124. %    CLC
  4125. %    ADC #18
  4126. %    INY
  4127. %    TAY
  4128. %    TXA
  4129. %    RTS
  4130. %
  4131.  
  4132. ├ONVERT THE GIVEN LOGICAL BLOCK NUMBER TO THE CORRESPONDING PHYSICAL CYLINDER,
  4133. SIDE, AND SECTOR NUMBERS.  ╘HIS ROUTINE FOLLOWS THE FORMULAE GIVEN IN THE
  4134. PREVIOUS ARTICLE WITH A FEW SIMPLIFYING TRICKS.
  4135.  
  4136. % CONVERT╠OGICAL┬LOCK╬UM = *  ;( .┴┘=BLOCK╬UM ) : .┴=CYL, .╪=SIDE,.┘=SEC
  4137. %    JSR DIVIDE┬Y18
  4138. %    LDX #0
  4139. %    CPY #9
  4140. %    BCC +
  4141. %    PHA
  4142. %    TYA
  4143. %    SBC #9
  4144. %    TAY
  4145. %    PLA
  4146. %    LDX #1
  4147. % +  INY
  4148. %    RTS
  4149. %
  4150.  
  4151. ├OPY A SEQUENTIAL GROUP OF LOGICAL SECTORS INTO MEMORY.  ╘HIS ROUTINE IS USED
  4152. BY THE DIRECTORY LOADING ROUTINE TO LOAD THE ╞┴╘ AND ╥OOT ─IRECTORY, AND IS
  4153. USED BY THE CLUSTER READING ROUTINE TO RETRIEVE ALL OF THE BLOCKS OF A
  4154. CLUSTER.  ┴FTER THE GIVEN STARTING LOGICAL SECTOR NUMBER IS CONVERTED INTO ITS
  4155. PHYSICAL CYLINDER, SIDE, AND SECTOR EQUIVALENT, THE PHYSICAL VALUES ARE
  4156. INCREMENTED TO GET THE ADDRESS OF SUCCESSIVE SECTORS OF THE GROUP.  ╘HIS
  4157. AVOIDS THE OVERHEAD OF THE LOGICAL TO PHYSICAL CONVERSION.  ╤UITE A NUMBER OF
  4158. TEMPORARIES ARE NEEDED.
  4159.  
  4160. % DEST╨TR = 6
  4161. % CUR├YLINDER = 8
  4162. % CUR╙IDE = 9
  4163. % CUR╙ECTOR = 10
  4164. % BLOCK├OUNTDOWN = 11
  4165. % SOURCE╨TR = 12
  4166. %
  4167. % COPY┬LOCKS = *  ;( .┴┘=START┬LOCK, .╪=BLOCK├OUNT, ($6)=DEST ) : .├╙=ERR
  4168. %    STX BLOCK├OUNTDOWN
  4169. %    JSR CONVERT╠OGICAL┬LOCK╬UM
  4170. %    STA CUR├YLINDER
  4171. %    STX CUR╙IDE
  4172. %    STY CUR╙ECTOR
  4173. %
  4174. %    COPY┬LOCK╠OOP = *
  4175. %    LDA CUR├YLINDER
  4176. %    LDX CUR╙IDE
  4177. %    LDY CUR╙ECTOR
  4178. %    JSR READ┬LOCK
  4179. %    BCC +
  4180. %    RTS
  4181. % +  STA SOURCE╨TR
  4182. %    STY SOURCE╨TR+1
  4183. %    LDX #2
  4184. %    LDY #0
  4185.  
  4186. ╚ERE ╔ UNROLL THE COPYING LOOP A LITTLE BIT TO CUT THE OVERHEAD OF THE BRANCH
  4187. INSTRUCTION IN HALF.  (┴ CYCLE SAVED... YOU KNOW).
  4188.  
  4189. % -  LDA (SOURCE╨TR),Y
  4190. %    STA (DEST╨TR),Y
  4191. %    INY
  4192. %    LDA (SOURCE╨TR),Y
  4193. %    STA (DEST╨TR),Y
  4194. %    INY
  4195. %    BNE -
  4196. %    INC SOURCE╨TR+1
  4197. %    INC DEST╨TR+1
  4198. %    DEX
  4199. %    BNE -
  4200.  
  4201. ╔NCREMENT THE CYLINDER, SIDE, SECTOR VALUES.
  4202.  
  4203. %    INC CUR╙ECTOR
  4204. %    LDA CUR╙ECTOR
  4205. %    CMP #10
  4206. %    BCC +
  4207. %    LDA #1
  4208. %    STA CUR╙ECTOR
  4209. %    INC CUR╙IDE
  4210. %    LDA CUR╙IDE
  4211. %    CMP #2
  4212. %    BCC +
  4213. %    LDA #0
  4214. %    STA CUR╙IDE
  4215. %    INC CUR├YLINDER
  4216. % +  DEC BLOCK├OUNTDOWN
  4217. %    BNE COPY┬LOCK╠OOP
  4218. %    CLC
  4219. %    RTS
  4220. %
  4221.  
  4222. ├ONVERT A GIVEN CLUSTER NUMBER INTO THE FIRST CORRESPONDING LOGICAL BLOCK
  4223. NUMBER.
  4224.  
  4225. % CONVERT├LUSTER╬UM = *  ;( .┴┘=CLUSTER╬UM ) : .┴┘=LOGICAL┬LOCK╬UM
  4226. %    SEC
  4227. %    SBC #2
  4228. %    BCS +
  4229. %    DEY
  4230. % +  LDX CLUSTER┬LOCK├OUNT
  4231. %    CPX #1
  4232. %    BEQ +
  4233. %    ASL
  4234. %    STY 7
  4235. %    ROL 7
  4236. %    LDY 7
  4237. % +  CLC
  4238. %    ADC FIRST╞ILE┬LOCK
  4239. %    BCC +
  4240. %    INY
  4241. % +  RTS
  4242. %
  4243.  
  4244. ╥EAD A CLUSTER INTO THE ├LUSTER ┬UFFER, GIVEN THE CLUSTER NUMBER.  ╘HE CLUSTER
  4245. NUMBER IS CONVERTED TO A LOGICAL SECTOR NUMBER AND THEN THE SECTOR COPYING
  4246. ROUTINE IS CALLED.  ╘HE FORMULA GIVEN IN THE PREVIOUS ARTICLE IS USED.
  4247.  
  4248. % READ├LUSTER = *  ;( .┴┘=CLUSTER╬UMBER ) : CLUSTER┬UF, .├╙=ERR
  4249. %    JSR CONVERT├LUSTER╬UM
  4250. %
  4251. %    ;** READ LOGICAL BLOCKS COMPRISING CLUSTER
  4252. %    LDX #<CLUSTER┬UF
  4253. %    STX 6
  4254. %    LDX #>CLUSTER┬UF
  4255. %    STX 7
  4256. %    LDX CLUSTER┬LOCK├OUNT
  4257. %    JMP COPY┬LOCKS
  4258. %
  4259.  
  4260. ╫RITE A LOGICAL BLOCK OUT TO DISK.  ╘HE REAL PURPOSE OF THIS ROUTINE IS TO
  4261. INVALIDATE THE READ-TRACK CACHE IF THE BLOCK TO BE WRITTEN IS CONTAINED IN
  4262. THE CACHE.
  4263.  
  4264. % WRITE╠OGICAL┬LOCK = *  ;( .┴┘=LOGICAL┬LOCK╬UMBER, BUFPTR ) : .├╙=ERR
  4265. %    JSR CONVERT╠OGICAL┬LOCK╬UM
  4266. %    CMP BUF├YLINDER
  4267. %    BNE +
  4268. %    CPX BUF╙IDE
  4269. %    BNE +
  4270. %    PHA
  4271. %    LDA #$FF
  4272. %    STA BUF├YLINDER
  4273. %    STA BUF╙IDE
  4274. %    PLA
  4275. % +  JSR WRITE╙ECTOR
  4276. %    RTS
  4277. %
  4278. % WRITE├LUSTER╙AVE .BUF 2
  4279. %
  4280.  
  4281. ╫RITE A CLUSTER-FUL OF DATA OUT TO DISK FROM THE CLUSTER BUFFER.  ╘HIS ROUTINE
  4282. SIMPLY CALLS THE WRITE LOGICAL BLOCK ROUTINE ONCE OR TWICE, DEPENDING ON THE
  4283. CLUSTER SIZE OF THE DISK INVOLVED.
  4284.  
  4285. % WRITE├LUSTER = *  ;( .┴┘=CLUSTER╬UMBER, CLUSTER┬UF ) : .├╙=ERR
  4286. %    JSR CONVERT├LUSTER╬UM
  4287. %    LDX #<CLUSTER┬UF
  4288. %    STX BUFPTR
  4289. %    LDX #>CLUSTER┬UF
  4290. %    STX BUFPTR+1
  4291. %    STA WRITE├LUSTER╙AVE
  4292. %    STY WRITE├LUSTER╙AVE+1
  4293. %    JSR WRITE╠OGICAL┬LOCK
  4294. %    BCC +
  4295. %    RTS
  4296. % +  LDA CLUSTER┬LOCK├OUNT
  4297. %    CMP #2
  4298. %    BCS +
  4299. %    RTS
  4300. % +  LDA WRITE├LUSTER╙AVE
  4301. %    LDY WRITE├LUSTER╙AVE+1
  4302. %    CLC
  4303. %    ADC #1
  4304. %    BCC +
  4305. %    INY
  4306. % +  JSR WRITE╠OGICAL┬LOCK
  4307. %    RTS
  4308. %
  4309.  
  4310. ╘HIS NEXT LEVEL OF ROUTINES DEAL WITH THE DATA STRUCTURES OF THE ═╙-─╧╙ DISK
  4311. FORMAT.
  4312.  
  4313. % ;====═╙-─╧╙ FORMAT LEVEL====
  4314. %
  4315. % BOOT┬LOCK = 2
  4316. %
  4317.  
  4318. ╥EAD THE DISK FORMAT PARAMETERS, DIRECTORY, AND ╞┴╘ INTO MEMORY.
  4319.  
  4320. % MS─IR = *  ;( ) : .┴┘=DIRBUF, .╪=DIR┼NTRIES, .├╙=ERR
  4321. %    LDA #$0E
  4322. %    STA $FF00
  4323. %
  4324.  
  4325. ╥EAD THE BOOT SECTOR AND EXTRACT THE PARAMETERS.
  4326.  
  4327. %    ;** GET PARAMETERS FROM BOOT SECTOR
  4328. %    LDA #0
  4329. %    LDY #0
  4330. %    JSR CONVERT╠OGICAL┬LOCK╬UM
  4331. %    JSR READ┬LOCK
  4332. %    BCC +
  4333. %    RTS
  4334. % +  STA BOOT┬LOCK
  4335. %    STY BOOT┬LOCK+1
  4336. %    LDY #13              ;GET CLUSTER SIZE
  4337. %    LDA (BOOT┬LOCK),Y
  4338. %    STA CLUSTER┬LOCK├OUNT
  4339. %    CMP #3
  4340. %    BCC +
  4341. %
  4342.  
  4343. ╔F A DISK PARAMETER IS FOUND TO EXCEED THE LIMITS OF ╠╥╥, ERROR CODE #60 IS
  4344. RETURNED.
  4345.  
  4346. %    INVALID╨ARMS = *
  4347. %    LDA #60
  4348. %    STA ERRNO
  4349. %    SEC
  4350. %    RTS
  4351. %
  4352. % +  LDY #16              ;CHECK ╞┴╘ REPLICATION COUNT, MUST BE 2
  4353. %    LDA (BOOT┬LOCK),Y
  4354. %    CMP #2
  4355. %    BNE INVALID╨ARMS
  4356. %    LDY #22              ;GET ╞┴╘ SIZE IN SECTORS
  4357. %    LDA (BOOT┬LOCK),Y
  4358. %    STA FAT┬LOCKS
  4359. %    CMP #4
  4360. %    BCS INVALID╨ARMS
  4361. %    LDY #17              ;GET DIRECTORY SIZE
  4362. %    LDA (BOOT┬LOCK),Y
  4363. %    STA ROOT─IR┼NTRIES
  4364. %    CMP #129
  4365. %    BCS INVALID╨ARMS
  4366. %    LSR
  4367. %    LSR
  4368. %    LSR
  4369. %    LSR
  4370. %    STA ROOT─IR┬LOCKS
  4371. %    LDY #19              ;GET TOTAL SECTOR COUNT
  4372. %    LDA (BOOT┬LOCK),Y
  4373. %    STA TOTAL╙ECTORS
  4374. %    INY
  4375. %    LDA (BOOT┬LOCK),Y
  4376. %    STA TOTAL╙ECTORS+1
  4377. %    LDY #24              ;CHECK SECTORS PER TRACK, MUST BE 9
  4378. %    LDA (BOOT┬LOCK),Y
  4379. %    CMP #9
  4380. %    BNE INVALID╨ARMS
  4381. %    LDY #26
  4382. %    LDA (BOOT┬LOCK),Y
  4383. %    CMP #2               ;CHECK NUMBER OF SIDES, MUST BE 2
  4384. %    BNE INVALID╨ARMS
  4385. %    LDY #14              ;CHECK NUMBER OF BOOT SECTORS, MUST BE 1
  4386. %    LDA (BOOT┬LOCK),Y
  4387. %    CMP #1
  4388. %    BNE INVALID╨ARMS
  4389. %
  4390.  
  4391. ├ALCULATE THE DERIVED PARAMETERS.
  4392.  
  4393. %    ;** GET DERIVED PARAMETERS
  4394. %    LDA FAT┬LOCKS        ;FIRST ROOT DIRECTORY SECTOR
  4395. %    ASL
  4396. %    CLC
  4397. %    ADC #1
  4398. %    STA FIRST╥OOT─IR┬LOCK
  4399. %    CLC                  ;FIRST FILE SECTOR
  4400. %    ADC ROOT─IR┬LOCKS
  4401. %    STA FIRST╞ILE┬LOCK
  4402. %    LDA TOTAL╙ECTORS     ;NUMBER OF FILE CLUSTERS
  4403. %    LDY TOTAL╙ECTORS+1
  4404. %    SEC
  4405. %    SBC FIRST╞ILE┬LOCK
  4406. %    BCS +
  4407. %    DEY
  4408. % +  STA FILE├LUSTER├OUNT
  4409. %    STY FILE├LUSTER├OUNT+1
  4410. %    LDA CLUSTER┬LOCK├OUNT
  4411. %    CMP #2
  4412. %    BNE +
  4413. %    LSR FILE├LUSTER├OUNT+1
  4414. %    ROR FILE├LUSTER├OUNT
  4415. % +  CLC
  4416. %    LDA FILE├LUSTER├OUNT
  4417. %    ADC #2
  4418. %    STA LAST╞AT┼NTRY
  4419. %    LDA FILE├LUSTER├OUNT+1
  4420. %    ADC #0
  4421. %    STA LAST╞AT┼NTRY+1
  4422. %
  4423. %    ;** LOAD ╞┴╘
  4424. %    LDA #<FATBUF
  4425. %    LDY #>FATBUF
  4426. %    STA 6
  4427. %    STY 7
  4428. %    LDA #1
  4429. %    LDY #0
  4430. %    LDX FAT┬LOCKS
  4431. %    JSR COPY┬LOCKS
  4432. %    BCC +
  4433. %    RTS
  4434. %
  4435. %    ;** LOAD ACTUAL DIRECTORY
  4436. % +  LDA #<DIRBUF
  4437. %    LDY #>DIRBUF
  4438. %    STA 6
  4439. %    STY 7
  4440. %    LDA FIRST╥OOT─IR┬LOCK
  4441. %    LDY #0
  4442. %    LDX ROOT─IR┬LOCKS
  4443. %    JSR COPY┬LOCKS
  4444. %    BCC +
  4445. %    RTS
  4446. % +  LDA #<DIRBUF
  4447. %    LDY #>DIRBUF
  4448. %    LDX ROOT─IR┼NTRIES
  4449. %    CLC
  4450. %    RTS
  4451. %
  4452.  
  4453. ╘HIS ROUTINE LOCATES THE GIVEN ╞┴╘ TABLE ENTRY NUMBER AND RETURNS THE VALUE
  4454. STORED IN IT.  ╙OME WORK IS NEEDED TO DEAL WITH THE 12-BIT COMPRESSED DATA
  4455. STRUCTURE.
  4456.  
  4457. % ENTRY┴DDR = 2
  4458. % ENTRY╫ORK = 4
  4459. % ENTRY┬ITS = 5
  4460. % ENTRY─ATA0 = 6
  4461. % ENTRY─ATA1 = 7
  4462. % ENTRY─ATA2 = 8
  4463. %
  4464. % LOCATE╞AT┼NTRY = *  ;( .┴┘=FAT┼NTRY╬UMBER ) : ENTRY┴DDR, ENTRY┬ITS%1
  4465.  
  4466. ─IVIDE THE ╞┴╘ ENTRY NUMBER BY TWO AND MULTIPLY BY THREE BECAUSE TWO ╞┴╘
  4467. ENTRIES ARE STORED IN THREE BYTES.  ╘HEN ADD THE ╞┴╘ BASE ADDRESS AND WE HAVE
  4468. THE ADDRESS OF THE THREE BYTES THAT CONTAIN THE ╞┴╘ ENTRY WE ARE INTERESTED
  4469. IN.  ╔ RETRIEVE THE THREE BYTES INTO ZERO-PAGE MEMORY FOR EASY MANIPULATION.
  4470.  
  4471. %    STA ENTRY┬ITS
  4472. %    ;** DIVIDE BY TWO
  4473. %    STY ENTRY┴DDR+1
  4474. %    LSR ENTRY┴DDR+1
  4475. %    ROR
  4476. %
  4477. %    ;** TIMES THREE
  4478. %    STA ENTRY╫ORK
  4479. %    LDX ENTRY┴DDR+1
  4480. %    ASL
  4481. %    ROL ENTRY┴DDR+1
  4482. %    CLC
  4483. %    ADC ENTRY╫ORK
  4484. %    STA ENTRY┴DDR
  4485. %    TXA
  4486. %    ADC ENTRY┴DDR+1
  4487. %    STA ENTRY┴DDR+1
  4488. %
  4489. %    ;** ADD BASE, GET DATA
  4490. %    CLC
  4491. %    LDA ENTRY┴DDR
  4492. %    ADC #<FATBUF
  4493. %    STA ENTRY┴DDR
  4494. %    LDA ENTRY┴DDR+1
  4495. %    ADC #>FATBUF
  4496. %    STA ENTRY┴DDR+1
  4497. %    LDY #2
  4498. % -  LDA (ENTRY┴DDR),Y
  4499. %    STA ENTRY─ATA0,Y
  4500. %    DEY
  4501. %    BPL -
  4502. %    RTS
  4503. %
  4504. % GET╞AT┼NTRY = *  ;( .┴┘=FAT┼NTRY╬UMBER ) : .┴┘=FAT┼NTRY╓ALUE
  4505. %    JSR LOCATE╞AT┼NTRY
  4506. %    LDA ENTRY┬ITS
  4507. %    AND #1
  4508. %    BNE +
  4509. %
  4510.  
  4511. ╔F THE ORIGINAL GIVEN ╞┴╘ ENTRY NUMBER IS EVEN, THEN WE WANT THE FIRST 12-BIT
  4512. COMPRESSED FIELD.  ╘HE NYBBLES ARE EXTRACTED ACCORDING TO THE DIAGRAM SHOWN
  4513. EARLIER.
  4514.  
  4515. %    ;** CASE 1: FIRST 12-BIT CLUSTER
  4516. %    LDA ENTRY─ATA1
  4517. %    AND #$0F
  4518. %    TAY
  4519. %    LDA ENTRY─ATA0
  4520. %    RTS
  4521. %
  4522.  
  4523. ╧THERWISE, WE WANT THE SECOND 12-BIT FIELD.
  4524.  
  4525. %    ;** CASE 2: SECOND 12-BIT CLUSTER
  4526. % +  LDA ENTRY─ATA1
  4527. %    LDX #4
  4528. % -  LSR ENTRY─ATA2
  4529. %    ROR
  4530. %    DEX
  4531. %    BNE -
  4532. %    LDY ENTRY─ATA2
  4533. %    RTS
  4534. %
  4535. % FAT╓ALUE = 9
  4536. %
  4537.  
  4538. ├HANGE THE VALUE IN A ╞┴╘ ENTRY.  ╘HIS ROUTINE IS QUITE SIMILAR TO THE GET
  4539. ROUTINE.
  4540.  
  4541. % SET╞AT┼NTRY = *  ;( .┴┘=FAT┼NTRY╬UMBER, (FAT╓ALUE) )
  4542. %    JSR LOCATE╞AT┼NTRY
  4543. %    LDA FAT╓ALUE+1
  4544. %    AND #$0F
  4545. %    STA FAT╓ALUE+1
  4546. %    LDA ENTRY┬ITS
  4547. %    AND #1
  4548. %    BNE +
  4549. %
  4550. %    ;** CASE 1: FIRST 12-BIT CLUSTER
  4551. %    LDA FAT╓ALUE
  4552. %    STA ENTRY─ATA0
  4553. %    LDA ENTRY─ATA1
  4554. %    AND #$F0
  4555. %    ORA FAT╓ALUE+1
  4556. %    STA ENTRY─ATA1
  4557. %    JMP SET╞AT┼XIT
  4558. %
  4559. %    ;** CASE 2: SECOND 12-BIT CLUSTER
  4560. % +  LDX #4
  4561. % -  ASL FAT╓ALUE
  4562. %    ROL FAT╓ALUE+1
  4563. %    DEX
  4564. %    BNE -
  4565. %    LDA FAT╓ALUE+1
  4566. %    STA ENTRY─ATA2
  4567. %    LDA ENTRY─ATA1
  4568. %    AND #$0F
  4569. %    ORA FAT╓ALUE
  4570. %    STA ENTRY─ATA1
  4571. %
  4572. %    SET╞AT┼XIT = *
  4573. %    LDY #2
  4574. % -  LDA ENTRY─ATA0,Y
  4575. %    STA (ENTRY┴DDR),Y
  4576. %    DEY
  4577. %    BPL -
  4578. %    STY FAT─IRTY
  4579. %    RTS
  4580. %
  4581.  
  4582. ═ARK THE DIRECTORY SECTOR CORRESPONDING TO THE GIVEN DIRECTORY ENTRY AS BEING
  4583. DIRTY SO IT WILL BE WRITTEN OUT TO DISK THE NEXT TIME THE MS╞LUSH ROUTINE IS
  4584. CALLED.
  4585.  
  4586. % DIRTY─IRENT = *  ;( WRITE─IRENT )
  4587. %    SEC
  4588. %    LDA WRITE─IRENT
  4589. %    SBC #<DIRBUF
  4590. %    LDA WRITE─IRENT+1
  4591. %    SBC #>DIRBUF
  4592. %    LSR
  4593. %    AND #$07
  4594. %    TAX
  4595. %    LDA #$FF
  4596. %    STA DIR─IRTY,X
  4597. %    RTS
  4598. %
  4599. % DEL├LUSTER = 14
  4600. %
  4601.  
  4602. ─ELETE THE ═╙-─╧╙ FILE WHOSE DIRECTORY ENTRY IS GIVEN.  ╨UT THE $┼5 INTO
  4603. ITS FILENAME, GET ITS STARTING CLUSTER AND FOLLOW THE CHAIN OF CLUSTERS
  4604. ALLOCATED TO THE FILE IN THE ╞┴╘, MARKING THEM AS UNALLOCATED (VALUE $000)
  4605. AS WE GO.  ┼XIT BY MARKING THE DIRECTORY ENTRY AS "DIRTY".
  4606.  
  4607. % MS─ELETE = *  ;( WRITE─IRENT )
  4608. %    LDY #$0E
  4609. %    STY $FF00
  4610. %    LDA WRITE─IRENT
  4611. %    LDY WRITE─IRENT+1
  4612. %    STA 2
  4613. %    STY 3
  4614. %    LDA #$E5
  4615. %    LDY #0
  4616. %    STA (2),Y
  4617. %    LDY #26
  4618. %    LDA (2),Y
  4619. %    STA DEL├LUSTER
  4620. %    INY
  4621. %    LDA (2),Y
  4622. %    STA DEL├LUSTER+1
  4623. % -  LDA DEL├LUSTER+1
  4624. %    CMP #5
  4625. %    BCC +
  4626. %    JMP DIRTY─IRENT
  4627. % +  TAY
  4628. %    LDA DEL├LUSTER
  4629. %    JSR GET╞AT┼NTRY
  4630. %    PHA
  4631. %    TYA
  4632. %    PHA
  4633. %    LDA #0
  4634. %    STA FAT╓ALUE
  4635. %    STA FAT╓ALUE+1
  4636. %    LDA DEL├LUSTER
  4637. %    LDY DEL├LUSTER+1
  4638. %    JSR SET╞AT┼NTRY
  4639. %    PLA
  4640. %    STA DEL├LUSTER+1
  4641. %    PLA
  4642. %    STA DEL├LUSTER
  4643. %    JMP -
  4644. %
  4645. % FLUSH┬LOCK = 14
  4646. % FLUSH├OUNTDOWN = $60
  4647. % FLUSH╥EPEATS = $61
  4648. % FLUSH─IR╔NDEX = $61
  4649. %
  4650.  
  4651. ╫RITE THE ╞┴╘ AND DIRECTORY SECTORS FROM MEMORY TO DISK, IF THEY ARE DIRTY.
  4652.  
  4653. % MS╞LUSH = *  ;( MS─EVICE, MS╘YPE ) : .├╙=ERROR
  4654. %    LDA #$0E
  4655. %    STA $FF00
  4656. %    LDA FAT─IRTY
  4657. %    BEQ FLUSH─IRECTORY
  4658. %    LDA #0
  4659. %    STA FAT─IRTY
  4660. %
  4661. %    ;** FLUSH FAT
  4662.  
  4663. ╞LUSH BOTH COPIES OF THE ╞┴╘, IF THERE ARE TWO; OTHERWISE, ONLY FLUSH THE ONE.
  4664.  
  4665. %    LDA #2
  4666. %    STA FLUSH╥EPEATS
  4667. %    LDA #1
  4668. %    STA FLUSH┬LOCK
  4669. %
  4670. %    MASTER╞LUSH = *
  4671. %    LDA FAT┬LOCKS
  4672. %    STA FLUSH├OUNTDOWN
  4673. %    LDA #<FATBUF
  4674. %    LDY #>FATBUF
  4675. %    STA BUFPTR
  4676. %    STY BUFPTR+1
  4677. % -  LDA FLUSH┬LOCK
  4678. %    LDY #0
  4679. %    JSR WRITE╠OGICAL┬LOCK
  4680. %    BCC +
  4681. %    RTS
  4682. % +  INC FLUSH┬LOCK
  4683. %    DEC FLUSH├OUNTDOWN
  4684. %    BNE -
  4685. %    DEC FLUSH╥EPEATS
  4686. %    BNE MASTER╞LUSH
  4687. %
  4688. %    ;** FLUSH DIRECTORY
  4689. %    FLUSH─IRECTORY = *
  4690. %    LDA FIRST╥OOT─IR┬LOCK
  4691. %    STA FLUSH┬LOCK
  4692. %    LDA ROOT─IR┬LOCKS
  4693. %    STA FLUSH├OUNTDOWN
  4694. %    LDA #0
  4695. %    STA FLUSH─IR╔NDEX
  4696. %    LDA #<DIRBUF
  4697. %    LDY #>DIRBUF
  4698. %    STA BUFPTR
  4699. %    STY BUFPTR+1
  4700. % -  LDX FLUSH─IR╔NDEX
  4701. %    LDA DIR─IRTY,X
  4702. %    BEQ +
  4703. %    LDA #0
  4704. %    STA DIR─IRTY,X
  4705. %    LDA FLUSH┬LOCK
  4706. %    LDY #0
  4707. %    JSR WRITE╠OGICAL┬LOCK
  4708. %    DEC BUFPTR+1
  4709. %    DEC BUFPTR+1
  4710. % +  INC FLUSH┬LOCK
  4711. %    INC FLUSH─IR╔NDEX
  4712. %    INC BUFPTR+1
  4713. %    INC BUFPTR+1
  4714. %    DEC FLUSH├OUNTDOWN
  4715. %    BNE -
  4716. %    CLC
  4717. %    RTS
  4718. %
  4719. % BF╞AT┼NTRY = 14
  4720. % BF┬LOCKS = $60
  4721. %
  4722.  
  4723. ├OUNT THE NUMBER OF FREE ╞┴╘ ENTRIES (VALUE $000) FROM ENTRY 2 UP TO THE
  4724. HIGHEST ╞┴╘ ENTRY AVAILABLE FOR CLUSTER ALLOCATION.  ╘HEN MULTIPLY THIS
  4725. BY THE NUMBER OF BYTES PER CLUSTER (EITHER 512 OR 1024).
  4726.  
  4727. % MS┬YTES╞REE = *  ;( ) : .┴┘╪=FILE┬YTES╞REE
  4728. %    LDY #$0E
  4729. %    STY $FF00
  4730. %    LDA #2
  4731. %    LDY #0
  4732. %    STA BF╞AT┼NTRY
  4733. %    STY BF╞AT┼NTRY+1
  4734. %    STY BF┬LOCKS
  4735. %    STY BF┬LOCKS+1
  4736. % -  LDA BF╞AT┼NTRY
  4737. %    LDY BF╞AT┼NTRY+1
  4738. %    JSR GET╞AT┼NTRY
  4739. %    STY 2
  4740. %    ORA 2
  4741. %    BNE +
  4742. %    INC BF┬LOCKS
  4743. %    BNE +
  4744. %    INC BF┬LOCKS+1
  4745. % +  INC BF╞AT┼NTRY
  4746. %    BNE +
  4747. %    INC BF╞AT┼NTRY+1
  4748. % +  LDA BF╞AT┼NTRY
  4749. %    CMP LAST╞AT┼NTRY
  4750. %    LDA BF╞AT┼NTRY+1
  4751. %    SBC LAST╞AT┼NTRY+1
  4752. %    BCC -
  4753. %    LDX CLUSTER┬LOCK├OUNT
  4754. % -  ASL BF┬LOCKS
  4755. %    ROL BF┬LOCKS+1
  4756. %    DEX
  4757. %    BNE -
  4758. %    LDA #0
  4759. %    LDY BF┬LOCKS
  4760. %    LDX BF┬LOCKS+1
  4761. %    RTS
  4762. %
  4763.  
  4764. ╘HIS IS THE FILE COPYING LEVEL.  ╔T DEALS WITH READING/WRITING THE CLUSTERS OF
  4765. ═╙-─╧╙ FILES AND COPYING THE DATA THEY CONTAIN TO/FROM THE ALREADY-OPEN ├┬═
  4766. ╦ERNAL FILE, POSSIBLY WITH ┴╙├╔╔/╨┼╘╙├╔╔ TRANSLATION.
  4767.  
  4768. % ;====FILE COPY LEVEL====
  4769. %
  4770. % TRANS═ODE = 14
  4771. % LFN = 15
  4772. % CBM─ATA╨TR = $60
  4773. % CBM─ATA╠EN = $62
  4774. % CLUSTER = $64
  4775. %
  4776.  
  4777. ├OPY THE GIVEN CLUSTER TO THE ├┬═ OUTPUT FILE.  ╘HIS ROUTINE FETCHES THE NEXT
  4778. CLUSTER OF THE FILE FOR THE NEXT TIME THIS ROUTINE IS CALLED, AND IF IT HITS
  4779. THE ╬╒╠╠ POINTER OF THE LAST CLUSTER OF A FILE, IT ADJUSTS THE NUMBER OF VALID
  4780. FILE DATA BYTES THE CURRENT CLUSTER CONTAINS TO ╞ILE╠ENGTH % ├LUSTER╠ENGTH
  4781. (SEE NOTE BELOW).
  4782.  
  4783. % COPY╞ILE├LUSTER = *  ;( CLUSTER, LFN, TRANS═ODE ) : .├╙=ERR
  4784.  
  4785. ╥EAD THE CLUSTER AND SETUP TO COPY THE WHOLE CLUSTER TO THE ├┬═ FILE.
  4786.  
  4787. %    LDA CLUSTER
  4788. %    LDY CLUSTER+1
  4789. %    JSR READ├LUSTER
  4790. %    BCC +
  4791. %    RTS
  4792. % +  LDA #<CLUSTER┬UF
  4793. %    LDY #>CLUSTER┬UF
  4794. %    STA CBM─ATA╨TR
  4795. %    STY CBM─ATA╨TR+1
  4796. %    LDA #0
  4797. %    STA CBM─ATA╠EN
  4798. %    LDA CLUSTER┬LOCK├OUNT
  4799. %    ASL
  4800. %    STA CBM─ATA╠EN+1
  4801. %
  4802.  
  4803. ╞ETCH THE NEXT CLUSTER NUMBER OF THE FILE, AND ADJUST THE CLUSTER DATA LENGTH
  4804. FOR THE LAST CLUSTER OF THE FILE.
  4805.  
  4806. %    ;**GET NEXT CLUSTER
  4807. %    LDA CLUSTER
  4808. %    LDY CLUSTER+1
  4809. %    JSR GET╞AT┼NTRY
  4810. %    STA CLUSTER
  4811. %    STY CLUSTER+1
  4812. %    CPY #$05
  4813. %    BCC COPY╞ILE├LUSTER─ATA
  4814. %    LDA LEN═╠
  4815. %    STA CBM─ATA╠EN
  4816. %    LDA #$01
  4817. %    LDX CLUSTER┬LOCK├OUNT
  4818. %    CPX #1
  4819. %    BEQ +
  4820. %    LDA #$03
  4821. % +  AND LEN═╠+1
  4822.  
  4823. ╘HE FOLLOWING THREE LINES WERE ADDED IN A LAST MINUTE PANIC AFTER REALIZING
  4824. THAT IF ╞ILE╠ENGTH % ├LUSTER╙IZE == 0, THEN THE LAST CLUSTER OF THE FILE
  4825. CONTAINS ├LUSTER╙IZE BYTES, NOT ZERO BYTES.
  4826.  
  4827. %    BNE +
  4828. %    LDX LEN═╠
  4829. %    BEQ COPY╞ILE├LUSTER─ATA
  4830. % +  STA CBM─ATA╠EN+1
  4831. %
  4832. %    COPY╞ILE├LUSTER─ATA = *
  4833. %    JSR COMMIE╧UT
  4834. %    RTS
  4835. %
  4836.  
  4837. ├OPY THE FILE DATA IN THE ═╙-─╧╙ CLUSTER BUFFER TO THE ├┬═ OUTPUT FILE.
  4838.  
  4839. % CBM─ATA╠IMIT = $66
  4840. %
  4841. % COMMIE╧UT = *  ;( CBM─ATA╨TR, CBM─ATA╠EN ) : .├╙=ERR
  4842.  
  4843. ╔F THE THE LOGICAL FILE NUMBER TO COPY TO IS 0 ("NULL DEVICE"), THEN DON'T
  4844. BOTHER COPYING ANYTHING.
  4845.  
  4846. %    LDX LFN
  4847. %    BNE +
  4848. %    CLC
  4849. %    RTS
  4850.  
  4851. ╧THERWISE, PREPARE THE LOGICAL FILE NUMBER FOR OUTPUT.
  4852.  
  4853. % +  JSR KERNEL├HKOUT
  4854. %    BCC COMMIE╧UT═ORE
  4855. %    STA ERRNO
  4856. %    RTS
  4857. %
  4858.  
  4859. ╨ROCESS THE CLUSTER DATA IN CHUNKS OF UP TO 255 BYTES OR THE NUMBER OF DATA
  4860. BYTES REMAINING IN THE CLUSTER.
  4861.  
  4862. %    COMMIE╧UT═ORE = *
  4863. %    LDA #255
  4864. %    LDX CBM─ATA╠EN+1
  4865. %    BNE +
  4866. %    LDA CBM─ATA╠EN
  4867. % +  STA CBM─ATA╠IMIT
  4868. %    LDY #0
  4869. % -  LDA (CBM─ATA╨TR),Y
  4870. %    BIT TRANS═ODE
  4871. %    BPL +
  4872.  
  4873. ╔F WE HAVE TO TRANSLATE THE CURRENT ┴╙├╔╔ CHARACTER, LOOK UP THE ╨┼╘╙├╔╔ VALUE
  4874. IN THE TRANSLATION TABLE AND OUTPUT THAT VALUE.  ╔F THE TRANSLATION TABLE
  4875. ENTRY VALUE IS $00, THEN DON'T OUTPUT A CHARACTER (FILTER OUT INVALID
  4876. CHARACTER CODES).
  4877.  
  4878. %    TAX
  4879. %    LDA TRANS┬UF,X
  4880. %    BEQ COMMIE╬EXT
  4881. % +  JSR KERNEL├HROUT
  4882. %    COMMIE╬EXT = *
  4883. %    INY
  4884. %    CPY CBM─ATA╠IMIT
  4885. %    BNE -
  4886. %
  4887.  
  4888. ╔NCREMENT THE CLUSTER BUFFER POINTER AND DECREMENT THE CLUSTER BUFFER CHARACTER
  4889. COUNT ACCORDING TO THE NUMBER OF BYTES JUST PROCESSED, AND REPEAT THE ABOVE IF
  4890. MORE FILE DATA REMAINS IN THE CURRENT CLUSTER.
  4891.  
  4892. %    CLC
  4893. %    LDA CBM─ATA╨TR
  4894. %    ADC CBM─ATA╠IMIT
  4895. %    STA CBM─ATA╨TR
  4896. %    BCC +
  4897. %    INC CBM─ATA╨TR+1
  4898. % +  SEC
  4899. %    LDA CBM─ATA╠EN
  4900. %    SBC CBM─ATA╠IMIT
  4901. %    STA CBM─ATA╠EN
  4902. %    BCS +
  4903. %    DEC CBM─ATA╠EN+1
  4904. % +  LDA CBM─ATA╠EN
  4905. %    ORA CBM─ATA╠EN+1
  4906. %    BNE COMMIE╧UT═ORE
  4907.  
  4908. ╔F WE ARE FINISHED WITH THE CLUSTER, THEN CLEAR THE ├┬═ ╦ERNAL OUTPUT CHANNEL.
  4909.  
  4910. %    JSR KERNEL├LRCHN
  4911. %    CLC
  4912. %    RTS
  4913. %
  4914.  
  4915. ╘HE FILE COPYING MAIN ROUTINE.  ╙ET UP FOR THE STARTING CLUSTER, AND CALL
  4916. THE CLUSTER COPYING ROUTINE UNTIL END-OF-FILE IS REACHED.  ├HECKS FOR A
  4917. ╬╒╠╠ CLUSTER POINTER IN THE DIRECTORY ENTRY TO HANDLE ZERO-LENGTH FILES.
  4918.  
  4919. % MS╥EAD = *  ;( CLUSTER, LEN═╠, .┴=TRANS═ODE, .╪=LFN ) : .├╙=ERR
  4920. %    LDY #$0E
  4921. %    STY $FF00
  4922. %    STA TRANS═ODE
  4923. %    STX LFN
  4924. %    LDA START├LUSTER
  4925. %    LDY START├LUSTER+1
  4926. %    STA CLUSTER
  4927. %    STY CLUSTER+1
  4928. %    JMP +
  4929. % -  JSR COPY╞ILE├LUSTER
  4930. %    BCC +
  4931. %    RTS
  4932. % +  LDA CLUSTER+1
  4933. %    CMP #$05
  4934. %    BCC -
  4935. %    CLC
  4936. %    RTS
  4937. %
  4938. % IN╠FN = $50
  4939. % GENERATE╠F = $51
  4940. % CBM─ATA═AX = $52
  4941. % REACHED┼OF = $54
  4942. % PREV╙T = $55
  4943. %
  4944.  
  4945. ╙ET THE TRANSLATION AND INPUT LOGICAL FILE NUMBER AND SET UP FOR READING
  4946. FROM A ├┬═-╦ERNAL INPUT FILE.
  4947.  
  4948. % COMMIE╔N╔NIT = *  ;( .┴=TRANS═ODE, .╪=IN╠FN )
  4949. %    STA TRANS═ODE
  4950. %    STX IN╠FN
  4951. %    LDA #0
  4952. %    STA GENERATE╠F
  4953. %    STA REACHED┼OF
  4954. %    STA PREV╙T
  4955. %    RTS
  4956. %
  4957.  
  4958. ╥EAD UP TO "CBM─ATA═AX" BYTES INTO THE SPECIFIED BUFFER FROM THE ESTABLISHED
  4959. ├┬═ LOGICAL FILE NUMBER.  ╘HE NUMBER OF BYTES READ IS RETURNED IN
  4960. "CBM─ATA╠EN".  ╔F END OF FILE OCCURS, "CBM─ATA╠EN" WILL BE ZERO AND THE .┌
  4961. FLAG WILL BE SET.  ╥EGULAR ERROR RETURN.
  4962.  
  4963. % COMMIE╔N = *  ;( CBM─ATA╨TR++, CBM─ATA═AX ) : CBM─ATA╠EN, .├╙=ERR, .┌=EOF
  4964.  
  4965. ┼STABLISH INPUT FILE, OR RETURN IMMEDIATELY IF ALREADY PAST EOF.
  4966.  
  4967. %    LDA #0
  4968. %    STA CBM─ATA╠EN
  4969. %    STA CBM─ATA╠EN+1
  4970. %    LDX REACHED┼OF
  4971. %    BEQ +
  4972. %    LDA #0
  4973. %    CLC
  4974. %    RTS
  4975. % +  LDX IN╠FN
  4976. %    JSR KERNEL├HKIN
  4977. %    BCC COMMIE╔N═ORE
  4978. %    STA ERRNO
  4979. %    RTS
  4980. %
  4981.  
  4982. ╥EAD NEXT CHUNK OF UP TO 255 BYTES INTO INPUT BUFFER.
  4983.  
  4984. %    COMMIE╔N═ORE = *
  4985. %    LDA #255
  4986. %    LDX CBM─ATA═AX+1
  4987. %    BNE +
  4988. %    LDA CBM─ATA═AX
  4989. % +  STA CBM─ATA╠IMIT
  4990. %    LDY #0
  4991. % -  JSR COMMIE╔N┬YTE
  4992. %    BCC +
  4993. %    RTS
  4994. % +  BEQ +
  4995. %    STA (CBM─ATA╨TR),Y
  4996. %    INY
  4997. %    CPY CBM─ATA╠IMIT
  4998. %    BNE -
  4999. %
  5000.  
  5001. ╨REPARE TO READ ANOTHER CHUNK, OR EXIT.
  5002.  
  5003. % +  STY CBM─ATA╠IMIT
  5004. %    CLC
  5005. %    LDA CBM─ATA╨TR
  5006. %    ADC CBM─ATA╠IMIT
  5007. %    STA CBM─ATA╨TR
  5008. %    BCC +
  5009. %    INC CBM─ATA╨TR+1
  5010. % +  CLC
  5011. %    LDA CBM─ATA╠EN
  5012. %    ADC CBM─ATA╠IMIT
  5013. %    STA CBM─ATA╠EN
  5014. %    BCC +
  5015. %    INC CBM─ATA╠EN+1
  5016. % +  SEC
  5017. %    LDA CBM─ATA═AX
  5018. %    SBC CBM─ATA╠IMIT
  5019. %    STA CBM─ATA═AX
  5020. %    BCS +
  5021. %    DEC CBM─ATA═AX+1
  5022. % +  LDA REACHED┼OF
  5023. %    BNE +
  5024. %    LDA CBM─ATA═AX
  5025. %    ORA CBM─ATA═AX+1
  5026. %    BNE COMMIE╔N═ORE
  5027.  
  5028. ╙HUT DOWN READING AND EXIT.
  5029.  
  5030. % +  JSR KERNEL├LRCHN
  5031. %    LDA CBM─ATA╠EN
  5032. %    ORA CBM─ATA╠EN+1
  5033. %    CLC
  5034. %    RTS
  5035. %
  5036.  
  5037. ╥EAD A SINGLE BYTE FROM THE ├┬═-╦ERNAL INPUT LOGICAL FILE NUMBER.  ╘RANSLATE
  5038. CHARACTER INTO ┴╙├╔╔ AND EXPAND ├╥ INTO ├╥+╠╞ IF NECESSARY.  ╥ETURN ┼╧╞ IF
  5039. PREVIOUS CHARACTER RETURNED WAS LAST FROM DISK INPUT CHANNEL.
  5040.  
  5041. % COMMIE╔N┬YTE = *  ;( ) : .┴=CHAR, .├╙=ERR, .┌=EOF, REACHED┼OF
  5042. %    ;** CHECK FOR ALREADY PAST EOF
  5043. %    LDA REACHED┼OF
  5044. %    BEQ +
  5045. %    BRK
  5046. %    ;** CHECK FOR GENERATED LINEFEED
  5047. % +  LDA GENERATE╠F
  5048. %    BEQ +
  5049. %    LDA #0
  5050. %    STA GENERATE╠F
  5051. %    LDA #$0A
  5052. %    CLC
  5053. %    RTS
  5054. %    ;** CHECK FOR EOF
  5055. % +  LDA PREV╙T
  5056. %    AND #$40
  5057. %    BEQ +
  5058. %    LDA #$FF
  5059. %    STA REACHED┼OF
  5060. %    LDA #0
  5061. %    CLC
  5062. %    RTS
  5063. %    ;** READ ACTUAL CHARACTER
  5064. % +  JSR KERNEL├HRIN
  5065. %    LDX ST
  5066. %    STX PREV╙T
  5067. %    BCC +
  5068. %    STA ERRNO
  5069. %    JSR KERNEL├LRCHN
  5070. %    RTS
  5071. %    ;** TRANSLATE IF NECESSARY
  5072. % +  BIT TRANS═ODE
  5073. %    BPL +
  5074. %    TAX
  5075. %    LDA TRANS┬UF╘O┴SCII,X
  5076. %    BEQ COMMIE╔N┬YTE
  5077.  
  5078. ╬OTE HERE THAT THE TRANSLATED CHARACTER IS CHECKED TO SEE IF IT IS A CARRIAGE
  5079. RETURN, RATHER THAN CHECKING THE NON-TRANSLATED CHARACTER, TO SEE IF A
  5080. LINEFEED MUST BE GENERATED NEXT.  ╘HUS, YOU COULD DEFINE THAT A ├OMMODORE
  5081. CARRIAGE RETURN BE TRANSLATED INTO A LINEFEED (FOR ╒NIX) AND NO ADDITIONAL
  5082. UNWANTED LINEFEED WOULD BE GENERATED.
  5083.  
  5084. %    CMP #$0D
  5085. %    BNE +
  5086. %    STA GENERATE╠F
  5087. %    ;** EXIT
  5088. % +  LDX #$FF
  5089. %    CLC
  5090. %    RTS
  5091. %
  5092. % FIRST╞REE╞AT┼NTRY = $5A
  5093. %
  5094.  
  5095. ╙EARCH ╞┴╘ FOR A FREE CLUSTER, AND RETURN THE CLUSTER (╞┴╘ ENTRY) NUMBER.  ┴
  5096. GLOBAL VARIABLE "FIRST╞REE╞AR┼NTRY" IS MAINTAINED WHICH POINTS TO THE FIRST
  5097. ╞┴╘ ENTRY THAT COULD POSSIBLY BE FREE, TO AVOID WASTING TIME SEARCHING FROM
  5098. THE VERY BEGINNING OF THE ╞┴╘ EVERY TIME.  ├LUSTERS ARE ALLOCATED IN
  5099. FIRST-FREE ORDER.
  5100.  
  5101. % ALLOCATE╞AT┼NTRY = *  ;( ) : .┴┘=FAT┼NTRY, .├╙=ERR
  5102. % -  LDA FIRST╞REE╞AT┼NTRY
  5103. %    CMP LAST╞AT┼NTRY
  5104. %    LDA FIRST╞REE╞AT┼NTRY+1
  5105. %    SBC LAST╞AT┼NTRY+1
  5106. %    BCC +
  5107. %    RTS
  5108. % +  LDA FIRST╞REE╞AT┼NTRY
  5109. %    LDY FIRST╞REE╞AT┼NTRY+1
  5110. %    JSR GET╞AT┼NTRY
  5111. %    STY 2
  5112. %    ORA 2
  5113. %    BNE +
  5114. %    LDA FIRST╞REE╞AT┼NTRY
  5115. %    LDY FIRST╞REE╞AT┼NTRY+1
  5116. %    CLC
  5117. %    RTS
  5118. % +  INC FIRST╞REE╞AT┼NTRY
  5119. %    BNE -
  5120. %    INC FIRST╞REE╞AT┼NTRY+1
  5121. %    JMP -
  5122. %
  5123. % MS╞ILE╠ENGTH = $5C  ;(3 BYTES)
  5124. %
  5125.  
  5126. ┴LLOCATE A NEW CLUSTER TO A FILE, LINK IT INTO THE FILE CLUSTER CHAIN, AND
  5127. WRITE THE CLUSTER BUFFER TO DISK IN THAT CLUSTER, ADDING "CBM─ATA╠EN" BYTES
  5128. TO THE FILE.
  5129.  
  5130. % MS╫RITE├LUSTER = *  ; (*) : .├╙=ERR
  5131. %    ;** GET A NEW CLUSTER
  5132. %    JSR ALLOCATE╞AT┼NTRY
  5133. %    BCC +
  5134. %    RTS
  5135. %    ;** MAKE PREVIOUS FAT ENTRY POINT TO NEW CLUSTER
  5136. % +  STA FAT╓ALUE
  5137. %    STY FAT╓ALUE+1
  5138. %    LDA CLUSTER
  5139. %    ORA CLUSTER+1
  5140. %    BEQ +
  5141. %    LDA CLUSTER
  5142. %    LDY CLUSTER+1
  5143. %    LDX FAT╓ALUE
  5144. %    STX CLUSTER
  5145. %    LDX FAT╓ALUE+1
  5146. %    STX CLUSTER+1
  5147. %    JSR SET╞AT┼NTRY
  5148. %    JMP MS├LUSTER╬EW
  5149.  
  5150. ╚ANDLE CASE OF NO PREVIOUS CLUSTER - MAKE DIRECTORY ENTRY POINT TO NEW
  5151. CLUSTER.
  5152.  
  5153. % +  LDA WRITE─IRENT
  5154. %    LDY WRITE─IRENT+1
  5155. %    STA 2
  5156. %    STY 3
  5157. %    LDY #26
  5158. %    LDA FAT╓ALUE
  5159. %    STA (2),Y
  5160. %    STA CLUSTER
  5161. %    INY
  5162. %    LDA FAT╓ALUE+1
  5163. %    STA (2),Y
  5164. %    STA CLUSTER+1
  5165. %
  5166. %    ;** MAKE NEW FAT ENTRY POINT TO NULL
  5167. %    MS├LUSTER╬EW = *
  5168. %    LDA #$FF
  5169. %    LDY #$0F
  5170. %    STA FAT╓ALUE
  5171. %    STY FAT╓ALUE+1
  5172. %    LDA CLUSTER
  5173. %    LDY CLUSTER+1
  5174. %    JSR SET╞AT┼NTRY
  5175. %    ;** WRITE NEW CLUSTER DATA
  5176. % +  LDA CLUSTER
  5177. %    LDY CLUSTER+1
  5178. %    JSR WRITE├LUSTER
  5179. %    BCC +
  5180. %    RTS
  5181. %    ;** ADD CLUSTER LENGTH TO FILE LENGTH
  5182. % +  CLC
  5183. %    LDA MS╞ILE╠ENGTH
  5184. %    ADC CBM─ATA╠EN
  5185. %    STA MS╞ILE╠ENGTH
  5186. %    LDA MS╞ILE╠ENGTH+1
  5187. %    ADC CBM─ATA╠EN+1
  5188. %    STA MS╞ILE╠ENGTH+1
  5189. %    BCC +
  5190. %    INC MS╞ILE╠ENGTH+2
  5191. % +  CLC
  5192. %    RTS
  5193. %
  5194.  
  5195. ├OPY A ├┬═-╦ERNAL FILE TO AN ═╙-─╧╙ FILE, POSSIBLY WITH TRANSLATION.
  5196.  
  5197. % MS╫RITE = *  ;( MS─EVICE, MS╘YPE, WRITE─IRENT, .┴=TRANS, .╪=CBM╠FN ) :.├╙=ERR
  5198. %    LDY #$0E
  5199. %    STY $FF00
  5200. %    ;** INITIALIZE
  5201.  
  5202. ╙ET INPUT FILE TRANSLATION AND LOGICAL FILE NUMBER, INIT CLUSTER, FILE LENGTH,
  5203. ╞┴╘ ALLOCATION FIRST FREE POINTER (TO CLUSTER #2, THE FIRST DATA CLUSTER).
  5204.  
  5205. %    JSR COMMIE╔N╔NIT
  5206. %    LDA #0
  5207. %    STA CLUSTER
  5208. %    STA CLUSTER+1
  5209. %    STA FIRST╞REE╞AT┼NTRY+1
  5210. %    STA MS╞ILE╠ENGTH
  5211. %    STA MS╞ILE╠ENGTH+1
  5212. %    STA MS╞ILE╠ENGTH+2
  5213. %    LDA #2
  5214. %    STA FIRST╞REE╞AT┼NTRY
  5215. %
  5216. %    ;** COPY CLUSTER FROM CBM FILE
  5217. % -  LDA #<CLUSTER┬UF
  5218. %    LDY #>CLUSTER┬UF
  5219. %    STA CBM─ATA╨TR
  5220. %    STY CBM─ATA╨TR+1
  5221. %    LDA CLUSTER┬LOCK├OUNT
  5222. %    ASL
  5223. %    TAY
  5224. %    LDA #0
  5225. %    STA CBM─ATA═AX
  5226. %    STY CBM─ATA═AX+1
  5227. %    JSR COMMIE╔N
  5228. %    BCC +
  5229. %    RTS
  5230. % +  BEQ +
  5231. %    JSR MS╫RITE├LUSTER
  5232. %    BCC -
  5233. %    RTS
  5234. %
  5235. %    ;** WRAP UP AFTER WRITING - SET FILE LENGTH, DIRTY FLAG, EXIT.
  5236. % +  LDA WRITE─IRENT
  5237. %    LDY WRITE─IRENT+1
  5238. %    STA 2
  5239. %    STY 3
  5240. %    LDX #0
  5241. %    LDY #28
  5242. % -  LDA MS╞ILE╠ENGTH,X
  5243. %    STA (2),Y
  5244. %    INY
  5245. %    INX
  5246. %    CPX #3
  5247. %    BCC -
  5248. %    JSR DIRTY─IRENT
  5249. %    CLC
  5250. %    RTS
  5251. %
  5252.  
  5253. ╘HIS LEVEL DEALS EXCLUSIVELY WITH ├OMMODORE FILES.
  5254.  
  5255. % ;===== COMMODORE FILE LEVEL =====
  5256. %
  5257.  
  5258. ├OPY FROM AN INPUT DISK LOGICAL FILE NUMBER TO AN OUTPUT LFN, IN UP TO 1024
  5259. BYTE CHUNKS.  ╘HIS ROUTINE MAKES USE OF THE EXISTING "COMMIE╔N" AND
  5260. "COMMIE╧UT" ROUTINES.  ╬O FILE TRANSLATION IS AVAILABLE; BINARY TRANSLATION IS
  5261. USED FOR BOTH COMMIE╔N AND COMMIE╧UT.
  5262.  
  5263. % CBM├OPY = *  ;( .┴=IN╠FN, .╪=OUT╠FN )
  5264. %    LDY #$0E
  5265. %    STY $FF00
  5266. %    STX LFN
  5267. %    TAX
  5268. %    LDA #0
  5269. %    JSR COMMIE╔N╔NIT
  5270. % -  LDA #<CLUSTER┬UF
  5271. %    LDY #>CLUSTER┬UF
  5272. %    STA CBM─ATA╨TR
  5273. %    STY CBM─ATA╨TR+1
  5274. %    LDA #<1024
  5275. %    LDY #>1024
  5276. %    STA CBM─ATA═AX
  5277. %    STY CBM─ATA═AX+1
  5278. %    JSR COMMIE╔N
  5279. %    BCS +
  5280. %    BEQ +
  5281. %    LDA #<CLUSTER┬UF
  5282. %    LDY #>CLUSTER┬UF
  5283. %    STA CBM─ATA╨TR
  5284. %    STY CBM─ATA╨TR+1
  5285. %    JSR COMMIE╧UT
  5286. %    BCS +
  5287. %    JMP -
  5288. % +  RTS
  5289. %
  5290.  
  5291. ╥EAD A SINGLE DIRECTORY ENTRY FROM THE GIVEN LOGICAL FILE NUMBER, WHICH IS
  5292. ASSUMED TO BE OPEN FOR READING A DIRECTORY ("$").  ╘HE DATA OF THE DIRECTORY
  5293. ENTRY ARE RETURNED IN THE INTERFACE VARIABLES.
  5294.  
  5295. % CBM─IRENT = *  ;( .┴=LFN )
  5296.  
  5297. ╔NITIALIZE.
  5298.  
  5299. %    LDY #$0E
  5300. %    STY $FF00
  5301. %    TAX
  5302. %    JSR KERNEL├HKIN
  5303. %    BCC +
  5304. %    CDIR┼RR = *
  5305. %    LDA #0
  5306. %    STA CDIR╞LEN
  5307. %    STA CDIR┬LOCKS
  5308. %    STA CDIR┬LOCKS+1
  5309. %    RTS
  5310. %    ;** GET BLOCK COUNT
  5311. % +  JSR CDIR╟ETCH
  5312. %    JSR CDIR╟ETCH
  5313. %    JSR CDIR╟ETCH
  5314. %    STA CDIR┬LOCKS
  5315. %    JSR CDIR╟ETCH
  5316. %    STA CDIR┬LOCKS+1
  5317. %    ;** LOOK FOR FILENAME
  5318. %    LDA #0
  5319. %    STA CDIR╞LEN
  5320. % -  JSR CDIR╟ETCH
  5321. %    CMP #34
  5322. %    BEQ +
  5323. %    CMP #"B"
  5324. %    BNE -
  5325. %    JSR KERNEL├LRCHN
  5326. %    RTS
  5327. %    ;** GET FILENAME
  5328. % +  LDY #0
  5329. % -  JSR CDIR╟ETCH
  5330. %    CMP #34
  5331. %    BEQ +
  5332. %    STA CDIR╬AME,Y
  5333. %    INY
  5334. %    BNE -
  5335. % +  STY CDIR╞LEN
  5336.  
  5337. ╠OOK FOR AND GET FILE TYPE.
  5338.  
  5339. % -  JSR CDIR╟ETCH
  5340. %    CMP #" "
  5341. %    BEQ -
  5342. %    STA CDIR╘YPE
  5343.  
  5344. ╙CAN FOR END OF DIRECTORY ENTRY, RETURN.
  5345.  
  5346. % -  JSR CDIR╟ETCH
  5347. %    CMP #0
  5348. %    BNE -
  5349. %    JSR KERNEL├LRCHN
  5350. %    RTS
  5351. %
  5352.  
  5353. ╟ET A SINGLE CHARACTER OF THE DIRECTORY ENTRY, WATCHING FOR END OF FILE (WHICH
  5354. WOULD INDICATE ERROR HERE).
  5355.  
  5356. % CDIR╟ETCH = *
  5357. %    JSR KERNEL├HRIN
  5358. %    BCS +
  5359. %    BIT ST
  5360. %    BVS +
  5361. %    RTS
  5362. % +  PLA
  5363. %    PLA
  5364. %    JSR KERNEL├LRCHN
  5365. %    JMP CDIR┼RR
  5366. %
  5367. % ;===== DATA =====
  5368. %
  5369.  
  5370. ╘HIS IS THE TRANSLATION TABLE USED TO CONVERT FROM ┴╙├╔╔ TO ╨┼╘╙├╔╔.  ┘OU CAN
  5371. MODIFY IT TO SUIT YOUR NEEDS IF YOU WISH.  ╔F YOU CANNOT REASSEMBLE THIS FILE,
  5372. THEN YOU CAN SIFT THROUGH THE BINARY FILE AND LOCATE THE TABLE AND CHANGE IT
  5373. THERE.  ┴N ENTRY OF $00 MEANS THE CORRESPONDING ┴╙├╔╔ CHARACTER WILL NOT BE
  5374. TRANSLATED.  ┘OU'LL NOTICE THAT ╔ HAVE SET UP TRANSLATIONS FOR THE FOLLOWING
  5375. ┴╙├╔╔ CONTROL CHARACTERS INTO ╨┼╘╙├╔╔: ┬ACKSPACE, ╘AB, ╠INEFEED (├╥), AND
  5376. ╞ORMFEED.  ╔ ALSO TRANSLATE THE NON-╨┼╘╙├╔╔ CHARACTERS SUCH AS {, |, ~, AND _
  5377. ACCORDING TO WHAT THEY PROBABLY WOULD HAVE BEEN IF ├OMMODORE WASN'T SO
  5378. CONCERNED WITH THE GRAPHICS CHARACTERS.
  5379.  
  5380. % TRANS┬UF = *
  5381. %        ;0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  5382. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$14,$09,$0D,$00,$93,$00,$00,$00 ;0
  5383. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;1
  5384. % .BYTE $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F ;2
  5385. % .BYTE $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F ;3
  5386. % .BYTE $40,$C1,$C2,$C3,$C4,$C5,$C6,$C7,$C8,$C9,$CA,$CB,$CC,$CD,$CE,$CF ;4
  5387. % .BYTE $D0,$D1,$D2,$D3,$D4,$D5,$D6,$D7,$D8,$D9,$DA,$5B,$5C,$5D,$5E,$5F ;5
  5388. % .BYTE $C0,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4A,$4B,$4C,$4D,$4E,$4F ;6
  5389. % .BYTE $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5A,$DB,$DC,$DD,$DE,$DF ;7
  5390. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;8
  5391. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;9
  5392. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;A
  5393. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;B
  5394. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;C
  5395. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;D
  5396. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;E
  5397. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;F
  5398. %
  5399.  
  5400. ╘HIS IS THE TRANSLATION TABLE USED TO CONVERT FROM ╨┼╘╙├╔╔ TO ┴╙├╔╔.  ┘OU CAN
  5401. MODIFY IT TO SUIT YOUR NEEDS, SIMILAR TO THE ┴╙├╔╔ TO ╨┼╘╙├╔╔ TABLE.  ┴N ENTRY
  5402. OF $00 MEANS THE CORRESPONDING ╨┼╘╙├╔╔ CHARACTER WILL NOT BE TRANSLATED.
  5403. ┘OU'LL NOTICE THAT ╔ HAVE SET UP TRANSLATIONS FOR THE FOLLOWING ╨┼╘╙├╔╔
  5404. CONTROL CHARACTERS INTO ┴╙├╔╔: ─ELETE (INTO ┬ACKSPACE), ╘AB, ├ARRIAGE ╥ETURN
  5405. (INTO ├╥+╠╞), AND ├LEAR╙CREEN (INTO ╞ORDFEED).  ┴PPROPRIATE TRANSLATIONS INTO
  5406. THE ┴╙├╔╔ CHARACTERS {, }, ^, _, ~, \, AND | ARE ALSO SET UP.
  5407.  
  5408. % TRANS┬UF╘O┴SCII = *
  5409. %        ;0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  5410. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$09,$00,$00,$00,$0D,$00,$00 ;0
  5411. % .BYTE $00,$00,$00,$00,$08,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;1
  5412. % .BYTE $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F ;2
  5413. % .BYTE $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F ;3
  5414. % .BYTE $40,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6A,$6B,$6C,$6D,$6E,$6F ;4
  5415. % .BYTE $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7A,$5B,$5C,$5D,$5E,$5F ;5
  5416. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;6
  5417. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;7
  5418. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;8
  5419. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;9
  5420. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;A
  5421. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;B
  5422. % .BYTE $60,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4A,$4B,$4C,$4D,$4E,$4F ;C
  5423. % .BYTE $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5A,$7B,$7C,$7D,$7E,$7F ;D
  5424. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;E
  5425. % .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7E ;F
  5426. %
  5427. % ;====BSS STORAGE (SIZE=11,264 BYTES)====
  5428. %
  5429.  
  5430. ╘HIS IS WHERE THE TRACK CACHE, ETC. ARE STORED.  ╘HIS SECTION REQUIRES 11╦ OF
  5431. STORAGE SPACE BUT DOES NOT INCREASE THE LENGTH OF THE BINARY PROGRAM FILE
  5432. SINCE THESE STORAGE AREAS ARE ─┼╞╔╬┼─ RATHER THAN ALLOCATED WITH ".BUF"
  5433. DIRECTIVES.  ╘HE ╒NIX TERMINOLOGY FOR THIS TYPE OF UNINITIALIZED DATA IS
  5434. "BSS".
  5435.  
  5436. % BSS = *
  5437. % TRACKBUF   = BSS
  5438. % CLUSTER┬UF = TRACKBUF+4608
  5439. % FATBUF     = CLUSTER┬UF+1024
  5440. % DIRBUF     = FATBUF+1536
  5441. % END        = DIRBUF+4096
  5442.  
  5443. 5. ╒╙┼╥-╔╬╘┼╥╞┴├┼ ╨╥╧╟╥┴═
  5444.  
  5445. ╘HIS SECTION PRESENTS THE LISTING OF THE USER-INTERFACE ┬┴╙╔├ PROGRAM.  ┘OU
  5446. SHOULD BE AWARE THAT YOU CAN EASILY CHANGE SOME OF THE DEFAULTS TO YOUR OWN
  5447. PREFERENCES IF YOU WISH.  ╔N PARTICULAR, YOU MAY WISH TO CHANGE THE "DV" AND
  5448. "DT" VARIABLES IN LINES 25 AND 26.  ╘HIS PROGRAM IS NOT LISTED IN THE "%"
  5449. FORMAT THAT THE ASSEMBLER LISTING IS SINCE YOU CAN RECOVER THIS LISTING FROM
  5450. THE UUENCODED BINARY PROGRAM FILE.  ╘HE LISTING IS HERE IN ITS ENTIRETY.
  5451.  
  5452. 10 PRINT CHR$(147);"LITTLE RED READER 128 VERSION 1.00"
  5453. 11 PRINT : PRINT"BY CRAIG BRUCE 09-FEB-93 FOR C=HACKING" : PRINT
  5454. 12 :
  5455. 20 CD=PEEK(186):IF CD<8 THEN CD=8 : REM ** DEFAULT CBM-DOS DRIVE **
  5456. 25 DV=9:DT=0 :  REM ** MS-DOS DRIVE, TYPE (0=1571,255=1581)
  5457. 26 IF DV=CD THEN DV=8:DT=0 : REM ** ALTERNATE MS-DOS DRIVE
  5458. 27 :
  5459. 30 PRINT "INITIALIZING..." : PRINT
  5460. 40 BANK0 : PK=DEC("8000") : PV=PK+30
  5461. 50 IF PEEK(PV+0)=DEC("CB") AND PEEK(PV+1)=132 THEN 60
  5462. 55 PRINT"LOADING MACHINE LANGUAGE ROUTINES..." : BLOAD"LRR.BIN",U(CD)
  5463. 60 POKE PV+3,DV : POKE PV+4,DT : SYS PK
  5464. 70 DIM T,R,B,I,A$,C,DT$,FL$,IL$,X,X$
  5465. 71 CM$="DMFTC+-Q "+CHR$(13)+CHR$(145)+CHR$(17)+CHR$(157)+CHR$(29)+CHR$(19)
  5466. 72 CM$=CM$+CHR$(147)+"/RNX"+CHR$(92)
  5467. 75 DL=-1 : CF=-1 : ME=0 : CA=0 : MA=0
  5468. 80 DIM DI$(1,300),CL(128),SZ(128),DP(128),CN$(300)
  5469. 90 IF DT=255 THEN DT$="1581" :ELSE DT$="1571"
  5470. 100 FL$=CHR$(19)+CHR$(17)+CHR$(17)+CHR$(17)+CHR$(17)
  5471. 110 IL$=FL$:FORI=1TO19:IL$=IL$+CHR$(17):NEXT
  5472. 120 GOTO 500
  5473. 130 :
  5474. 131 REM ** LOAD MS-DOS DIRECTORY **
  5475. 140 PRINT"LOADING MS-DOS DIRECTORY..." : PRINT
  5476. 150 SYS PK : SYS PK+3
  5477. 160 DL=0
  5478. 170 RREG BL,DC,BH,S : E=PEEK(PV+2)
  5479. 180 IF (S AND 1) THEN GOSUB 380 : DL=-1 : RETURN
  5480. 190 PRINT"SCANNING MS-DOS DIRECTORY..." : PRINT
  5481. 200 DB=BL+256*BH
  5482. 205 SYS PK+21 : RREG BL,X,BH : MA=BL+BH*256+X*65536
  5483. 210 IF DC=0 THEN 360
  5484. 220 FOR DP=DB TO DB+32*(DC-1) STEP 32
  5485. 230 IF PEEK(DP)=0 OR PEEK(DP)=229 THEN 350
  5486. 240 IF PEEK(DP+11) AND 24 THEN 350
  5487. 250 DL=DL+1
  5488.  
  5489. ╠INE 260 SETS THE DEFAULT SELECTION, TRANSLATION, AND FILETYPES FOR ═╙-─╧╙
  5490. FILES.  ├HANGE TO YOUR LIKING.
  5491.  
  5492. 260 D$=RIGHT$(" "+STR$(DL),3)+"     ASC  SEQ  " : REM ** DEFAULT SEL/TR/FT **
  5493. 270 A$="" : FORI=0TO10 : A$=A$+CHR$(PEEK(DP+I)) : NEXT
  5494. 280 A$=LEFT$(A$,8)+"  "+RIGHT$(A$,3)
  5495. 290 PRINT DL; A$
  5496. 300 D$=D$+A$+"  "
  5497. 310 CL(DL)=PEEK(DP+26)+256*PEEK(DP+27)
  5498. 320 SZ=PEEK(DP+28)+256*PEEK(DP+29)+65536*PEEK(DP+30)
  5499. 330 DI$(0,DL)=D$+RIGHT$("    "+STR$(SZ),6)
  5500. 335 DP(DL)=DP
  5501. 340 SZ(DL)=SZ
  5502. 350 NEXT DP
  5503. 360 RETURN
  5504. 370 :
  5505. 371 REM ** REPORT MS-DOS DISK ERROR **
  5506. 380 PRINT CHR$(18);"MS-DOS DISK ERROR #";MID$(STR$(E),2);
  5507. 390 PRINT " ($";MID$(HEX$(E),3);"), PRESS KEY.";CHR$(146)
  5508. 400 GETKEY A$ : RETURN
  5509. 410 :
  5510. 411 REM ** SCREEN HEADING **
  5511. 420 PRINT CHR$(147);CHR$(18);
  5512. 421 IF ME=0 THEN PRINT"MS-DOS";:X=MA:ELSE PRINT"CBMDOS";:X=CA
  5513. 422 PRINT CHR$(146);"  MS=";MID$(STR$(DV),2);":";DT$;
  5514. 430 PRINT"  CBM=";MID$(STR$(CD),2);"  FREE=";MID$(STR$(X),2)
  5515. 440 PRINT : RETURN
  5516. 450 :
  5517. 451 REM ** SCREEN FOOTING **
  5518. 460 PRINT IL$;"D=DIR M=MSDEV F=CBMDEV C=COPY Q=QUIT   "
  5519. 470 PRINT     "T=TOGGLE R=REMOVE X=CBMCPY /=MENU +-=PG";
  5520. 480 RETURN
  5521. 490 :
  5522. 491 REM ** MAIN ROUTINE **
  5523. 500 T=1 : C=0
  5524. 501 R=0
  5525. 510 IF ME=0 THEN MF=DL:MC=2 : ELSE MF=CF:MC=1
  5526. 520 GOSUB 420
  5527. 521 IF ME<>0 THEN 542
  5528. 530 PRINT "NUM  S  TRN  TYP  FILENAME  EXT  LENGTH"
  5529. 540 PRINT "---  -  ---  ---  --------  ---  ------"
  5530. 541 GOTO 550
  5531. 542 PRINT "NUM  S  TRN  FILENAME         T  LENGTH"
  5532. 543 PRINT "---  -  ---  ---------------- -  ------"
  5533. 550 GOSUB 460
  5534. 560 B=T+17 : IF B>MF THEN B=MF
  5535. 570 PRINT FL$;: IF T>MF THEN 590
  5536. 580 FOR I=T TO B : PRINT DI$(ME,I) : NEXT
  5537. 590 IF MF<0 THEN PRINT CHR$(18);"<DIRECTORY NOT LOADED>";CHR$(146)
  5538. 591 IF MF=0 THEN PRINT CHR$(18);"<NO FILES>";CHR$(146)
  5539. 600 IF MF<=0 THEN 660
  5540. 610 PRINT LEFT$(IL$,R+5);CHR$(18);
  5541. 620 ON C+1 GOTO 630,640,650
  5542. 630 PRINT SPC(4);MID$(DI$(ME,T+R),5,3) : GOTO 660
  5543. 640 PRINT SPC(7);MID$(DI$(ME,T+R),8,5) : GOTO 660
  5544. 650 PRINT SPC(12);MID$(DI$(ME,T+R),13,5) : GOTO 660
  5545. 660 GETKEY A$
  5546. 670 I=INSTR(CM$,A$)
  5547. 680 IF MF>0 THEN PRINT LEFT$(IL$,R+5);DI$(ME,T+R)
  5548. 690 IF I=0 THEN 600
  5549. 700 ON I GOTO 760,1050,1110,950,1150,1000,1020,730,860,860,770,790,810,830,850
  5550. 705 ON I-15 GOTO 500,713,1400,713,1500,713
  5551. 710 STOP
  5552. 711 :
  5553. 712 REM ** VARIOUS MENU OPTIONS **
  5554. 713 ME=-(ME=0)
  5555. 714 GOTO500
  5556. 730 PRINT CHR$(147);"HAVE AN AWESOME DAY." : BANK15
  5557. 740 END
  5558. 760 IF ME=1 THEN GOSUB 420 : GOSUB 2500 : GOTO 500
  5559. 765 GOSUB 420 : GOSUB 140 : GOTO 500
  5560. 770 R=R-1 : IF R<0 THEN R=B-T
  5561. 780 GOTO 600
  5562. 790 R=R+1 : IF T+R>B THEN R=0
  5563. 800 GOTO 600
  5564. 810 C=C-1 : IF C<0 THEN C=MC
  5565. 820 GOTO 600
  5566. 830 C=C+1 : IF C>MC THEN C=0
  5567. 840 GOTO 600
  5568. 850 R=0 : C=0 : GOTO 600
  5569. 860 IF MF<=0 THEN 600
  5570. 870 X=T+R : ON C+1 GOSUB 890,910,930
  5571. 880 PRINT LEFT$(IL$,R+5);DI$(ME,X) : GOTO 600
  5572. 890 IF MID$(DI$(ME,X),6,1)=" " THEN X$="*" :ELSE X$=" "
  5573. 900 MID$(DI$(ME,X),6,1)=X$ : RETURN
  5574. 910 IF MID$(DI$(ME,X),9,1)="A" THEN X$="BIN" :ELSE X$="ASC"
  5575. 920 MID$(DI$(ME,X),9,3)=X$ : RETURN
  5576. 930 IF MID$(DI$(ME,X),14,1)="S" THEN X$="PRG" :ELSE X$="SEQ"
  5577. 940 MID$(DI$(ME,X),14,3)=X$ : RETURN
  5578. 950 IF MF<=0 THEN 600
  5579. 960 FOR X=1 TO MF
  5580. 970 ON C+1 GOSUB 890,910,930
  5581. 980 NEXT X
  5582. 990 GOTO 520
  5583. 1000 R=0:IF B=MF THEN T=1 : GOTO 510
  5584. 1010 T=T+18 : GOTO 510
  5585. 1020 IF MF<=0 THEN 660
  5586. 1025 R=0:IF T=1 THEN T=MF-(MF-INT(MF/18)*18)+1 : IF T<=MF THEN 510
  5587. 1030 T=T-18 : IF T<1 THEN T=1
  5588. 1040 GOTO 510
  5589. 1050 PRINT IL$;CHR$(27);"@";
  5590. 1060 INPUT"MS-DOS DEVICE NUMBER (8-30)";DV
  5591. 1061 IF CD=DV THENPRINT"MS-DOS AND CBM-DOS DEVICES MUST BE DIFFERENT!":GOTO1060
  5592. 1070 X=71 : INPUT"MS-DOS DEVICE TYPE  (71/81)";X
  5593. 1080 IF X=8 OR X=81 OR X=1581 THEN DT=255:DT$="1581" :ELSE DT=0:DT$="1571"
  5594. 1090 POKE PV+3,DV : POKE PV+4,DT : SYS PK : DL=-1 : MA=0
  5595. 1100 GOTO 500
  5596. 1110 PRINT IL$;CHR$(27);"@";
  5597. 1120 INPUT "CBM-DOS DEVICE NUMBER (0-30)";CD
  5598. 1130 IF CD=DV THENPRINT"MS-DOS AND CBM-DOS DEVICES MUST BE DIFFERENT!":GOTO1120
  5599. 1140 CF=-1 : CA=0 : GOTO 500
  5600. 1141 :
  5601. 1142 REM ** COPY FILES **
  5602. 1150 IF ME=1 THEN 2000
  5603. 1151 PRINT CHR$(147);"COPY MS-DOS -> CBM-DOS":PRINT:PRINT
  5604. 1160 IF DL<=0 THEN FC=0 : GOTO 1190
  5605. 1170 FC=0 : FOR F=1 TO DL : IF MID$(DI$(0,F),6,1)="*" THEN GOSUB 1200
  5606. 1180 NEXT F
  5607. 1190 PRINT : PRINT"FILES COPIED =";FC;" - PRESS KEY"
  5608. 1191 GETKEY A$ : GOTO 520
  5609. 1200 FC=FC+1
  5610. 1210 X$=MID$(DI$(0,F),19,8)+"."+MID$(DI$(0,F),29,3)
  5611. 1220 CF$="":FORI=1TOLEN(X$):IF MID$(X$,I,1)<>" " THEN CF$=CF$+MID$(X$,I,1)
  5612. 1230 NEXT
  5613. 1231 IF RIGHT$(CF$,1)="." THEN CF$=LEFT$(CF$,LEN(CF$)-1)
  5614. 1232 CF$=CF$+","+MID$(DI$(0,F),14,1)
  5615. 1240 PRINT STR$(FC);". ";CHR$(34);CF$;CHR$(34);TAB(20);SZ(F)"BYTES";
  5616. 1245 PRINT TAB(35);MID$(DI$(0,F),9,3)
  5617. 1250 CL=CL(F) : LB=SZ(F) - INT(SZ(F)/65536)*65536
  5618. 1260 IF CD>=8 THEN DOPEN#1,(CF$+",W"),U(CD) :ELSE IF CD<>0 THEN OPEN 1,CD,7
  5619. 1265 IF CD<8 THEN 1288
  5620. 1270 IF DS<>63 THEN 1288
  5621. 1275 X$="Y" : PRINT "CBM FILE EXISTS; OVERWRITE (Y/N)";
  5622. 1280 CLOSE 1 : INPUT X$ : IF X$="N" THEN FC=FC-1 : RETURN
  5623. 1285 SCRATCH(CF$),U(CD)
  5624. 1286 DOPEN#1,(CF$+",W"),U(CD)
  5625. 1288 IF CD<8 THEN 1320
  5626. 1300 IF DS<20 THEN 1320
  5627. 1310 PRINT CHR$(18)+"CBM DISK ERROR: "+DS$ : FC=FC-1 : CLOSE1 : RETURN
  5628. 1320 POKE PV+6,CL/256 : POKE PV+5,CL-PEEK(PV+6)*256
  5629. 1330 POKE PV+8,LB/256 : POKE PV+7,LB-PEEK(PV+8)*256
  5630. 1340 TR=0 : IF MID$(DI$(0,F),9,1)="A" THEN TR=255
  5631. 1346 X=1 : IF CD=0 THEN X=0
  5632. 1350 SYS PK+6,TR,X
  5633. 1355 RREG X,X,X,S : E=PEEK(PV+2)
  5634. 1356 IF (S AND 1) THEN GOSUB 380 : FC=FC-1
  5635. 1360 IF CD<>0 AND CD<8 THEN CLOSE1
  5636. 1370 IF CD>=8 THEN DCLOSE#1 : IF DS>=20 THEN 1310
  5637. 1380 RETURN
  5638. 1398 :
  5639. 1399 REM ** REMOVE MS-DOS FILE **
  5640. 1400 PRINT CHR$(147);"REMOVE (DELETE) SELECTED MS-DOS FILES:":PRINT
  5641. 1401 IF ME<>0 THEN PRINT"MS-DOS MENU MUST BE SELECTED!" : GOTO2030
  5642. 1402 A$="Y":INPUT"ARE YOU LIKE SURE ABOUT THIS (Y/N)";A$
  5643. 1403 PRINT:IF A$="N" THEN GOTO 520
  5644. 1410 IF DL<=0 THEN FC=0 : GOTO 1440
  5645. 1420 FC=0 : F=1
  5646. 1425 IF MID$(DI$(0,F),6,1)="*" THEN GOSUB 1470 : FC=FC+1 : F=F-1
  5647. 1430 F=F+1 : IF F<=DL THEN 1425
  5648. 1434 PRINT"FLUSHING..."
  5649. 1435 SYS PK+12
  5650. 1440 PRINT : PRINT"FILES REMOVED =";FC;" - PRESS KEY"
  5651. 1445 SYS PK+21 : RREG A,X,Y : MA=A+Y*256+X*65536
  5652. 1450 GETKEY A$ : GOTO 500
  5653. 1470 PRINT"REMOVING ";CHR$(34);MID$(DI$(0,F),19,13);CHR$(34)
  5654. 1490 POKE PV+10,DP(F)/256 : POKE PV+9,DP(F)-PEEK(PV+10)*256
  5655. 1492 SYS PK+15
  5656. 1494 DI$(0,F)=DI$(0,DL):SZ(F)=SZ(DL):DP(F)=DP(DL):CL(F)=CL(DL)
  5657. 1495 DL=DL-1
  5658. 1496 RETURN
  5659. 1498 :
  5660. 1499 REM ** COPY CBM FILES **
  5661. 1500 PRINT CHR$(147);"COPY CBM-DOS TO CBM-DOS:":PRINT
  5662. 1501 IF CF<=0 THEN PRINT"COMMODORE DIRECTORY NOT LOADED" : GOTO 2030
  5663. 1502 X=0 : INPUT"DEVICE NUMBER TO COPY TO";X : PRINT
  5664. 1503 IF X<=0 OR X>=64 THEN PRINT"BAD DEVICE NUMBER!" : GOTO 2030
  5665. 1504 IF X=CD THEN PRINT"CANNOT COPY TO SAME DEVICE" : GOTO 2030
  5666. 1505 FOR F=1 TO CF : IF MID$(DI$(1,F),6,1)<>"*" THEN 1570
  5667. 1506 PRINT DI$(1,F) : OPEN1,CD,2,CN$(F)+",R"
  5668. 1507 IF X<8 THEN OPEN 2,X,7 : GOTO1550
  5669. 1508 CF$=CN$(F)+","+MID$(DI$(1,F),31,1)+",W"
  5670. 1509 OPEN2,X,3,CF$
  5671. 1510 IF DS<>63 THEN 1530
  5672. 1511 CLOSE2
  5673. 1512 X$="Y":INPUT"FILE EXISTS: OVERWRITE (Y/N)";X$ : IF X$="N" THEN 1560
  5674. 1520 SCRATCH(CN$(F)),U(X)
  5675. 1525 OPEN2,X,3,CF$
  5676. 1530 IF DS>20 THEN PRINT CHR$(18);"CBM DOS ERROR: ";DS$ : GOTO1560
  5677. 1550 SYS PK+24,1,2
  5678. 1560 CLOSE1 : CLOSE2
  5679. 1570 NEXT F
  5680. 1580 PRINT : PRINT"FINISHED - PRESS A KEY" : GETKEY A$ : GOTO510
  5681. 1998 :
  5682. 1999 REM ** COPY CBM-DOS TO MS-DOS **
  5683. 2000 PRINT CHR$(147);"COPY CBM-DOS TO MS-DOS:" : PRINT : PRINT
  5684. 2010 IF DL>=0 THEN 2035
  5685. 2020 PRINT"MS-DOS DIRECTORY MUST BE LOADED FIRST"
  5686. 2030 PRINT : PRINT"PRESS ANY KEY" : GETKEY A$ : GOTO 510
  5687. 2035 FC=0
  5688. 2036 FOR F=1 TO CF : IF MID$(DI$(1,F),6,1)<>"*" THEN 2045
  5689. 2040 FC=FC+1 : C$=CN$(F)
  5690. 2041 PRINTMID$(STR$(FC),2);" ";MID$(DI$(1,F),14,16);MID$(DI$(1,F),34);":";
  5691. 2042 GOSUB2050 : PRINT LEFT$(M$,8);".";RIGHT$(M$,3)
  5692. 2043 TR=0 : IF MID$(DI$(1,F),9,1)="A" THEN TR=255
  5693. 2044 GOSUB2100
  5694. 2045 NEXT
  5695. 2046 PRINT"FLUSHING..." : SYS PK+12
  5696. 2047 SYS PK+21 : RREG A,X,Y : MA=A+Y*256+X*65536
  5697. 2048 PRINT: PRINT"FILES COPIED =";FC : GOTO2030
  5698. 2049 :
  5699. 2050 X=INSTR(C$,".") : IF X=0 THEN M$=C$+"           " : GOTO2090
  5700. 2055 X=LEN(C$)+1 : DO : X=X-1 : LOOP UNTIL MID$(C$,X,1)="."
  5701. 2060 M$=LEFT$(LEFT$(C$,X-1)+"        ",8)
  5702. 2070 X$=MID$(C$,X+1)+"   "
  5703. 2080 M$=M$+X$
  5704. 2090 M$=LEFT$(M$,11)
  5705. 2091 FORI=1TO11:X$=CHR$(ASC(MID$(M$,I,1))AND127):IF X$="."ORX$=" " THEN X$="_"
  5706. 2092 MID$(M$,I,1)=X$ : NEXT I
  5707. 2093 I=8 : DO WHILE I>1 AND MID$(M$,I,1)="_" : MID$(M$,I,1)=" " : I=I-1 : LOOP
  5708. 2094 I=11 : DO WHILE I>8 AND MID$(M$,I,1)="_" : MID$(M$,I,1)=" " : I=I-1 : LOOP
  5709. 2098 RETURN
  5710. 2099 :
  5711. 2100 FORI=0TO0
  5712. 2105 FOR DP=DB TO DB+32*(DC-1) STEP 32
  5713. 2110 IF PEEK(DP)=0 OR PEEK(DP)=229 THEN 2140
  5714. 2120 NEXT DP
  5715. 2130 PRINT"NO FREE MS-DOS DIRECTORY ENTIRES" : RETURN
  5716. 2140 NEXT I
  5717. 2160 FORI=1TOLEN(M$):POKEDP+I-1,ASC(MID$(M$,I,1)) AND 127:NEXT
  5718. 2170 FORI=11TO31:POKE DP+I,0:NEXT
  5719. 2180 POKEDP+26,255:POKEDP+27,15
  5720. 2190 POKE PV+10,DP/256:POKE PV+9,DP-PEEK(PV+10)*256
  5721. 2200 OPEN1,CD,2,C$
  5722. 2300 SYS PK+9,TR,1 : RREG X,X,X,S
  5723. 2301 CLOSE1
  5724. 2305 IF S AND 1 THEN E=PEEK(PV+2) : GOSUB380 : RETURN
  5725.  
  5726. ╠INE 2310 SETS THE DEFAULT ═╙-─╧╙ SELECTION, TRANSLATION, AND FILETYPE AFTER
  5727. COPYING TO ═╙-─╧╙ DISK, BASED ON THE ├┬═-─╧╙ FILETYPE.  ├HANGE TO YOUR LIKING.
  5728.  
  5729. 2310 X$="     ASC  SEQ  ":IF TR=0 THEN X$="     BIN  PRG  "
  5730. 2320 DL=DL+1 : D$=RIGHT$(" "+STR$(DL),3)+X$
  5731. 2330 D$=D$+LEFT$(M$,8)+"  "+RIGHT$(M$,3)
  5732. 2340 CL(DL)=PEEK(DP+26)+256*PEEK(DP+27)
  5733. 2350 SZ=PEEK(DP+28)+256*PEEK(DP+29)+65536*PEEK(DP+30)
  5734. 2360 DI$(0,DL)=D$+RIGHT$("        "+STR$(SZ),8)
  5735. 2370 DP(DL)=DP
  5736. 2380 SZ(DL)=SZ
  5737. 2395 RETURN
  5738. 2498 :
  5739. 2499 REM ** LOAD COMMODORE DOS DIRECTORY **
  5740. 2500 PRINT"LOADING COMMODORE DOS DIRECTORY..." : PRINT
  5741. 2501 IF CD<8 THEN PRINT"CBMDOS DEVICE MUST BE >= 8!" : GOTO2030
  5742. 2505 OPEN1,CD,0,"$0":GET#1,A$,A$ : CF=-1 : Q$=CHR$(34)
  5743. 2506 DO
  5744. 2507 SYS PK+27,1 : B=PEEK(PV+11)+256*PEEK(PV+12) : T$=CHR$(PEEK(PV+13))
  5745. 2510 X=PEEK(PV+14)
  5746. 2520 IF X=0 THEN EXIT
  5747. 2530 X$="" : FOR I=PV+15 TO PV+15+X-1 : X$=X$+CHR$(PEEK(I)) : NEXT
  5748. 2575 CF=CF+1
  5749. 2590 IF CF=0 THEN PRINT"DISK="Q$X$Q$ : PRINT : GOTO2650
  5750. 2600 CN$(CF)=X$
  5751. 2610 A$=LEFT$(X$+"                 ",17)+T$+RIGHT$("       "+STR$(B*254),8)
  5752.  
  5753. ╠INES 2620 AND 2625 SET THE DEFAULT ├┬═-─╧╙ SELECTION AND TRANSLATION MODES
  5754. BASED ON THE FILETYPE.  ├HANGE TO YOUR LIKING.
  5755.  
  5756. 2620 DI$(1,CF)=RIGHT$("  "+STR$(CF),3)+"     ASC  "+A$
  5757. 2625 IF T$<>"S" THEN MID$(DI$(1,CF),9,3)="BIN"
  5758. 2630 PRINT DI$(1,CF)
  5759. 2650 LOOP
  5760. 2670 CA=B*256 : CLOSE1 : RETURN
  5761.  
  5762. 6. ╒╒┼╬├╧─┼─ ╞╔╠┼╙
  5763.  
  5764. ╚ERE ARE THE BINARY EXECUTABLES IN UUENCODED FORM.  ╘HE ├╥├32S OF THE TWO
  5765. FILES ARE AS FOLLOWS:
  5766.  
  5767. CRC32 = 3896271974 FOR "LRR-128"
  5768. CRC32 = 2918283051 FOR "LRR.BIN"
  5769.  
  5770. ╘HE "LRR.128" FILE IS THE MAIN ┬┴╙╔├ PROGRAM AND THE "LRR.BIN" FILE CONTAINS
  5771. THE MACHINE LANUGAGE DISK-ACCESSING ROUTINES.
  5772.  
  5773. BEGIN 640 LRR-128
  5774. ═`1╨╙'`╚`╞2#'*#$╘-╥─[(─╤)5%1,12!2140@4─5!1$52(#$╥."!615)324].
  5775. ═(#$╬,#`┬`&─<"╨"9(#╚@╞2)"62!#4─%)1╥!"4┼5#12`╨.2╒&14(═.3,@1─]2
  5776. ═($,]2$%#2╘┼.1╥(@.┬"9`&\<#``┌`*╠<%`!#1++"*#$╪-┬─┌┬╥!#1+,╪(*<@
  5777. ═0╘2╥."`┌((\@*┬╚@1$5&055,5"!#0─╘═1$]3($12259%("╚╩`.8<&0!$5╦(┘
  5778. ═.─14╠├`@.┬`@├╥`╩*┬!-4╥╒$3╒,@1%))5─4╠(%194$4@*#`],34╫,2╨╥-34]
  5779. ═,34╪,2─`'!╘:`(╠@1%:╥0╘0@╔╥!$5╦(╪.─14╠├`@.┬"/("╚╩($%,5$523─%4
  5780. ═12!-4╥╒$3╒,@1%))5─4`(┴╘;`#╚`/┴╘>`)─@(─┼.251)04╤)6─┼.1╥╪╬+┬(@
  5781. ═.┬"9`&`=*`#^`├`@.┬!02[+1*"(╪,#`╨(┬─@.┬!05╦)02┌╚╙,`")'3(`┬╥#"
  5782. ═*%!6╩├`╔╠═$╚(─-"(┬─@╦╥#"*%!6╩├$╔╠├$╙,┬"╟(#8╨`,─=-╨"9(─╤/041)
  5783. ═3─<@34%#2$┼.12!,04┘'54%'12!23╒5424┘%4╥╪╬+┬(@.┬#^$2),4┼(╬0─┼.
  5784. ═(┬╤5*$-$*0#╩'3╨`┼╥!05╩╚╙+$16(#╚@┼╥!05╩╚╘+$14(#╚@╟┬!02╨`.'─8`
  5785. ═┴┬!4+%(╠0┬╤)+$$─+$,╠1%0─+$9,)"╤)3"0╠6"╤8)`!('─<`0╘╘─╠┬)$3494
  5786. ═0╥╠═42`┬╩╠<╚,3,╔╩╠<╚,30╒*:╦'*#$╫*:╦'*#$╒-╥╞╩╤╥@╥.2╞╩╤╥@╤.2─`
  5787. ═:!┘(`$--)+)#322╩╤╥@╤-#<╔╩┬(╧4─┘8(╩╦'*#─╥*0"/'─╠`1$╥╥╩╙$@.┬!#
  5788. ═1╦*╦,2`┌($╒%╠├`@.┬!#0;(╨(#╚@34&╥,`#!'┼``┴┬!$220╚,2╨╙,#`╔+$-,
  5789. ═*#$╥."─╠4╒╚╚,3(╪*2╤$4"@╤,├@╔+$-.)"@╙,#`╔`.─>6@"+($14╠├(╒-2"╟
  5790. ═($14)+(┬,34╪,2(@.═4@1%0─╠┬(╤-3<╤(@`/'╓0`1─╨─╠╠<╚,3─╔╩╠<╚,3<╔
  5791. ═╩╠<╚,3<╔╩╠<╚,3<╔╩╠<╚,3<╔`#,?;@!)3"2╥1─╨─.╚%)╠├&─,3─┌24╨─╠─┼,
  5792. ═)*╦'*#$╫*3╩"`#╘?>`")(#4╨,`!#'╪(`.@!┼'╪,`├╥`╩*┬!,3╘%$($╒3+41/
  5793. ═4╥!$25)%0╒1/4┼─@*┬╚`├!^,`)─┬3$]!1$┼.1╥!-4╥╒$3╒,@1$┼214-43╒)9
  5794. ═+┬╪╬(┬`┌()─`╟┴^6`)╪@4$╠@.┬">(%!+╩├,`╔╤^@`$1,╠├``╤1^╩`/╪)($),
  5795. ═+$1#+$)(+%,@.┬!%╠╠(╚4%:╩,┬─`┘╤^╘`(╠@*%,@╦╥`╤*2"╟((╘@,╙@╨(#╚@
  5796. ═1$╥╥╩╙$@.┬".``\@╧@"9(┼-#04┘.24┘'($╒3+41/4╥!$25)%0╒1/4┼─╬+┬╪┬
  5797. ═(#╚@╞0`@(,@`1$*╥0─╥╩,├4╓╦$)(`%`@╙0">(%!+╩├(╤(#╚@_@─@0─╨╠6"╤"
  5798. ═2"`┌($╒!╠─),╩─)(╦#(╒-╩╔8╦#8╒-3,╓`&$@╘@"+($1#╠├`@╔╥`╙-├``@2#<
  5799. ═`($@1%"╥1$(@╔"!$0╩╚╙,╩╨╚1$.╦,2─@╩2`╙,@"┴(.8`┬╥#"*$10*;(╨(+`@
  5800. ═╨┬┴$4"╞╥,├(┘(*<@,╙4╨`+╠@\`"+(,(╚1%"╩,3$╔(*\@,├0@╔╥`╙-3``╤╥#┌
  5801. ═`$1,╠─1,╩├$`"╥$$`40─╠╠─╚(┬`┬╩╠0╚1$╨╔+#,╔╩┬(@("`@($%30╥`@4╘51
  5802. ═("`┬(#╚@├╥`╩*┬!$149!54╤4(%-%3"]44┬]&5"`╩*@`╓(0╪!022╥(┬(@.┬"!
  5803. ═2;(╨╔#$╨(#╚@022╥022╩╤╥├"*$10╩──╔*2`┌(((`4┬$8`4$─╠╠@╚020╠."╞╩
  5804. ═(┬`@(╩╦)*$$─+#,╔`%\┴(@&9($1,.╥!!)`!╤(2╨!1"2╥1"2╩022╩(┬`@(@"2
  5805. ═(38!0╘╨╚1$╨╔╠╠(╚1%"╩,├8╔╩├(╒-╩╙"*$10╩├(╫*0"^(4`!4╒╩╥╨┬┴$4*╚╥
  5806. ═."╞╩,├4╓╦,(╚1%"╩,├─╔╩├8╒-3,╓╦,(╚1%"╩,╙`╔`.$┴2@%$220╚,"╤$3"╞╥
  5807. ═1"2╩╥2@┬("`@("*╩╤"┴36┬─╠-┬─`[╥%/`410*$1,*;)$4`#](50!4╒╚╚1$╨╔
  5808. ═╠┼-:``8┬7@&"($10``╨┬:`&.`!(┬<@$┌`#<┬<╨&/("╚╩(%)%4$]25"!-4╥╒$
  5809. ═3╒,@1$┼32╥!%4┼)/4┬`╩*@!─(╟╨!╞2#'*#$╪*3╠┬35,═1$]3($1)4╘╠@15)2
  5810. ═3╒(@(╥([╥┬├$*$4╔+#(╔.╨"1(╚8!╞2`┬("@─(├╧**-(╚12─╠,╥─[(┬─╠(%!2
  5811. ═15-3($═%62╪┬.\<╚,30╓*0"?(╔`!╚?─@020@.┬".`*4┬╞@$┌`,`┬╞╨&/("╚╩
  5812. ═(%-#4─5%3┬!(14%$24┘'("╚╩`-0┬╔`&9(,<╚,30╫*3╧'*#$╪*3╠``╥.┼`8╠@
  5813. ═346╥,""╟()─┬35,═1$]3(├╠┌6+)-03╦5()─┬0╘)-1$]3(├╠┌6+)#00`╠(┌8!
  5814. ═╞2#'*#$╘-┬─[(┬`@35,](├╧**,0╚1%8╔+#(╔.╥(┌(├═$5"0[`%─├╦@&9(┬`@
  5815. ═0╘)-/2([╥┬├$*$-$*2╨╥*3╠┬("!&4─5%/2([╥┬├$*%@╔+#(╔`&,├╬`&9(#╚@
  5816. ═├@!╔(\(!.@"$(\,!├╥`╩*┬!30╒)%14╪@1─]/5$┼.1╥`╩*@"╪(\╨!╞2!)3"0[
  5817. ═(─0]1$┼2($╘]35-$158@1├╒#0─╒$158@0╙╒#3╒!9(%$]455)5"`@("(`[2/6
  5818. ═`9─@("`@(")4/51/1╘=,12!2/5)%34]612!8/4-"34-062`╧/4╒%3┼4@*╥╘]
  5819. ═4$<┬.╨#╙(^`!├@#┘(^╚!.@`2).╠!├╥`╩*┬!-04┼.(%)/551)3─4@*┬╚`("3╘
  5820. ═`52╥,2`┌($.╥,``╚)/4!4╦(╨`$\─_@&+($╒%╠├`@╔╥!-1╦)$3#╔-0[(╥(#╚@
  5821. ═╒2!-1╦)#1├╔-0[(╤`%──"`*-(#0╥,`!╦)`─"┬╥!-1;.╤,""╟(#4╘,@";)!("
  5822. ═╞2`┬3┼5-("!3("!44─╪@(%194"`@1─┼,14┘!344@($585"`@3$5.1╒1((@#+
  5823. ═)!╨"╞2`┬+2╘═("`═("`═+2╘@("╘═+2`@+2╘═+2╘═+2╘@("╘═+2`@+2╘═+2╘═
  5824. ═(@#5)!╘"┬2`╒-3``!24>`╔─@(─┘532`@4╥`@5%).("!&24╤%3─%-12`@("`@
  5825. ═("`@(%0@($╤%3─=42"(`-24?`╔─@(┬╘═+2`@+2`@+2╘═("`═+2╘═+2╘═+2╘═
  5826. ═+2╘═+2╘═("╘@("╘═+2╘═+2(`/╥4╞`╚╘@-#8╨`%╚┼,`)"╠┼2╩,3<@.┬"+($*╤
  5827. ═348@╔╥!"╠─╒&`',┼.@*9($9,)#╠┌((╠@5+%-1┬"╟(#4┘,`"3)40"@2!)╠┼0@
  5828. ═╔"!"(#╚@╞2!$220╚344╠22─@.┬""`,@┼3@*+($╒&╠╙`@╔╥"9(,<╚,3@╔.╥(\
  5829. ═1$┼214-43╒)9($┘/5"!,3╘%$140^(├╧'*#$╘-┬─`\25/`╚╠@34:╥,""╟()─@
  5830. ═╤╥@╤."─[(├╤.3╥!&24╤%4╙╪┬.\<╚,30╓*0`#)┼@"┬╥!-1╦.╥,""╟(#8╓,``;
  5831. ═)╞("╞2#(*$┼,)"╤2╩├4╔.\<╚,3@╔.╨`╙)╞╨"─2!#╩├$@┬2`╓,╙`╠-├0╨+#8╒
  5832. ═,`!8)╟8"╞2"╞-"─[╥┬┴$220╚344╠5*╔2*2╨╒+#,╔(#╚@┬2`╓-├``?2:``╔─@
  5833. ═╔├<╔.\╚╚1$──*$╒%+%2╩4┬─╠."╨╒*2`┌((─@-├8╨`*0╞┬@*9(*8╤,┬─[╥┬┴$
  5834. ═220╚344╠5*╔2*2╨╤,╥╨╒*2`┌((─@-├8╨`*╪╞┼`*┴^2!!)`"^)╔╪"2;+4*$--
  5835. ═)"╤!)"─`┘":╚`╚╠@34:╤,""╟()─@╥"┴)3"0╠4╩╚╒*3═$220╚344╠5*╔2*0#╘
  5836. ═)╦("┬╥!)╠├`@╔╥`╓,#``/╥>\`╔$@22")(#<╓,"╨╤,#4╨+#$╤,3`╠.34╨+#$╤
  5837. ═-3`╠,3`╨,"╨╤,#(╨+#<╙,"╨╪-├`╠.#8╨+#<╫,"╨╫.3`╠.#$╨+#@╙,"╨╪-3``
  5838. ═9┬?!`╔$@2:╠╤-2")(#4╨,"╨╫,3,╠,30╨,"╨╫,3,╠,34╨,"╨╫,3,`;"?&`╔``
  5839. ═<┬?'`├╚`─╥?(`╚\@*┬╚@5─%224]54╥!-14┘5($]05$┼/3┼,@*┬╚`╚┬?)`─╒%
  5840. ═╠╩╠╚346╥,"─`╩╥?*`╚─╒,#``╒┬?:`╔─@╤╥@╤-#<╔.╥)(059%($%.($%715-/
  5841. ═344@1$%9+┬(@.┬#^`├$╒`-╨╟┘`*````╚^`*+($╒%╠├$@╔╥"-(#0╥,"`┌((╘@
  5842. ═,├4╨,"`┌((─@-3`╨`!╚╚_0*-(#0╥,"`┌((╘@,30╨(#╚@┬2`╒,#``-"@"`╒*╥
  5843. ═4╩╠╤(#╚@┬╥!2╠╙`@╔╥!2╠─*╦5``^*`╨#┬2`╓,#``6"@6`╒*╥4╩╚╤(#╚@┬╥!4
  5844. ═╩┼*╤0┬"╟(%*╥,`!┬*"`#┬2`╓,#``>╥@╩`╘.╥0┌╠╤(#╚@┬╥!#╠╙`@╔╥!#╠─╒#
  5845. ═`(4╚-`.)(#8╨,`">*#╪#0[)#╩├$@.┬"+($.╤34,@╔╥!#╠├``╩"┴(`╪─@-├`╨
  5846. ═`+╪╚4@-2╠├`@.┬!#╠├`@.┬")(#8╨,`#0*%╨#┬╥!-1╦.╥,""╟(#8╨,`#╨*&8#
  5847. ═6+)4╩┼(@.┬"1($.╩,2"-(#@┘,"╨┘,3`╠.3,╨`!,╔<`.9(,@╚24╨─+%*╩-2─[
  5848. ═1$──*$╒%+%@╔(#╚@┬2`╓,#``02┼┌`╪╠@╥┬┴$220╚344╠6"─╠-┬╨╤*;(┬("(@
  5849. ═╔╥!8)+(┬*┬(@.═4@6"2╥(┬`┬`%╘╔┴`/**$1))"┴-12╤8*2╨╓+#$╔╠┼@─(#╚@
  5850. ═├@"/*8╪#┬╥#**$1))"┴-12╤8*2╨┘+#$╔╠┬)!(┬"╟(%@─╠┬)"24╪┬(#╦5(%@─
  5851. ═╠┬)!4╘,┬`*╠╔╞`/**$1))"┴-12╤8*2╨┘+#,╔╠┼@─(#╚@├@#>*:(#┬╥#**$1)
  5852. ═)"┴-12╤8*2╨╤-"╨╤*;(┬4╥(@╔╥!8)+(┬4%)'(┬`┌╒2!8)+(┬4╘51(@#[*:╨#
  5853. ═╥┬┴$220╚344╠6"─╠,30╠,╥╞╥6"0@.┬".``╘╩═@.+($╒&╠[(╨(*<@-├`╨`!╨╩
  5854. ═╨`.!(%┬╥,2"─($╒&`#0╩╥@.1($.╩,2"-(#@┘,"╨┘,3`╠.3,╨`#╨╩╒`."(%@`
  5855. ═1┬╦>`╪─@-3(╨`&,╩┌`-2╠├`┌┬╥!"╠─╒&(*<@5+(╤(#╚@┬2`╒,3``=┬╦╥`╒2╥
  5856. ═5*╚╤."`┌((─@-3$╨`(@╩_`.+($╒&╠[(╨(*<@-├8╨`,`╩`012╠├`┌┬╥!4╠├$@
  5857. ═╔╥!4╠─╒&╩╥┴-1╩╬╒*$╒&╦3$╪*:╨╤."╞╩,2`┌((╠@5+.╥348@╔╥`╒,3``╓2╚&
  5858. ═!%2╥5*╠╤."`┌((╠@5+,╤(*<@5+(╤`.,╩$`2)(#4╤,`#╪*┴╚$╞2!)3"0[╤╥@╥
  5859. ═-╥─[(─`┬.╨`>*╥0$┴2)-4╥╒$3╒,@1$5624-%($┘534)%4┬`╚."╘╙,"─┬.╘16
  5860. ═`&(╦)02+($-$╠─16(*>9(─╒3+41/4╥!!3─0@0╘)-+41/4╥!$159)0╘53($╒5
  5861. ═4╒0@0─4@1$┼&1─5214┘4(2(┌┬3$╨-├``├┬╠╬!%┬╥-╙$@.┬"%(─╒3+41/4╥!$
  5862. ═159)0╘4@5%┼012`@*#<╤+╙@╤*2([6`#/*╙@$┬╥!8╠├@@╠"!8╠├@╤(+`@6+(╤
  5863. ═-3@╤(*<@1%2╥,├4╒.─14)+(┬,34╪,2(@.═4@1%2╥,#╔$5"2╥(├$╒-╙$┬`/\╦
  5864. ═0@27(%!6╩├,╠1%8@.┬"7(%!6╩├0╠1%0@.┬">(%!+(#╚@1$╥╥╩╙$@.┬!-0;(╨
  5865. ═``─╠3`2)(#4╨,``>+%8$╞2!)3"0[╤╥@╥-╥─[(─`┬.╨!&+&`$┴2`┬0╘)-+41/
  5866. ═4╥!$159)0╘4@3┼5-0─52("@╨+3,╨*2([0╘0`┬┬╤╩!(╠@0╘2╥1%8@╔┘─┬35,═
  5867. ═1$]3($%.1"!#0─╘═1$]3($1%5─┼#15,@35535"!"12!$249&15)%3┼0┴(├╩)
  5868. ═,3$╥,`"├+'0$0╘:╥╩╙$@.┬!#0;(╨(#╚@┬2`╒,#``╩2╤╒!#╚`╨"╤╓!(\@*┬╚@
  5869. ═0╘]062!&24╤%4╥`╩*@#2+'╪$┬╥!-1;(╤(*<@,├`╨,`#\+'\$╞2#'*#$╘-╥─[
  5870. ═(─-/4%─@35,═1$]3("╘^($-"32╒$3╒,┬.╔─┌╞0`8+8@$┬╥!$3+.╥,""╟($9#
  5871. ═╠├`@.┬")(#$╤.3``3╥╓2!$9#╠├`@.┬"!($:╥,2"─($1,(#╚@┬╥#**$1))"@╨
  5872. ═+$8╔+#8╠,2╞╥(┬╚┬(*<@├2`╤,├`╨`%<═╟`2"($8`@╥╓╞!)─@.┬"9(─9)3$53
  5873. ═($-/4$┼%1"`](├═&0╙╠┬("╘@4%)%4╒,@2╘59(@"5+:<$╚?─@020@.┬")(#4╥
  5874. ═,`"┴+;`$1─.╥1─.╩,0#.+;╚$6"2╥╥┬┴$220╚,"╤&*2╨╤.2╨╪*:╚┬+┬*╩╥┬┴$
  5875. ═220╚,"╤&*2╨╥.2╨╙*0`)+╠0$0╘8─╠┬(┬.╚%)╠├&─╨╥┴8)"─┌┬╥#**%@─+$─╠
  5876. ═,2╞╙╠2(@(┬"╟($-&)+)#1┬2╩╥┬┴8)"╤)+#$╔``\╬╙@2"`#@╬╙╨2+(,─╚0╘8─
  5877. ═+#$╔╠┬(╬(┬"╟($-&)++(*$-&)"╙#*$-&)"╞╦,2─`62[0!$-&)+)#1┬2╩(┬╨┬
  5878. ═╩╠╚╚1$──*#`╠1┬─╠,30╠,2─`├2[8!)─@╤"┴&0╥─[(┬╪@(├╧'*#,╘*3═#1┬0[
  5879. ═╤╥@╙-"─[╚╙(╨*3═36┬┴&*2)"651%4╥([`*@╬╫029(*,╙-2─[╥┬┴$220╚,"╤&
  5880. ═*2╨┘+#,╔`-<╬╪@1#3+)#3"┴&*2`┌($╤"╠┼-:*$8╔(*╠@═2┴36┬┴&*:╘╓-34╙
  5881. ═-┬╞╠-├4╒,╙8`$2_╠!(╠@0╘2╤╠├@@╔╥#^#2,╤+"┴#1┬2╩(┬╤7(┬─╠52┴#1"─@
  5882. ═.═4@┬╥!#1+.╤,""╟()\@,2╤#1"╨╫`",╧\02+($-$╠╙@@╔╥`╤,├@╪`#<╧]@2+
  5883. ═($13╠[$╓,╥"╟(#$╥.#@`:┬_[!%@─╠┬)9(┬`┌()─@(─-"32!&24╤%($5825-4
  5884. ═4╙╠@3╒9%4┼=2251%("┴9+╘╪╔(├╠`─┬\`!:`@,2`┌((4@6"0@.┬"+(%@─╠┬).
  5885. ═(┬"╟($9#╠─9#╩╙$@.┬".`*,╧!07╥*$-&)"─╠52┴#1"─`╧2\&!?╪-(╙$╠*$-&
  5886. ═)*╚┬+%<┬*2╤5*$-$*0#/+╨@%┬╥!#1+,╪(*<@,3,╥,`#┬+╤0%┬╥!$4[,╥,""╟
  5887. ═(#$╙,├``&#`>!9─@╤╥@╤."╞╩(─-"32!$25-+($524─]2.┬`┬╩─13)"`┌($9#
  5888. ═╠─9#╩╙$@.┬"@,2`┌((╪`0├`╚!9<@4%:╩-┬╤#3*╘╥-38@.┬"7(%!6╩├4╠0╘╥╦
  5889. ═╨┬┴05╩╚╓*:╨╥-38`;#`╥!9<@4%:╩."╤,0╩╘╥-38@.┬"7(%!6╩├<╠3$*╦╨┬┴0
  5890. ═5╩╚╪*:╨╥-38`┼├`\!512╠├`@.┬"+(,╚╚1$──*#`╠1┬─╠.2╨╤*;(┬02(@╔╥!4
  5891. ═4╦(╥-34`╦3!"!5┬╥,2`┌((╠@0╘2╥,""╟(%┬╥,`"],$8%╟┬!02┌╚╓+%12+%@`
  5892. ═╓#!+!?╪)(%@╠6"╤8+%,@.┬!%╠╠(╚4%:╩,┬─`^#!,!8╠@*%,@╦╥`╤*2"╟((╘@
  5893. ═,╙@╨(#╚@1─.╥1─.╦,0`0,5`%┬╥!#1+.╤,""╧($-$╠╙@@╔╥"@,0`╒,5╚%┬╥!#
  5894. ═1+&╥.""╟(/╪/(╙$@.┬"+($13╠;(╥,""╟(#$╙,3``.╙%─!8╪`03%╓!3╚`8#%╫
  5895. ═!8\@*┬╚@4─5-3╒9%($╒3+41/4╥!&24╤%("╚╩`)@╤>`69(,<╚,30╫*3╠┬4─5-
  5896. ═3╒9%("┴$14╤%5$4╔(%-%3$5#5$5$($╒3+41/4╥!&24╤%4╙╚┬.╔─`╙╙%┘!8╠@
  5897. ═346╙╠3`@╔╥"9(─╒3+41/4╥!-14┘5($╒54╒0@0─4@4╘5,14-4140┴(┬`┌((─╥
  5898. ═,#,╨``,╥>@5!)+(┬62(┌┴2)!4─4@64]5($╤)2╘4@4╒5212!!0─]55"!42$┼3
  5899. ═("┴9+╘╪╔(├═!)``:,╟╠%╞3╩+($$─╠┬).(┬"╟((─@-3(╨`#8╥@@6+($1,╠[(╨
  5900. ═(*<@1─.╥,"`┌((─@,30╘,`!%,╚╨%1─.╥,"`┌($:╥,0!┌,╔$%┬╥#**$1))"@╨
  5901. ═+$8╔+#8╠,2╞╥(┬╚┬(*<@├2`╤-#<╨(#╚@1─.╥1─.╩,2`┌($:╥1╩╠╤`)4╥┼@5&
  5902. ═╠─:╩,2`┌((╠@1╦.╥1$╨@╔╥`╤-#(╒`*@╥╞@69(─9,55-(24┘'+┬╪╬(@"╘,╔╠%
  5903. ═╟┬!02┌╚╤,@#┴,╩`%╞2`┌()─┬1─┼,15,@4─5-3╒9%1"`](├═&0╙╠┬("╘@4%)%
  5904. ═4╒,@2╘59(@`-,┌4%╟┬!02┌╚╥,2`┌(/╪)($$╠6"╤9(#╚@34&╥0:╔9╦#(╒-╩╔8
  5905. ═╦#8╒-3,╓`!\╙╩@6┴^2!!)"`┌((─@-3`╨`$╪╙╧@69(┼)%34]624┘'("([╤╥@╙
  5906. ═-"─[╥┬┴$220╚,"╤&*2╨╤.2╨╤,╥─[╤╥@╙-"─`@#/2!9<@4%:╩,3`╠1%`╚1┬╞═
  5907. ═,├4╓(#╚@┼╥!05╩╚┘+$10*$8╔╩\(╚4%:╩,3`╔╦#(╒-@",,]0%╟┬!02┌╚╤-0#*
  5908. ═,]8%1$──*#`╠1┬╞╥1$──*#`╠1$╨╔.┼-:*$8╔╠┼-:*$1,*3╔$4"┴&*;)$4"┴$
  5909. ═3"─┌0╘╨╚1┬╞╥0╘╨╚1$╨╔`-8╙╒╨5$3+)$3*╠╤`-╨╙╓`6.`.(╙╓@4┌`/╘╙╓╨6/
  5910. ═("╚╩($-/4%─@0╘)-($9)3$53("╚╩`"<╘╫`69(,<╚,30╫*3╠┬0╘]062!#0─╘═
  5911. ═1$]3(%1/($-"32╒$3╒,┌(├╩9`&`╘╫06+($-&╠[(╨(*<@╞2)#3╘╒-3╘1/4─4@
  5912. ═1$┼214-43╒)9($┘/5"!,3╘%$140┬(#╚@┬2`╥,#,╨`(╨╘╫@58╠├`@.┬"%(─1%
  5913. ═5─┼#12!.54╒"15(@5$\@0╘]062!43╥([6"`┌()─`╨#3?!8╠@6+.╥,""╨(%┬╤
  5914. ═╠├8╘(*<@╞2)"040@1$5624-%($┘534)%4┬$┬(#╚@┬2`╥,#,╨`/0╘╪`6+(%┬╥
  5915. ═0╘0@╔╥"9(─-!3─┘/5"!#3╒!9(%1/(%-!344@1$5624-%(┬`┌((─@,├`╙,``├
  5916. ═->$%@2!&╠├$@╔"!#1┬`┌((╠@╥┬┴$220╚,2╤&*2╨╓+#$╔╠[$┬*┬(@╔╥`╤-3<╨
  5917. ═`$@╒╪@69($1))"@╤+$8╔(#╚@╟╙$╠0╘0╠,┬╤#3┬0╚1┬╞╩(┬╤2(@!─->,%┬╥!8
  5918. ═╠╙@@╔╥"?(#(╠6"╨╫(#╚@┬3$╒-3``├37─!4-&)+)#3┬0╚1┬╞╩(┬╨┬╩╠╚╚1$──
  5919. ═*#$╠1┬─╠,╙$╠,2╞╩(┬╤7(@"<->4%╟╙(╠6"╨╙+$-&)`"╨->8%┬╥!$4[.╤-├,@
  5920. ═╔╥`╤-3,╨`+<╒┘╨6@,@#╫->@%6"2╥(┼─┬.╚4┬1─┼,12!%6$┼35%,┌($]615)7
  5921. ═4─┼412`╚62].*2([6"0@.┬"+(%@─╠┬).(┬"╟(#$╒-├``"├;╨!?(╚0╘╪─*$8╔
  5922. ═*2╤5*%@╔`!─╓]06?,┬╤8+#,╠0╘8─`$╘╓^@6+($13╠3(╨(*<@╞2#'*#$╪*3╠┬
  5923. ═0╘)-($1/4╥!%4┼)/4├╚@(├═$4╥0@.┬"),34╓,`!=-@╪&╟┬!02┌╚╥-"╨╤+#(`
  5924. ═:388!╩`╤(#╚@╚#(`<38┬!╚(@1@"┬-┬╨&╞2`┌()─┬1─┼.25-(140@+2!04─53
  5925. ═4╥!!($═%62(@.┬"┴^2!!)"`┌((─╒,3``╩#;.!╙╚`╥╙;/!╪\@*┬╚@0╘]062!#
  5926. ═0─╘═1$]3(%1/($╒3+41/4╥`╩*@#┌-═`'╞2#'*#$╘-╥─[(─-/4%─@0╘)-+41/
  5927. ═4╥!43╥!-4╥╒$3╒,┌(┬`┌()─@.┬"9``╘╫╓@>+($1,╠;(╨(*<@,├`╙-0`┌-^0'
  5928. ═╞2)-4╥╒$3╒,@1$┼214-43╒)9($╒54╒0@0─4@3$]!1$5$($9)4┼-4(@!├-^╪'
  5929. ═╞2`┌()─┬4%)%4╒,@04┘9($═%62(@.┬"┴^2!!)"`┌((─@-3$╨`&╨╫\╨=&0[(╨
  5930. ═`)╠╫]`>!($:╥,2"─($-&(#╚@┬╥#**$1))"@╤+$8╔+#8╠,2╞╙╠2(╩(┬"╟(#(╨
  5931. ═-#4`╠╙?╪!╘9#╠─9#╩├$@.┬!#)+)#3┬0╚1┬─`[3?┘!┘╟**,0╚1─,╔+#(╔.╥(@
  5932. ═(├╧**$1))"@╤+$8╔+#$╘+#$╓*3╧**$1))"@╤+$8╔+#,╘*3╠┬.┬([``\╪^@>-
  5933. ═,├`╒,"`┌()─@╥"┴-)"╨╪*3╠┬+┬([╥2┴-)"╨╙*0`┘./╠'5%*╥,"`┌((╠@╥┬┴$
  5934. ═220╚,2╤&*2╨┘+#$╔╠┬)!(┬"╟(%12╠├(╒-0!#./╨'├3(╤,#``23├]!╪(`9├├^
  5935. ═!┘─┬1─╤54╘┴)3─<╬+┬╪┬(#╚@╟┬!02┌╚╤,@"2./\'╟┬!02┌╚╥,2`┌(/╪)($$╠
  5936. ═6"╤9(#╚@34&╥0:╔9╦#(╒-╩╔8╦#8╒-3,╓`+8╪``┬9.┬"9(─9)3$53($-/4$┼%
  5937. ═1"`](├═&0╥`┌((─╥,#,╨`+╨╪`0@┌`/(╪`@┴8╠═0╚0╥0╠(┬╪┬*2`┌((╠@6+(╨
  5938. ═(*<@322╥0╥2╩(┬`@("`@("`@("`@(┬`┌((─╥,#─╨`"`┘!╨┴8╠╠,╚0╥0╔╩├$@
  5939. ═.┬#╦(#╚@6+)8╩╙$@.┬#╠(/╨@╥┬┴#)"╤8+#$╔╠┬(╬(@!!.0╨(322╥╥"├(*$,─
  5940. ═+%┬╦,2╞╩(┬`@("`@("`@(┬╨╪*0!8.18(6"2╥╥┬┴#)"╤8╩├$╔╩┬(@("`┬`&4┘
  5941. ═(`┴-)+)-)*╔8)`!╒.2╚(322╥╥"┴-)"╨╤,2─`╠3─╦"(%)╠├&─,3$┌6"2╥╤╥├&
  5942. ═*,╚╚320╠22╨╤*2╞╧,3(╫*3╩+(%@─╠┬(╬(╦!8)+(┬("(@╔╥!8)+(┬7╥(`╥#─╠
  5943. ═",╚╚320╠22╨╤*;)8)"`┌(((@20`&.┬╘(2;(╪(#╚@┌╥#]($╞╤,2"╧(,╚╚320╠
  5944. ═22╨╤*;(┬7╥(@.┬#**$╘─+$─╠,2╞╥(┬`┬(#╚@2;))╩╙$@.┬#╠`$4┌+@┴)╠├$╤
  5945. ═(#╚@┌╥#]($╞╤.""╧(,╚╚320╠22╨╤*;(┬7╥(@.┬#**$╘─+$─╠,2╞╥(┬`┬(#╚@
  5946. ═2;))╩╙$@.┬#╠`$╠┌,@┬.`%$┌,╨@┌`%╨┌-`┬!2;(╨╔#``?#╚┘"($@1%"╥1$(@
  5947. ═╔"!$0╩╚╙,╩╨╚1$.╦,2─@╩2`╙,@"=.├╪(┬╥#"*$10*;(╨(+`@╨┬┴$4"╞╥,├(┘
  5948. ═(*<@,├$╘,`"╞.─@(@┬!$4`#2.┼((╞2).3╥!&4─5%($╒3+41/4╥!$25)%0╒1/
  5949. ═4┼─@14┘425)%4╥(@.┬".`-╚┌7`┬"($─`!├═╨"(%)╠├&─╨╥┴-)"─┌┼╘10╩─╞╦
  5950. ═,2╙&*,╚╚320╠22╨╤*2─@╦╥`╤,├<┌@@`>.╫╚(@4╞╥,3&─,╙$┌┼╥!$4*╔)+#`┌
  5951. ═@@`╫.╪0(┼╘10╩├(╓+#(╒-3╩71%"╩,├<╠,34`83╬.")<@4%:╩,3`╠1%"═,├4╓
  5952. ═.╔<@4%:╩.2╤$4*╧"*%!6╩├$╨*:╨╥-38`<#╬8")\╤+$-$+#(╠0╥0`├3╧\")╪@
  5953. ═4$╬╩.2╤44┬╨╤(#╚@_@─@6"╤8+%@╠4╨"4._╘(╚#$`═╙╠!"8╠@4╥"╧(#$@╔╥!%
  5954. ═╠╠(╚4%:╩,┬─@.┬"-,╙@╨(#╚@├@#╬.╨8)6"2╥(┬`@("`@05-#("!315$@("(┌
  5955. ═┬╥!44╦(╨(*<@6"2╥(┬`@("`@0─┼.("!04─<@("(`$3╨0"41,╠─1,╩├$@.┬!$
  5956. ═)++)*"(@(╩╦$*$1,*2╨╙*:╔8)``╨/!╚)1"2╥1"2╩╥"┴-)"╨╪*:╚┬("`┬╩╠─╚
  5957. ═320╠,╥─`43╨─"4-,*$1,*;+"*$10╩├(╓*:╚╥-3:╠╨┬┴$4*╚╥-╥─`?3╨╬"5-:
  5958. ═╠╠(╚1%"╩,├@╔╩├(╒-╩╙"*$10╩├(┘*:╚╓-34╙-╩╙"*$10╩├,╨*0"─/#@)1$──
  5959. ═*#`╠1$╨╔╠─0─╩╠─╚(┬`@("`@("`@(╩╦$*%-:*2╨╪*0"╥/$()1%`╚1$╨╔╠─10
  5960. ═`,`\3`┼36┬┴$3"╞╥4╒╚`╤├╤;"8╪`╙#╙""3╚`]3╙#"8\@*┬╚@3$]!1"!#3╘╒-
  5961. ═3╘1/4─4@1$]3($1)4─5#5$]262`╩*@`├/<0)╞2),3╘%$24┘'($-/34╒/1$]2
  5962. ═12!$3╒,@1$┼214-43╒)9+┬╪╬(┬`┌()─`5╙╫%"8╠@0╘2╙.""╟()─┬0╘)-1$]3
  5963. ═($1%5─┼#12!-55-4($)%(#╪](#@┴(┬`┌((─╥,#,╨`(4]╥0╞?,2╤#1"╨╨+"(─
  5964. ═,"(┌╚2,╤+$$─+$$─(#╚@0╘:╥╩╙$@.┬!1)++'*#,╘*0"+/<╚)┌╨#$/<╠)╟┬!0
  5965. ═2┌╚╥-╥╨╤(#╚@0╦+"*%!6╩├$╤*:╚╥-3:╠╨┬┴05╩╚╤,┬─@.┬!4)++'*,(╚4%:╩
  5966. ═,3,╔*0#3/<╪)6++"*%!6╩├$╘*0#┴/=@)┬╥!8╠├`@╔╥#═`!<^╪@┼8)+(┬(┬`┌
  5967. ═(($@2;)05╩╚╤-2"─(%!6╩├$╒╩┼┬╦,2`┌(%@─╠┼@─╩╠<╚╨┬┴)*2─@.┬""`",^
  5968. ═#╨╔#1╦)#1╩╚╤`$╠^'@╩+($-&╠├`@╔╥"9(─1)4╘╠](┼$─6"11)"`┌()─@.┬")
  5969. ═,├8╒,`!:/┬@*0╘╪─*$-&*;)8)`"9/├(*022╥╥"┴8)*╚┬("`@("`@("`@("`@
  5970. ═("`@("`┬+#$╫*:╔4)*╦)*"(@("`@("`@(╩╦$*$*╠,├4╘*2╨╪*0#'/├╨*1$──
  5971. ═*#$╠0╘8╔╠╠─╚(┬`@(╩╦$*$-&*2╨╙*:╚┬("`@("!!4╘,@("*╩020`[├┘!"╚╠@
  5972. ═5"2╙╠2)3(┬"╟(,╚╚1$──*#$╠0╘8╔+#─╠,╥╞╥(─))3┬(`_├┘&"╔─@1$──*#$╠
  5973. ┬0╘8╔``0_6@╦╠`!╚_;@╔#0;)"╦#(╒-┬`┌(*`╤(#╚@├@``````
  5974. `
  5975. END
  5976. BEGIN 640 LRR.BIN
  5977. ═`(!,#(),7(-,┴89,\╪=,,(5,┌(1,/8!,╚╪5,2╪┴,@(├+┴```````````````
  5978. ═````````````````````````````````````````````````````````````
  5979. ═````2*─`┴9"═(8`@╠?^╔;╥"3_┌┼5(*├_))`╨#┌─╨(*├_:""╚_╥20,`(88*─%
  5980. ═├2"`.&"═`-╒)$(╘`╫6"╔""╨-╫/#[8""3@*╪,╫""*@(╔@╩1╚@6╪"0`6`@╦╧\─
  5981. ═─##.&"!'_╥╨-╫""*@"";@(╘@@"─/╥0*╨):``()╬`╞56`╥,`&─/48╩0@@6╪"0
  5982. ═`6"╔`2╨┬@#`"╩00@╩/\@╦╧]@2(╚╔`0╚*"@╚╠(╚`0`──0(%╬`:)`!8""╚_┌─!
  5983. ═(*├_╩0─@╩/\@╦╧]╪&"!'_╥╨-╫""*@*╟╓╚(╩%`╚0#╩0"%!"╨┬@#`#($:!(%┌!
  5984. ═╠`╟╞!*4$╥0╞0┌╤┴88*╟╓┴0*╞!!┬╔┬╟╒5@84#8``($`8.!`╨""┬";@(╘@@"─/
  5985. ═╥0*0`6"┬`╩``╩0@╠#=╙╨^┌╘`╫4─0├0#=╦0╙<─0+(╘.╟╞`\╦0┘&!(┴`2**0$*
  5986. ═"@╚*"0(╠(╚`0`──0(%╬`:)`!8""╚_┌4$(*├_╩0$@╩/\@╦╧]╪╩4"%!3@@1_]╪
  5987. ═+`╫<╚@*@`*╘`╫<╘`╫=#╪104╔0/#╥╠0*-#-╥┼!4┼`┴06╔""╨-╫/#[╥-#=┘@/*
  5988. ═╘-@8($?_+`╫<((╩`().`╦@╙<((╩`┬╚╘@@"─/╥0)88*─.├0#_╩?^-2╚"-2╪"┬
  5989. ═!┘╒-@,╚0^╚╒,@!┴@╙4╩`╘!#╠2╪#0"╪┬8"┴┴╔┬╩┬╔]┴┴@├4╩`├─╬`┴`4@\8"0
  5990. ═&:╘@@"─/╥0╧╨`├┴@(*:`╦4╩`╦─╬`╔`60╓╓"═2╚"╬2╪"─!4╨╞@╩+_┌#├╔$╦#┌
  5991. ═┬!#╫&&─2╥*┬*8"!╠@╩(`╨`╞0"$┬8┌0╞╚:*(!╥&"&"╥!^@╚4(┴@╞$"╩4(╔@╞─
  5992. ═"┬`╞@╔`!8(4,┴`╓┬`╩``╠0╥1!╠┬╤#)$&╥-#╘┘@╫╞!\╦0[>8*╔0╦)"╔`2╩0&%
  5993. ═"╬8)╔0╟)`╔`&╩0"%">8(╤@╧0╬╤┴@..─"╠`&(╦├┌`╪`'╨!╨╩$!╥8'╔`<8;42`
  5994. ═─`'(8"#├@╩+╓┴@:┬╟(8'╦├┌`3)&"('┌"╙4╩`╘`_╠2╪#0"─┬╔_╪╒*@(╒+@&@@
  5995. ═├(%@```@╪╪*┬]╚8"╚╔╥&`╪╘╦@╪╨╠@╥`0@┘`!8*╘^@,─"╠`%@╦2╬#╦"╥#&&─!
  5996. ═─`'((!"#8*─.├0#_╩0"@`"!^@┬`╞@╔`!8(4"┴`.@#;$"├3┌`╥0.0!┌─\├2"`
  5997. ═.&"@$+$"╥0+0\:`6╠0*-/╪#)!+#╞╚!&╤`╚╒!@,╞!╠-═*2─╔*├4"`╚!.╤`╚╒"
  5998. ═@,┬╤`╚╒#@*`8╠0+)"="_╚!╩╤`╠─"╘+>@#╦$"╥0'0╦┌╘_@`╚8:0&-18`8;4"`
  5999. ═├42`╦4*`╦$.`..╒$@+`!┬(╒&@(╤'@*╘^@,─"╘`9.1╪!╬1╚`8╦4:`:0*-2("═
  6000. ═1╪!╔`(╒)@*╟╓╚*"%!╚0'╩0&@`*╪_@""1@╔`!8*╟╓╚*:%!╚0'╦46`╚`"╬0(`@
  6001. ═─8*0`6"╔]╩"╞╦─&`&&"%!80#1@-╩┴02╞`╨╚╞`╤┴┼!(4"┬╞4#┴0,8╔0)╔]╚4"
  6002. ═╔0-╔╚(4#╚`*╤`╔─&`(@0^&`@1(2┼!2─!╘`┬┼!╥─/╩*4&8*4'╚@1&"&╦*╘/╩─
  6003. ═"&`@1(2┼"┬─/┴0╩┼!2─!╘`^┼"84&╔0<╔\`4*┴0=,╤82┬!`8))@╦*╘/╞┼"╚4(
  6004. ═╔0<╔#╨4)┴0>@`╦─&`)$"┬!#╪├$╥`8#┬═)╪#╔]╩╘╚@.╞╞2┬─'╩╩╟_╟4╓`8*`.
  6005. ═├`#_╦2>`╦"┬`┴0*$`┌╟┼╚`"1`╩`:╠0*%#╠┬╤`╚4/╔0_)!9`#3-.$╩*4.('2$
  6006. ═2)┴(╩0"%"84*╔0┌─#╥"2┴&┬%#╓┬%#─╨(┴:─.├0#_╦4╥`\"┌╔`(╒,@*─"┴6&╔
  6007. ═`84.╦3^`┴6"╔]╩"@┴0*$`┌4.╚``@$(.0`6#╞#╠9@╘/#&8=#?╦46`┴0┌═0("%
  6008. ═8*─`┴6&╔]╩"╞┴0*$`┌9┴╧4╓`\!"╔`)╒-@*4.╚``@$(/&`\8#┘@[╞8>8#┘@/&
  6009. ═8-#=&&"@#╚╨`_┌─"╚`"%#╚0/┴&"$8:4.╔`\@=(2$`@4"╘`;╞8-`"┘╞'╞#═`"
  6010. ═┘@^┼#╠╒(@*4/[4╞`─-╬╬/╚`&8"9┴╥═#┘╩0"─8*9┴8*5─╔&4@_╪*0`6"╔]╩"<
  6011. ═┴6"$8:─`┴6*═/╚`*┴6.┼9*1┼('2$┴62$9<`%─!╥═)8"%8╩─!╦├┌`╪`'╨`╩─#
  6012. ═+2:`╘`6╬)8#╨`╚5├(#6&8*8/╘`(88"#)_┘`$├2"`8*╟_╔╞/0`╩5┬┴6:@`+%@
  6013. ═)`╪0!╩╩]]╚├╨`╥#2_\├$9═#╠&*5@96:%8)`"┘╞$╪╔6+┼9╚5┬╠`+&8┌5┬!6/0
  6014. ═╤"#,_╤┴@╚`┌,`/^%#╚8/╦2.`╦"2`┴62$94╥┴┴┬#╩┴9`!8*5┼╥060]!┴@┴0┌&
  6015. ═4*─`┴5&%5(558*─`┴6*%8┌94\`2╔`!┴@╔┼`@╤╧^0!(╘@@&"╔_┌93╘`*┼4╚5╞
  6016. ═╚``@((>0`6#╨!┘%@╥,1╞╘/&$9┴┬┼8&5╞┴6"0`╬9┴&*5┬96:%8╔`"┘╞,╪╔5+┼
  6017. ═9╚52╠`+&4┌54╘`:┼4@53╘+@@╙/^┼8@5├&&"┼5/`!`*51\`┬╔`(51╩0╚88*55
  6018. ═*4#╨"*╟_┴52╔`!┴@(,__╔╔"&59`'├2"`(,╙_8"0.$`╥╩╧?:)\,?)#=`"┴5&┬
  6019. ═_╤┴@╔5╦-2("┼6^╒)@)`!8*5:╔%╠@=(2$`@4"╘`:┼6╩1;&&#╞6═#<┘┼═,8╪<@
  6020. ═8╪>0`6"%"80*╔60%9?`2╔62─9:8)┴╞2╞"╚9┼()*$3,>'╦2>`╦"┬`┴0*$`┌`:
  6021. ═╔0╞1`╚5─╥*4*─0*%9:╟_╚`^%"80*╔62─92"2┴*5─╔&4@+8.0`6`8╔5╤┼8╚5<
  6022. ═╔5╒┼8╪5=─`+╞7┴┴@╚`┌,`/\@╩8:╔`(5─┴66%6╪5<┴5╓%7╩─"┴5╩╔]╩"<┴6"$
  6023. ═8:╘^@`╩╚╩0"%4╚13(+:&─`%@\`8@├(>0╪&"═)╪"╠*("%`╚0#╚@"@'+5<─0+(
  6024. ═┌.`#─/8@╘╪088*`.├`#_┴@^╩╩0`@╩8:╔]╩"<┴6"$8:─`╚`2%4╚13(+:&╠!+╨
  6025. ═$*╟╓╚)╥%8(1┴(#6&╠`-,6(┴@╚`┌,`/^╩(,;_─`╥╔`(╘╠@(╘╔@(╘╩@&`@┘(@@
  6026. ═┘(@@┘(┬-*8`@┘(┬-*╚"╔`(╘╠@"#─┬,─┬\`├)0═#╒(,╙_8*``(.2(╥2+╨!╔─═
  6027. ═@,├0\╪╨╠@"#─┬,─@\/╞-*╪`@┘(├)`-#┘(,╙_8"#/_[`%))!╨`6!╚:"#,_╘╥+
  6028. ═┬```````````%`─-`),`````````````````````````("$┬(╥0┼)┬<╚*2╚╦
  6029. ═+"╘╬+╙`╤,├,╘-38╫.#─┌.╙╨]/├]`╨<+#╤,7&╤\├)╥╠╧,╙<[/╘-'2╘]35╒═?8
  6030. ═╓=╔;7%╒>7\!!0─-$149'2$┼*2╘╤-3─]045)35%565╒┴96═╧<╫=[?````````
  6031. ═````````````````````````````````````````````````````````````
  6032. ═````````````````````````````````````````````````````````````
  6033. ═```````````````````````````````````````````````````````)````
  6034. ═#0````````@``````````````"`┴(┬,─)28╟*"─╩*╥╨═+┬\╨,3(╙-#4╓-╙@┘
  6035. ═.├╠\/3╪_0&%┬8╓1┼9╞=╚:6╔╦;&╒╬;╫!╤<╟-╘=79╫>'┼┌6╒╤=7┼\`````````
  6036. ═````````````````````````````````````````````````````````````
  6037. ═``````````````````````````````````````````````````````````!@
  6038. ═04)#1$5&1╘┴)2─═,34┘/4%%24╒155┼=865╔[?'╒^?╨``````````````````
  6039. 2``````````````````````!^````
  6040. `
  6041. END
  6042.  
  6043. 7. ╘╚┼ ╞╒╘╒╥┼
  6044.  
  6045. ╞UTURE IMPROVEMENTS TO THIS PROGRAM WOULD INCLUDE IMPLEMENTATION OF ═╙-─╧╙
  6046. FORMATTING, MORE FILE MANIPLUATION COMMANDS (SUCH AS ╥ENAME), RE-WRITING THE
  6047. USER-INTERFACE ┬┴╙╔├ PROGRAM IN MACHINE LANGUAGE, AND MAKING A FILE BUFFERING
  6048. FACILITY FOR THOSE PEOPLE WITH ONLY ONE DISK DRIVE.  ╚OWEVER, ╔ DON'T INTEND
  6049. TO DO MUCH MORE TO THIS PROGRAM.  ═Y INTENTIONS ARE TO PUT THIS FUNCTIONALITY
  6050. INTO A DEVICE DRIVER FOR A NEW OPERATING SYSTEM (OR AT LEAST, OPERATING
  6051. ENVIRONMENT) FOR THE ├-128.  ┴NYONE ELSE IS FREE TO IMPROVE THIS PROGRAM.
  6052.  
  6053. =============================================================================
  6054. ╔N THE ╬EXT ╔SSUE:
  6055.  
  6056. ╘╫╧-╦┼┘ ╥╧╠╠╧╓┼╥
  6057.  
  6058. ╘HIS ARTICLE WILL EXAMINE HOW A TWO-KEY ROLLOVER MECHANISM WOULD WORK FOR THE
  6059. KEYBOARDS OF THE ├-128 AND 64 AND WILL PRESENT ╦ERNAL-WEDGE IMPLEMENTATIONS
  6060. FOR BOTH MACHINES.  ╫EBSTER'S DOESN'T SEEM TO KNOW, SO ╔'LL TELL YOU THAT THIS
  6061. MEANS THAT THE MACHINE WILL ACT SENSIBLY IF YOU ARE HOLDING DOWN ONE KEY AND
  6062. THEN PRESS ANOTHER WITHOUT RELEASING THE FIRST.  ╘HIS WILL BE USEFUL TO FAST
  6063. TOUCH TYPERS.
  6064.  
  6065. ╘HE ╙ECOND ╥OB ╚UBBARD ═USIC ╥OUTINE
  6066.  
  6067.   ╔N THIS ARTICLE, THE SECOND ╥OB ╚UBBARD MUSIC ROUTINE WILL BE PRESENTED IN
  6068. THE SAME WAY AS THE FIRST. ╞UTURE ISSUES WILL HOPEFULLY EXAMINE VARIOUS OTHER
  6069. MUSIC ROUTINES INCLUDING VARIOUS ═ARTIN ╟ALWAY, ┬ENN ─AGLISH, ╩EOREN ╘EL,
  6070. AND ═ANAICS OF ╬OISE ROUTINES. ╬OTE: ╒NFORTUNATELY THE AUTHOR COMPLETES
  6071. UNIVERSITY (AND THUS LOSES INTERNET ACCESS) IN ┴UGUST 1993.
  6072.  
  6073. ─┘├╨ - ╚ORIZONTAL ╙CROLLING
  6074.  
  6075. ─┘├╨ - IS A NAME FOR A HORIZONTAL SCROLLER, WHERE CHARACTERS GO SMOOTHLY
  6076. UP AND DOWN DURING THEIR VOYAGE FROM RIGHT TO LEFT. ╧NE POSSIBILITY IS A
  6077. SCROLL WITH ONLY 8 CHARACTERS - ONE CHARACTER PER SPRITE, BUT A REAL DEMO
  6078. CODER WON'T BE SATISFIED WITH THAT.
  6079.  
  6080. ═ULTI-╘ASKING ON THE ├=128 - ╨ART 2
  6081.  
  6082. ╘HIS ARTICLE WILL EXAMINE THE ACTUAL CODE THAT MAKES UP THE MULTI-TASKING
  6083. KERNAL IN DETAIL AND INCLUDE SOME EXAMPLE PROGRAMS EXPLAINING IT USE.
  6084.  
  6085. ╘HE 1351 ═OUSE ─EMYSTIFIED
  6086.  
  6087. ╘HIS ARTICLE WILL EXPLAIN HOW THE 1351 MOUSE WORKS AS WELL AS PROVIDE AN EASY
  6088. TO USE INTERFACE IN MACHINE LANGUAGE FOR BOTH BASIC AND MACHINE LANGUAGE
  6089. PROGRAMMERS.
  6090. ==============================================================================
  6091.  
  6092.  
  6093.