Commit 664368e8 authored by Kevin Bracey's avatar Kevin Bracey
Browse files

* DMA support completed.

* Selects PIO/DMA/Ultra DMA modes appropriate for each device.
* DMA support added to ADFS_IDEUserOp, but not yet ADFS_ATAPIOp.
* WinIDEMaxSectorsPerTransfer increased to 256.
* Floppy driver reattaches to DMA Manager if it's reinitialised.

Version 3.35. Tagged as 'ADFS-3_35'
parent fe5706c2
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "3.34"
Module_Version SETA 334
Module_MajorVersion SETS "3.35"
Module_Version SETA 335
Module_MinorVersion SETS ""
Module_Date SETS "28 Jan 2003"
Module_ApplicationDate SETS "28-Jan-03"
Module_Date SETS "03 Apr 2003"
Module_ApplicationDate SETS "03-Apr-03"
Module_ComponentName SETS "ADFS"
Module_ComponentPath SETS "RiscOS/Sources/FileSys/ADFS/ADFS"
Module_FullVersion SETS "3.34"
Module_HelpVersion SETS "3.34 (28 Jan 2003)"
Module_FullVersion SETS "3.35"
Module_HelpVersion SETS "3.35 (03 Apr 2003)"
END
/* (3.34)
/* (3.35)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.68.
*
*/
#define Module_MajorVersion_CMHG 3.34
#define Module_MajorVersion_CMHG 3.35
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 28 Jan 2003
#define Module_Date_CMHG 03 Apr 2003
#define Module_MajorVersion "3.34"
#define Module_Version 334
#define Module_MajorVersion "3.35"
#define Module_Version 335
#define Module_MinorVersion ""
#define Module_Date "28 Jan 2003"
#define Module_Date "03 Apr 2003"
#define Module_ApplicationDate "28-Jan-03"
#define Module_ApplicationDate "03-Apr-03"
#define Module_ComponentName "ADFS"
#define Module_ComponentPath "RiscOS/Sources/FileSys/ADFS/ADFS"
#define Module_FullVersion "3.34"
#define Module_HelpVersion "3.34 (28 Jan 2003)"
#define Module_LibraryVersionInfo "3:34"
#define Module_FullVersion "3.35"
#define Module_HelpVersion "3.35 (03 Apr 2003)"
#define Module_LibraryVersionInfo "3:35"
......@@ -208,7 +208,7 @@ ATAPIOp_EntryR1 * 4
MOVEQ R0,#IDEDrvHeadMagicBits+0:SHL:IDEDriveShift
MOVNE R0,#IDEDrvHeadMagicBits+1:SHL:IDEDriveShift
STRB R0,WinIDEParmDrvHead
MOV R0,#IDECmdPacket:OR:bit8
MOV R0,#IDECmdPacket:OR:(WinIDECmdFlag_NoDRDY:SHL:8)
STRB R0,WinIDECommandCode ; so transfer routines know
BL WinIDECommandDisc ; (R0->R0,V)
BVS %FT70
......
......@@ -291,6 +291,23 @@ Divide ROUT
Pull "R2,PC"
; =============
; StringCompare
; =============
; entry: R0->string,R1->string
; exit: EQ or NE
StringCompare ROUT
Push "R2,LR"
01 LDRB R2,[R0],#1
LDRB LR,[R1],#1
TEQ R2,LR
BNE %FT02
TEQ R2,#0
BNE %BT01
02
Pull "R2,PC"
; =========
; BlockMove
......
......@@ -190,6 +190,18 @@ WinInit ROUT
STR R0,WinIDECommandActive
[ IDEDMA
; Zero out our sector-padding data
sbaddr LR,WinIDEDMAZeroes
MOV R1,#?WinIDEDMAZeroes
01 STR R0,[LR],#4
SUBS R1,R1,#4
BNE %BT01
STR R0,WinIDECopiedScatterList
STR R0,WinIDECopiedScatterSize
]
; Flag both IDE drives not initialised
; R0 = 0
......@@ -312,6 +324,16 @@ WinInit ROUT
BLNE WinClaimIDEIRQs
BVS %FT80
Push "R1-R5"
ADDR R0, WinIDEDMAEnable
ADDR R1, WinIDEDMADisable
ADDR R2, WinIDEDMAStart
ADDR R3, WinIDEDMACompleted
ADDR R4, WinIDEDMASync
ADR R5, WinIDEDMAHandlers
STMIA R5, {R0-R4}
Pull "R1-R5"
MOV R0,#0 ; -SRST IEN
STRB R0,[R4,#:INDEX:IDERegDevCtrl]
......@@ -322,6 +344,7 @@ WinInit ROUT
MOVEQ R0,#1
SWIEQ XDMA_AllocateLogicalChannels
MOV R3,R0
STR R3,[R9,#WinIDEDMALC]
Pull "R0-R2" ; R5 already set up
ADD SP,SP,#4
LDR R6,WinIDEDMADeviceHandle
......@@ -386,6 +409,7 @@ WinInit ROUT
MOVEQ R0,#1
SWIEQ XDMA_AllocateLogicalChannels
MOV R3,R0
STR R3,[R9,#WinIDEDMALC]
Pull "R0-R2" ; R5 already set up
ADD SP,SP,#4
LDR R6,WinIDEDMADeviceHandle
......@@ -396,6 +420,13 @@ WinInit ROUT
[ IDEDMA
TEQ R6,#0
BLNE RegisterBusMaster
ADR R9,WinIDEHardware
BL WinIDERegisterDMAChannel
[ TwinIDEHardware
ADR R9,WinIDEHardware + SzWinIDEHardware
BL WinIDERegisterDMAChannel
]
]
[ :LNOT:AutoDetectIDE
......@@ -749,18 +780,32 @@ WinDie ROUT
sbaddr R9,WinIDEHardware
BL WinReleaseIDEIRQs ; (R9->R0,V)
[ IDEDMA
BL WinIDEDeregisterDMAChannel
]
[ TwinIDEHardware
ADD R9,R9,#SzWinIDEHardware
BL WinReleaseIDEIRQs ; (R9->R0,V)
[ IDEDMA
BL WinIDEDeregisterDMAChannel
]
]
[ IDEDMA
Push "R2,R6"
; deregister DMA devices (if registered)
Push "R6"
LDR R6,WinIDEDMADeviceHandle
TEQ R6,#0
BLNE DeleteBusMaster
Pull "R6"
; free up our copied scatter list
MOV R0,#ModHandReason_Free
LDR R2,WinIDECopiedScatterList
TEQ R2,#0
SWINE XOS_Module
Pull "R2,R6"
]
; release TickerV (if owned)
......@@ -850,6 +895,11 @@ WinReset ROUT
BL WinReleaseIDEIRQs ; (R9->R0,V)
BL WinClaimIDEIRQs ; (R9->R0,V)
[ IDEDMA
BL WinIDEDeregisterDMAChannel
BL WinIDERegisterDMAChannel
]
30
[ TwinIDEHardware
ADD R9,R9,#SzWinIDEHardware
......@@ -861,6 +911,11 @@ WinReset ROUT
BL WinReleaseIDEIRQs ; (R9->R0,V)
BL WinClaimIDEIRQs ; (R9->R0,V)
[ IDEDMA
BL WinIDEDeregisterDMAChannel
BL WinIDERegisterDMAChannel
]
]
Pull "R0,R9,PC" ; Return to caller
......
......@@ -550,7 +550,7 @@ DoSwiWinPowerControl ROUT
;*********************************************************************
GBLL UserOpDMA
UserOpDMA SETL {FALSE}
UserOpDMA SETL {TRUE} :LAND: IDEDMA
DoSwiIDEUserOp ROUT
;
......@@ -757,23 +757,24 @@ DoSwiIDEUserOp ROUT
STRB R0,WinIDEParmDrvHead
LDRB R0,[LR],#1 ; get command reg value
ORRNE R0,R0,#bit9 ; pass through "48-bit" flag
ASSERT WinIDECmdFlag_48bit = bit0
MOV LR,R0,LSR #9
STRB LR,WinIDECommandFlags
ORRNE R0,R0,#WinIDECmdFlag_48bit :SHL:8
; Start the command
TSTS R7,#bit1 ; pass through "ignore DRDY" flag
ORRNE R0,R0,#bit8
ORRNE R0,R0,#WinIDECmdFlag_NoDRDY:SHL:8
MOV LR,R0,LSR #8
STRB LR,WinIDECommandFlags
STRB R0,WinIDECommandCode
BL WinIDECommandDisc ; (R0->R0,V)
BVS %FT70
[ UserOpDMA
TSTS R7,#bit26 ; DMA command?
BNE %FT40
]
BL WinIDECommandDisc ; (R0->R0,V)
BVS %FT70
; Allow time for drive to go busy (upto 400ns according to CAM 2.1).
07 MOV R0,#1*2 ; 1/2 us units
......@@ -891,31 +892,69 @@ DoSwiIDEUserOp ROUT
[ UserOpDMA
40
; DMA command - we always get an interrupt on completion/error,
; so program up the DMA channel and wait for an interrupt.
; DMA command - we just program up the transfer, and it's the DMA manager's
; job, together with our callbacks (in Adfs14), to tell us when it's finished.
TST R7,#bit24
MOVNE R0,#0
MOVEQ R0,#1
LDR R1, WinIDEDMAHandle
SWI XDMA_QueueTransfer
ORR LR,LR,#WinIDECmdFlag_DMA
STRB LR,WinIDECommandFlags
STR R5,WinTickCount
MOV LR,#0
STRB LR,WinIDECommandCode_PIO ; no PIO fallback
41 BL WinIDECheckIRQStatus
BNE %FT42
TST R7,#bit24 ; read or write (Z flag also used
MOVNE R0,#0 ; below)
MOVEQ R0,#1
sbaddr LR,WinIDEFakeScatterList ; turn it into a scatter list
STMIA LR!,{R3,R4}
MOV R7,#WinIDEBytesPerSector ; add in padding to make it a multiple
SUB R7,R7,#1 ; of the sector size
MOV R3,R4
ADD R4,R4,R7 ; R4 = length rounded up to
BIC R4,R4,R7 ; a sector
SUB R7,R4,R3 ; R7 = amount of padding
sbaddr R3,WinIDEDMASink,NE ; excess reads -> sink
sbaddr R3,WinIDEDMAZeroes,EQ ; excess writes as 0
STMIA LR,{R3,R7}
SUB R3,LR,#8 ; R3 -> scatter, R4 = rounded length
BL WinIDEQueueTransfer ; DMA handlers will issue
BVS %FT48 ; actual ATA command
41 LDRB LR,WinIDEDMAStatus
TST LR,#DMAStat_Completed
BNE %FT45
BL WinIDEExamineTransfer ; We need to "prod" the DMA manager
BVS %FT48 ; like this, as the bus master
; has no interrupts of its own.
LDR R7,WinTickCount
TEQS R7,#0
BNE %BT41
MOV R0,#WinIDEErrTimeout
B %FT70
42 LDRB R0,IDERegStatus
TSTS R0,#IDEStatusErrorBits
BEQ %FT43
BL WinIDEDecodeDriveStatus
B %FT70
MOV R0,#WinIDEErrTimeout
BL WinIDETerminateTransfer ; this will cause "Completed" status
B %BT41
45 LDR R0,WinIDEDMAResult
48 TEQ R0, #0 ; R0 = error from DMA routine
BEQ %FT49 ; if 0, check drive status
CMP R0, #256 ; if <256, it's already a status
BLO %FT70
LDR LR, [R0] ; else if error = "Device error"
LDR R7, =&C36
TEQ LR, R7
BEQ %FT49 ; then check drive status
B %FT88 ; else return the error
49
LDRB R0,IDERegStatus
ANDS R0,R0,#IDEStatusErrorBits
BLNE WinIDEDecodeDriveStatus ; if error, decode status...
B %FT70 ; ...and branch
]
......@@ -997,6 +1036,10 @@ DoSwiIDEUserOp ROUT
;****** Never fall through
88
; other error (controller is locked)
BL UnlockIDEController
B %FT98
82
; bad parameter block or buffer address (controller is locked)
......@@ -1006,6 +1049,7 @@ DoSwiIDEUserOp ROUT
; call international stuff to make R0 -> international error block
BL copy_error ; (R0->R0)
98
Pull "LR"
ORR LR,LR,#V_bit
RestPSR LR,,cf
......@@ -1015,6 +1059,8 @@ DoSwiIDEUserOp ROUT
Pull "R1,R6,R7,R9,IDE,PC"
]
LTORG
;*********************************************************************
[ AutoDetectIDE
......@@ -1408,7 +1454,7 @@ WinIDEAdjustStatus ROUT
RSBHIS R5,R0,#MaxDiscErr+1 ; if yes, is it a disc error ?
BLS %FT01
[ NewErrors
Push "R1,R3,R4"
Push "R1-R4"
MOV R1,R0,LSL #8
ORR R1,R1,R2,LSR #(32-3)
BIC R2,R2,#DiscBits
......@@ -1418,7 +1464,7 @@ WinIDEAdjustStatus ROUT
ADR R0,WinIDEErrorNo
STMIA R0,{R1,R2,R3}
ORR R0,R0,#NewDiscErrorBit
Pull "R1,R3,R4"
Pull "R1-R4"
|
Push "R1"
MOV R1, R0
......@@ -1644,7 +1690,7 @@ WinIDEOpVerify ROUT
MOV R0,#IDECmdVerify
]
[ BigDisc
ORR R0,R0,#IDECmdVerifyExt:SHL:8
ORR R0,R0,#IDECmdVerifyExt:SHL:16
]
BL WinIDEReadWriteSecs ; (R0-R4->R0,R2-R5,V)
......@@ -1895,10 +1941,7 @@ WinIDEOpWriteSecs ROUT
; R5 undefined
; All other registers preserved
MOV R0,#IDECmdWriteSecs
[ BigDisc
ORR R0,R0,#IDECmdWriteSecsExt:SHL:8
]
LDR R0,WinIDEWriteCmds
B WinIDEReadWriteSecs ; (R0-R4->R0,R2-R5,V)
;*********************************************************************
......@@ -1945,10 +1988,7 @@ WinIDEOpReadSecs ROUT
; R5 undefined
; All other registers preserved
MOV R0,#IDECmdReadSecs
[ BigDisc
ORR R0,R0,#IDECmdReadSecsExt:SHL:8
]
LDR R0,WinIDEReadCmds
ASSERT . = WinIDEReadWriteSecs
;****** Fall through to WinIDEReadWriteSecs
......@@ -1963,9 +2003,9 @@ WinIDEReadWriteSecs ROUT
;
; Entry:
; R0 = IDE command code for the op.
[ BigDisc
; bits 8..15 = 48-bit addressing code (0 if none)
]
; bits 8..15 = DMA code (0 if none)
; bits 15..23 = 48-bit addressing code (0 if none)
; bits 24..31 = 48-bit DMA code (0 if none)
; R1 = b0-3: reason code
; 0= verify, 1= read, 2= write sectors
; 3= verify track, 4= format track,
......@@ -2010,13 +2050,28 @@ WinIDEReadWriteSecs ROUT
BLO %FT05
; If end address is >= &10000000 then switch to a 48-bit command
MOV LR,#WinIDECmdFlag_48bit
MOVS R0,R0,LSR #8
MOVS R0,R0,LSR #16
BNE %FT05
; no 48-bit form? Then can't do command.
MOV R0,#BadParmsErr
SETV
Pull "PC"
05
]
[ IDEDMA
TST R0,#&FF:SHL:8 ; if the command has a DMA form
BEQ %FT08
LDRB R5,WinIDEDriveNum
Push "R1"
sbaddr R1,WinIDEDriveDMAFlags ; and DMA is enabled for this drive
LDRB R5,[R1,R5]
Pull "R1"
TEQ R5,#0
BEQ %FT08
ORR LR,LR,#WinIDECmdFlag_DMA ; then use the DMA form (with a
STRB R0,WinIDECommandCode_PIO ; PIO fallback)
MOV R0,R0,LSR #8
08
]
STRB R0,WinIDECommandCode
STRB LR,WinIDECommandFlags
......@@ -2082,4 +2137,9 @@ WinIDEReadWriteSecs ROUT
;*********************************************************************
WinIDEReadCmds
= IDECmdReadSecs, IDECmdReadDMA, IDECmdReadSecsExt, IDECmdReadDMAExt
WinIDEWriteCmds
= IDECmdWriteSecs,IDECmdWriteDMA,IDECmdWriteSecsExt,IDECmdWriteDMAExt
END
This diff is collapsed.
......@@ -732,8 +732,6 @@ FlpReset1772
Pull "R0-R2,PC" ; Return to caller
]
LTORG
[ FloppyPCI
;-----------------------------------------------------------------------;
......@@ -755,7 +753,7 @@ FlpReset1772
FlpRegisterDMAChannel
Push "LR"
MOV R0, #0
LDR R1, =&101
LDR R1, =DMALC_Floppy
MOV R2, #0
MOV R3, #1
ADR R4, FlpDMAHandlers
......@@ -768,6 +766,8 @@ FlpRegisterDMAChannel
Pull "PC"
]
LTORG
;-----------------------------------------------------------------------;
; FlpBuildDCB ;
......
......@@ -506,6 +506,9 @@ ServiceTable
& Service_Portable
[ FloppyPCI :LOR: IDEDMA
& Service_ModulePostInit
]
[ IDEDMA
& Service_ModulePostFinal
]
& Service_ADFSPoduleIDEDying
& 0
......@@ -526,6 +529,9 @@ ServiceEntry ROUT
TEQNES R1,#Service_Portable ; Portable service?
[ FloppyPCI :LOR: IDEDMA
TEQNES R1,#Service_ModulePostInit ; DMA manager starting?
]
[ IDEDMA
TEQNES R1,#Service_ModulePostFinal
]
LDRNE LR,=Service_ADFSPoduleIDEDying ; IDE podule dying?
TEQNES R1,LR
......@@ -548,6 +554,11 @@ ServiceEntry3
BEQ ServiceModulePostInit ; Yes then jump
]
[ IDEDMA
TEQS R1,#Service_ModulePostFinal ; Module dead?
BEQ ServiceModulePostFinal ; Yes then jump
]
TEQS R1,#Service_Reset ; reset?
Pull "LR",NE ; else IDEPoduleDying
BNE WinIDEPoduleDying
......@@ -562,26 +573,45 @@ ServiceEntry3
; Direct-call re-registration
;
ServiceModulePostInit ROUT
Push "R0-R5"
Push "R0-R5,R9"
ADR R0,DMAManagerTitle
01 LDRB R1,[R0],#1
LDRB LR,[R2],#1
TEQ R1,#0
TEQEQ LR,#0
BEQ %FT02 ; String match
TEQ R1,LR
BEQ %BT01
Pull "R0-R5,PC" ; Not a match
02
[ FloppyPCI
MOV R1,R2
BL StringCompare
Pull "R0-R5,R9,PC",NE
[ FloppyPCI
BL FlpRegisterDMAChannel
]
[ IDEDMA
sbaddr R9,WinIDEHardware
BL WinIDERegisterDMAChannel
[ TwinIDEHardware
ADD R9,R9,#SzWinIDEHardware
BL WinIDERegisterDMAChannel
]
Pull "R0-R5,PC"
]
Pull "R0-R5,R9,PC"
DMAManagerTitle = "DMAManager", 0
ALIGN
]
[ IDEDMA
ServiceModulePostFinal ROUT
Push "R0-R5,R9"
ADR R0,DMAManagerTitle
MOV R1,R2
BL StringCompare
Pull "R0-R5,R9,PC",NE
sbaddr R9,WinIDEHardware
MOV R0,#-1
STR R0,[R9,#WinIDEDMAHandle]
[ TwinIDEHardware
STR R0,[R9,#SzWinIDEHardware+WinIDEDMAHandle]
]
Pull "R0-R5,R9,PC"
]
; Portable power control
;
[ IDEPower
......@@ -2058,4 +2088,29 @@ ConfigReturn
STRVS R0, [SP]
Pull "R0-R6,SB,PC"
; C-compatible memcpy. R2-R3 corrupted, all other regs preserved.
memcpy
ADD R0,R0,R2
ADD R1,R1,R2
ORR R3,R0,R1
ORR R3,R3,R2
TST R3,#3
BEQ %FT10
01 SUBS R2,R2,#1
LDRCSB R3,[R1,#-1]!
STRCSB R3,[R0,#-1]!
BCS %BT01
MOV PC,LR
; Same again, but word-aligned
_memcpy
ADD R0,R0,R2
ADD R1,R1,R2
10 SUBS R2,R2,#4
LDRCS R3,[R1,#-4]!
STRCS R3,[R0,#-4]!
BCS %BT10
MOV PC,LR
END
......@@ -50,6 +50,15 @@ BMStatus_Active * 1:SHL:0
BMPRDTab_EOT * 1:SHL:31
GBLL ReportDeviceErrors
ReportDeviceErrors SETL {FALSE}
GBLL RandomErrors
RandomErrors SETL {FALSE}
[ RandomErrors
RandomErrorCounter DCD 0
]
CreateBusMaster
;
......@@ -324,11 +333,15 @@ Channel_Deactivate
TST a4, #BMStatus_Error :OR: BMStatus_Active
LDREQ a2, Chan_ProgLength
STREQ a2, Chan_DoneLength
[ ReportDeviceErrors
ASSERT BMStatus_Interrupt :SHR: 2 = BMStatus_Active
EOR a2, a4, a4, LSR #2
TST a2, #BMStatus_Active ; If these bits were set the same
MOVNE a2, #0 ; then we have a device error
MOVEQ a2, #DMAListTransferStatusFlag_DeviceError
|
MOV a2, #0
]
TST a4, #BMStatus_Error ; This bit set means a memory error
MOVNE a2, #DMAListTransferStatusFlag_MemoryError ; and overrides other bits
STRB a2, Chan_ErrorFlags ; Remember error state
......@@ -367,11 +380,15 @@ Channel_Abort
TST a4, #BMStatus_Error :OR: BMStatus_Active
LDREQ a2, Chan_ProgLength
STREQ a2, Chan_DoneLength ; If finished then mark as all done
[ ReportDeviceErrors