Path: ns-mx!uunet!ogicse!orstcs!jacobs.CS.ORST.EDU!parkern From: parkern@jacobs.CS.ORST.EDU (Neil Parker) Newsgroups: comp.sys.apple2 Subject: Controlling the 3.5 Drive hardware (IIGS only) (2 of 2) Summary: Sample program included Keywords: IIGS disk hardware Message-ID: <1991May17.110015.932@lynx.CS.ORST.EDU> Date: 17 May 91 11:00:15 GMT Sender: @lynx.CS.ORST.EDU Reply-To: parkern@jacobs.CS.ORST.EDU (Neil Parker) Organization: The Universal Society for the Prevention of Reality Lines: 286 Nntp-Posting-Host: jacobs.cs.orst.edu Controlling the 3.5 Drive Hardware on the Apple IIGS Part 2 of 2: A real live working program! By Neil Parker The program listed below was written to illustrate the steps necessary to control the hardware of the 3.5 Drive from your own programs, without the use of the operating system or the firmware. It is essentially a 3.5-inch version of the DUMP program by Don Worth which was printed in "Beneath Apple DOS." It will read a track from a 3.5-inch disk into your Apple's memory, in its raw, encoded form. Included below are a commented source code listing and a hex dump suitable for typing directly into the System Monitor (or capturing into a text file and EXECing). Instructions: First, boot DOS 3.3 or ProDOS 8. DUMP3.5 should be compatible with either operating system. If you booted ProDOS, get into BASIC.SYSTEM. When you see the ] prompt, type "BLOAD DUMP3.5", and then "CALL-151". Store the number of the track you wish to examine in memory location 6, and the disk side you wish to examine (0 for the lower side, anything else for the upper side) in location 7. Put the disk to be examined in Drive 1, and type "900G". The raw track data will then be found in memory locations $1000 through $7FFF (this buffer is much longer than an actual track, so the data will most likely be repeated several times in the buffer). For example, ]BLOAD DUMP3.5 (Load the program) ]CALL-151 (Enter the Monitor) *6:20 (Select track $20) *7:1 (Select upper side) *900G (Run DUMP3.5 (don't forget to insert the disk first)) *1000.10FF (Examine the first 256 bytes of the track) The usual Dire Warnings apply: I make no guarantees whatsoever for this program. I have tested it, and it seems to work on my computer, but I recommend using it ONLY on expendable disks, and ONLY with the write-protect hole open. I assume no responsibility for any damage which may result from the use or misuse of this program. Be especially careful if you enter either the assemby listing or the hex dump by hand--the slightest typographical error could turn a benign tool into a malevolent disk-eating monster. I hope this program helps clarify the disk access process. If there is enough interest in an explanation of how to interpret what it accesses, it might be possible to talk me into writing up an explanation of the block encoding process. (I recommend first reading "Beneath Apple DOS" (if you can find a copy), and also the SmartPort chapter of the Firmware Reference.) - Neil Parker ;************************************************************************* ; DUMP3.5--Dump a track of a 3.5-inch disk to memory. (IIGS only) ; ; By Neil Parker--inspired by Don Worth's DUMP program from "Beneath ; Apple DOS" ; ; Inputs: $06 = Track to be dumped ; $07 = Side to be dumped (0=lower side, non-0=upper side) ; Outputs: $1000-$7FFF = raw track data ; ; Example: ; *6:20 1 (Select track $20, upper side) ; *900G (Run DUMP3.5) ; *1000.10FF (Examine part of the track) ;************************************************************************* ORG $900 TRACK EQU 6 ;Track number SIDE EQU 7 ;Side number PTR EQU 8 BUFFER EQU $1000 ;Start address for track data SLTROMSEL EQU $C02D ;Select internal/external ROMs for slots DISKREG EQU $C031 ;Select 3.5/5.25 drive, control SEL line CYAREG EQU $C036 ;System speed and motor-on-detect bits CA0 EQU $C0E0 ;Phase 0, 3.5 drive control CA1 EQU $C0E2 ;Phase 1, 3.5 drive control CA2 EQU $C0E4 ;Phase 2, 3.5 drive control LSTRB EQU $C0E6 ;Phase 3, control strobe ENABLE EQU $C0E8 ;Turn drive off/on SELECT EQU $C0EA ;Select drive 1/2 Q6 EQU $C0EC Q7 EQU $C0EE ; LDA SLTROMSEL ;Get slot 6 status, PHA ;save it, AND #$BF ;force internal ROM+I/O for Slot 6 STA SLTROMSEL LDA CA0 ;Clear disk I/O latches LDA CA1 LDA CA2 LDA LSTRB LDA ENABLE ;Insure that drive is off LDA SELECT ;Select drive 1 LDA Q6 ;Set IWM for reading (a "safe" state) LDA Q7 LDA #$F ;Configure IWM for 3.5 access JSR SELIWM LDA DISKREG ;Save old DISKREG PHA ORA #$40 ;Select 3.5 drive STA DISKREG LDA ENABLE+1 ;Turn drive on LDA #2 ;Is there a disk in the drive? JSR SEL35 JSR TEST35 BPL THERE ;If so, read JMP DONE ;otherwise quit THERE LDA #8 ;Turn motor on JSR SEL35 JSR TRIG35 LDA #1 ;Set step direction=outward JSR SEL35 JSR TRIG35 TSTTRK0 LDA #$A ;Are we at track 0 yet? JSR SEL35 JSR TEST35 BPL ATTRK0 ;If so, go read LDA #4 ;otherwise do a step JSR SEL35 JSR TRIG35 SEEKING0 JSR TEST35 ;Step still in progress? BPL SEEKING0 ;If so, loop until step done BMI TSTTRK0 ;otherwise go see if we're at track 0 yet ATTRK0 LDX TRACK ;What track did the user want? BEQ DUMP ;If track 0, we're already there--go read LDA #0 ;else set step direction=inward JSR SEL35 JSR TRIG35 SEEK LDA #4 ;Do a step JSR SEL35 JSR TRIG35 SEEKING JSR TEST35 ;Step still in progress? BPL SEEKING ;If so, loop until step done DEX ;otherwise see if we've stepped enough yet BNE SEEK ;If not, go step again DUMP LDA #$B ;Disk ready for reading yet? JSR SEL35 READYT JSR TEST35 BMI READYT ;Loop until disk ready LDA SIDE ;What side did the user want? BEQ SIDE1 ;If 0, set lower side LDA #3 ;else set upper side BNE SETSIDE SIDE1 LDA #1 SETSIDE JSR SEL35 JSR TEST35 PHP ;Save interrupt status SEI ;Don't let anything interrupt us LDA CYAREG ;Save old system speed PHA AND #$FB ;Set speed=fast ORA #$80 STA CYAREG LDA #BUFFER ;change #> to #< and #< to #>.) STA PTR+1 LDY #0 DUMPLP LDA Q6 ;Read a byte BPL DUMPLP ;Loop until we have a valid byte STA (PTR),Y ;Store byte in buffer INC PTR ;Advance buffer pointer BNE DUMPLP INC PTR+1 LDA PTR+1 ;Buffer full yet? CMP #$80 BCC DUMPLP ;If not, go read some more PLA ;Done. Restore system speed STA CYAREG PLP ;Restore interrupt status LDA #9 ;Turn motor off JSR SEL35 JSR TRIG35 DONE LDA ENABLE ;Turn drive off LDA CA0 ;Clear disk I/O latches LDA CA1 LDA CA2 LDA LSTRB PLA ;Restore old DISKREG value STA DISKREG LDA #0 ;Configure IWM for 5.25 access JSR SELIWM PLA ;Restore original slot configuration STA SLTROMSEL RTS ;Amen. ; ;Subroutine to select 3.5 drive status/control registers ;Enter with accumulator=desired status: ; Bit 0=CA2 status ; Bit 1=SEL status ; Bit 2=CA0 status ; Bit 3=CA1 status ; SEL35 BIT CA0 BIT CA1+1 BIT LSTRB BIT CA2 LSR ;If bit 0 set, turn on CA2 BCC S35A BIT CA2+1 S35A LSR ;If bit 1 set, turn on SEL PHA LDA DISKREG AND #$7F BCC S35B ORA #$80 S35B STA DISKREG PLA LSR ;If bit 2 set, turn on CA0 BCC S35C BIT CA0+1 S35C LSR ;If bit 3 set, turn on CA1 BCS S35D BIT CA1 S35D RTS ; ;Subroutine to read the status of the 3.5 drive ;First call SEL35 to select register to examine ;Result is in processor N (negative) flag ; TEST35 BIT Q6+1 BIT Q7 RTS ; ;Subroutine to perform a 3.5 drive control function ;First call SEL35 to select function to be performed ; TRIG35 BIT LSTRB+1 BIT LSTRB RTS ; ;Subroutine to configure the IWM chip ;Before calling, make sure drive is OFF! ;Call with accumulator=desired Mode Register value ; A=$00 for 5.25 drive ; A=$0F for 3.5 drive ; SELIWM TAY BIT Q6+1 ;Prepare to access Mode & Status Regs. JMP SELIWM2 ;First see if it's already set like we want it SELIWM1 TYA STA Q7+1 ;Try writing to Mode Reg. SELIWM2 TYA EOR Q7 ;Compare input to Status Reg. AND #$1F BNE SELIWM1 ;If not the same, try writing again BIT Q6 ;else prepare IWM for data RTS Here is the hext dump corresponding to the above assembler listing. This can be entered by hand into the Monitor, or you can capture it into a text file, put "CALL-151" at the beginning and "3D0G" and "BSAVE DUMP3.5,A$900,L$145" at the end and EXEC it to create the program. 900:AD 2D C0 48 29 BF 8D 2D C0 AD E0 C0 AD E2 C0 AD 910:E4 C0 AD E6 C0 AD E8 C0 AD EA C0 AD EC C0 AD EE 920:C0 A9 0F 20 2E 0A AD 31 C0 48 09 40 8D 31 C0 AD 930:E9 C0 A9 02 20 F2 09 20 20 0A 10 03 4C D5 09 A9 940:08 20 F2 09 20 27 0A A9 01 20 F2 09 20 27 0A A9 950:0A 20 F2 09 20 20 0A 10 0F A9 04 20 F2 09 20 27 960:0A 20 20 0A 10 FB 30 E7 A6 06 F0 18 A9 00 20 F2 970:09 20 27 0A A9 04 20 F2 09 20 27 0A 20 20 0A 10 980:FB CA D0 F0 A9 0B 20 F2 09 20 20 0A 30 FB A5 07 990:F0 04 A9 03 D0 02 A9 01 20 F2 09 20 20 0A 08 78 9A0:AD 36 C0 48 29 FB 09 80 8D 36 C0 A9 00 85 08 A9 9B0:10 85 09 A0 00 AD EC C0 10 FB 91 08 E6 08 D0 F5 9C0:E6 09 A5 09 C9 80 90 ED 68 8D 36 C0 28 A9 09 20 9D0:F2 09 20 27 0A AD E8 C0 AD E0 C0 AD E2 C0 AD E4 9E0:C0 AD E6 C0 68 8D 31 C0 A9 00 20 2E 0A 68 8D 2D 9F0:C0 60 2C E0 C0 2C E3 C0 2C E6 C0 2C E4 C0 4A 90 A00:03 2C E5 C0 4A 48 AD 31 C0 29 7F 90 02 09 80 8D A10:31 C0 68 4A 90 03 2C E1 C0 4A B0 03 2C E2 C0 60 A20:2C ED C0 2C EE C0 60 2C E7 C0 2C E6 C0 60 A8 2C A30:ED C0 4C 39 0A 98 8D EF C0 98 4D EE C0 29 1F D0 A40:F4 2C EC C0 60 -- Neil Parker No cute ASCII art...no cute quote...no cute parker@corona.uoregon.edu disclaimer...no deposit, no return... parkern@jacobs.cs.orst.edu (This space intentionally left blank: )