217 lines
7.9 KiB
Plaintext
217 lines
7.9 KiB
Plaintext
|
|
||
|
Attention Game Vendors!
|
||
|
by Bryce Nesbitt
|
||
|
* Copyright 1988 Commodore-Amiga, Inc.
|
||
|
* This information is provided "as is"; no warranties are made. All
|
||
|
* use is at your own risk. No liability or responsibility is assumed.
|
||
|
* Permission granted to reproduce, provided this notice remains.
|
||
|
|
||
|
|
||
|
There are some very nice games for the Amiga that ignore the Operating System
|
||
|
and take over the machine. This practice is discouraged, but allowable.
|
||
|
Some of these games use the floppy disk hardware in an incorrect manner.
|
||
|
Such misuse is *NOT ACCEPTABLE*.
|
||
|
|
||
|
Worse yet, some books by major publishers have advocated incorrect use of the
|
||
|
disk hardware. For the benefit of software vendors, Commodore, dealers,
|
||
|
customers and the Amiga, this must stop.
|
||
|
|
||
|
|
||
|
Commodore uses floppy disk drives manufactured by several different vendors.
|
||
|
These vendors often upgrade or modernize their disk drive lines, usually
|
||
|
making the older drive models unavailable. For this reason, it is impossible
|
||
|
for a developer to test with all possible drive types. In order to work
|
||
|
across this broad spectrum of drives, certain rules must be adhered to.
|
||
|
|
||
|
To make compliance simple, here is complete and ready to use source code.
|
||
|
Three functions are provided to correctly implement the three most critical
|
||
|
drive operations. This code may be dropped directly into an existing loader
|
||
|
with no hassle, fuss or mess.
|
||
|
|
||
|
MOTORON ;Turn the motor on, and properly wait for the
|
||
|
; drive to reach full speed.
|
||
|
MOTOROFF ;Turn off and deselect all drives
|
||
|
STEPHEAD ;Step the head, and properly wait for the 3.0
|
||
|
; millisecond step delay on any speed CPU.
|
||
|
TEST ;Test program showing use of above functions.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
* opt l+,c+,w-
|
||
|
;
|
||
|
; Low-level "take over the machine" disk drive functions.
|
||
|
;
|
||
|
; *** FOR USE ONLY WHEN YOU HAVE TAKEN OVER THE MACHINE ***
|
||
|
;
|
||
|
; Written by Bryce Nesbitt, Commodore-Amiga, Inc.
|
||
|
; No copyright claimed.
|
||
|
;
|
||
|
;****** Externally visible functions
|
||
|
|
||
|
XDEF MOTORON ;Turn drive 0 motor ON & wait for READY.
|
||
|
XDEF MOTOROFF ;Turn off all drive motors.
|
||
|
XDEF STEPHEADS ;Step the drive head & wait properly.
|
||
|
|
||
|
|
||
|
;****** Hard-coded I/O register locations
|
||
|
;
|
||
|
CIAA_PRA EQU $BFE001 ;Port "A" on CIA "A".
|
||
|
CIAB_PRB EQU $BFD100 ;Port "B" on CIA "B".
|
||
|
CIAA_TALO EQU $BFE401 ;Timer A low
|
||
|
CIAA_TAHI EQU $BFE501 ;Timer A high
|
||
|
CIAA_ICR EQU $BFED01 ;Interrupt control register
|
||
|
CIAA_CRA EQU $BFEE01 ;Timer A control
|
||
|
|
||
|
|
||
|
;;;;;;; MOTORON ;;;;;;;
|
||
|
;
|
||
|
; Turn off the motors of drives 1-3, then turn on drive 0.
|
||
|
; This function returns when drive 0 is ON and spinning at full speed.
|
||
|
; If drive 0 is already spinning, this function returns very quickly.
|
||
|
;
|
||
|
; The direction and side lines are untouched.
|
||
|
;
|
||
|
MOTORON:
|
||
|
or.b #$F9,CIAB_PRB ;Set motor line to off, deselect
|
||
|
;all drives, and unset STEP line.
|
||
|
and.b #$8F,CIAB_PRB ;Select drives 1-3 so they see the
|
||
|
;motor off setting
|
||
|
or.b #$70,CIAB_PRB ;Deselect drives 1-3
|
||
|
|
||
|
and.b #$7F,CIAB_PRB ;Set motor ON. This must be done
|
||
|
;*BEFORE* selecting drives!
|
||
|
and.b #$F7,CIAB_PRB ;Select drive zero. The drive will
|
||
|
;"remember" the motor setting
|
||
|
;if the motor was already on,
|
||
|
;nothing happens
|
||
|
|
||
|
motor_wait btst.b #5,CIAA_PRA ;Check READY line
|
||
|
bne.s motor_wait ;Busy-wait until drive is ready
|
||
|
rts
|
||
|
|
||
|
|
||
|
|
||
|
;;;;;;; MOTOROFF ;;;;;;;
|
||
|
;
|
||
|
; Turn OFF all drive motors.
|
||
|
;
|
||
|
;
|
||
|
MOTOROFF:
|
||
|
or.b #$F8,CIAB_PRB ;Deselect all drives and set motor
|
||
|
;line to OFF
|
||
|
and.b #$87,CIAB_PRB ;Select all drives so they see the
|
||
|
;new motor setting.
|
||
|
or.b #$F8,CIAB_PRB ;Deselect all drives
|
||
|
rts
|
||
|
|
||
|
|
||
|
|
||
|
;;;;;;; STEPHEADS ;;;;;;;
|
||
|
;
|
||
|
; D0 must contain zero to step te heads inward, and -1 to step the
|
||
|
; heads toward the outside of the disk.
|
||
|
;
|
||
|
; The heads will step in the direction indicated. After stepping this
|
||
|
; function will do a processor-independant wait for the required
|
||
|
; 3.0 milisecond step delay. Note that some disk drives do not
|
||
|
; require a full 3.0 miliseconds, but others do. It is not safe
|
||
|
; to release a commercial product with a shorter step delay.
|
||
|
;
|
||
|
; Note that the STEP line must always start out high, be pulsed
|
||
|
; low, then return high.
|
||
|
;
|
||
|
; Using this timer chip method and interrupts, it is easy to create
|
||
|
; a loader that keeps on loading while your title music plays.
|
||
|
;
|
||
|
STEPHEADS:
|
||
|
and.b #2,d0 ;Remove garbage bits
|
||
|
or.b d0,CIAB_PRB ;Set direction register FIRST
|
||
|
|
||
|
;(Try to be a little bit slow about pulsing the step line)
|
||
|
bclr.b #0,CIAB_PRB ;Pulse STEP line low
|
||
|
bset.b #0,CIAB_PRB ;Return STEP high
|
||
|
;
|
||
|
; Use the timer chip to waste 3.0 miliseconds
|
||
|
;
|
||
|
; The base Amiga crytal frequecies are:
|
||
|
; NTSC 28.318181 Mhz
|
||
|
; PAL 28.37516 Mhz
|
||
|
; The two 16 bit timers on the 8520 chips each count down at 1/10
|
||
|
; the CPU clock, or .715909 Mhz. That works out to 1.3968255
|
||
|
; microseconds per count. Under PAL the countdown is a hair
|
||
|
; slower, .709379 Mhz.
|
||
|
;
|
||
|
; To wait 1/100 second would require waiting 10,000 microseconds.
|
||
|
; The timer register would be set to (10,000 / 1.3968255 =
|
||
|
; 7159).
|
||
|
;
|
||
|
; To wait 3 miliseconds would require waiting 3000 microsecsonds.
|
||
|
; The register would be set to (3000 / 1.3968255 = 2148).
|
||
|
;
|
||
|
; See the hardware manual for more information on the 8520 chips.
|
||
|
;
|
||
|
|
||
|
|
||
|
;----Setup (really only needs to be done once)
|
||
|
move.w #$7fff,$dff09a ;Kill all custom chip interrupts
|
||
|
;----This sets timer A to one-shot mode.
|
||
|
move.b CIAA_CRA,d0 ;Set control register A
|
||
|
and.b #%11000000,d0 ;Don't trash the 60/50Hz flag
|
||
|
or.b #%00001000,d0 ;or serial direction bits
|
||
|
move.b d0,CIAA_CRA
|
||
|
move.b #%01111111,CIAA_ICR ;Clear all 8520 interrupts
|
||
|
;----end setup
|
||
|
|
||
|
;----Set time (low byte THEN high byte)
|
||
|
move.b #(2148&255),CIAA_TALO ;Mask off low part
|
||
|
move.b #(2148>>8),CIAA_TAHI ;Shift high part 8 bits
|
||
|
|
||
|
;----Wait for the timer to count down
|
||
|
busy_wait: btst.b #0,CIAA_ICR ;Wait for timer expired flag
|
||
|
beq.s busy_wait
|
||
|
rts
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
;;;;;;; TEST ;;;;;;;
|
||
|
;
|
||
|
; Quick, nasty test program
|
||
|
;
|
||
|
|
||
|
* INCDIR "inc:"
|
||
|
INCLUDE "exec/types.i"
|
||
|
INCLUDE "exec/ables.i"
|
||
|
|
||
|
XREF _LVODisable
|
||
|
|
||
|
|
||
|
TEST: move.l 4,a6
|
||
|
jsr _LVODisable(a6)
|
||
|
bsr MOTORON
|
||
|
|
||
|
moveq #10,d3 ;Ten full seeks before end
|
||
|
fullseek:
|
||
|
bset.b #1,CIAB_PRB ;Set direction to OUTWARD
|
||
|
moveq #80-1,d2 ;80 tracks
|
||
|
test4 bsr STEPHEADS
|
||
|
btst.b #4,CIAA_PRA ;Check track 00 sensor
|
||
|
dbeq d2,test4 ;Decrement and branch until
|
||
|
;EQual or count exceeded
|
||
|
moveq #80-1,d2
|
||
|
bclr.b #1,CIAB_PRB ;Set direction to INWARD
|
||
|
test3 bsr STEPHEADS
|
||
|
dbra d2,test3
|
||
|
|
||
|
dbra d3,fullseek
|
||
|
|
||
|
|
||
|
bsr MOTOROFF
|
||
|
fish bra.s fish
|
||
|
;
|
||
|
; We have killed the operating system, so this tester never exits
|
||
|
;
|
||
|
|