Classic Computer Magazine Archive COMPUTE! ISSUE 34 / MARCH 1983 / PAGE 222

Custom Catalog

G. J. Vullings

For Apples with DOS 3.2.1 or 3.3, all memory sizes, this program lets you create customized directory headers, with inverse or normal input.

Have you ever wished to personalize your disks, identify the theme of a series of programs on a disk, or just improve the appearance of the directory as it appears on the screen after a CATALOG command? "Custom Catalog" will allow you these prerogatives and more by creating seven "bogus" files at the top of the directory. These bogus files will serve as a header to the disk's directory, displaying contents, ownership, DOS version, or whatever you wish.

The program is designed to run in either a DOS 3.2.1 or 3.3 environment. It will, additionally, permit either inverse or normal input and will allow toggling between the two input states. These features make possible directories with content and artistry.

Your Choice Of Input Types

The program should be used only with newly-initialized diskettes since it will occupy the first seven entries in the director. Thus, if the program is used with established diskettes, the first seven programs will become inaccessible. To implement Custom Catalog, initialize a diskette the normal way and then delete the "HELLO" program. Run Custom Catalog and, when prompted, insert the diskette to be customized.

You have an initial choice of input states (normal or inverse) and may then design seven lines of 23 characters each (any except for control characters) to represent your identifying remarks or messages. The program sets aside a buffer of 256 bytes in high memory, using the input/output block at decimal location 896. There it stores the last sector of the directory track, which is normally track 17, sector 12 or sector 15, depending on the DOS version.

Each directory entry occupies 35 bytes. The first two represent the track and sector of the track/sector list (header). These we will direct towards an empty sector, namely track 17 (in most cases), sector one. The third byte represents the file type. Here we will use "00" to indicate an unlocked text file. The next 30 bytes represent the file name. We will make the first seven bytes backspaces to eliminate the "t" (for text) and the sector count from the display. The remaining 23 bytes may be anything of your choosing (normal or inverse). The 34th byte is the file length. This we set to "00" and the last byte is the end marker, which is also normally "00".

We now alter the entries in the buffer, but one problem remains. The output for the directory listing is via the COUT routine at $FDED using screen ASCII values, but keyboard ASCII values which we entered are in a different range. We can translate these values listing logical variables (one of the least used, yet very powerful, variable types). See page 15 of the Apple Reference Manual for screen ASCII values for both normal and inverse display. After altering the buffer, the revised version is written back to the disk.

Using a similar technique, track 2, sector 2 is then read into the buffer and the DISK VOLUME message which occupies the 176th to 186th bytes, inclusive, may be optionally changed.

A typical directory header might look like the following example:

&&&&&&&&&&&&&&&&&&&&&&&&
& APPLE II - DOS 3.3   &
&  DISK UTILITIES      &
&   JANUARY 1983       &
&PROP. OF G.J. VULLINGS&
&&&&&&&&&&&&&&&&&&&&&&&&

The above looks especially attractive in inverse mode. A hint: if the seventh line is left blank, a natural break is formed to separate the header from the rest of the directory.

Both backspace and forwardspace editing are implemented and work normally, with a few enhancements (because of the two modes of input). The only exception to normal implementation is that you cannot backspace beyond the first column (column numbers are provided to make centering easier). Therefore, pressing "RETURN" or typing past column 23 is final.

After the seventh line is entered, you are given the choice of accepting or rejecting the header that you have constructed. If you reject it, the procedure will begin again. Rejecting headers will give practice in obtaining a result which is aesthetically pleasing. If, on the other hand, you accept the header, it will be permanently written to the disk. The choice will then be offered to change the DISK VOLUME message to any 11 (or fewer) characters of your choice.

You can create additional custom entries using the method in this program, or you might want flashing entries, which you can get by translating to the required ASCII values. Have fun experimenting, and happy customizing.

How It Works

LINES

