Sprinter-BIOS/bios/rom/SETUP/AUTOIDE.asm
2026-05-19 19:48:28 +10:00

1128 lines
24 KiB
NASM
Raw Blame History

;[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
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 ; <20><><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD>⮪ (1 <20><><EFBFBD><EFBFBD>⪠ - 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 ; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
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 ; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
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 ; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
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
LD B,+(_ATA_IDENTIFY_DEVICE_DATA.MaximumBlockTransfer - _ATA_IDENTIFY_DEVICE_DATA.ModelNumber)/2
CALL PRINT_STR_BIG_ENDIAN
AND A
RET
;
.unknown: LD A,msgStrings.ideUnknown
CALL POSTMSG
AND A
RET
/////////////////////////////////////////////////////////////////////[^]
/////////////////////////////////////////////////////////////////////[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 ; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD>
JP AUTODETECTING.IDE_ABSENT
/////////////////////////////////////////////////////////////////////[^]
/////////////////////////////////////////////////////////////////////[v]
GETPARAM: LD HL,PAUSES.WAIT.IDE
;LD DE,256*(IDE.CtrlByte.Busy + IDE.CtrlByte.DataRequest) + IDE.CtrlByte.DataRequest
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
;
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> ATAPI <20> .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
;-------;
;-------;
; <20><20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>⮩, <20><> <20><><EFBFBD><E2A0A5><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><>, <20><><EFBFBD> <20><20><><EFBFBD><EFBFBD><E2A0A2><EFBFBD><EFBFBD>
; <20><><EFBFBD><E1ABA5><EFBFBD><EFBFBD> <20><><> c <20><><EFBFBD><E2ADAE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>
; <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ALIGN 2 ; <20><><EFBFBD> <20><EFBFBD> <20><><EFBFBD><E0A0A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><E3ACA0><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><E2A5AD> <20><> <20><><EFBFBD>
.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
; <20><20><><EFBFBD>⮩: 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]
; 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
;