IDE.asm 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. ;;; ----------------------------------------------------------------------
  2. ;;; concept code for controlling an (8-bit mode) IDE interface
  3. ;;; through a 6522 VIA.
  4. ;;; --
  5. ;;; Chris Baird,, <cjb@brushtail.apana.org.au>
  6. ;;; ----------------------------------------------------------------------
  7. ;;; ATA IDE drive stuff
  8. IDE_REG_data = 0
  9. IDE_REG_error = 1 ; when reading
  10. IDE_REG_count = 2 ; number of sectors to read/write
  11. IDE_REG_LBA0 = 3
  12. IDE_REG_LBA8 = 4
  13. IDE_REG_LBA16 = 5
  14. IDE_REG_LBA24 = 6 ; b4 = drive#=0, b6=LBA=1, b5+7=1
  15. IDE_REG_sector = 3
  16. IDE_REG_cylinderlo = 4
  17. IDE_REG_cylinderhi = 5
  18. IDE_REG_head = 6 ; b4 = drive#, b6=LBA=0
  19. IDE_REG_status = 7 ; when reading
  20. IDE_REG_command = 7 ; when writing
  21. IDE_head_drive = 16 ; various bit fields
  22. IDE_head_LBA = 64
  23. IDE_head_extras = 128 + 32 ; required MFM codes
  24. IDE_status_Busy = 128
  25. IDE_status_Ready = 64
  26. IDE_status_DataReq = 8
  27. IDE_status_Err = 1
  28. IDE_DCR_SRST = $04
  29. IDE_CMD_IdentifyDrive = $EC
  30. IDE_CMD_Idle = $95
  31. IDE_CMD_InitDriveParams = $91
  32. IDE_CMD_ReadSector = $20
  33. IDE_CMD_Seek = $70
  34. IDE_CMD_Recalibrate = $10
  35. IDE_CMD_SetFeatures = $EF
  36. IDE_CMD_WriteSector = $30
  37. ;;; ----------------------------------------------------------------------
  38. VIA2 = $9800
  39. PORTB = VIA2 ; PORTB = to IDE D0-D7
  40. DDRB = VIA2 + 2
  41. PORTA = VIA2 + 15 ; PORTA = to IDE control lines
  42. DDRA = VIA2 + 3
  43. b_RD = %00001000
  44. b_WR = %00010000
  45. b_CS0 = %00100000
  46. b_RST = %01000000
  47. IADDRS = $FB
  48. ZT1 = $FD
  49. Sector_Buffer = $1000
  50. ;;; ----------------------------------------------------------------------
  51. .org $A000
  52. lda #147
  53. jsr $FFD2
  54. lda #0
  55. tay
  56. s0: sta 37888,y
  57. sta 38138,y
  58. iny
  59. bne s0
  60. jsr Disk_Init
  61. ;;
  62. loop:
  63. lda #<Sector_Buffer
  64. sta IADDRS
  65. lda #>Sector_Buffer
  66. sta IADDRS+1
  67. ldy IDE_LBA0
  68. sty 4580
  69. ldy IDE_LBA8
  70. sty 4581
  71. ldy IDE_LBA16
  72. sty 4582
  73. ldy IDE_LBA24
  74. sty 4583
  75. jsr ReadSector
  76. clc
  77. lda IDE_LBA0
  78. adc #1
  79. sta IDE_LBA0
  80. lda IDE_LBA8
  81. adc #0
  82. sta IDE_LBA8
  83. lda IDE_LBA16
  84. adc #0
  85. sta IDE_LBA16
  86. lda IDE_LBA24
  87. adc #0
  88. sta IDE_LBA24
  89. jmp loop
  90. IDE_LBA0: .byte 0
  91. IDE_LBA8: .byte 0
  92. IDE_LBA16: .byte 0
  93. IDE_LBA24: .byte 0
  94. ;;; ----------------------------------------------------------------------
  95. ;;; ----------------------------------------------------------------------
  96. Disk_Init:
  97. lda #$FF ; port A is all outputs
  98. sta DDRA ; B is taken care of later
  99. lda #b_WR + b_RD + b_CS0 ; reset the drive as well
  100. sta PORTA
  101. jsr resetdelay
  102. lda #b_WR + b_RD + b_CS0 + b_RST
  103. sta PORTA
  104. lda #0 ; set these in case a routine
  105. sta IDE_LBA0 ; doesn't want to specify the
  106. sta IDE_LBA8 ; whole range
  107. sta IDE_LBA16
  108. sta IDE_LBA24
  109. lda #IDE_CMD_InitDriveParams
  110. ldx #IDE_REG_command
  111. jmp IDE_Write_Register
  112. ;;;
  113. resetdelay:
  114. ldx #10
  115. ldy #0
  116. sdl1:
  117. dey
  118. bne sdl1
  119. dex
  120. bne sdl1
  121. rts
  122. ;;;
  123. IDE_Write_Register:
  124. ;; register to write in X
  125. ;; value taken from A
  126. pha
  127. lda #$FF ; set PORTB for output
  128. sta DDRB
  129. ;; /CS0=0; /RD=1; /WR=1; /RESET=1; A0:2
  130. txa
  131. ora #(b_RD + b_WR + b_RST) ; activate CS0
  132. sta PORTA
  133. tax
  134. pla
  135. sta PORTB ;the byte to go.. (does it matter if /CS0 is first?)
  136. txa
  137. and #~b_WR ;activate WR
  138. sta PORTA
  139. ora #b_WR ;deactivate WR
  140. sta PORTA
  141. ora #b_CS0 ;deactivate CS0
  142. sta PORTA
  143. rts
  144. ;;;
  145. IDE_Read_Register:
  146. ;; register to read in X
  147. ;; value returned in A
  148. lda #0 ; set PORTB for input
  149. sta DDRB
  150. ;; /CS0=0; /RD=1; /WR=1, A0:2
  151. txa
  152. ora #(b_RD + b_WR + b_RST) ; activate /CS0
  153. sta PORTA
  154. and #~b_RD ; activate /RD
  155. sta PORTA
  156. ldx PORTB
  157. ora #b_RD
  158. sta PORTA ; deactivate /RD
  159. ora #b_CS0 ; deactive /CS0
  160. sta PORTA
  161. txa
  162. rts
  163. ;;;
  164. IDE_Send_LBA:
  165. jsr IDE_WaitGood
  166. lda IDE_LBA0
  167. ldx #IDE_REG_LBA0
  168. jsr IDE_Write_Register
  169. lda IDE_LBA8
  170. ldx #IDE_REG_LBA8
  171. jsr IDE_Write_Register
  172. lda IDE_LBA16
  173. ldx #IDE_REG_LBA16
  174. jsr IDE_Write_Register
  175. lda IDE_LBA24
  176. and #15
  177. ora #IDE_head_LBA + IDE_head_extras
  178. ldx #IDE_REG_LBA24
  179. jsr IDE_Write_Register
  180. lda #1 ; one sector at a time..
  181. ldx #IDE_REG_count
  182. jmp IDE_Write_Register
  183. ;;;
  184. ReadSector:
  185. jsr IDE_Send_LBA
  186. lda #IDE_CMD_ReadSector
  187. ldx #IDE_REG_command
  188. jsr IDE_Write_Register
  189. jsr IDE_WaitReady
  190. jsr IDE_WaitDataReq
  191. ;jsr IDE_CheckError ; check error flags
  192. ;bcs TheRts ; :/
  193. ldy #0
  194. rs1:
  195. ldx #IDE_REG_data
  196. jsr IDE_Read_Register
  197. sta (IADDRS),y
  198. iny
  199. bne rs1
  200. jmp IDE_WaitGood
  201. ;;;
  202. WriteSector:
  203. jsr IDE_Send_LBA
  204. lda #IDE_CMD_WriteSector
  205. ldx #IDE_REG_command
  206. jsr IDE_Write_Register
  207. jsr IDE_WaitnotBusy
  208. jsr IDE_WaitDataReq
  209. ldy #0
  210. w_s1:
  211. lda (IADDRS),y
  212. ldx #IDE_REG_data
  213. jsr IDE_Write_Register
  214. iny
  215. bne w_s1
  216. jsr IDE_WaitGood
  217. jmp IDE_CheckError ; check (and return) error flags
  218. ;;; these routines are probably a good place to do sanity/error checking..
  219. ;;; involving timeouts most likely..
  220. IDE_WaitGood:
  221. jsr IDE_WaitnotBusy
  222. ;; wait-to-go-high
  223. IDE_WaitReady:
  224. lda #IDE_status_Ready
  225. .byte $2c
  226. IDE_WaitDataReq:
  227. lda #IDE_status_DataReq
  228. .byte $2c
  229. IDE_CheckError:
  230. lda #IDE_status_Err
  231. sta ZT1
  232. I_WSH1:
  233. ldx #IDE_REG_status
  234. jsr IDE_Read_Register
  235. bit ZT1
  236. beq I_WSH1 ; TODO delay and timeout code here
  237. rts
  238. ;; wait-to-go-low
  239. IDE_WaitnotBusy:
  240. lda #IDE_status_Busy
  241. sta ZT1
  242. I_WSH2:
  243. ldx #IDE_REG_status
  244. jsr IDE_Read_Register
  245. bit ZT1
  246. bne I_WSH2 ; TODO delay and timeout code here
  247. ;; is carry clear?
  248. rts
  249. ;;; ----------------------------------------------------------------------