Image Map Image Map
Page 1 of 3 123 LastLast
Results 1 to 10 of 23

Thread: Strange disk problem Kaypro selfbuilt bios for harddisk

  1. #1

    Default Strange disk problem Kaypro selfbuilt bios for harddisk

    Hello,

    Having added an ISA MFM controller to my Kaypro 4-83 and trying to create a bios for it, I am running into the following problem:
    Note: Harddrive is C, floppydrives are still A and B (maybe a bit unconventional for CP/M)

    When the current drive is A: I can succesfully do a dir C: but when the current drive is C: I can not get the directory of A with dir A:

    The result is this:
    2020-06-30 22.02.52.jpg

    I lowered the CCP, BDOS and Bios to D400/EA00 to get space for my own routines for testing, later on I will add them to the rom.
    For now I divert the diverse bios disk functions for A or B to the original rom routines and for the harddisk to my own code.


    Copying with PIP from floppy to harddisk is also not working, neither A to C nor C to A, it does create a xxxx.$$$ file but it is empty

    When PIP is executed on the C drive itself (copying to C) it is working OK, same for using PIP on A to A

    I managed to install some files on the C drive with the terminal program ST which seems to have no problems writing to C (even when started from A)

    Assembling and such works fine on the C drive alone.

    Any ideas where to look ?

  2. #2

    Default

    Can't tell for sure how your ROM differs from the original Kaypro ROM BIOS, but Kaypro used a chunk of high memory for buffers and variables for the ROM. If you are using any of the original Kaypro ROM code, you'll need to avoid touching any of that RAM in your routines. Or at the very least you must use it in a compatible way.
    - Doug

  3. #3

    Default

    Quote Originally Posted by durgadas311 View Post
    Can't tell for sure how your ROM differs from the original Kaypro ROM BIOS, but Kaypro used a chunk of high memory for buffers and variables for the ROM. If you are using any of the original Kaypro ROM code, you'll need to avoid touching any of that RAM in your routines. Or at the very least you must use it in a compatible way.
    As far as I can tell from the 81-149C rom source (which seems mostly the same as my 81-232 rom) and the KBIOS.MAC source I used as reference, the range from $FC00-$FFFF is used by the rom/bdos/original bios.
    My code sits at $EA00 (with the CCP at $D400) and goes up to $F0A9 so it should not conflict but never say never..

    Strange thing is that if I try to do a DIR A: from C: it never touches the floppy, I can see the harddisk light flash a few times and then it prints the garbage directory so it is not reading the correct drive.
    I do not know how CP/M handles the indirection given by prepending the path with A:, does it do a seldsk or does it use some buffer for that and if so can I force a reload if necessary?

    If typing A: (return)
    and then doing a DIR it works fine
    same for C: (return)
    DIR

    This is my seldsk function at the moment:

    Code:
    ; select drive, number in C
    seldsk:
    	mov	a,c
    	cpi	2		; drive C ?
    	jz	hd0seldsk
    	cpi	3		; drive D ?
    	jz	hd1seldsk
    
    	mvi	l,rom+0FH	; select disk drive
    	jmp	callrom   ; dispatch to oroginal rom code
    
    hd0seldsk:
       	lxi 	h,hd0dpbase ; set to my harddisk disk parameter header
    	 sta	lastdrive  ; set current drive number (at $0004)
    	ret
    
    hd1seldsk;
        lxi h,0    ; not installed
    	ret
    
    ; disk Parameter header for disk C
    hd0dpbase:
        	dw  	0000h, 0000h
    	dw 	0000h, 0000h
    	dw 	dirbf, dpblk
    	dw 	chk00, all00
    	db	00h
    ; disk parameter header for disk D
    hd1dpbase:
        	dw 	0000h, 0000h
    	dw  	0000h, 0000h
    	dw 	dirbf, dpblk
    	dw 	chk01, all01
    	db	00h
    ;
    dpblk: ;disk parameter block for hard disk
      	dw  68 	;sectors per track
    	db 	7 	;block shift factor
    	db 	127	;block mask
    	db 	7 	;null mask
    	dw 	663	;disk size-1
    	dw 	63 	;directory max
    	db 	240	;alloc 0
    	db 	0 	;alloc 1
    	dw 	0 	;check size
    	dw 	8 	;track offset

  4. #4

    Default

    I'll spend some more thought on it, but first idea I had was that maybe the Kaypro ROM (since you are using it directly) does not realize that you had selected a different disk and so it was taking an optimization that it wasn't entitled to. I'm not sure what that might be, though. Does your code use the same 'dirbf' as the ROM BIOS (floppy)?

    Another possibility is that 'all00' is not the right size (too small), and some memory corruption results.

    While this is not going to cause any fatal problems, I do notice that your "alloc 0/1" bytes (DPB.ALV0) are reserving 4 blocks for the directory, but you are using (DPB.DRM) only 64 directory entries (which is very small for a harddisk). You reserved 4 blocks, and have specified 16K block size, so that is a total of 2048 directory entries reserved (possible, in the space reserved). The number in the DPB.DRM word defines how much work the BDOS does when scanning the directory, and the DPB.ALV0 bytes just reserve the space. Kaypro floppies reserve extra space for the system (CCP or BIOS, I forget which) and so have a similar anomaly - just much smaller discrepancy. CP/M 2.2 generally does not perform well with huge directories, so you need to find a balance between the size of the drive (DPB.DSM) and what is practical for CP/M 2.2. Your drive size is 664 blocks (less 4 reserved), and you have a very large block size, so most files are going to fit in a single block. In order to be able to use all the drive space, you would need 660 directory entries. Of course, if a number of files will be larger than 16K then you could reduce that number.
    - Doug

  5. #5

    Default

    Quote Originally Posted by durgadas311 View Post
    I'll spend some more thought on it, but first idea I had was that maybe the Kaypro ROM (since you are using it directly) does not realize that you had selected a different disk and so it was taking an optimization that it wasn't entitled to. I'm not sure what that might be, though. Does your code use the same 'dirbf' as the ROM BIOS (floppy)?
    Was thinking along that line too, maybe the rom code takes a shortcut in calculating the DPH and since it normally only does only 2 drives and now finds a drive number of 3 in lastdrive, it gets the wrong disk parameters.
    My (seperate) 'dirbuf' points to the end of my code, just beyond the sector buffer I have.

    Another possibility is that 'all00' is not the right size (too small), and some memory corruption results.
    While this is not going to cause any fatal problems, I do notice that your "alloc 0/1" bytes (DPB.ALV0) are reserving 4 blocks for the directory, but you are using (DPB.DRM) only 64 directory entries (which is very small for a harddisk). You reserved 4 blocks, and have specified 16K block size, so that is a total of 2048 directory entries reserved (possible, in the space reserved). The number in the DPB.DRM word defines how much work the BDOS does when scanning the directory, and the DPB.ALV0 bytes just reserve the space.
    Have been fiddling with those numbers and since it is not a really big harddrive (only 10 MByte) I came up with these. Since CP/M seems to have no notion of 'heads' and to keep numbers in manageable quantities I made the following scheme:

    316 cylinders
    17 sectors (of 512 bytes) per track
    4 heads

    By incorporating the head number into the track number as bottom two bits (and since that was already a 16 bit number), head movement would be optimized for every 4 cpm tracks.
    Same thing for the sector number, by shifting the sector number two bits up, I can use the bottom two bits as index for which of the 128 bytes cpm wants to read/write out of the 512 byte physical sectors.
    That way the sector number is still within 8 bits and easier to code with. My bios read/write sector routines simply receive a track and a sector number. My blocking/deblocking routine is always reading/writing a whole 512 byte sector for every 128 byte cpm sector aka 'not cached' and so not optimal but since the speed is more than adequate I do not mind (yet).

    Kaypro floppies reserve extra space for the system (CCP or BIOS, I forget which) and so have a similar anomaly - just much smaller discrepancy.
    Yes I did find out that Kaypro floppies have the CCP/BDOS/BIOS sectors on track 0 and 1, and in a strange layout: on track 0 it uses cpm sectors 1 to 39 but then it advances to sector 16 on track 1 for the rest.
    Sectors 0-15 on track 1 are for the directory. Oh, and sector 0 on track 0 is used to store some info on where to put the CCP/BDOS/BIOS in memory (so it is not a boot sector as such).
    The strange layout got me puzzled as all the CP/M books just say: load in the first two tracks and you're done. So I wrote my 'getsys' program to copy the system to the first track(s) of the harddrive and just got rubbish (since the directory data got in the middle of the code..)

    CP/M 2.2 generally does not perform well with huge directories, so you need to find a balance between the size of the drive (DPB.DSM) and what is practical for CP/M 2.2. Your drive size is 664 blocks (less 4 reserved), and you have a very large block size, so most files are going to fit in a single block. In order to be able to use all the drive space, you would need 660 directory entries. Of course, if a number of files will be larger than 16K then you could reduce that number.
    Yes maybe I need to recalculate the DPB for the harddrive, for now it seems to work. Also CP/M does not really know how to 'format' the drive. I ended up just writing a bunch of $E5 on the directory sectors (in fact: on a large part of the disk) and started writing some files downloaded with the communication program (ST.COM) and so far it looks ok. STAT gave me about 9000k on the empty drive and now with some 35 files on it, it gives 8576k free space. Considering I wrote the blocking/deblocking code in one stretch and so far the CP/M programs I stored onto the drive seem to behave I am quite happy with that..
    On the original Kaypro disks I have there is a beautiful basic (compiler) called S-Basic and it came with a pretty large demo program called XAMN.BAS, it displays the disk information it finds from the DPB(s). It compiled without a hitch on the harddisk btw.

    For disk 2 (my harddisk) it comes up with this):
    2020-06-30 18.22.16.jpg
    When selecting disk 0 or 1 it also comes up with sensible data:
    2020-06-30 20.31.16.jpg

  6. #6

    Default

    Just realized that you have a CP/M 2.2 drive with a capacity of 10624K. That actually won't work, CP/M 2.2 can only address a drive of 8192K maximum. I *think* that only becomes a problem when you start allocating blocks past 8192K, but you should not be running that large of a drive. The BDOS is not able to do the math, and it will likely start overwriting the beginning of the drive. The maximum number of (16K) blocks should be 512, or DPB.DSM = 511.
    - Doug

  7. #7

    Default

    Quote Originally Posted by durgadas311 View Post
    Just realized that you have a CP/M 2.2 drive with a capacity of 10624K. That actually won't work, CP/M 2.2 can only address a drive of 8192K maximum. I *think* that only becomes a problem when you start allocating blocks past 8192K, but you should not be running that large of a drive. The BDOS is not able to do the math, and it will likely start overwriting the beginning of the drive. The maximum number of (16K) blocks should be 512, or DPB.DSM = 511.
    Ah, a good point, although BDOS seems to get the math right with the free space .. I read that the file size limit is 8192k
    But it is easily fixed by adjusting the DPB. The rest of the space I can create a seperate DPB for and make it drive D:

  8. #8

    Default

    Quote Originally Posted by gertk View Post
    ...

    Have been fiddling with those numbers and since it is not a really big harddrive (only 10 MByte) I came up with these. Since CP/M seems to have no notion of 'heads' and to keep numbers in manageable quantities I made the following scheme:

    316 cylinders
    17 sectors (of 512 bytes) per track
    4 heads

    By incorporating the head number into the track number as bottom two bits (and since that was already a 16 bit number), head movement would be optimized for every 4 cpm tracks.
    Same thing for the sector number, by shifting the sector number two bits up, I can use the bottom two bits as index for which of the 128 bytes cpm wants to read/write out of the 512 byte physical sectors.
    That way the sector number is still within 8 bits and easier to code with. My bios read/write sector routines simply receive a track and a sector number. My blocking/deblocking routine is always reading/writing a whole 512 byte sector for every 128 byte cpm sector aka 'not cached' and so not optimal but since the speed is more than adequate I do not mind (yet).


    ...
    Not sure if this relates to the problem you are seeing, but I just noticed another math problem. You tell CP/M that you have 68 sectors per track (128B records). But, the drive has only 17 sectors per track (as you say you are not using the full 512B only the first 128B). So, what you describe for the sector arithmetic would apply to a BIOS where you were actually doing deblocking, NOT the case where you only use the first 128B of each physical sector. something is wrong there.
    - Doug

  9. #9

    Default

    Quote Originally Posted by durgadas311 View Post
    Not sure if this relates to the problem you are seeing, but I just noticed another math problem. You tell CP/M that you have 68 sectors per track (128B records). But, the drive has only 17 sectors per track (as you say you are not using the full 512B only the first 128B). So, what you describe for the sector arithmetic would apply to a BIOS where you were actually doing deblocking, NOT the case where you only use the first 128B of each physical sector. something is wrong there.
    No, my own blocking/deblocking code takes care of that, If the sector number is 0 the first 128 bytes of the 512 byte sector are read, if sector number is 1, bytes 128 to 255 are read, when 2 bytes 256 to 383 are read and when 3 bytes 384 to 512 are read. That works fine. When writing it takes a bit of overhead as I need to read the whole 512 byte sector in, overwrite the appropriate part and write it back. Not optimal but works

  10. #10

    Default

    Just did a quick test: XAMN.BAS can scan for bad sectors and asks for start and end track

    I entered 1023 as starting track and 1024 as end track and it scans track 1023 (harddrive light flashing) and when it hits track 1024 the program still runs but the harddrive light stays dark.
    So I definitely need to adjust the DPB

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •