{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033\deflangfe1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}{\f1\fmodern\fprq1\fcharset0 Courier New;}{\f2\fnil\fcharset0 Courier New;}} {\colortbl ;\red255\green255\blue0;} {\*\generator Riched20 10.0.14393}{\*\mmathPr\mnaryLim0\mdispDef1\mwrapIndent1440 }\viewkind4\uc1 \pard\nowidctlpar\qc\f0\fs36 BPBIOS Errata\par \pard\nowidctlpar\fs22\par \ul\fs28 File: deblock.z80 @ SLP0:\par \ulnone\fs22\par When attempting to increment the sector number for sequential unallocated write matching, HL was pointing one byte past the sector number byte when it was intended to point at the sector number byte. Added a DEC HL to make it point to the right place. Without this fix, there will be far more disk writes than desired, but no data corruption as far as I can tell.\par \f1\par \fs20 ; More unallocated records remain. Check for any change.\par \par \tab DEC\tab A\tab\tab ; Decrement unallocated count\par \tab LD\tab (UNACNT),A\tab ; And save it\par \tab LD\tab B,4\tab\tab ; Compare four bytes\par \tab LD\tab HL,UNADSK\tab ; Compare Old Disk, Track & Sector\par \tab LD\tab DE,SEKDSK\tab ; .to New Disk, Track & Sector\par SLP0:\tab LD\tab A,(DE)\par \tab CP\tab (HL)\tab\tab ; Same?\par \tab JR\tab NZ,ALLOC\tab ; ..jump if not\par \tab INC\tab HL\tab\tab ; Else advance to next\par \tab INC\tab DE\par \tab DJNZ\tab SLP0\tab\tab ; ..and loop til done\par \par ; Everything matches, anticipate the next sector\par \par \highlight1\tab DEC\tab HL\tab\tab ; WBW: point back to sector num\par \highlight0\tab INC\tab (HL)\tab\tab ; Unasec+1\par \tab LD\tab A,(CPMSPT)\tab ; Max sectors per track\par \tab CP\tab (HL)\tab\tab ; Compare them\par \tab JR\tab NZ,NOOVF\tab ; ..jump if not ready for new track yet\par \fs22\par \ul\f0\fs28 File: hardide.z80 \strike & hard-dx.z80\strike0 @ HDWRIT:\par \ulnone\fs22\par HSTACT was being reset instead of HSTWRT at every disk write call. Makes no sense and was causing many extra writes. Switched to HSTWRT which is what the floppy driver does.\par \f1\par \fs20 ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\par ; Write to Hard Disk Drive\tab\tab\tab < Internal BIOS Routine >\par ; Writes from HSTBUF using HSTTRK and HSTSEC to build Block Number.\par ; NOTE: This routine uses physical drive characteristics from ICFG-xx.\par \par HDWRIT:\tab XOR\tab A\par \highlight1 ;WBW\tab LD\tab (HSTACT),A\tab ; Show no active writes pending\par \tab LD\tab (HSTWRT),A\tab ; WBW: Show no active writes pending\par \highlight0\par \tab LD\tab HL,7CH*256+CMDWR ; Set the IDE Write Command\par \tab JR\tab HDRW\tab\tab ; ..continue\par \fs22\par \ul\f0\fs28\page\strike selrwd.z80 @ SELDK0:\par \ulnone\fs22\par It appears that if a disk is selected (SELDSK) and is not a new disk login, then, the driver select processing is being bypassed. Does not make sense to me, but not causing any harm that I can see at this point.\par \par No code fix created yet.\par \strike0\par \ul\fs28 fdc-dx.z80 @ FDCDN:\par \ulnone\fs22\par At high clock speeds (>~24MHz) the seek/recal command wait for completion needs to make sure the prior command is not still active.\par \par \f1\fs20 ;.....\par ; Check for Proper Termination of Seek/Recalibrate Actions by\par ; executing a Check Interrupt Command returning ST0 in A.\par \par FDCDN: PUSH HL\tab\tab ; Don't alter regs\par EI\tab\tab\tab\tab ; (Ints Ok Now)\par FDCDN0: CALL WRDY\tab\tab ; Ready? (leave Ints alone)\par \highlight1 BIT 4,A\tab\tab ; WBW: Prior command still active?\par JR NZ,FDCDN0\tab ; WBW: If so, keep checking\par \highlight0 LD A,08H\tab\tab ; Else Issue Sense Interrupt Status Comnd\par OUT0 (DR),A\par CALL WRDY\par IN0 A,(DR)\tab\tab ; Get first Result Byte (ST0)\par LD L,A\par CP 80H\tab\tab ; Invalid Command?\par JR Z,FDCDN0\tab ; ..jump to exit if So\par CALL WRDY\par IN0 A,(DR)\tab\tab ; Read Second Result Byte (Trk #)\par LD A,L\par BIT 5,A\tab\tab ; Command Complete?\par JR Z,FDCDN0\tab ; ..loop if Not\par POP HL\par RET\par ENDIF ;~fddma\f0\fs22\par \par \ul\fs28\page fdc-dx.z80 @ WRDY:\par \ulnone\fs22\par At high clock speeds (>~24MHz), a small delay is needed between MSR register reads.\par \par \f1\fs20 ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\par ; Wait for FDC RQM to become Ready, and return DIO status in Zero Flag\par ; Pause before reading status port based on CPU Speed and Data Rate.\par \par WRDY: LD A,(DLYCNT\tab ; Get computed delay count\par WRDY0: DEC A\tab\tab\tab ; Done?\par JR NZ,WRDY0\tab ; ..loop if Not\par WRDYL: IN A,(MSR\tab\tab ; Read Main Status Register\par BIT 7,A\tab\tab ; Interrupt Present?\par \highlight1 NOP\tab\tab\tab\tab ; WBW: Reg recovery for hi speed op\par \highlight0 RET NZ\tab\tab ; Return if So\par JR WRDYL\tab\tab ; Else Loop\par \f0\fs22\par \ul\fs28 fdc-dx.z80 @ FDRst:\par \ulnone\fs22\par At high clock speeds (>~24MHz), an additional delay is needed to make sure that the reset minimum timing is met. The code fix below seems to work, but it wold be better to implement a loop based on clock speed.\par \par \f1\fs20 ========================================================================\par ; Reset the Floppy Disk Controller. Called from CBOOT in case of Hard\par ; Disk Boot which leaves the controller in a "hung" state, and locally\par ; if the Controller times out (often due to changing diskettes).\par \par FDRst: PUSH AF\tab\tab ; Save any status\par XOR A\par OUT (DCR),A\tab\tab ; Place Controller in Reset state\par \highlight1 EX (SP),HL\tab\tab ; WBW: Delay required at high speed\par EX (SP),HL\tab\tab ; WBW: ... to ensure reset works\par \highlight0 LD A,(ACTIVE\tab ; get current settings\par AND 0FCH\tab\tab ; keep only motors, DMA and Ready\par OUT (DCR),A\tab\tab ; and Restore\par POP AF\tab\tab ; Restore Status\par RET\par \f0\fs28\par \ul fdc-dx.z80 @ FDCINT:\par \ulnone\fs22\par At high clock speeds, the FDC interrupt polling loop is insufficient. Assuming the original value of 30 is optimal for 16MHz and assuming we want to handle up to 50MHz now, a reasonable new value is 90.\par \par \f2\fs20\tab LD\tab BC,0000\tab\tab ; Inner loop timeout\par \highlight1 ;\tab LD\tab D,30\tab\tab\tab ; Outer loop timeout\par \tab LD\tab D,90\tab\tab\tab ; Outer loop timeout\par \highlight0\tab LD\tab HL,ST0\tab\tab ; Point to Status Area\f1\fs22\par }