| Roland Zeuge | ELE 408 Project | IDE Hard Drive Interface | Register Use: | A0: starting address of the buffer | A1: Address of the output registers | A2: | D0: (L) contains active LBA | D1: (b) contains upper 8 bits of 40-bit signal | D2: (L) contains lower 32 bits of 40-bit signal | D3: (L) temporary register | D4: (L) temporary register | D5: (L) used to pass values to a subroutine | D6: (L) temp counting variable | D7: if D7 is zero, the program will write 512 bytes from the buffer to the HDD. | Otherwise, the program will read 512 bytes from the HDD to the buffer |J9 = J9 Connector, which is 60 bits (only 40 are used) movea.l #0x21000, %A0 movea.l #0x10000AB8, %A1 movea.l #0x10000ABC, %A2 move.l %D7, %d7 beq WRITING READING: jsr INITIALIZE move.l #0, %D0 jsr SET_LBA move.l #512, %D6 move.w (%A0)+, %D5 READ_LOOP: jsr INPUT jsr GET_DATA subq.l #1, %D6 bne READ_LOOP trap #14; |end WRITING: jsr INITIALIZE move.l #512, %D6 move.w (%A0)+, %D5 WRITE_LOOP: jsr SET_DATA jsr OUTPUT subq.l #1, %D6 bne READ_LOOP trap #14; | Wait subroutine | Write a number into D5 and it will be excecuted that many times WAIT: subq.l #1, %D5 bne WAIT rts | SET_LBA Subroutine | Changes the LBA to the value in D0 SET_LBA: move.l %D0, %D5 lsr.l #4, %D0 lsr.l #4, %D0 jsr SET_DATA move.l #3, %D5 jsr SET_DA move.l #1, %D5 jsr SET_CS1FX move.l #0, %D5 jsr SET_CS1FX jsr OUTPUT move.l #0, %D5 jsr SET_CS1FX move.l #1, %D5 jsr SET_CS1FX jsr OUTPUT move.l %D0, %D5 lsr.l #4, %D0 lsr.l #4, %D0 jsr SET_DATA move.l #4, %D5 jsr SET_DA move.l #1, %D5 jsr SET_CS1FX move.l #0, %D5 jsr SET_CS1FX jsr OUTPUT move.l #0, %D5 jsr SET_CS1FX move.l #1, %D5 jsr SET_CS1FX jsr OUTPUT move.l %D0, %D5 lsr.l #4, %D0 lsr.l #4, %D0 jsr SET_DATA move.l #5, %D5 jsr SET_DA move.l #1, %D5 jsr SET_CS1FX move.l #0, %D5 jsr SET_CS1FX jsr OUTPUT move.l #0, %D5 jsr SET_CS1FX move.l #1, %D5 jsr SET_CS1FX jsr OUTPUT move.l %D0, %D5 lsr.l #4, %D0 lsr.l #4, %D0 jsr SET_DATA move.l #6, %D5 jsr SET_DA move.l #1, %D5 jsr SET_CS1FX move.l #0, %D5 jsr SET_CS1FX jsr OUTPUT move.l #0, %D5 jsr SET_CS1FX move.l #1, %D5 jsr SET_CS1FX jsr OUTPUT rts | OUTPUT Subroutine | Outputs a 40-bit signal from D1 and D2 to J9 OUTPUT: move.l #0, %D5 jsr SET_DIOW | move.l %D1, %A1 move.l %D2, %A2 move.l #50, %D5 jsr WAIT move.l #1, %D5 jsr SET_DIOW | move.l %D1, %A1 move.l %D2, %A2 rts | INPUT Subroutine | Reads a 40-bit signal from J9 to D1 and D2 INPUT: move.l #0, %D5 jsr SET_DIOR | move.l %A1, %D1 move.l %A2, %D2 move.l #50, %D5 jsr WAIT move.l #1, %D5 jsr SET_DIOR | move.l %A1, %D1 move.l %A2, %D2 rts | Subroutine INITIALIZE | initializes start state and resets the Hard Disk move.b #0, %D1 move.l #0, %D2 jsr OUTPUT move.l #25, %D5 jsr WAIT move.l #1, %D5 jsr SET_RESET jsr SET_DIOR jsr SET_DIOW jsr OUTPUT rts | Subroutines to set the D1 and D2 registers (signals to the hard disk) | signals that are not used, or that are ground, are preset or set to zero. | Signals: (- indicates active low) | CS1FX (-) | CS3FX (-) | DIOR (-) | DIOW (-) | RESET (-) | DA[2:0] | DATA[15:0] | Subroutine SET_CS1FX | if D5 is 0, sets CS1FX to 0, if D5 is 1, set to 1 | CS1FX is pin 37, corresponds to D1(4) move.l %D5, %D3 beq CS1FX_0 | set the bit or.l #0x10, %D1 bra CS1FX_END CS1FX_0: and.l #0xEF, %D1 CS1FX_END: rts | Subroutine SET_CS3FX | if D5 is 0, sets CS3FX to 0, if D5 is 1, set to 1 | CS1FX is pin 38, corresponds to D1(5) move.l %D5, %D3 beq CS3FX_0 | set the bit or.l #0x20, %D1 bra CS3FX_END CS3FX_0: and.l #0xDF, %D1 CS3FX_END: rts | Subroutine SET_DIOR | if D5 is 0, sets DIOR to 0, if D5 is 1, set to 1 | DIOR is pin 25, corresponds to D2(24) move.l %D5, %D3 beq DIOR_0 | set the bit or.l #0x02000000, %D1 bra DIOR_END DIOR_0: and.l #0xFDFFFFFF, %D1 DIOR_END: rts | Subroutine SET_DIOW | if D5 is 0, sets DIOW to 0, if D5 is 1, set to 1 | DIOR is pin 23, corresponds to D2(22) move.l %D5, %D3 beq DIOW_0 | set the bit or.l #0x00800000, %D1 bra DIOR_END DIOW_0: and.l #0xFFEFFFFF, %D1 DIOW_END: rts | Subroutine SET_RESET | if D5 is 0, sets RESET to 0, if D5 is 1, set to 1 | RESET is pin 1, corresponds to D2(0) move.l %D5, %D3 beq RESET_0 | set the bit or.l #0x00000001, %D1 bra RESET_END RESET_0: and.l #0xFFFFFFFE, %D1 RESET_END: rts | Subroutine SET_DA | the value of the DA bits are set to the value of D5 (0-7 are acceptable) | The DA bits are pins 36, 33, and 35 (DA2, DA1, DA0, respectively) | and D1(3, 0, and 2, respectively) move.l %D5, %D3 and.l #0x04, %D3 beq DABIT2IS0 or.l #0x04, %D1 bra DABIT1 DABIT2IS0: and.l #0xFB, %D1 DABIT1: move.l %D5, %D3 and.l #0x02, %D3 beq DABIT1IS0 or.l #0x01, %D1 bra DABIT0 DABIT1IS0: and.l #0xFE, %D1 DABIT0: move.l %D5, %D3 and.l #0x01, %D3 beq DABIT0IS0 or.l #0x02, %D1 bra DAEND DABIT0IS0: and.l #0xFB, %D1 DAEND: rts | Subroutine SET_DATA | The value of the DATA bits are set to the value of D5 (16 bits are acceptable) | The DATA bits are (LSB-MSB): | Pins 18 16 14 12 10 8 6 4 3 5 7 9 11 13 15 17 | D2 bits 17 15 13 11 9 7 5 3 2 4 6 8 10 12 14 16 move.l %D5, %D3 and.l #0x8000, %D3 beq BIT15IS0 or.l #0x00010000, %D1 bra DABIT14 BIT15IS0: and.l #0xFFFEFFFF, %D1 DABIT14: move.l %D5, %D3 and.l #0x4000, %D3 beq BIT14IS0 or.l #0x00004000, %D1 bra DABIT13 BIT14IS0: and.l #0xFFFFBFFF, %D1 DABIT13: move.l %D5, %D3 and.l #0x2000, %D3 beq BIT13IS0 or.l #0x00001000, %D1 bra DABIT12 BIT13IS0: and.l #0xFFFFEFFF, %D1 DABIT12: move.l %D5, %D3 and.l #0x1000, %D3 beq BIT12IS0 or.l #0x00000400, %D1 bra DABIT11 BIT12IS0: and.l #0xFFFFFBFF, %D1 DABIT11: move.l %D5, %D3 and.l #0x0800, %D3 beq BIT11IS0 or.l #0x00000100, %D1 bra DABIT10 BIT11IS0: and.l #0xFFFFFEFF, %D1 DABIT10: move.l %D5, %D3 and.l #0x0400, %D3 beq BIT10IS0 or.l #0x00000040, %D1 bra DABIT9 BIT10IS0: and.l #0xFFFFFFBF, %D1 DABIT09: move.l %D5, %D3 and.l #0x0200, %D3 beq BIT09IS0 or.l #0x00000010, %D1 bra DABIT8 BIT09IS0: and.l #0xFFFFFFEF, %D1 DABIT08: move.l %D5, %D3 and.l #0x0100, %D3 beq BIT08IS0 or.l #0x00000004, %D1 bra DABIT7 BIT08IS0: and.l #0xFFFFFFFB, %D1 DABIT07: move.l %D5, %D3 and.l #0x0070, %D3 beq BIT06IS0 or.l #0x00000002, %D1 bra DABIT6 BIT07IS0: and.l #0xFFFFFFFD, %D1 DABIT06: move.l %D5, %D3 and.l #0x0060, %D3 beq BIT05IS0 or.l #0x00000008, %D1 bra DABIT5 BIT06IS0: and.l #0xFFFFFFF7, %D1 DABIT05: move.l %D5, %D3 and.l #0x0020, %D3 beq BIT05IS0 or.l #0x00000020, %D1 bra DABIT4 BIT05IS0: and.l #0xFFFFFFDF, %D1 DABIT04: move.l %D5, %D3 and.l #0x0010, %D3 beq BIT04IS0 or.l #0x00000080, %D1 bra DABIT3 BIT04IS0: and.l #0xFFFFFF7F, %D1 DABIT03: move.l %D5, %D3 and.l #0x0008, %D3 beq BIT03IS0 or.l #0x00000200, %D1 bra DABIT2 BIT03IS0: and.l #0xFFFFFDFF, %D1 DABIT02: move.l %D5, %D3 and.l #0x0004, %D3 beq BIT02IS0 or.l #0x00000800, %D1 bra DABIT1 BIT02IS0: and.l #0xFFFFF7FF, %D1 DABIT01: move.l %D5, %D3 and.l #0x0002, %D3 beq BIT01IS0 or.l #0x00002000, %D1 bra DABIT0 BIT01IS0: and.l #0xFFFFDFFF, %D1 DABIT00: move.l %D5, %D3 and.l #0x0001, %D3 beq BIT00IS0 or.l #0x00008000, %D1 bra DABITEND BIT00IS0: and.l #0xFFFF7FFF, %D1 DABITEND: rts | Subroutine GET_DATA | The Data word in the D2 register is extracted and written to the buffer pointed to by A0 | The DATA bits are (LSB-MSB): | Pins 18 16 14 12 10 8 6 4 3 5 7 9 11 13 15 17 | D2 bits 17 15 13 11 9 7 5 3 2 4 6 8 10 12 14 16 move.l #0, %D4 move.l %D2, %D3 and.l #0x00010000, %D3 beq GETBIT14 or.l #0x8000, %D4 GETBIT14: move.l %D2, %D3 and.l #0x00004000, %D3 beq GETBIT13 or.l #0x4000, %D4 GETBIT13: move.l %D2, %D3 and.l #0x00001000, %D3 beq GETBIT12 or.l #0x2000, %D4 GETBIT12: move.l %D2, %D3 and.l #0x00000400, %D3 beq GETBIT11 or.l #0x1000, %D4 GETBIT11: move.l %D2, %D3 and.l #0x00000100, %D3 beq GETBIT10 or.l #0x0800, %D4 GETBIT10: move.l %D2, %D3 and.l #0x00000040, %D3 beq GETBIT09 or.l #0x0400, %D4 GETBIT09: move.l %D2, %D3 and.l #0x00000010, %D3 beq GETBIT08 or.l #0x0200, %D4 GETBIT08: move.l %D2, %D3 and.l #0x00010004, %D3 beq GETBIT07 or.l #0x0100, %D4 GETBIT07: move.l %D2, %D3 and.l #0x00000002, %D3 beq GETBIT06 or.l #0x0080, %D4 GETBIT06: move.l %D2, %D3 and.l #0x0000008, %D3 beq GETBIT05 or.l #0x0040, %D4 GETBIT05: move.l %D2, %D3 and.l #0x00000020, %D3 beq GETBIT04 or.l #0x0020, %D4 GETBIT04: move.l %D2, %D3 and.l #0x00000080, %D3 beq GETBIT03 or.l #0x0010, %D4 GETBIT03: move.l %D2, %D3 and.l #0x00000200, %D3 beq GETBIT02 or.l #0x0008, %D4 GETBIT02: move.l %D2, %D3 and.l #0x00000800, %D3 beq GETBIT01 or.l #0x0004, %D4 GETBIT01: move.l %D2, %D3 and.l #0x00002000, %D3 beq GETBIT00 or.l #0x0002, %D4 GETBIT00: move.l %D2, %D3 and.l #0x00008000, %D3 beq GETBITEND or.l #0x0001, %D4 GETBITEND: move.l %D4, (%A0)+ rts