Changes

SYMBiFACE II:IDE routines

4,424 bytes added, 00:02, 26 August 2006
These are the core [[SYMBiFACE II]] IDE low level routines of [[SymbOS]]. They show how to read and write sectors from/to an IDE device.

<pre>
;==============================================================================
;### IDE-HARDDISC-ROUTINES ####################################################
;==============================================================================

ideprtsta equ #fd0f ;Portaddress + #f (Status/Command)
ideprtsdh equ #fd0e ;Portaddress + #e (SDH)
ideprtdat equ #fd08 ;Portaddress + #8 (Data)
ideprterr equ #fd09 ;Portaddress + #9 (Error)
ideprtdig equ #fd06 ;Portaddress + #6 (Digital-Output)

;### IDEADR -> set address
;### Eingabe HL=Track, E=Sector, D=SDH (head, drive, mode), B=number of sectors
;### Ausgabe CF=0 -> ok
;### CF=1 -> A=error code (...)
;### Verändert AF,BC
ideadr call ideadr0
ret c
dec c
out (c),h ;Track High
dec c
out (c),l ;Track Low
dec c
out (c),e ;Sector
dec c
out (c),a ;number of Sectors
ret
ideadr0 call iderdy
ret c
push bc
ld bc,ideprtsdh
out (c),d ;write SDH-Register
call iderdy
jr c,ideadr1
pop af ;A=number of sectors
or a
ret
ideadr1 pop bc
ret

;### IDECMD -> Send command
;### Eingabe A=Command
;### Verändert BC
idecmd ld bc,ideprtsta
out (c),a
ret

;### IDERDY -> Wait, until IDE-drive is ready for command
;### Output CF=0 -> ok, CF=1 -> error (A=code)
;### Verändert AF
iderdy push bc
push hl
ld bc,ideprtsta
ld hl,256*60
iderdy1 in a,(c)
and #80
jr z,iderdy2
dec l
jr nz,iderdy1
call subslp
dec h
jr nz,iderdy1
iderdy3 ld a,stoerrabo
scf
iderdy2 pop hl
pop bc
ret

;### IDEDRQ -> wait for "Data Request"
;### Output BC=Portnumber of the Status Register
;### Verändert AF
idedrq ld bc,ideprtsta
idedrq1 in a,(c)
and #08
jr z,idedrq1
ret

;### IDERED -> read 512Bytes
;### Input HL=destination address
;### Output HL=address behind destination
;### Verändert AF,BC
idered call idedrq
ld bc,ideprtdat
ld a,512/32
idered1 ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b
ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b
ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b
ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b:ini:inc b
dec a
jr nz,idered1
ret

;### IDEWRT -> write 512Bytes
;### Input HL=source address
;### Output HL=addresse behind source
;### Verändert AF,BC
idewrt call idedrq ;wait for ready
ld bc,ideprtdat ;bc=IDE data port
ld a,512/32
idewrt1 inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi
inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi
inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi
inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi:inc b:outi
dec a
jr nz,idewrt1
ret

;### IDEERR -> check error status
;### Output CF=0 -> ok (A=0 everthing is fine, A=1 data needed to be corrected),
;### CF=1 -> error (A=code, 6=error while read/write, 7=error while positioning, 8=abort, 9=unknown)
;### Verändert BC
ideerr ld bc,ideprtsta
in a,(c)
and 1+4
ret z ;CF=0, A=0 -> ok
cp 4
ld a,1 ;CF=0, A=1 -> ok, but with data correction
ret z
ld bc,ideprterr
in a,(c)
ld c,a
ld b,6
and 128+64 ;Sector unreadable/BadMarkedSector -> error while read/write
jr nz,ideerr1
ld a,c
inc b
and 2+16 ;Track0 not found/wrong SectorNum -> error while positioning
jr nz,ideerr1
inc b
bit 2,c ;Command Aborted -> abort
jr nz,ideerr1
inc b ;everything else -> unknown
ideerr1 ld a,b
scf
ret
</pre>