home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 6 / Sonderheft_6-96.iso / pd / disktools / softrack / source / install.s < prev    next >
Text File  |  1996-11-03  |  7KB  |  301 lines

  1.  
  2. ; Install.s
  3. ; It istalls two routines at the DoIO and SendIO vectors.
  4. ; To be Assembled with SAS/C 6.50 Assembler and linked with slink
  5. ; to produce SofTrack:  1> asm Install.s 
  6. ; Written by Kamran Karimi.
  7.  
  8.  
  9.  INCLUDE "exec/memory.i"
  10.  INCLUDE "exec/ports.i"
  11.  INCLUDE "exec/io.i"
  12.  INCLUDE "devices/trackdisk.i"
  13.  INCLUDE "dos/dos.i"
  14.  
  15. ExecBase equ 4
  16.  
  17.  ;EXEC library 
  18. PutMsg      equ -366
  19. Allocmem    equ -198
  20. FreeMem     equ -210
  21. Forbid      equ -132
  22. Permit      equ -138
  23. SetFunction equ -420
  24.  
  25. ; DoIO and SendIO offsets point to the actual jump address, not the 'jmp'
  26. ; instruction before them. the jmp for DoIO and SendIO are at offset -456 and -462
  27. ; respectvely. As you can see, the 'jmp' opcode has two bytes.
  28. DoIO     equ -454
  29. SendIO   equ -460
  30.  
  31. ; the main proram will prepare the message port and the routines in this
  32. ; file will send information to it
  33.  XREF _Port
  34.  
  35. ; these variables are initialized here but used in the main program
  36.  XREF _ReservedDoIO
  37.  XREF _ReservedSendIO
  38.  XREF _SaveDoIO
  39.  XREF _SaveSendIO
  40.  XREF _SizeOfIO
  41.  
  42.  
  43.  SECTION inst,CODE
  44.  
  45.  XDEF _Install
  46.  
  47. _Install:
  48.  
  49. ; subroutines in Amiga can use registers d0, d1, a0 and a1 as scratch.
  50. ; all other registers should remain intact, so we save a6, as we will
  51. ; over write it here
  52.  
  53.  move.l  a6,-(a7)
  54.  
  55. ; initialize message port parameters before they are copied 
  56.  
  57.  lea     Message,a1
  58.  move.b  #NT_MESSAGE,LN_TYPE(a1)      ;message type
  59.  move.w  #MN_SIZE+8,MN_LENGTH(a1)      ;message length
  60.  
  61. ; save the original vector addresses.
  62.  
  63.  move.l  ExecBase,a6
  64.  move.l  DoIO(a6),_SaveDoIO
  65.  move.l  SendIO(a6),_SaveSendIO
  66.  
  67. ; the two routines for DoIO and SendIO are identical, so we copy the 
  68. ; code provided here in two newly allocated places in memory.
  69. ; each one will have its own structures and the ability to send messages
  70. ; to the main program's port.
  71. ;
  72. ; NOTE: Amiga does not support run-time relocation of code. 
  73. ; to be able to move a piece of code after it is loaded in memory,
  74. ; all the addressings in it should be PC relative.
  75.  
  76.  move.l  ExecBase,a6
  77.  move.l  _Port,Port 
  78.  move.l  #EndeIO-BeginIO,d0
  79.  move.l  d0,_SizeOfIO
  80.  move.l  #MEMF_PUBLIC,d1
  81.  jsr     Allocmem(a6) ; allocate memory for DoIO
  82.  move.l  d0,_ReservedDoIO
  83.  beq     End_Main ; no mem?
  84.  move.l  _SizeOfIO,d0
  85.  move.l  #MEMF_PUBLIC,d1
  86.  jsr     Allocmem(a6) ; another for SendIO
  87.  move.l  d0,_ReservedSendIO
  88.  bne     MemAllocated
  89.  move.l  _ReservedDoIO,a1 ; if failed, free the DoIO memory
  90.  move.l  _SizeOfIO,d0
  91.  jsr     FreeMem(a6)
  92.  bra     End_Main
  93.  
  94. ; memory allocated, now copy the code provided under the BeginIO label
  95. ; to these places.
  96.  
  97. MemAllocated: 
  98.  
  99. ; we need the original vector address, so that we can activate it after 
  100. ; the information have been sent to the main program
  101.  
  102.  move.l  DoIO(a6),_SaveIO  
  103.  move.l  #BeginIO,a0 ; source
  104.  move.l  _ReservedDoIO,a1 ;destination
  105.  move.l  _SizeOfIO,d0 ; size in bytes
  106.  divu    #2,d0 ; a word (2 bytes) at a time
  107.  subi.l  #1,d0 ; 'dbra' stops when the counter in d0 reaches -1!
  108. lop1:
  109.  move.w  (a0)+,(a1)+ ; do the copy
  110.  dbra    d0,lop1 ; 'dbra' done?
  111.  
  112.  move.l  ExecBase,a1
  113.  move.l  #DoIO-2,a0
  114.  move.l  _ReservedDoIO,d0
  115.  jsr     SetFunction(a6) ; DoIO vector is changed
  116.  
  117. ; the above operations are repeated for SendIO
  118.  
  119.  move.l  SendIO(a6),_SaveIO
  120.  move.l  #BeginIO,a0
  121.  move.l  _ReservedSendIO,a1
  122.  move.l  _SizeOfIO,d0
  123.  divu    #2,d0
  124.  subi.l  #1,d0
  125. lop2:
  126.  move.w  (a0)+,(a1)+
  127.  dbra    d0,lop2
  128.  
  129.  move.l  ExecBase,a1
  130.  move.l  #SendIO-2,a0
  131.  move.l  _ReservedSendIO,d0
  132.  jsr     SetFunction(a6)
  133.  
  134.  moveq   #RETURN_OK,d0 ; we succeded
  135.  bra     Payan
  136. End_Main:
  137.  move.l  #RETURN_FAIL,d0 ; we failed
  138. Payan:   
  139.  move.l (a7)+,a6
  140.  rts
  141.  
  142.  
  143. ; this is the common routine for getting disk operation information.
  144. ; all addresses are relative to program counter, to enable it to be moved
  145. ; around in memory
  146.  
  147. BeginIO:
  148.  
  149. ; save the original register contents. we should give them intact to
  150. ; the original DoIO ro SendIO routine.
  151. ;
  152. ; the address of a ioRequest is in a1. this contains all the information
  153. ; about the requested action.
  154.  
  155.  movem.l d0-d4/a0-a4/a6,-(a7)
  156.  
  157. ; first we see if the request is for 'trackdisk.device'
  158.  
  159.  move.l  IO_DEVICE(a1),a2 ; pointer to device structure is in a2 
  160.  move.l  LN_NAME(a2),a3
  161.  move.l  #15,d0
  162.  lea     TrackName(pc),a4
  163. lop22:
  164.  cmpm.b  (a3)+,(a4)+
  165.  bne     Endit ; not for 'trackdisk.device'. just call the original routine 
  166.  dbra    d0,lop22
  167.  
  168. ; prepare the message structure to be filled with information
  169.  
  170.  lea     Message(pc),a2
  171.  move.l  IO_UNIT(a1),a4 ; pointer to a Unit structure is in a4
  172.  
  173. ; this offset ($41) is not documented! (see SofTrack.doc)
  174. ; it seems that this code breaks under 2.0 and above! (i.e. the information
  175. ; for all drives is shown in the df1 space.
  176.  
  177.  move.b  $41(a4),d0
  178.  
  179. ; is it for DF0?
  180.  
  181.  btst    #3,d0
  182.  bne     df1
  183.  move.b  #0,20(a2)
  184.  bra     Cont
  185. df1:
  186.  btst    #4,d0 ;maybe df1?
  187.  bne     df2
  188.  move.b  #1,20(a2)
  189.  bra     Cont
  190. df2:
  191.  btst    #5,d0 ;or df2 ?
  192.  bne     df3
  193.  move.b  #2,20(a2)
  194.  bra     Cont
  195. df3:
  196.  btst    #6,d0 ; or df3 ?
  197.  bne     Endit ; none of them? just call the original routine.
  198.  move.b  #3,20(a2)
  199. Cont:
  200.  move.w  IO_COMMAND(a1),d0         ;d0 has command
  201.  bclr    #TDB_EXTCOM,d0 ; being an extended command is not interesting to us
  202.  
  203. ; now find out the command (read, write, format... )
  204.  
  205.  cmpi.w  #CMD_READ,d0
  206.  bne     NotR
  207.  move.b  #'R',26(a2)
  208.  bra     TrackChange
  209. NotR:
  210.  cmpi.w  #TD_SEEK,d0
  211.  bne     NotS
  212.  move.b  #'S',26(a2)
  213.  bra     TrackChange
  214. NotS:
  215.  cmpi.w  #TD_RAWREAD,d0
  216.  bne     NotRawR
  217.  move.b  #'R',26(a2)
  218.  bra     TrackChange
  219. NotRawR:
  220.  cmpi.w  #CMD_WRITE,d0
  221.  bne     NotW
  222.  move.b  #'W',26(a2)
  223.  bra     TrackChange
  224. NotW:
  225.  cmpi.w  #TD_FORMAT,d0
  226.  bne     NotF
  227.  move.b  #'F',26(a2)
  228.  bra     TrackChange
  229. NotF:
  230.  cmpi.w  #TD_RAWWRITE,d0
  231.  bne     Endit
  232.  move.b  #'W',26(a2)
  233.  
  234. TrackChange:
  235.  moveq   #0,d4  
  236.  move.l  #16,d2 ; used for shifts. the result of divu are 16 bit.
  237.  move.l  44(a1),d1  ;sector offset
  238.  
  239. ;11264 = 512 (bytes per sector) * 11 (sectors per track) * 2 (sides per disk)
  240.  
  241.  move.l  #11264,d3
  242.  divu    d3,d1     ;track
  243.  andi.l  #$0000ffff,d1 ; we need only the quotient 
  244.  
  245. ; now turn the track number into ASCII, so that it can be displayed
  246. ; to the user
  247.  
  248.  divu    #100,d1
  249.  addi.b  #48,d1
  250.  cmp.b   #'0',d1
  251.  bne     NZ1
  252.  move.b  #' ',d1 ; don't show 0
  253.  moveq   #1,d4
  254. NZ1:
  255.  move.b  d1,22(a2)
  256.  lsr.l   d2,d1 ; now the remainder
  257.  divu    #10,d1
  258.  addi.b  #48,d1
  259.  tst     d4
  260.  beq     NZ2
  261.  cmp.b   #'0',d1
  262.  bne     NZ2
  263.  move.b  #' ',d1
  264. NZ2:
  265.  move.b  d1,23(a2)
  266.  lsr.l   d2,d1
  267.  addi.b  #48,d1
  268.  move.b  d1,24(a2)
  269.  
  270.  move.l  ExecBase,a6
  271.  move.l  Port(pc),a0
  272.  lea     Message(pc),a1
  273.  jsr     PutMsg(a6)
  274.  
  275. Endit:
  276.  
  277. ; restore the original register contents.
  278.  
  279.  movem.l (a7)+,d0-d4/a0-a4/a6
  280.  
  281. ; push the original routine address on the stack. now an 'rts' will
  282. ; transfer control to it.
  283.  
  284.  move.l  _SaveIO(pc),-(a7)
  285.  rts
  286.  
  287. _SaveIO:    dc.l 0
  288.  
  289. Message:    ds.b 20 ;<- this is the main message structure
  290.             dc.w 0  ; <- the unit obeying the command is put here
  291.             dc.b "000  ",0 ; <- information to be displayed is put here
  292.  
  293. ; message port address 
  294.  
  295. Port:       dc.l 0
  296.  
  297. TrackName: dc.b "trackdisk.device",0,0
  298. EndeIO:
  299.  
  300.  END
  301.