;[BEGIN] ;//MODULE: AUTOIDE ;//CREATE: 27-07-2001 AUTHOR: Denis Parinov ;----------------------------------------------------------------------- ;Rev Date Name Description ;----------------------------------------------------------------------- ;R02 17.08.2023 BAO New AUTODETECT ATA/ATAPI procedure ;R01 01.08.2001 DNS FIX BUG INT "SELECT_IDE" ;R00 24.07.2001 DNS ADD SECONDARY IDE ; 24.07.2001 DNS INITIAL NEW VERSION 2.48 ;======================================================================= ; MODULE AUTOIDE /* ;Write HDW_3F7 EQU #4155 ;3F7H Command HDW_3F6 EQU #4154 ;3F6H Device Control ;Read HDR_3F7 EQU #4055 ;3F7H Drive Address HDR_3F6 EQU #4054 ;3F6H Alt. Status ;Write IDE.Write.Command EQU #4153 ; #1F7 Command HDW_DRV EQU #4152 ; #1F6 Drive Control HDW_CLH EQU #0155 ; #1F5 Cylinder High HDW_CLL EQU #0154 ; #1F4 Cylinder Low HDW_SEC EQU #0153 ; #1F3 Sector HDW_CNT EQU #0152 ; #1F2 Counter HDW_ERR EQU #0151 ; #1F1 Error HDW_DAT EQU #0150 ; #1F0 Data ;Read HDR_CTL EQU #4053 ; #1F7 Status (Control) HDR_DRV EQU #4052 ; #1F6 Drive Control HDR_CLH EQU #0055 ; #1F5 Cylinder High HDR_CLL EQU #0054 ; #1F4 Cylinder Low HDR_SEC EQU #0053 ; #1F3 Sector HDR_CNT EQU #0052 ; #1F2 Counter HDR_ERR EQU #0051 ; #1F1 Error HDR_DAT EQU #0050 ; #1F0 Data ;Bits for HDR_CTL ;---[] BSY EQU 7 RDY EQU 6 DRQ EQU 3 ERR EQU 0 ;---[] HDD EQU 1 CDROM EQU 2 ;EQU FOR IY+ ;---[] DRVHD_H EQU 0 SC_PT_H EQU 1 IDE.HDD_INIT_TABLE.HeadsNumber EQU 2 CYL_L_H EQU 3 CYL_H_H EQU 4 SPCLL_H EQU 5 SPCLH_H EQU 6 DTYPE_H EQU 7 ;---[] ;-------[ ;!!!!! hardcoded table]------- IDE0 EQU #C1C0 IDE1 EQU #C1C8 IDE2 EQU #C1D0 IDE3 EQU #C1D8 ;--------------------------------------- */ ;IDE0 DB #FF ;DRIVE/HEAD REGISTER ;00 ; DB #FF ;SECTORS PER TRACK ;01 ; DB #FF ;HEADS ;02 ; DB #FF ;CYLINDERS LOW ;03 ; DB #FF ;CYLINDERS HIGH ;04 ; DB #FF ;SECTOR PER CYLINDER LOW ;05 ; DB #FF ;SECTOR PER CYLINDER HIGH ;06 ; DB #FF ;DEVICE TYPE ;07 ;IDE1 DB #FF ;DRIVE/HEAD REGISTER ;00 ; DB #FF ;SECTORS PER TRACK ;01 ; DB #FF ;HEADS ;02 ; DB #FF ;CYLINDERS LOW ;03 ; DB #FF ;CYLINDERS HIGH ;04 ; DB #FF ;SECTOR PER CYLINDER LOW ;05 ; DB #FF ;SECTOR PER CYLINDER HIGH ;06 ; DB #FF ;DEVICE TYPE ;07 MODULE CONFIGURE_IDE_DRIVES IDE_NAME_MARKER: .None EQU #00 .NoInfo EQU #FF .Unknown EQU #FE MODULE PAUSES HALT: .Time_2s EQU 100 .SMALL EQU 200 ; 04 ᥪ .MEDIUM EQU 400 ; 08 ᥪ .BIG EQU 1550 ; 31 ᥪ WAIT: .IDE EQU #0000 .SMALL EQU #0200 .ERROR EQU #0400 ENDMODULE ; WAIT_IDE EQU #0000 ; WAIT_SML EQU #1000 ; WAIT_ERROR EQU #0400 ; M_CYLL EQU #12 ; M_CYLH EQU #13 ; M_HEAD EQU #14 ; M_SECT EQU #15 ; S_CYLL EQU #16 ; S_CYLH EQU #17 ; S_HEAD EQU #18 ; S_SECT EQU #19 ; SM_CYLL EQU #37 ; SM_CYLH EQU #38 ; SM_HEAD EQU #39 ; SM_SECT EQU #3A ; SS_CYLL EQU #3B ; SS_CYLH EQU #3C ; SS_HEAD EQU #3D ; SS_SECT EQU #3E MACRO PAUSE_DJNZ num IF num<256 LD B,num .loop: DJNZ .loop ELSE ASSERT 0, "WRONG PAUSE NUMBER!!!" ENDIF ENDM /////////////////////////////////////////////////////////////////////[v] START: ; reset all LD A,IDE.Chanel.Primary OUT (IDE.Chanel.Set),A CALL RESET_IDE_CHANEL LD A,IDE.Chanel.Secondary ;SELECT SECONDARY OUT (IDE.Chanel.Set),A CALL RESET_IDE_CHANEL ; ; IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD HL,IDE.INIT_TBL_IDE0 LD BC,256*(IDE.HDD_INIT_TABLE * 4) + #FF ;R02 ;CLEAR HDD VARIABLE .FILLIDE: LD (HL),C INC HL DJNZ .FILLIDE ; EX AF,AF' OUT (SLOT3),A LD IY,IDE.INIT_TBL_IDE0 XOR A CALL STEP1_GETCMOS LD IY,IDE.INIT_TBL_IDE1 LD A,#01 CALL STEP1_GETCMOS LD IY,IDE.INIT_TBL_IDE2 LD A,#02 CALL STEP1_GETCMOS LD IY,IDE.INIT_TBL_IDE3 LD A,#03 CALL STEP1_GETCMOS ;[x] save hdd parameters to cmos for "setup" in settings CALL WRITING ; JP ScreenPOS.CRLF ;RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] RESET_IDE_CHANEL: LD BC,IDE.Write.DeviceControl LD A,IDE.DeviceControlByte.setReset OUT (C),A DJNZ $ LD B,high IDE.Write.DeviceControl LD A,IDE.DeviceControlByte.resReset OUT (C),A RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] AUTODETECT: LD A,L ;DETECT MESSAGE CALL POSTMSG CALL ScreenPOS.SUBNAME LD A,(MasterSlave) CALL AUTODETECTING .IDEJUMPBACK: CALL NC,PRINT_IDE_MODEL LD A,(SKIP) INC A LD A,msgStrings.ideNone JR Z,.NOSKIPKEY ; LD A,msgStrings.ideSkiped .NOSKIPKEY: CALL C,POSTMSG CALL ScreenPOS.CRLF RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] STEP1_GETCMOS: LD (MasterSlave),A LD H,A ;SAVE DRIVE NUMBER CALL SELECT_IDE LD A,IDE.Device.NONE LD (IDEDEV),A LD (SKIP),A LD A,H ; AND A LD BC,CMOS_CELL.DrivesSetup_1.Mask.PriIDEmaster ;#3011 LD L,msgStrings.detectIdePrMA JR Z,.choose ; DEC A LD BC,CMOS_CELL.DrivesSetup_1.Mask.PriIDEslave ;#C011 LD L,msgStrings.detectIdePrSL JR Z,.choose ; DEC A LD BC,CMOS_CELL.DrivesSetup_2.Mask.SecIDEmaster LD L,msgStrings.detectIdeSecMA JR Z,.choose ; ;DEC A LD BC,CMOS_CELL.DrivesSetup_2.Mask.SecIDEslave LD L,msgStrings.detectIdeSecSL ;JR Z,.choose ;SCF ;RET ;0 - AUTODETECT ;1 - GETTING FROM SETUP ;2 - CD-ROM (ATAPI device) ;3 - DISABLED .choose: EI ; CALL GET_CMOS_VALUE OR A JR Z,AUTODETECT ;AUTO DETECT ; DEC A JR Z,SETUP_FROM_CMOS ;Get from CMOS (SETUP) ; DEC A RET NZ ;DON'T CHECK THIS DEVICE ;JR Z,IT_IS_ATAPI ;CD-ROM /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] IT_IS_ATAPI: LD A,L ;DETECT MESSAGE CALL POSTMSG CALL ScreenPOS.SUBNAME LD HL,PAUSES.HALT.BIG CALL BITS_WAITS.Clear_BUSY JR C,AUTODETECTING.IDE_ABSENT CALL AUTODETECTING.Its_ATAPI JP AUTODETECT.IDEJUMPBACK /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] SEND_NOP: XOR A LD BC,IDE.Write.Features OUT (C),A LD BC,IDE.Write.Command LD E,IDE.CMD.ATA.Nop OUT (C),E PAUSE_DJNZ 32 RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] AUTODETECTING: CALL SEND_NOP ; CALL DETECTORS.CheckChanel JR C,.IDE_ABSENT CALL Bug31SecCheck JR NC,.next LD HL,PAUSES.HALT.BIG CALL BITS_WAITS.Clear_BUSY JR C,.IDE_ABSENT .next: CALL DETECTORS.Counter JR C,.IDE_ABSENT CALL DETECTORS.NOP_Check JR C,.IDE_ABSENT ; CALL DISABLE_8bit ; DISABLE 8 bit data transfer 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 LD A,IDE.Device.ATAPI JR .get .Its_ATA: LD A,IDE.Device.HDD .get: LD (IDEDEV),A CALL GETPARAM RET NC ;JR C,.IDE_ABSENT ;CALL DisableWriteCache ;CALL DisableStandBy ;AND A ;RET .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 ; PAUSE_DJNZ 0 ; LD BC,IDE.Read.Status ;; ;IN A,(C) ; IDE.Read.Status SCF RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] SETUP_FROM_CMOS: LD A,H LD IX,PRIM_MASTER_CMOS_TABLE OR A JR Z,.step1 ; LD IX,PRIM_SLAVE_CMOS_TABLE DEC A JR Z,.step1 ; LD IX,SEC_MASTER_CMOS_TABLE DEC A JR Z,.step1 ; LD IX,SEC_SLAVE_CMOS_TABLE .step1: LD HL,IDENTIFY_DEVICE_BUFFER LD DE,IDENTIFY_DEVICE_BUFFER+1 LD BC,511 LD (HL),0 LDIR ; CALL Bug31SecCheck JR NC,.step2 ; LD HL,PAUSES.HALT.BIG CALL BITS_WAITS.Clear_BUSY JR C,AUTODETECTING.IDE_ABSENT ; .step2: LD A,(IX + IDE_CMOS_TABLE.Heads) CALL READCMS LD (IDENTIFY_DEVICE_BUFFER.NumHeads),A ; LD A,(IX + IDE_CMOS_TABLE.CylindersHigh) CALL READCMS PUSH AF ; LD A,(IX + IDE_CMOS_TABLE.CylindersLow) CALL READCMS POP HL LD L,A LD (IDENTIFY_DEVICE_BUFFER.NumCylinders),HL ; LD A,(IX + IDE_CMOS_TABLE.Sectors) CALL READCMS LD (IDENTIFY_DEVICE_BUFFER.NumSectorsPerTrack),A ; LD A,IDE.Device.HDD LD (IDEDEV),A ; CALL IDESPEC ; RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] PARSE_IdentifyDevice: IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A ; LD A,(IDEDEV) LD (IY+IDE.HDD_INIT_TABLE.DriveType),A CP IDE.Device.ATAPI JR Z,.FOR_ATAPI ; LD BC,IDE.Read.Control IN A,(C) AND #F0 LD B,A LD A,(IDENTIFY_DEVICE_BUFFER.NumHeads) LD (IY+IDE.HDD_INIT_TABLE.HeadsNumber),A DEC A AND #0F OR B LD B,A LD A,(IDENTIFY_DEVICE_BUFFER.Capabilities_high) AND %0000'0010 JR Z,.NONLBA ; SET 6,B .NONLBA: LD A,B LD BC,IDE.Write.DeviceHead OUT (C),A AND #F0 ;!HARDCODE DRIVE/HEAD REGISTER PHISICAL DISK bitmask LD HL,ICHANEL OR (HL) LD (IY+IDE.HDD_INIT_TABLE.DRV_Flags),A LD HL,(IDENTIFY_DEVICE_BUFFER.NumCylinders) LD (IY+IDE.HDD_INIT_TABLE.CylinderNumberLow),L LD (IY+IDE.HDD_INIT_TABLE.CylinderNumberHigh),H ; [ ] removable media LD A,(IDENTIFY_DEVICE_BUFFER.GeneralConfiguration) RLCA AND %0000'0001 LD (IY+IDE.HDD_INIT_TABLE.MediaParameters),A ; LD A,(IDENTIFY_DEVICE_BUFFER.NumSectorsPerTrack) LD (IY+IDE.HDD_INIT_TABLE.SectorsPerTrack),A LD B,high IDE.Write.Counter OUT (C),A LD A,IDE.CMD.ATA.InitializeDeviceParameters CALL IDE_CMD LD C,(IY+IDE.HDD_INIT_TABLE.SectorsPerTrack) ; Sector per track LD B,0 LD H,B LD L,B LD A,(IY+IDE.HDD_INIT_TABLE.HeadsNumber) ; Head per HDD ; .loop: ADD HL,BC DEC A JR NZ,.loop ; LD (IY+IDE.HDD_INIT_TABLE.SectorsPerCylinderLow),L LD (IY+IDE.HDD_INIT_TABLE.SectorsPerCylinderHigh),H .END: RES 1,(IY + IDE.HDD_INIT_TABLE.MediaParameters) ; [ ] removable media ; [x] save hdd parameters to cmos for "setup" in settings .END_2: LD A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) ; for save to cmos in GETPARM ; EX AF,AF' OUT (SLOT3),A AND A RET ; .FOR_ATAPI: LD BC,IDE.Read.Control IN A,(C) AND #F0 LD HL,ICHANEL OR (HL) LD (IY+IDE.HDD_INIT_TABLE.DRV_Flags),A ; LD (IY+IDE.HDD_INIT_TABLE.MediaParameters),%0000'0001 LD B,200 ; áçñâ稪 ¯®¯ë⮪ (1 ¯®¯ë⪠ - 1 HALT) .get_error_loop: PUSH BC ;LD HL,ATAPI_CMD_PACKET.TEST_UNIT_READY ;CALL EXEC_PACKET_COMMAND.start CALL EXEC_TEST_CMD POP BC JR NC,.s_size ; CP BIOS.Error.ATAPI.UnitAttention JR Z,PARSE_IdentifyDevice.END ;!TEST ;!FIXIT ZIP bug ; HALT ; PUSH AF CALL SKIPKEY JR NC,.noSkipKey ; CF=1 LD A,#FF LD (SKIP),A ; LD (IY+IDE.HDD_INIT_TABLE.SectorSize),A ; LD (IY+IDE.HDD_INIT_TABLE.SectorSize + 1),A SET 2,(IY + IDE.HDD_INIT_TABLE.MediaParameters) ; [ ] removable media POP AF SCF JR .set_sector .noSkipKey: POP AF ; CP BIOS.Error.ATAPI.NotReady JR Z,.get_error_loop DJNZ .get_error_loop ; ; [ ] sector size ATAPI .s_size: LD DE,IDENTIFY_DEVICE_BUFFER.ReservedWord224 ; ¯à®áâ® ­ã¦¥­ ¡ë« ¡ãä¥à CALL ATAPI_READ_CAPACITY_DATA ; .set_sector: LD HL,#FFFF JR C,.No_Media ; LD HL,(IDENTIFY_DEVICE_BUFFER.ReservedWord224) ; media size high LD (IY+IDE.HDD_INIT_TABLE.MediaSizeHigh),H LD (IY+IDE.HDD_INIT_TABLE.MediaSizeHigh+1),L LD HL,(IDENTIFY_DEVICE_BUFFER.ReservedWord224 + 2) ; media size low LD (IY+IDE.HDD_INIT_TABLE.MediaSizeLow),H LD (IY+IDE.HDD_INIT_TABLE.MediaSizeLow+1),L LD HL,(IDENTIFY_DEVICE_BUFFER.ReservedWord224 + 6) ; sector size ; .No_Media: LD (IY+IDE.HDD_INIT_TABLE.SectorSize),H LD (IY+IDE.HDD_INIT_TABLE.SectorSize + 1),L ; JR PARSE_IdentifyDevice.END ;!TEST ;!FIXIT ZIP bug ; /* ;====; ;!TEST ;!FIXIT ZIP bug .TEST_SET: LD HL,.MODE_SENSE LD DE,SYS_PAGE.MS_BPB ; ¯à®áâ® ­ã¦¥­ ¡ë« ¡ãä¥à LD BC,BIOS.DRV_EXTENDED.ATAPI_Custom_PCMD CALL ATAPI_CUSTOM_CMD JR NC,.OK_DONE ; LD A,COLORS.CGA.BORDER.CYAN OUT (BorderColor),A JR .go_exit ; .OK_DONE: LD A,(SYS_PAGE.MS_BPB + 2) AND A JR NZ,.go_exit ; LD (SYS_PAGE.MS_BPB + 10),A LD HL,(SYS_PAGE.MS_BPB) LD (.MODE_SELECT.Size),HL LD HL,.MODE_SELECT LD DE,SYS_PAGE.MS_BPB ; ¯à®áâ® ­ã¦¥­ ¡ë« ¡ãä¥à LD BC,BIOS.DRV_EXTENDED.ATAPI_Custom_PCMD CALL ATAPI_CUSTOM_CMD JR NC,.go_exit ; LD A,COLORS.CGA.BORDER.GREEN OUT (BorderColor),A ;JR .go_exit ; .go_exit: AND A JP PARSE_IdentifyDevice.END ; ; .MODE_SENSE: BYTE #5A BYTE #08 .MODE_SENSE.Page: BYTE #08 ;bit7..6 - Page Control, bit5..0 - Page Code BLOCK 4,0 BYTE #02,#00 BLOCK 3,0 ; .MODE_SELECT: BYTE #55 BYTE #08 .MODE_SELECT.Page: BYTE #08 ;bit7..6 - Page Control, bit5..0 - Page Code BLOCK 4,0 .MODE_SELECT.Size: BYTE #02,#00 BLOCK 3,0 ; ;====; ;!TEST */ ; /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] IDE_CMD: PUSH AF LD HL,PAUSES.WAIT.IDE LD DE,256*IDE.CtrlByte.Busy + 0 CALL BITS_WAITS.WAIT_PRT POP HL RET C INC B ; LD BC,IDE.Write.Command OUT (C),H LD HL,PAUSES.WAIT.IDE ;LD DE,256*IDE.CtrlByte.Busy + 0 JR BITS_WAITS.WAIT_PRT /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] PRINT_IDE_MODEL: LD HL,IDENTIFY_DEVICE_BUFFER.ModelNumber LD A,(HL) OR A JR Z,.unknown ; ;CALL PRINT_STR_BIG_ENDIAN LD B,+(_ATA_IDENTIFY_DEVICE_DATA.MaximumBlockTransfer - _ATA_IDENTIFY_DEVICE_DATA.ModelNumber)/2 PUSH HL CALL ATAxx_IdentifyDevice.STR_BIG_ENDIAN_TO_LITTLE POP HL LD B,_ATA_IDENTIFY_DEVICE_DATA.MaximumBlockTransfer - _ATA_IDENTIFY_DEVICE_DATA.ModelNumber CALL LP_PRINT_LINE2 AND A RET ; .unknown: ;LD HL,.marker ;LD A,.marker.Size ;CALL COPY_IDE_NAME_TO_SYS_PAGE LD A,msgStrings.ideUnknown CALL POSTMSG AND A RET ; ;.marker: BYTE IDE_NAME_MARKER.Unknown ;.marker.Size: EQU $ - .marker /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] BITS_WAITS: ; IN: ; HL - Waiting delay ; DE - MASK : PATTERN ; OUT: ; NC: (PORT & D)-E = 0 ; CF: waiting delay exceeded .WAIT_PRT: LD BC,IDE.Read.Status .loop: IN A,(C) AND D CP E RET Z DEC HL CALL SKIPKEY RET C LD A,L OR H JP NZ,.loop SCF RET ; ; Pause for clear BUSY and DATA REQUEST .Clear_BUSY: LD BC,IDE.Read.Status IN A,(C) AND IDE.CtrlByte.Busy; + IDE.CtrlByte.DataRequest RET Z ; HALT DEC HL LD A,H OR L SCF RET Z ; CALL SKIPKEY RET C JR .Clear_BUSY /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] SELECT_IDE: AND A ;%0000'0011 LD B,IDE.Drive.Master JR Z,.AUTO_0 ; DEC A LD B,IDE.Drive.Slave JR Z,.AUTO_0 ; DEC A ;R00 LD B,IDE.Drive.Master JR Z,.AUTO_1 ; DEC A LD B,IDE.Drive.Slave .AUTO_1: LD A,IDE.Chanel.Secondary ;SELECT SECONDARY OUT (IDE.Chanel.Set),A JP .AUTO ; .AUTO_0: LD A,IDE.Chanel.Primary ;SELECT PRIMARY OUT (IDE.Chanel.Set),A ; XOR A .AUTO: LD (ICHANEL),A ;R01 LD A,B LD BC,IDE.Write.DeviceHead OUT (C),A ; RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] SKIPKEY: EXX CALL SCANKEY EXX ;SCF ;CCF RET Z EXX LD HL,#3E00 ;!HARDCODE ;XOR A SBC HL,DE EXX SCF CCF RET NZ ;A=0 LD (SKIP),A INC A SCF RET ;ZF=0, CF=1 /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] ; [x] save hdd parameters to cmos for "setup" in settings ; IN: A' = DRV_Flags SaveToCMOS: LD A,(IDEDEV) CP IDE.Device.HDD RET NZ EX AF,AF' ;LD A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) AND %0001'0001 LD IX,PRIM_MASTER_CMOS_TABLE JR Z,.save_to_cmos ; DEC A LD IX,SEC_MASTER_CMOS_TABLE JR Z,.save_to_cmos ; CP %0001'0000 LD IX,SEC_SLAVE_CMOS_TABLE JR Z,.save_to_cmos ; LD IX,PRIM_SLAVE_CMOS_TABLE .save_to_cmos: LD HL,(IDENTIFY_DEVICE_BUFFER.NumCylinders) LD B,L LD A,(IX + IDE_CMOS_TABLE.CylindersLow) CALL WRITCMS LD B,H LD A,(IX + IDE_CMOS_TABLE.CylindersHigh) CALL WRITCMS LD A,(IDENTIFY_DEVICE_BUFFER.NumHeads) LD B,A LD A,(IX + IDE_CMOS_TABLE.Heads) CALL WRITCMS ; Heads LD A,(IDENTIFY_DEVICE_BUFFER.NumSectorsPerTrack) LD B,A LD A,(IX + IDE_CMOS_TABLE.Sectors) JP WRITCMS /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[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 ; 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 RRA RET C ; 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 PAUSE_DJNZ 32 LD BC,IDE.Write.Command LD A,IDE.CMD.ATAPI.Reset OUT (C),A PAUSE_DJNZ 64 LD A,IDE.Drive.Master LD BC,IDE.Write.DeviceHead OUT (C),A PAUSE_DJNZ 32 ; ;CALL SEND_NOP ;SCF ;CF=1 RET ; .skip: POP BC ; ¡ « ­á á⥪  JP AUTODETECTING.IDE_ABSENT /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] GETPARAM: LD HL,PAUSES.WAIT.IDE LD DE,256*IDE.CtrlByte.DataRequest + IDE.CtrlByte.DataRequest CALL BITS_WAITS.WAIT_PRT RET C LD BC,IDE.Read.Data LD HL,IDENTIFY_DEVICE_BUFFER INIR INIR CALL PARSE_IdentifyDevice ; [x] save hdd parameters to cmos for "setup" in settings CALL SaveToCMOS AND A RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] DETECTORS: ;-------; ; CHECK BY COUNTER PORT. ; Exit: CF - No device .test_counter EQU 5 .Counter: LD A,.test_counter LD BC,IDE.Write.Counter OUT (C),A LD HL,PAUSES.WAIT.SMALL LD DE,IDE.CtrlByte.Busy*256 + 0 CALL BITS_WAITS.WAIT_PRT RET C ; LD BC,IDE.Read.Counter IN A,(C) CP .test_counter SCF RET NZ AND A RET ; ; § ¡¨¢ ¥¬ âãä⮩ ¤«ï â¥áâ  ATAPI ¢ .IdentDevCheck ;XOR A ;INC B ;INC C ; IDE.Write.Sector ;OUT (C),A ;INC C ; IDE.Write.CylinderLow ;OUT (C),A ;INC C ; IDE.Write.CylinderHigh ;OUT (C),A ;RET ;-------; ;-------; ; CHECK BY EXECUTING NOP COMMAND AND WAIT. ; Exit: CF - No device .NOP_Check: CALL SEND_NOP LD HL,PAUSES.HALT.MEDIUM LD BC,IDE.Read.Status ; .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 RET Z ; HALT DEC HL LD A,H OR L ;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 ;-------; ;-------; ; CHECK WITH Identify Device. ; Exit: CF - No device ; NC and ZF - ATA ; NC and NZ - ATAPI .IdentDevCheck: LD E,IDE.CMD.ATA.IdentifyDevice LD BC,IDE.Write.Command OUT (C),E ; LD DE,IDE.CtrlByte.Busy * 256 + 0 LD HL,PAUSES.WAIT.IDE CALL BITS_WAITS.WAIT_PRT RET C ; Absent ; LD BC,IDE.Read.Status IN A,(C) RRCA JR C,.non_ATA ; AND (IDE.CtrlByte.DataRequest + IDE.CtrlByte.Ready) / 2 SCF RET Z ; XOR A RET ; ATA ; .non_ATA: LD BC,IDE.Read.Error IN A,(C) AND IDE.ErrorByte.Abort ; RET NZ ; ATAPI SCF RET ; Absent ; check signature #0114EB ;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 ; ;-------; ;-------; ; ATAPI or Absent ; Exit: CF - No device ; NC - ATAPI .IdentPDevChk: LD E,IDE.CMD.ATAPI.IdentifyPacketDevice LD BC,IDE.Write.Command OUT (C),E ; LD HL,PAUSES.HALT.Time_2s LD DE,IDE.CtrlByte.Busy*256 + 0 CALL BITS_WAITS.Clear_BUSY RET C ; ; BC = IDE.Read.Status IN A,(C) RRCA RET ;-------; ;-------; ; ¥á«¨ ª ­ « ¯ãá⮩, â® ç¨â ¥âáï ¨§ ¯®àâ  â®, çâ® ¡ë«® ¢ëáâ ¢«¥­® ; ¯®á«¥¤­¨¬ ­  設ã c çñâ­®£®  ¤à¥á  ¢ ¯ ¬ï⨠  íâ® ¯¥à¢ë© ¨«¨ ¢â®à®© ; ¡ ©â ª®¤  ª®¬ ­¤ë ALIGN 2 ; âã⠭㦭® ¢ëà ¢­¨¢ ­¨¥ ¯® § ¤ã¬ ­­ë¬  ¤à¥á ¬ ¤«ï ª®¬ ­¤ ç⥭¨ï ¨§ ¯®à⮢ .CheckChanel: LD BC,IDE.Read.Status IN A,(C) ;#ED78 A=#78 IN L,(C) ;#ED68 L=#68 LD D,A IN A,(C) ;#ED60 A=#ED LD E,L ; ¥á«¨ ¯ãá⮩: DE=#7868, A=#ED ; LD HL,#7868 ; #7868 + #ED = #7955 AND A SBC HL,DE JR Z,.NOT_HL ; AND A RET ; not absent ; .NOT_HL: XOR #ED RET NZ SCF RET ; absent ;-------; /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] IFUSED Nop_CHANELS Nop_CHANELS: LD A,1 CALL .CMD LD A,3 CALL .CMD XOR A ; LD A,0 CALL .CMD LD A,2 .CMD: CALL SELECT_IDE PAUSE_DJNZ 32 LD BC,IDE.Write.Command LD H,IDE.CMD.ATA.Nop OUT (C),H PAUSE_DJNZ 64 LD BC,IDE.Read.Status IN A,(C) RET ; Disable INTRQ ; LD BC,IDE.Write.DeviceControl ; LD A,%0000'0010 ; OUT (C),A ; PAUSE_DJNZ 32 ; ; ; CALL DisableStandBy ; PAUSE_DJNZ 32 ENDIF /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] ; ‚室: A - ¤«¨­  áâப¨ ; HL -  ¤à¥á áâப¨ ; IY -  ¤à¥á ¤ ­­ëå ¤à ©¢  ¢ SYS_PAGE (.IDE_0 .. .IDE_3) ; ‚ë室: B - ¤«¨­  áâப¨ ; COPY_IDE_NAME_TO_SYS_PAGE: ; ; save IDE name ; LD C,A ; LD B,0 ; IN A,(SLOT3) ; EX AF,AF' ; LD A,SYS_PAGE ; OUT (SLOT3),A ; ; SYS_PAGE.IDE_x --> SYS_PAGE.IDE_x.NAME ; PUSH IY ; POP DE ; SET 1,D ; LD A,%0010'0000 ; XOR E ; LD E,A ; SLA E ; SLA E ; ; ; LD A,C ; LDIR ; LD B,A ; EX AF,AF' ; OUT (SLOT3),A ; RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] ; DisableWriteCache: ; LD BC,IDE.Write.Features ; LD A,IDE.CMD.ATA.SetFeatures.DisableWriteCache ; OUT (C),A ; LD A,IDE.CMD.ATA.SetFeatures ; JP IDE_CMD /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] ;Disable StandBy timer ; DisableStandBy: ; LD BC,IDE.Write.Counter ; XOR A ; OUT (C),A ; LD A,IDE.CMD.ATA.Idle ; JP IDE_CMD /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] ; DISABLE_8bit: ; LD BC,IDE.Write.Features ; LD A,IDE.CMD.ATA.SetFeatures.Disable8bit ; OUT (C),A ; LD A,IDE.CMD.ATA.SetFeatures ; JP IDE_CMD /////////////////////////////////////////////////////////////////////[^] IDE_CMOS_TABLE: .CylindersLow EQU 0 .CylindersHigh EQU 1 .Heads EQU 2 .Sectors EQU 3 ; PRIM_MASTER_CMOS_TABLE: DB CMOS_CELL.IDE_Setup.PriMaster.CylindersLow DB CMOS_CELL.IDE_Setup.PriMaster.CylindersHigh DB CMOS_CELL.IDE_Setup.PriMaster.Heads DB CMOS_CELL.IDE_Setup.PriMaster.Sectros PRIM_SLAVE_CMOS_TABLE: DB CMOS_CELL.IDE_Setup.PriSlave.CylindersLow DB CMOS_CELL.IDE_Setup.PriSlave.CylindersHigh DB CMOS_CELL.IDE_Setup.PriSlave.Heads DB CMOS_CELL.IDE_Setup.PriSlave.Sectros SEC_MASTER_CMOS_TABLE: DB CMOS_CELL.IDE_Setup.SecMaster.CylindersLow DB CMOS_CELL.IDE_Setup.SecMaster.CylindersHigh DB CMOS_CELL.IDE_Setup.SecMaster.Heads DB CMOS_CELL.IDE_Setup.SecMaster.Sectros SEC_SLAVE_CMOS_TABLE: DB CMOS_CELL.IDE_Setup.SecSlave.CylindersLow DB CMOS_CELL.IDE_Setup.SecSlave.CylindersHigh DB CMOS_CELL.IDE_Setup.SecSlave.Heads DB CMOS_CELL.IDE_Setup.SecSlave.Sectros SKIP: BYTE #FF IDEDEV: BYTE #FF ICHANEL: BYTE #00 MasterSlave BYTE #00 ;WAITHDD DEC L ; RET NZ ; DEC H ; RET NZ ; DEC E ; RET NZ ; SCF ; RET ; E - Second * 10 ;PAUSE LD HL,#0000 ;PAUSE1 DEC L ; JR NZ,PAUSE1 ; DEC H ; JR NZ,PAUSE1 ; DEC E ; JR NZ,PAUSE1 ; RET ENDMODULE ;