ISCOVE%UTOROCI.bitnet@ugw.utcs.utoronto.ca (08/22/89)
These updates correct a rather subtle bug that was causing the
program occasionally to fail to silence one of the drives.
Version 3.4 also incorporates changes to the jump tables in
the ram copy of trackdisk (thanks to Werner Guenther for the
suggestion) so that the routines point back into
the ram copy. The result is that the fix ('fixbug' in the
source) to the raw read/write code will actually take effect.
Version 3.3 differs only in omitting the 'fixjumps' section.
Version 3.4 is to be used with care - there are advantages to
having code controlling disk i/o protected in rom.
begin 644 NoClick3.3
M```#\P`````````!``````````````!.```#Z0```$Y(YS\^+'@`!'P!1_D`0
M``$D2?D```#R3J[_B$'N`98B3$ZN_NPFP"!`9O1'Z__\0>X!I%'._^I.KO^"<
M2?D```$D80``IB!K`$:Q_`#X``!C``"00?D```#R<`!R`$/Y```!!$ZN_D1F*
M``!X)GD```$80_D```$$3J[^/B)K``J2_``8)!%822!1D,)V`#8(5D,@`W(!B
M3J[_.B)`Y$L@0B+84<O__"I`"&T`!P$%.WP,@!HX2?D```$D82XD:P!&E<+;W
MRDZN_X@G30!&3J[_@F$89PY.KO^()TT`1DZN_X)@[DS??/QP`$YU(EPF:0`V3
M(`E.=71R86-K9&ES:RYD979I8V4`````````````````````````````````*
M``````````````````````````````````````````/L````"``````````,#
D````$@```#P```!4````7@```&P```!R````M`````````/R'
``
end
size 396
begin 644 NoClick3.4
M```#\P`````````!``````````````!3```#Z0```%-(YS\^+'@`!'P!1_D`:
M``$V2?D```$$3J[_B$'N`98B3$ZN_NPFP"!`9O1'Z__\0>X!I%'._^I.KO^"!
M2?D```$V80``N"!K`$:Q_`#X``!C``"B0?D```$$<`!R`$/Y```!%DZN_D1FE
M``"*)GD```$J0_D```$63J[^/B)K``J2_``8)!%822!1D,)V`#8(5D,@`W(!8
M3J[_.B)`Y$L@0B+84<O__"8"EH`@0$'H"AQX%9>84<S__"I`"&T`!P$%.WP,I
M@!HX2?D```$V82XD:P!&E<+;RDZN_X@G30!&3J[_@F$89PY.KO^()TT`1DZN,
M_X)@[DS??/QP`$YU(EPF:0`V(`E.=71R86-K9&ES:RYD979I8V4`````````R
M`````````````````````````````````````````````````````````````
M``!.<0```^P````(``````````P````2````/````%0```!>````;````'(`@
+``#&`````````_((#
``
end
size 416
*************************************************************************
* *
* *
* Program Name: NoClick3.4 *
* *
* Version Date: 20 August 1989 *
* *
* Based on the prototype NoClick program posted by *
* Dan Babcock to PLINK in May 1989 *
* *
* With thanks to Werner Guenther for showing the use of *
* FindName to generate the trackdisk task list, and *
* pointing out the possibility of changing the code's *
* jump table. *
* *
* Copyright (c) 1989 - Norman Iscove iscove@utoroci (bitnet) *
* *
* *
* USAGE: Place in c: directory. Type 'NoClickxx' from CLI, *
* or include in Startup-sequence, preferably after FastMemFirst. *
* Safer not to invoke it at a point where disks are concurrently *
* active. *
* *
* FUNCTION: *
* *
* Intended to eliminate clicking of empty drives installed in *
* Amiga 500, 1000 or 2x00 computers, provided the particular *
* drive models respond quietly to negative stepping of the *
* heads past track 0. The program checks for and sets *
* additional floppy drives if also present. Aborts harmlessly *
* if a second execution is attempted. Also repairs a known *
* bug in the trackdisk.device code involving raw read and *
* write calls. *
* *
* Works by copying the trackdisk.device code from rom into *
* ram. A single byte is modified so that the drive heads *
* will be stepped (silently) in a negative rather than *
* positive direction during the regular system checks for a *
* disk change. One word is also altered to repair the raw *
* read/write bug. After creating the copy and fixing it, the *
* program changes the system vectors in each drive's task *
* structure to point to the ram copy. *
* *
* *
* ENTRY REGISTERS: none assumed *
* *
* EXIT REGISTERS: d2-d7/a2-a6 preserved in entry condition *
* d0 = 0 *
* *
* ASSUMPTIONS: *
* *
* Private structure of the trackdisk.device code in rom is *
* not documented. The offsets of the pointers to start and *
* end of the code, and the offsets of the bytes to be altered *
* are all determined by inspection of the code in the 1.3 rom. *
* *
* CAVEAT: *
* *
* Has been tested and works on a B2000 running KS/WB 1.3 V34.2 *
* with two internal floppy drives, 2 MB expansion memory (2058) *
* and no hard drive. *
* *
*************************************************************************
INCLUDE 'execlib'
*-----------------------------------------------------------------------*
* Save the incoming registers *
*-----------------------------------------------------------------------*
main: movem.l d2-d7/a2-a6,-(sp)
movea.l 4,a6 ;a6 = execbase
*-----------------------------------------------------------------------*
* Make a list of all the trackdisk tasks *
*-----------------------------------------------------------------------*
tasklist:
moveq #1,d6 ;d6 = counter (search through two lists)
lea tasks,a3 ;a3 = pointer to my list of td tasks
lea tdname,a4 ;a4 = pointer to "trackdisk.device"
jsr _LVODisable(a6) ;disable interrupts & task switching
lea 406(a6),a0 ;a0 = start of taskready queue
nexttask:
move.l a4,a1 ;a1 = pointer to "trackdisk.device"
jsr _LVOFindName(a6) ;find the next task with this name
move.l d0,(a3)+ ;save task pointer in my list, sets cond.
movea.l d0,a0 ;a0 = start for next FindName search
bne.s nexttask ;check for next task if not zero
waitqueue:
lea -4(a3),a3 ;correct pointer
lea 420(a6),a0 ;a0 = start of taskwait queue
dbf d6,nexttask
jsr _LVOEnable(a6)
*-----------------------------------------------------------------------*
* Abort if already installed *
*-----------------------------------------------------------------------*
check:
lea tasks,a4 ;1st entry is the one that was ready
bsr nextset
move.l $46(a3),a0 ;a0 = finalPC, td code that task exits to
cmp.l #$f80000,a0 ;exit if already pointing to ram
bls exit
*-----------------------------------------------------------------------*
* Find trackdisk.device in rom, get start, end, size *
*-----------------------------------------------------------------------*
findcode:
lea tdname,a0
moveq #0,d0 ;unit df0:
moveq #0,d1 ;flags
lea iorequest,a1
jsr _LVOOpenDevice(a6) ;open the trackdisk.device
bne exit
move.l iodevice,a3 ;a3 = trackdisk library base address C03AE4
lea iorequest,a1
jsr _LVOCloseDevice(a6)
move.l $0A(a3),a1 ;ln_name(a3) (C03AEE) points to string
; 'trackdisk.device' at FE957E
sub.w #$18,a1 ;a1 = FE9566
move.l (a1),d2 ;d2 = start of trackdisk routine in rom,
; FE9564.
add.w #4,a1 ;a1 = FE956A
move.l (a1),a0 ;a0 = end of trackdisk routine in rom,
; FEB05C
suba d2,a0 ;a0 = signed length of trackdisk routine
moveq #0,d3
move.w a0,d3 ;d3 = unsigned length (bytes) of td routine
addq #3,d3 ;ensure all copied if not multiple of 4
*-----------------------------------------------------------------------*
* Allocate some ram and copy to it *
*-----------------------------------------------------------------------*
copy:
move.l d3,d0 ;d0 = number of bytes
moveq #1,d1 ;d1 = MEMF_PUBLIC, fastmem if available
jsr _LVOAllocMem(a6)
move.l d0,a1 ;d0,a1 = location of reserved block in ram
lsr.w #2,d3 ;d3 = number of longs to copy
move.l d2,a0 ;a0 = start of rom routine
cploop:
move.l (a0)+,(a1)+ ;copy rom routine to ram
dbra d3,cploop
*-----------------------------------------------------------------------*
* Fix the copy's jump table so that the code patched by fixbug *
* (below) is actually used (thanks to W. Guenther) *
*-----------------------------------------------------------------------*
fixjumps:
move.l d2,d3 ;d3 = start of rom routine
sub.l d0,d3 ;- start of ram copy = offset
movea.l d0,a0 ;a0 = start of ram copy
lea $a1c(a0),a0 ;a0 = pointer to copy's jump table
moveq #21,d4 ;d4 = 22 functions to patch
fj1:
sub.l d3,(a0)+ ;correct the address of each function
dbf d4,fj1
*-----------------------------------------------------------------------*
* Stop the clicks *
*-----------------------------------------------------------------------*
rmvclick:
move.l d0,a5 ;a5 = location of copy
bchg #7,$0105(a5) ;fix the critical byte
*-----------------------------------------------------------------------*
* Repair trackdisk read/write bug originally at $feaf9c (1.3) *
*-----------------------------------------------------------------------*
fixbug:
move.w #$0C80,$1A38(a5) ;fix to cmp.l #$8000,d0
*-----------------------------------------------------------------------*
* Fix each task's exit vector to point to ram version *
*-----------------------------------------------------------------------*
fixptrs:
lea tasks,a4 ;a4 = address of task list
bsr.s nextset
move.l $46(a3),a2 ;a2 = finalPC, td code that task exits to
sub.l d2,a2 ;a2 = offset of code from start (d2) in rom
add.l a2,a5 ;a5 = corresponding address in ram copy
jsr _LVODisable(a6)
move.l a5,$46(a3) ;replace corrected finalPC pointer
jsr _LVOEnable(a6)
fixloop:
bsr.s nextset
beq.s exit
jsr _LVODisable(a6)
move.l a5,$46(a3) ;replace corrected finalPC pointer
jsr _LVOEnable(a6)
bra.s fixloop
*-----------------------------------------------------------------------*
* Done *
*-----------------------------------------------------------------------*
exit:
movem.l (sp)+,d2-d7/a2-a6 ;restore the incoming registers
moveq #0,d0 ;tell system no error
rts
;*** subroutines
*-----------------------------------------------------------------------*
* Find task's exit pointer to trackdisk code *
* *
* Exit registers: a1 = address of task structure *
* a3 = tc_SPReg *
* d0 = a1 *
* z flag = 0 if no more tasks *
*-----------------------------------------------------------------------*
nextset:
move.l (a4)+,a1 ;a1 = address of this task structure
move.l $36(a1),a3 ;a3 = tc_SPReg for this task
move.l a1,d0 ;test for a1=0
rts
;*** data
tdname:
dc.b 'trackdisk.device',0
EVEN
iorequest:
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
iodevice:
dc.b 0,0,0,0
iounit:
dc.b 0,0,0,0,0,0,0,0
EVEN
tasks:
ds.l 4 ;room for 4 drives
dc.l 0 ;end of list marker
END