Image Map Image Map
Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 23

Thread: Strange disk problem Kaypro selfbuilt bios for harddisk

  1. #11

    Default

    Quote Originally Posted by gertk View Post
    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
    Does XAMN.BAS access the track/sector via BIOS, or does it somehow create a fake/temp file and access via BDOS? Only the BDOS (file access) has the 8192K limit. Track and sector access via BIOS should not care, as long as you are using the full 16-bit values for track. It seems suspicious that you run into a problem at exactly tracks 0x03ff/0x0400, as that would be the point where the cylinder number (after extracting head number) overflows 8-bits.
    - Doug

  2. #12

    Default

    Quote Originally Posted by durgadas311 View Post
    Does XAMN.BAS access the track/sector via BIOS, or does it somehow create a fake/temp file and access via BDOS? Only the BDOS (file access) has the 8192K limit. Track and sector access via BIOS should not care, as long as you are using the full 16-bit values for track. It seems suspicious that you run into a problem at exactly tracks 0x03ff/0x0400, as that would be the point where the cylinder number (after extracting head number) overflows 8-bits.
    XAMN.BAS uses BIOS calls

    This is my 'hdmath' code for calculating the head, sector and cylinder number from the numbers given by BDOS, on first glance I do not see something amiss here.

    Code:
    ;
    ; calculate head, sector and cylinder number
    ; from the given cpm sector (stored in hdsecno)
    ; and track number (in HL)
    ;
    hdmath:
    	lxi	h,0		    ; calculate sector offset
    	lxi	d,128		; cpm sector size
    	lda	hdsecno		; get cpm sector number
    	ani	03h		    ; which sector offset ?
    	cpi	00h		    ; start at 0
    	jz	hdmath1     ; if so we're done
    	dad	d           ; else  add offset
    	cpi	01h		    ; and start at 128
    	jz	hdmath1     ; done
    	dad	d           ; else add offset
    	cpi	02h		    ; and start at 256
    	jz	hdmath1     ; done
    	dad	d		    ; else add offset and start at 384
    hdmath1:
    	shld	hdsecoff	; store in sector offset
    
        ; calculate cylinder number
    	lhld	hdtrackno	; get 16 bit track number
    	mov	a,l		; get lower byte of tracknumber and keep bits 0 and 1
    	ani	03h		; make head number
    	mov	e,a		; save in E
    	; shift the hdtrackno two bits to the right
    	; (HL still contains the cpm track number)
    	mov	a,h
    	ora	a	; clear carry
    	rar		; rotate right through carry
    	mov	h,a ; save the result
    	mov	a,l ; get lower byte
    	rar     ; rotate right
    	mov	l,a ; store back
    	; and again
    	mov	a,h ; get high byte
    	ora	a	; clear carry
    	rar		; rotate right through carry
    	mov	h,a ; save the result
    	mov	a,l ; get low byte
    	rar     ; rotate right
    	mov	l,a ; store back
    
    	; shift the sector number down by two bits (divide by 4)
        ; as each 512 byte sector can contain four 128 byte cpm sectors
    	lda	hdsecno ; get sector number
    	ora	a       ; clear carry
    	rar         ; rotate right
    	ora	a       ; clear carry again
    	rar         ; and rotate once more
    	mov	d,a     ; store in D
    	; HL now contains the physical cylinder number (tracknumber divided by 4=the number of heads)
    	; E contains the head number (0-3)
    	; D contains the 512 byte physical sector number (0-16)
    	ret

  3. #13

    Default

    I also don't see anything wrong with the track/head/sector math. From you description of the symptoms, it sounds like when the track reaches 0x0400 (or greater) that the HDD is simply not selected/accessed. Maybe something is going wrong in the case where H is non-zero (cylinder > 00FF, track > 03FF).

    But, that's probably not the cause of the problem you originally saw? Just doing "DIR" you are not going beyond track 03FF?
    - Doug

  4. #14

    Default

    Quote Originally Posted by durgadas311 View Post
    I also don't see anything wrong with the track/head/sector math. From you description of the symptoms, it sounds like when the track reaches 0x0400 (or greater) that the HDD is simply not selected/accessed. Maybe something is going wrong in the case where H is non-zero (cylinder > 00FF, track > 03FF).

    But, that's probably not the cause of the problem you originally saw? Just doing "DIR" you are not going beyond track 03FF?
    Ha, the 1023 track (well actually 255 track) problem was a nice one and caused by inconsistent information in the controller datasheet..
    Found the solution in a piece of Linux kernel source.. (from a long time ago...)

    For setting the desired cylinder you need to write two bytes to the controller, the high byte needs to be shifted up so the sector number fits in the lower bits.
    According to multiple datasheets the high byte of the cylinder number needs to go in bits 7,6 and 5 and the remaining bits are for the sector number.
    In the kernel source they use only bits 7 and 6 which also seems more in accordance to the 1023 cylinder limit of the controller.

    Code:
    	; send high byte of cylinder (H)
    	; reduced to three bits in bit 5,6 and 7 (not correct ? only two bits ?)
    	; and put sector number over it
    	call waitforsr
    	mov a,h
    	rrc
    	rrc
    ;	rrc
    ;	ani 0e0h
        ani 0c0h
    	ora d
    	out WDData
    Now that is fixed it I also changed the DPH/DPB to split the drive in two 'partitions'.

    Code:
    hd0dpblk:
        ; disk parameter block for (hard)disk C
        ; 4k blocks on 4 x 70 physical cylinders with 17 sectors a 512 bytes
        ; total byte size 2437120 bytes
        ; 2437120 / 128 =  19040 cpm sectors
        ; 2437120 / 4096 = 595 blocks of 4 k
      	dw  68 	    ;sectors per track
    	db 	5 	    ;block shift factor
    	db 	31	    ;block mask
    	db 	7 	    ;null mask
    	dw 	594	    ;disk size-1    (594+1)*4096 bytes
    	dw 	255 	;directory max
    	db 	0c0h	;alloc 0    (two blocks of 4096 bytes need to store (255+1) x 32 bytes entries)
    	db 	0 	    ;alloc 1
    	dw 	0 	    ;check size
    	dw 	8 	    ;track offset
    
    hd1dpblk:
        ; disk parameter block for (hard)disk D
        ; 16k blocks on 4 x 233 physical cylinders with 17 sectors a 512 bytes
        ; total byte size 8112128 bytes
        ; 8112128 / 128 =  63376 cpm sectors
        ; 8112128 / 16384 = 495 blocks of 16k
      	dw  68 	    ;sectors per track
    	db 	7 	    ;block shift factor
    	db 	127	    ;block mask
    	db 	7 	    ;null mask
    	dw 	494	    ;disk size-1
    	dw 	1023	;directory max
    	db 	0c0h	;alloc 0    (two blocks of 16384 bytes needed to store (1023+1) x 32 bytes entries)
    	db 	0 	    ;alloc 1
    	dw 	0 	    ;check size
    	dw 	288     ;track offset
    2020-07-02 19.49.15.jpg 2020-07-02 19.49.55.jpg

    BTW: Copying files with PIP works fine between C and D, still not to (or from) A to C (or D)
    Will go through the rom source to see if I can find the cause.

  5. #15

    Default

    Quick update:

    copying seems to work with PIP but the directory gets messed up after some copy actions.
    Writing on the C or D drive from within the comm program (ST.COM) works flawless though.
    Last edited by gertk; July 3rd, 2020 at 01:45 AM.

  6. #16

    Default

    My guess is still that there is some conflict or interference between the ROM BIOS and your add-on BIOS. Unfortunately, my simulator does not support the earliest Kaypro hardware (II, 4/83) (that's on my "someday todo list") or else we could run your software there and try to diagnose it.

    Are you saying that the directory (on disk) gets corrupted after/during PIP between floppy and HDD? A dump of the corrupted directory might give some clue as to what is causing it. Also, when running the "DIR" test, does it always show the same bogus directory pattern: are those file names filled with apostrophes? And there are always (exactly) 12 of those bogus files shown?
    - Doug

  7. #17

    Default

    The directories got corrupted even when copying from C to D or vice versa, I tried to re-use the original bios buffer space but also ran into trouble.
    Right now I am thinking that my 'perfect' harddisk is probably not perfect..
    I will write a testprogram for that to rule that out.

    My benchmark stresstest is compiling the XAMN.BAS program and it compiles fine on drive D but not on drive C, it errors out with a strange REF-DEV LIB error.
    Same files (for as far as I can tell, I have no tool to proof) different partitions, different results.

    Tried renaming the sbasic files and copying 'fresh' copies from the working D drive but the error stays the same, so it could also be some weird stack or other memory problem.

    P.S. do my new disk parameter blocks make a bit of sense ?

  8. #18

    Default

    Update:
    Checked the harddisk by reading each sector, writing the full sector with $AA, read it again, compare the data and signal if error, then write the full sector with $55, reading, comparing and finally writing the original data back. No errors except for the very last track 305, head 3 sector 9, then it goes in semi endless retry seeks. That sound I never have heard during normal CP/M use.
    Since that track is not a part of any active partition I can say the harddrive itself is fine. So back to debugging my code

  9. #19

    Default

    I did get a Kaypro 4/83 simulator running (but not with an ISA MFM HDD). One thing I noticed is that the graphic displayed for the NUL (00H) character is what I was mistaking for an apostrophe (27H). So, it means that the "bogus" directory listing you get is full of NULs. That may help with what is going on. From the CCP perspective, it must be getting "success" back from the search calls, but the dma buffer is filled with NULs. That would imply that the BIOS is returning NULs, or possibly the buffer being used (0080H) has NULs (garbage) in it and the BIOS is failing to copy the disk data to the current DMA buffer. I have not studied the normal Kaypro BIOS for over 30 years, but could it be that your BIOS changes have affected the final "deblocking" copy done for the floppy? I suspect the ROM BIOS read routine for the floppy cannot copy the data to the user's DMA buffer, as it is likely to be "underneath" the ROM. So, the ROM probably reads the physical sector into high memory and leaves it to the CP/M BIOS to do the final copy after the ROM returns. This requires the two to be in perfect sync, right down to knowing the exact buffer address as well as knowing which partial sector to copy.

    This doesn't explain why only 12 directory entries are printed, as I'd expect that to keep happening for the total number configured for the floppy disk. But, perhaps there is more randomness somewhere and the buffer contents changes.
    - Doug

  10. #20

    Default

    Some progress:

    The directory corruption (and compile problems of S-Basic) is fixed: my Extent Mask (other CP/M book named it 'Null Mask') was wrong on the C partition.
    On the D drive the compilation went ok but on the C Drive it failed with the most exotic errors like: I'm Lost...

    My next step would have been to make the block size and such the same as the D Drive and try again and then I saw the Null Mask/Extent Mask value being the same for both partitions and thought: that can't be right ? So back to my new favourite CP/M book: Programmers CP/M Handbook by Andy Johnson-Laird.

    There this value was called 'extent mask' and with more detailed explanation on how to choose the value. (I had a value of 7, which was fine for the 16k block D drive but not for the 4k blocks of C). Changed the value into '1' and wiped the directory of C.
    PIP-ed the files from D to C and retried the compilation of XAMN.BAS on the C drive and it worked!

    Now for the floppy drive problems:

    The original rom routines do quite a lot of trickery by buffering sectors and only write/read when absolutely necessary (for example if you change drives)
    Since the original rom routines/bios have no support for more than 2 drives it gets confused when you forcibly set the 'last drive' number to 2 or 3 (which is totally acceptable for BDOS).

    The way the bios signals a disk change is quite deeply buried in the code. Since I only have the annotated source of the Kaypro II rom it is like trying to find a needle in a haystack. The voodoo for the floppies is quite extensive, including support for single density and double density, single sided and double sided, 128 byte sectors and 512 byte sectors.

    Modifying the original bios is daunting as so much is hardcoded for just two (floppy) drives.

    I bet my chances are higher in just adding the floppy routines from scratch in my own bios, it might not end up as being efficient but hey, if it works..
    With the harddisk up and running the floppy drive will only be used occasionally so if it does not copy as fast as the original code, so be it.

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
  •