BPB-37 (Display BIOS Parameter Block, Version 37)
Post date: Apr 25, 2013 1:46:11 PM
I wrote this in 1989-1990 and published it on 11th November 1992 (!), and found it again, still on the U-Mich Atari ST Archive.
Here is the documentation file:
BPB-37.TOS by Domenico De Vitto <ddv@uk.ac.bton.unix> (only till 1/7/1995)
Well this the first bit o' program that I am going to fling into the
big wide world, and I'm only doing it because I'm off ill and this is one
(the one ?) bit of program that works 100% and cannot be improved
(I think ...) that I have ever wrote.
First it was written many years ago (1989-1990???), not based or idea
copied from anything, it simply tells you all about the boot sector details
of a drive and also gets the lower-screen-half from the TOS, in case you
need to compare the details.
As you all thought that was a copyright notice and naturally skipped it, I
needn't be embarresed further in the document so anwards & upways...
Running it ...
It should have a 'TOS' extention because of its nature but I haven't seen
any difference when it has a PRG or TTP extention so it can be changed.
It is meant to be run from the desktop so don't moan about it clearing
you shell screen, anyway I think it looks nice.
Things it does...
I was going to enter a huge piece of text on its workings but that is
really boring for all the non-programmers, and they can read the source.
This is what it does:
If you're in medium-rez it changes down to low - perfectly legal this
and it's clearer.
Drops the title on the top line.
Gets from the TOS the valid drive letters and displays them.
Gets a key from the keyboard & converts it to uppercase (if a letter!).
If the key is a valid drive letter (bit complex this check) it displays
the drive you selected (now in uppercase).
Reads in the bootsector from the right drive, even if the disc has just
been swapped.
If the read sector call returns non-zero - error - tell the user & skip
the display of the boot sector info.
Otherwaise..
Displays all the info it can about the boot-sector :
Boot branch - 'system disks' & the like use this to load the operating
system, games (can) use it for loading quickly, as do virii.
- if this is 0 you cannie have a boot-sector virus on the disk.(theory?)
Volume serial - used by the system to tell if you swapped disks, every disk
should have a random serial put here at format time for this purpose.
Bytes per sector - $200 (512 decimal) on most disks - if its not the same
at the ACTUAL sector size system may(??) go mad as a sponge.
Sectors per cluster - 'cluster' being the smallest number of sectors one
file can use on the disk, usually 2 (sectors).
Reseerved sectors - always at least one as the boot sector counts as the
first. Used by system-loaders & VERY BIG virii (gulp).
File Allocation Tables (FATs) (number of) - FATs are used to keep track of
all the places on the disk where your files are etc. 'Cause the're so
important there are this many (usually 2) copies updated at the same time.
Max root dir entries - the largest number of files that you can have in
the root dir, usually 128 for floppies. Folders are files and can grow
in size if more file entries (=name,date modified,size in bytes etc)
are needed, but the root dir is a set size and therfore can only hold
a limited number of file entries.
Sectors - the total number of sectorson the media including
reserved sectors, any hidden sectors, the FATs, the root dir and the
'data area' where your files & folders are stored.
Media descripter - this is meant to describe the media type on PCs
ie hard disk, 3.5" floppy etc, etc. should really be $F8, but the TOS
ignores it completely, so it is whatever your formatter sets it to be!
Sectors per FAT - this is the size in sectors of EACH File Allocation
Table.
Sectors per track - The number of sectors per track usually 9 or 10.
therefore TRACKS = (total sectors / sides on media) / sectors per track.
Sides on media - for floppies 1 or 2 is valid, but hard disk controllers
can pull a few tricks on the TOS and pretend there are more 'sides'
- 64 is not unusual.
Hidden sectors - this isn't very well documented anywhere, but I think
these are like 'extra reserved sectors' - comments anyone ?
Calculated dir sector - worked out as :
reserved sectors + hidden sectors + (number of FATs * sectors per FAT)
this should be the first root dir sector.
I have recently used this info to write zeros to this sector and then ran
a file system checker (FCHK.TOS) to clean up the mess and leave me with a
completely clean hard disk partition ! (I wanted this as well!)
Information from the TOS
This info I added to BPB-37 'cause it gives :
Total clusters - should be something like (you may need to +/- 1 ? to this)
(total sectors - system sectors) / sectors per cluster
where system sectors is
calculated dir sector +
( number of root dir entries * 32 / bytes per sector )
Free clusters - the number of free clusters.
Sectors per cluster - a less trustable source of this value than direct
from the boot sector, but what the TOS THINKS it is.
Bytes per sector - likewise.
'Therefore free space' - free space in bytes (using the TOS values) as
free clusters * sectors per cluster * bytes per sector
divided by 1024 to get Kb.
Phew ! After you have read all the info it waits for a keypress (any).
If it was originally in medium rez it changes back and resets the colours
so the system as it was - all legal calls !!!
Then...... it quits back to the calling desktop/shell etc.
Phew ! - all the equations & algos by the way are from the top of my head
so don't trust me, check them yourself.
Notes.
It gives you a lot of info, it fits in 2K (the original version was less
than 1Kb). It was written in assembly using Genst 1.25 (Thanks ST-Format !)
and the book 'The conise atari st 68000 programmer's reference guide'
by Kathrine Peel (one really good book).
Copyrights & the disclaimers
I wrote this software but you use it at your own risk, so don't get me in
court is it causes earthquakes in El-Salvador or something.
You may copy, distribute, BUT NOT SELL IT, modest distribution costs may be
charged - but remember it's FREE.
If you do pass it on you should pass this doc file on with it so that it's
ease of use is not lost down the generations.
Please feel free to use the routines in the source code in your own
programs but bear in mind that once the program all fitted in less than 2K
I paid no attention to speed, effeciency or 'properness' of the code, but
I think that it all works properly !
This doc file is toooooo huge for the program now so just remember this:
If you believe this software to be worth paying for, then pay me 10%
of what it's worth - thats how much I'd get if I marketed it.
Course you could simply send me any tips/advice/good jokes and then we
can get on with the job of writing better software for the ST range.
Any problems/enquiries etc with the program please E-mail me at :
ddv@uk.ac.bton.unix
Yours,
Domenico De Vitto.
And the source MC68000 assembler:
program
bsr setscreen
bsr getdrive
bsr readboot
bsr interpret
bsr extrainfo
bsr pressanykeytoexit
bsr resetscreen
clr.w -(sp)
trap #1
setscreen
move.w #4,-(sp)
trap #14 * get screen mode in d0
addq.l #2,sp
cmp.w #1,d0
bne dontchgmode
move.w d0,screenmode * if med-res save 1 in screenmode
move.w #0,-(sp)
move.l #-1,-(sp)
move.l #-1,-(sp)
move.w #5,-(sp)
trap #14 * change to mode 0
add.l #12,sp
move.l #colregs,-(sp)
move.w #6,-(sp)
trap #14
addq.l #6,sp
dontchgmode
bsr print
dc.b 27,"E","BPB-37 by Domenico De Vitto",0
rts
getdrive
move.w #10,-(sp)
trap #13
addq.l #2,sp
move.l d0,drivemap
bsr showdrives
bsr getdrv
rts
showdrives
bsr print
dc.b 10,13,"Drives Available :",0
even
moveq #0,d7
drvloop
bsr checkdrive
tst d0
bne nextdrv
moveq #65,d0
add.b d7,d0
bsr printchr
nextdrv
addq #1,d7
btst #5,d7
beq drvloop
rts
getdrv
bsr print
dc.b 10,13,"Enter Drive Letter :",0
even
gdrvloop
bsr getkey
bsr convertlu
sub.b #65,d0
bmi gdrvloop
cmp #31,d0
bpl gdrvloop
exg d0,d7
bsr checkdrive
bne gdrvloop
move.w d7,driveselect
exg d0,d7
add.b #65,d0
bsr printchr
rts
readboot
move.w driveselect,-(sp)
move.w #0,-(sp)
move.w #1,-(sp)
move.l #buffer,-(sp)
move.w #2,-(sp) * must be read 2 in order to catch disk changes.
move.w #4,-(sp)
trap #13
add.l #14,sp
rts
interpret
tst d0
beq okdrive
bsr print
dc.b 10,13,"Error Reading Drive",0
even
rts
okdrive
bsr print
dc.b 10,13,27,"p"," From the Boot sector : ",27,"q"
dc.b 10,13,"Branch to boot code :$",0
even
move.w buffer(pc),d0
bsr hexword86
bsr print
dc.b 10,13,"Volume Serial # :$",0
even
move.w buffer+8(pc),d0
bsr hexword86
move.b buffer+10(pc),d0
bsr hexprint
bsr print
dc.b 10,13,"Bytes per sector :$",0
even
move.l buffer+10(pc),d0
ror.l #8,d0
bsr hexword86
bsr print
dc.b 10,13,"Sectors per Cluster :$",0
even
move.w buffer+12(pc),d0
ror.w #8,d0
bsr hexprint
bsr print
dc.b 10,13,"Reserved Sectors (inc. boot) :$",0
even
move.w buffer+14(pc),d0
bsr hexword86
bsr print
dc.b 10,13,"File Allocation Tables (FATs):$",0
even
move.b buffer+16(pc),d0
bsr hexprint
bsr print
dc.b 10,13,"Max Root Directory entries :$",0
even
move.l buffer+16(pc),d0
ror.l #8,d0
bsr hexword86
bsr print
dc.b 10,13,"Sectors (inc reserved) :$",0
even
move.l buffer+18(pc),d0
ror.l #8,d0
bsr hexword86
bsr print
dc.b 10,13,"Media Descripter (not used by TOS) :$",0
even
move.b buffer+21(pc),d0
bsr hexprint
bsr print
dc.b 10,13,"Sectors per FAT :$",0
even
move.w buffer+22(pc),d0
bsr hexword86
bsr print
dc.b 10,13,"Sectors per Track :$",0
even
move.w buffer+24(pc),d0
bsr hexword86
bsr print
dc.b 10,13,"Sides on media :$",0
even
move.w buffer+26(pc),d0
bsr hexword86
bsr print
dc.b 10,13,"Hidden Sectors :$",0
even
move.w buffer+28(pc),d0
bsr hexword86
bsr print
dc.b 10,13,"Calculated dir sector :$",0
even
moveq #0,d0
move.b buffer+16(pc),d0
move.w buffer+22(pc),d1
ror.w #8,d1
mulu d1,d0
move.w buffer+14(pc),d1
ror.w #8,d1
add.l d1,d0
rol.l #8,d0
bsr hexprint
rol.l #8,d0
bsr hexprint * print longword of start sect of dir
rol.l #8,d0
bsr hexprint
rol.l #8,d0
bsr hexprint
rts
extrainfo
move.w driveselect(pc),d0
addq.w #1,d0
move.w d0,-(sp)
pea driveextra(pc)
move.w #54,-(sp)
trap #1
addq.l #8,sp
bsr print
dc.b 10,13,27,"p"," From the Operating System (TOS) : ",27,"q"
dc.b 10,13,"Total Clusters :$",0
move.l driveextra+4(pc),d0
bsr hexlongst
bsr print
dc.b 10,13,"Free Clusters :$",0
move.l driveextra(pc),d0
bsr hexlongst
bsr print
dc.b 10,13,"Sectors per Cluster :$",0
move.l driveextra+12(pc),d0
bsr hexlongst
bsr print
dc.b 10,13,"Bytes per Sector :$",0
move.l driveextra+8(pc),d0
bsr hexlongst
bsr freespace
rts
freespace
jsr print
dc.b 10,13,"Therefore Free space = ",0
even
move.l driveextra(pc),d0 * no free clusters
move.l driveextra+12(pc),d6 * sects per cluster
mulu driveextra+10(pc),d6
mulu d6,d0
divu #$400,d0 * mulu and print free space
move.w d0,digibyte
jsr digits
jsr print
dc.b "K of ",0
move.l driveextra+4(pc),d0 * total no of clusters
move.l driveextra+12(pc),d6 * sects per cluster
mulu driveextra+10(pc),d6
mulu d6,d0
divu #$400,d0
move.w d0,digibyte
jsr digits
jsr print
dc.b " total",0
rts
pressanykeytoexit
bsr print
dc.b 10,13,27,"p"," Press any key to exit ",27,"q",0
even
bsr getkey
rts
resetscreen
tst screenmode
beq resetscreenexit
move.w #1,-(sp)
move.l #-1,-(sp)
move.l #-1,-(sp)
move.w #5,-(sp)
trap #14
add.l #12,sp
move.l #colregs,-(sp)
move.w #6,-(sp)
trap #14
addq.l #6,sp
resetscreenexit
rts
***************************************
*** digital word print ,word in digibyte bsr digits
digits
moveq.l #0,d7
move.w digibyte,d7
divu #10000,d7
bsr digiprint
moveq.l #0,d7
move.w digibyte,d7
divu #1000,d7
bsr digiprint
moveq.l #0,d7
move.w digibyte,d7
divu #100,d7
bsr digiprint
moveq.l #0,d7
move.w digibyte,d7
divu #10,d7
bsr digiprint
move.w #$ffff,digiflag
move.w digibyte,d7
swap d7
bsr digiprint
clr.w digiflag
rts
digiprint
swap d7
move.w d7,digibyte
swap d7
tst.b d7
beq digizero
move.w #$ffff,digiflag
digiret1
add.w #"0",d7
digiret2
move.w d7,-(sp)
move.w #2,-(sp)
trap #1
addq.l #4,sp
rts
digizero
tst digiflag
bne digiret1
rts * The end of VERY long digital print routine !
digiflag
dc.w 0
digibyte
dc.w 0
getkey
move.l #$20002,-(SP)
trap #13
add.l #4,SP
rts
hexlongst
move.l d0,-(sp)
rol.l #8,d0
bsr hexprint
rol.l #8,d0
bsr hexprint
rol.l #8,d0
bsr hexprint
rol.l #8,d0
bsr hexprint
move.l (sp)+,d0
rts
hexprint
move.l d0,-(sp)
asr.l #4,d0
bsr hpnext
move.l (sp),d0
bsr hpnext
move.l (sp)+,d0
rts
hpnext
andi.l #$f,d0
cmpi.b #10,d0
bmi hpnext2
addq.b #7,d0
hpnext2
addi.b #48,d0
move.w d0,-(sp)
move.w #2,-(sp)
trap #1
addq.l #4,sp
rts
hexword86
move.l d0,-(sp)
bsr hexprint
ror.l #8,d0
bsr hexprint
move.l (sp)+,d0
rts
move.l (sp),-(sp)
move.w #9,-(sp)
trap #1
addq.l #6,sp
move.l (sp)+,a0
ploop
move.w (a0),d0
tst.b d0
beq pend
asr.w #8,d0
tst.b d0
beq pend
adda #2,a0
bra ploop
pend
adda #2,a0
move.l a0,-(sp)
rts
printchr
move.l d0,-(sp)
and.l #$ff,d0
move.w d0,-(sp)
move.w #2,-(sp)
move.w #3,-(sp)
trap #13
add.l #6,sp
move.l (sp)+,d0
rts
checkdrive
move.l drivemap,d6
btst d7,d6 * drv to check = d7
beq checkdrivexit
moveq #0,d0 * ret code in d0
rts * -1 = not there, 0=ok
checkdrivexit
moveq #-1,d0
rts
convertlu
cmp.b #"a",d0 * if d0>=asc "a" subtract 32 from it
bmi convertexit * eg a => A , z => Z
sub.b #32,d0
convertexit
rts
driveextra
ds.l 4
drivemap
dc.l 0
driveselect
dc.w 0
colour0
dc.w 16
screenmode
dc.w 0
colregs
dc.l $ffff3f00
dc.l $f8f80000
ds.l 6
buffer
(the end)