SYMBiFACE II:IDE routines
From CPCWiki - THE Amstrad CPC encyclopedia!
These are the core SYMBiFACE II IDE low level routines of SymbOS, written by Prodatron. 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 ;### Input HL=Track, E=Sector, D=SDH (head, drive, mode), B=number of sectors ;### Output CF=0 -> ok ;### CF=1 -> A=error code (...) ;### Destroyed 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 ;### Input A=Command ;### Destroyed 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) ;### Destroyed 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 ;### Destroyed 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 ;### Destroyed 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 ;### Destroyed 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) ;### Destroyed 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 ;### IDE48B -> set 48bit address ;### Eingabe IX[32-47],HL[16-31],DE[0-15]=Sectornumber, A=SDH, B=Number of Sectors ;### Output CF=0 -> ok ;### CF=1 -> A=error code (...) ;### Destroyed AF,BC,DE ide48b push af ;4 call iderdy ; wait for ready before SDH write jr c,ide48b1 ;2 pop af ;3 ld c,a ;1 push bc ;4 ld bc,ideprtsdh ;3 or #0f ;2 dec a ;1 out (c),a ;4 write SDH Register (low bytes) dec c ;1 out (c),l ;4 LBA 16-23 dec c ;1 out (c),d ;4 LBA 08-15 dec c ;1 out (c),e ;4 LBA 00-07 ld bc,ideprtsdh ;3 pop de ;3 inc e ;1 out (c),e ;4 write SDH Register (high bytes) dec c ;1 db #dd:ld a,h ;2 out (c),a ;4 LBA 40-47 dec c ;1 db #dd:ld a,l ;2 out (c),a ;4 LBA 32-39 dec c ;1 out (c),h ;4 LBA 24-31 dec c ;1 out (c),d ;4 Sector count ret ;3 -> 77 microseconds ide48b1 pop bc ;Return on Error ret