home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / dskutl / alloc3.lbr / ALLOC3.AQM / ALLOC3.ASM
Encoding:
Assembly Source File  |  1985-02-09  |  18.6 KB  |  1,038 lines

  1. ;Name:        ALLOC.ASM
  2. ;Author:        Ward Christensen
  3. ;Written:    08/23/81
  4. ;Function:    Print allocation bit map of a disk
  5. ;Processor:     ASM or MAC
  6. ;Dependencies:     NONE
  7. ;Usage:
  8.  
  9.     ORG    100H
  10.     JMP    BEGIN
  11. PROMPT    CALL    EXIT
  12.  DB CR,LF
  13.  DB 'ALLOC   4/10/82     by Ward C.'
  14.  DB CR,LF
  15.  DB CR,LF
  16.  DB '   ALLOC             show bit map.'
  17.  DB CR,LF
  18.  DB '   ALLOC B:          show bit map for drive B.'
  19.  DB CR,LF
  20.  DB '   ALLOC FOO.ASM     show bit map, with FOO.ASM as "*".'
  21.  DB CR,LF
  22.  DB '   ALLOC 22          zap (temporarily write-protect) 22K of map.'
  23.  DB CR,LF
  24.  DB '   ALLOC - 22        zap "all but" 22K.'
  25.  DB CR,LF
  26.  DB '   ALLOC - FOO.ASM   zap "all but" nnK, where nn = FOO.ASM size.'
  27.  DB CR,LF
  28.  DB CR,LF
  29.  DB '   Notes:'
  30.  DB CR,LF
  31.  DB '   1)  Typing ^C restores the original map.'
  32.  DB CR,LF
  33.  DB '   2)  If interrupted, '
  34.  DB          'ALLOC skips bit map and prints just totals.'
  35.  DB CR,LF
  36.  DB '   3)  Drive name prefix is ok:  "ALLOC - B:FOO.ASM"'
  37.  DB CR,LF
  38.  DB '   4)  "- " may precede or follow the operand:  "ALLOC 22 -"'
  39.  DB CR,LF
  40.  DB CR,LF,'$'
  41.  
  42. ;History:
  43. ;               Based on my original alloc.asm idea,
  44. ;        but rewritten for CP/M 1.4-2.2 independence,
  45. ;        and to dynamically determine disk size.
  46. ;
  47. ;
  48. ;Revs:        (LAST FIRST)
  49. ;    04/10/82 Add negative allocations ("all but") and ability
  50. ;         to give implicit "nn" operand via filename.typ.
  51. ;         Also:  allow reexecution without reloading.
  52. ;         (Roy Lipscomb)
  53. ;    12/13/81 Check console status to interrupt display -    
  54. ;         particularly necess. on remote systems where
  55. ;         you may not want to see all the bit map.
  56. ;    12/08/81 re-compute max size - forgot to allow for dir.
  57. ;    10/03/81 Print "D"s for directory bits
  58. ;    09/13/81 Print total K on disk, not just "free"
  59. ;    08/25/81 add "nn" operand to "FORCE" allocation
  60. ;        of bits, i.e. so any file created on the disk
  61. ;        will be placed "further down".  A ^C restores the
  62. ;        original bit map.
  63. ;
  64. ;
  65. ;
  66.  
  67.  
  68.  
  69. ;Init local stack
  70. ;
  71. BEGIN    LXI    H,0        ;HL =
  72.     DAD    SP        ;    CP/M STACK
  73.     SHLD    STACK        ;SAVE FOR RETURN
  74.     LXI    SP,STACK     ;SET NEW STACK
  75. ;
  76. ;DETERMINE IF INSTRUCTIONS, BITMAP ONLY, OR BITMAP PLUS ZAPPING WANTED.
  77.     MVI    B,NO        ;SET FOR DEFAULT:  NOT "ALL BUT" OP
  78.  
  79.     LDA    FCB2+1
  80.     CPI    '-'
  81.     JZ    SETMIN1
  82.  
  83.     LDA    FCB+2
  84.     CPI    ' '
  85.     JNZ    SETMIN2
  86.  
  87.     LDA    FCB+1
  88.     CPI    'H'
  89.     JZ    PROMPT
  90.  
  91.     CPI    '-'
  92.     JNZ    SETMIN2
  93.  
  94.     CALL    MOVFCB        ;OVERLAY '- ' WITH FILE NAME
  95.  
  96. SETMIN1    MVI    B,YES
  97.  
  98. SETMIN2    MOV    A,B
  99.     STA    MINUS
  100.  
  101. ;PRINT SIGNON PROMPT
  102. ;
  103.     LXI    D,SIGNON    ;POINT TO SIGNON MSG
  104.     MVI    C,PRINT        ;PRINT
  105.     CALL    BDOS        ;    IT
  106.  
  107. ;INITIALIZE WORK AREAS
  108.     LXI    H,0
  109.     SHLD    ZAP
  110.     SHLD    ZAPHOLD
  111.  
  112.     LXI    H,2020H        ;INSERT SPACES INTO MESSAGES
  113.     SHLD    ALOCDIR
  114.     SHLD    ALOCUSD
  115.     SHLD    ALOCFRE
  116.     SHLD    ALOCTOT
  117.  
  118.     LXI    H,3020H        ;INSERT ' 0' INTO MESSAGES
  119.     SHLD    ALOCDIR+2
  120.     SHLD    ALOCUSD+2
  121.     SHLD    ALOCFRE+2
  122.     SHLD    ALOCTOT+2
  123.  
  124.     MVI    A,1
  125.     STA    KPERBIT
  126.  
  127.     XRA    A
  128.     STA    ROUND
  129.  
  130.     CALL    MAKMAP        ;CLEAR "MAP" AREA FOR GROUPS OF FILE.
  131.  
  132.  
  133. ;
  134. ;SEE IF SPECIFIC DISK REQUIRED
  135. ;
  136.     LDA    FCB    ;GET DISK
  137.     ORA    A    ;    DEFAULT?
  138.     JZ    NODISK    ;    YES, NO SELECT
  139.  
  140.     DCR    A    ;ADJUST FOR LOGIN
  141.     MOV    E,A    ;    PUT IN PARM REG
  142.     MVI    C,LOGIN    ;    SETUP REQUEST
  143.     CALL    BDOS    ;    LOGIN REQUESTED DISK
  144.  
  145. ;GET THE SIZE OF THE DISK
  146. ;
  147. NODISK    MVI    C,GETVERS
  148.     CALL    BDOS    ;GET VERSION
  149.     MOV    A,L    ;L IS 0 IF 1.4
  150.     ORA    A    ;ZERO?
  151.     JNZ    ALOC22    ;    NO, IT'S 2.2
  152. ;
  153. ;THIS IS 1.4, SO GET PARM BLOCK FROM THE FRONT OF BDOS
  154. ;
  155.     LHLD    BDOS+1    ;GET ADDR
  156.     LXI    D,36H    ;OFFSET TO PARM
  157.     DAD    D
  158.     MOV    A,M    ;GET BLOCK SHIFT FACTOR
  159.     INX    H
  160.     INX    H
  161.     MOV    E,M    ;GET DISK SIZE
  162.     MVI    D,0
  163.     INX    H    ;TO DIRECTORY BIT MAP SIZE
  164.     MOV    B,M
  165.     MVI    C,0
  166.     JMP    ALOCCAL
  167. ;
  168. ; THIS IS 2.0 OR HIGHER
  169. ALOC22    MVI    C,GETPARM
  170.     CALL    BDOS    ;GET DISK PARM ADDR
  171.     INX    H    ;SKIP
  172.     INX    H    ;    TO
  173.     MOV    A,M    ;    #K PER BIT
  174.     INX    H    ;SKIP
  175.     INX    H    ;    TO
  176.     INX    H    ;    TOTAL
  177.     MOV    E,M    ;    DISK
  178.     INX    H    ;    SIZE
  179.     MOV    D,M    ;MOVE IT TO DE
  180.     INX    H
  181.     INX    H
  182.     INX    H
  183.     MOV    B,M    ;DIR BIT MAP
  184.     INX    H
  185.     MOV    C,M    ;    TO BC
  186.  
  187. ;SAVE DISK PARAMETERS, INITIALIZE VARIABLES
  188. ALOCCAL    STA    BSH        ;SAVE BLOCK SHIFT
  189.  
  190.     CALL    COMPDIR        ;COMPUTE DIR SIZE
  191.     INX    H        ;FUDGE HL TO # OF BITS IN MAP
  192.     SHLD    TOTBITS        ;SAVE FOR PRINT OF TOTAL
  193.  
  194.  
  195. ;CHECK COMMAND USAGE
  196. ;
  197.     LDA    FCB+1
  198.     CPI    ' '    ;OPERAND IS BLANK?
  199.     JZ    PASSTWO    ;    YES, NO OPTIONS
  200.  
  201. ;INITIALIZE ZAPHOLD
  202.     CALL    GETDEC    ;GET DECIMAL # TO ZAP OR (IF "ALL BUT") NOT ZAP
  203.     CC    GETGRPS ;IF NON-DIGIT FOUND, TREAT AS FILENAME
  204.  
  205. ;PASS ONE:  DON'T ZAP YET, JUST COMPUTE FREE GROUPS AND "ALL BUT" COUNT
  206. ;(SKIP IF NOT "ALL BUT" OPTION)
  207.     LDA    MINUS
  208.     CPI    YES
  209.     JNZ    PASSTWO
  210.  
  211.     MVI    A,1
  212.     STA    PASS
  213.  
  214.     CALL    BMAP    ;(RETURNS WITH FREE COUNT IN BC)
  215.  
  216.     PUSH    B
  217.     POP    H
  218.     CALL    GRPS2K    ;CONVERT HL (CONTAINS GROUP COUNT) INTO K
  219.  
  220.     CALL    INVERTZ    ;SUBTRACT ZAPHOLD FROM HL, PUT IN ZAPHOLD
  221.  
  222. ;PASS TWO:  ZAP BITS IF REQUESTED; PRINT BIT MAP
  223. PASSTWO EQU    $
  224.     MVI    A,2
  225.     STA    PASS
  226.  
  227.     LHLD    ZAPHOLD
  228.     SHLD    ZAP
  229.  
  230.     CALL    BMAP
  231.  
  232.     JMP    ALOCASC    ;DONE, COMPUTE IN ASCII
  233.  
  234.  
  235.  
  236. ;PROCESS BIT MAP
  237.  
  238. ;INITIALIZE
  239. BMAP    LXI    D,GROUPS-1 ;COMPUTE FIRST AVAILABLE GROUP AFTER
  240.                ;DIRECTORY (SUBTRACT 1 TO COUNTERACT INITIAL
  241.                ;"INX H" BELOW).
  242.     LHLD    DIRSIZE
  243.     MVI    H,0
  244.     DAD    D
  245.     SHLD    MAPINX
  246.  
  247.     LHLD    ZAP    ;(WILL BE ALL ZEROS ON PASS ONE)
  248.     CALL    K2GRPS    ;CONVERT K TO GROUPS:  ZAP = ZAP/(#K/BIT)
  249.     SHLD    ZAP
  250.  
  251.     CALL    CRLF0    ;RESET COLUMN COUNT
  252.  
  253. ;DO ZAP
  254.     LHLD    TOTBITS
  255.     LDA    DIRSIZE    ;BACK OUT
  256.     CMA        ;    DIR BITS
  257.     MOV    E,A    ;    FROM
  258.     MVI    D,0FFH    ;    TOTAL
  259.     INX    D    ;    DE = NEG DIR BITS
  260.     XCHG
  261.     DAD    D    ;    ADD TO HL
  262.  
  263.     PUSH    H    ;SAVE # BITS
  264.  
  265.     PUSH    D    ;SAVE WITHOUT DIR SUBTRACTED
  266.     MVI    C,INQALC
  267.     CALL    BDOS    ;GET ALLOCATION POINTER INTO HL
  268.     POP    D    ;GET BIT MAP COUNT
  269.  
  270.     PUSH    H    ;SAVE POINTER TO ALLOCATION VECTOR
  271.     CALL    ZAPEM    ;ZAP REQUESTED BITS
  272.     CALL    PRINTD    ;PRINT "D"'S, SET UP MASK IN A
  273.     POP    H
  274.  
  275.     POP    D    ;GET # WITH DIR SUBTRACTED
  276.  
  277.     LXI    B,0    ;INIT #K FREE
  278.  
  279. ;PROCESS-BIT LOOP
  280. ALOCBIT    PUSH    PSW    ;SAVE MASK
  281.  
  282.     PUSH    D    ;SAVE COUNTDOWN OF BITS IN ALLOCATION VECTOR
  283.     PUSH    H    ;SAVE POINTER TO ALLOCATION VECTOR
  284.     INX    B    ;INCREMENT COUNT OF FREE
  285.  
  286.     ANA    M    ;FREE?
  287.     MVI    A,'0'    ;    SETUP TO PRINT '0'
  288.  
  289.     LHLD    MAPINX    ;INDEX TO ENTRY IN MAP OF FILE'S GROUPS
  290.     INX    H
  291.     SHLD    MAPINX
  292.  
  293.     JZ    ALOCTYP    ;    YES, PRINT '0'
  294.  
  295. ;PROCESS "USED" BIT.
  296.     DCX    B        ;ADJUST COUNT OF FREE
  297.  
  298.     MOV    A,M        ;GET FLAG FROM GROUP MAP
  299.     ORA    A        ;IS IT GROUP FOR SPECIFIED FILE?
  300.     JNZ    ALOCTYP        ;(YES IF A <> 0)
  301.  
  302.     MVI    A,'1'        ;  NO, SET TO "1"
  303.  
  304. ;PRINT BIT
  305. ALOCTYP    PUSH    B
  306.     CALL    STYPE    ;TYPE IT (Unless interrupted)
  307.  
  308.     LDA    COL    ;BUMP
  309.     INR    A    ;    OUTPUT
  310.     STA    COL    ;    COLUMN,
  311.  
  312.     CPI    50    ;    AND CRLF
  313.     CZ    SCRLF    ;    AFTER 50
  314.  
  315.     POP    B
  316.     POP    H
  317.     POP    D
  318.  
  319.     DCX    D    ;COUNT DOWN # BITS
  320.     MOV    A,D
  321.     ORA    E
  322.     JZ    BMAPX
  323.  
  324.     POP    PSW    ;GET MASK
  325.     CALL    RIGHT
  326.     JMP    ALOCBIT
  327.  
  328. ;EXIT FROM BIT-MAP CREATION
  329. BMAPX    POP    PSW
  330.     RET
  331.  
  332. ;
  333. ;MAKE (A) (MASK) AND (HL) (POINTER) POINT TO NEXT BIT
  334. ;
  335. RIGHT    ORA    A    ;NO CARRY
  336.     RAR        ;RIGHT 1 BIT,
  337.     RNC        ;    RET IF NOT INTO CARRY
  338.     RAR        ;    OTHERWISE MAKE IT 80H
  339.     INX    H    ;TO NEXT BYTE
  340.     RET
  341.  
  342.  
  343. ;CONVERT POSITIVE K INTO "ALL BUT" K, BY SUBTRACTING FROM NUMBER FREE.
  344. ;(ON ENTRY, HL = #K)
  345. INVERTZ    PUSH    H
  346.     POP    B
  347.  
  348.     LHLD    ZAPHOLD    ;GET AMOUNT TO PROTECT FROM ZAPPING,
  349.  
  350.     MOV    A,C    ;SUBTRACT FROM TOTAL FREE (IN BC)
  351.     SUB    L
  352.     MOV    L,A
  353.  
  354.     MOV    A,B
  355.     SBB    H
  356.     MOV    H,A
  357.  
  358.     JNC    INVERT2        ;IF # TO SAVE IS LARGER THAN # FREE,
  359.     LXI    H,0        ;SAVE ALL FROM BEING ZAPPED
  360.  
  361. INVERT2    SHLD    ZAPHOLD    ;NUMBER TO ZAP, TO LEAVE DESIRED NUMBER FREE
  362.     RET
  363.  
  364.  
  365.  
  366. ;
  367. ;DONE; BC = # BITS OFF, CONVERT TO K, THEN TO ASCII
  368. ;
  369. ;
  370. ;FIRST, MULTIPLY THE # OF BITS THAT WERE 0,
  371. ;    BY THE # OF K PER BIT
  372. ;
  373. ALOCASC    LDA    BSH    ;GET BLOCK SHIFT
  374.     MOV    D,B
  375.     MOV    E,C    ;MOVE COUNT TO DE
  376.     XCHG        ;THEN TO HL
  377.     SUI    3    ;IS IT 1K?
  378.     JZ    ALOCASB    ;YES
  379.  
  380. ;DOUBLE # OF BITS FREE, TOTAL DISK SIZE, AND K/BIT.
  381. ALOCINK    DAD    H    ;DOUBLE # OF BITS FREE
  382.  
  383.     PUSH    H    ;DOUBLE DISK SIZE
  384.     LHLD    TOTBITS
  385.     DAD    H
  386.     SHLD    TOTBITS
  387.     POP    H
  388.  
  389.     PUSH    PSW        ;DOUBLE K/BIT
  390.     LDA    KPERBIT
  391.     ADD    A    ;DOUBLE
  392.     DAA        ;CONVERT TO PACKED DECIMAL
  393.     STA    KPERBIT
  394.     POP    PSW
  395.     DCR    A    ;COUNT DOWN
  396.     JNZ    ALOCINK
  397.  
  398. ALOCASB    SHLD    TOTFREE    ;SAVE FOR FINAL CALC
  399.     XCHG        ;BIT COUNT TO DE
  400.     LXI    H,ALOCFRE+3 ;INIT FOR "ADD1"
  401.  
  402. ALOCASL    MOV    A,D    ;DOWN TO
  403.     ORA    E    ;    0 LEFT?
  404.     JZ    ALOCPRT    ;    YES, PRINT IT
  405.  
  406.     PUSH    H    ;SAVE POINTER
  407.     CALL    ADD1    ;ADD 1 IN ASCII
  408.     POP    H
  409.     DCX    D    ;DCR COUNT
  410.     JMP    ALOCASL
  411. ;
  412. ;READY TO PRINT, CONVERT PACKED DECIMAL K PER BIT TO ASCII
  413. ;
  414. ALOCPRT    LXI    H,KPERBIT
  415.     MOV    A,M    ;GET VALUE
  416.     MVI    M,' '    ;BLANK IT
  417.     CPI    10
  418.     JC    PRTLT10    ;IT IS LESS THAN 10
  419.     PUSH    PSW    ;SAVE FOR LATER
  420.     RAR ! RAR ! RAR ! RAR
  421.     ANI    0FH    ;GET DIGIT
  422.     ORI    '0'    ;MAKE ASCII
  423.     MOV    M,A    ;STORE IT
  424.     POP    PSW    ;GET LOW ORDER
  425.     ANI    0FH    ;MAKE 0-9
  426. PRTLT10    ORI    '0'    ;CONVERT TO ASCII
  427.     INX    H
  428.     MOV    M,A
  429. ;
  430. ;NOW, FORMAT #K USED, AND TOTAL DISK SIZE
  431. ;
  432.     LHLD    TOTBITS
  433.     PUSH    H        ;SAVE TOTAL
  434.     XCHG
  435.     LXI    H,ALOCTOT+3
  436.     CALL    ASCICON    ;CONV TO ASCII
  437.     LHLD    TOTBITS    ;GET TOT
  438.     XCHG        ;TO DE
  439.     LHLD    TOTFREE    ;GET # FREE
  440.     MOV    A,E
  441.     SUB    L
  442.     MOV    E,A
  443.     MOV    A,D
  444.     SBB    H
  445.     MOV    D,A    ;DE = TOT USED
  446. ;
  447. ;SUBTRACT OUT DIRECTORY SIZE
  448. ;    
  449.     LDA    DIRK
  450.     CMA
  451.     MOV    L,A
  452.     MVI    H,0FFH
  453.     INX    H        ;MAKE 2'S COMPLEMENT
  454.     DAD    D
  455.     PUSH    H        ;SAVE #K USED
  456.     XCHG
  457.     LXI    H,ALOCUSD+3
  458.     CALL    ASCICON
  459. ;
  460. ;COMPUTE % FULL: (USED*100)/TOT
  461. ;
  462.     POP    B        ;GET # USED
  463.     MOV    H,B
  464.     MOV    L,C        ;COPY TO HL
  465.     MVI    E,0        ;INIT "OVERFLOW" BYTE
  466.     CALL    X2        ;X2
  467.     INX    H        ;ROUND UP .5K
  468.     CALL    A1        ;+1=3
  469.     CALL    X2        ;X6
  470.     CALL    X2        ;X12
  471.     CALL    X2        ;X24
  472.     CALL    A1        ;X25
  473.     CALL    X2        ;X50
  474.     CALL    X2        ;X100
  475. ;
  476. ;E,H,L HOW CONTAIN 24 BIT "100 TIMES #K USED".
  477. ;
  478.     POP    B        ;GET TOTAL K ON DISK
  479.     MOV    A,C
  480.     CMA
  481.     MOV    C,A
  482.     MOV    A,B
  483.     CMA
  484.     MOV    B,A
  485.     INX    B        ;BC = NEGATIVE
  486.     MVI    D,0FFH        ;INIT QUOTIENT TO -1
  487. ;
  488. DIVIDE    INR    D        ;BUMP QUOTIENT
  489.     DAD    B        ;"SUBTRACT"
  490.     MOV    A,E
  491.     ACI    0FFH        ;EXTEND "SUBTRACT" TO 24 BITS
  492.     MOV    E,A
  493.     JC    DIVIDE
  494.     MOV    E,D
  495.     MVI    D,0
  496.     LXI    H,PERCENT+1
  497.     MVI    M,' '
  498.     INX    H
  499.     MVI    M,' '
  500. ;
  501. ;NOW CONVERT TO DECIMAL, HL POINTS TO LOW ORDER ASCII
  502. ;
  503.     CALL    ASCICON
  504. ;
  505. ;PRINT THE MESSAGE, SUPPRESSING REDUNDANT ' ' SO
  506. ;    IT "LOOKS NICER"
  507. ;
  508.     LXI    H,STATS
  509.     MVI    B,' '    ;INIT PREV CHAR
  510. NBPR    MOV    A,M    ;GET CHAR
  511.     INX    H
  512.     ORA    A    ;DONE? (=00)
  513.     JZ    DONE    ;    YES, EXIT
  514.     CPI    ' '    ;SPACE?
  515.     JNZ    NBNSP    ;    NO
  516.     CMP    B    ;COMPARE TO PREV CHAR
  517.     JZ    NBPR
  518. NBNSP    MOV    B,A    ;SAVE FOR NEXT COMPARE
  519.     CPI    '('    ;TREAT '(' AS SPACE SO
  520.     JNZ    NBTYPE    ;    "(nK" is not "( nK"
  521.     MVI    B,' '
  522. NBTYPE    CALL    TYPE
  523.     JMP    NBPR
  524. ;
  525. ;MULTIPLY E-H-L BY 2
  526. ;
  527. X2    DAD    H        ;MULTIPLY HL BY 2, CARRY?
  528.     MOV    A,E        ;GET 3
  529.     RAL            ;SHIFT, WITH CARRY IF ON
  530.     MOV    E,A
  531.     RET
  532. ;
  533. ;ADD BC TO E-H-L
  534. ;
  535. A1    DAD    B
  536.     RNC
  537.     INR    E
  538.     RET
  539. ;
  540. STATS    DB    CR,LF
  541. KPERBIT    DB    1,' K/bit; '    ;1 IS CONVERTED TO ASCII
  542. ALOCDIR    DB    '   0K dir. + '
  543. ALOCUSD    DB    '   0K files +'
  544. ALOCFRE    DB    '   0K free = '
  545. ALOCTOT    DB    '   0K total.',CR,LF
  546. PERCENT    DB    ' ??% full',cr,lf,0
  547. ;
  548. ;COMPUTE THE DIRECTORY SIZE
  549. ;
  550. COMPDIR    PUSH    PSW
  551.     MOV    H,B
  552.     MOV    L,C    ;BIT MAP TO HL
  553.     MVI    B,16    ;# OF SHIFTS
  554.     MVI    C,0    ;# OF BITS IN DIR
  555. CDSHFT    DAD    H    ;SHIFT OFF A BIT
  556.     JNC    CDNOCY
  557.     INR    C
  558. CDNOCY    DCR    B
  559.     JNZ    CDSHFT
  560.     MOV    A,C    ;GET BITS/DIR
  561.     STA    DIRSIZE
  562.     XCHG
  563.     POP    PSW    ;GET SHIFT FACTOR
  564.     PUSH    PSW
  565.     PUSH    H
  566.     SUI    3    ;=0 IF 1K BLOCKS
  567.     MOV    C,A    ;SHIFT COUNT TO C
  568.     LDA    DIRSIZE
  569.     MOV    B,A
  570.     JZ    CDADD    ;GO ADD IT IN
  571. CDSHK    ADD    A    ;MULT BY 2
  572.     MOV    B,A    ;SAVE FOR ADD LOOP LATER
  573.     DCR    C    ;MORE?
  574.     JNZ    CDSHK    ;SHIFT TO COMPUTE #K
  575.     MOV    A,B
  576.     STA    DIRK
  577. CDADD    LXI    H,ALOCDIR+3
  578.     CALL    ADD1    ;ADD 1 IN ASCII
  579.     DCR    B
  580.     JNZ    CDADD
  581.     POP    H
  582.     POP    PSW
  583.     RET
  584. ;
  585. ;PRINT A 'D' FOR EVERY DIR ENTRY BIT
  586. ;    AND ADJUST STARTING BIT MAP
  587.  
  588. PRINTD    LDA    DIRSIZE
  589.     MOV    C,A
  590.     MVI    B,80H    ;INIT MASK
  591.  
  592. CDPRTD    LDA    PASS
  593.     CPI    2    ;PRINT IF PASS TWO
  594.     MVI    A,'D'
  595.     CZ    TYPE
  596.  
  597.     LDA    COL
  598.     INR    A
  599.     STA    COL
  600.  
  601.     MOV    A,B    ;GET MASK
  602.     CALL    RIGHT    ;ROTATE RIGHT,
  603.     MOV    B,A    ;    BUMPS H IF OVERFLOW
  604.  
  605.     DCR    C
  606.     JNZ    CDPRTD
  607.  
  608.     MOV    A,B    ;GET INITIAL MASK
  609.     RET
  610. ;
  611. ;EXIT PRINTING MSG FOLLOWING CALL EXIT
  612. ;
  613. EXIT    POP    D
  614.     MVI    C,PRINT
  615.     CALL    BDOS
  616. DONE    LHLD    STACK
  617.     SPHL        ;RESTORE IT
  618.     RET
  619. ;
  620. ;
  621. ;CONVERT GROUPS (IN HL) INTO K
  622. GRPS2K    LDA    BSH    ;RESTORE BLOCK-SHIFT FACTOR
  623.  
  624. GRPLP    CPI    3    ;DOWN TO 1K?
  625.     RZ
  626.     DAD    H    ;MULTIPLY HL BY 2
  627.     DCR    A
  628.     JMP    GRPLP
  629.  
  630. ;
  631. ;
  632. ;====>    K2GRPS    TAKES HL, WHICH IS # OF K TO
  633. ;        ALLOCATE, AND CONVERTS IT INTO
  634. ;        THE # OF BITS TO TURN OFF
  635. ;
  636. K2GRPS    LDA    BSH    ;RESTORE BLOCK-SHIFT FACTOR
  637.  
  638. K2GP1    CPI    3    ;DOWN TO 1K?
  639.     JZ    K2GP9
  640.     CALL    HALFH    ;DIVIDE HL IN HALF
  641.     DCR    A
  642.     JMP    K2GP1
  643. ;
  644. ;DONE:  PUT OUT MESSAGE IF ROUNDED DOWN
  645. K2GP9    LDA    ROUND
  646.     ORA    A
  647.     RZ            ;RETURN IF NO ROUNDING
  648.  
  649.     LDA    PASS        ;DON'T PRINT MESSAGE DURING PASS 1
  650.     CPI    1
  651.     RZ
  652.  
  653.     LXI    D,ROUNDMS
  654.     MVI    C,PRINT
  655.     PUSH    H
  656.     CALL    BDOS
  657.     POP    H
  658.  
  659.     RET
  660. ;
  661. ROUNDMS    DB    '++ K to "zap" rounded down '
  662.     DB    'to whole blocks ++',CR,LF,'$'
  663. ;
  664. ;DIVIDE HL BY 2
  665. ;
  666. HALFH    PUSH    PSW    ;SAVE
  667.     ORA    A    ;CLEAR CARRY
  668.     MOV    A,H
  669.     RAR
  670.     MOV    H,A    ;H= .5 H
  671.     MOV    A,L
  672.     RAR
  673.     MOV    L,A    ;L= .5 L
  674.     LDA    ROUND    ;GET PREV ROUND (0 IF NONE)
  675.     ACI    0    ;ADD 1 IF CARRY SET
  676.     STA    ROUND    ;STORE BACK, 0 IF NO ROUND
  677.     POP    PSW
  678.     RET
  679. ;
  680. ;====>    ZAPEM    TURNS OFF THE REQUESTED # OF BITS IN MEMORY
  681. ;
  682. ZAPEM    LDA    PASS    ;EXIT UNLESS PASS TWO
  683.     CPI    2
  684.     RNZ
  685.  
  686.     PUSH    D    ;SAVE # BITS IN MAP
  687.     PUSH    H    ;SAVE POINTER TO BITMAP
  688.     LHLD    ZAP    ;GET # TO ZAP OFF
  689.     MOV    B,H    ;BC
  690.     MOV    C,L    ;    = # TO ZAP
  691.     POP    H    ;HL = POINTER
  692.     PUSH    H
  693.     MVI    A,80H    ;INITIAL BIT MASK
  694. ZAPLP    PUSH    PSW    ;SAVE MASK
  695.     ANA    M    ;CANDIDATE TO ZAP?
  696.     JNZ    ZAPNO    ;    NO
  697. ;
  698. ;GOT ONE TO ZAP, ANY MORE REQUESTED?
  699. ;
  700.     MOV    A,B    ;IS BC
  701.     ORA    C    ;    =0?
  702.     JZ    ZAPPED    ;    YA, WE ARE DONE
  703.     DCX    B    ;    NO, SO COUNT IT
  704.     POP    PSW    ;GET MASK
  705.     PUSH    PSW    ;SAVE BACK
  706.     ORA    M    ;TURN ON (TUNE IN, DROP OUT?)
  707.     MOV    M,A    ;PUT BACK
  708. ;
  709. ;POINT TO NEXT BIT
  710. ;
  711. ZAPNO    DCX    D    ;DECREMENT BIT MAP SIZE
  712.     MOV    A,D    ;IS DE
  713.     ORA    E    ;    =0?
  714.     JZ    ZAPPED    ;    YES, WE ARE DONE
  715. ;
  716. ;NOT DONE, FIND NEXT BIT TO TEST
  717. ;
  718.     POP    PSW    ;GET MASK
  719.     ORA    A    ;CLEAR CARRY
  720.     RRC        ;SHIFT AROUND, AND TO CARRY
  721.     JNC    ZAPLP    ;LOOP IF STILL IN BYTE
  722.     INX    H    ;TO NEXT BYTE
  723.     JMP    ZAPLP
  724. ;
  725. ZAPPED    POP    PSW    ;DELETE BIT MASK
  726.     POP    H    ;PUT THINGS
  727.     POP    D    ;    BACK
  728.     RET
  729.  
  730. ;MOVE FCB2'S DISK AND NAME TO FCB1
  731. MOVFCB    MVI    B,12
  732.     LXI    D,FCB
  733.     LXI    H,FCB2
  734. MOVFCB1    MOV    A,M
  735.     STAX    D
  736.     INX    D
  737.     INX    H
  738.     DCR    B
  739.     JNZ    MOVFCB1
  740.     RET
  741. ;
  742.  
  743.  
  744. ;CLEAR A LARGE AREA, TO USE AS MAP FOR SPECIFIED FILE (IF ANY)
  745. MAKMAP    LXI    D,8*1024    ;8K (1 GROUP PER BYTE) SHOULD SUFFICE
  746.     LXI    H,GROUPS
  747.     MVI    B,0
  748.  
  749. MAKMAP1    MOV    M,B    ;CLEAR GROUP AREA FOR THIS FILE
  750.     INX    H
  751.     DCX    D
  752.     MOV    A,D
  753.     ORA    E
  754.     JNZ    MAKMAP1
  755.  
  756.     RET
  757.  
  758.  
  759. ;FIGURE DIRECTORY BYTES PER GROUP-NUMBER AND GROUP-NUMBERS PER ENTRY.
  760. GETGRPS    LHLD    TOTBITS
  761.     DCX    H
  762.  
  763.     MOV    A,H
  764.     ORA    A        ;IS DISK CAPACITY <= 256 GROUPS?
  765.  
  766.     MVI    H,1
  767.     MVI    L,16
  768.     JZ    GRPS0        ;  YES, 1 BYTE/GROUP, 16 GROUPS/ENTRY
  769.  
  770.     MVI    H,2        ;  NO, 2 BYTES/GROUP, 8 GROUPS/ENTRY
  771.     MVI    L,8
  772.  
  773. GRPS0    SHLD    BGE        ;SAVE BYTES/GROUP AND GROUPS/BYTE
  774.  
  775. ;BUILD MAP FOR THIS FILE
  776.     LXI    D,FCB
  777.     MVI    A,'?'
  778.     STA    FCBEXT        ;SET FOR NEXT DIR ENTRY OF THIS FILE
  779.  
  780.     MVI    A,SEARCH
  781.     STA    SERCHCD        ;FIRST SEARCH ON THIS FILE
  782.     JMP    GRPS5
  783.  
  784. ;GROUP-SEARCHING LOOP
  785. GRPS1
  786.     LHLD    BGE        ;LOAD BYTES/GROUP AND GROUPS/ENT PARMS
  787.     MOV    B,H        ;BYTES/GROUP TO B
  788.     MOV    C,L        ;GROUPS/ENTRY TO C
  789.  
  790.     DCR    A
  791.     MOV    L,A
  792.     MVI    H,0
  793.  
  794.     DAD    H    ;X 32 TO GET OFFSET OF DIRECTORY ENTRY
  795.     DAD    H
  796.     DAD    H
  797.     DAD    H
  798.     DAD    H
  799.  
  800.     LXI    D,TBUFF        ;ADDRESS DESIRED DIRECTORY ENTRY
  801.     DAD    D
  802.  
  803.     LXI    D,16
  804.     DAD    D        ;ADDRESS DIR ENTRY'S GROUP NUMBERS
  805.  
  806.     MVI    D,0        ;INITIALIZE HIGH BYTE OF GROUP NUMBER
  807.  
  808. ;COUNT THIS GROUP
  809. GRPS3    MOV    E,M
  810.     INX    H        ;GET GROUP NUMBER INTO DE
  811.  
  812.     MOV    A,B
  813.     DCR    A
  814.     JZ    GRPS4        ;IF 1 BYTE/GROUP-NUMBER, SKIP
  815.  
  816.     MOV    D,M
  817.     INX    H
  818.  
  819.     MOV    A,D
  820. GRPS4    ORA    E
  821.     JZ    GRPS5        ;IF END OF GROUPS, QUIT THIS ENTRY
  822.  
  823.     PUSH    H
  824.  
  825.     LXI    H,GROUPS
  826.     DAD    D
  827.     MVI    M,FILMRK    ;SET ON "BIT" IN THIS FILE'S MAP
  828.  
  829.     LHLD    ZAPHOLD        ;INCREMENT COUNT OF FILE'S GROUPS
  830.     INX    H
  831.     SHLD    ZAPHOLD
  832.  
  833.     POP    H
  834.  
  835.     DCR    C        ;COUNTDOWN GROUPS IN THIS ENTRY
  836.     JNZ    GRPS3
  837.  
  838. ;SEARCH FOR NEXT ENTRY FOR FILENAME
  839. GRPS5
  840.     LDA    SERCHCD
  841.     MOV    C,A
  842.     MVI    A,SERCHNX
  843.     STA    SERCHCD        ;NEXT SEARCH SHOULD BE "SEARCH NEXT"
  844.     CALL    BDOS
  845.     INR    A
  846.     JNZ    GRPS1        ;MORE ENTRIES? CONTINUE
  847.  
  848. ;ALL FILENAME'S ENTRIES ACCOUNTED FOR
  849.     LDA    MINUS
  850.     CPI    YES
  851.     JZ    GRPS9
  852.  
  853.     LXI    H,0
  854.     SHLD    ZAPHOLD        ;SET ZAP COUNT TO ZERO UNLESS "ALL BUT".
  855.     RET
  856.  
  857. GRPS9    LHLD    ZAPHOLD
  858.     CALL    GRPS2K        ;CONVERT GROUP COUNT INTO K COUNT
  859.     SHLD    ZAPHOLD
  860.     RET
  861.  
  862.  
  863.  
  864.  
  865. ;====>    GETDEC    GETS DECIMAL VALUE, STORES IN HL.
  866. ;        SETS CARRY IF ERROR.
  867. ;        BC POINTS TO INPUT.  SPACE TERMINATES
  868. ;
  869. GETDEC    LXI    H,0    ;INIT RESULT
  870.     LXI    B,FCB+1    ;INIT BC TO OPTION STRING
  871. GETDLP    LDAX    B    ;TO NEXT
  872.     INX    B
  873.  
  874.     CPI    ' '    ;END DELIM?
  875.     JNZ    GETDLP1    ;  NO, CONTINUE
  876.     SHLD    ZAPHOLD
  877.     RET
  878.  
  879. GETDLP1    CPI    '0'    ;BAD?
  880.     RC        ;    YES, RET W/CARRY
  881.     CPI    '9'+1    ;SET CARRY IF 0-9
  882.     CMC        ;FLIP CARRY
  883.     RC        ;RET IF NOT 0-9
  884.  
  885. ;GOT 0-9, MULT PREV BY 10
  886.     MOV    D,H    ;SET UP
  887.     MOV    E,L    ;    FOR MULT
  888.     DAD    H    ;X2
  889.     DAD    H    ;X4
  890.     DAD    D    ;X5
  891.     DAD    H    ;X10
  892. ;ADD IN THIS DIGIT
  893.     SUI    '0'    ;DELETE ASCII BIAS
  894.     ADD    L    ;ADD IT IN
  895.     MOV    L,A    ;PUT BACK
  896.     JNC    GETDLP    ;LOOP IF NO CARRY TO H
  897.     INR    H    ;PROPAGATE CARRY
  898.     JMP    GETDLP    ;    THEN LOOP
  899.  
  900. ;
  901. ;TYPE CRLF IF HAVEN'T BEEN INTERRUPTED, AND IF NOT PASS 1
  902. ;
  903. SCRLF    LDA    INTERR
  904.     ORA    A
  905.     JNZ    CRLF0    ;JUST RESET COLUMN
  906.  
  907.     LDA    PASS
  908.     CPI    1
  909.     JZ    CRLF0    ;SKIP IF PASS 1
  910. ;
  911. ;CR/LF, AND SET COLUMN TO 0
  912. ;
  913. CRLF    MVI    A,CR
  914.     CALL    TYPE
  915.     MVI    A,LF
  916.     CALL    TYPE
  917. CRLF0    XRA    A
  918.     STA    COL
  919.     RET
  920. ;
  921. ;CONVERT NUMBER IN DE TO ASCII, STORE AT (HL)
  922. ;    (HL POINTS TO LOW-ORDER ASCII DIGIT)
  923. ;
  924. ASCICON    PUSH    H    ;SAVE LOW ORDER
  925. ASCICLP    POP    H
  926.     MOV    A,D
  927.     ORA    E
  928.     RZ        ;RET IF DONE
  929.     PUSH    H
  930.     CALL    ADD1    ;BUMP IN ASCII
  931.     DCX    D    ;DECREMENT DECIMAL COUNT
  932.     JMP    ASCICLP
  933. ;
  934. ;ADD 1 IN ASCII
  935. ;
  936. ADD1    MOV    A,M
  937.     ORI    '0'
  938.     INR    A
  939.     MOV    M,A
  940.     CPI    '9'+1
  941.     RNZ
  942.     MVI    M,'0'
  943.     DCX    H
  944.     JMP    ADD1
  945. ;
  946. ;TYPE CHAR UNLESS INTERRUPT FLAG SET, OR PASS 1
  947. ;
  948. STYPE    PUSH    PSW    ;SAVE CHAR
  949.     LDA    INTERR
  950.     ORA    A    ;PREVIOUSLY INTERRUPTED?
  951.     JNZ    SNOTYPE    ;    YES, DON'T TYPE
  952.  
  953.     LDA    PASS
  954.     CPI    1
  955.     JZ    SNOTYPE    ;SKIP IF PASS 1
  956.  
  957.     POP    PSW
  958.     JMP    TYPE    ;TYPE THE CHARACTER
  959. ;
  960. SNOTYPE    POP    PSW
  961.     RET
  962. ;
  963. ;TYPE CHAR IN A, SAVE ALL REGS;
  964. ;    TEST FOR BEING INTERRUPTED;
  965. ;    SAVE CHAR IN "INTERR";
  966. ;    ABORT IF ^C
  967. ;
  968. TYPE    PUSH    B
  969.     PUSH    D
  970.     PUSH    H
  971.     MVI    C,WRCON    ;WRITE
  972.     MOV    E,A    ;    THE
  973.     CALL    BDOS    ;    CHAR
  974.     MVI    C,CONST    ;TEST CONSOLE
  975.     CALL    BDOS    ;    STATUS
  976.     ORA    A    
  977.     JZ    NOCONST    ;IF NONE, RETURN
  978.     MVI    C,RDCON    ;READ THE CHAR    
  979.     CALL    BDOS
  980.     STA    INTERR
  981.     CPI    'C'-40H    ;^C?
  982.     JZ    DONE
  983. NOCONST    POP    H
  984.     POP    D
  985.     POP    B
  986. FUNCT    RET
  987. ;
  988. SIGNON    DB    'ALLOC as of 04/10/82. '
  989.     DB    'Type ALLOC H for help',CR,LF,'$'
  990. ZAP    DW    0    ;# BITS TO ZAP
  991. ROUND    DB    0    ;ROUNDING LOSS?
  992. INTERR    DB    0    ;NON-0 IF INTERRUPTED
  993. COL    DB    0    ;CR/LF AFTER 50
  994. ZAPHOLD    DW    0
  995.  
  996. MINUS    DS    1    ;IS MINUS-OPTION BEING INVOKED? (YES OR NO)
  997. PASS    DS    1    ;PASS 1 DOESN'T PRINT OR ZAP, JUST COMPUTES
  998. BSH    DS    1    ;SAVE AREA FOR BLOCK SHIFT FACTOR
  999. BGE    DS    2    ;# BYTES USED IN GIVING GROUP NUMBER (1 OR 2),
  1000.             ; AND # GROUPS IN ONE DIR ENTRY (16 OR 8)
  1001. SERCHCD    DS    1    ;"SEARCH FIRST" OR "SEARCH NEXT" FUNCTION CODE
  1002. DIRSIZE    DS    1    ;BITS ON FOR DIRECTORY
  1003. DIRK    DS    1    ;#K IN DIRECTORY
  1004. TOTFREE    DS    2
  1005. TOTBITS    DS    2
  1006. MAPINX    DS    2
  1007.     DS    200
  1008. STACK    DS    2
  1009. ;
  1010. ;BDOS EQUATES
  1011. ;
  1012. RDCON    EQU    1
  1013. PRINT    EQU    9
  1014. CONST    EQU    11    ;0BH
  1015. LOGIN    EQU    14    ;0EH    0=A
  1016. GETVERS    EQU    12    ;0CH
  1017. SEARCH    EQU    17
  1018. SERCHNX    EQU    18
  1019. GETPARM    EQU    31    ;1FH
  1020. INQALC    EQU    27    ;1BH
  1021. WRCON    EQU    2
  1022.  
  1023. ;
  1024. BDOS    EQU    5
  1025. FCB    EQU    5CH 
  1026. FCBEXT    EQU    FCB+12
  1027. FCB2    EQU    FCB+16
  1028. TBUFF    EQU    80H
  1029. CR    EQU    0DH
  1030. LF    EQU    0AH
  1031.  
  1032. FILMRK    EQU    '*'        ;CHAR TO MARK FILE'S GROUPS IN BIT MAP
  1033. NO    EQU    0
  1034. YES    EQU    1
  1035.  
  1036. ;START OF AREA USED IN MAPPING GROUPS FOR OPERAND
  1037. GROUPS    EQU    $
  1038.