; Routines for the ATA-interface
;
;
;
;

ACC     EQU     0E0H
DPH     EQU     083H
DPL     EQU     082H



;
; Routine to wait for end of busy
;

ATBSY   MOV     DPTR,#0C00FH;
        MOVX    A,@DPTR
        JB      ACC.7,ATBSY
        RET

;
; Routine to wait for DataReQuest
;

ATDRQ   MOV     DPTR,#0C00FH
        MOVX    A,@DPTR
        JNB     ACC.3,ATDRQ
        RET

;
; Routine to reset ATA-device 0
;

ATRES   MOV     DPTR,#0C006H    ; DPTR points to DeviceControl Register
        MOV     A,#00000110B    ; Reset, no interrupt
        MOVX    @DPTR,A         ; Write to register
        MOV     A,#00000010B;   ; No reset, no interrupt
        MOVX    @DPTR,A         ; Write to register
BSY     MOV     DPTR,#0C00FH;
        MOVX    A,@DPTR
        JB      ACC.7,BSY
        RET

;
; Routine to read a sector
; input : R0 cylinder (HIGH)
;         R1 cylinder (LOW)
;         R2 sector
;         R3 head
;         DPTR pointer to external RAM to store sector
;

ATREAD  PUSH    DPL
        PUSH    DPH
        MOV     DPTR,#0C00AH    ; DPTR points to SectorCount register
        MOV     A,#01H          ; Read 1 sector
        MOVX    @DPTR,A
        INC     DPTR            ; DPTR points to SectorNumber register
        MOV     A,R2            
        MOVX    @DPTR,A
        INC     DPTR            ; DPTR points to CyllinderLow register
        MOV     A,R1
        MOVX    @DPTR,A
        INC     DPTR            ; DPTR points to CyillinderHigh register
        MOV     A,R0
        MOVX    @DPTR,A
        INC     DPTR            ; DPTR points to DriveHead register
        MOV     A,R3
        MOVX    @DPTR,A
        INC     DPTR            ; DPTR points to Command register
        MOV     A,#20H          ; READ SECTOR(S)
        MOVX    @DPTR,A
        ACALL   ATBSY           ; Wait for end of BUSY
        ACALL   ATDRQ           ; Wait for DataReQuest
        MOV     R1,#0           ; 1 sector = 512 bytes = 256 words
ATRD    MOV     DPTR,#0C008H    ; DPTR points to Data register
        MOVX    A,@DPTR         ; Read LSB
        POP     DPH
        POP     DPL
        MOVX    @DPTR,A         ; Store LSB
        INC     DPTR
        PUSH    DPL
        PUSH    DPH
        MOV     DPTR,#0C000H
        MOVX    A,@DPTR         ; Read MSB
        POP     DPH
        POP     DPL
        MOVX    @DPTR,A         ; Store MSB
        INC     DPTR
        PUSH    DPL
        PUSH    DPH
        DJNZ    R1,ATRD         ; Read until 256 words
        POP     DPH             ; Make sure that the stack is cleaned up
        POP     DPL
        RET


;
; Routine to write a sector
; input : R0 cylinder (HIGH)
;         R1 cylinder (LOW)
;         R2 sector
;         R3 head
;         DPTR pointer to external RAM to store sector
;

ATWRITE PUSH    DPL
        PUSH    DPH
        MOV     DPTR,#0C00AH    ; DPTR points to SectorCount register
        MOV     A,#01H          ; Read 1 sector
        MOVX    @DPTR,A
        INC     DPTR            ; DPTR points to SectorNumber register
        MOV     A,R2            
        MOVX    @DPTR,A
        INC     DPTR            ; DPTR points to CyllinderLow register
        MOV     A,R1
        MOVX    @DPTR,A
        INC     DPTR            ; DPTR points to CyillinderHigh register
        MOV     A,R0
        MOVX    @DPTR,A
        INC     DPTR            ; DPTR points to DriveHead register
        MOV     A,R3
        MOVX    @DPTR,A
        INC     DPTR            ; DPTR points to Command register
        MOV     A,#30H          ; WRITE SECTOR(S)
        MOVX    @DPTR,A
        ACALL   ATBSY           ; Wait for end of BUSY
        ACALL   ATDRQ           ; Wait for DataReQuest
        MOV     R1,#0           ; 1 sector = 512 bytes = 256 words

ATWR    POP     DPH             ; Get pointer to data in external RAM
        POP     DPL
        MOVX    A,@DPTR         ; Read LSB
        MOV     R2,A            ; Save LSB
        INC     DPTR
        MOVX    A,@DPTR         ; Get MSB
        INC     DPTR
        PUSH    DPL             ; Save new pointer
        PUSH    DPH
        MOV     DPTR,#0C000H    ; DPTR points to MSB latch
        MOVX    @DPTR,A
        MOV     DPTR,#0C008H    ; DPTR points to Data register
        MOV     A,R2            ; Restore LSB
        MOVX    @DPTR,A         ; Write to ATA device
        DJNZ    R1,ATWR         ; Read until 256 words
        POP     DPH             ; Make sure that the stack is cleaned up
        POP     DPL

        RET

        END
