home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-02-12 | 65.5 KB | 1,809 lines |
- =============================================================================
- ╠╔╘╘╠┼ ╥┼─ ╥┼┴─┼╥: ═╙-─╧╙ FILE READER FOR THE 128 AND 1571/81 DRIVES.
-
- BY ├RAIG ┬RUCE <CSBRUCE@NEUMANN.UWATERLOO.CA>
-
- 1. ╔╬╘╥╧─╒├╘╔╧╬
-
- ╘HIS ARTICLE PRESENTS A PROGRAM THAT READS ═╙-─╧╙ FILES AND THE ROOT DIRECTORY
- OF ═╙-─╧╙ DISKS. ╘HE PROGRAM COPIES ONLY FROM DRIVE TO DRIVE WITHOUT
- BUFFERING FILE DATA INTERNALLY. ╘HIS IS SIMPLER AND IMPOSES NO LIMITS ON THE
- SIZE OF THE FILES TRANSFERRED, ALTHOUGH IT REQUIRES THE USE OF TWO DISK DRIVES
- (OR A LOGICAL DRIVE). ╘HE USER-INTERFACE CODE IS WRITTEN IN ┬┴╙╔├ AND
- PRESENTS A FULL-SCREEN FILE SELECTION MENU. ╘HE GRUNT-WORK CODE IS WRITTEN IN
- ASSEMBLY LANGUAGE AND OPERATES AT MAXIMUM VELOSITY.
-
- ╘HE ┬URST ├OMMAND ╔NSTRUCTION ╙ET OF THE 1571/81 IS USED TO READ THE ═╙-─╧╙
- DISK BLOCKS AND THE STANDARD KERNEL ROUTINES ARE USED FOR OUTPUTTING THE
- DATA. (╔ AM AN OPERATING SYSTEMS SPECIALIST, SO ╔ CALL IT A KERN┼L!) ╘HUS,
- THE ═╙-─╧╙ FILES MUST BE READ FROM A 1571 OR 1581 DISK DRIVE, BUT THE OUTPUT
- DEVICE MAY BE ANY DISK DRIVE TYPE, THE SCREEN OR A PRINTER, OR A VIRTUAL DRIVE
- TYPE SUCH AS ╥┴═╠INK, ╥┴═─RIVE, OR ╥┴═─╧╙ (FOR THE ╥┼╒). ╔T IS INTERESTING TO
- NOTE THAT THE DATA CAN BE READ IN FROM AN ═╙-─╧╙ DISK FASTER THAN IT CAN BE
- WRITTEN OUT TO A 1571, 1581, OR EVEN A ╥┴═─╧╙ FILE. ┴ ╥┴═╠INK CAN SWALLOW THE
- DATA ONLY SLIGHTLY FASTER THAN IT CAN BE READ.
-
- ╠ITTLE ╥ED ╥EADER (╠╥╥) SUPPORTS DOUBLE DENSITY 3.5" DISKS FORMATTED WITH 80
- TRACKS, 9 SECTORS PER TRACK, AND 2 SIDES WITH A 1581 AND 5.25" DOUBLE DENSITY
- DISKS FORMATTED WITH 40 TRACKS, 9 SECTORS PER TRACK, AND 2 SIDES WITH A 1571.
- ┴ LIMIT OF 128 DIRECTORY ENTRIES AND 3 ╞ILE ┴LLOCATION ╘ABLE (╞┴╘) SECTORS IS
- IMPOSED. ╘HERE MUST BE 2 COPIES OF THE ╞┴╘ AND THE CLUSTER SIZE MAY BE 1 OR 2
- SECTORS. ╘HE SECTOR SIZE MUST BE 512 BYTES.
-
- ╧H, ABOUT THE NAME. ╔T IS A PLAY ON THE NAME OF ANOTHER ═╙-─╧╙ FILE COPIER
- AVAILABLE FOR THE ├-128. "╠ITTLE" MEANS THAT IT IS SMALLER IN SCOPE THAN THE
- OTHER PROGRAM, AND "╥ED" IS A DIFFERENT PRIMARY COLOR TO AVOID ANY LEGAL
- COMPLICATIONS. ╔T IS ALSO THE NON-WHITE COLOR OF THE FLAG OF THE COUNTRY OF
- ORIGIN OF THIS PROGRAM (NO, ╔ AM NOT ╩APANESE). ┴LSO, THIS PROGRAM IS ╨UBLIC
- ─OMAIN ╙OFTWARE, AS IS ALL SOFTWARE ╔ DEVELOP FOR 8-BIT ├OMMODORE ├OMPUTERS.
- ╞EEL FREE TO ┼-MAIL ME IF YOU HAVE QUESTIONS OR COMMENTS ABOUT THIS ARTICLE.
-
- 2. ╒╙┼╥ ╟╒╔─┼
-
- ╠╧┴─ AND ╥╒╬ THE "LRR.128" ┬┴╙╔├ PROGRAM FILE. ╫HEN THE PROGRAM IS FIRST RUN,
- IT WILL DISPLAY AN "INITIALIZING" MESSAGE AND WILL LOAD IN THE BINARY MACHINE
- LANGUAGE PACKAGE FROM THE "CURRENT" ├OMMODORE ─╧╙ DRIVE (THE CURRENT DRIVE IS
- OBTAINED FROM ╨┼┼╦(186) - THE LAST DEVICE ACCESSED). ╘HE BINARY PACKAGE IS
- LOADED ONLY ON THE FIRST RUN AND IS NOT RELOADED ON SUBSEQUENT RUNS IF THE
- PACKAGE ╔─ FIELD IS IN PLACE.
-
- 2.1. ═┴╔╬ ╙├╥┼┼╬
-
- ╘HE MAIN SCREEN OF THE PROGRAM IS THEN DISPLAYED. ╘HE MAIN SCREEN OF THE
- PROGRAM WILL LOOK SOMETHING LIKE THIS:
-
- ═╙-─┼╓=9 ═╙-╘┘╨┼=1581 ├┬═-─┼╓=8
-
- ╬╒═ ╙ ╘╥╬ ╘┘╨ ╞╔╠┼╬┴═┼ ┼╪╘ ╠┼╬╟╘╚
- --- - --- --- -------- --- ------
- 1 * ┴╙├ ╙┼╤ ╚┴├╦4 ╘╪╘ 120732
- 2 ┬╔╬ ╨╥╟ ╥┴═─╧╙ ╙╞╪ 34923
-
- ─=─╔╥┼├╘╧╥┘ ═=═╙-─┼╓ ╞=├┬═-─┼╓ ╤=╤╒╔╘
- ╘=╘╧╟╟╠┼-├╧╠╒═╬, ├=├╧╨┘-╞╔╠┼╙, +/- ╨┴╟┼
-
- EXCEPT THAT IMMEDIATELY AFTER STARTING UP, "<NO FILES>" WILL BE DISPLAYED
- RATHER THAN FILENAMES. ╘HE "═╙-─┼╓" AND "═╙-╘┘╨┼" FIELDS GIVE THE DEVICE
- NUMBER AND TYPE OF THE DRIVE CONTAINING THE ═╙-─╧╙ DISK TO COPY FROM, AND THE
- "├┬═-─┼╓" GIVES THE DEVICE NUMBER OF THE DRIVE/VIRTUAL DRIVE/CHARACTER DEVICE
- TO COPY FILE DATA TO.
-
- ╔NFORMATION ABOUT ALL ═╙-─╧╙ FILES IN THE ROOT DIRECTORY OF THE ═╙-─╧╙ DISK IS
- DISPLAYED IN COLUMNS BELOW THE DRIVE INFORMATION. "╬╒═" GIVES THE NUMBER OF
- THE ═╙-─╧╙ FILE IN THE DIRECTORY LISTING, AND "╙" INDICATES WHETHER THE FILE
- IS "SELECTED" OR NOT. ╔F THE FILE IS SELECTED, AN ASTERISK (*) IS DISPLAYED;
- OTHERWISE, A BLANK IS DISPLAYED. ╫HEN YOU LATER ENTER ├OPY ═ODE, ONLY THE
- FILES THAT HAVE BEEN "SELECTED" ARE COPIED.
-
- ╘HE "╘╥╬" FIELD INDICATES THE CHARACTER TRANSLATION SCHEME TO BE USED WHEN THE
- FILE IS COPIED. ┴ VALUE OF "┬╔╬" (BINARY) MEANS NO TRANSLATION AND A VALUE OF
- "┴╙├" (ASCII) MEANS THE FILE CHARACTERS ARE TO BE TRANSLATED FROM ═╙-─╧╙ ┴╙├╔╔
- (OR "┴╙├╔╔-├R╠F") TO ╨┼╘╙├╔╔. ╘HE "╘┘╨" FIELD INDICATES THE TYPE OF
- ├OMMODORE-─╧╙ FILE TO CREATE FOR WRITING THE ═╙-─╧╙ FILE CONTENTS INTO. ╘HE
- POSSIBLE VALUES ARE "╙┼╤" (SEQUENTIAL) AND "╨╥╟" (PROGRAM). ╘HE VALUES OF THE
- ╘╥╬ AND ╘┘╨ FILEDS ARE SET INDEPENDENTLY, SO YOU CAN COPY BINARY DATA TO ╙┼╤
- FILES AND ASCII DATA TO ╨╥╟ FILES IF YOU WISH.
-
- ╘HE "╞╔╠┼╬┴═┼" AND "┼╪╘" FIELDS GIVE THE FILENAME AND EXTENSION TYPE OF THE
- ═╙-─╧╙ FILES AND "╠┼╬╟╘╚" GIVES THE EXACT LENGTH OF THE FILES IN BYTES. ╬OTE
- THAT IF YOU PERFORM "┴╙├" TRANSLATION ON A FILE, ITS ╨┼╘╙├╔╔ VERSION WILL HAVE
- A SHORTER LENGTH.
-
- 2.2. ╒╙┼╥ ├╧══┴╬─╙
-
- ╘HE BOTTOM OF THE SCREEN GIVES THE COMMAND SUMMARY. ┴FTER STARTING THE
- PROGRAM, YOU WILL WANT TO SETUP THE ═╙-─╧╙ AND ├┬═-─╧╙ DRIVES WITH THE "═" AND
- "╞" COMMANDS. ╙IMPLY PRESS THE (LETTER) KEY CORRESPONDING TO THE COMMAND
- NAME TO ACTIVATE THE COMMAND. ╨RESSING ═ WILL PROMPT YOU FOR THE ═╙-─╧╙ ─RIVE
- ╬UMBER AND THE ═╙-─╧╙ ─RIVE ╘YPE. ╔N BOTH CASES, TYPE THE NUMBER AND PRESS
- ╥┼╘╒╥╬. (╙ORRY FOR INSULTING ALL NON-NOVICES OUT THERE, BUT ╔ WANT TO BE
- COMPLETE). ╘HE ═╙-─╧╙ DRIVE NUMBER CANNOT BE THE SAME AS THE ├┬═-─╧╙ DRIVE
- NUMBER (SINCE THE PROGRAM COPIES FROM DRIVE-TO-DRIVE WITHOUT INTERNAL
- BUFFERING). ╞OR THE DRIVE TYPE, ENTER AN "8", "81", OR "1581" FOR A 1581
- DRIVE OR ANYTHING ELSE FOR A 1571 DRIVE.
-
- ╨RESSING ╞ WILL PROMPT YOU FOR THE ├┬═-─╧╙ DEVICE NUMBER. ┘OU MAY ENTER A
- NUMBER FROM 0 TO 30, EXCEPT THAT IT MUST NOT BE THE ═╙-─╧╙ DRIVE NUMBER.
- ┼NTER A "1" FOR ├ASSETTE ─RIVE (╟OD FORBID!), A "3" FOR THE SCREEN, A "4" FOR
- THE PRINTER (WITH AN AUTOMATIC SECONDARY ADDRESS OF 7 (LOWERCASE)), ANY NUMBER
- ABOVE 7 FOR A ├OMMODORE DISK DRIVE OR SPECIAL VIRTUAL DRIVE, OR A VALUE OF "0"
- FOR THE SPECIAL "NULL" DRIVE. ┴ ├┬═-─┼╓ VALUE OF 0 WILL CASE THE PROGRAM TO
- READ ═╙-─╧╙ FILES AND DO NOTHING WITH THE OUTPUT. ┘OU CAN USE THIS FEATURE TO
- CHECK OUT THE RAW READING SPEED OF THE PROGRAM.
-
- ┴FTER SETTING UP THE DRIVES, PRESS ─ TO READ IN THE ROOT DIRECTORY OFF THE
- ═╙-─╧╙ DISK. ╘HE DATA WILL COME BLAZING IN FROM THE DISK BUT ┬┴╙╔├ WILL TAKE
- ITS GOOD OLE TIME SIFTING THROUGH IT. ╞ILENAMES ARE DISPLAYED ON THE SCREEN
- AS THEY ARE SCANNED IN. ╘HE PROGRAM WILL (EVENTUALLY) RETURN TO THE MAIN
- SCREEN AND DISPLAY THE FORMATTED FILE INFORMATION. ╧NE NOTE: THE PROCESS OF
- LOGGING IN A 1581 ═╙-─╧╙ DISK TAKES ABOUT 12 SECONDS (ON MY 1581, ANYWAY), SO
- BE PATIENT. ┴N ═╙-─╧╙ DISK WILL HAVE TO BE "LOGGED IN" EVERY TIME YOU CHANGE
- ═╙-─╧╙ DISKS. (─ISKS ARE LOGGED IN AUTOMATICALLY).
-
- ┴ COUPLE OF NOTES ABOUT ACCESSING ═╙-─╧╙ DISKS: DON'T TRY TO ACCESS A DEVICE
- THAT IS NOT PRESENT BECAUSE THE MACHINE LANGUAGE ROUTINES CANNOT HANDLE THIS
- ERROR FOR SOME REASON AND WILL LOCK UP, REQUIRING A ╙╘╧╨+╥┼╙╘╧╥┼. ┴LSO, MAKE
- SURE THAT AN ACTUAL ═╙-─╧╙ DISK IS LOADED INTO THE DRIVE. ╔F YOU ACCIDENTALLY
- PLACE ├OMMODORE-─╧╙ DISK INTO THE ═╙-─╧╙ DRIVE, THE 1581 WILL REPORT AN
- INVALID BOOT PARAMETERS ERROR (#60), BUT A 1571 WILL LOCK UP (SINCE ╔ DON'T
- CHECK THE SECTOR SIZE AND MY BURST ROUTINES ARE EXPECTING 512 BYTES TO COME
- OUT OF A SECTOR WHEREAS ├OMMODORE DISKS HAVE ONLY 256 BYTES PER SECTOR).
-
- ╬OW YOU ARE READY TO PICK WHAT FILES YOU WANT COPIED AND HOW YOU WANT THEM
- COPIED. ┘OU WILL NOTICE THAT A "CURSOR" APPEARS IN THE "╙" COLUMN OF THE
- FIRST FILE. ┘OU MAY MOVE THE CURSOR AROUND WITH THE CURSOR KEYS: ╒╨, ─╧╫╬,
- ╠┼╞╘, ╥╔╟╚╘, ╚╧═┼, AND ├╠╥. ├╠╥ (╙╚╔╞╘-╚╧═┼) WILL MOVE THE CURSOR BACK TO THE
- FIRST FILE ON THE FIRST SCREEN. ┘OU CAN MOVE THE CURSOR AMONG THE SELECT,
- TRANSLATION, AND FILE-TYPE COLUMNS OF ALL THE FILES. ╨RESSING A ╙╨┴├┼ OR A
- ╥┼╘╒╥╬ WILL TOGGLE THE VALUE OF THE FIELD THAT THE CURSOR IS ON. ╘O TOGGLE
- ALL OF THE VALUES OF THE "CURSOR" COLUMN (INCLUDING FILES ON ALL OTHER
- SCREENS), PRESS ╘. ┘OU WILL NOTICE THAT MOVING THE CURSOR AROUND AND TOGGLING
- FIELDS IS A BIT SLUGGISH, ESPECIALLY IF YOU ARE IN ╙LOW MODE ON THE 40-COLUMN
- SCREEN. ─ID ╔ MENTION THAT THIS PROGRAM WILL RUN ON EITHER THE 40 OR
- 80-COLUMN SCREEN? ╘OGGLING AN ENTIRE COLUMN CAN TAKE A COUPLE OF SECONDS.
-
- ╔F THERE ARE MORE THAN 18 ═╙-─╧╙ FILES, YOU CAN PRESS THE "+" AND "-" KEYS TO
- MOVE AMONG ALL OF THE SCREENS OF FILES. ╘HE CURSOR MOVEMENT KEYS WILL WRAP
- AROUND ON THE CURRENT SCREEN. "+" IS PAGE FORWARD, AND "-" IS PAGE BACKWARD.
- ╘HE SCREENS WRAP AROUND TOO.
-
- ┴FTER YOU HAVE SELECTED ALL OF THE FILES YOU WANT TO COPY AND THEIR TRANSLATION
- AND FILE-TYPE FIELDS HAVE BEEN SET, PRESS THE ├ KEY TO GO INTO ├OPY ═ODE (NEXT
- SECTION). ┴FTER COPYING, YOU ARE RETURNED TO THE MAIN SCREEN WITH ALL OF THE
- FIELD SETTINGS STILL INTACT. ╘O EXIT FROM THE PROGRAM, PRESS ╤.
-
- 2.3. ├╧╨┘ ═╧─┼
-
- ╫HEN YOU ENTER COPY MODE, THE SCREEN WILL CLEAR AND THE NAME OF EACH SELECTED
- FILE IS DISPLAYED AS IT IS BEING COPIED. ╔F AN ERROR IS ENCOUNTERED ON EITHER
- THE ═╙-─╧╙ OR ├┬═-─╧╙ DRIVE DURING COPYING, AN ERROR MESSAGE WILL BE DISPLAYED
- AND COPYING WILL CONTINUE (AFTER YOU PRESS A KEY FOR ═╙-─╧╙ ERRORS).
-
- ╘O GENERATE A ├┬═-─╧╙ FILENAME FROM AN ═╙-─╧╙ FILENAME, THE EIGHT FILENAME
- CHARACTERS ARE TAKEN (INCLUDING SPACES) AND A DOT (.) AND THE THREE CHARACTERS
- OF THE EXTENSION ARE APPENDED. ╘HEN, ALL SPACES ARE REMOVED, AND IF THE NAME
- ENDS WITH A DOT (.) CHARACTER, THEN THAT DOT CHARACTER IS REMOVED AS WELL. ╔
- THINK THIS IS FAIRLY REASONABLE.
-
- ╔F THERE ALREADY IS A FILE WITH THE SAME FILENAME ON THE ├┬═-─╧╙ DISK, THEN
- YOU WILL BE PROMPTED IF YOU WANT TO OVERWRITE THE FILE OR NOT. ┼NTERING AN
- "N" WILL ABORT THE COPYING OF THAT FILE AND GO ON TO THE NEXT FILE, AND
- ENTERING A "Y" (OR ANYTHING ELSE) WILL CAUSE THE ├┬═-─╧╙ FILE TO BE
- "SCRATCHED" AND THEN RE-WRITTEN.
-
- ╘HE PHYSICAL COPYING OF THE FILE IS DONE COMPLETELY IN MACHINE LANGUAGE AND
- NOTHING IS DISPLAYED ON THE SCREEN WHILE THIS IS HAPPENING, BUT YOU CAN FOLLOW
- THINGS BY LOOKING AT DAS BLINKIN LICHTES AND LISTENING FOR CLICKS AND GRINDS.
- ┘OU WILL PROBABLY BE SURPRISED BY THE ═╙-─╧╙ FILE READING SPEED (╔ MEAN IN A
- GOOD WAY). ╘HE DISK DATA IS READ IN WHOLE TRACKS AND CACHED IN MEMORY AND THE
- DIRECTORY INFORMATION AND THE ╞┴╘ ARE RETAINED IN MEMORY AS WELL. ╘HE RESULT
- IS THAT MINIMAL TIME IS SPENT READING DISK DATA, AND NO COSTLY SEEKS ARE
- REQUIRED FOR OPENING A NEW ═╙-─╧╙ FILE. ┴ RESULT IS THAT SMALL FILES ARE
- COPIED ONE AFTER ANOTHER VERY QUICKLY. ┘OU WILL HAVE TO WAIT, HOWEVER, ON THE
- RELATIVELY SLOW STANDARD KERNEL/├OMMODORE-─╧╙ FILE WRITING.
-
- ┴ FEW CHANGES HAD TO BE MADE TO THE PROGRAM TO ACCOMODATE THE ╥┴═─╧╙ PROGRAM.
- ╥┴═─╧╙ USES MEMORY FROM $2300 TO $3╞╞╞ OF ╥┴═0, WHICH IS NOT REALLY A GOOD
- PLACE FOR A DEVICE DRIVER, AND IT USES SOME OF THE ZERO-PAGE LOCATIONS THAT ╔
- WANTED TO USE. ┬UT, DIFFICULTIES WERE OVERCOME. ╘HE IMPORTANCE OF ╥┴═─╧╙
- COMPATIBILITY IS THAT IF YOU ONLY HAVE ONE DISK DRIVE BUT YOU HAVE AN ╥┼╒, YOU
- CAN USE ╥┴═─╧╙ TO STORE THE ═╙-─╧╙ FILES TEMPORARILY. ╔F YOU ONLY HAVE ONE
- DISK DRIVE AND NO ╥┼╒, YOU ARE ╙╧╠ (╧UT OF ╠UCK) UNLESS YOU CAN GET A
- ╥AM─ISK-TYPE PROGRAM FOR AN UNEXPANDED 128. ╘HE ╥┴═─╧╙ PROGRAM IS AVAILABLE
- FROM ╞╘╨ SITE "CCOSUN.CALTECH.EDU" IN FILE "/PUB/RKNOP/UTIL128/RAMDOSII.SFX".
- ╧NE NOTE ╔ FOUND OUT ABOUT ╥┴═─╧╙: YOU CANNOT USE A
-
- ─╧╨┼╬#1,(├╞$),╒(├─),╫
-
- WITH IT LIKE YOU ARE SUPPOSED TO BE ABLE TO; YOU HAVE TO USE A
-
- ─╧╨┼╬#1,(├╞$+",╫"),╒(├─)
-
- ╚ERE IS A TABLE OF COPYING SPEEDS FOR COPYING FROM 1571S AND 1581S WITH ┴╙├
- AND ┬╔╬ TRANSLATION MODES. ┴LL FIGURES ARE IN BYTES/SECOND. ╘HESE RESULTS
- WERE OBTAINED FROM COPYING A 127,280 BYTE TEXT FILE (THE TEXT OF ├= ╚ACKING
- ╔SSUE #3).
-
- ╞╥╧═ \ ╘╧: "NULL" ╥┴═╠INK ╥┴═─╧╙ ╩─1581 ╩─1571
- -------+ ------ ------- ------ ------ ------
- 81-BIN ▄ 5772 3441 2146 N/A 644
- 81-ASC ▄ 5772 3434 2164 N/A 661
- 71-BIN ▄ 4323 2991 1949 1821 N/A
- 71-ASC ▄ 4323 2982 1962 1847 N/A
-
- ╘HE "NULL" DEVICE IS THAT "0" ├┬═-─╧╙ DEVICE NUMBER, AND A COUPLE OF ENTRIES
- ARE "N/A" SINCE ╔ ONLY HAVE ONE 1571 AND ONE 1581. ╬OTE THAT MY 71 AND 81 ARE
- ╩IFFY─╧╙-IFIED, SO THE PERFORMANCE OF A STOCK 71/81 WILL BE POORER. ╩IFFY─╧╙
- GIVES ABOUT A 2X PERFORMANCE IMPROVEMENT FOR THE STANDARD FILE ACCESSING CALLS
- (OPEN, CLOSE, CHRIN, CHROUT). ╥┴═─╧╙ DOESN'T SEEM TO BE AS SNAPPY AS YOU
- MIGHT THINK.
-
- ╘HE "NULL" FIGURES ARE QUITE IMPRESSIVE, BUT THE RAW SECTOR READING SPEED
- WITHOUT THE OVERHEAD OF MUCKING AROUND WITH FILE ORGANIZATION IS 6700
- BYTES/SEC FOR A 1581 AND 4600 ┬/S FOR A 71. ╘HE REASON THAT THE 1571 OPERATES
- SO QUICKLY IS THAT ╔ USE A SECTOR INTERLEAVE OF 4 (WHICH IS OPTIMAL) FOR
- READING THE TRACKS. ╔ THINK THAT OTHER ═╙-─╧╙ FILE COPIER PROGRAM USES AN
- INTERLEAVE OF 1 (WHICH IS NOT OPTIMAL). ╔ LOSE SOME OF THE RAW PERFORMANCE
- BECAUSE ╔ COPY THE FILE DATA INTERNALLY ONCE BEFORE OUTPUTTING IT (TO SIMPLIFY
- SOME OF THE CODE).
-
- ╔N A COUPLE OF PLACES YOU WILL NOTICE THAT ┴╙├ TRANSLATION GIVES SLIGHTLY
- BETTER OR SLIGHTLY WORSE PERFORMANCE THAN ┬╔╬. ╘HIS IS BECAUSE ALTHOUGH
- SLIGHTLY MORE WORK IS REQUIRED TO TRANSLATE THE CHARACTERS, SLIGHTLY FEWER
- CHARACTERS WILL HAVE TO BE WRITTEN TO THE ├┬═-─╧╙ FILE, SINCE ╨┼╘╙├╔╔ USES
- ONLY ├╥ WHERE ═╙-─╧╙ ┴╙├╔╔ USES ├╥ AND ╠╞ TO REPRESENT END-OF-LINE.
- ╘RANSLATION IS DONE BY USING A TABLE (THAT YOU CAN CHANGE IF YOU WISH). ═ANY
- ENTRIES IN THIS TABLE CONTAIN A VALUE OF ZERO, WHICH MEANS THAT NO CHARACTER
- WILL BE OUTPUT ON TRANSLATION. ═OST OF THE CONTROL CHARACTERS AND ALL OF THE
- CHARACTERS OF VALUE 128 (0X80) OR GREATER ARE THROWN AWAY ON BEING
- TRANSLATED. ╘HE TABLE IS SET UP SO THAT ├╥ CHARACTERS ARE THROWN AWAY AND THE
- ╠╞ CHARACTER IS TRANSLATED TO A ├┬═-─╧╙ ├╥ CHARACTER. ╘HUS, BOTH ═╙-─╧╙ ┴╙├╔╔
- FILES AND ╒╬╔╪ ┴╙├╔╔ FILES CAN BE TRANSLATED CORRECTLY.
-
- 2. ┬╒╥╙╘ ├╧══┴╬─╙
-
- ╘HREE BURST COMMANDS FROM THE 1571/81 DISK DRIVE ┬URST ├OMMAND ╔NSTRUCTION ╙ET
- ARE REQUIRED TO ALLOW THIS PROGRAM TO READ THE ═╙-─╧╙ DISKS: ╤UERY ─ISK
- ╞ORMAT, ╙ECTOR ╔NTERLEAVE, AND ╥EAD. ╘HE GRUNGY DETAILS ABOUT ISSUING BURST
- COMMANDS AND BURST MODE HANDSHAKING ARE COVERED IN ├= ╚ACKING ╔SSUE #3. ╘HE
- ╤UERY ─ISK ╞ORMAT COMMAND IS USED TO "LOG IN" THE ═╙-─╧╙ DISK. ╘HE ╔NQUIRE
- ─ISK BURST COMMAND CANNOT BE USED WITH AN ═╙-─╧╙ DISK ON THE 1581 FOR SOME
- UNKNOWN REASON. ╔ FOUND THIS OUT THE HARD WAY. ╘HE ╤UERY ─ISK ╞ORMAT COMMAND
- HAS THE FOLLOWING FORMAT:
-
- ┬┘╘┼ \ BIT: 7 6 5 4 3 2 1 0 ▄ ╓ALUE
- -------+--------+-----+-----+-----+-----+-----+-----+-----+-------
- 0 ▄ 0 ▄ 1 ▄ 0 ▄ 1 ▄ 0 ▄ 1 ▄ 0 ▄ 1 ▄ "╒"
- 1 ▄ 0 ▄ 0 ▄ 1 ▄ 1 ▄ 0 ▄ 0 ▄ 0 ▄ 0 ▄ "0"
- 2 ▄ ╞ ▄ ╪ ▄ ╪ ▄ ╙ ▄ 1 ▄ 0 ▄ 1 ▄ ╬ ▄ 10
- -------+--------------------------------------------------+-------
-
- WHERE THE ╞, ╙, AND ╬ BITS HAVE A VALUE OF 0 FOR OUR PURPOSES. ┴ RESPONSE OF
- A BURST STATUS BYTE AND SIX OTHER THROW-AWAY BYTES IS GIVEN FROM THE DRIVE.
- ╘HIS COMMAND TAKES QUITE A LONG TIME TO EXECUTE ON MY 1581 BUT WORKS QUITE
- QUICKLY ON MY 1571. ┘OU ONLY HAVE TO LOG IN A DISK WHENEVER YOU CHANGE
- DISKS.
-
- ╘HE ╙ECTOR ╔NTERLEAVE COMMAND IS USED TO SET A SOFT INTERLEAVE FOR THE ╥EAD
- COMMAND. ╔ USE AN INTERLEAVE OF 1 FOR THE 1581 AND AN INTERLEAVE OF 4 FOR THE
- 1571. ╘HIS MEANS THAT THE ═╙-─╧╙ SECTORS WILL COME FROM 1571 TO THE COMPUTER
- IN THE FOLLOWING ORDER: 1, 5, 9, 4, 8, 3, 7, 2, 6 (THERE ARE 9 SECTORS PER
- TRACK ON AN ═╙-─╧╙ DISK (BOTH 3.5" AND 5.25"), NUMBERED FROM 1 TO 9). ╠╥╥
- HANDLES THE DATA COMING IN IN THIS ORDER, AND IN STRAIGHT ORDER FROM THE
- 1581. ╘HE ╙ECTOR ╔NTERLEAVE COMMAND HAS THE FOLLOWING FORMAT, WHERE THE ╫ AND
- ╬ BITS ARE 0 FOR US:
-
- ┬┘╘┼ \ BIT: 7 6 5 4 3 2 1 0 ▄ ╓ALUE
- -------+--------+-----+-----+-----+-----+-----+-----+-----+-------
- 0 ▄ 0 ▄ 1 ▄ 0 ▄ 1 ▄ 0 ▄ 1 ▄ 0 ▄ 1 ▄ "╒"
- 1 ▄ 0 ▄ 0 ▄ 1 ▄ 1 ▄ 0 ▄ 0 ▄ 0 ▄ 0 ▄ "0"
- 2 ▄ ╫ ▄ ╪ ▄ ╪ ▄ 0 ▄ 1 ▄ 0 ▄ 0 ▄ ╬ ▄ 8
- 3 ▄ <INTERLEAVE> ▄ 1 OR 4
- -------+--------------------------------------------------+-------
-
- ╘HE ╥EAD COMMAND IS USED TO TRANSFER THE NINE SECTORS OF A TRACK TO THE
- COMPUTER IN THE ORDER SPECIFIED BY THE INTERLEAVE. ╘HE FORMAT IS:
-
- ┬┘╘┼ \ BIT: 7 6 5 4 3 2 1 0 ▄ ╓ALUE
- -------+--------+-----+-----+-----+-----+-----+-----+-----+-------
- 0 ▄ 0 ▄ 1 ▄ 0 ▄ 1 ▄ 0 ▄ 1 ▄ 0 ▄ 1 ▄ "╒"
- 1 ▄ 0 ▄ 0 ▄ 1 ▄ 1 ▄ 0 ▄ 0 ▄ 0 ▄ 0 ▄ "0"
- 2 ▄ ╘/╠ ▄ ┼ ▄ ┬/╪ ▄ ╙ ▄ 0 ▄ 0 ▄ 0 ▄ ╬ ▄ 0 OR 16
- 3 ▄ <TRACK> ▄ ???
- 4 ▄ <SECTOR> ▄ 1
- 5 ▄ <NUMBER OF SECTORS> ▄ 9
- -------+--------------------------------------------------+-------
-
- ╘HERE ARE A COUPLE OF DIFFERENCES BETWEEN THE 1571 AND 1581 VERSIONS OF THIS
- COMMAND. ═OST IMPORTANT, THE ╙ BIT (╙IDE OF DISK TO USE) HAS THE OPPOSITE
- MEANING ON THE TWO DRIVES. ╘HERE'S NO GOOD REASON THAT ╔ KNOW OF FOR THIS
- INCONSISTENCY. ╘HIS IS THE REASON THAT ╠╥╥ NEEDS TO KNOW WHAT TYPE OF ═╙-─╧╙
- DRIVE IT IS DEALING WITH (PLUS INTERLEAVING).
-
- ╘HE READ COMMAND RETURNS THE FOLLOWING DATA USING BURST MODE HANDSHAKING:
-
- +-------------------+
- 0 ▄ ┬URST ╙TATUS ┬YTE ▄
- +-------------------+
- 1 ▄ ▄
- ... + 512 ─ATA ┬YTES ▄
- 512 ▄ ▄
- +-------------------+
-
- FOR EACH SECTOR TRANSFERRED. ╔F THE ┬URST ╙TATUS ┬YTE INDICATES AN ERROR,
- THEN THE DATA IS NOT TRANSFERRED AND NONE OF THE FOLLOWING SECTORS ARE
- EITHER. ╔F THE STATUS BYTE GIVES A "─ISK ├HANGED" ERROR, THEN YOU HAVE TO LOG
- IN THE DISK WITH THE ╤UERY ─ISK ╞ORMAT COMMAND BEFORE READ WILL WORK
- PROPERLY. ╘HIS IS ACTUALLY A GOOD FEATURE SINCE IT LETS YOU KNOW ABOUT A DISK
- CHANGE SO YOU CAN UPDATE ANY DATA STRUCTURES YOU MAY HAVE. ╠╥╥ SIMPLY RE-LOGS
- IN THE DISK WITHOUT UPDATING ANY DATA STRUCTURES AND RE-TRIES THE FAILED READ
- OPERATION.
-
- 3. ═╙-─╧╙ ─╔╙╦ ╞╧╥═┴╘
-
- ┴N ═╙-─╧╙ DISK IS SEPARATED INTO 4 DIFFERENT PARTS: THE ┬OOT ╙ECTOR, THE
- ╞┴╘(S), THE ╥OOT ─IRECTORY, AND THE ╞ILE ─ATA ╙ECTORS. ╘HE LOGICAL SECTORS
- (BLOCKS) OF A DISK ARE NUMBERED FROM 0 TO SOME MAXIMUM NUMBER (1439 FOR A
- 3.5", 719 FOR A 5.25" ── DISK). ╘HE PHYSICAL LAYOUT AND THE LOGICAL SECTOR
- NUMBERS TYPICALLY USED BY A 3.5" DISK ARE SHOWN HERE:
-
- +-------------------+
- 0 ▄ ┬OOT ╙ECTOR ▄
- +-------------------+
- 1..3 ▄ ╞┴╘ COPY #1 ▄
- +-------------------+
- 4..6 ▄ ╞┴╘ COPY #2 ▄
- +-------------------+
- 7..14 ▄ ╥OOT ─IRECTORY ▄
- +-------------------+
- 15 ▄ ▄
- ... ▄ ╞ILE ─ATA ╙ECTORS ▄
- 1439 ▄ ▄
- +-------------------+
-
- 3.1. ╘╚┼ ┬╧╧╘ ╙┼├╘╧╥
-
- ╘HE ┬OOT ╙ECTOR IS ALWAYS AT LOGICAL SECTOR NUMBER 0. ╔T CONTAINS SOME
- IMPORTANT INFORMATION ABOUT THE FORMAT OF THE DISK AND IT ALSO CONTAINS CODE
- TO BOOT AN ═╙-─╧╙ MACHINE FROM. ╫E AREN'T CONCERNED WITH THE BOOTSTRAPPING
- CODE, BUT THE IMPORTANT VALUES WE NEED TO OBTAIN FROM THE BOOT SECTOR ARE:
-
- ┴┬┬╥ ╧╞╞╙┼╘ 1571 1581 ─┼╙├╥╔╨╘╔╧╬
- ---- ------ ---- ---- -----------
- ├╙ 13 2 2 ├LUSTER SIZE IN SECTORS
- ╬┬ 14 1 1 ╬UMBER OF BOOT SECTORS
- ╬╞ 16 2 2 ╬UMBER OF ╞┴╘S
- ╞╠ 23 2 3 ╞┴╘ SIZE IN SECTORS
- ─┼ 17 112 112 ╬UMBER OF ROOT DIRECTORY ENTRIES
- ╘╙ 19,20 720 1440 ╘OTAL ╬UMBER OF SECTORS
- ╬╙ 24 9 9 ╬UMBER OF SECTORS PER TRACK
- ╬╚ 26 2 2 ╬UMBER OF SIDES
-
- ╘HE 1571 AND 1581 COLUMNS GIVE THE TYPICAL VALUES OF THESE PARAMETERS FOR
- 5.25" AND 3.5" DISKS. ╘HE ╧╞╞╙┼╘ IS THE ADDRESS OF THE PARAMETER WITHIN THE
- BOOT SECTOR. ╘HE TOTAL NUMBER OF SECTORS IS GIVEN IN LOW-BYTE, HIGH-BYTE
- ORDER (SINCE THE 80X86 FAMILY IS LITTLE-ENDIAN LIKE THE 6502 FAMILY). ╞ROM
- THE ABOVE PARAMETERS, WE CAN DERIVE THE FOLLOWING IMPORTANT PARAMETERS:
-
- ┴┬┬╥ ╞╧╥═╒╠┴ 1571 1581 ─┼╙├╥╔╨╘╔╧╬
- ---- ------- ---- ---- -----------
- ╞1 ╬┬+╬╞*╞╠ 5 7 ╞IRST ROOT DIRECTORY SECTOR
- ╞╙ ╬┬+╬╞*╞╠+─┼ 12 14 ╞IRST FILE DATA SECTOR NUMBER
- ╬├ (╘╙-╞╙)/├╙ 354 713 ╘OTAL NUMBER OF FILE CLUSTERS
-
- ╠╥╥ IMPOSES A NUMBER OF LIMITS ON THESE PARAMETERS AND WILL ERROR-OUT IF YOU
- TRY TO USE A DISK THAT IS OUTSIDE OF ╠╥╥'S LIMITS.
-
- 3.2. ├╚┼╫╔╬╟ ╘╚┼ ╞┴╘
-
- ═╙-─╧╙ DISKS USE A DATA STRUCTURE CALLED A ╞ILE ┴LLOCATION ╘ABLE (╞┴╘) TO
- RECORD WHICH CLUSTERS BELONG TO WHICH FILE IN WHAT ORDER AND WHICH BLOCKS ARE
- FREE. ┴ CLUSTER IS A SET OF CONTIGUOUS SECTORS WHICH ARE ALLOCATED TO FILES
- AS A GROUP. ╠╥╥ HANDLES CLUSTER SIZES OF 1 AND 2 SECTORS, GIVING A LOGICAL
- FILE BLOCK SIZE OF 512 OR 1024 BYTES. ╘YPICALLY, A CLUSTER SIZE OF 2 SECTORS
- IS USED.
-
- ╘HE ╞┴╘ IS AN ARRAY OF 12-BIT NUMBERS, WITH AN ENTRY CORRESPONDING TO EACH
- CLUSTER THAT CAN BE ALLOCATED TO FILES. ╞┴╘ ENTRIES 0 AND 1 ARE RESERVED. ╔F
- A ╞┴╘ ENTRY CONTAINS A VALUE OF $000, THEN THE CORRESPONDING CLUSTER IS FREE
- AND CAN BE ALLOCATED TO A FILE; OTHERWISE, THE CLUSTER IS ALLOCATED AND THE
- ╞┴╘ ENTRY CONTAINS THE NUMBER OF THE ╬┼╪╘ ╞┴╘ ENTRY THAT BELONGS TO THE FILE.
- ╘HUS, ═╙-─╧╙ FILES ARE STORED IN A SINGLY-LINKED LIST OF CLUSTERS LIKE
- ├OMMODORE-─╧╙ FILES ARE, EXCEPT THAT THE LINKS ARE NOT IN THE DATA SECTORS BUT
- RATHER ARE IN THE ╞┴╘. ╘HE POINTER TO THE FIRST ╞┴╘ ENTRY FOR A FILE IS GIVEN
- IN THE FILE'S DIRECTORY ENTRY.
-
- ┴ SPECIAL ╬╒╠╠/╬╔╠ POINTER VALUE OF $╞╞╞ IS USED TO INDICATE THE END OF THE
- CHAIN OF CLUSTERS ALLOCATED TO A FILE. ╘HIS VALUE IS STORED IN THE ╞┴╘ ENTRY
- OF THE LAST CLUSTER ALLOCATED TO A FILE (OF COURSE). ├ONSIDER THE FOLLOWING
- EXAMPLE ╞┴╘:
-
- ┼╬╘╥┘ ╓┴╠╒┼
- ----- -----
- $000 $╞╞╞
- $001 $╞╞╞
- $002 ▄----$003 <------─IRECTORY ┼NTRY
- $003 +--> $005----+
- $004 $000 ▄
- $005 $╞╞╞ <--+
-
- ┼NTRIES 0 AND 1 ARE INSIGNIFICANT SINCE THEY ARE RESERVED. ╙AY THAT A FILE
- STARTS AT ╞┴╘ ENTRY #2. ╘HEN, IT CONSISTS OF THE FOLLOWING CHAIN OF CLUSTERS:
- 2, 3, AND 5. ├LUSTER #4 IS FREE. ├LUSTERS CAN BE ALLOCATED TO A FILE IN
- RANDOM ORDER, BUT IF THEY ARE ALLOCATED CONTIGUOUSLY IN FORWARD ORDER, THEN
- THE FILE WILL BE ABLE TO BE READ FASTER. ╘HE ╞┴╘ IS SUCH AN IMPORTANT DATA
- STRUCTURE THAT TYPICALLY TWO COPIES ARE KEPT ON THE DISK INCASE ONE OF THEM
- SHOULD BECOME CORRUPTED.
-
- ╘HE ═╙-─╧╙ DESIGNERS WERE A LITTLE SNEAKY IN STORING THE 12-BIT ╞┴╘ ENTRIES -
- THEY USED ONLY 12 REAL BITS PER ENTRY. ╔E., THEY STORE TWO ╞┴╘ ENTRIES IN
- THREE BYTES, WHERE THE TWO ENTRIES SHARE THE TWO NYBBLES OF THE MIDDLE BYTE.
- ╘HE FOLLOWING DIAGRAM SHOWS HOW THE NYBBLES 1 (HIGH), 2 (MID), AND 3 (LOW) ARE
- STORED INTO ╞┴╘ ENTRIES ┴ AND ┬:
-
- ┬┘╘┼: 0 1 2
- +---+---+ +---+---+ +---+---+
- ┼╬╘╥┘: ▄ ┴ ▄ ┴ ▄ ▄ ┬ ▄ ┴ ▄ ▄ ┬ ▄ ┬ ▄
- ╬┘┬┬╠┼: ▄ 2 ▄ 3 ▄ ▄ 3 ▄ 1 ▄ ▄ 1 ▄ 2 ▄
- +---+---+ +---+---+ +---+---+
-
- ┴NYWAY, LET'S JUST SAY IT'S A BIT TRICKY TO EXTRACT THE 12-BIT VALUES FROM
- THIS COMPRESSED DATA STRUCTURE. ╧N TOP OF THAT, ╔ DON'T THINK THERE IS ANY
- SAVING IN DISK SPACE RESULTING FROM COMPRESSING THIS STRUCTURE; THEY MIGHT AS
- WELL HAVE JUST USED A 16-BIT ╞┴╘ (LIKE THEY DO NOWADAYS ON LARGER DISKS).
-
- 3.3. ╘╚┼ ╥╧╧╘ ─╔╥┼├╘╧╥┘
-
- ╘HE ROOT DIRECTORY HAS A FIXED SIZE, ALTHOUGH ╔ DON'T THINK THAT
- SUBDIRECTORIES DO. ╠╥╥ CANNOT ACCESS SUBDIRECTORIES. ┼ACH 512-BYTE SECTOR OF
- THE ROOT DIRECTORY CONTAINS SIXTEEN 32-BYTE DIRECTORY ENTRIES. ╧NE DIRECTORY
- ENTRY IS REQUIRED FOR EACH FILE STORED ON THE DISK. ┴ DIRECTORY ENTRY HAS THE
- FOLLOWING STRUCTURE:
-
- ╧╞╞╙┼╘ ╠┼╬ ─┼╙├╥╔╨╘╔╧╬
- ------ --- -----------
- 0..7 8 ╞ILENAME
- 8..10 3 ┼XTENSION
- 11 1 <UNUSED?>
- 12 1 ┴TTRIBUTES: $10=─IRECTORY, $08=╓OLUME╔D
- 13..21 9 <UNUSED>
- 22..25 4 ─ATE
- 26..27 2 ╙TARTING ╞┴╘ ENTRY NUMBER
- 28..31 4 ╞ILE LENGTH IN BYTES
-
- ╘HE FILENAME AND EXTENSION ARE STORED WITH TRAILING PADDING SPACES. ╔F A
- DIRECTORY ENTRY IS UNUSED OR DELETED, THEN THE FIRST CHARACTER OF THE FILENAME
- IS EITHER A $00 OR A $┼5 (229). ╘HIS IS WHY YOU HAVE TO PROVIDE THE FIRST
- CHARACTER OF A FILENAME IF YOU ARE UNDELETING A FILE ON AN ═╙-─╧╙ MACHINE.
- ╬OTE THAT THERE IS ENOUGH UNUSED SPACE THAT ═ICROSOFT OR ╔┬═ COULD HAVE
- DITCHED THE ANNOYING 8+3 CHARACTER FILENAME FORMAT.
-
- ╘HE ATTRIBUTES BITS TELL WHETHER THE DIRECTORY ENTRY IS FOR A REGULAR FILE, A
- SUBDIRECTORY, A DISK VOLUME NAME (IN WHICH CASE THERE IS NO FILE DATA), AND A
- COUPLE OF OTHER THINGS ╔ CAN'T REMEMBER. ╔'M NOT SURE ABOUT THE EXACT
- POSITION OR FORMAT OF THE DATE, BUT ╠╥╥ DOESN'T USE IT ANYWAY. ╘HE STARTING
- ╞┴╘ ENTRY NUMBER AND THE FILE LENGTH ARE STORED IN LOWER-BYTE-FIRST ORDER.
-
- 3.4. ╘╚┼ ╞╔╠┼ ─┴╘┴ ╙╨┴├┼
-
- ╘HE RAMAINDER OF THE DISK SPACE IS USED FOR STORING FILE DATA IN CLUSTERS OF 1
- OR 2 SECTORS EACH. ╟IVEN A CLUSTER NUMBER (WHICH IS ALSO THE ╞┴╘ ENTRY
- NUMBER), THE FOLLOWING FORMULA IS USED TO CALCULATE THE STARTING LOGICAL
- SECTOR NUMBER OF THE CLUSTER:
-
- (├LUSTER╬UMBER - 2) * ├LUSTER╙IZE╔N┬LOCKS + ╞IRST╞ILE─ATA╠OGICAL╙ECTOR╬UMBER
-
- WHERE "╞IRST╞ILE─ATA╠OGICAL╙ECTOR╬UMBER" IS THE "╞╙" PARAMETER DERIVED
- EARLIER. ╘HE FOLLOWING CONSECUTIVE LOGICAL SECTOR NUMBERS UP TO THE NUMBER OF
- SECTORS PER CLUSTER FORM THE REST OF THE CLUSTER. ╬OTE THAT A SINGLE CLUSTER
- CAN SPAN SECTORS FROM ONE SIDE OF THE DISK TO ANOTHER OR FROM ONE TRACK TO
- ANOTHER. ╫E PERFORM THE "(├LUSTER╬UMBER - 2)" PORTION OF THE CALCULATION
- SINCE THE FIRST TWO ╞┴╘ ENTRIES ARE RESERVED.
-
- ╙INCE THE ╥EAD BURST COMMAND OF THE 1571/81 WANTS THE SIDE, TRACK, AND SECTOR
- NUMBER OF A SECTOR RATHER THAN ITS LOGICAL NUMBER, WE ALSO NEED FORMULAE FOR
- THESE CONVERSIONS:
-
- ╘RACK = ╠OGICAL╙ECTOR╬UMBER / 18
- ╙ECTOR = ╠OGICAL╙ECTOR╬UMBER % 9 + 1
- ╙IDE = (╠OGICAL╙ECTOR╬UMBER / 9) % 2
-
- ╘HESE FORMULAE ARE MORE PROBLEMATIC THAN THE PREVIOUS ONE SINCE THEY REQUIRE
- DIVISION BY 9 AND 18. ╠╥╥ USES THE METHOD OF REPEATED SUBTRACTION TO PERFROM
- THE NECESSARY DIVISION (ONLY ONE DIVISION IS NECESSARY). ╘HE ABOVE FORMULAE
- IMPLY THAT SEQUENTIAL LOGICAL SECTORS ARE STORED ON THE TOP OF THE DISK
- FIRST AND THEN THE BOTTOM OF THE DISK OF THE SAME TRACK, AND THEN ON THE TOP
- OF THE NEXT TRACK, ETC. ╘HIS IS A GOOD SECTOR NUMBERING SCHEME (UNLIKE THE
- ├┬═-─╧╙ SCHEME FOR 1571 SECTORS) SINCE IT IS FASTER TO SWITCH SIDES OF THE
- DISK THAN IT IS TO SWITCH TRACKS, SO YOU CAN READ THE DISK FASTER.
-
- ╧H YEAH, THE WAY THAT YOU KNOW HOW MANY FILE DATA BYTES ARE IN THE LAST
- CLUSTER OF A FILE CHAIN (THE CLUSTER WITH THE ╬╒╠╠ ╞┴╘ ENTRY) IS TO TAKE THE
- FILE LENGTH FROM THE DIRECTORY ENTRY AND "MOD" (THE ├ LANGUAGE % OPERATOR) IT
- WITH THE CLUSTER SIZE. ╧NE SPECIAL CASE IS IF THIS CALCULATION RESULTS IN A
- ZERO, THEN THE LAST CLUSTER IS COMPLETELY FULL (RATHER THAN COMPLETELY EMPTY
- AS THE CALCULATION WOULD SUGGEST). ╘HIS CALCULATION IS EASILY DONE IN
- MACHINE LANGUAGE WITH AN ┴╬─ OPERATION SINCE THE CLUSTER SIZE IS ALWAYS A
- POWER OF TWO.
-
- 4. ╞╔╠┼ ├╧╨┘╔╬╟ ╨┴├╦┴╟┼
-
- ╘HIS SECTION DISCUSSES THE INTERFACE TO AND IMPLEMENTATION OF THE ═╙-─╧╙ FILE
- COPYING PACKAGE. ╔T IS WRITTEN IN ASSEMBLY LANGUAGE AND IS LOADED INTO MEMORY
- AT ADDRESS $8000 ON BANK 0 AND REQUIRES ABOUT 13╦ OF MEMORY. ╘HE PACKAGE IS
- LOADED AT THIS HIGH ADDRESS TO BE OUT OF THE WAY OF THE MAIN ┬┴╙╔├ PROGRAM,
- EVEN IF ╥┴═─╧╙ IS INSTALLED.
-
- 4.1. ╔╬╘┼╥╞┴├┼
-
- ╘HE SUBROUTINE CALL AND PARAMETER PASSING INTERFACE TO THE FILE COPYING
- PACKAGE IS SUMMARIZED AS FOLLOWS:
-
- ┴──╥┼╙╙ ─┼╙├╥╔╨╘╔╧╬
- ------- -----------
- ╨╦ ╔NIT╨ACKAGE SUBROUTINE
- ╨╦+3 ╠OAD─IRECTORY SUBROUTINE
- ╨╦+6 ├OPY╞ILE SUBROUTINE
- ╨╦+9 TWO-BYTE PACKAGE IDENTIFICATION NUMBER
- ╨╦+15 ERRNO : ERROR CODE RETURNED
- ╨╦+16 ═╙-─╧╙ DEVICE NUMBER (8 TO 30)
- ╨╦+17 ═╙-─╧╙ DEVICE TYPE ($00=1571, $╞╞=1581)
- ╨╦+18 TWO-BYTE STARTING CLUSTER NUMBER FOR FILE COPYING
- ╨╦+20 LOW AND MID BYTES OF FILE LENGTH FOR COPYING
-
- WHERE "╨╦" IS THE LOAD ADDRESS OF THE PACKAGE. ┴DDITIONAL SUBROUTINE
- PARAMETERS ARE PASSED IN THE PROCESSOR REGISTERS.
-
- ╘HE "╔NIT╨ACKAGE" SUBROUTINE SHOULD BE CALLED WHEN THE PACKAGE IS FIRST
- INSTALLED, WHENEVER THE ═╙-─╧╙ DEVICE NUMBER IS CHANGED, AND WHENEVER A NEW
- DISK IS MOUNTED TO INVALIDATE THE INTERNAL TRACK CACHE. ╔T REQUIRES NO
- PARAMETERS.
-
- ╘HE "╠OAD─IRECTORY" SUBROUTINE WILL LOAD THE DIRECTORY, ╞┴╘, AND THE ┬OOT
- ╙ECTOR PARAMETERS INTO THE INTERNAL MEMORY OF THE PACKAGE FROM THE CURRENT
- ═╙-─╧╙ DEVICE NUMBER. ╬O (OTHER) INPUT PARAMETERS ARE NEEDED AND THE
- SUBROUTINE RETURNS A POINTER TO THE DIRECTORY SPACE IN THE .┴┘ REGISTERS AND
- THE NUMBER OF DIRECTORY ENTRIES IN THE .╪ REGISTER. ╔F AN ERROR OCCURS, THEN
- THE SUBROUTINE RETURNS WITH THE ├ARRY FLAG SET AND THE ERROR CODE IS AVAILABLE
- IN THE "ERRNO" INTERFACE VARIABLE. ╘HE DIRECTORY ENTRY DATA IS IN THE
- DIRECTORY SPACE AS IT WAS READ IN RAW FROM THE DIRECTORY SECTORS ON THE ═╙-─╧╙
- DISK.
-
- ╘HE "├OPY╞ILE" SUBROUTINE WILL COPY A SINGLE FILE FROM THE ═╙-─╧╙ DISK TO A
- SPECIFIED ├┬═-╦ERNAL LOGICAL FILE NUMBER (THE ├┬═ FILE MUST ALREADY BE
- OPENED). ╔F THE ├┬═ LOGICAL FILE NUMBER IS ZERO, THEN THE FILE DATA IS SIMPLY
- DISCARDED AFTER IT IS READ FROM THE ═╙-─╧╙ FILE. ╘HE STARTING CLUSTER NUMBER
- OF THE FILE TO COPY AND THE LOW AND MID BYTES OF THE FILE LENGTH ARE PASSED IN
- THE ╨╦+18 AND ╨╦+20 INTERFACE WORDS. ╘HE TRANSLATION MODE TO USE IS PASSED IN
- THE .┴ REGISTER ($00=BINARY, $╞╞=ASCII) AND THE ├┬═ LOGICAL FILE NUMBER TO
- OUTPUT TO IS PASSED IN THE .╪ REGISTER. ╔F AN ERROR OCCURS, THE ROUTINE
- RETURNS WITH THE ├ARRY FLAG SET AND THE ERROR CODE IN THE "ERRNO" INTERFACE
- VARIABLE. ╘HERE ARE NO OTHER OUTPUT PARAMETERS.
-
- ╬OTE THAT SINCE THE STARTING CLUSTER NUMBER AND LOW-FILE LENGTH OF THE FILE TO
- BE COPIED ARE REQUIRED RATHER THAN THE FILENAME, IT IS THE RESPONSIBILITY OF
- THE FRONT-END APPLICATION PROGRAM TO DIG THROUGH THE RAW DIRECTORY SECTOR DATA
- TO GET THIS INFORMATION. ╘HE APPLICATION MUST ALSO OPEN THE ├OMMODORE-─╧╙
- FILE OF WHATEVER FILETYPE ON WHATEVER DEVICE IS REQUIRED; THE PACKAGE DOES NOT
- NEED TO KNOW THE ├OMMODORE-─╧╙ DEVICE NUMBER.
-
- ╘HE ═╙-─╧╙ DEVICE NUMBER AND DEVICE TYPE INTERFACE VARIABLES ALLOW YOU TO SET
- THE ═╙-─╧╙ DRIVE AND THE PACKAGE IDENTIFICATION NUMBER ALLOWS THE APPLICATION
- PROGRAM TO CHECK IF THE PACKAGE IS ALREADY LOADED INTO MEMORY SO THAT IT ONLY
- HAS TO LOAD THE PACKAGE THE FIRST TIME THE APPLICATION IS RUN AND NOT ON
- RE-RUNS. ╘HE IDENTIFICATION SEQUENCE IS A VALUE OF $├┬ FOLLOWED BY A VALUE
- OF 131.
-
- 4.2. ╔═╨╠┼═┼╬╘┴╘╔╧╬
-
- ╘HIS SECTION PRESENTS THE CODE THAT IMPLEMENTS THE ═╙-─╧╙ FILE READING
- PACKAGE. ╔T IS HERE IN A SPECIAL FORM; EACH CODE LINE IS PRECEDED BY A FEW
- SPECIAL CHARACTERS AND THE LINE NUMBER. ╘HE SPECIAL CHARACTERS ARE THERE TO
- ALLOW YOU TO EASILY EXTRACT THE ASSEMBLER CODE FROM THE REST OF THIS MAGAZINE
- (AND ALL OF MY UGLY COMMENTS). ╧N A ╒NIX SYSTEM, ALL YOU HAVE TO DO IS
- EXECUTE THE FOLLOWING COMMAND LINE (SUBSTITUTE FILENAMES AS APPROPRIATE):
-
- GREP '^\.%...\!' ╚ACK4 ▄ SED 'S/^.%...\!..//' ▄ SED 'S/.%...\!//' >LRR.S
-
- ┘OU'LL NOTICE THAT THE INITIAL COMMENT LINES HERE WERE AN AFTERTHOUGHT.
-
- .%000! ;╠ITTLE ╥ED ╥EADER ═╙-─╧╙ FILE COPIER PROGRAM
- .%000! ;WRITTEN 92/10/03 BY ├RAIG ┬RUCE FOR ├= ╚ACKING ╬ET ═AGAZINE
- .%000!
-
- ╘HE CODE IS WRITTEN FOR THE ┬UDDY ASSEMBLER AND HERE ARE A COUPLE SETUP
- DIRECTIVES. ╬OTE THAT MY COMMENTS COME BEFORE THE SECTION OF CODE.
-
- .%001! .ORG $8000
- .%002! .OBJ "@:LRR.BIN"
- .%003!
- .%004! ;====JUMP TABLE AND PARAMETERS INTERFACE ====
- .%005!
- .%006! JMP INIT╨ACKAGE
- .%007! JMP LOAD─IRECTORY
- .%008! JMP COPY╞ILE
- .%009!
- .%010! .BYTE $CB,131 ;IDENTIFICATION
- .%011! .BYTE 0,0,0,0
- .%012!
-
- ╘HESE VARIABLES ARE INCLUDED IN THE PACKAGE PROGRAM SPACE TO MINIMIZE UNWANTED
- INTERACTION WITH OTHER PROGRAMS LOADED AT THE SAME TIME, SUCH AS THE ╥┴═─╧╙
- DEVICE DRIVER.
-
- .%013! ERRNO .BUF 1 ;(LOCATION PK+15)
- .%014! SOURCE─EVICE .BUF 1
- .%015! SOURCE╘YPE .BUF 1 ;$00=1571, $FF=1581
- .%016! START├LUSTER .BUF 2
- .%017! LEN═╠ .BUF 2 ;LENGTH MEDIUM AND LOW BYTES
- .%018!
- .%019! ;====GLOBAL DECLARAIONS====
- .%020!
- .%021! KERNEL╠ISTEN = $FFB1
- .%022! KERNEL╙ECOND = $FF93
- .%023! KERNEL╒NLSN = $FFAE
- .%024! KERNEL┴CPTR = $FFA2
- .%025! KERNEL├IOUT = $FFA8
- .%026! KERNEL╙PINP = $FF47
- .%027! KERNEL├HKOUT = $FFC9
- .%028! KERNEL├LRCHN = $FFCC
- .%029! KERNEL├HROUT = $FFD2
- .%030!
- .%031! ST = $D0
- .%032! CIA├LOCK = $DD00
- .%033! CIA╞LAGS = $DC0D
- .%034! CIA─ATA = $DC0C
- .%035!
-
- ╘HESE ARE THE PARAMETERS AND DERIVED PARAMETERS FROM THE BOOT SECTOR. ╘HEY
- ARE KEPT IN THE PROGRAM SPACE TO AVOID INTERACTIONS.
-
- .%036! CLUSTER┬LOCK├OUNT .BUF 1 ;1 OR 2
- .%037! FAT┬LOCKS .BUF 1 ;UP TO 3
- .%038! ROOT─IR┬LOCKS .BUF 1 ;UP TO 8
- .%039! ROOT─IR┼NTRIES .BUF 1 ;UP TO 128
- .%040! TOTAL╙ECTORS .BUF 2 ;UP TO 1440
- .%041! FIRST╞ILE┬LOCK .BUF 1
- .%042! FIRST╥OOT─IR┬LOCK .BUF 1
- .%043! FILE├LUSTER├OUNT .BUF 2
- .%044!
-
- ╘HE CYLINDER (TRACK) AND SIDE THAT IS CURRENTLY STORED IN THE TRACH CACHE.
-
- .%045! BUF├YLINDER .BUF 1
- .%046! BUF╙IDE .BUF 1
- .%047! FORMAT╨ARMS .BUF 6
- .%048!
-
- ╘HIS PACKAGE IS SPLIT INTO A NUMBER OF LEVELS. ╘HIS LEVEL INTERFACES WITH THE
- ╦ERNAL SERIAL BUS ROUTINES AND THE BURST COMMAND PROTOCOL OF THE DISK DRIVES.
-
- .%049! ;====HARDWARE LEVEL====
- .%050!
-
- ├ONNECT TO THE ═╙-─╧╙ DEVICE AND SEND THE "╒0" BURST COMMAND PREFIX AND THE
- BURST COMMAND BYTE.
-
- .%051! SEND╒0 = * ;( .┴=BURST├OMMAND├ODE ) : .├╙=ERR
- .%052! PHA
- .%053! LDA #0
- .%054! STA ST
- .%055! LDA SOURCE─EVICE
- .%056! JSR KERNEL╠ISTEN
- .%057! LDA #$6F
- .%058! JSR KERNEL╙ECOND
- .%059! LDA #"U"
- .%060! JSR KERNEL├IOUT
- .%061! BIT ST
- .%062! BMI SEND╒0┼RROR
- .%063! LDA #"0"
- .%064! JSR KERNEL├IOUT
- .%065! PLA
- .%066! JSR KERNEL├IOUT
- .%067! BIT ST
- .%068! BMI SEND╒0┼RROR
- .%069! CLC
- .%070! RTS
- .%071!
- .%072! SEND╒0┼RROR = *
- .%073! LDA #5
- .%074! STA ERRNO
- .%075! SEC
- .%076! RTS
- .%077!
-
- ╘OGGLE THE "─ATA ┴CCEPTED / ╥EADY ╞OR ═ORE" CLOCK SIGNAL FOR THE BURST
- TRANSFER PROTOCOL.
-
- .%078! TOGGLE├LOCK = *
- .%079! LDA CIA├LOCK
- .%080! EOR #$10
- .%081! STA CIA├LOCK
- .%082! RTS
- .%083!
-
- ╫AIT FOR A BURST BYTE TO ARRIVE IN THE SERIAL DATA REGISTER OF ├╔┴#1 FROM THE
- FAST SERIAL BUS.
-
- .%084! SERIAL╫AIT = *
- .%085! LDA #$08
- .%086! - BIT CIA╞LAGS
- .%087! BEQ -
- .%088! RTS
- .%089!
-
- ╫AIT FOR AND GET A BURST BYTE FROM THE FAST SERIAL BUS, AND SEND THE "─ATA
- ┴CCEPTED" SIGNAL.
-
- .%090! GET┬URST┬YTE = *
- .%091! JSR SERIAL╫AIT
- .%092! LDX CIA─ATA
- .%093! JSR TOGGLE├LOCK
- .%094! TXA
- .%095! RTS
- .%096!
-
- ╙END THE BURST COMMANDS TO "LOG IN" THE ═╙-─╧╙ DISK AND SET THE ╥EAD SECTOR
- INTERLEAVE FACTOR.
-
- .%097! MOUNT─ISK = * ;() : .├╙=ERR
- .%098! LDA #%00011010
- .%099! JSR SEND╒0
- .%100! BCC +
- .%101! RTS
- .%102! + JSR KERNEL╒NLSN
- .%103! BIT ST
- .%104! BMI SEND╒0┼RROR
- .%105! CLC
- .%106! JSR KERNEL╙PINP
- .%107! BIT CIA╞LAGS
- .%108! JSR TOGGLE├LOCK
- .%109! JSR GET┬URST┬YTE
- .%110! STA ERRNO
- .%111! AND #$0F
- .%112! CMP #2
- .%113! BCS MOUNT┼XIT
-
- ╟RAB THE THROW-AWAY PARAMETERS FROM THE MOUNT OPERATION.
-
- .%114! LDY #0
- .%115! - JSR GET┬URST┬YTE
- .%116! STA FORMAT╨ARMS,Y
- .%117! INY
- .%118! CPY #6
- .%119! BCC -
- .%120! CLC
-
- ╙ET THE SECTOR INTERLEAVE TO 1 FOR A 1581 OR 4 FOR A 1571.
-
- .%121! ;** SET INTERLEAVE
- .%122! LDA #%00001000
- .%123! JSR SEND╒0
- .%124! BCC +
- .%125! RTS
- .%126! + LDA #1 ;INTERLEAVE OF 1 FOR 1581
- .%127! BIT SOURCE╘YPE
- .%128! BMI +
- .%129! LDA #4 ;INTERLEAVE OF 4 FOR 1571
- .%130! + JSR KERNEL├IOUT
- .%131! JSR KERNEL╒NLSN
- .%132! MOUNT┼XIT = *
- .%133! RTS
- .%134!
-
- ╥EAD ALL OF THE SECTORS OF A GIVEN TRACK INTO THE TRACK CACHE.
-
- .%135! BUFPTR = 2
- .%136! SECNUM = 4
- .%137!
- .%138! READ╘RACK = * ;( .┴=CYLINDER, .╪=SIDE ) : TRACKBUF, .├╙=ERR
- .%139! PHA
- .%140! TXA
-
- ╟ET THE SIDE AND PUT IT INTO THE COMMAND BYTE. ╥EMEMBER THAT WE HAVE TO FLIP
- THE SIDE BIT FOR A 1581.
-
- .%141! AND #$01
- .%142! ASL
- .%143! ASL
- .%144! ASL
- .%145! ASL
- .%146! BIT SOURCE╘YPE
- .%147! BPL +
- .%148! EOR #$10
- .%149! + JSR SEND╒0
- .%150! BCC +
- .%151! RTS
- .%152! + PLA ;CYLINDER NUMBER
- .%153! JSR KERNEL├IOUT
- .%154! LDA #1 ;START SECTOR NUMBER
- .%155! JSR KERNEL├IOUT
- .%156! LDA #9 ;SECTOR COUNT
- .%157! JSR KERNEL├IOUT
- .%158! JSR KERNEL╒NLSN
-
- ╨REPARE TO RECEIVE THE TRACK DATA.
-
- .%159! SEI
- .%160! CLC
- .%161! JSR KERNEL╙PINP
- .%162! BIT CIA╞LAGS
- .%163! JSR TOGGLE├LOCK
- .%164! LDA #<TRACKBUF
- .%165! LDY #>TRACKBUF
- .%166! STA BUFPTR
- .%167! STY BUFPTR+1
-
- ╟ET THE SECTOR DATA FOR EACH OF THE 9 SECTORS OF THE TRACK.
-
- .%168! LDA #0
- .%169! STA SECNUM
- .%170! - BIT SOURCE╘YPE
- .%171! BMI +
-
- ╔F WE ARE DEALING WITH A 1571, WE HAVE TO SET THE BUFFER POINTER FOR THE NEXT
- SECTOR, TAKING INTO ACCOUNT THE SOFT INTERLEAVE OF 4.
-
- .%172! JSR GET1571┬UF╨TR
- .%173! + JSR READ╙ECTOR
- .%174! BCS TRACK┼XIT
- .%175! INC SECNUM
- .%176! LDA SECNUM
- .%177! CMP #9
- .%178! BCC -
- .%179! CLC
- .%180! TRACK┼XIT = *
- .%181! CLI
- .%182! RTS
- .%183!
-
- ╟ET THE BUFFER POINTER FOR THE NEXT 1571 SECTOR.
-
- .%184! GET1571┬UF╨TR = *
- .%185! LDA #<TRACKBUF
- .%186! STA BUFPTR
- .%187! LDX SECNUM
- .%188! CLC
- .%189! LDA #>TRACKBUF
- .%190! ADC BUFPTR1571,X
- .%191! STA BUFPTR+1
- .%192! RTS
- .%193!
- .%194! BUFPTR1571 = *
- .%195! .BYTE 0,8,16,6,14,4,12,2,10
- .%196!
-
- ╥EAD AN INDIVIDUAL SECTOR INTO MEMORY AT THE SPECIFIED ADDRESS.
-
- .%197! READ╙ECTOR = * ;( BUFPTR ) : .├╙=ERR
-
- ╟ET AND CHECK THE BURST STATUS BYTE FOR ERRORS.
-
- .%198! JSR GET┬URST┬YTE
- .%199! STA ERRNO
- .%200! AND #$0F
- .%201! CMP #2
- .%202! BCC +
- .%203! RTS
- .%204! + LDX #2
- .%205! LDY #0
- .%206!
-
- ╥ECEIVE THE 512 SECTOR DATA BYTES INTO MEMORY.
-
- .%207! READ┬YTE = *
- .%208! LDA #$08
- .%209! - BIT CIA╞LAGS
- .%210! BEQ -
- .%211! LDA CIA├LOCK
- .%212! EOR #$10
- .%213! STA CIA├LOCK
- .%214! LDA CIA─ATA
- .%215! STA (BUFPTR),Y
- .%216! INY
- .%217! BNE READ┬YTE
- .%218! INC BUFPTR+1
- .%219! DEX
- .%220! BNE READ┬YTE
- .%221! RTS
- .%222!
-
- ╘HIS NEXT LEVEL OF ROUTINES DEALS WITH LOGICAL SECTORS AND THE TRACK CACHE
- RATHER THAN WITH HARDWARE.
-
- .%223! ;====LOGICAL SECTOR LEVEL====
- .%224!
-
- ╔NVALIDATE THE TRACK CACHE IF THE ═╙-─╧╙ DRIVE NUMBER IS CHANGED OR IF A NEW
- DISK IS INSERTED. ╘HIS ROUTINE HAS TO ESTABLISH A ╥┴═ CONFIGURATION OF $0┼
- SINCE IT WILL BE CALLED FROM ╥┴═0. ├ONFIGURATION $0┼ GIVES ╥┴═0 FROM $0000 TO
- $┬╞╞╞, ╦ERNAL ╥╧═ FROM $├000 TO $╞╞╞╞, AND THE ╔/╧ SPACE OVER THE ╦ERNAL FROM
- $─000 TO $─╞╞╞. ╘HIS CONFIGURATION IS SET BY ALL APPLICATION INTERFACE
- SUBROUTINES.
-
- .%225! INIT╨ACKAGE = *
- .%226! LDA #$0E
- .%227! STA $FF00
- .%228! LDA #$FF
- .%229! STA BUF├YLINDER
- .%230! STA BUF╙IDE
- .%231! CLC
- .%232! RTS
- .%233!
-
- ╠OCATE A SECTOR (BLOCK) IN THE TRACK CACHE, OR READ THE CORRESPONDING PHYSICAL
- TRACK INTO THE TRACK CACHE IF NECESSARY. ╘HIS ROUTINE ACCEPTS THE CYLINDER,
- SIDE, AND SECTOR NUMBERS OF THE BLOCK.
-
- .%234! SECTOR╙AVE = 5
- .%235!
- .%236! READ┬LOCK = * ;( .┴=CYLINDER,.╪=SIDE,.┘=SECTOR ) : .┴┘=BLK╨TR,.├╙=ERR
-
- ├HECK IF THE CORRECT TRACK IS IN THE TRACK CACHE.
-
- .%237! CMP BUF├YLINDER
- .%238! BNE READ┬LOCK╨HYSICAL
- .%239! CPX BUF╙IDE
- .%240! BNE READ┬LOCK╨HYSICAL
-
- ╔F SO, THEN LOCATE THE SECTOR'S ADDRESS AND RETURN THAT.
-
- .%241! DEY
- .%242! TYA
- .%243! ASL
- .%244! CLC
- .%245! ADC #>TRACKBUF
- .%246! TAY
- .%247! LDA #<TRACKBUF
- .%248! CLC
- .%249! RTS
- .%250!
-
- ╚ERE, WE HAVE TO READ THE PHYSICAL TRACK INTO THE TRACK CACHE. ╫E SAVE THE
- INPUT PARAMETERS AND CALL THE HARDWARE-LEVEL TRACK-READING ROUTINE.
-
- .%251! READ┬LOCK╨HYSICAL = *
- .%252! STA BUF├YLINDER
- .%253! STX BUF╙IDE
- .%254! STY SECTOR╙AVE
- .%255! JSR READ╘RACK
-
- ├HECK FOR ERRORS.
-
- .%256! BCC READ┬LOCK╨HYSICAL╧K
- .%257! LDA ERRNO
- .%258! AND #$0F
- .%259! CMP #11 ;DISK CHANGE
- .%260! BEQ +
- .%261! SEC
- .%262! RTS
-
- ╔F THE ERROR THAT HAPPENED IS A "─ISK ├HANGE" ERROR, THEN MOUNT THE DISK AND
- TRY TO READ THE PHYSICAL TRACK AGAIN.
-
- .%263! + JSR MOUNT─ISK
- .%264! LDA BUF├YLINDER
- .%265! LDX BUF╙IDE
- .%266! LDY SECTOR╙AVE
- .%267! BCC READ┬LOCK╨HYSICAL
- .%268! RTS
- .%269!
-
- ╚ERE, THE PHYSICAL TRACK HAS BEEN READ INTO THE TRACK CACHE OK, SO WE RECOVER
- THE ORIGINAL INPUT PARAMETERS AND TRY THE TOP OF THE ROUTINE AGAIN.
-
- .%270! READ┬LOCK╨HYSICAL╧K = *
- .%271! LDA BUF├YLINDER
- .%272! LDX BUF╙IDE
- .%273! LDY SECTOR╙AVE
- .%274! JMP READ┬LOCK
- .%275!
-
- ─IVIDE THE GIVEN NUMBER BY 18. ╘HIS IS NEEDED FOR THE CALCULATIONS TO CONVERT
- A LOGICAL SECTOR NUMBER TO THE CORRESPONDING PHYSICAL CYLINDER, SIDE, AND
- SECTOR NUMBERS THAT THE LOWER-LEVEL ROUTINES REQUIRE. ╘HE METHOD OF REPEATED
- SUBTRACTION IS USED. ╘HIS ROUTINE WOULD PROBABLY WORK FASTER IF WE TRIED TO
- REPEATEDLY SUBTRACT 360 (18*20) AT THE TOP, BUT ╔ DIDN'T BOTHER.
-
- .%276! DIVIDE┬Y18 = * ;( .┴┘=NUMBER ) : .┴=QUOTIENT, .┘=REMAINDER
- .%277! ;** COULD REPEATEDLY SUBTRACT 360 HERE
- .%278! LDX #$FF
- .%279! - INX
- .%280! SEC
- .%281! SBC #18
- .%282! BCS -
- .%283! DEY
- .%284! BPL -
- .%285! CLC
- .%286! ADC #18
- .%287! INY
- .%288! TAY
- .%289! TXA
- .%290! RTS
- .%291!
-
- ├ONVERT THE GIVEN LOGICAL BLOCK NUMBER TO THE CORRESPONDING PHYSICAL CYLINDER,
- SIDE, AND SECTOR NUMBERS. ╘HIS ROUTINE FOLLOWS THE FORMULAE GIVEN EARLIER
- WITH A FEW SIMPLIFYING TRICKS.
-
- .%292! CONVERT╠OGICAL┬LOCK╬UM = * ;( .┴┘=BLOCK╬UM ) : .┴=CYL, .╪=SIDE, .┘=SEC
- .%293! JSR DIVIDE┬Y18
- .%294! LDX #0
- .%295! CPY #9
- .%296! BCC +
- .%297! PHA
- .%298! TYA
- .%299! SBC #9
- .%300! TAY
- .%301! PLA
- .%302! LDX #1
- .%303! + INY
- .%304! RTS
- .%305!
-
- ├OPY A SEQUENTIAL GROUP OF LOGICAL SECTORS INTO MEMORY. ╘HIS ROUTINE IS USED
- BY THE DIRECTORY LOADING ROUTINE TO LOAD THE ╞┴╘ AND ╥OOT ─IRECTORY, AND IS
- USED BY THE CLUSTER READING ROUTINE TO RETRIEVE ALL OF THE BLOCKS OF A
- CLUSTER. ┴FTER THE GIVEN STARTING LOGICAL SECTOR NUMBER IS CONVERTED INTO ITS
- PHYSICAL CYLINDER, SIDE, AND SECTOR EQUIVALENT, THE PHYSICAL VALUES ARE
- INCREMENTED TO GET THE ADDRESS OF SUCCESSIVE SECTORS OF THE GROUP. ╘HIS
- AVOIDS THE OVERHEAD OF THE LOGICAL TO PHYSICAL CONVERSION. ╤UITE A NUMBER OF
- TEMPORARIES ARE NEEDED.
-
- .%306! DEST╨TR = 6
- .%307! CUR├YLINDER = 8
- .%308! CUR╙IDE = 9
- .%309! CUR╙ECTOR = 10
- .%310! BLOCK├OUNTDOWN = 11
- .%311! SOURCE╨TR = 12
- .%312!
- .%313! COPY┬LOCKS = * ;( .┴┘=START┬LOCK, .╪=BLOCK├OUNT, ($6)=DEST ) : .├╙=ERR
- .%314! STX BLOCK├OUNTDOWN
- .%315! JSR CONVERT╠OGICAL┬LOCK╬UM
- .%316! STA CUR├YLINDER
- .%317! STX CUR╙IDE
- .%318! STY CUR╙ECTOR
- .%319!
- .%320! COPY┬LOCK╠OOP = *
- .%321! LDA CUR├YLINDER
- .%322! LDX CUR╙IDE
- .%323! LDY CUR╙ECTOR
- .%324! JSR READ┬LOCK
- .%325! BCC +
- .%326! RTS
- .%327! + STA SOURCE╨TR
- .%328! STY SOURCE╨TR+1
- .%329! LDX #2
- .%330! LDY #0
-
- ╚ERE ╔ UNROLL THE COPYING LOOP A LITTLE BIT TO CUT THE OVERHEAD OF THE BRANCH
- INSTRUCTION IN HALF. (┴ CYCLE SAVED... YOU KNOW).
-
- .%331! - LDA (SOURCE╨TR),Y
- .%332! STA (DEST╨TR),Y
- .%333! INY
- .%334! LDA (SOURCE╨TR),Y
- .%335! STA (DEST╨TR),Y
- .%336! INY
- .%337! BNE -
- .%338! INC SOURCE╨TR+1
- .%339! INC DEST╨TR+1
- .%340! DEX
- .%341! BNE -
-
- ╔NCREMENT THE CYLINDER, SIDE, SECTOR VALUES.
-
- .%342! INC CUR╙ECTOR
- .%343! LDA CUR╙ECTOR
- .%344! CMP #10
- .%345! BCC +
- .%346! LDA #1
- .%347! STA CUR╙ECTOR
- .%348! INC CUR╙IDE
- .%349! LDA CUR╙IDE
- .%350! CMP #2
- .%351! BCC +
- .%352! LDA #0
- .%353! STA CUR╙IDE
- .%354! INC CUR├YLINDER
- .%355! + DEC BLOCK├OUNTDOWN
- .%356! BNE COPY┬LOCK╠OOP
- .%357! CLC
- .%358! RTS
- .%359!
-
- ╥EAD A CLUSTER INTO THE ├LUSTER ┬UFFER, GIVEN THE CLUSTER NUMBER. ╘HE CLUSTER
- NUMBER IS CONVERTED TO A LOGICAL SECTOR NUMBER AND THEN THE SECTOR COPYING
- ROUTINE IS CALLED. ╘HE FORMULA GIVEN EARLIER IS USED FOR THE CONVERSION.
-
- .%360! READ├LUSTER = * ;( .┴┘=CLUSTER╬UMBER ) : CLUSTER┬UF, .├╙=ERR
- .%361! ;** CONVERT CLUSTER NUMBER TO LOGICAL BLOCK NUMBER
- .%362! SEC
- .%363! SBC #2
- .%364! BCS +
- .%365! DEY
- .%366! + LDX CLUSTER┬LOCK├OUNT
- .%367! CPX #1
- .%368! BEQ +
- .%369! ASL
- .%370! STY 7
- .%371! ROL 7
- .%372! LDY 7
- .%373! + CLC
- .%374! ADC FIRST╞ILE┬LOCK
- .%375! BCC +
- .%376! INY
- .%377!
- .%378! ;** READ LOGICAL BLOCKS COMPRISING CLUSTER
- .%379! + LDX #<CLUSTER┬UF
- .%380! STX 6
- .%381! LDX #>CLUSTER┬UF
- .%382! STX 7
- .%383! LDX CLUSTER┬LOCK├OUNT
- .%384! JMP COPY┬LOCKS
- .%385!
-
- ╘HIS NEXT LEVEL OF ROUTINES DEAL WITH THE DATA STRUCTURES OF THE ═╙-─╧╙ DISK
- FORMAT.
-
- .%386! ;====═╙-─╧╙ FORMAT LEVEL====
- .%387!
- .%388! BOOT┬LOCK = 2
- .%389!
-
- ╥EAD THE DISK FORMAT PARAMETERS, DIRECTORY, AND ╞┴╘ INTO MEMORY.
-
- .%390! LOAD─IRECTORY = * ;( ) : .┴┘=DIRBUF, .╪=DIR┼NTRIES, .├╙=ERR
- .%391! LDA #$0E
- .%392! STA $FF00
- .%393!
-
- ╥EAD THE BOOT SECTOR AND EXTRACT THE PARAMETERS.
-
- .%394! ;** GET PARAMETERS FROM BOOT SECTOR
- .%395! LDA #0
- .%396! LDY #0
- .%397! JSR CONVERT╠OGICAL┬LOCK╬UM
- .%398! JSR READ┬LOCK
- .%399! BCC +
- .%400! RTS
- .%401! + STA BOOT┬LOCK
- .%402! STY BOOT┬LOCK+1
- .%403! LDY #13 ;GET CLUSTER SIZE
- .%404! LDA (BOOT┬LOCK),Y
- .%405! STA CLUSTER┬LOCK├OUNT
- .%406! CMP #3
- .%407! BCC +
- .%408!
-
- ╔F A DISK PARAMETER IS FOUND TO EXCEED THE LIMITS OF ╠╥╥, ERROR CODE #60 IS
- RETURNED.
-
- .%409! INVALID╨ARMS = *
- .%410! LDA #60
- .%411! STA ERRNO
- .%412! SEC
- .%413! RTS
- .%414!
- .%415! + LDY #16 ;CHECK ╞┴╘ REPLICATION COUNT, MUST BE 2
- .%416! LDA (BOOT┬LOCK),Y
- .%417! CMP #2
- .%418! BNE INVALID╨ARMS
- .%419! LDY #22 ;GET ╞┴╘ SIZE IN SECTORS
- .%420! LDA (BOOT┬LOCK),Y
- .%421! STA FAT┬LOCKS
- .%422! CMP #4
- .%423! BCS INVALID╨ARMS
- .%424! LDY #17 ;GET DIRECTORY SIZE
- .%425! LDA (BOOT┬LOCK),Y
- .%426! STA ROOT─IR┼NTRIES
- .%427! CMP #129
- .%428! BCS INVALID╨ARMS
- .%429! LSR
- .%430! LSR
- .%431! LSR
- .%432! LSR
- .%433! STA ROOT─IR┬LOCKS
- .%434! LDY #19 ;GET TOTAL SECTOR COUNT
- .%435! LDA (BOOT┬LOCK),Y
- .%436! STA TOTAL╙ECTORS
- .%437! INY
- .%438! LDA (BOOT┬LOCK),Y
- .%439! STA TOTAL╙ECTORS+1
- .%440! LDY #24 ;CHECK SECTORS PER TRACK, MUST BE 9
- .%441! LDA (BOOT┬LOCK),Y
- .%442! CMP #9
- .%443! BNE INVALID╨ARMS
- .%444! LDY #26
- .%445! LDA (BOOT┬LOCK),Y
- .%446! CMP #2 ;CHECK NUMBER OF SIDES, MUST BE 2
- .%447! BNE INVALID╨ARMS
- .%448! LDY #14 ;CHECK NUMBER OF BOOT SECTORS, MUST BE 1
- .%449! LDA (BOOT┬LOCK),Y
- .%450! CMP #1
- .%451! BNE INVALID╨ARMS
- .%452!
-
- ├ALCULATE THE DERIVED PARAMETERS.
-
- .%453! ;** GET DERIVED PARAMETERS
- .%454! LDA FAT┬LOCKS ;FIRST ROOT DIRECTORY SECTOR
- .%455! ASL
- .%456! CLC
- .%457! ADC #1
- .%458! STA FIRST╥OOT─IR┬LOCK
- .%459! CLC ;FIRST FILE SECTOR
- .%460! ADC ROOT─IR┬LOCKS
- .%461! STA FIRST╞ILE┬LOCK
- .%462! LDA TOTAL╙ECTORS ;NUMBER OF FILE CLUSTERS
- .%463! LDY TOTAL╙ECTORS+1
- .%464! SEC
- .%465! SBC FIRST╞ILE┬LOCK
- .%466! BCS +
- .%467! DEY
- .%468! + STA FILE├LUSTER├OUNT
- .%469! STY FILE├LUSTER├OUNT+1
- .%470! LDA CLUSTER┬LOCK├OUNT
- .%471! CMP #2
- .%472! BNE +
- .%473! LSR FILE├LUSTER├OUNT+1
- .%474! ROR FILE├LUSTER├OUNT
- .%475!
-
- ╟EE, ╔ HAVE MORE COMMENTS EMBEDDED IN THE CODE THAN ╔ DID LAST ISSUE.
-
- .%476! ;** LOAD ╞┴╘
- .%477! + LDA #<FATBUF
- .%478! LDY #>FATBUF
- .%479! STA 6
- .%480! STY 7
- .%481! LDA #1
- .%482! LDY #0
- .%483! LDX FAT┬LOCKS
- .%484! JSR COPY┬LOCKS
- .%485! BCC +
- .%486! RTS
- .%487!
- .%488! ;** LOAD ACTUAL DIRECTORY
- .%489! + LDA #<DIRBUF
- .%490! LDY #>DIRBUF
- .%491! STA 6
- .%492! STY 7
- .%493! LDA FIRST╥OOT─IR┬LOCK
- .%494! LDY #0
- .%495! LDX ROOT─IR┬LOCKS
- .%496! JSR COPY┬LOCKS
- .%497! BCC +
- .%498! RTS
- .%499! + LDA #<DIRBUF
- .%500! LDY #>DIRBUF
- .%501! LDX ROOT─IR┼NTRIES
- .%502! CLC
- .%503! RTS
- .%504!
-
- ╘HIS ROUTINE LOCATES THE GIVEN ╞┴╘ TABLE ENTRY NUMBER AND RETURNS THE VALUE
- STORED IN IT. ╙OME WORK IS NEEDED TO DEAL WITH THE 12-BIT COMPRESSED DATA
- STRUCTURE.
-
- .%505! ENTRY┴DDR = 2
- .%506! ENTRY╫ORK = 4
- .%507! ENTRY┬ITS = 5
- .%508! ENTRY─ATA0 = 6
- .%509! ENTRY─ATA1 = 7
- .%510! ENTRY─ATA2 = 8
- .%511!
- .%512! GET╞AT┼NTRY = * ;( .┴┘=FAT┼NTRY╬UMBER ) : .┴┘=FAT┼NTRY╓ALUE
- .%513! STA ENTRY┬ITS
-
- ─IVIDE THE ╞┴╘ ENTRY NUMBER BY TWO AND MULTIPLY BY THREE BECAUSE TWO ╞┴╘
- ENTRIES ARE STORED IN THREE BYTES. ╘HEN ADD THE ╞┴╘ BASE ADDRESS AND WE HAVE
- THE ADDRESS OF THE THREE BYTES THAT CONTAIN THE ╞┴╘ ENTRY WE ARE INTERESTED
- IN. ╔ RETRIEVE THE THREE BYTES INTO ZERO-PAGE MEMORY FOR EASY MANIPULATION.
-
- .%514! ;** DIVIDE BY TWO
- .%515! STY ENTRY┴DDR+1
- .%516! LSR ENTRY┴DDR+1
- .%517! ROR
- .%518!
- .%519! ;** TIMES THREE
- .%520! STA ENTRY╫ORK
- .%521! LDX ENTRY┴DDR+1
- .%522! ASL
- .%523! ROL ENTRY┴DDR+1
- .%524! CLC
- .%525! ADC ENTRY╫ORK
- .%526! STA ENTRY┴DDR
- .%527! TXA
- .%528! ADC ENTRY┴DDR+1
- .%529! STA ENTRY┴DDR+1
- .%530!
- .%531! ;** ADD BASE, GET DATA
- .%532! CLC
- .%533! LDA ENTRY┴DDR
- .%534! ADC #<FATBUF
- .%535! STA ENTRY┴DDR
- .%536! LDA ENTRY┴DDR+1
- .%537! ADC #>FATBUF
- .%538! STA ENTRY┴DDR+1
- .%539! LDY #2
- .%540! - LDA (ENTRY┴DDR),Y
- .%541! STA ENTRY─ATA0,Y
- .%542! DEY
- .%543! BPL -
- .%544! LDA ENTRY┬ITS
- .%545! AND #1
- .%546! BNE +
- .%547!
-
- ╔F THE ORIGINAL GIVEN ╞┴╘ ENTRY NUMBER IS EVEN, THEN WE WANT THE FIRST 12-BIT
- COMPRESSED FIELD. ╘HE NYBBLES ARE EXTRACTED ACCORDING TO THE DIAGRAM SHOWN
- EARLIER.
-
- .%548! ;** CASE 1: FIRST 12-BIT CLUSTER
- .%549! LDA ENTRY─ATA1
- .%550! AND #$0F
- .%551! TAY
- .%552! LDA ENTRY─ATA0
- .%553! RTS
- .%554!
-
- ╧THERWISE, WE WANT THE SECOND 12-BIT FIELD.
-
- .%555! ;** CASE 2: SECOND 12-BIT CLUSTER
- .%556! + LDA ENTRY─ATA1
- .%557! LDX #4
- .%558! - LSR ENTRY─ATA2
- .%559! ROR
- .%560! DEX
- .%561! BNE -
- .%562! LDY ENTRY─ATA2
- .%563! RTS
- .%564!
-
- ╞INALLY, THIS IS THE FILE COPYING LEVEL. ╔T DEALS WITH READING THE CLUSTERS
- OF ═╙-─╧╙ FILES AND COPYING THE DATA THEY CONTAIN TO THE ALREADY-OPEN ├┬═
- ╦ERNAL FILE, POSSIBLY WITH ┴╙├╔╔-TO-╨┼╘╙├╔╔ TRANSLATION.
-
- .%565! ;====FILE COPY LEVEL====
- .%566!
- .%567! TRANS═ODE = 14
- .%568! LFN = 15
- .%569! CBM─ATA╨TR = $60
- .%570! CBM─ATA╠EN = $62
- .%571! CLUSTER = $64
- .%572!
-
- ├OPY THE GIVEN CLUSTER TO THE ├┬═ OUTPUT FILE. ╘HIS ROUTINE FETCHES THE NEXT
- CLUSTER OF THE FILE FOR THE NEXT TIME THIS ROUTINE IS CALLED, AND IF IT HITS
- THE ╬╒╠╠ POINTER OF THE LAST CLUSTER OF A FILE, IT ADJUSTS THE NUMBER OF VALID
- FILE DATA BYTES THE CURRENT CLUSTER CONTAINS TO ╞ILE╠ENGTH % ├LUSTER╠ENGTH
- (SEE NOTE BELOW).
-
- .%573! COPY╞ILE├LUSTER = * ;( CLUSTER, LFN, TRANS═ODE ) : .├╙=ERR
-
- ╥EAD THE CLUSTER AND SETUP TO COPY THE WHOLE CLUSTER TO THE ├┬═ FILE.
-
- .%574! LDA CLUSTER
- .%575! LDY CLUSTER+1
- .%576! JSR READ├LUSTER
- .%577! BCC +
- .%578! RTS
- .%579! + LDA #<CLUSTER┬UF
- .%580! LDY #>CLUSTER┬UF
- .%581! STA CBM─ATA╨TR
- .%582! STY CBM─ATA╨TR+1
- .%583! LDA #0
- .%584! STA CBM─ATA╠EN
- .%585! LDA CLUSTER┬LOCK├OUNT
- .%586! ASL
- .%587! STA CBM─ATA╠EN+1
- .%588!
-
- ╞ETCH THE NEXT CLUSTER NUMBER OF THE FILE, AND ADJUST THE CLUSTER DATA LENGTH
- FOR THE LAST CLUSTER OF THE FILE.
-
- .%589! ;**GET NEXT CLUSTER
- .%590! LDA CLUSTER
- .%591! LDY CLUSTER+1
- .%592! JSR GET╞AT┼NTRY
- .%593! STA CLUSTER
- .%594! STY CLUSTER+1
- .%595! CMP #$FF
- .%596! BNE COPY╞ILE├LUSTER─ATA
- .%597! CPY #$0F
- .%598! BNE COPY╞ILE├LUSTER─ATA
- .%599! LDA LEN═╠
- .%600! STA CBM─ATA╠EN
- .%601! LDA #$01
- .%602! LDX CLUSTER┬LOCK├OUNT
- .%603! CPX #1
- .%604! BEQ +
- .%605! LDA #$03
- .%606! + AND LEN═╠+1
-
- ╘HE FOLLOWING THREE LINES WERE ADDED IN A LAST MINUTE PANIC AFTER REALIZING
- THAT IF ╞ILE╠ENGTH % ├LUSTER╙IZE == 0, THEN THE LAST CLUSTER OF THE FILE
- CONTAINS ├LUSTER╙IZE BYTES, NOT ZERO BYTES.
-
- .%000! BNE +
- .%000! LDX LEN═╠
- .%000! BEQ COPY╞ILE├LUSTER─ATA
- .%607! + STA CBM─ATA╠EN+1
- .%608!
- .%609! COPY╞ILE├LUSTER─ATA = *
- .%610! JSR COMMIE╧UT
- .%611! RTS
- .%612!
-
- ├OPY THE FILE DATA IN THE ═╙-─╧╙ CLUSTER BUFFER TO THE ├┬═ OUTPUT FILE.
-
- .%613! CBM─ATA╠IMIT = $66
- .%614!
- .%615! COMMIE╧UT = * ;( CBM─ATA╨TR, CBM─ATA╠EN ) : .├╙=ERR
-
- ╔F THE THE LOGICAL FILE NUMBER TO COPY TO IS 0 ("NULL DEVICE"), THEN DON'T
- BOTHER COPYING ANYTHING.
-
- .%616! LDX LFN
- .%617! BNE +
- .%618! CLC
- .%619! RTS
-
- ╧THERWISE, PREPARE THE LOGICAL FILE NUMBER FOR OUTPUT.
-
- .%620! + JSR KERNEL├HKOUT
- .%621! BCC COMMIE╧UT═ORE
- .%622! STA ERRNO
- .%623! RTS
- .%624!
- .%625! COMMIE╧UT═ORE = *
-
- ╨ROCESS THE CLUSTER DATA IN CHUNKS OF UP TO 255 BYTES OR THE NUMBER OF DATA
- BYTES REMAINING IN THE CLUSTER.
-
- .%626! LDA #255
- .%627! LDX CBM─ATA╠EN+1
- .%628! BNE +
- .%629! LDA CBM─ATA╠EN
- .%630! + STA CBM─ATA╠IMIT
- .%631! LDY #0
- .%632! - LDA (CBM─ATA╨TR),Y
- .%633! BIT TRANS═ODE
- .%634! BPL +
-
- ╔F WE HAVE TO TRANSLATE THE CURRENT ┴╙├╔╔ CHARACTER, LOOK UP THE ╨┼╘╙├╔╔ VALUE
- IN THE TRANSLATION TABLE AND OUTPUT THAT VALUE. ╔F THE TRANSLATION TABLE
- ENTRY VALUE IS $00, THEN DON'T OUTPUT A CHARACTER (FILTER OUT INVALID
- CHARACTER CODES).
-
- .%635! TAX
- .%636! LDA TRANS┬UF,X
- .%637! BEQ COMMIE╬EXT
- .%638! + JSR KERNEL├HROUT
- .%639! COMMIE╬EXT = *
- .%640! INY
- .%641! CPY CBM─ATA╠IMIT
- .%642! BNE -
- .%643!
-
- ╔NCREMENT THE CLUSTER BUFFER POINTER AND DECREMENT THE CLUSTER BUFFER CHARACTER
- COUNT ACCORDING TO THE NUMBER OF BYTES JUST PROCESSED, AND REPEAT THE ABOVE IF
- MORE FILE DATA REMAINS IN THE CURRENT CLUSTER.
-
- .%644! CLC
- .%645! LDA CBM─ATA╨TR
- .%646! ADC CBM─ATA╠IMIT
- .%647! STA CBM─ATA╨TR
- .%648! BCC +
- .%649! INC CBM─ATA╨TR+1
- .%650! + SEC
- .%651! LDA CBM─ATA╠EN
- .%652! SBC CBM─ATA╠IMIT
- .%653! STA CBM─ATA╠EN
- .%654! BCS +
- .%655! DEC CBM─ATA╠EN+1
- .%656! + LDA CBM─ATA╠EN
- .%657! ORA CBM─ATA╠EN+1
- .%658! BNE COMMIE╧UT═ORE
-
- ╔F WE ARE FINISHED WITH THE CLUSTER, THEN CLEAR THE ├┬═ ╦ERNAL OUTPUT CHANNEL.
-
- .%659! JSR KERNEL├LRCHN
- .%660! CLC
- .%661! RTS
- .%662!
-
- ╘HE FILE COPYING MAIN ROUTINE. ╙ET UP FOR THE STARTING CLUSTER, AND CALL
- THE CLUSTER COPYING ROUTINE UNTIL END-OF-FILE IS REACHED. ├HECKS FOR A
- ╬╒╠╠ CLUSTER POINTER IN THE DIRECTORY ENTRY TO HANDLE ZERO-LENGTH FILES.
-
- .%663! COPY╞ILE = * ;( START├LUSTER, LEN═╠, .┴=TRANS═ODE, .╪=LFN ) : .├╙=ERR
- .%664! LDY #$0E
- .%665! STY $FF00
- .%666! STA TRANS═ODE
- .%667! STX LFN
- .%668! LDA START├LUSTER
- .%669! LDY START├LUSTER+1
- .%670! STA CLUSTER
- .%671! STY CLUSTER+1
- .%672! JMP +
- .%673! - JSR COPY╞ILE├LUSTER
- .%674! BCC +
- .%675! RTS
- .%676! + LDA CLUSTER
- .%677! CMP #$FF
- .%678! BNE -
- .%679! LDA CLUSTER+1
- .%680! CMP #$0F
- .%681! BNE -
- .%682! CLC
- .%683! RTS
- .%684!
-
- ╘HIS IS THE TRANSLATION TABLE USED TO CONVERT FROM ┴╙├╔╔ TO ╨┼╘╙├╔╔. ┘OU CAN
- MODIFY IT TO SUIT YOUR NEEDS IF YOU WISH. ╔F YOU CANNOT REASSEMBLE THIS FILE,
- THEN YOU CAN SIFT THROUGH THE BINARY FILE AND LOCATE THE TABEL AND CHANGE IT
- THERE. ┴N ENTRY OF $00 MEANS THE CORRESPONDING ┴╙├╔╔ CHARACTER WILL NOT BE
- TRANSLATED. ┘OU'LL NOTICE THAT ╔ HAVE SET UP TRANSLATIONS FOR THE FOLLOWING
- ┴╙├╔╔ CONTROL CHARACTERS INTO ╨┼╘╙├╔╔: ┬ACKSPACE, ╘AB, ╠INEFEED (├╥), AND
- ╞ORMFEED. ╔ ALSO TRANSLATE THE NON-╨┼╘╙├╔╔ CHARACTERS SUCH AS █, ▄, ▐, AND _
- ACCORDING TO WHAT THEY PROBABLY WOULD HAVE BEEN IF ├OMMODORE WASN'T SO
- CONCERNED WITH THE GRAPHICS CHARACTERS.
-
- .%685! TRANS┬UF = *
- .%686! ;0 1 2 3 4 5 6 7 8 9 A B C D E F
- .%687! .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$14,$09,$0D,$00,$93,$00,$00,$00 ;0
- .%688! .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;1
- .%689! .BYTE $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F ;2
- .%690! .BYTE $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F ;3
- .%691! .BYTE $40,$C1,$C2,$C3,$C4,$C5,$C6,$C7,$C8,$C9,$CA,$CB,$CC,$CD,$CE,$CF ;4
- .%692! .BYTE $D0,$D1,$D2,$D3,$D4,$D5,$D6,$D7,$D8,$D9,$DA,$5B,$5C,$5D,$5E,$5F ;5
- .%693! .BYTE $C0,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4A,$4B,$4C,$4D,$4E,$4F ;6
- .%694! .BYTE $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5A,$DB,$DC,$DD,$DE,$DF ;7
- .%695! .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;8
- .%696! .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;9
- .%697! .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;A
- .%698! .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;B
- .%699! .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;C
- .%700! .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;D
- .%701! .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;E
- .%702! .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;F
- .%703!
-
- ╘HIS IS WHERE THE TRACK CACHE, ETC. ARE STORED. ╘HIS SECTION REQUIRES 11╦ OF
- STORAGE SPACE BUT DOES NOT INCREASE THE LENGTH OF THE BINARY PROGRAM FILE
- SINCE THESE STORAGE AREAS ARE ─┼╞╔╬┼─ RATHER THAN ALLOCATED WITH ".BUF"
- DIRECTIVES. ╘HE ╒NIX TERMINOLOGY FOR THIS TYPE OF UNINITIALIZED DATA IS "BSS".
-
- .%704! ;====BSS STORAGE====
- .%705!
- .%706! BSS = *
- .%707! TRACKBUF = BSS
- .%708! CLUSTER┬UF = TRACKBUF+4608
- .%709! FATBUF = CLUSTER┬UF+1024
- .%710! DIRBUF = FATBUF+1536
- .%711! END = DIRBUF+4096
-
- 5. ╒╙┼╥-╔╬╘┼╥╞┴├┼ ╨╥╧╟╥┴═
-
- ╘HIS SECTION PRESENTS THE LISTING OF THE USER-INTERFACE ┬┴╙╔├ PROGRAM. ┘OU
- SHOULD BE AWARE THAT YOU CAN EASILY CHANGE SOME OF THE DEFAULTS TO YOUR OWN
- PREFERENCES IF YOU WISH. ╘HIS PROGRAM IS NOT LISTED IN THE ".%NNN!" FORMAT
- THAT THE ASSEMBLER LISTING IS SINCE YOU CAN RECOVER THIS LISTING FROM THE
- UUENCODED BINARY PROGRAM FILE. ╘HIS PROGRAM SHOULD BE A LITTLE EASIER TO
- FOLLOW THAN THE ASSEMBLER LISTING SINCE ┬┴╙╔├ IS A SELF-COMMENTING LANGUAGE. :-)
-
- 10 REM LITTLE RED READER, BY CRAIG BRUCE, 30-SEP-92, FOR C= HACKING NETMAG
- 11 :
-
- ╘HESE LINES SET UP THE DEFAULT ├┬═-─╧╙ AND ═╙-─╧╙ DEVICE NUMBERS, TAKING CARE
- TO DISALLOW THEM TO BE THE SAME DEVICE. ┘OU CAN CHANGE THIS TO YOUR OWN DRIVE
- CONFIGURATION.
-
- 20 CD=PEEK(186) : REM ** DEFAULT CBM-DOS DRIVE **
- 25 DV=9:DT=0 : REM ** MS-DOS DRIVE, TYPE (0=1571,255=1581)
- 26 IF DV=CD THEN DV=8:DT=0 : REM ** ALTERNATE MS-DOS DRIVE
- 27 :
- 30 PRINT CHR$(147);"INITIALIZING..." : PRINT
- 40 BANK0 : PK=DEC("8000")
- 50 IF PEEK(PK+9)=DEC("CB") AND PEEK(PK+10)=131 THEN 60
- 55 PRINT"LOADING MACHINE LANGUAGE ROUTINES..." : BLOAD"LRR.BIN",U(CD)
- 60 POKE PK+16,DV : POKE PK+17,DT : SYS PK
-
- ╔ "DIM" THE FOLLOWING VARIABLES BEFORE THE ARRAYS TO AVOID THE OVERHEAD OF
- PUSHING THE ARRAYS AROUND WHEN CREATING NEW SCALAR VARIABLES.
-
- 70 DIM T,R,B,I,A$,C,DT$,FL$,IL$,X,X$
- 80 DIM DI$(128),CL(128),SZ(128)
- 90 IF DT=255 THEN DT$="1581" :ELSE DT$="1571"
- 100 FL$=CHR$(19)+CHR$(17)+CHR$(17)+CHR$(17)+CHR$(17)
- 110 IL$=FL$:FORI=1TO19:IL$=IL$+CHR$(17):NEXT
- 120 GOTO 500
- 130 :
- 131 REM ** LOAD MS-DOS DIRECTORY **
- 140 PRINT"LOADING DIRECTORY..." : PRINT
- 150 SYS PK : SYS PK+3
- 160 DL=0
-
- ╘HE "RREG" INSTRUCTION RETURNS THE RETURN VALUES OF THE .┴, .╪, .┘, AND .╙
- REGISTERS FROM THE LAST "SYS" CALL. ╔ CHECK THE 1-BIT OF THE .╙ REGISTER
- (THE ├ARRY FLAG) FOR ERROR RETURNS.
-
- 170 RREG BL,DC,BH,S : E=PEEK(PK+15)
- 180 IF (S AND 1) THEN GOSUB 380 : RETURN
- 190 PRINT"SCANNING DIRECTORY..." : PRINT
- 200 DB=BL+256*BH
- 210 IF DC=0 THEN 360
- 220 FOR DP=DB TO DB+32*(DC-1) STEP 32
- 230 IF PEEK(DP)=0 OR PEEK(DP)=229 THEN 350
- 240 IF PEEK(DP+12) AND 24 THEN 350
- 250 DL=DL+1
-
- ╘HIS NEXT LINE IS WHERE ╔ SET THE DEFAULT SELECTION STATUS, TRANSLATION TYPE,
- AND ├┬═ FILE TYPE FOR THE ═╙-─╧╙ FILES. ┘OU CAN CHANGE THESE DEFAULTS SIMPLY
- BY OVERTYPING THE STRING IN ( ▄ ▄▄▄ ▄▄▄ ) THE "╓" LOCATIONS.
- ╓ ╓╓╓ ╓╓╓
- 260 D$=RIGHT$(" "+STR$(DL),3)+" ASC SEQ " : REM ** DEFAULT SEL/TR/FT **
- 270 A$="" : FORI=0TO10 : A$=A$+CHR$(PEEK(DP+I)) : NEXT
- 280 A$=LEFT$(A$,8)+" "+RIGHT$(A$,3)
- 290 PRINT DL; A$
- 300 D$=D$+A$+" "
- 310 CL(DL)=PEEK(DP+26)+256*PEEK(DP+27)
- 320 SZ=PEEK(DP+28)+256*PEEK(DP+29)+65536*PEEK(DP+30)
- 330 DI$(DL)=D$+RIGHT$(" "+STR$(SZ),6)
- 340 SZ(DL)=SZ
- 350 NEXT DP
- 360 RETURN
- 370 :
- 371 REM ** REPORT MS-DOS DISK ERROR **
- 380 PRINT CHR$(18);"MS-DOS DISK ERROR #";MID$(STR$(E),2);
- 390 PRINT " ($";MID$(HEX$(E),3);"), PRESS KEY.";CHR$(146)
- 400 GETKEY A$ : RETURN
- 410 :
- 411 REM ** SCREEN HEADING **
- 420 PRINTCHR$(147);"MS-DEV=";MID$(STR$(DV),2);" MS-TYPE=";DT$;
- 430 PRINT" CBM-DEV=";MID$(STR$(CD),2):PRINT
- 440 RETURN
- 450 :
- 451 REM ** SCREEN FOOTING **
- 460 PRINT IL$;"D=DIRECTORY M=MS-DEV F=CBM-DEV Q=QUIT"
- 470 PRINT"T=TOGGLE-COLUMN, C=COPY-FILES, +/- PAGE";
- 480 RETURN
- 490 :
- 491 REM ** MAIN ROUTINE **
- 500 T=1 : C=0
- 510 R=0
- 520 GOSUB 420
- 530 PRINT "NUM S TRN TYP FILENAME EXT LENGTH"
- 540 PRINT "--- - --- --- -------- --- ------"
- 550 GOSUB 460
- 560 B=T+17 : IF B>DL THEN B=DL
- 570 PRINT FL$;: IF T>DL THEN 590
- 580 FOR I=T TO B : PRINT DI$(I) : NEXT
- 590 IF DL=0 THEN PRINT CHR$(18);"<NO FILES>";CHR$(146)
- 600 IF DL=0 THEN 660
- 610 PRINT LEFT$(IL$,R+5);CHR$(18);
- 620 ON C+1 GOTO 630,640,650
- 630 PRINT SPC(4);MID$(DI$(T+R),5,3) : GOTO 660
- 640 PRINT SPC(7);MID$(DI$(T+R),8,5) : GOTO 660
- 650 PRINT SPC(12);MID$(DI$(T+R),13,5) : GOTO 660
- 660 GETKEY A$
-
- ╧H SHI^╚OOT. ╔ SCREWED UP THE FOLLOWING LINE IN THE STRING AFTER THE
- "+CHR$(13)+" PART. ┘OU'LL NOTICE THAT ╔ HAVE AVOIDED PUTTING CURSOR CONTROL
- CHARACTERS INTO THE STRINGS EVERYWHERE ELSE, BUT ╔ FORGOT TO DO THAT HERE.
- ╘HE "█STUFF▌" SHOULD BE ├URSOR╒P, ├URSOR─OWN, ├URSOR╠EFT, ├URSOR╥IGHT,
- ├URSOR╚OME, AND ├URSOR├╠╥ CONTROL CHARACTERS, RESPECTIVELY. ╘HESE CHARACTERS
- GIVE THE INDEX FOR THE "ON" STATEMENT BELOW.
-
- 670 I=INSTR("DMFTC+-Q "+CHR$(13)+"█STUFF▌",A$)
- 680 PRINT LEFT$(IL$,R+5);DI$(T+R)
- 690 IF I=0 THEN 600
- 700 ONIGOTO760,1050,1110,950,1150,1000,1020,730,860,860,770,790,810,830,850,500
- 710 STOP
- 720 :
- 721 REM ** VARIOUS MENU OPTIONS **
- 730 PRINT CHR$(147);"HAVE AN AWESOME DAY."
- 740 END
- 760 GOSUB 420 : GOSUB 140 : GOTO 500
- 770 R=R-1 : IF R<0 THEN R=B-T
- 780 GOTO 600
- 790 R=R+1 : IF T+R>B THEN R=0
- 800 GOTO 600
- 810 C=C-1 : IF C<0 THEN C=2
- 820 GOTO 600
- 830 C=C+1 : IF C>2 THEN C=0
- 840 GOTO 600
- 850 R=0 : C=0 : GOTO 600
- 860 IF DL=0 THEN 600
- 870 X=T+R : ON C+1 GOSUB 890,910,930
- 880 PRINT LEFT$(IL$,R+5);DI$(X) : GOTO 600
- 890 IF MID$(DI$(X),6,1)=" " THEN X$="*" :ELSE X$=" "
- 900 MID$(DI$(X),6,1)=X$ : RETURN
- 910 IF MID$(DI$(X),9,1)="A" THEN X$="BIN" :ELSE X$="ASC"
- 920 MID$(DI$(X),9,3)=X$ : RETURN
- 930 IF MID$(DI$(X),14,1)="S" THEN X$="PRG" :ELSE X$="SEQ"
- 940 MID$(DI$(X),14,3)=X$ : RETURN
- 950 IF DL=0 THEN 600
- 960 FOR X=1 TO DL
- 970 ON C+1 GOSUB 890,910,930
- 980 NEXT X
- 990 GOTO 520
- 1000 IF B=DL THEN T=1 : GOTO 510
- 1010 T=T+18 : GOTO 510
- 1020 IF T=1 THEN T=DL-(DL-INT(DL/18)*18)+1 : GOTO 510
- 1030 T=T-18 : IF T<1 THEN T=1
- 1040 GOTO 510
- 1050 PRINT IL$;CHR$(27);"@";
- 1060 INPUT"MS-DOS DEVICE NUMBER (8-30)";DV
- 1061 IF CD=DV THEN PRINT"MS-DOS AND CBM-DOS DEVICES MUST BE DIFFERENT!":GOTO1060
- 1070 INPUT"MS-DOS DEVICE TYPE (71/81)";X
- 1080 IF X=8 OR X=81 OR X=1581 THEN DT=255:DT$="1581" :ELSE DT=0:DT$="1571"
- 1090 POKE PK+16,DV : POKE PK+17,DT : SYS PK
- 1100 GOTO 520
- 1110 PRINT IL$;CHR$(27);"@";
- 1120 INPUT "CBM-DOS DEVICE NUMBER (0-30)";CD
- 1130 IF CD=DV THEN PRINT"MS-DOS AND CBM-DOS DEVICES MUST BE DIFFERENT!":GOTO1120
- 1140 GOTO 520
- 1141 :
- 1142 REM ** COPY FILES **
- 1150 PRINT CHR$(147);"COPY FILES":PRINT:PRINT
- 1160 IF DL=0 THEN FC=0 : GOTO 1190
- 1170 FC=0 : FOR F=1 TO DL : IF MID$(DI$(F),6,1)="*" THEN GOSUB 1200
- 1180 NEXT F
- 1190 PRINT : PRINT"FILES COPIED =";FC;" - PRESS KEY"
- 1191 GETKEY A$ : GOTO 520
- 1200 FC=FC+1
- 1210 X$=MID$(DI$(F),19,8)+"."+MID$(DI$(F),29,3)
- 1220 CF$="":FORI=1TOLEN(X$):IF MID$(X$,I,1)<>" " THEN CF$=CF$+MID$(X$,I,1)
- 1230 NEXT
- 1231 IF RIGHT$(CF$,1)="." THEN CF$=LEFT$(CF$,LEN(CF$)-1)
- 1232 CF$=CF$+","+MID$(DI$(F),14,1)
- 1240 PRINT STR$(FC);". ";CHR$(34);CF$;CHR$(34);TAB(20);SZ(F)"BYTES";
- 1245 PRINT TAB(35);MID$(DI$(F),9,3)
- 1250 CL=CL(F) : LB=SZ(F) - INT(SZ(F)/65536)*65536
-
- ╔ HAD TO USE A ─╧╨┼╬ STATEMENT HERE FOR DISK FILES BECAUSE THE REGULAR ╧╨┼╬
- STATMENT DOES NOT REDIRECT THE ─╙ AND ─╙$ PSEUDO-VARIABLES. ┘OU'LL NOTICE
- THAT THE NON-DISK ╧╨┼╬ STATMENT BELOW HAS A SECONDARY ADDRESS OF 7. ╘HIS IS
- TO PUT THE PRINTER INTO LOWERCASE MODE IF YOU ARE OUTPUTTING DIRECTLY TO IT.
- ┘OU CAN REPLACE THIS WITH A 5 (OR WHATEVER) IF YOU HAVE A SPECIAL INTERFACE
- TO AN ╔┬═-COMPATIBLE PRINTER AND YOU WANT TO PRINT DIRECTLY IN ┴╙├╔╔. ╔N THIS
- CASE, YOU WOULD SELECT THE "┬╔╬" TRANSLATION MODE FOR THE FILE YOU ARE ROUTING
- DIRECTLY TO THE PRINTER.
-
- 1260 IF CD>=8 THEN DOPEN#1,(CF$+",W"),U(CD) :ELSE IF CD<>0 THEN OPEN 1,CD,7
- 1265 IF CD<8 THEN 1288
- 1270 IF DS<>63 THEN 1288
- 1275 X$="Y" : PRINT "FILE EXISTS; OVERWRITE (Y/N)";
- 1280 CLOSE 1 : INPUT X$ : IF X$="N" THEN FC=FC-1 : RETURN
- 1285 SCRATCH(CF$),U(CD)
- 1286 DOPEN#1,(CF$+",W"),U(CD)
- 1288 IF CD<8 THEN 1320
- 1300 IF DS<20 THEN 1320
- 1310 PRINT CHR$(18)+"CBM DISK ERROR: "+DS$ : FC=FC-1 : CLOSE1 : RETURN
- 1320 POKE PK+19,CL/256 : POKE PK+18,CL-PEEK(PK+19)*256
- 1330 POKE PK+21,LB/256 : POKE PK+20,LB-PEEK(PK+21)*256
- 1340 TR=0 : IF MID$(DI$(F),9,1)="A" THEN TR=255
- 1346 X=1 : IF CD=0 THEN X=0
- 1350 SYS PK+6,TR,X
- 1355 RREG X,X,X,S : E=PEEK(PK+15)
- 1356 IF (S AND 1) THEN GOSUB 380 : FC=FC-1
- 1360 IF CD<>0 AND CD<8 THEN CLOSE1
- 1370 IF CD>=8 THEN DCLOSE#1 : IF DS>=20 THEN 1310
- 1380 RETURN
-
- 6. ╒╒┼╬├╧─┼─ ╞╔╠┼╙
-
- ╚ERE ARE THE BINARY EXECUTABLES IN UUENCODED FORM. ╘HE ├╥├32S OF THE TWO
- FILES ARE AS FOLLOWS:
-
- "LRR.128" 1106058594
- "LRR.BIN" 460671650
-
- ╘HE "LRR.128" FILE IS THE MAIN ┬┴╙╔├ PROGRAM AND THE "LRR.BIN" FILE CONTAINS
- THE MACHINE LANUGAGE DISK-ACCESSING ROUTINES.
-
- [╠╥╥.128 AND ╠╥╥.┬╔╬ ARE INCLUDED IN THIS ARCHIVE. -╥╫]
-
- 7. ┬╔┬╠╔╧╟╥┴╨╚┘
-
- ╘HE FOLLOWING WORKS WERE CONSULTED IN CREATING THIS ARTICLE:
-
- [1] ╩IM ┬UTTERFIELD, "╩IM ┬UTTERFIELD'S ├OMPLETE ├128 ═EMORY ═AP",
- _╘HE_╘RANSACTOR_, ╓OLUME 7, ╔SSUE 01, ╩ULY 1986 (┴ ═UST!).
-
- [2] ├OMMODORE ┬USINESS ═ACHINES, _├OMMODORE_1571_─ISK_─RIVE_╒SER'S_╟UIDE_,
- ├┬═, 1985.
-
- [3] ╙OME PROGRAM CALLED "MSDOS-TO-128" INCLUDED WITH "CS-DOS" BY
- ═. ╟-SOMETHING. ╧RIGINALLY PUBLISHED IN ├╧═╨╒╘┼!'S ╟AZZETTE, ╔ THINK.
-
- [4] ├OMMODORE ┬USINESS ═ACHINES, _├OMMODORE_128_╨ROGRAMMER'S_╥EFERENCE_╟UIDE_,
- ┬ANTAM ┬OOKS, 1986.
-
- [5] _╘HE_╘RANSACTOR_, ╓OLUME 4, ╔SSUE 05 ("╘HE ╥EFERENCE ╔SSUE"), ═AY 1983.
-
- =============================================================================
-