home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff246.lzh / NoClick / NoClick.asm < prev    next >
Assembly Source File  |  1989-09-14  |  13KB  |  265 lines

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