123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- ;;; ----------------------------------------------------------------------
- ;;; concept code for controlling an (8-bit mode) IDE interface
- ;;; through a 6522 VIA.
- ;;; --
- ;;; Chris Baird,, <cjb@brushtail.apana.org.au>
- ;;; ----------------------------------------------------------------------
- ;;; ATA IDE drive stuff
- IDE_REG_data = 0
- IDE_REG_error = 1 ; when reading
- IDE_REG_count = 2 ; number of sectors to read/write
- IDE_REG_LBA0 = 3
- IDE_REG_LBA8 = 4
- IDE_REG_LBA16 = 5
- IDE_REG_LBA24 = 6 ; b4 = drive#=0, b6=LBA=1, b5+7=1
- IDE_REG_sector = 3
- IDE_REG_cylinderlo = 4
- IDE_REG_cylinderhi = 5
- IDE_REG_head = 6 ; b4 = drive#, b6=LBA=0
- IDE_REG_status = 7 ; when reading
- IDE_REG_command = 7 ; when writing
- IDE_head_drive = 16 ; various bit fields
- IDE_head_LBA = 64
- IDE_head_extras = 128 + 32 ; required MFM codes
- IDE_status_Busy = 128
- IDE_status_Ready = 64
- IDE_status_DataReq = 8
- IDE_status_Err = 1
- IDE_DCR_SRST = $04
- IDE_CMD_IdentifyDrive = $EC
- IDE_CMD_Idle = $95
- IDE_CMD_InitDriveParams = $91
- IDE_CMD_ReadSector = $20
- IDE_CMD_Seek = $70
- IDE_CMD_Recalibrate = $10
- IDE_CMD_SetFeatures = $EF
- IDE_CMD_WriteSector = $30
- ;;; ----------------------------------------------------------------------
- VIA2 = $9800
- PORTB = VIA2 ; PORTB = to IDE D0-D7
- DDRB = VIA2 + 2
- PORTA = VIA2 + 15 ; PORTA = to IDE control lines
- DDRA = VIA2 + 3
- b_RD = %00001000
- b_WR = %00010000
- b_CS0 = %00100000
- b_RST = %01000000
- IADDRS = $FB
- ZT1 = $FD
- Sector_Buffer = $1000
- ;;; ----------------------------------------------------------------------
- .org $A000
- lda #147
- jsr $FFD2
- lda #0
- tay
- s0: sta 37888,y
- sta 38138,y
- iny
- bne s0
- jsr Disk_Init
- ;;
- loop:
- lda #<Sector_Buffer
- sta IADDRS
- lda #>Sector_Buffer
- sta IADDRS+1
- ldy IDE_LBA0
- sty 4580
- ldy IDE_LBA8
- sty 4581
- ldy IDE_LBA16
- sty 4582
- ldy IDE_LBA24
- sty 4583
- jsr ReadSector
- clc
- lda IDE_LBA0
- adc #1
- sta IDE_LBA0
- lda IDE_LBA8
- adc #0
- sta IDE_LBA8
- lda IDE_LBA16
- adc #0
- sta IDE_LBA16
- lda IDE_LBA24
- adc #0
- sta IDE_LBA24
- jmp loop
- IDE_LBA0: .byte 0
- IDE_LBA8: .byte 0
- IDE_LBA16: .byte 0
- IDE_LBA24: .byte 0
- ;;; ----------------------------------------------------------------------
- ;;; ----------------------------------------------------------------------
- Disk_Init:
- lda #$FF ; port A is all outputs
- sta DDRA ; B is taken care of later
- lda #b_WR + b_RD + b_CS0 ; reset the drive as well
- sta PORTA
- jsr resetdelay
- lda #b_WR + b_RD + b_CS0 + b_RST
- sta PORTA
- lda #0 ; set these in case a routine
- sta IDE_LBA0 ; doesn't want to specify the
- sta IDE_LBA8 ; whole range
- sta IDE_LBA16
- sta IDE_LBA24
- lda #IDE_CMD_InitDriveParams
- ldx #IDE_REG_command
- jmp IDE_Write_Register
- ;;;
- resetdelay:
- ldx #10
- ldy #0
- sdl1:
- dey
- bne sdl1
- dex
- bne sdl1
- rts
- ;;;
- IDE_Write_Register:
- ;; register to write in X
- ;; value taken from A
- pha
- lda #$FF ; set PORTB for output
- sta DDRB
- ;; /CS0=0; /RD=1; /WR=1; /RESET=1; A0:2
- txa
- ora #(b_RD + b_WR + b_RST) ; activate CS0
- sta PORTA
- tax
- pla
- sta PORTB ;the byte to go.. (does it matter if /CS0 is first?)
- txa
- and #~b_WR ;activate WR
- sta PORTA
- ora #b_WR ;deactivate WR
- sta PORTA
- ora #b_CS0 ;deactivate CS0
- sta PORTA
- rts
- ;;;
- IDE_Read_Register:
- ;; register to read in X
- ;; value returned in A
- lda #0 ; set PORTB for input
- sta DDRB
- ;; /CS0=0; /RD=1; /WR=1, A0:2
- txa
- ora #(b_RD + b_WR + b_RST) ; activate /CS0
- sta PORTA
- and #~b_RD ; activate /RD
- sta PORTA
- ldx PORTB
- ora #b_RD
- sta PORTA ; deactivate /RD
- ora #b_CS0 ; deactive /CS0
- sta PORTA
- txa
- rts
- ;;;
- IDE_Send_LBA:
- jsr IDE_WaitGood
- lda IDE_LBA0
- ldx #IDE_REG_LBA0
- jsr IDE_Write_Register
- lda IDE_LBA8
- ldx #IDE_REG_LBA8
- jsr IDE_Write_Register
- lda IDE_LBA16
- ldx #IDE_REG_LBA16
- jsr IDE_Write_Register
- lda IDE_LBA24
- and #15
- ora #IDE_head_LBA + IDE_head_extras
- ldx #IDE_REG_LBA24
- jsr IDE_Write_Register
- lda #1 ; one sector at a time..
- ldx #IDE_REG_count
- jmp IDE_Write_Register
- ;;;
- ReadSector:
- jsr IDE_Send_LBA
- lda #IDE_CMD_ReadSector
- ldx #IDE_REG_command
- jsr IDE_Write_Register
- jsr IDE_WaitReady
- jsr IDE_WaitDataReq
- ;jsr IDE_CheckError ; check error flags
- ;bcs TheRts ; :/
- ldy #0
- rs1:
- ldx #IDE_REG_data
- jsr IDE_Read_Register
- sta (IADDRS),y
- iny
- bne rs1
- jmp IDE_WaitGood
- ;;;
- WriteSector:
- jsr IDE_Send_LBA
- lda #IDE_CMD_WriteSector
- ldx #IDE_REG_command
- jsr IDE_Write_Register
- jsr IDE_WaitnotBusy
- jsr IDE_WaitDataReq
- ldy #0
- w_s1:
- lda (IADDRS),y
- ldx #IDE_REG_data
- jsr IDE_Write_Register
- iny
- bne w_s1
- jsr IDE_WaitGood
- jmp IDE_CheckError ; check (and return) error flags
- ;;; these routines are probably a good place to do sanity/error checking..
- ;;; involving timeouts most likely..
- IDE_WaitGood:
- jsr IDE_WaitnotBusy
- ;; wait-to-go-high
- IDE_WaitReady:
- lda #IDE_status_Ready
- .byte $2c
- IDE_WaitDataReq:
- lda #IDE_status_DataReq
- .byte $2c
- IDE_CheckError:
- lda #IDE_status_Err
- sta ZT1
- I_WSH1:
- ldx #IDE_REG_status
- jsr IDE_Read_Register
- bit ZT1
- beq I_WSH1 ; TODO delay and timeout code here
- rts
- ;; wait-to-go-low
- IDE_WaitnotBusy:
- lda #IDE_status_Busy
- sta ZT1
- I_WSH2:
- ldx #IDE_REG_status
- jsr IDE_Read_Register
- bit ZT1
- bne I_WSH2 ; TODO delay and timeout code here
- ;; is carry clear?
- rts
- ;;; ----------------------------------------------------------------------
|