30-220 - the input routine, which allows input in two modes as well as forwardspace and backspace editing.
250-260 - translate keyboard ASCII into screen ASCII and store into disk buffer.
280-290 - toggle input status.
310-330 - backspace edit routine.
350-390 - forwardspace edit routine. Translate screen ASCII to keyboard ASCII.
410-450 - point each of the "bogus" header files to empty track 17, sector 1; declare each file to be of type "text-unlocked" of length zero; and set the end marker.
470 - inputs a series of seven backspaces into the filenames so that the lock indicator, file type, and sector count do not appear on screen.
480 - checks the memory size of your Apple and sets up a disk buffer, making the program virtually memory-size independent.
500-570 - organize screen display.
590-620 - set HIMEM: to protect the buffer and also initialize the variables.
640-670 - use track 17, sector 0, to find the directory, thus making it possible to use the program with either DOS 3.2.1 or 3.3, or even with disks having directories on tracks other than track 17.
680-800 - main routine.
820-840 - write the catalog header to the disk.
860-920 - change DISK VOLUME message.
940-990 - finishing touches.
1020-1040 - set up the input/output block for the Read Write Track Sector routine.
5 TEXT : HOME : ONERR GOTO 1000
10 GOTO 480
20 REM   ***.INPUT ROUTINE.***
30 FOR I = 0 TO 6
40 VTAB VTB + I : HTAB HTB
50 CN = 1
60 INVERSE
70 IF NOT INV THEN NORMAL
80 GET CH$ : IF CH$ <> CHR$ (13) THEN 110
90 IF CN > 23 THEN 200
100 FOR Z = CN TO 23 : CH$ = "" ; PRINT CH$ ; : GOSUB 250 : CN = CN + 1 : NEXT : GOTO 200
110 IF CH$ = CHR$ (27) THEN GOSUB 270 : GOTO 60
120 IF CH$ = CHR$ (8) THEN GOSUB 300 : GOTO 60
130 IF CN > 23 THEN 200
140 IF CH$ = CHR$ (21) THEN GOSUB 340 : GOTO 160
150 IF ASC (CH$) < 32 THEN 60
160 PRINT CH$;
170 GOSUB 250
180 CN = CN + 1
190 GOTO 60
200 GOSUB 460
210 GOSUB 400
220 NEXT
230 RETURN
240 REM ***.SCRN ASC INTO BUFFER.***
250 IF ASC (CH$) > = 32 AND ASC (CH$) < 64 THEN POKE BFR + I * 35 + 10 + CN, ASC (CH$)
        + ( NOT INV  < 0) * 128 : RETURN
260 POKE BFR + I * 35 + 10 + CN, ASC (CH$) - (INV < 0) * 64 + ( NOT INV < 0) * 128 : RETURN
270 REM   ***.CHANGE INPUT STATE.***
280 IF INV THEN INV = 0 : RETURN
290 INV = 1 : RETURN
300 REM   ***.BACKSPACE ROUTINE.***
310 CN = CN - 1 : IF CN = 0 THEN POP : GOTO 50
320 PRINT CH$;
330 RETURN
340 REM   ***.FORWARD SPACE ROUTINE.***
350 ASKII = PEEK ( PEEK (40) + 256 * PEEK (41) + PEEK (36))
360 IF ASKII < 32 THEN CH$ = CHR$ (ASKII + 64) : RETURN
370 IF ASKII < 64 THEN CH$ = CHR$ (ASKII) : RETURN
390 CH$ = CHR$ (ASKII - 128) : RETURN
400 REM   ***.PLACE COMMON POINTERS.***
410 POKE BFR + I * 35 + 1, TRK
420 POKE BFR + I * 35 + 2, 1
430 POKE BFR + I * 35 + 3, 0
440 POKE BFR + I * 35 + 34, 0
450 POKE BFR + I * 35 + 35, 0 : RETURN
460 REM   ***.PUT BKSPACES IN DIRECTORY.***
470 FOR M = 4 TO 10 : POKE BFR + I * 35 + M, 136 : NEXT : RETURN
475 REM   ***.SET DISK BUFFER.***
480 BL = PEEK (115) : BH = PEEK (116) - 1 : BUFFR = BL + BH * 256
490 REM   ***.INITIALIZE SCREEN.***
500 TEXT : HOME : VTAB 2 : INVERSE : FOR I = 1 TO 40 : PRINT "=" ; : NEXT
510 PRINT "= APPLE II CATALOG CUSTOMIZER    =";
520 PRINT "=";
530 FOR I = 1 TO 38 : PRINT "" ; : NEXT
540 PRINT "=";
550 PRINT "="   ; : NORMAL : PRINT "BY G.J. VULLINGS" ; : INVERSE : PRINT "=";
560 FOR I = 1 TO 40 : PRINT "=" ; : NEXT : NORMAL
570 POKE 34, 6
580 REM   ***.INITIALIZE VARIABLES.***
590 HIMEM : BUFR : IOB = 904 : ITRK = IOB + 4 : ISECT = IOB  + 5 : IBUFP = IOB + 8 : ICMD = IOB + 12 :
        ST = IOB + 13 : RWTS = 896 : D$ = CHR$ (13) + CHR$ (4) : RD = 1 : WRT = 2 : BFR = BUFR + 10
