From 4a3574fe3f2a501e8c0c0dabbdd3a85c90f12eff Mon Sep 17 00:00:00 2001 From: Tolik <85737314+Tolik-Trek@users.noreply.github.com> Date: Tue, 27 May 2025 19:20:05 +1000 Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=BA=D0=B0=20AUTOIDE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Shared_Includes | 2 +- src/bios/exp/EXTENDED/IDE/ATA_DRV.ASM | 12 +- src/bios/exp/EXTENDED/IDE/shared.asm | 10 +- src/bios/rom/SETUP/AUTOIDE.asm | 203 ++++++++++++++++---------- src/bios/rom/SETUP/MAIN.asm | 1 + src/bios/rom/SETUP/SETTINGS.asm | 53 ++++--- src/bios/shared/RECOVERY.IMG | Bin 98304 -> 98304 bytes 7 files changed, 165 insertions(+), 116 deletions(-) diff --git a/Shared_Includes b/Shared_Includes index 25ac1c8..8371051 160000 --- a/Shared_Includes +++ b/Shared_Includes @@ -1 +1 @@ -Subproject commit 25ac1c89f4ce070e041437ddbcdd18ab2ab223be +Subproject commit 8371051031cac61e25740ba6cf9f2acacdc783b7 diff --git a/src/bios/exp/EXTENDED/IDE/ATA_DRV.ASM b/src/bios/exp/EXTENDED/IDE/ATA_DRV.ASM index d07d348..102d965 100644 --- a/src/bios/exp/EXTENDED/IDE/ATA_DRV.ASM +++ b/src/bios/exp/EXTENDED/IDE/ATA_DRV.ASM @@ -300,8 +300,9 @@ RW_ATA_SECTORs: PUSH BC ; POP BC ; признак short/long в C RET C ; - EXX - CALL WAITPRT + EXX + LD DE,256*(IDE.CtrlByte.Busy+IDE.CtrlByte.Ready) + IDE.CtrlByte.Ready + CALL WAITPRT.custom EXX RET C ; @@ -547,8 +548,9 @@ ATA_5x_VERIFY: PUSH IY .VERIFY: LD C,IDE.Device.HDD CALL SELECT_DRIVE RET C - EXX - CALL WAITPRT + EXX + LD DE,256*(IDE.CtrlByte.Busy+IDE.CtrlByte.Ready) + IDE.CtrlByte.Ready + CALL WAITPRT.custom EXX RET C ;PUSH DE @@ -664,7 +666,7 @@ DIV32X: ;HL:DE / BC => DE:IX HL-OSTATOK ; D - MASK ; E - PATTERN ; !!! некоторые функции надеются, что на выходе всегда ZF -WAITPRT: LD DE,256*(IDE.CtrlByte.Busy+IDE.CtrlByte.Ready+IDE.CtrlByte.Error)+IDE.CtrlByte.Ready +WAITPRT: LD DE,256*(IDE.CtrlByte.Busy+IDE.CtrlByte.Ready+IDE.CtrlByte.Error) + IDE.CtrlByte.Ready .custom: LD BC,IDE.Read.Status LD HL,#0000 ; задержка ;!HARDCODE ; diff --git a/src/bios/exp/EXTENDED/IDE/shared.asm b/src/bios/exp/EXTENDED/IDE/shared.asm index d4dbc7e..160ec71 100644 --- a/src/bios/exp/EXTENDED/IDE/shared.asm +++ b/src/bios/exp/EXTENDED/IDE/shared.asm @@ -51,12 +51,14 @@ SELECT_DRIVE: AND #0F LD BC,IDE.Write.DeviceHead OUT (C),A ; - LD A,high IDE.Read.Status +.del_me: LD A,high IDE.Read.Status IN A,(low IDE.Read.Status) AND IDE.CtrlByte.Busy - JR Z,.notBusy - LD B,32 - DJNZ $ + ; тестирование задержек + ;JR NZ,.del_me + JR Z,.notBusy + LD B,32 + DJNZ $ ; .notBusy: LD A,H EXX diff --git a/src/bios/rom/SETUP/AUTOIDE.asm b/src/bios/rom/SETUP/AUTOIDE.asm index 2068315..1294eeb 100644 --- a/src/bios/rom/SETUP/AUTOIDE.asm +++ b/src/bios/rom/SETUP/AUTOIDE.asm @@ -96,6 +96,7 @@ IDE3 EQU #C1D8 HALT: .Time_2s EQU 100 .SMALL EQU 200 ; 04 сек +.MEDIUM EQU 400 ; 08 сек .BIG EQU 1550 ; 31 сек WAIT: .IDE EQU #0000 @@ -137,7 +138,7 @@ WAIT: ENDM /////////////////////////////////////////////////////////////////////[v] -START: CALL SetUP_CHANELS +START: ;CALL Nop_CHANELS ; IN A,(SLOT3) EX AF,AF' @@ -172,8 +173,8 @@ START: CALL SetUP_CHANELS ;[x] save hdd parameters to cmos for "setup" in settings CALL WRITING ; - CALL ScreenPOS.CRLF - RET + JP ScreenPOS.CRLF + ;RET /////////////////////////////////////////////////////////////////////[^] @@ -200,7 +201,6 @@ AUTODETECT: /////////////////////////////////////////////////////////////////////[v] -; !HARDCODE заменить числа на метки в этой процедуре STEP1_GETCMOS: LD (MasterSlave),A LD H,A ;SAVE DRIVE NUMBER @@ -225,12 +225,12 @@ STEP1_GETCMOS: LD L,msgStrings.detectIdeSecMA JR Z,.choose ; - DEC A + ;DEC A LD BC,CMOS_CELL.DrivesSetup_2.Mask.SecIDEslave LD L,msgStrings.detectIdeSecSL - JR Z,.choose - SCF - RET + ;JR Z,.choose + ;SCF + ;RET ;0 - AUTODETECT ;1 - GETTING FROM SETUP ;2 - CD-ROM (ATAPI device) @@ -269,7 +269,7 @@ AUTODETECTING: CALL DETECTORS.CheckChanel JR C,.IDE_ABSENT CALL Bug31SecCheck - JR C,.next + JR NC,.next LD HL,PAUSES.HALT.BIG CALL BITS_WAITS.Clear_BUSY @@ -286,7 +286,6 @@ AUTODETECTING: CALL DETECTORS.CheckChanel CALL DETECTORS.IdentDevCheck JR C,.IDE_ABSENT JR Z,.Its_ATA - ; enter point for ATAPI in setup .Its_ATAPI: CALL DETECTORS.IdentPDevChk JR C,.IDE_ABSENT @@ -304,11 +303,15 @@ AUTODETECTING: CALL DETECTORS.CheckChanel ; .IDE_ABSENT: LD A,IDE.Device.NONE LD (IDEDEV),A - LD A,IDE.CMD.ATA.Nop - LD BC,IDE.Write.Command - OUT (C),A - DEC B - IN A,(C) ; IDE.Read.Status + ;LD A,IDE.CMD.ATA.Nop + ;LD BC,IDE.Write.Command + ;OUT (C),A + ;; + ; ;DEC B + ; PAUSE_DJNZ 0 + ; LD BC,IDE.Read.Status + ;; + ;IN A,(C) ; IDE.Read.Status SCF RET /////////////////////////////////////////////////////////////////////[^] @@ -337,7 +340,7 @@ SETUP_FROM_CMOS: LDIR ; CALL Bug31SecCheck - JR C,.step2 + JR NC,.step2 ; LD HL,PAUSES.HALT.BIG CALL BITS_WAITS.Clear_BUSY @@ -447,8 +450,9 @@ IDESPEC: IN A,(SLOT3) LD (IY+IDE.HDD_INIT_TABLE.MediaParameters),%0000'0001 LD B,100 ; счётчик попыток (1 попытка - 1 HALT) .get_error_loop: PUSH BC - LD HL,ATAPI_CMD_PACKET.TEST_UNIT_READY - CALL EXEC_PACKET_COMMAND.start + ;LD HL,ATAPI_CMD_PACKET.TEST_UNIT_READY + ;CALL EXEC_PACKET_COMMAND.start + CALL EXEC_TEST_CMD POP BC JR NC,.s_size ; @@ -458,7 +462,7 @@ IDESPEC: IN A,(SLOT3) ; HALT DJNZ .get_error_loop - ; + ; ; [ ] sector size ATAPI .s_size: LD DE,IDENTIFY_DEVICE_BUFFER.ReservedWord224 ; просто нужен был буфер CALL ATAPI_READ_CAPACITY_DATA @@ -541,11 +545,6 @@ BITS_WAITS: ; Pause for clear BUSY and DATA REQUEST .Clear_BUSY: LD BC,IDE.Read.Status IN A,(C) - ;!TEST for normal bus with pull-ups - ;CP #FF - ;SCF - ;RET Z - ; AND IDE.CtrlByte.Busy; + IDE.CtrlByte.DataRequest RET Z ; @@ -607,16 +606,17 @@ SKIPKEY: RET Z EXX LD HL,#3E00 ;!HARDCODE - AND A + XOR A SBC HL,DE EXX SCF CCF RET NZ - LD A,0 + ;A=0 LD (SKIP),A - SCF - RET + INC A + SCF + RET ;ZF=0, CF=1 /////////////////////////////////////////////////////////////////////[^] @@ -664,9 +664,43 @@ SaveToCMOS: JP WRITCMS /////////////////////////////////////////////////////////////////////[^] - /////////////////////////////////////////////////////////////////////[v] -RESET_Slave_ATAPI: +; Check bug with 31 sec freeze +; Bug31SecCheck: LD A,(MasterSlave) +; AND 1 +; RET NZ +; ; +; LD HL,PAUSES.HALT.Time_2s +; CALL BITS_WAITS.Clear_BUSY +; CCF +; RET C +; ; +; .RESET_Slave_ATAPI: +; LD A,IDE.Drive.Slave +; LD BC,IDE.Write.DeviceHead +; OUT (C),A +; PAUSE_DJNZ 16 +; LD BC,IDE.Write.Command +; LD A,IDE.CMD.ATAPI.Reset +; OUT (C),A +; PAUSE_DJNZ 16 +; LD A,IDE.Drive.Master +; LD BC,IDE.Write.DeviceHead +; OUT (C),A +; RET +/////////////////////////////////////////////////////////////////////[^] +/////////////////////////////////////////////////////////////////////[v] +; Check bug with 31 sec freeze +Bug31SecCheck: LD A,(MasterSlave) + AND 1 + RET Z + ; + LD HL,PAUSES.HALT.Time_2s + CALL BITS_WAITS.Clear_BUSY + RET NC + JR NZ,.skip + ; +.RESET_Slave_ATAPI: LD A,IDE.Drive.Slave LD BC,IDE.Write.DeviceHead OUT (C),A @@ -679,40 +713,26 @@ RESET_Slave_ATAPI: LD BC,IDE.Write.DeviceHead OUT (C),A RET + ; +.skip: POP BC ; баланс стека + JP AUTODETECTING.IDE_ABSENT /////////////////////////////////////////////////////////////////////[^] - /////////////////////////////////////////////////////////////////////[v] -; Check bug with 31 sec freeze -Bug31SecCheck: LD A,(MasterSlave) - AND 1 - RET NZ - ; - LD HL,PAUSES.HALT.Time_2s - CALL BITS_WAITS.Clear_BUSY - CCF +GETPARAM: LD HL,PAUSES.WAIT.IDE + LD DE,IDE.CtrlByte.DataRequest * 256 + IDE.CtrlByte.DataRequest + CALL BITS_WAITS.WAIT_PRT RET C + LD BC,IDE.Read.Data + LD HL,IDENTIFY_DEVICE_BUFFER + INIR + INIR + CALL IDESPEC + ; [x] save hdd parameters to cmos for "setup" in settings + CALL SaveToCMOS ; - JP RESET_Slave_ATAPI -/////////////////////////////////////////////////////////////////////[^] - - -/////////////////////////////////////////////////////////////////////[v] -GETPARAM: - LD HL,PAUSES.WAIT.IDE - LD DE,IDE.CtrlByte.DataRequest * 256 + IDE.CtrlByte.DataRequest - CALL BITS_WAITS.WAIT_PRT - RET C - LD BC,IDE.Read.Data - LD HL,IDENTIFY_DEVICE_BUFFER - INIR - INIR - CALL IDESPEC - ; [x] save hdd parameters to cmos for "setup" in settings - CALL SaveToCMOS - ; - AND A - RET + AND A + RET /////////////////////////////////////////////////////////////////////[^] @@ -747,13 +767,16 @@ DETECTORS: PAUSE_DJNZ 0 - LD HL,PAUSES.HALT.SMALL + ;LD HL,PAUSES.HALT.SMALL + LD HL,PAUSES.HALT.MEDIUM LD BC,IDE.Read.Status - ;DEC B ; .loop: IN A,(C) SCF RET Z + ; old CF bug fix + CP IDE.CtrlByte.Ready + IDE.CtrlByte.SeekComplete + RET Z ; AND IDE.CtrlByte.Busy + IDE.CtrlByte.DataRequest + IDE.CtrlByte.Error CP IDE.CtrlByte.Error @@ -763,20 +786,19 @@ DETECTORS: DEC HL LD A,H OR L - ;SCF - ;RET Z ; Absent - JR Z,.nop_exit + ;JR Z,.nop_exit + SCF + RET Z ; Absent ; CALL SKIPKEY RET C ; Skipped = Absent - ; JR .loop ; -.nop_exit: IN A,(C) - CP IDE.CtrlByte.Ready + IDE.CtrlByte.SeekComplete - RET Z ; old CF bug fix - SCF - RET ; Absent +; .nop_exit: IN A,(C) +; CP IDE.CtrlByte.Ready + IDE.CtrlByte.SeekComplete +; RET Z ; old CF bug fix +; SCF +; RET ; Absent ;-------; ;-------; @@ -808,10 +830,31 @@ DETECTORS: .non_ATA: LD BC,IDE.Read.Error IN A,(C) AND IDE.ErrorByte.Abort - RET NZ ; ATAPI + ; check signature #0114EB + ;RET NZ ; ATAPI + ;SCF + ;RET ; Absent + SCF + RET Z ; Absent + LD C,low IDE.Read.Sector + IN A,(C) + DEC A + ;CF=1 + RET NZ + ; + INC C ; LD BC,IDE.Read.CylinderLow + IN L,(C) + INC C ; LD BC,IDE.Read.CylinderHigh + IN H,(C) + ;AND A + LD BC,#EB14 - 1 ; CF=1 + SBC HL,BC + SCF + RET NZ + ;A=0, CF=1 + ADC A,A ; CF=0,ZF=0 + RET ; ATAPI ; - SCF ; Absent - RET ;-------; ;-------; @@ -858,20 +901,24 @@ DETECTORS: /////////////////////////////////////////////////////////////////////[v] -SetUP_CHANELS: + IFUSED Nop_CHANELS +Nop_CHANELS: LD A,1 CALL .CMD LD A,3 CALL .CMD - LD A,0 + XOR A ; LD A,0 CALL .CMD LD A,2 .CMD: CALL SELECT_IDE - PAUSE_DJNZ 32 + PAUSE_DJNZ 0 LD BC,IDE.Write.Command LD H,IDE.CMD.ATA.Nop OUT (C),H - PAUSE_DJNZ 32 + PAUSE_DJNZ 0 + LD BC,IDE.Read.Status + IN A,(C) + RET ; Disable INTRQ ; LD BC,IDE.Write.DeviceControl ; LD A,%0000'0010 @@ -880,7 +927,7 @@ SetUP_CHANELS: ; ; ; CALL DisableStandBy ; PAUSE_DJNZ 32 - RET + ENDIF /////////////////////////////////////////////////////////////////////[^] diff --git a/src/bios/rom/SETUP/MAIN.asm b/src/bios/rom/SETUP/MAIN.asm index f35a39e..314eac8 100644 --- a/src/bios/rom/SETUP/MAIN.asm +++ b/src/bios/rom/SETUP/MAIN.asm @@ -777,6 +777,7 @@ INFO_MESSAGE: CALL TSETUP ;!TODO может пихнуть её на прерывания? CALL CONFIGURE_IDE_DRIVES.START + ;CALL CONFIGURE_IDE_DRIVES.Nop_CHANELS CALL CTRLKEY LD A,B ; [x] 05/07/2024 diff --git a/src/bios/rom/SETUP/SETTINGS.asm b/src/bios/rom/SETUP/SETTINGS.asm index 45411b0..1e8e30f 100644 --- a/src/bios/rom/SETUP/SETTINGS.asm +++ b/src/bios/rom/SETUP/SETTINGS.asm @@ -617,15 +617,15 @@ GET_CMOS_VALUE: RET ; [x] чтоб не влезло куда не надо -READCMS: - LD D,high CMOSARE - LD E,A - CP CMOS.USED_MAX_ADDRESS+1 - JR NC,.error - LD A,(DE) - RET -.error: SCF - RET +READCMS: LD D,high CMOSARE + LD E,A + CP CMOS.USED_MAX_ADDRESS+1 + JR NC,.error + LD A,(DE) + RET + ; +.error: SCF + RET ; [x] чтоб не влезло куда не надо WRITCMS: @@ -688,25 +688,22 @@ READING: JR NZ,.loop RET -WRITING: - CALL CHEKSUM - LD B,H - LD A,CMOS.Cell.CheckSum - CALL WRITCMS - LD D,CMOS.USED_MIN_ADDRESS ; !HARDCODE CMOS -.loop: - LD H,high CMOSARE - LD L,D - LD A,(HL) - PUSH DE - CALL CMOS_WR - - POP DE - LD A,CMOS.USED_MAX_ADDRESS+1 - INC D - CP D - JR NZ,.loop - RET +WRITING: CALL CHEKSUM + LD B,H + LD A,CMOS.Cell.CheckSum + CALL WRITCMS + LD D,CMOS.USED_MIN_ADDRESS +.loop: LD H,high CMOSARE + LD L,D + LD A,(HL) + PUSH DE + CALL CMOS_WR + POP DE + LD A,CMOS.USED_MAX_ADDRESS+1 + INC D + CP D + JR NZ,.loop + RET SETDEFX: LD A,#FF diff --git a/src/bios/shared/RECOVERY.IMG b/src/bios/shared/RECOVERY.IMG index ac5171fa5cff53cab03e44064ce7a9d7742af950..5be649a21a38e55f228f4e620f18009903576097 100644 GIT binary patch delta 3706 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 delta 3688 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 UKS!ey%YpF>^hx_U0hK@SZ!Z@zo&W#<