SYMBiFACE II:IDE routines

From CPCWiki - THE Amstrad CPC encyclopedia!
Revision as of 20:02, 25 August 2006 by Prodatron (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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.

;==============================================================================
;### 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