You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

130 lines
6.8 KiB

{\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
}