Advanced Disk Logging On The 64
Jim Butterfield, Associate Editor
"Disk Log 64" provides you with access to some useful data in the disk directory which is not available via the usual BASIC commands.
There's information on disk that you can't get with an ordinary catalog sequence
LOAD "$", 8 LIST
Often it doesn't matter. At other times, you find yourself wishing that you could get at the data.
".Disk Log 64" allows you to do that. It's set up specifically for the 64, and will give you a lot of information.
Programs
On program files, you'll get start and end addresses, in hexadecimal. That's the most convenient way to read them. You might use these addresses to help you make a copy of special overlay files that are often used in music and graphics. (See "Complex Disk Copies For The 64" in this issue.) Note that the "end" address is actually one location higher than the true end; that's the way they are most commonly used. So if you see that a program goes from $0801 to $1039, you know that the last byte is actually at $1038; $1039 is the first available memory location. Don't forget that these are hexadecimal numbers.
If you have a mixed disk of programs, you can often guess what type of systems the programs were written on. PET/CBM programs will start at $0401; programs written on the minimum VIC will start at $1001. A VIC with a 3K expansion will write programs that start at $0401, like the PET; but if 8K or more is added, then programs will start at $1201. You'll note that conventional 64 programs begin at $0801, but there can be exceptions. Character sets, high-resolution graphics, music, and machine language programs can be loaded into unusual memory locations with a LOAD "NAME",8,1 type of command; and then it will be useful to know where such data blocks or programs are being used.
In normal circumstances, programs relocate when loaded into the 64 (or VIC, for that matter). If you use a conventional LOAD from disk, the start address doesn't matter too much: The program will be moved over to the start-of-BASIC location—normally $0801.
Sequential And User Files
On this type of file, Disk Log 64 counts the bytes for you. No big deal, but sometimes this is more useful than the related coarse measure, block count. There are about 254 characters stored in each disk sector, but the last sector is often partially full. An exact character count can also help you refine file estimates.
A user (USR) file is identical to a sequential (SEQ) file, except that it is named as type USR when it is written. Why would a programmer bother? Usually to mark that there is something unusual about this file. For example, a file written as packed binary should probably be written as a USR file to warn programmers that they cannot list it in the usual way.
Relative Files
Relative files may be written on the 1541, and if they are found there, Disk Log 64 gives some very useful information which is not available elsewhere. First, it gives the file's record length—the standard size set for each record of this file. For example, L = 45 would mean that each record is set to not more than 45 characters on the relative file. Following this, the program gives the number of records existing on the file.
Machine Language Aids
This program builds machine language aids into the cassette buffer. It then calls them in two different ways.
Relative file records are counted using the SYS command in line 740. The machine language program places the record count that it finds in locations 139 and 140, where BASIC picks it up.
Files which are not relative are measured for size using the USR command in line 760. The machine language program carefully places the answer—the number of characters in the file—into a series of locations called the Floating Point Accumulator. This value is given to BASIC the moment that the USR function returns. Note that the USR vector is set up in line 760 with POKEs to addresses 785 and 786: The Commodore 64 differs from all previous machines in this area, since PET, CBM, and VIC would use addrress 1 and 2 for the same purpose.
The program has been checked out with a standard 64 equipped with disk and printer. It should work on interfaces which give access to the IEEE bus, but not all combinations have been tested.
Disk Log 64
100 DIMT$ (4) :rem 104 110 PRINT "DISK FILE LOG" :rem 144 130 C$ = CHR$(0) :rem 186 140 DATA 169,0,162,4,149,98,202,16,251 :rem 78 145 DATA 169,160,133,97,162,2,32,198,255 :rem 192 150 DATA 230,101,208,10,230,100,208,6,230,99 :rem 91 155 DATA 208,2,230,98,32,228,255,165,144 :rem 185 160 DATA 240,235,32,204,255,198,97, :rem 146 165 DATA 6,101,38,100,38,99,38,98,16,244,96 :rem 91 170 DATA 169,0,133,139,133,140 :rem 190 180 DATA 230,139,208,2,230,140 :rem 183 190 DATA 162,15,32,201,255,169,80,32,210,255 :rem 111 200 DATA 169,4,32,210,255,165,139,32,210,255 :rem 109 205 DATA 165,140,32,210,255 :rem 38 210 DATA 169,1,32,210,255,32,204,255 :rem 221 215 DATA 162,15,32,198,255,32,228,255 :rem 37 220 DATA 72,32,204,255,104,201,48,240,200,96 :rem 101 230 FOR J=860TO977: READ X: T=T+X: POKE J,X:NEXT J :rem 53 240 IF T <> 16312 THEN STOP :rem 101 250 DATA "XXX", "SEQ", "PRG", "USR", "REL" :rem 108 260 FOR J = 0 TO 4 : READ T$(J): NEXT :rem 239 270 INPUT "PRINTER" ; Z$ :rem 74 280 Z=3:IF ASC (Z$)=89 THEN Z=4:INPUT "DATE"; D$ :rem 74 290 U = 8: REM UNIT 8 :rem 251 300 D = 0: REM DRIVE 0 :rem 12 330 OPEN 4, Z:OPEN1,U,15 "I" + CHR$(D+48): CLOSE 1 :rem 36 340 G$ = "{17 SPACES}" :rem 131 350 OPEN 15,U,15 :rem 67 360 OPEN 1, U, 3, "$" + CHR$(D+48) :rem 200 370 GET #1,A$:A=ASC (A$+" ") :rem 19 380 IF A=LORA=65 THEN L1=141:L2=89:GOTO 410 :rem 80 390 IF A=67 THEN L1=3: L2=735:GOTO 410 :rem 206 400 CLOSE1: PRINT"???": STOP :rem 131 410 PRINT # 4, "*** DISK LOG *** {2 SPACES}"; D$ :rem 149 420 FOR J=1TOL1 : GET#1, A$ : NEXT J :rem 23 430 PRINT#4, "{2 SPACES}" ;: FOR J = 1 TO 23: GET#1, A$, PRINT#4, A$; : NEXT J :rem 179 440 PRINT#4:FOR J = 1 TO L2: GET#1, A$,:NEXT J :rem 56 450 M=M+1:GET#1, K$, T$, S$ :rem 28 460 L7=-1:Z$=CHR$(160): F$=" ": FOR J = 1 TO 16:G ET#1,A$ :rem 157 470 IF A$ = Z$ THEN L7 = 0 :rem 105 480 IF L7 THEN F$ = F$+A$ :rem 126 490 NEXT J :rem 38 500 GET#1,A$,A$,A$ : L% = ASC (A$+C$) :rem 131 510 FOR J=1TO6: GET#1, A$: NEXTJ :rem 208 530 GET#1, A$ : L=ASC(A$+C$) :rem 63 550 GET#1, A$: L=L+256*ASC(A$+C$) : IFM <8 THEN GET#l,A$,A$: GOTO 570 :rem 157 560 M = 0 :rem 85 570 SW=ST: IF K$ = " " GOTO 820 :rem 182 580 K = ASC(K$)-128: IF K <lORK> 4 THEN K=0 :rem 74 620 PRINT#4, T$(K) :rem 188 630 PRINT#4, RIGHT$ (" " +STR$(L),3); " "; :rem 222 640 PRINT#4, LEFT$ (F$+G$, 17); :rem 25 650 IF K = 0 GOTO 810 :rem 180 660 IF K=4 THEN PRINT#4, "L=" ; MID$(STR$ (L%), 2); :rem 245 670 OPEN 2, U, 4, CHR$(D+48) + " : "+F$+", " + T$ (K) :rem 83 680 A = 0: IF K < > 2 GOTO 730 :rem 223 690 GET#2, A$, B$ : A = ASC(A$+C$) :rem 206 700 B=ASC (B$+C$) :rem 54 710 GOSUB 840 :rem 180 730 IF K < > 4 GOTO 760 :rem 248 740 SYS 915: A=PEEK(139) + PEEK(140)* 256-l :rem 95 750 PRINT#4, ", " ; MID$(STR$(A), 2); "R"; : GOTO 800 :rem 202 760 POKE 785, 92 : POKE 786, 3 : A = A + USR (0):rem 19 770 IF K <> 2 THEN PRINT#4, A; "BYTES" ;: GOTO 800 :rem 240 780 PRINT#4, " " :A% = A/256 : A = A-A% * 256:B = B+A% :rem 247 790 GOSUB 840 :rem 188 800 CLOSE2 :rem 64 810 PRINT#4 :rem 125 820 IF SW = 0 GOTO 450 :rem 18 830 INPUT#15, A: CLOSE1 : PRINT#4, CHR$(13) : CLOSE4 : CLOSE15 : END :rem 13 840 X=B/16: GOSUB 850 : X=A/16 :rem 6 850 FOR J = l TO 2 : X%=X : X =(X-X%)* 16: IF X% >9 THEN X% = X%+7 :rem 149 860 PRINT#4, CHR$ (X%+48); ; NEXTJ :RETURN :rem 44