home *** CD-ROM | disk | FTP | other *** search
- ;
- ; BITMAP for CP/M 2.0+ as of 12/21/80
- ;
- ;
- ; By: Lauren Guimont
- ; 14211 8th Avenue South
- ; Seattle, Washington 98168
- ; (206) 246-5615
- ;
- ;
- ;
- ;The bitmap idea is based upon Ward Christensen's original
- ; bitmap program, which refused to run on 2.0+ systems.
- ; After giving his program a quick going over with SID, I
- ; decided it would be easier to rewrite it than to try and
- ; patch it for 2.0, 2.1, 2.2, etc.
- ;
- ;Addition of binary to decimal routine, printing of disk
- ; space left, and general clean up of the block allocation
- ; sizing routines on 7/1/80 by Steve Vinokuroff.
- ;
- ;Correction of a bug in the block size allocation routine
- ; and reformatted the terminal output on 7/6/80 by
- ; Lauren Guimont.
- ;
- ;Added print out of total disk R/W capacity on 7/14/80
- ; by Lauren Guimont.
- ;
- ;Added print out of the space already used on the disk.
- ; Use this often when wishing to know if the files on
- ; a DD disk will fit on a SD disk. On 8/26/80 by
- ; Lauren Guimont
- ;
- ;Located bug in computing R/W space. It didn't show up
- ; until the disk block size reached or exceeded 4K. On
- ; 12/21/80 by Lauren Guimont.
- ;
- ;
- ; ***** EQUATES *****
- ;
- base equ 0 ; "normal" CP/M
- bdos equ base+5 ; jump to bdos
- ochar equ 2 ; BDOS console output
- sdsk equ 14 ; select disk
- curdsk equ 25 ; current disk
- gtaloc equ 27 ; get allocation address
- dskpar equ 31 ; get disk parameters
- fcb equ base+5ch ; file control block
- ;
- ;
- ;
- ;
- org base+100h ; start of "normal" TPA
-
- lxi h,0 ; clear <HL>
- dad sp ; load <HL> with CCP <SP>
- shld oldsp ; save it for later
- lxi sp,stack ; initialize our own <SP>
- jmp start ; bypass some subroutines
- ds 48 ; stack space
- stack equ $ ; our own stack
- oldsp ds 2 ; old stack pointer from CCP
- ;
- inlprt: ; in line print
- xthl ; <HL> to stack/pointer to <HL>
- inlprt1 mov a,m ; get a character
- inx h ; increment the pointer
- cpi '$' ; endmark?
- jz inlprt2 ; if so, prepare to exit
- call conout ; output to console
- jmp inlprt1 ; go get another
- inlprt2 xthl ; orig <HL>/<SP> at end of msg
- ret ; return to end of msg
- ;
- conout push h ; single character console
- push d ; ...output; 1st save all
- push b ; ...the registers
- push psw
- mvi c,ochar ; tell BDOS
- mov e,a ; BDOS wants it in <E>
- call bdos ; let BDOS do it
- pop psw ; reinstate all registers
- pop b
- pop d
- pop h
- ret ; return to caller
- ;
- crlf call inlprt ; use in line print
- db 0dh,0ah,'$' ; ...for cr & lf
- ret ; return to caller
- ;
- one push psw ; save <A> and <PSW>
- mvi a,'1' ; print a '1' to console
- call conout ; do it
- pop psw ; restore <A> and <PSW>
- ret ; return to caller
- ;
- zero push psw ; save <A> and <PSW>
- mvi a,'0' ; print a '0' to console
- call conout ; do it
- pop psw ; restore <A> and <PSW>
- ret ; return to caller
- ;
- zero1 push h ; save <HL>
- lhld free ; get number of free blocks
- inx h ; add one
- shld free ; store total free count
- pop h ; restore <HL>
- ret ; return to caller
- ;
- ;Binary to decimal output routine. Enter with 8 bit binary
- ; number in <A>. Second entry at BNDEC2 assumes 16 bit
- ; number in <HL>.
- ;
- bndec1 mvi h,0 ; enter here for value of <A>
- mov l,a ; <HL> now has it
- ;
- bndec2 push b ; enter here for value of <HL>
- push d
- push h
- lxi b,-10
- lxi d,-1
- bndc dad b
- inx d
- jc bndc
- lxi b,10
- dad b
- xchg
- mov a,h
- ora l
- cnz bndec2
- mov a,e
- adi '0'
- call conout
- pop h
- pop d
- pop b
- ret
- ;
- err1 call inlprt ; in line print
- db 0dh,0ah,'Nonstandard disk '
- db 'parameter block error'
- db 0dh,0ah,'$'
- ;
- finis lhld oldsp ; get CCP <SP>
- sphl ; retore it
- ret ; direct return to CCP
- ;
- ;We need a little internal storage
- ;
- drive ds 1 ; current drive
- aldrv ds 1 ; alternate specified drv
- dpb ds 2 ; disk parameter block add
- tbtr ds 2 ; total bits to read
- alloc ds 2 ; allocation address
- blksiz ds 1 ; block size code
- totdsk ds 2 ; total disk space
- usedsp ds 2 ; used disk space
- free dw 0 ; count of free blocks
- ;
- ;The actual start of it all
- ;
- start lda fcb ; get any alternate drv
- sta aldrv ; save it for later
- call inlprt ; in line print
- db 0ah,'BITMAP 2.2 '
- db ' as of '
- db '12/21/80',0dh,0ah,'$'
- mvi c,curdsk ; get current disk in
- call bdos ; ...use from BDOS
- sta drive ; save it
- lda aldrv ; get any alternate drv
- ora a ; any specified?
- jz dpblk ; if not, skip next
- dcr a ; less one
- sta drive ; save as drive to use
- ;
- dpblk lda drive ; get drive to bitmap
- mvi c,sdsk ; set call for disk select
- mov e,a ; bdos wants it in <E>
- call bdos ; let BDOS do it
- mvi c,dskpar ; we want dsk parameter blk
- call bdos ; get it, and.....
- shld dpb ; ...save it
- lxi d,5 ; offset for total blks used
- dad d ; add it to <HL>
- mov e,m ; lsb into <E>
- inx h ; point to msb
- mov d,m ; get it
- xchg ; put it in <HL>...
- inx h ; alloc size = (dsm/8)+1
- shld tbtr ; ...and save it
- lhld dpb ; get dsk parameter blk add
- inx h ; ...and increment <HL> to
- inx h ; ...the 3rd byte
- mov a,m ; it has the block size
- sui 2 ; it will be 3-7 (make it 1-5)
- cpi 5+1 ; check for over 5
- jnc err1 ; nonstandard size
- cpi 1 ; check for less than 1
- jc err1 ; nonstandard size
- push psw ; save it
- call inlprt ; in line print
- db 'Allocated disk block size is $'
- pop psw ; get block size back
- sta blksiz ; save it for end
- lxi h,512 ; start at half of smallest size
- lp dad h ; block size doubles each time
- dcr a ; less block size code count
- jnz lp ; loop till <A>=0
- call bndec2 ; print size in "K"
- ;
- dpbend call inlprt ; finish message
- db ' bytes per block',0dh,0ah,'$'
- ;
- ;Now let's print out the total disk R/W capacity
- ;
- lda blksiz ; get the block size
- mov c,a ; stuff it in <C>
- mvi a,1 ; start with 1"K"
- lhld tbtr ; total bits (blks) to read
- push h ; also into <DE>...
- pop d ; ...via the stack
- getsz dcr c ; found block size yet?
- jz getsz1 ; if so, go find total R/W
- add a ; double the block size
- jmp getsz ; go do it again
- getsz1 dcr a ; end of addition?
- jz getsz2 ; if zero it is
- dad d ; add it in
- jmp getsz1 ; keep adding until <A>=0
- getsz2 shld totdsk ; save total disk capacity
- call inlprt ; in line print
- db 'Total disk R/W capacity on drive $'
- lda drive ; get specified drive
- adi 'A' ; make it ascii
- call conout ; send it out
- call inlprt ; in line print
- db ': $' ; finish lead in statement
- call bndec2 ; output <HL> as decimal
- call inlprt ; in line print
- db 'K',0dh,0ah,'$'
- ;
- ;Now prepare to print actual R/W left on disk
- ;
- lhld tbtr ; total bits to read
- push h ; save it in the stack
- lda drive ; again to be safe
- mov e,a ; into <E> for BDOS
- mvi c,sdsk ; reselect disk
- call bdos ; let BDOS do it
- mvi c,gtaloc ; get the allocation address
- call bdos ; ...from BDOS...
- shld alloc ; ...and save it
- pop d ; total bits to read from stack
- dcx h ; back allocation up one
- ;
- ;
- ;We now have the total number of bits to read in <DE>, and
- ; the address to start reading them at in <HL> for the
- ; proper drive. So now let's compute the free disk space.
- ;
- ;
- bmap1a inx h ; kick the pointer
- mov a,m ; get the byte
- mvi b,8 ; it has 8 bits
- bmap2a rlc ; runn'em through carry
- cnc zero1 ; carry not set = free block
- dcx d ; decrement total bit count
- push psw ; save the bit pattern
- mov a,d ; check to see if...
- ora e ; ...<DE>=0
- jz prtfre ; print free disk space
- pop psw ; restore bit pattern
- dcr b ; decrement byte bit count
- jz bmap1a ; new byte if zero
- jmp bmap2a ; finish this byte
- ;
- prtfre pop psw ; keep the stack right
- call inlprt ; in line print
- db 'Available R/W space on drive $'
- lda drive ; get drive used
- adi 'A' ; make it ascii
- call conout ; output it to console
- call inlprt ; in line print
- db ': $'
- lda blksiz ; get block size code
- lhld free ; get number of free blocks
- lp1 dcr a ; less one
- jz don ; multiplied by size of block
- dad h ; times 2
- jmp lp1
- ;
- don shld free
- call bndec2 ; print size of free space
- call inlprt ; in line print
- db 'K',0dh,0ah,'$'
- ;
- lhld free ; number of open blocks
- xchg ; into <DE>
- lhld totdsk ; get total disk space
- spused dcx d ; decrement <DE>
- dcx h ; ...and <HL>
- mov a,e ; check to see if...
- ora d ; ...<DE>=0
- jnz spused ; loop until it does
- shld usedsp ; save used disk space
- call inlprt ; in line print
- db 'R/W space used on drive $'
- lda drive ; get drive used
- adi 'A' ; make it ascii
- call conout ; output to console
- call inlprt ; in line print
- db ': $'
- lhld usedsp ; get used space
- call bndec2 ; output <HL> in decimal
- call inlprt ; in line print
- db 'K',0dh,0ah,'$'
- ;
- lhld tbtr ; total bits to read
- xchg ; put'em into <DE>
- lhld alloc ; get allocation address
- dcx h ; back it up one
- ;
- ;
- ;We now have the total number of bits to read in <DE>, and
- ; the address to start reading them at in <HL> for the
- ; proper drive. So now let's print the bitmap.
- ;
- ;
- bmap mvi c,48 ; 1's and 0's per line
- call crlf ; followed by a cr,lf
- bmap1 inx h ; kick the pointer
- mov a,m ; get the byte
- mvi b,8 ; it has 8 bits
- bmap2 rlc ; runn'em through carry
- cc one ; carry set = print '1'
- cnc zero ; carry not set = print '0'
- dcx d ; decrement total bit count
- push psw ; save the bit pattern
- mov a,d ; check to see if...
- ora e ; ...<DE>=0
- jz bmapend ; if so, we're finished
- pop psw ; restore bit pattern
- dcr c ; decrement line count
- jz bmap ; new line if zero
- dcr b ; decrement byte bit count
- jz bmap1 ; new byte if zero
- jmp bmap2 ; finish this byte
- ;
- bmapend pop psw ; not neccessary, but keeps the
- call crlf ; ...stack straight..send cr,lf
- jmp finis ; restore things and GET OUT
- ;
- end
-