home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff241.lzh / NoClick / NoClick.asm < prev    next >
Assembly Source File  |  1989-08-27  |  12KB  |  255 lines

  1. *************************************************************************
  2. *                                                                       *
  3. *                                                                       *
  4. *       Program Name:   NoClick3.4                                      *
  5. *                                                                       *
  6. *       Version Date:   20 August 1989                                  *
  7. *                                                                       *
  8. *       Based on the prototype NoClick program posted by                *
  9. *       Dan Babcock to PLINK in May 1989                                *
  10. *                                                                       *
  11. *       With thanks to Werner Guenther for showing the use of           *
  12. *       FindName to generate the trackdisk task list, and               *
  13. *       pointing out the possibility of changing the code's             *
  14. *       jump table.                                                     *
  15. *                                                                       *
  16. *       Copyright (c) 1989 - Norman Iscove  iscove@utoroci (bitnet)     *
  17. *                                                                       *
  18. *                                                                       *
  19. *       USAGE:  Place in c: directory.  Type 'NoClickxx' from CLI,      *
  20. *       or include in Startup-sequence, preferably after FastMemFirst.  *
  21. *       Safer not to invoke it at a point where disks are concurrently  *
  22. *       active.                                                         *
  23. *                                                                       *
  24. *       FUNCTION:                                                       *
  25. *                                                                       *
  26. *       Intended to eliminate clicking of empty drives installed in     *
  27. *       Amiga 500, 1000 or 2x00 computers, provided the particular      *
  28. *       drive models respond quietly to negative stepping of the        *
  29. *       heads past track 0.  The program checks for and sets            *
  30. *       additional floppy drives if also present.  Aborts harmlessly    *
  31. *       if a second execution is attempted.  Also repairs a known       *
  32. *       bug in the trackdisk.device code involving raw read and         *
  33. *       write calls.                                                    *
  34. *                                                                       *
  35. *       Works by copying the trackdisk.device code from rom into        *
  36. *       ram.  A single byte is modified so that the drive heads         *
  37. *       will be stepped (silently) in a negative rather than            *
  38. *       positive direction during the regular system checks for a       *
  39. *       disk change.  One word is also altered to repair the raw        *
  40. *       read/write bug.  After creating the copy and fixing it, the     *
  41. *       program changes the system vectors in each drive's task         *
  42. *       structure to point to the ram copy.                             *
  43. *                                                                       *
  44. *                                                                       *
  45. *       ENTRY REGISTERS:  none assumed                                  *
  46. *                                                                       *
  47. *       EXIT  REGISTERS:  d2-d7/a2-a6 preserved in entry condition      *
  48. *                         d0 = 0                                        *
  49. *                                                                       *
  50. *       ASSUMPTIONS:                                                    *
  51. *                                                                       *
  52. *       Private structure of the trackdisk.device code in rom is        *
  53. *       not documented.  The offsets of the pointers to start and       *
  54. *       end of the code, and the offsets of the bytes to be altered     *
  55. *       are all determined by inspection of the code in the 1.3 rom.    *
  56. *                                                                       *
  57. *       CAVEAT:                                                         *
  58. *                                                                       *
  59. *       Has been tested and works on a B2000 running KS/WB 1.3 V34.2    *
  60. *       with two internal floppy drives, 2 MB expansion memory (2058)   *
  61. *       and no hard drive.                                              *
  62. *                                                                       *
  63. *************************************************************************
  64.  
  65.  
  66.  
  67.  
  68.         INCLUDE 'execlib'
  69.  
  70. *-----------------------------------------------------------------------*
  71. *               Save the incoming registers                             *
  72. *-----------------------------------------------------------------------*
  73. main:   movem.l d2-d7/a2-a6,-(sp)
  74.         movea.l 4,a6            ;a6 = execbase
  75.  
  76.  
  77. *-----------------------------------------------------------------------*
  78. *       Make a list of all the trackdisk tasks                          *
  79. *-----------------------------------------------------------------------*
  80. tasklist:
  81.         moveq   #1,d6           ;d6 = counter (search through two lists)
  82.         lea     tasks,a3        ;a3 = pointer to my list of td tasks
  83.         lea     tdname,a4       ;a4 = pointer to "trackdisk.device"
  84.         jsr     _LVODisable(a6) ;disable interrupts & task switching
  85.         lea     406(a6),a0      ;a0 = start of taskready queue
  86. nexttask:
  87.         move.l  a4,a1           ;a1 = pointer to "trackdisk.device"
  88.         jsr     _LVOFindName(a6) ;find the next task with this name
  89.         move.l  d0,(a3)+        ;save task pointer in my list, sets cond.
  90.         movea.l d0,a0           ;a0 = start for next FindName search
  91.         bne.s   nexttask        ;check for next task if not zero
  92. waitqueue:
  93.         lea     -4(a3),a3       ;correct pointer
  94.         lea     420(a6),a0      ;a0 = start of taskwait queue
  95.         dbf     d6,nexttask
  96.         jsr     _LVOEnable(a6)
  97.  
  98.  
  99. *-----------------------------------------------------------------------*
  100. *               Abort if already installed                              *
  101. *-----------------------------------------------------------------------*
  102. check:
  103.         lea     tasks,a4        ;1st entry is the one that was ready
  104.         bsr     nextset
  105.         move.l  $46(a3),a0      ;a0 = finalPC, td code that task exits to
  106.         cmp.l   #$f80000,a0     ;exit if already pointing to ram
  107.         bls     exit
  108.  
  109.  
  110. *-----------------------------------------------------------------------*
  111. *       Find trackdisk.device in rom, get start, end, size              *
  112. *-----------------------------------------------------------------------*
  113. findcode:
  114.  
  115.         lea     tdname,a0
  116.         moveq   #0,d0           ;unit df0:
  117.         moveq   #0,d1           ;flags
  118.         lea     iorequest,a1
  119.         jsr     _LVOOpenDevice(a6) ;open the trackdisk.device
  120.         bne     exit
  121.         move.l  iodevice,a3     ;a3 = trackdisk library base address C03AE4
  122.         lea     iorequest,a1
  123.         jsr     _LVOCloseDevice(a6)
  124.         move.l  $0A(a3),a1      ;ln_name(a3) (C03AEE) points to string
  125.                                 ; 'trackdisk.device' at FE957E
  126.         sub.w   #$18,a1         ;a1 = FE9566
  127.         move.l  (a1),d2         ;d2 = start of trackdisk routine in rom,
  128.                                 ;     FE9564.
  129.         add.w   #4,a1           ;a1 = FE956A
  130.         move.l  (a1),a0         ;a0 = end of trackdisk routine in rom,
  131.                                 ;     FEB05C
  132.         suba    d2,a0           ;a0 = signed length of trackdisk routine
  133.         moveq   #0,d3
  134.         move.w  a0,d3           ;d3 = unsigned length (bytes) of td routine
  135.         addq    #3,d3           ;ensure all copied if not multiple of 4
  136.  
  137.  
  138. *-----------------------------------------------------------------------*
  139. *              Allocate some ram and copy to it                         *
  140. *-----------------------------------------------------------------------*
  141. copy:
  142.         move.l  d3,d0           ;d0 = number of bytes
  143.         moveq   #1,d1           ;d1 = MEMF_PUBLIC, fastmem if available
  144.         jsr     _LVOAllocMem(a6)
  145.         move.l  d0,a1           ;d0,a1 = location of reserved block in ram
  146.         lsr.w   #2,d3           ;d3 = number of longs to copy
  147.         move.l  d2,a0           ;a0 = start of rom routine
  148.  
  149. cploop:
  150.         move.l  (a0)+,(a1)+     ;copy rom routine to ram
  151.         dbra    d3,cploop
  152.  
  153.  
  154. *-----------------------------------------------------------------------*
  155. *       Fix the copy's jump table so that the code patched by fixbug    *
  156. *        (below) is actually used (thanks to W. Guenther)               *
  157. *-----------------------------------------------------------------------*
  158. fixjumps:
  159.         move.l  d2,d3          ;d3 = start of rom routine
  160.         sub.l   d0,d3          ;- start of ram copy = offset
  161.         movea.l d0,a0          ;a0 = start of ram copy
  162.         lea     $a1c(a0),a0    ;a0 = pointer to copy's jump table
  163.         moveq   #21,d4         ;d4 = 22 functions to patch
  164. fj1:
  165.         sub.l   d3,(a0)+       ;correct the address of each function
  166.         dbf     d4,fj1
  167.  
  168.  
  169. *-----------------------------------------------------------------------*
  170. *                   Stop the clicks                                     *
  171. *-----------------------------------------------------------------------*
  172. rmvclick:
  173.         move.l  d0,a5           ;a5 = location of copy
  174.         bchg    #7,$0105(a5)    ;fix the critical byte
  175.  
  176.  
  177. *-----------------------------------------------------------------------*
  178. *       Repair trackdisk read/write bug originally at $feaf9c (1.3)     *
  179. *-----------------------------------------------------------------------*
  180. fixbug:
  181.         move.w  #$0C80,$1A38(a5) ;fix to cmp.l #$8000,d0
  182.  
  183.  
  184. *-----------------------------------------------------------------------*
  185. *       Fix each task's exit vector to point to ram version             *
  186. *-----------------------------------------------------------------------*
  187. fixptrs:
  188.         lea     tasks,a4        ;a4 = address of task list
  189.         bsr.s   nextset
  190.         move.l  $46(a3),a2      ;a2 = finalPC, td code that task exits to
  191.         sub.l   d2,a2           ;a2 = offset of code from start (d2) in rom
  192.         add.l   a2,a5           ;a5 = corresponding address in ram copy
  193.  
  194.         jsr     _LVODisable(a6)
  195.         move.l  a5,$46(a3)      ;replace corrected finalPC pointer
  196.         jsr     _LVOEnable(a6)
  197.  
  198. fixloop:
  199.         bsr.s   nextset
  200.         beq.s   exit
  201.         jsr     _LVODisable(a6)
  202.         move.l  a5,$46(a3)      ;replace corrected finalPC pointer
  203.         jsr     _LVOEnable(a6)
  204.         bra.s   fixloop
  205.  
  206.  
  207. *-----------------------------------------------------------------------*
  208. *                       Done                                            *
  209. *-----------------------------------------------------------------------*
  210. exit:
  211.         movem.l (sp)+,d2-d7/a2-a6 ;restore the incoming registers
  212.         moveq   #0,d0             ;tell system no error
  213.         rts
  214.  
  215.  
  216.  
  217.  
  218. ;*** subroutines
  219.  
  220. *-----------------------------------------------------------------------*
  221. *       Find task's exit pointer to trackdisk code                      *
  222. *                                                                       *
  223. *       Exit registers:  a1 = address of task structure                 *
  224. *                        a3 = tc_SPReg                                  *
  225. *                        d0 = a1                                        *
  226. *                        z flag = 0 if no more tasks                    *
  227. *-----------------------------------------------------------------------*
  228. nextset:
  229.         move.l  (a4)+,a1        ;a1 = address of this task structure
  230.         move.l  $36(a1),a3      ;a3 = tc_SPReg for this task
  231.         move.l  a1,d0           ;test for a1=0
  232.         rts
  233.  
  234.  
  235. ;*** data
  236.  
  237.  
  238. tdname:
  239.         dc.b    'trackdisk.device',0
  240.         EVEN
  241.  
  242. iorequest:
  243.         dc.b    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  244. iodevice:
  245.         dc.b    0,0,0,0
  246. iounit:
  247.         dc.b    0,0,0,0,0,0,0,0
  248.         EVEN
  249.  
  250. tasks:
  251.     ds.l    4   ;room for 4 drives
  252.     dc.l    0   ;end of list marker
  253.  
  254.         END
  255.