;[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 сек .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<255 LD B,num .loop: DJNZ .loop ELSE ASSERT 0, "WRONG PAUSE NUMBER!!!" ENDIF ENDM /////////////////////////////////////////////////////////////////////[v] START: CALL SetUP_CHANELS ; 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 ; CALL ScreenPOS.CRLF RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] AUTODETECT: LD A,L ;DETECT MESSAGE CALL POSTMSG CALL ScreenPOS.SUBNAME LD A,(MasterSlave) ; CALL AUTODETECTING .IDEJUMPBACK: CALL NC,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] ; !HARDCODE заменить числа на метки в этой процедуре 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 G_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] AUTODETECTING: CALL DETECTORS.CheckChanel JR C,.IDE_ABSENT CALL Bug31SecCheck JR C,.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.CDROM LD (IDEDEV),A JR .get .Its_ATA: LD A,IDE.Device.HDD LD (IDEDEV),A .get: CALL GETPARAM JR C,.IDE_ABSENT ;CALL DisableWriteCache ;CALL DisableStandBy AND A RET ; .IDE_ABSENT: LD A,IDE.Device.NONE LD (IDEDEV),A LD A,IDE.ATA.Nop LD BC,IDE.Write.Command OUT (C),A DEC B IN A,(C) ; IDE.Read.Status SCF RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] SETUP_FROM_CMOS: LD A,H LD IX,PRIM_MASTER_CMOS_T OR A JR Z,.step1 ; LD IX,PRIM_SLAVE_CMOS_T CP 1 JR Z,.step1 ; LD IX,SEC_MASTER_CMOS_T CP 2 JR Z,.step1 ; LD IX,SEC_SLAVE_CMOS_T .step1: LD HL,TEMP LD DE,TEMP+1 LD BC,511 LD (HL),0 LDIR ; CALL Bug31SecCheck JR C,.step2 ; LD HL,PAUSES.HALT.BIG CALL BITS_WAITS.Clear_BUSY JR C,AUTODETECTING.IDE_ABSENT ; .step2: LD A,(IX+2) ;M_HEAD CALL READCMS LD (TEMP+3*2),A ; !TODO сделать через структуру. HEADS PER TRACK ; LD A,(IX+1) ;M_CYLH CALL READCMS PUSH AF ; LD A,(IX+0) ;M_CYLL CALL READCMS POP HL LD L,A LD (TEMP+1*2),HL ; !TODO сделать через структуру. CYLINDERS ; LD A,(IX+3) ;M_SECT CALL READCMS LD (TEMP+6*2),A ; !TODO сделать через структуру. SECTOR PER TRACK ; LD A,IDE.Device.HDD LD (IDEDEV),A CALL IDESPEC RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] IDESPEC: 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.CDROM JP Z,.FOR_CDR ; LD BC,IDE.Read.Control IN A,(C) AND #F0 LD B,A LD A,(TEMP+#06) ; !TODO сделать через структуру. HEADS PER TRACK LD (IY+IDE.HDD_INIT_TABLE.HeadsNumber),A DEC A AND #0F OR B LD B,A LD A,(TEMP+#63) ; !TODO сделать через структуру. LBA/NON-LBA bit 1 (FROM ZERO!) BIT 1,A 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,(TEMP+#02) ; !TODO сделать через структуру. CYLINDERS LD (IY+IDE.HDD_INIT_TABLE.CylinderNumberLow),L LD (IY+IDE.HDD_INIT_TABLE.CylinderNumberHigh),H LD A,(TEMP+#0C) ; !TODO сделать через структуру. SECTOR PER TRACK LD (IY+IDE.HDD_INIT_TABLE.SectorsPerTrack),A IF IDE_Optimization LD B,high IDE.Write.Counter ELSE LD BC,IDE.Write.Counter ENDIF OUT (C),A LD A,IDE.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: ; [x] save hdd parameters to cmos for "setup" in settings 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_CDR: LD BC,IDE.Read.Control IN A,(C) AND #F0 LD HL,ICHANEL OR (HL) LD (IY+IDE.HDD_INIT_TABLE.DRV_Flags),A JR IDESPEC.END /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] IDE_CMD: PUSH AF LD HL,PAUSES.WAIT.IDE LD DE,256*IDE.ControlByte.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.ControlByte.Busy + 0 JR BITS_WAITS.WAIT_PRT /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] MODEL: LD HL,TEMP+27*2 ; !TODO сделать через структуру. LD A,(HL) OR A JR Z,.unknown LD B,20 ;!HARDCODE CALL DWPRINT 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) ;!TEST for normal bus with pull-ups ;CP #FF ;SCF ;RET Z ; AND IDE.ControlByte.Busy; + IDE.ControlByte.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 AND A SBC HL,DE EXX SCF CCF RET NZ LD A,0 LD (SKIP),A SCF RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[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_T JR Z,.save_to_cmos ; DEC A LD IX,SEC_MASTER_CMOS_T JR Z,.save_to_cmos ; CP %0001'0000 LD IX,SEC_SLAVE_CMOS_T JR Z,.save_to_cmos ; LD IX,PRIM_SLAVE_CMOS_T .save_to_cmos: LD HL,(TEMP+1*2) LD B,L LD A,(IX+0) CALL WRITCMS ; Cylinder low LD B,H LD A,(IX+1) CALL WRITCMS ; Cylinder high LD A,(TEMP+3*2) LD B,A LD A,(IX+2) CALL WRITCMS ; Heads LD A,(TEMP+6*2) LD B,A LD A,(IX+3) JP WRITCMS ; Heads /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] 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.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 NZ ; LD HL,PAUSES.HALT.Time_2s CALL BITS_WAITS.Clear_BUSY CCF RET C ; JP RESET_Slave_ATAPI /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] GETPARAM: LD HL,PAUSES.WAIT.IDE LD DE,IDE.ControlByte.DataRequest * 256 + IDE.ControlByte.DataRequest CALL BITS_WAITS.WAIT_PRT RET C LD BC,IDE.Read.Data LD HL,TEMP INIR INIR CALL IDESPEC ; [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.ControlByte.Busy*256 + 0 CALL BITS_WAITS.WAIT_PRT RET C ; LD BC,IDE.Read.Counter ; LD BC,IDE.Read.Counter IN A,(C) CP .test_counter RET Z SCF RET ;-------; ;-------; ; CHECK BY EXECUTING NOP COMMAND AND WAIT. ; Exit: CF - No device .NOP_Check: LD E,IDE.ATA.Nop LD BC,IDE.Write.Command OUT (C),E PAUSE_DJNZ 0 LD HL,PAUSES.HALT.SMALL LD BC,IDE.Read.Status ;DEC B ; .loop: IN A,(C) SCF RET Z ; AND IDE.ControlByte.Busy + IDE.ControlByte.DataRequest + IDE.ControlByte.Error CP IDE.ControlByte.Error RET Z ; HALT DEC HL LD A,H OR L SCF RET Z ; Absent ; CALL SKIPKEY RET C ; Skipped = Absent ; JR .loop ;-------; ;-------; ; CHECK WITH Identify Device. ; Exit: CF - No device ; NC and ZF - ATA ; NC and NZ - ATAPI .IdentDevCheck: LD E,IDE.ATA.IdentifyDevice LD BC,IDE.Write.Command OUT (C),E ; LD DE,IDE.ControlByte.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.ControlByte.DataRequest + IDE.ControlByte.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 ; Absent RET ;-------; ;-------; ; ATAPI or Absent ; Exit: CF - No device ; NC - ATAPI .IdentPDevChk: LD E,IDE.ATAPI.IdentifyPackedDevice LD BC,IDE.Write.Command OUT (C),E LD HL,PAUSES.WAIT.IDE LD DE,IDE.ControlByte.Busy*256 + 0 CALL BITS_WAITS.WAIT_PRT RET C ; LD BC,IDE.Read.Status IN A,(C) RRCA RET C XOR A 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 + #ED AND A SBC HL,DE XOR L RET NZ ; not absent SCF RET ; absent ;-------; /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] SetUP_CHANELS: LD A,1 CALL .CMD LD A,3 CALL .CMD LD A,0 CALL .CMD LD A,2 .CMD: CALL SELECT_IDE LD BC,IDE.Write.Command LD H,IDE.ATA.Nop OUT (C),H PAUSE_DJNZ 32 ; Disable INTRQ ; LD BC,IDE.Write.DeviceControl ; LD A,%0000'0010 ; OUT (C),A ; PAUSE_DJNZ 32 ; ; ; CALL DisableStandBy ; PAUSE_DJNZ 32 RET /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] ; DisableWriteCache: ; LD BC,IDE.Write.Features ; LD A,IDE.ATA.SetFeatures.DisableWriteCache ; OUT (C),A ; LD A,IDE.ATA.SetFeatures ; JP IDE_CMD /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] ;Disable StandBy timer ; DisableStandBy: ; LD BC,IDE.Write.Counter ; XOR A ; OUT (C),A ; LD A,IDE.ATA.Idle ; JP IDE_CMD /////////////////////////////////////////////////////////////////////[^] /////////////////////////////////////////////////////////////////////[v] ; DISABLE_8bit: ; LD BC,IDE.Write.Features ; LD A,IDE.ATA.SetFeatures.Disable8bit ; OUT (C),A ; LD A,IDE.ATA.SetFeatures ; JP IDE_CMD /////////////////////////////////////////////////////////////////////[^] ;!FIXIT CMOS переделать под названия ячеек из SP2000.inc PRIM_MASTER_CMOS_T: DB M_CYLL,M_CYLH,M_HEAD,M_SECT PRIM_SLAVE_CMOS_T: DB S_CYLL,S_CYLH,S_HEAD,S_SECT SEC_MASTER_CMOS_T: DB SM_CYLL,SM_CYLH,SM_HEAD,SM_SECT SEC_SLAVE_CMOS_T: DB SS_CYLL,SS_CYLH,SS_HEAD,SS_SECT 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 ;