;
;                       SD.A86
;                 (revised 05/05/81)
;
;               SUPER DIRECTORY PROGRAM
;                 by Bruce R. Ratoff
;
;Displays the directory of a CP/M disk, sorted alphabetically,
;with the file size in K, rounded to the nearest CP/M block size.
;
;This latest variation on a common theme will automatically adjust
;itself for any block size and directory length under CP/M 1.4 or 2.x
;or MP/M (any version).  If the screen fills, program will pause until
;a key is struck (see NPL and LPS equates below).  Total space used
;and number of files are printed at end.
;
;Command: SD FILENAME.FILETYPE or just SD
;
;Allows '*' or '?' type specifications.  Drive name may also be
;specified.  Ignores "SYS" files unless SOPT is TRUE and 'S' option
;is given (i.e., SD *.* S will print all files).
;
;05/03/81 First 8086 version. (Bruce R. Ratoff)
;
;01/21/81 Fixed print abort test so it would work like "DIR"
;         [aborts on any character, or on ^S, ^C].
;         (ASB)
;
;
;01/06/81 Made output go through BDOS so if the printer was on,
;         you could get the output on it. The ^S test was rendered
;         useless, as was the ^C test, as BDOS buffers one character
;         ahead when it is writing out to the console. [You now need
;         to do a ^S ^C combonation to abort, and the size message
;         is not printed, but I don't think that is a major problem.]
;         (Andrew S. Beals)
;
;01/06/81 Added conditional assembly to print user number when in CP/M
;         2.x. (ASB)
;
;12/15/80 Added space suppression when printing file
;         totals.  (KBP)
;
;12/14/80 Added logic to print space remaining on disk.
;         Changed ^C test so that interrupting character is
;         not echoed (makes remote use cleaner).  (BRR)
;
;12/02/80 Fixed bug in print routine which compared last file
;         against garbage before printing. (BRR)
;
;11/29/80 Changed to allow printing 4 file names. (Ben Bronson
;         and Keith Petersen)
;
;11/22/80 Fixed bug in handling >256 files.  Changed abort test in
;         print routine to only abort on control-c.  (brr)
;
;Based on 'DIRS' by Keith Petersen, W8SDZ
;
;Set 'RMAC' TRUE to assemble with relocating assembler (requires
;link with PAGE 0 equates in separate file).
;
FALSE   EQU     0               ;DEFINE LOGICAL FALSE
TRUE    EQU     NOT FALSE       ;DEFINE LOGICAL TRUE
;
SOPT    EQU     TRUE    ;PUT TRUE TO ALLOW 'DIR *.* S' FORM
WIDE    EQU     true    ;PUT TRUE TO ALLOW 4 NAMES ACROSS
user    equ     true    ;print user numbers for cp/m 2.x also?
;
;
;
BASE    EQU     0
TPA     EQU     100H
;
FCB     EQU     5CH
;
       IF      WIDE
NPL     EQU     4       ;NUMBER OF NAMES PER LINE
       ENDIF
;
       IF      NOT WIDE
NPL     EQU     3       ;NUMBER OF NAMES PER LINE
       ENDIF
;
LPS     EQU     23      ;NUMBER OF LINES PER SCREEN
DELIM   EQU     ':'     ;FENCE (DELIMITER) CHARACTER
;
       org     TPA
;
START:
       cld
;
       IF      SOPT
       mov     al,byte ptr .FCB+17      ;SAVE S OPTION FLAG
       mov     SOPFLG,al        ;(BLANK OR LETTER S)
       ENDIF
;
       mov     USERNO,0         ;DEFAULT TO USER 0
       mov     LINCNT,0         ;CLEAR COUNT OF LINES ON SCREEN
       mov     cl,12
       CALL    BDOS     ;CHECK CP/M VERSION
       mov     word ptr VERFLG,bx  ;LO ORD >0 IF 2.X, HI ORD>0 IF MP/M
       mov     dl,0FFH
       mov     cl,CURUSR ;INTERROGATE USER NUMBER
       CALL    BDOS
       mov     USERNO,al
;
       if      not user
       mov     al,MPMFLG        ;MP/M?
       test    al,al    ;IF SO, TYPC HEADING LINE
       JZ      CHKDRV   ; ELSE SKIP IT
       endif
;
       mov     dx,offset USRMSG ;DISPLAY IT
       mov     cl,PRINT
       CALL    BDOS     ;FIRST PART OF MESSAGE
       mov     al,USERNO
       cmp     al,10    ;IF USER NO. > 9 PRINT LEADING 1
       JB      DUX
       mov     al,'1'
       CALL    TYPC
       mov     al,USERNO        ;PRINT LOW DIGIT OF USER NO.
       sub     al,10
;
DUX:    add     al,'0'
       CALL    TYPC
       mov     dx,offset USRMS2 ;PRINT TAIL OF MESSAGE
       mov     cl,PRINT
       CALL    BDOS
       mov     LINCNT,1        ;WE USED A LINE
;
CHKDRV: mov     si,offset FCB
       lods    al      ;get drive name
       test    al,al   ;ANY SPECIFIED?
       JNZ     START2  ;YES SKIP NEXT ROUTINE
       mov     cl,CURDSK
       CALL    BDOS    ;GET CURRENT DISK NR
       inc     al      ;MAKE A:=1
       mov     byte ptr .FCB,al
;
START2: add     al,'A'-1        ;MAKE IT PRINTABLE
       mov     DRNAM,al        ;SAVE FOR LATER
       mov     di,offset FCB+1 ;POINT TO NAME
       mov     al,[di] ;ANY SPECIFIED?
       cmp     al,' '
       JNZ     GOTFCB
;No FCB - make FCB all '?'
       mov     cx,11   ;FN+FT COUNT
       mov     al,'?'
;
       rep stos al     ;fill fcb with '?'
;
GOTFCB:
       mov     byte ptr .FCB+12,'?'    ;FORCE WILD EXTENT
       mov     al,byte ptr .FCB        ;CHECK FOR EXPLICIT DRIVE
       dec     al
       mov     dl,al   ;SELECT SPECIFIED DRIVE
       mov     cl,SELDSK
       CALL    BDOS
       mov     byte ptr .FCB,0
;
       mov     cl,CURDPB;IT'S 2.X OR MP/M...REQUEST DPB
       push    es      ;save current extra segment
       int     224     ;return bx=offset dpb, es=segment dpb
       add     bx,2
       mov     al,es: [bx]
       mov     BLKSHF,al       ;GET BLOCK SHIFT
       inc     bx      ;BUMP TO BLOCK MASK
       mov     al,es: [bx]
       mov     BLKMSK,al
       add     bx,2
       mov     ax,es: [bx]
       mov     BLKMAX,ax
       add     bx,2
       mov     ax,es: [bx]
       mov     DIRMAX,ax       ;SAVE IT
       pop     es              ;restore our extra segment
;
SETTBL: inc     ax      ;DIRECTORY SIZE IS DIRMAX+1
       shl     ax,1    ;DOUBLE DIRECTORY SIZE
       add     ax,offset ORDER ;TO GET SIZE OF ORDER TABLE
       mov     TBLOC,ax ;NAME TABLE BEGINS WHERE ORDER TABLE ENDS
       mov     NEXTT,ax
       mov     bx,word ptr .BASE+6     ;MAKE SURE WE HAVE ROOM TO CONTINUE
       cmp     ax,bx
       jb      SFIRST
       JMP     OUTMEM
;
;Look up the FCB in the directory
;
SFIRST: mov     cl,FSRCHF ;GET 'SEARCH FIRST' FNC
       mov     dx,offset FCB
       CALL    BDOS    ;READ FIRST
       inc     al      ;WERE THERE ANY?
       JNZ     SOME    ;GOT SOME
;
NONE:   mov     dx,offset FNF   ;PREPARE MP/M ERROR MESSAGE
       mov     al,MPMFLG
       test    al,al   ;USE IT IF REALLY MP/M
       jz      NOFILE
       JMP     ERXIT1
NOFILE: CALL    ERXIT   ;ELSE USE CP/M ERROR MESSAGE
       DB      'NO FILE$'
FNF     DB      'File not found.$'
;
USRMSG  DB      'Directory for user $'
USRMS2  DB      ':',13,10,'$'
;
;Read more directory entries
;
MORDIR: mov     cl,FSRCHN ;SEARCH NEXT
       mov     dx,offset FCB
       CALL    BDOS    ;READ DIR ENTRY
       inc     al      ;CHECK FOR END (0FFH)
       JZ      SPRINT  ;NO MORE - SORT & PRINT
;
;Point to directory entry
;
SOME:   dec     al      ;UNDO PREV 'INR A'
       mov     cl,5
       shl     al,cl   ;entry no. times 32
       mov     ah,0
       add     al,80h
       mov     bx,ax ;POINT TO BUFFER
                       ;(SKIP TO FN/FT)
;
       IF      SOPT
       mov     al,SOPFLG       ;DID USER REQUEST SYS FILES?
       cmp     al,'S'
       JZ      SYSFOK
       ENDIF
;
       test    byte ptr 10[bx],80H     ;check bit 7 of SYS byte
       JNZ     MORDIR  ;SKIP THAT FILE
;
SYSFOK: mov     al,USERNO       ;GET CURRENT USER
       cmp     al,[bx]
       JNZ     MORDIR  ;IGNORE IF DIFFERENT
       inc     bx
;
;Move entry to table
;
       mov     si,bx   ;si points to name
       mov     di,NEXTT        ;NEXT TABLE ENTRY TO di
       mov     cx,12   ;ENTRY LENGTH (NAME, TYPC, EXTENT)
;
TMOVE:  lods    al      ;GET ENTRY CHAR
       and     al,7FH  ;REMOVE ATTRIBUTES
       stos    al      ;store in table
       loop    TMOVE
       mov     al,2[si]        ;get sector count
       MOV     [di],al ;STORE IN TABLE
       inc     di
       mov     NEXTT,di        ;SAVE UPDATED TABLE ADDR
       inc     COUNT
       add     di,13   ;SIZE OF NEXT ENTRY
       sub     di,word ptr .BASE+6     ;PICK UP TPA END
       JB      MORDIR  ;IF TPA END>NEXTT THEN LOOP BACK FOR MORE
;
OUTMEM: CALL    ERXIT
       DB      'Out of memory.',13,10,'$'
;
;Sort and print
;
SPRINT: mov     cx,COUNT        ;GET FILE NAME COUNT
       test    cx,cx
       jnz     SPRINI
       jmp     NONE    ;NONE, EXIT
;Init the order table
SPRINI: mov     ax,TBLOC        ;GET START OF NAME TABLE
       mov     di,offset ORDER ;POINT TO ORDER TABLE
;
BLDORD: stos    ax
       add     ax,13
       loop    BLDORD
       mov     bx,COUNT        ;GET COUNT
       mov     SCOUNT,bx       ;SAVE AS # TO SORT
       dec     bx      ;only 1 entry?
       JZ      DONE    ;..YES, SO SKIP SORT
;
SORT:   mov     SWITCH,0        ;SHOW NONE SWITCHED
       mov     bx,SCOUNT       ;GET COUNT
       dec     bx              ;use 1 less
       mov     word ptr TEMP,bx        ;SAVE # TO COMPARE
       mov     SCOUNT,bx       ;SAVE HIGHEST ENTRY
       JZ      DONE    ;EXIT IF NO MORE
       mov     bx,offset ORDER ;POINT TO ORDER TABLE
;
SORTLP: mov     cx,12   ;# BYTES TO COMPARE
       CALL    COMPR   ;COMPARE 2 ENTRIES
       jbe     NOSWAP
       CALL    SWAP    ;SWAP IF NOT IN ORDER
NOSWAP: add     bx,2    ;bump order table ptr
       dec     TEMP    ;BUMP COUNT
       JNZ     SORTLP  ;CONTINUE
;One pass of sort done
       mov     al,SWITCH       ;ANY SWAPS DONE?
       test    al,al
       JNZ     SORT
;
;Sort is all done - print entries
;
DONE:   mov     bx,offset ORDER
       mov     NEXTT,bx
;
;Print an entry
;
       IF      NOT WIDE
       CALL    DRPRNT  ;PRINT DRIVE NAME
       ENDIF
       mov     cx,NPL  ;NR. OF NAMES PER LINE
       mov     TOTSIZ,0        ; TOTAL K USED
       mov     TOTFIL,0        ; AND TOTAL FILES
;
ENTRY:  mov     bx,COUNT        ; CHECK COUNT OF REMAINING FILES
       dec     bx      ; skip compare if only 1 left
       JZ      OKPRNT
       PUSH    cx
;
       mov     cl,dconio       ;get console status
       mov     dl,0ffh
       call    bdos
       test    al,al   ;char?
       jz      nobrk   ;no char, bypass the other stuff
       jmp     exit    ;abort
;
NOBRK:  mov     bx,NEXTT
       mov     cx,11
       CALL    COMPR   ;DOES THIS ENTRY MATCH NEXT ONE?
       pop     cx
       JNE     OKPRNT  ;NO, PRINT IT
       add     bx,2    ;SKIP, SINCE HIGHEST EXTENT COMES LAST IN LIST
       mov     NEXTT,bx
       dec     COUNT   ;COUNT DOWN
       JMP     ENTRY   ;GO GET NEXT
;
OKPRNT:
       push    cx
;
       IF      NOT WIDE
       CALL    FENCE   ;PRINT FENCE CHAR AND SPACE
       ENDIF
;
       mov     bx,NEXTT        ;GET ORDER TABLE POINTER
       mov     si,[bx]
       add     bx,2
       mov     NEXTT,bx        ;SAVE UPDATED TABLE POINTER
       mov     cx,8    ;FILE NAME LENGTH
       CALL    TYPCIT  ;TYPC FILENAME
       mov     al,'.'  ;PERIOD AFTER FN
       CALL    TYPC
       mov     cx,3    ;GET THE FILETYPC
       CALL    TYPCIT
       mov     dl,[si]
       mov     dh,0
       inc     si
       mov     al,[si] ;GET SECTOR COUNT OF LAST EXTENT
       mov     cl,4    ;# OF EXTENTS TIMES 16K
       shl     dx,cl
       ADD     al,BLKMSK       ;ROUND LAST EXTENT TO BLOCK SIZE
       mov     cl,3
       shr     al,cl           ;CONVERT FROM SECTORS TO K
       mov     ah,0
       add     dx,ax   ;add to total K
       mov     al,BLKMSK       ;GET SECTORS/BLK-1
       mov     cl,3
       shr     ax,cl           ;CONVERT TO K/BLK
       not     ax              ;USE TO FINISH ROUNDING
       and     dx,ax
       add     TOTSIZ,dx       ;add to total used
       inc     TOTFIL  ;INCREMENT FILE COUNT
       mov     ax,dx           ;GET BACK FILE SIZE
       CALL    DECPRT  ; AND PRINT IT
       mov     al,'k'  ;FOLLOW WITH K
       CALL    TYPC
;
       IF      NOT WIDE
       CALL    SPACE
       ENDIF
;
;See if more entries
;
       dec     COUNT   ;COUNT DOWN ENTRIES
       pop     cx
       JZ      PRTOTL  ;IF OUT OF FILES, PRINT TOTALS
       DEC     CX      ;ONE LESS ON THIS LINE
       jz      DOCRLF
;
       IF      WIDE
       CALL    FENCE   ;NO CR-LF NEEDED, DO FENCE
       ENDIF
;
       jmps    NOCRLF
;
DOCRLF: CALL    CRLF    ;CR-LF NEEDED
NOCRLF: JMP     ENTRY
;
;Print HL in decimal with leading zero suppression
;
DECPRT:                 ;CLEAR LEADING ZERO FLAG
       mov     LZFLG,0
       mov     bx,1000 ;PRINT 1000'S DIGIT
       CALL    DIGIT
       mov     bx,100  ;ETC
       CALL    DIGIT
       mov     bx,10
       CALL    DIGIT
       add     al,'0'  ;GET 1'S DIGIT
       JMP     TYPC
;
DIGIT:  mov     dx,0    ;init hi order dividend
       div     bx      ;divide ax by digit value (dx gets rmdr)
       add     al,'0'  ;convert to ASCII digit
;
       cmp     al,'0'  ;ZERO DIGIT?
       JNZ     DIGNZ   ;NO, TYPC IT
       mov     al,LZFLG        ;LEADING ZERO?
       test    al,al
       mov     al,'0'
       JNZ     DIGPR   ;PRINT DIGIT
       mov     al,SUPSPC       ;GET SPACE SUPPRESSION FLAG
       test    al,al   ;SEE IF PRINTING FILE TOTALS
       jz      DIGNP           ;YES, DON'T GIVE LEADING SPACES
       mov     al,' '
       JMPS    DIGPR   ;LEADING ZERO...PRINT SPACE
;
DIGNZ:  mov     LZFLG,0ffh ;SET LEADING ZERO FLAG SO NEXT ZERO PRINTS
DIGPR:  call    TYPC    ;AND PRINT DIGIT
DIGNP:  mov     ax,dx   ;set up remainder for next digit
       ret
;
;Show total space and files used
;
PRTOTL: mov     SUPSPC,0        ;SUPPRESS LEADING SPACES IN TOTALS
       CALL    CRLF    ;NEW LINE (WITH PAUSE IF NECESSARY)
;
       IF      WIDE
       mov     dx,offset TOTMS1 ;PRINT FIRST PART OF TOTAL MESSAGE
       ENDIF
;
       IF      NOT WIDE
       mov     dx,offset TOTMS1+1 ;PRINT FIRST PART OF TOTAL MESSAGE
       ENDIF
;
       mov     cl,PRINT
       CALL    BDOS
       mov     ax,TOTSIZ       ;PRINT TOTAL K USED
       CALL    DECPRT
       mov     dx,offset TOTMS2;NEXT PART OF MESSAGE
       mov     cl,PRINT
       CALL    BDOS
       mov     ax,TOTFIL       ;PRINT COUNT OF FILES
       CALL    DECPRT
       mov     dx,offset TOTMS3;TAIL OF MESSAGE
       mov     cl,PRINT
       CALL    BDOS
       mov     cl,GALLOC       ;GET ADDRESS OF ALLOCATION VECTOR
       push    es      ;save our ES
       int     224     ;return bx=offset ALV, es=segment ALV
       mov     dx,BLKMAX       ;GET ITS LENGTH
       inc     dx
       mov     cx,0    ;INIT BLOCK COUNT TO 0
;
GSPBYT: PUSH    bx      ;SAVE ALLOC ADDRESS
       mov     al,es: [bx]
       mov     bl,8    ;SET TO PROCESS 8 BLOCKS
;
GSPLUP: shl     al,1            ;TEST BIT
       JB      NOTFRE
       inc     cx
;
NOTFRE: dec     dx      ;COUNT DOWN BLOCKS
       JZ      ENDALC  ;QUIT IF OUT OF BLOCKS
       dec     bl      ;COUNT DOWN 8 BITS
       JNZ     GSPLUP  ;DO ANOTHER BIT
       POP     bx      ;BUMP TO NEXT BYTE
       INC     bx      ;OF ALLOC. VECTOR
       JMPS    GSPBYT  ;PROCESS IT
;
ENDALC: pop     es      ;restore our es
       mov     ax,cx
       mov     cl,BLKSHF       ;GET BLOCK SHIFT FACTOR
       sub     cl,3    ;CONVERT FROM SECTORS TO K
       JZ      PRTFRE  ;SKIP SHIFTS IF 1K BLOCKS
;
       shl     ax,cl   ;mult blks by k/blk
;
PRTFRE: CALL    DECPRT  ;PRINT K FREE
       mov     dx,offset TOTMS4
       mov     cl,PRINT
       CALL    BDOS
       JMP     EXIT    ;ALL DONE...RETURN TO CP/M
;
TOTMS1  DB      ' : Total of $'
DRNAM   equ     TOTMS1
TOTMS2  DB      'k in $'
TOTMS3  DB      ' files with $'
TOTMS4  DB      'k space remaining.$'
;
FENCE:
       IF      WIDE
       CALL    SPACE
       ENDIF
       mov     al,DELIM        ;FENCE CHARACTER
       CALL    TYPC    ;PRINT IT, FALL INTO SPACE
;
SPACE:  mov     al,' '
;
;Type character in A
;
TYPC:   PUSH    cx
       PUSH    dx
       push    bx
       push    si
       mov     dl,al   ;use bdos calls, that's what they're there for
       mov     cl,dconio
       call    bdos
       pop     si
       POP     bx
       POP     dx
       POP     cx
       RET
;
TYPCIT: lods    al
       CALL    TYPC
       loop    TYPCIT
       RET
;
;Fetch character from console (without echo)
;
CINPUT: mov     cl,dconio
       mov     al,0ffh
       call    BDOS
       and     al,7FH
       jz      CINPUT
       RET
;
CRLF:   mov     al,LINCNT       ;CHECK FOR END OF SCREEN
       inc     al
       cmp     al,LPS
       JB      NOTEOS  ;SKIP MESSAGE IF MORE LINES LEFT ON SCREEN
       mov     dx,offset EOSMSG;SAY WE'RE PAUSING FOR INPUT
       mov     cl,PRINT
       CALL    BDOS
       CALL    CINPUT  ;WAIT FOR CHAR.
       mov     al,0    ;SET UP TO ZERO LINE COUNT
;
NOTEOS: mov     LINCNT,al       ;SAVE NEW LINE COUNT
       mov     al,13   ;print cr
       call    TYPC
       mov     al,10   ;lf
       call    TYPC
;
       IF      NOT WIDE
       CALL    DRPRNT  ;DRIVE NAME
       ENDIF
;
       mov     cx,NPL  ;RESET NUMBER OF NAMES PER LINE
       RET
;
EOSMSG  DB      13,10,'(Strike any key to continue)$'
;
       IF      NOT WIDE
DRPRNT: mov     al,DRNAM
       JMP     TYPC
       ENDIF
;
;Compare routine for sort
;
COMPR:  mov     si,[bx]
       mov     di,2[bx]
       repe cmps al,al
       ret
;
;
;Swap entries in the order table
;
SWAP:   mov     SWITCH,1        ;SHOW A SWAP WAS MADE
       mov     dx,[bx]
       xchg    dx,2[bx]
       mov     [bx],dx
       ret
;
;Error exit
;
ERXIT:  POP     dx      ;GET MSG
;
ERXIT1: mov     cl,PRINT
;
CALLB:  CALL    BDOS    ;PERFORM REQUESTED FUNCTION
;
;(fall into exit)
;Exit - all done, restore stack
;
EXIT:   mov     cl,0    ;exit is via BDOS call 0
;
BDOS:   push    es      ;preserve es thru bdos call
       int     224     ;call bdos 8086 style
       pop     es
       ret
;
;Temporary storage area
;
BLKSHF  DB      0       ;# SHIFTS TO MULT BY SEC/BLK
BLKMSK  DB      0       ;SEC/BLK - 1
BLKMAX  DW      0       ;HIGHEST BLOCK # ON DRIVE
DIRMAX  DW      0       ;HIGHEST FILE # IN DIRECTORY
TOTSIZ  DW      0       ;TOTAL SIZE OF ALL FILES
TOTFIL  DW      0       ;TOTAL NUMBER OF FILES
LINCNT  DB      0       ;COUNT OF LINES ON SCREEN
TBLOC   DW      0       ;POINTER TO START OF NAME TABLE
NEXTT   DW      0       ;NEXT TABLE ENTRY
COUNT   DW      0       ;ENTRY COUNT
SCOUNT  DW      0       ;# TO SORT
SWITCH  DB      0       ;SWAP SWITCH FOR SORT
SUPSPC  DB      0FFH    ;LEADING SPACE FLAG FOR DECIMAL RTN.
BUFAD   DW      BASE+80H ;OUTPUT ADDR
SOPFLG  db      0       ;SET TO 'S' TO ALLOW SYS FILES TO PRINT
USERNO  db      0       ;CONTAINS CURRENT USER NUMBER
TEMP    dw      0       ;SAVE DIR ENTRY
VERFLG  db      0       ;VERSION FLAG
MPMFLG  db      0       ;MP/M FLAG
LZFLG   db      0       ;0 WHEN PRINTING LEADING ZEROS
ORDER   EQU     $       ;ORDER TABLE STARTS HERE
;
;BDOS equates
;
RDCHR   EQU     1       ;READ CHAR FROM CONSOLE
WRCHR   EQU     2       ;WRITE CHR TO CONSOLE
DCONIO  EQU     6       ;direct console i/o
PRINT   EQU     9       ;PRINT CONSOLE BUFF
CONST   EQU     11      ;CHECK CONS STAT
SELDSK  EQU     14      ;SELECT DISK
FOPEN   EQU     15      ;0FFH=NOT FOUND
FCLOSE  EQU     16      ;   "   "
FSRCHF  EQU     17      ;   "   "
FSRCHN  EQU     18      ;   "   "
CURDSK  EQU     25      ;GET CURRENTLY LOGGED DISK NAME
GALLOC  EQU     27      ;GET ADDRESS OF ALLOCATION VECTOR
CURDPB  EQU     31      ;GET CURRENT DISK PARAMETERS
CURUSR  EQU     32      ;GET CURRENTLY LOGGED USER NUMBER (2.x ONLY)
;
       END