600 GOSUB 1020 : POKE IBUFP, BL : POKE IBUFP + 1, BH
610 HOME : VTAB 20 : PRINT "INSERT DISK TO BE CUSTOMIZED"
620 VTAB 22 : PRINT "THEN PRESS" ; : INVERSE : PRINT "RETURN" ; : NORMAL : GET Z$ : PRINT Z$
630 REM   ***.READ CATALOG INTO BUFFER.***
640 TRK = 17 : SECTR = 0
650 POKE ITRK, TRK : POKE ISECT, SECTR : POKE ICMD, RD : CALL RWTS
660 TRK = PEEK (BUFR + 1) : SECTR = PEEK (BUFR + 2)
670 POKE ITRK, TRK : POKE ISECT, SECTR : CALL RWTS675 REM ***.MAIN ROUTINE.***
680 HOME : VTAB 20 : PRINT "(I)NVERSE OR (N)ORMAL "; : GET A$: PRINT A$; VTB = 12 : HTB = 8
690 INV = 0
700 IF A$ = "I" THEN INV = 1
710 Z1$ = "00000000011111111112222"
720 Z2$ = "12345678901234567890123"
730 VTAB 10: HTAB HTB: PRINT Z1$: HTAB HTB : PRINT Z2$
740 TB = 12: FOR Z = 0 TO 6
750 VTAB TB + Z : HTAB 7 : PRINT "+"; : IF INV THEN INVERSE
760 FOR J = 1 TO 23: PRINT " ";: NEXT : NORMAL : PRINT "+"
770 NEXT
780 VTAB 20: CALL - 958 : HTAB 5 : PRINT "INPUT LINES OF CUSTOM CATALOG"
790  VTAB 22 : PRINT " PRESS "; : INVERSE : PRINT "ESC"; : NORMAL : PRINT " TO CHANGE DISPLAY STATUS"
800 GOSUB 30 : NORMAL
810 REM ***.WRITE SECTOR TO DISK.***
820 PRINT : VTAB 20 : CALL - 958 : PRINT "IS THIS WHAT YOU WANT? (Y/N) "; : GET ZZ$ : PRINT ZZ$
830 IF ZZ$ = "N" THEN 680
840 POKE ICMD, WR : CALL RWTS
850 REM ***.CHANGE DISK VOLUME.***
860 PRINT : PRINT "IS" : INVERSE : PRINT "DISK VOLUME "; :: NORMAL :
        PRINT "TO BE REPLACED? (Y/N) ";: GET Z$ : PRINT Z$
870 IF Z$ <  > "Y" THEN 930
880 TRK = 2 : SECTR = 2 : POKE ITRK, TRK : POKE I SECT,SECTR : POKE ICMD,RD : CALL RWTS
890 INPUT "INPUT 11 CHARACTER HEADER : "; MS$ : LN = LEN (MS$): IF LN > = 11
        THEN MS$ = LEFT$ (MS$, 11) : GOTO 910
900 FOR I = LN + 1 TO 11 : MS$ = MS$ + " " : NEXT
910 J = 0 : FOR I = BUFR + 176 TO BUFR + 186: POKE I, ASC (MID$ (MS$, 11 - J, 1)) + 1 28 :
        J = J + 1 : NEXT
920 POKE ICMD, WR : CALL RWTS
930 REM ***.DISPLAY CATALOG AND FINISH.***
940 HOME : PRINT D$"CATALOGD1"
950 PRINT : PRINT "MORE CUSTOMIZING? (Y/N)"; : GET ZZ* : PRINT ZZ$
960 IF ZZ$ = "Y" THEN 610
970 TEXT : HOME : VTAB 10 : HTAB 11 : FLASH : PRINT "SEE YA' LATER!! " : NORMAL
980 VTAB 23 : END
990 RETURN
1000 HOME : PRINT "***.ERROR.***" : END
1010 REM ***.SET-UP IOB.***
1020 FOR I = 1 TO 25: READ I% : POKE 896 + I -1, I% : NEXT I : RETURN
1030 DATA 160, 136, 169, 3, 32, 181, 183, 96, 1, 96, 1, 0, 17, 15, 251, 183, 0, 128, 0, 0
1040 DATA 2, 2, 254, 96, 1, 59, 236, 236, 59, 59, 236, 236, 59, 27, 236, 28, 29, 30, 236, 236