From be6233a072213dae0a3cb00719d930ad46ac3617 Mon Sep 17 00:00:00 2001 From: Anatoliy Belyanskiy Date: Thu, 21 Dec 2023 05:31:39 +1000 Subject: [PATCH] ... --- Shared_Includes | 2 +- src/bios/exp/BIOS_FUNC.asm | 254 +++++++++--------- src/bios/exp/EXTENDED/FDD_DRIVER_2.asm | 4 +- src/bios/exp/EXTENDED/IDE/CD_DRV.ASM | 350 ++++++++++++++----------- src/bios/exp/EXTENDED/IDE/HDD_DRV.ASM | 125 ++++----- src/bios/exp/EXTENDED/IDE/shared.asm | 100 +++++++ src/bios/exp/FUNC_5x.asm | 5 +- src/bios/rom/SETUP/AUTOIDE.asm | 4 +- src/bios/rom/SETUP/MAIN.asm | 3 +- src/bios/shared/RECOVERY.IMG | Bin 98304 -> 98304 bytes 10 files changed, 486 insertions(+), 361 deletions(-) create mode 100644 src/bios/exp/EXTENDED/IDE/shared.asm diff --git a/Shared_Includes b/Shared_Includes index f112b13..226dbc1 160000 --- a/Shared_Includes +++ b/Shared_Includes @@ -1 +1 @@ -Subproject commit f112b1359045d7fe7aa47f843011fddc5e03eba2 +Subproject commit 226dbc13e8cacb202848245b7f11de3df2f0cbd7 diff --git a/src/bios/exp/BIOS_FUNC.asm b/src/bios/exp/BIOS_FUNC.asm index 3d7726d..cb4241c 100644 --- a/src/bios/exp/BIOS_FUNC.asm +++ b/src/bios/exp/BIOS_FUNC.asm @@ -92,11 +92,11 @@ TAB_FNS: DB low FN_5x_Parser_8 ;#58 - Get Media parameters DB low FN_5x_Parser_9 ;#59 - Set Media parameters - DB low DRV_VERSION ;#5A - Version number - DB low FN_RESERVED_5x ;#5B - DB low FN_RESERVED_5x ;#5C - DB low FN_RESERVED_5x ;#5D - DB low FN_RESERVED_5x ;#5E + DB low DRV_VERSION ;#5A - Version number + DB low FN_RESERVED_5x ;#5B + DB low FN_RESERVED_5x ;#5C + DB low FN_RESERVED_5x ;#5D + DB low FN_5x_Parser_E ;#5E DB low DRV_LIST ;#5F ;-------------- @@ -288,7 +288,7 @@ TAB_FNS: DB high FN_RESERVED_5x DB high FN_RESERVED_5x DB high FN_RESERVED_5x - DB high FN_RESERVED_5x + DB high FN_5x_Parser_E DB high DRV_LIST ;-------------- @@ -434,6 +434,27 @@ TAB_FNS: DB high REINIT DB high FN_RESERVED DB high FN_VERSION +//////////////////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////////////////// +; +; ,----, ,----,. +; ,/ .`| ,' ,' | +; ,` .' : ,--, ,' .' | +; ; ; / ,---, ,--.'| ,----.' .' +; .'___,/ ,' ,---.'| | | : | | .' +; | : | | | : : : ' : : |--, ,--, ,--, +; ; |.'; ; ,--.--. : : : | ' | ,---. : | ;.' \|'. \/ .`| +; `----' | | / \ : |,-.' | | / \ | | |' \/ / ; +; ' : ;.--. .-. || : ' || | : / / | `----'.'\ ; \ \.' / +; | | ' \__\/: . .| | / :' : |__ . ' / | __ \ . | \ ; ; +; ' : | ," .--.; |' : |: || | '.'|' ; /| / /\/ / : / \ \ \ +; ; |.' / / ,. || | '/ :; : ;' | / | / ,,/ ',- ./__; ; \ +; '---' ; : .' \ : || , / | : | \ ''\ ;| :/\ \ ; +; | , .-./ \ / ---`-' \ \ / \ \ .' `---' `--` +; `--`---' `-'----' `----' `--`-,-' +//////////////////////////////////////////////////////////////////////////////////////// _mInfoALIGN 256,0 @@ -451,11 +472,11 @@ TAB_5xFNS: ; --< LOW PART >-- ;-------------------------------------------------------------[ FDD #0 ] ; - DB low FN_RESERVED_5x ;#50 - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#50 - Дубль. На эту функцию прыгает из основного обработчика DB low FDD_5x.RESET ;#51 DB low FDD_5x.LONG_READ ;#52 DB low FDD_5x.LONG_WRITE ;#53 - DB low FN_ABSENT_5x ;#54 + DB low FN_ABSENT_5x ;#54 DB low FDD_5x.READ ;#55 DB low FDD_5x.WRITE ;#56 DB low FDD_5x.DETECT ;#57 @@ -463,10 +484,10 @@ TAB_5xFNS: DB low FDD_5x.SETMED ;#59 DB low DRV_VERSION ;#5A - Дубль. На эту функцию прыгает из основного обработчика - DB low FN_RESERVED_5x ;#5B - Дубль. На эту функцию прыгает из основного обработчика - DB low FN_RESERVED_5x ;#5C - Дубль. На эту функцию прыгает из основного обработчика - DB low FN_RESERVED_5x ;#5D - Дубль. На эту функцию прыгает из основного обработчика - DB low FN_RESERVED_5x ;#5E - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#5B - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#5C - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#5D - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#5E - Дубль. На эту функцию прыгает из основного обработчика DB low DRV_LIST ;#5F - Дубль. На эту функцию прыгает из основного обработчика ; ;---------------------------------------------------------------------[] @@ -477,14 +498,14 @@ TAB_5xFNS: ;-------------------------------------------------------[ RAM DRIVE #6 ] ; - DB low FN_RESERVED_5x - DB low FN_ABSENT_5x + DB low FN_RESERVED_5x + DB low FN_ABSENT_5x DB low RMD_5x.LONG_READ DB low RMD_5x.LONG_WRITE - DB low FN_ABSENT_5x + DB low FN_ABSENT_5x DB low RMD_5x.READ DB low RMD_5x.WRITE - DB low FN_ABSENT_5x + DB low FN_ABSENT_5x DB low RMD_5x.GETMED DB low RMD_5x.SETMED @@ -502,7 +523,7 @@ TAB_5xFNS: ;-------------------------------------------------------------[ HDD #8 ] ; - DB low FN_RESERVED_5x + DB low FN_RESERVED_5x DB low HDD_5x.RESET DB low HDD_5x.LONG_READ DB low HDD_5x.LONG_WRITE @@ -514,10 +535,10 @@ TAB_5xFNS: DB low HDD_5x.SETMED DB low DRV_VERSION - DB low FN_RESERVED_5x - DB low FN_RESERVED_5x - DB low FN_RESERVED_5x - DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x DB low DRV_LIST ;---------------------------------------------------------------------[] @@ -527,22 +548,22 @@ TAB_5xFNS: ;-----------------------------------------------------------[ CDROM #C ] ; - DB low FN_RESERVED_5x + DB low FN_RESERVED_5x DB low CD_5x.RESET DB low CD_5x.LONG_READ - DB low FN_ABSENT_5x - DB low FN_ABSENT_5x + DB low FN_ABSENT_5x + DB low FN_ABSENT_5x DB low CD_5x.READ - DB low FN_ABSENT_5x + DB low FN_ABSENT_5x DB low CD_5x.DETECT - DB low FN_ABSENT_5x - DB low FN_ABSENT_5x + DB low FN_ABSENT_5x + DB low FN_ABSENT_5x DB low DRV_VERSION - DB low FN_RESERVED_5x - DB low FN_RESERVED_5x - DB low FN_RESERVED_5x - DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low CD_5x.Extended DB low DRV_LIST ;---------------------------------------------------------------------[] @@ -554,23 +575,22 @@ TAB_5xFNS: ; --< HIGH PART >-- ;-------------------------------------------------------------[ FDD #0 ] ; - DB high FN_RESERVED_5x ;#50 - Дубль. На эту функцию прыгает из основного обработчика - DB high FDD_5x.RESET ;#51 - DB high FDD_5x.LONG_READ ;#52 - DB high FDD_5x.LONG_WRITE ;#53 - DB high FN_ABSENT_5x ;#54 - DB high FDD_5x.READ ;#55 - DB high FDD_5x.WRITE ;#56 - DB high FDD_5x.DETECT ;#57 - DB high FDD_5x.GETMED ;#58 - DB high FDD_5x.SETMED ;#59 - - DB high DRV_VERSION ;#5A - Дубль. На эту функцию прыгает из основного обработчика - DB high FN_RESERVED_5x ;#5B - Дубль. На эту функцию прыгает из основного обработчика - DB high FN_RESERVED_5x ;#5C - Дубль. На эту функцию прыгает из основного обработчика - DB high FN_RESERVED_5x ;#5D - Дубль. На эту функцию прыгает из основного обработчика - DB high FN_RESERVED_5x ;#5E - Дубль. На эту функцию прыгает из основного обработчика - DB high DRV_LIST ;#5F - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#50 - Дубль. На эту функцию прыгает из основного обработчика + DB high FDD_5x.RESET ;#51 + DB high FDD_5x.LONG_READ ;#52 + DB high FDD_5x.LONG_WRITE ;#53 + DB high FN_ABSENT_5x ;#54 + DB high FDD_5x.READ ;#55 + DB high FDD_5x.WRITE ;#56 + DB high FDD_5x.DETECT ;#57 + DB high FDD_5x.GETMED ;#58 + DB high FDD_5x.SETMED ;#59 + DB high DRV_VERSION ;#5A - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#5B - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#5C - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#5D - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#5E - Extended functions + DB high DRV_LIST ;#5F - Дубль. На эту функцию прыгает из основного обработчика ; ;---------------------------------------------------------------------[] @@ -580,23 +600,22 @@ TAB_5xFNS: ;-------------------------------------------------------[ RAM DRIVE #6 ] ; - DB high FN_RESERVED_5x - DB high FN_ABSENT_5x - DB high RMD_5x.LONG_READ - DB high RMD_5x.LONG_WRITE - DB high FN_ABSENT_5x - DB high RMD_5x.READ - DB high RMD_5x.WRITE - DB high FN_ABSENT_5x - DB high RMD_5x.GETMED - DB high RMD_5x.SETMED - - DB high DRV_VERSION - DB high FN_RESERVED_5x - DB high FN_RESERVED_5x - DB high FN_RESERVED_5x - DB high FN_RESERVED_5x - DB high DRV_LIST + DB high FN_RESERVED_5x + DB high FN_ABSENT_5x + DB high RMD_5x.LONG_READ + DB high RMD_5x.LONG_WRITE + DB high FN_ABSENT_5x + DB high RMD_5x.READ + DB high RMD_5x.WRITE + DB high FN_ABSENT_5x + DB high RMD_5x.GETMED + DB high RMD_5x.SETMED + DB high DRV_VERSION + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high DRV_LIST ;---------------------------------------------------------------------[] ;---------------------------------[ #7 ] @@ -605,23 +624,22 @@ TAB_5xFNS: ;-------------------------------------------------------------[ HDD #8 ] ; - DB high FN_RESERVED_5x - DB high HDD_5x.RESET - DB high HDD_5x.LONG_READ - DB high HDD_5x.LONG_WRITE - DB high HDD_5x.VERIFY - DB high HDD_5x.READ - DB high HDD_5x.WRITE - DB high HDD_5x.DETECT - DB high HDD_5x.GETMED - DB high HDD_5x.SETMED - - DB high DRV_VERSION - DB high FN_RESERVED_5x - DB high FN_RESERVED_5x - DB high FN_RESERVED_5x - DB high FN_RESERVED_5x - DB high DRV_LIST + DB high FN_RESERVED_5x + DB high HDD_5x.RESET + DB high HDD_5x.LONG_READ + DB high HDD_5x.LONG_WRITE + DB high HDD_5x.VERIFY + DB high HDD_5x.READ + DB high HDD_5x.WRITE + DB high HDD_5x.DETECT + DB high HDD_5x.GETMED + DB high HDD_5x.SETMED + DB high DRV_VERSION + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high DRV_LIST ;---------------------------------------------------------------------[] ;-----------------------------[ #9..#B ] @@ -630,23 +648,22 @@ TAB_5xFNS: ;----------------------------------------------------------[ CDROM #C0 ] ; - DB high FN_RESERVED_5x - DB high CD_5x.RESET - DB high CD_5x.LONG_READ - DB high FN_ABSENT_5x - DB high FN_ABSENT_5x - DB high CD_5x.READ - DB high FN_ABSENT_5x - DB high CD_5x.DETECT - DB high FN_ABSENT_5x - DB high FN_ABSENT_5x - - DB high DRV_VERSION - DB high FN_RESERVED_5x - DB high FN_RESERVED_5x - DB high FN_RESERVED_5x - DB high FN_RESERVED_5x - DB high DRV_LIST + DB high FN_RESERVED_5x + DB high CD_5x.RESET + DB high CD_5x.LONG_READ + DB high FN_ABSENT_5x + DB high FN_ABSENT_5x + DB high CD_5x.READ + DB high FN_ABSENT_5x + DB high CD_5x.DETECT + DB high FN_ABSENT_5x + DB high FN_ABSENT_5x + DB high DRV_VERSION + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high CD_5x.Extended + DB high DRV_LIST ;---------------------------------------------------------------------[] ;-----------------------------[ #D..#F ] @@ -668,31 +685,34 @@ EXP_FNS_RST18: RET FN_5x_Parser_1: - LD C,1 - JP FN_5x_Parser + LD C,#01 + JP FN_5x_Parser FN_5x_Parser_2: - LD C,2 - JP FN_5x_Parser + LD C,#02 + JP FN_5x_Parser FN_5x_Parser_3: - LD C,3 - JP FN_5x_Parser + LD C,#03 + JP FN_5x_Parser FN_5x_Parser_4: - LD C,4 - JP FN_5x_Parser -FN_5x_Parser_5: - LD C,5 - JP FN_5x_Parser + LD C,#04 + JP FN_5x_Parser FN_5x_Parser_6: - LD C,6 - JP FN_5x_Parser + LD C,#06 + JP FN_5x_Parser FN_5x_Parser_7: - LD C,7 - JP FN_5x_Parser + LD C,#07 + JP FN_5x_Parser FN_5x_Parser_8: - LD C,8 - JP FN_5x_Parser + LD C,#08 + JP FN_5x_Parser FN_5x_Parser_9: - LD C,9 + LD C,#09 + JP FN_5x_Parser +FN_5x_Parser_E: + LD C,#0E + JP FN_5x_Parser +FN_5x_Parser_5: + LD C,5 FN_5x_Parser: PUSH HL LD H,A diff --git a/src/bios/exp/EXTENDED/FDD_DRIVER_2.asm b/src/bios/exp/EXTENDED/FDD_DRIVER_2.asm index b8635e7..d4dd0f4 100644 --- a/src/bios/exp/EXTENDED/FDD_DRIVER_2.asm +++ b/src/bios/exp/EXTENDED/FDD_DRIVER_2.asm @@ -173,7 +173,7 @@ FDD_5x.READ: ; HL:IX - Sector ; DE - Address ; B - Sector counter -; A'- Memory ID Block +; A'- Memory Page Number ;Return: ; HL:IX - Sector + Sector counter ; DE - Address + (Sector counter * Size sector) @@ -320,7 +320,7 @@ FDD_5x.WRITE: ; HL:IX - Sector ; DE - Address ; B - Sector counter -; A'- Memory ID Block +; A'- Memory Page Number ;Return: ; HL:IX - Sector + Sector counter ; DE - Address + (Sector counter * Size sector) diff --git a/src/bios/exp/EXTENDED/IDE/CD_DRV.ASM b/src/bios/exp/EXTENDED/IDE/CD_DRV.ASM index 35a1ac8..af8984b 100644 --- a/src/bios/exp/EXTENDED/IDE/CD_DRV.ASM +++ b/src/bios/exp/EXTENDED/IDE/CD_DRV.ASM @@ -1,4 +1,6 @@ -;CD ROM DRIVE DRIVER ;!FIXIT ALL! +;[ ] 18/12/2023. добавление/допиливание API CD-ROM (ATAPI) + +;CD ROM DRIVE DRIVER ;--------------------------------------------------------------- ;Rev Date Name Description ;--------------------------------------------------------------- @@ -11,12 +13,15 @@ RAM_ATAPI_PK EQU SYS_PAGE.SHARED_BUFFER_32b RAM_ATAPI_READ EQU SYS_PAGE.SHARED_BUFFER_32b+16 ASSERT ((PKTSIZE % 2) = 0), "PKTSIZE must be an even number" -;[]===========================================================[] + +;[]================================================================[#51] CD_5x.RESET: + LD C,IDE.Device.CDROM + CALL SELECT_DRIVE + RET C LD B,50 .loop: PUSH BC - LD A,1 CALL CD_TEST POP BC RET NC @@ -24,70 +29,46 @@ CD_5x.RESET: HALT DJNZ .loop RET -;[]===========================================================[] +;[]================================================================[#51] -;[]===========================================================[] -CD_5x.LONG_READ: ; !FIXIT не надо сохранять страницу SLOT3 как в других драйвах? -;[]===========================================================[] -;[]===========================================================[] +;[]================================================================[#55] +;Function: Read Sectors +; A - Disk +; HL:IX - Sector +; DE - Address +; B - Sector counter +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) +;READ SECTOR(S) CD_5x.READ: - LD A,1 - JP CD_READ -;[]===========================================================[] - - -;[]===========================================================[] -CD.OPEN: - LD A,1 - JP CD_OPEN -;[]===========================================================[] - - -;[]===========================================================[] -CD.CLOSE: - LD A,1 - JP CD_CLOSE -;[]===========================================================[] - -CD_TEST LD HL,CMDNOPP - LD DE,0 - CALL AP_COM - RET - -; -;[]===========================================================[] -CD_5x.DETECT: ; !FIXIT - SCF - RET -;[]===========================================================[] -CD_OPEN: - LD HL,CMDOPEN - LD DE,0 - CALL AP_COM - RET -; - -CD_CLOSE: - LD HL,CMDCLOS - LD DE,0 - CALL AP_COM - RET - -; HL:IX - SECTOR -; DE - ADDRESS -; B - SECTOR COUNT -; A - DRIVE - -CD_READ: - LD C,A + EX AF,AF' + IN A,(SLOT3) + EX AF,AF' +;[]================================================================[#52] +;Function: Long Read Sectors +; A - Disk +; HL:IX - Sector +; DE - Address +; B - Sector counter +; A'- Memory Page Number +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) +;LONG READ SECTOR(S) +CD_5x.LONG_READ: + LD C,IDE.Device.CDROM + CALL SELECT_DRIVE + RET C + ; EXX LD C,SLOT3 IN A,(C) PUSH AF LD A,SYS_PAGE OUT (C),A - LD HL,CMDREAD + LD HL,ATAPI_CMD_PACKET.READ LD DE,RAM_ATAPI_READ LD BC,PKTSIZE LDIR @@ -101,59 +82,107 @@ CD_READ: LD A,H LD H,L LD L,A - LD (RAM_ATAPI_READ+SECREAD+0),HL + LD (RAM_ATAPI_READ + ATAPI_PACKET.SECTOR+0),HL ; LD A,XH - LD (RAM_ATAPI_READ+SECREAD+2),A ;R01 + LD (RAM_ATAPI_READ + ATAPI_PACKET.SECTOR+2),A ;R01 LD A,XL - LD (RAM_ATAPI_READ+SECREAD+3),A ;R01 + LD (RAM_ATAPI_READ + ATAPI_PACKET.SECTOR+3),A ;R01 LD A,B - LD (RAM_ATAPI_READ+COUNT+1),A ;R01 - POP AF + LD (RAM_ATAPI_READ + ATAPI_PACKET.COUNTER+1),A ;R01 + ; + EX AF,AF' OUT (SLOT3),A + ; + ; POP AF + ; OUT (SLOT3),A ;R01 LD HL,CMDREAD LD HL,RAM_ATAPI_READ - LD A,C CALL AP_COM + ; + POP BC + LD C,SLOT3 + OUT (C),B + ; RET +;[]===========================================================[#52, #55] + +;[]================================================================[#57] +;Function: Detect Disk +; A - Disk +;Return: CF=0 - A=Drive type +; CF=1 - drive not present, A=#02 +CD_5x.DETECT: + LD C,IDE.Device.CDROM + AND %1011'1111 + JP DRV_DETECT +;[]================================================================[#57] + + +;[]================================================================[#5E] +;Function: Extended +; A - Disk +; B - SubFunction +;Return: +; +CD_5x.Extended: + LD C,IDE.Device.CDROM + CALL SELECT_DRIVE + RET C + ; + LD A,B + CP 2 + JR C,TRAY_FN + ; ... + ; ... + LD A,#AA ;!HARDCODE error code + SCF + RET +;[]================================================================[#5E] + + +;----------------------------------------------------------------------; +TRAY_FN: + LD DE,0 ;!FIXIT нужно ли? + LD HL,ATAPI_CMD_PACKET.CLOSE + DEC A + JR Z,AP_COM + LD HL,ATAPI_CMD_PACKET.OPEN + JR AP_COM +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; ; INPUT: HL - AP paket (12bytes) ; RETURN: CF - ERROR -; 01h - RECOVERED ERROR -; 02h - NOT READY -; 03h - MEDIUM ERROR -; 04h - HARDWARE ERROR -; 05h - ILLEGAL REQUEST -; 06h - UNIT ATTETION -; 07h - DATA PROTECT -; 0Bh - ABORTED COMMAND -; 80h - TIME OUT -AP_COM: AND #01 - LD A,IDE.Drive.Master - JR Z,.APCOM1 - LD A,IDE.Drive.Slave -.APCOM1 LD BC,IDE.Write.DeviceHead - OUT (C),A ;SELECT DRIVE +; #01 - RECOVERED ERROR +; #02 - NOT READY +; #03 - MEDIUM ERROR +; #04 - HARDWARE ERROR +; #05 - ILLEGAL REQUEST +; #06 - UNIT ATTETION +; #07 - DATA PROTECT +; #0B - ABORTED COMMAND +; #80 - TIME OUT +AP_COM: EXX + LD DE,#8000 + CALL CD_WAITPRT EXX - LD DE,#8000 - ;LD BC,IDE.Read.Status - CALL CWAITPRT - EXX - JR NC,.CDREADY + JR NC,.READY LD BC,IDE.Write.Command - LD A,#08 + LD A,IDE.ATAPI.Reset OUT (C),A - LD B,#00 + LD B,#80 .pause: DJNZ .pause EXX - LD DE,#8000 - ;LD BC,IDE.Read.Status - CALL CWAITPRT + LD DE,#8000 + CALL CD_WAITPRT EXX RET C -.CDREADY: +.READY: LD C,SLOT3 IN B,(C) @@ -163,7 +192,7 @@ AP_COM: AND #01 LD A,SYS_PAGE OUT (C),A LD A,B - LD DE,RAM_ATAPI_PK + LD DE,RAM_ATAPI_PK ;!FIXIT может на стеке выделять место? LD BC,PKTSIZE LDIR @@ -173,32 +202,30 @@ AP_COM: AND #01 XOR A EXX - OUT (C),A - XOR A - LD BC,IDE.Write.Features - OUT (C),A - LD DE,SIZESEC ;SIZE BLOCK - LD BC,IDE.Write.CylinderLow - OUT (C),E - LD BC,IDE.Write.CylinderHigh - OUT (C),D - LD BC,IDE.Write.Command - LD A,IDE.ATAPI.Packet - OUT (C),A - LD DE,#8000 - ;LD BC,IDE.Read.Status - CALL CWAITPRT + ;OUT (C),A + ;XOR A + LD BC,IDE.Write.Features + OUT (C),A + LD DE,SIZESEC ;SIZE BLOCK ;!HARDCODE доставать из переменной какой-нибудь + LD BC,IDE.Write.CylinderLow + OUT (C),E + LD BC,IDE.Write.CylinderHigh + OUT (C),D + LD BC,IDE.Write.Command + LD A,IDE.ATAPI.Packet + OUT (C),A + LD DE,#8000 + CALL CD_WAITPRT EXX RET C EXX - LD DE,#0908 - ;LD BC,IDE.Read.Status - CALL CWAITPRT + LD DE,#0908 + CALL CD_WAITPRT EXX BIT IDE.ControlBit.Error,A JR NZ,.CDERROR JR NC,.YEP_DRQ - LD A,#80 + LD A,#80 ; TIME OUT ;!HARDCODE RET .YEP_DRQ: LD C,SLOT3 @@ -209,7 +236,6 @@ AP_COM: AND #01 LD HL,RAM_ATAPI_PK LD BC,IDE.Write.Data LD A,PKTSIZE/2 - ;SRL A .OUTPKT: OUTI OUTI @@ -224,9 +250,8 @@ AP_COM: AND #01 .AP_LOOP: EXX - LD DE,#8000 - ;LD BC,IDE.Read.Status - CALL CWAITPRT + LD DE,#8000 + CALL CD_WAITPRT EXX RET C LD BC,IDE.Read.Status @@ -245,7 +270,7 @@ AP_COM: AND #01 RET .NO_ERR: BIT IDE.ControlBit.DataRequest,A - LD A,0 + LD A,BIOS.Error.NoErrors RET Z ;NO DATA REQUEST EX DE,HL LD BC,IDE.Read.CylinderLow @@ -258,8 +283,8 @@ AP_COM: AND #01 LD BC,IDE.Read.Counter IN A,(C) AND #02 - CP #02 - JP Z,.FROM_CD + ;CP #02 + JP NZ,.FROM_CD ;.TO_CD: LD BC,IDE.Read.Data .WR_T_CD: @@ -298,26 +323,15 @@ AP_COM: AND #01 LD A,D OR E JR NZ,.RD_N_CD -; DE = 0 !!! + ; DE = 0 JR .AP_LOOP +;----------------------------------------------------------------------; - -; E - Second * 10 -; PAUSE LD HL,#0000 -; PAUSE1 DEC L -; JR NZ,PAUSE1 -; DEC H -; JR NZ,PAUSE1 -; DEC E -; JR NZ,PAUSE1 -; RET - - +;----------------------------------------------------------------------; ; D - MASK ; E - PATTERN - //; BC - PORT -CWAITPRT: +CD_WAITPRT: LD BC,IDE.Read.Status LD A,100 LD HL,#0000 @@ -344,32 +358,50 @@ CWAITPRT: .CWAITP1: SCF RET - -CMDNOPP DEFB #00 - DEFB 00,00,00 - DEFB #00 - DEFB 00,00,00 - DEFB 00,00,00 - DEFB #00 - -CMDOPEN DEFB #1B - DEFB #00,#00,#00 - DEFB #02 - DEFB #00,#00,#00,#00,#00,#00,#00 - -CMDCLOS DEFB #1B - DEFB #00,#00,#00 - DEFB #03 - DEFB #00,#00,#00,#00,#00,#00,#00 - -CMDREAD DEFB #28,#00 -SECREAD EQU $-CMDREAD - DEFB #00,#00,#00,#00 - DEFB #00 -COUNT EQU $-CMDREAD - DEFB #00,#01 - DEFB #00,#00,#00 - -;======================================================== +;----------------------------------------------------------------------; +;----------------------------------------------------------------------; +CD_TEST LD HL,ATAPI_CMD_PACKET.NOP + LD DE,0 ;!FIXIT нужно ли? + JP AP_COM +;----------------------------------------------------------------------; + + +//////////////////////////////////////////////////////////////////////// +ATAPI_CMD_PACKET: +.NOP: DUP 12 + DB #00 + EDUP +; +.OPEN: DB #1B + DB #00,#00,#00 + DB #02 + DB #00,#00,#00,#00,#00,#00,#00 +; +.CLOSE: DB #1B + DB #00,#00,#00 + DB #03 + DB #00,#00,#00,#00,#00,#00,#00 +; +.READ: DB #28,#00 + DB #00,#00,#00,#00 ; sector dword + DB #00 + DB #00,#01,#00,#00 ; counter dword + DB #00 +; +ATAPI_PACKET: +.SECTOR EQU 2 +.COUNTER EQU 7 +//////////////////////////////////////////////////////////////////////// +; +; E - Second * 10 +; PAUSE LD HL,#0000 +; PAUSE1 DEC L +; JR NZ,PAUSE1 +; DEC H +; JR NZ,PAUSE1 +; DEC E +; JR NZ,PAUSE1 +; RET +; \ No newline at end of file diff --git a/src/bios/exp/EXTENDED/IDE/HDD_DRV.ASM b/src/bios/exp/EXTENDED/IDE/HDD_DRV.ASM index cda8e56..f175b01 100644 --- a/src/bios/exp/EXTENDED/IDE/HDD_DRV.ASM +++ b/src/bios/exp/EXTENDED/IDE/HDD_DRV.ASM @@ -89,47 +89,6 @@ HDD_5x.RESET: ; !FIXIT RET ;[]================================================================[#51] -SELECTH: - AND #0F - LD IY,IDE.INIT_TBL_IDE0 - JR Z,SELHH - DEC A - LD IY,IDE.INIT_TBL_IDE1 - ;R02 - JR Z,SELHH - DEC A - LD IY,IDE.INIT_TBL_IDE2 - JR Z,SELHH - DEC A - LD IY,IDE.INIT_TBL_IDE3 - ; - JR NZ,NODRIVE -SELHH: EXX - LD C,SLOT3 - IN B,(C) - LD A,SYS_PAGE - OUT (C),A - - LD A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) - AND #01 - LD A,IDE.Chanel.Secondary - JR NZ,SELCHAN - LD A,IDE.Chanel.Primary -SELCHAN: - OUT (IDE.Chanel.Set),A ;R02 - LD A,(IY+IDE.HDD_INIT_TABLE.DriveType) - CP IDE.Device.HDD ;!FIXIT возможно, нахрен не нужно, потому-что если CD, то прилетит в драйвер CD - LD A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) - OUT (C),B ;возврат страницы - LD BC,IDE.Write.DeviceHead - RES 0,A - OUT (C),A - EXX - RET Z -NODRIVE: - LD A,BIOS.Error.BadDrvNumber - SCF - RET ;[]================================================================[#58] ;Function: Get Current Media Parameters @@ -141,7 +100,8 @@ NODRIVE: ; IX - Capacity sector in bytes ; B - Flags: MASTER/SLAVE, LBA/CHS HDD_5x.GETMED: - CALL SELECTH + LD C,IDE.Device.HDD + CALL SELECT_DRIVE RET C IN A,(SLOT3) EX AF,AF' @@ -170,7 +130,8 @@ HDD_5x.GETMED: ; B - Flags ;Return: None HDD_5x.SETMED: - CALL SELECTH + LD C,IDE.Device.HDD + CALL SELECT_DRIVE RET C IN A,(SLOT3) EX AF,AF' @@ -208,7 +169,7 @@ HDD_5x.READ: ; HL:IX - Sector ; DE - Address ; B - Sector counter -; A'- Memory ID Block +; A'- Memory Page Number ;Return: ; HL:IX - Sector + Sector counter ; DE - Address + (Sector counter * Size sector) @@ -273,7 +234,9 @@ RST8RDR: RESTORE_PORTY ;EX AF,AF' ;!TEST 21/11/23 RET ;READ SECTOR(S) -RDS000: CALL SELECTH +RDS000: + LD C,IDE.Device.HDD + CALL SELECT_DRIVE RET C EXX LD DE,#C140 ;WAIT BUSY=0 & READY=1 & ERR=0 @@ -333,6 +296,7 @@ RDS004: DUP 16 LD XH,A EX AF,AF' OUT (SLOT3),A + ; .W44: INC XL ;INC LOADED SECTORS EXX LD DE,#C140 ;WAIT BUSY=0 & ERR=0 & READY=1 @@ -369,7 +333,7 @@ HDD_5x.WRITE: ; HL:IX - Sector ; DE - Address ; B - Sector counter -; A'- Memory ID Block +; A'- Memory Page Number ;Return: ; HL:IX - Sector + Sector counter ; DE - Address + (Sector counter * Size sector) @@ -436,7 +400,8 @@ RST8WRR: RESTORE_PORTY ;WRITE SECTOR(S) WRS000: - CALL SELECTH + LD C,IDE.Device.HDD + CALL SELECT_DRIVE RET C EXX LD DE,#C140 ;WAIT BUSY=0 & READY=1 & ERR=0 @@ -550,7 +515,9 @@ HDD_5x.VERIFY: RET ;[]================================================================[#54] ;VERIFY SECTOR(S) -VRS000: CALL SELECTH +VRS000: + LD C,IDE.Device.HDD + CALL SELECT_DRIVE RET C EXX LD DE,#C140 ;WAIT BUSY=0 & READY=1 & ERR=0 @@ -665,9 +632,9 @@ CHS005: INC A LD L,A RET +;----------------------------------------------------------------------; ; D - MASK ; E - PATTERN - //; BC - PORT WAITPRT: LD BC,IDE.Read.Status LD HL,#0000 ; задержка ;!HARDCODE @@ -690,42 +657,46 @@ WAITPRT: RET .ok: POP HL RET +;----------------------------------------------------------------------; -;======================================================================= ;[]================================================================[#57] +;[ ] 18/12/2023. добавление/допиливание API CD-ROM (ATAPI) ;Function: Detect Disk ; A - Disk ;Return: CF=0 - A=Drive type -; CF=1 - drive not present, A=#FF +; CF=1 - drive not present, A=#02 HDD_5x.DETECT: - CP #84 ;!HARDCODE max HDD drives (#80,#81,#82,#83) - CCF - JR C,.error + LD C,IDE.Device.HDD + JP DRV_DETECT - LD HL,IDE.INIT_TBL_IDE0.DriveType - AND 3 - JR Z,.get_param - LD HL,IDE.INIT_TBL_IDE1.DriveType - DEC A - JR Z,.get_param - LD HL,IDE.INIT_TBL_IDE2.DriveType - DEC A - JR Z,.get_param - LD HL,IDE.INIT_TBL_IDE3.DriveType -.get_param: - IN A,(SLOT3) - LD B,A - LD A,SYS_PAGE - OUT (SLOT3),A +; CP #84 ;!HARDCODE max IDE drives (#80,#81,#82,#83) +; CCF +; JR C,.error + +; LD HL,IDE.INIT_TBL_IDE0.DriveType +; AND 3 +; JR Z,.get_param +; LD HL,IDE.INIT_TBL_IDE1.DriveType +; DEC A +; JR Z,.get_param +; LD HL,IDE.INIT_TBL_IDE2.DriveType +; DEC A +; JR Z,.get_param +; LD HL,IDE.INIT_TBL_IDE3.DriveType +; .get_param: +; IN A,(SLOT3) +; LD B,A +; LD A,SYS_PAGE +; OUT (SLOT3),A - LD A,(HL) - LD C,SLOT3 - OUT (C),B +; LD A,(HL) +; LD C,SLOT3 +; OUT (C),B - CP IDE.Device.HDD - RET Z - SCF -.error: LD A,BIOS.Error.BadDrvNumber - RET +; CP IDE.Device.HDD +; RET Z +; SCF +; .error: LD A,BIOS.Error.BadDrvNumber +; RET ;[]================================================================[#57] \ No newline at end of file diff --git a/src/bios/exp/EXTENDED/IDE/shared.asm b/src/bios/exp/EXTENDED/IDE/shared.asm new file mode 100644 index 0000000..5cbcabc --- /dev/null +++ b/src/bios/exp/EXTENDED/IDE/shared.asm @@ -0,0 +1,100 @@ +;[ ] 18/12/2023. добавление/допиливание API CD-ROM (ATAPI) + +;======================================================================= +; Вход: A - номер устройства +; C - Тип +SELECT_DRIVE: + AND #0F + LD IY,IDE.INIT_TBL_IDE0 + JR Z,.channel + DEC A + LD IY,IDE.INIT_TBL_IDE1 + ;R02 + JR Z,.channel + DEC A + LD IY,IDE.INIT_TBL_IDE2 + JR Z,.channel + DEC A + LD IY,IDE.INIT_TBL_IDE3 + ; + JR Z,.channel + LD A,BIOS.Error.BadDrvNumber + SCF + RET + ; +.channel: + EXX + IN A,(SLOT3) + PUSH AF + LD A,SYS_PAGE + OUT (SLOT3),A + ; + LD A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) + AND 1 + LD A,IDE.Chanel.Secondary + JR NZ,.device + LD A,IDE.Chanel.Primary +.device: + OUT (IDE.Chanel.Set),A ;R02 + LD C,(IY+IDE.HDD_INIT_TABLE.DriveType) + LD B,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) + POP AF + OUT (SLOT3),A ;возврат страницы + ; + LD A,C + EXX + CP C + EXX + SCF + LD A,BIOS.Error.BadDrvNumber + RET NZ + ; + LD A,B + AND #F0 + LD BC,IDE.Write.DeviceHead + OUT (C),A + EXX + RET + ; +; NODRIVE: +; LD A,BIOS.Error.BadDrvNumber +; SCF +; RET +;======================================================================= + + +;======================================================================= +;Function: Detect Disk +; A - Disk +; С - Type +;Return: CF=0 - A=Drive type +; CF=1 - drive not present, A=#02 +DRV_DETECT: + CP #84 ;!HARDCODE max IDE drives (#80,#81,#82,#83) + CCF + JR C,.error + + LD HL,IDE.INIT_TBL_IDE0.DriveType + AND 3 + JR Z,.get_param + LD HL,IDE.INIT_TBL_IDE1.DriveType + DEC A + JR Z,.get_param + LD HL,IDE.INIT_TBL_IDE2.DriveType + DEC A + JR Z,.get_param + LD HL,IDE.INIT_TBL_IDE3.DriveType +.get_param: + IN A,(SLOT3) + LD B,A + LD A,SYS_PAGE + OUT (SLOT3),A + + LD A,(HL) + CP C ; compare Type + LD C,SLOT3 + OUT (C),B + RET Z + SCF +.error: LD A,BIOS.Error.BadDrvNumber + RET \ No newline at end of file diff --git a/src/bios/exp/FUNC_5x.asm b/src/bios/exp/FUNC_5x.asm index 5f0a03d..679eb90 100644 --- a/src/bios/exp/FUNC_5x.asm +++ b/src/bios/exp/FUNC_5x.asm @@ -119,8 +119,9 @@ DRV_LIST: ; ????? INCLUDE 'EXTENDED/FDD_DRIVER_2.asm' INCLUDE 'EXTENDED/RAM_DISK_DRIVER_1.asm' - INCLUDE 'EXTENDED/HDD_DRIVER_6.asm' - INCLUDE 'EXTENDED/CD_DRIVER_0.asm' + INCLUDE 'EXTENDED/IDE/HDD_DRV.asm' + INCLUDE 'EXTENDED/IDE/CD_DRV.asm' + INCLUDE 'EXTENDED/IDE/SHARED.asm' ;DISPLAY " EXTENDED end addr: ", /A, $ diff --git a/src/bios/rom/SETUP/AUTOIDE.asm b/src/bios/rom/SETUP/AUTOIDE.asm index c34b87f..ff58d5f 100644 --- a/src/bios/rom/SETUP/AUTOIDE.asm +++ b/src/bios/rom/SETUP/AUTOIDE.asm @@ -4,7 +4,7 @@ ;----------------------------------------------------------------------- ;Rev Date Name Description ;----------------------------------------------------------------------- -;R02 17.08.2023 BAO Fixed bug with AUTODETECT ATAPI Drives +;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 @@ -169,7 +169,7 @@ START: CALL SetUP_CHANELS LD A,#03 CALL STEP1_GETCMOS - ;!TEST save hdd parameters to cmos for "setup" in settings + ;[x] save hdd parameters to cmos for "setup" in settings CALL WRITING ; CALL ScreenPOS.CRLF diff --git a/src/bios/rom/SETUP/MAIN.asm b/src/bios/rom/SETUP/MAIN.asm index 16fd523..725e2ac 100644 --- a/src/bios/rom/SETUP/MAIN.asm +++ b/src/bios/rom/SETUP/MAIN.asm @@ -884,6 +884,7 @@ RECOVERYstart: PrepareToBOOT: + CALL INT_ON HALT ; без него не срабатывает зажимание шифта при старте доса для отмены старта system.exe CALL INT_OFF CALL PORTS_INIT.clean_kbd_buf ;Clearing the keyboard buffer @@ -937,7 +938,7 @@ CDSTART: POP AF PUSH AF CALL PRINT_CHANEL - + ; POP BC SET 6,B SCF diff --git a/src/bios/shared/RECOVERY.IMG b/src/bios/shared/RECOVERY.IMG index 69bed98a2b44bf4f37788c3a8fafc1af497fc88e..1ecf1190c72757b15eaafe661448624c99dd0c18 100755 GIT binary patch delta 7639 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 W>cgErr9|4bn?VmFF(=uGl>ZAAX>VZw delta 8099 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