home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / SIMTEL / CPMUG / CPMUG078.ARK / BMAPORIG.ASM < prev    next >
Assembly Source File  |  1984-04-29  |  10KB  |  356 lines

  1. ;
  2. ;    BITMAP for CP/M 2.0+        as of 12/21/80
  3. ;
  4. ;
  5. ;   By: Lauren Guimont
  6. ;    14211 8th Avenue South
  7. ;    Seattle, Washington  98168
  8. ;    (206) 246-5615
  9. ;
  10. ;
  11. ;
  12. ;The bitmap idea is based upon Ward Christensen's original
  13. ;  bitmap program, which refused to run on 2.0+ systems.
  14. ;  After giving his program a quick going over with SID, I
  15. ;  decided it would be easier to rewrite it than to try and
  16. ;  patch it for 2.0, 2.1, 2.2, etc.
  17. ;
  18. ;Addition of binary to decimal routine, printing of disk
  19. ;  space left, and general clean up of the block allocation
  20. ;  sizing routines on 7/1/80 by Steve Vinokuroff.
  21. ;
  22. ;Correction of a bug in the block size allocation routine
  23. ;  and reformatted the terminal output on 7/6/80 by
  24. ;  Lauren Guimont.
  25. ;
  26. ;Added print out of total disk R/W capacity on 7/14/80
  27. ;  by Lauren Guimont.
  28. ;
  29. ;Added print out of the space already used on the disk.
  30. ;  Use this often when wishing to know if the files on
  31. ;  a DD disk will fit on a SD disk. On 8/26/80 by
  32. ;  Lauren Guimont
  33. ;
  34. ;Located bug in computing R/W space. It didn't show up
  35. ;  until the disk block size reached or exceeded 4K. On
  36. ;  12/21/80 by Lauren Guimont.
  37. ;
  38. ;
  39. ;        ***** EQUATES *****
  40. ;
  41. base    equ    0        ; "normal" CP/M
  42. bdos    equ    base+5        ; jump to bdos
  43. ochar    equ    2        ; BDOS console output
  44. sdsk    equ    14        ; select disk
  45. curdsk    equ    25        ; current disk
  46. gtaloc    equ    27        ; get allocation address
  47. dskpar    equ    31        ; get disk parameters
  48. fcb    equ    base+5ch    ; file control block
  49. ;
  50. ;
  51. ;
  52. ;
  53.     org    base+100h    ; start of "normal" TPA
  54.  
  55.     lxi    h,0        ; clear <HL>
  56.     dad    sp        ; load <HL> with CCP <SP>
  57.     shld    oldsp        ; save it for later
  58.     lxi    sp,stack    ; initialize our own <SP>
  59.     jmp    start        ; bypass some subroutines
  60.     ds    48        ; stack space
  61. stack    equ    $        ; our own stack
  62. oldsp    ds    2        ; old stack pointer from CCP
  63. ;
  64. inlprt:                ; in line print
  65.     xthl            ; <HL> to stack/pointer to <HL>
  66. inlprt1    mov    a,m        ; get a character
  67.     inx    h        ; increment the pointer
  68.     cpi    '$'        ; endmark?
  69.     jz    inlprt2        ; if so, prepare to exit
  70.     call    conout        ; output to console
  71.     jmp    inlprt1        ; go get another
  72. inlprt2    xthl            ; orig <HL>/<SP> at end of msg
  73.     ret            ; return to end of msg
  74. ;
  75. conout    push    h        ; single character console
  76.     push    d        ; ...output; 1st save all
  77.     push    b        ; ...the registers
  78.     push    psw
  79.     mvi    c,ochar        ; tell BDOS
  80.     mov    e,a        ; BDOS wants it in <E>
  81.     call    bdos        ; let BDOS do it
  82.     pop    psw        ; reinstate all registers
  83.     pop    b
  84.     pop    d
  85.     pop    h
  86.     ret            ; return to caller
  87. ;
  88. crlf    call    inlprt        ; use in line print
  89.     db    0dh,0ah,'$'    ; ...for cr & lf
  90.     ret            ; return to caller
  91. ;
  92. one    push    psw        ; save <A> and <PSW>
  93.     mvi    a,'1'        ; print a '1' to console
  94.     call    conout        ; do it
  95.     pop    psw        ; restore <A> and <PSW>
  96.     ret            ; return to caller
  97. ;
  98. zero    push    psw        ; save <A> and <PSW>
  99.     mvi    a,'0'        ; print a '0' to console
  100.     call    conout        ; do it
  101.     pop    psw        ; restore <A> and <PSW>
  102.     ret            ; return to caller
  103. ;
  104. zero1    push    h        ; save <HL>
  105.     lhld    free        ; get number of free blocks
  106.     inx    h        ; add one
  107.     shld    free        ; store total free count
  108.     pop    h        ; restore <HL>
  109.     ret            ; return to caller
  110. ;
  111. ;Binary to decimal output routine. Enter with 8 bit binary
  112. ;  number in <A>. Second entry at BNDEC2 assumes 16 bit
  113. ;  number in <HL>.
  114. ;
  115. bndec1    mvi    h,0        ; enter here for value of <A>
  116.     mov    l,a        ; <HL> now has it
  117. ;
  118. bndec2    push    b        ; enter here for value of <HL>
  119.     push    d
  120.     push    h
  121.     lxi    b,-10
  122.     lxi    d,-1
  123. bndc    dad    b
  124.     inx    d
  125.     jc    bndc
  126.     lxi    b,10
  127.     dad    b
  128.     xchg
  129.     mov    a,h
  130.     ora    l
  131.     cnz    bndec2
  132.     mov    a,e
  133.     adi    '0'
  134.     call    conout
  135.     pop    h
  136.     pop    d
  137.     pop    b
  138.     ret
  139. ;
  140. err1    call    inlprt        ; in line print
  141.     db    0dh,0ah,'Nonstandard disk '
  142.     db    'parameter block error'
  143.     db    0dh,0ah,'$'
  144. ;
  145. finis    lhld    oldsp        ; get CCP <SP>
  146.     sphl            ; retore it
  147.     ret            ; direct return to CCP
  148. ;
  149. ;We need a little internal storage
  150. ;
  151. drive    ds    1        ; current drive
  152. aldrv    ds    1        ; alternate specified drv
  153. dpb    ds    2        ; disk parameter block add
  154. tbtr    ds    2        ; total bits to read
  155. alloc    ds    2        ; allocation address
  156. blksiz    ds    1        ; block size code
  157. totdsk    ds    2        ; total disk space
  158. usedsp    ds    2        ; used disk space
  159. free    dw    0        ; count of free blocks
  160. ;
  161. ;The actual start of it all
  162. ;
  163. start    lda    fcb        ; get any alternate drv
  164.     sta    aldrv        ; save it for later
  165.     call    inlprt        ; in line print
  166.     db    0ah,'BITMAP 2.2             '
  167.     db    '            as of '
  168.     db    '12/21/80',0dh,0ah,'$'
  169.     mvi    c,curdsk    ; get current disk in
  170.     call    bdos        ; ...use from BDOS
  171.     sta    drive        ; save it
  172.     lda    aldrv        ; get any alternate drv
  173.     ora    a        ; any specified?
  174.     jz    dpblk        ; if not, skip next
  175.     dcr    a        ; less one
  176.     sta    drive        ; save as drive to use
  177. ;
  178. dpblk    lda    drive        ; get drive to bitmap
  179.     mvi    c,sdsk        ; set call for disk select
  180.     mov    e,a        ; bdos wants it in <E>
  181.     call    bdos        ; let BDOS do it
  182.     mvi    c,dskpar    ; we want dsk parameter blk
  183.     call    bdos        ; get it, and.....
  184.     shld    dpb        ; ...save it
  185.     lxi    d,5        ; offset for total blks used
  186.     dad    d        ; add it to <HL>
  187.     mov    e,m        ; lsb into <E>
  188.     inx    h        ; point to msb
  189.     mov    d,m        ; get it
  190.     xchg            ; put it in <HL>...
  191.     inx    h        ; alloc size = (dsm/8)+1
  192.     shld    tbtr        ; ...and save it
  193.     lhld    dpb        ; get dsk parameter blk add
  194.     inx    h        ; ...and increment <HL> to
  195.     inx    h        ; ...the 3rd byte
  196.     mov    a,m        ; it has the block size
  197.     sui    2        ; it will be 3-7 (make it 1-5)
  198.     cpi    5+1        ; check for over 5
  199.     jnc    err1        ; nonstandard size
  200.     cpi    1        ; check for less than 1
  201.     jc    err1        ; nonstandard size
  202.     push    psw        ; save it
  203.     call    inlprt        ; in line print
  204.     db    'Allocated disk block size is $'
  205.     pop    psw        ; get block size back
  206.     sta    blksiz        ; save it for end
  207.     lxi    h,512        ; start at half of smallest size
  208. lp    dad    h        ; block size doubles each time
  209.     dcr    a        ; less block size code count
  210.     jnz    lp        ; loop till <A>=0
  211.     call    bndec2        ; print size in "K"
  212. ;
  213. dpbend    call    inlprt        ; finish message
  214.     db    ' bytes per block',0dh,0ah,'$'
  215. ;
  216. ;Now let's print out the total disk R/W capacity
  217. ;
  218.     lda    blksiz        ; get the block size
  219.     mov    c,a        ; stuff it in <C>
  220.     mvi    a,1        ; start with 1"K"
  221.     lhld    tbtr        ; total bits (blks) to read
  222.     push    h        ; also into <DE>...
  223.     pop    d        ; ...via the stack
  224. getsz    dcr    c        ; found block size yet?
  225.     jz    getsz1        ; if so, go find total R/W
  226.     add    a        ; double the block size
  227.     jmp    getsz        ; go do it again
  228. getsz1    dcr    a        ; end of addition?
  229.     jz    getsz2        ; if zero it is
  230.     dad    d        ; add it in
  231.     jmp    getsz1        ; keep adding until <A>=0
  232. getsz2    shld    totdsk        ; save total disk capacity
  233.     call    inlprt        ; in line print
  234.     db    'Total disk R/W capacity on drive $'
  235.     lda    drive        ; get specified drive
  236.     adi    'A'        ; make it ascii
  237.     call    conout        ; send it out
  238.     call    inlprt        ; in line print
  239.     db    ': $'        ; finish lead in statement
  240.     call    bndec2        ; output <HL> as decimal
  241.     call    inlprt        ; in line print
  242.     db    'K',0dh,0ah,'$'
  243. ;
  244. ;Now prepare to print actual R/W left on disk
  245. ;
  246.     lhld    tbtr        ; total bits to read
  247.     push    h        ; save it in the stack
  248.     lda    drive        ; again to be safe
  249.     mov    e,a        ; into <E> for BDOS
  250.     mvi    c,sdsk        ; reselect disk
  251.     call    bdos        ; let BDOS do it
  252.     mvi    c,gtaloc    ; get the allocation address
  253.     call    bdos        ; ...from BDOS...
  254.     shld    alloc        ; ...and save it
  255.     pop    d        ; total bits to read from stack
  256.     dcx    h        ; back allocation up one
  257. ;
  258. ;
  259. ;We now have the total number of bits to read in <DE>, and
  260. ;  the address to start reading them at in <HL> for the
  261. ;  proper drive. So now let's compute the free disk space.
  262. ;
  263. ;
  264. bmap1a    inx    h        ; kick the pointer
  265.     mov    a,m        ; get the byte
  266.     mvi    b,8        ; it has 8 bits
  267. bmap2a    rlc            ; runn'em through carry
  268.     cnc    zero1        ; carry not set = free block
  269.     dcx    d        ; decrement total bit count
  270.     push    psw        ; save the bit pattern
  271.     mov    a,d        ; check to see if...
  272.     ora    e        ; ...<DE>=0
  273.     jz    prtfre        ; print free disk space
  274.     pop    psw        ; restore bit pattern
  275.     dcr    b        ; decrement byte bit count
  276.     jz    bmap1a        ; new byte if zero
  277.     jmp    bmap2a        ; finish this byte
  278. ;
  279. prtfre    pop    psw        ; keep the stack right
  280.     call    inlprt        ; in line print
  281.     db    'Available R/W space on drive $'
  282.     lda    drive        ; get drive used
  283.     adi    'A'        ; make it ascii
  284.     call    conout        ; output it to console
  285.     call    inlprt        ; in line print
  286.     db    ': $'
  287.     lda    blksiz        ; get block size code
  288.     lhld    free        ; get number of free blocks
  289. lp1    dcr    a        ; less one
  290.     jz    don        ; multiplied by size of block
  291.     dad    h        ; times 2
  292.     jmp    lp1
  293. ;
  294. don    shld    free
  295.     call    bndec2        ; print size of free space
  296.     call    inlprt        ; in line print
  297.     db    'K',0dh,0ah,'$'
  298. ;
  299.     lhld    free        ; number of open blocks
  300.     xchg            ; into <DE>
  301.     lhld    totdsk        ; get total disk space
  302. spused    dcx    d        ; decrement <DE>
  303.     dcx    h        ; ...and <HL>
  304.     mov    a,e        ; check to see if...
  305.     ora    d        ; ...<DE>=0
  306.     jnz    spused        ; loop until it does
  307.     shld    usedsp        ; save used disk space
  308.     call    inlprt        ; in line print
  309.     db    'R/W space used on drive $'
  310.     lda    drive        ; get drive used
  311.     adi    'A'        ; make it ascii
  312.     call    conout        ; output to console
  313.     call    inlprt        ; in line print
  314.     db    ': $'
  315.     lhld    usedsp        ; get used space
  316.     call    bndec2        ; output <HL> in decimal
  317.     call    inlprt        ; in line print
  318.     db    'K',0dh,0ah,'$'
  319. ;
  320.     lhld    tbtr        ; total bits to read
  321.     xchg            ; put'em into <DE>
  322.     lhld    alloc        ; get allocation address
  323.     dcx    h        ; back it up one
  324. ;
  325. ;
  326. ;We now have the total number of bits to read in <DE>, and
  327. ;  the address to start reading them at in <HL> for the
  328. ;  proper drive. So now let's print the bitmap.
  329. ;
  330. ;
  331. bmap    mvi    c,48        ; 1's and 0's per line
  332.     call    crlf        ; followed by a cr,lf
  333. bmap1    inx    h        ; kick the pointer
  334.     mov    a,m        ; get the byte
  335.     mvi    b,8        ; it has 8 bits
  336. bmap2    rlc            ; runn'em through carry
  337.     cc    one        ; carry set = print '1'
  338.     cnc    zero        ; carry not set = print '0'
  339.     dcx    d        ; decrement total bit count
  340.     push    psw        ; save the bit pattern
  341.     mov    a,d        ; check to see if...
  342.     ora    e        ; ...<DE>=0
  343.     jz    bmapend        ; if so, we're finished
  344.     pop    psw        ; restore bit pattern
  345.     dcr    c        ; decrement line count
  346.     jz    bmap        ; new line if zero
  347.     dcr    b        ; decrement byte bit count
  348.     jz    bmap1        ; new byte if zero
  349.     jmp    bmap2        ; finish this byte
  350. ;
  351. bmapend    pop    psw        ; not neccessary, but keeps the
  352.     call    crlf        ; ...stack straight..send cr,lf
  353.     jmp    finis        ; restore things and GET OUT
  354. ;
  355.     end
  356.