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 >
Wrap
Assembly Source File
|
1984-04-29
|
10KB
|
356 lines
;
; 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