home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / util / misc / VMM_src.lha / VMM / mem_trace.asm < prev    next >
Encoding:
Assembly Source File  |  1996-01-07  |  29.8 KB  |  837 lines

  1.                     INCLUDE   "exec/memory.i"
  2.                     INCLUDE   "exec/execbase.i"
  3.                     INCLUDE   "exec/ables.i"
  4.                     INCLUDE   "exec/funcdef.i"
  5.                     INCLUDE   "exec/ports.i"
  6.                     INCLUDE   "exec/exec_lib.i"
  7.                     INCLUDE   "exec/execbase.i"
  8.                     INCLUDE   "dos/dosextens.i"
  9.                     INCLUDE   "shared_defs.i"
  10.                     INCLUDE   "macros.i"
  11.  
  12.                     XDEF      _AllocVM
  13.                     XDEF      _AllocMemPatch
  14.                     XREF      _OrigAllocMem
  15.                     XREF      _AllocMemUsers
  16.  
  17.                     XDEF      _FreeMemPatch
  18.                     XREF      _OrigFreeMem
  19.  
  20.                     XDEF      _AvailMemPatch
  21.                     XREF      _OrigAvailMem
  22.  
  23.                     XDEF      _FreeMemAfterExit
  24.                     XDEF      _FreeMemAfterExitEnd
  25.                     XDEF      _ExecFreeMem
  26.                     XDEF      _PatchLoc1
  27.                     XDEF      _PatchLoc2
  28.                     XDEF      _PatchLoc3
  29.                     XDEF      _RemainingBytes
  30.                     XDEF      _RootTableContents
  31.  
  32.                     XDEF      _DoOrigAllocMem
  33.                     XDEF      _DoOrigAvailMem
  34.  
  35.                     XREF      _HashTab
  36.                     XREF      _VMPort
  37.                     XREF      _VirtAddrStart
  38.                     XREF      _VirtAddrEnd
  39.                     XREF      _VMToBeFreed
  40.                     XREF      _VMFreeRecycling
  41.                     XREF      _FreeVMSignal
  42.                     XREF      _PrePagerTask
  43.                     XREF      _NumPageFrames
  44.                     XREF      _PageReq
  45.                     XREF      _Free
  46.                     XREF      _PageFaultSignal
  47.                     XREF      _PageHandlerTask
  48.                     XREF      _LowMem
  49.                     XREF      _PageHandlerPort
  50.                     XREF      _VMD_NestCnt
  51.                     XREF      _MinVMAlloc
  52.                     XREF      _MemTracking
  53.                     XREF      _CreateTrackInfo
  54.                     XREF      _FreeTrackInfo
  55.                     XREF      _MemTrackList
  56.                     XREF      _CurrentConfig
  57.                     XREF      _EmptyPageCollector
  58.                     XREF      _VMFreeCounter
  59.                     XREF      _CreateTask
  60.                     IFD       USE_OWN_SEMAPHORES
  61.                     XREF      VMMObtainSemaphore
  62.                     XREF      VMMReleaseSemaphore
  63.                     ENDC
  64.                     
  65.  
  66. ****************************************************************
  67. * Memory tracking: Each allocation is prefixed by a standard 
  68. * header, so it is possible to figure out which task allocated
  69. * the block. The header looks like this:
  70. *    Offset     Value
  71. *      0        Ptr to MemTrackStruct
  72. *      4        MAGIC
  73. *      8        Start of buffer returned to requesting task
  74. *
  75. * AllocMem builds such a header for each request in VM if TrackMem
  76. * is set.
  77. * FreeMem checks for the magic longword on every deallocation.
  78. * If it is found the header and the corresponding node is freed also.
  79.  
  80.  
  81.                     IFD       _PHXASS_
  82.                     MACHINE   MC68030
  83.                     ENDC
  84.  
  85.                     SECTION   CODE
  86.  
  87.                     ALIGN_LONG
  88.  
  89. _FreeMemPatch:      * a1 : location
  90.                     * d0 : size
  91.                     * a6 : SysBase
  92.                     IN_VM     a1,NoVirtMemFree
  93.  
  94.                     PRINT_MEM "FreeMem: size %ld",d0
  95.                     PRINT_MEM "FreeMem: location %lx",a1
  96.  
  97.                     subq.l    #1,_VMFreeCounter
  98.                     bne       NoEmptyPageCollection
  99.  
  100.                     movem.l   a1/d0,-(sp)
  101.                     PRINT_DEB "Creating garbage collector"
  102.                     addq.w    #1,_VMD_NestCnt               ; disable allocation of VM
  103.                     move.l    #2000,-(sp)                   ; stacksize
  104.                     lea       _EmptyPageCollector,a0        ; task routine
  105.                     move.l    a0,-(sp)
  106.                     clr.l     -(sp)                         ; priority
  107.                     lea       GarbageCollName,a0
  108.                     move.l    a0,-(sp)                      ; taskname
  109.                     jsr       _CreateTask
  110.                     add.w     #4*4,sp
  111.                     subq.w    #1,_VMD_NestCnt               ; enable allocation of VM
  112.                     movem.l   (sp)+,a1/d0
  113.  
  114. NoEmptyPageCollection
  115.                     cmpi.w    #$ffff,IDNestCnt(a6)          ; compares TD and IDNestCnt
  116.                                                             ; simulataneously
  117.                     bne       LetPrePagerFreeIt
  118.  
  119.                     cmpi.l    #2*PAGESIZE,d0
  120.  
  121.                     bcs       FreeDirectly
  122.  
  123.                     * This region is more than 2 pages long. Inform the
  124.                     * pagehandler to free the corresponding frames or
  125.                     * swap pages. Then do the standard free procedure
  126.  
  127.                     PRINT_MEM "FreeMem: More than 2 pages"
  128.  
  129.                     movem.l   d2-d3/a2-a3,-(sp)
  130.                     move.l    d0,d2
  131.                     move.l    a1,a3
  132.                     move.l    #(MEMF_PUBLIC+MEMF_CLEAR),d1
  133.                     move.l    #VMM_SIZE,d0
  134.                     move.l    _OrigAllocMem,a0
  135.                     jsr       (a0)
  136.                     tst.l     d0
  137.                     beq       DontFreePages
  138.                     move.l    d0,a2
  139.                     move.l    ThisTask(a6),VMM_VMSender(a2)
  140.                     GET_SIGNAL
  141.                     ext.w     d0
  142.                     move.w    d0,VMM_ReplySignal(a2)
  143.                     move.w    d0,d3
  144.  
  145.                     move.w    #VMCMD_FreePages,VMM_VMCommand(a2)
  146.                     move.l    a3,VMM_FreeAddress(a2)
  147.                     move.l    d2,VMM_FreeSize(a2)
  148.                     move.l    a2,a1
  149.                     move.l    _PageHandlerPort,a0
  150.                     jsr       _LVOPutMsg(a6)
  151.  
  152.                     * Have to wait for the page-handler to complete its
  153.                     * operation, otherwise the memory list might be corrupted.
  154.                     moveq.l   #1,d0
  155.                     lsl.l     d3,d0
  156.                     jsr       _LVOWait(a6)
  157.  
  158.                     move.w    d3,d0
  159.                     RELEASE_SIGNAL
  160.                     move.l    _OrigFreeMem,a0
  161.                     move.l    a2,a1
  162.                     moveq.l   #VMM_SIZE,d0
  163.                     jsr       (a0)
  164.  
  165. DontFreePages       move.l    d2,d0
  166.                     move.l    a3,a1
  167.                     movem.l   (sp)+,d2-d3/a2-a3
  168. FreeDirectly
  169.                     MEM_FORBID
  170.  
  171.                     tst.w     _MemTracking
  172.                     beq       DontTrack
  173.  
  174.                     * Check if this was a tracked allocation
  175.                     move.l    a1,a0
  176.                     cmpi.l    #TRACK_MAGIC,-(a0)
  177.                     bne       DontTrack
  178.                     clr.l     (a0)           ; delete magic
  179.                     movem.l   a1/d0,-(sp)
  180.                     move.l    -(a0),-(sp)
  181.                     jsr       _FreeTrackInfo
  182.                     add.w     #4,sp
  183.                     movem.l   (sp)+,a1/d0
  184.                     suba.w    #8,a1          ; free header also
  185.                     addq.l    #8,d0
  186. DontTrack
  187.                     move.l    _OrigFreeMem,a0
  188.  
  189.                     jsr       (a0)
  190.  
  191.                     MEM_PERMIT
  192.                     rts
  193.  
  194.                     ALIGN_LONG
  195.  
  196. NoVirtMemFree
  197.                     PRINT_MEM "FreeMem: size %ld",d0
  198.                     PRINT_MEM "FreeMem: location %lx",a1
  199.  
  200.                     move.l    _OrigFreeMem,a0
  201.                     jmp       (a0)
  202.  
  203. LetPrePagerFreeIt:  * enqueue this chunk in the VMToBeFreed list
  204.                     * no need to enclose this in Forbid/Permit because
  205.                     * we're already in forbidden state
  206.  
  207.                     PRINT_MEM "FreeMem via PrePager"
  208.                     move.l    _VMFreeRecycling,a0
  209.                     tst.l     a0
  210.                     beq       AllocNew
  211.                     move.l    FF_NextFree(a0),_VMFreeRecycling
  212.                     bra       GotFFS              * ForbiddenFreeStruct
  213. AllocNew            movem.l   a1/d0,-(sp)
  214.                     moveq     #FF_SIZE,d0
  215.                     move.l    #MEMF_PUBLIC,d1
  216.                     move.l    _OrigAllocMem,a0
  217.                     jsr       (a0)
  218.                     tst.l     d0
  219.                     beq       FreeError
  220.                     move.l    d0,a0
  221.                     movem.l   (sp)+,a1/d0
  222.  
  223. GotFFS              move.l    a1,FF_address(a0)
  224.                     move.l    d0,FF_size(a0)
  225.  
  226.                     lea       _VMToBeFreed,a1
  227.                     move.l    (a1),FF_NextFree(a0)
  228.                     move.l    a0,(a1)
  229.  
  230.                     move.l    _PrePagerTask,a1
  231.                     move.w    _FreeVMSignal,d1
  232.                     moveq     #1,d0
  233.                     lsl.l     d1,d0
  234.                     jmp       _LVOSignal(a6)
  235.  
  236. FreeError           * there's no memory left for the FFS
  237.                     * Bite the bullet and free it directly
  238.                     * despite this might cause failure
  239.  
  240.                     PRINT_MEM "No mem left for ffs"
  241.                     PRINT_MEM "Freeing directly"
  242.                     movem.l   (sp)+,a1/d0
  243.                     bra       FreeDirectly
  244.  
  245. ****************************************************************
  246.  
  247. _AllocVM            add.w     #1,_AllocMemUsers
  248.                     move.l    d7,-(sp)
  249.                     moveq     #0,d7
  250.                     bclr.l    #MEMB_PUBLIC,d1
  251.                     bra       DoAlloc
  252.  
  253. ****************************************************************
  254.  
  255.                     ALIGN_LONG
  256.  
  257. _AllocMemPatch      * Handling this is quite complicated, so I first wrote it
  258.                     * down in C for clarity. Following is the C code.
  259.                     * It is not very up to date with the real assembler code
  260.                     *
  261.                     * void *C_AllocMem (ULONG size, ULONG flags)
  262.                     *
  263.                     * {
  264.                     * void *buf;
  265.                     * ULONG orig_flags;
  266.                     *
  267.                     * if (VMD_NestCnt != NULL)
  268.                     *   flags |= MEMF_PUBLIC;
  269.                     * else if (!(flags & MEMF_CHIP))
  270.                     *   flags = CheckHashTable (size, flags);
  271.                     *
  272.                     * orig_flags = flags;
  273.                     * if (!(flags & MEMF_CHIP))
  274.                     *   flags |= MEMF_FAST;
  275.                     *
  276.                     * for (;;)
  277.                     *   {
  278.                     *   if (flags & MEMF_PUBLIC)
  279.                     *     buf = CallOrigAllocMem (size, flags);
  280.                     *   else
  281.                     *     {
  282.                     *     MEM_FORBID;
  283.                     *     buf = CallOrigAllocMem (size, flags);
  284.                     *     MEM_PERMIT;
  285.                     *     }
  286.                     *
  287.                     *   if (buf != NULL)
  288.                     *     return (buf);
  289.                     *   if (NumPageFrames * PAGESIZE <= MinMem || FreeFrames (flags) == NULL)
  290.                     *     {
  291.                     *     if (flags != orig_flags)
  292.                     *       flags = orig_flags;
  293.                     *     else
  294.                     *       return (NULL);
  295.                     *     }
  296.                     *   }
  297.                     * }
  298.                     *
  299.  
  300.                     * Called with:
  301.                     * d0 : size of allocation
  302.                     * d1 : flags
  303.                     * a6 : SysBase
  304.  
  305.                     add.w     #1,_AllocMemUsers
  306.                     move.l    d7,-(sp)
  307.                     moveq     #0,d7                    ; used as a marker whether LowMem has been set
  308.  
  309.                     PRINT_MEM "AllocMemPatch: size %ld",d0
  310.                     PRINT_MEM "              flags %lx",d1
  311.  
  312.                     IFD       DEBUG
  313.                     IFD       TRACE_MEM
  314.                     movem.l   d0-d1,-(sp)
  315.                     moveq     #0,d0
  316.                     move.l    d0,d1
  317.                     jsr       _LVOSetSR(a6)
  318.                     btst.l    #13,d0
  319.                     movem.l   (sp)+,d0-d1
  320.                     beq       NoSVMode
  321.                     PRINT_MEM "AllocMem from SV: size %ld",d0
  322.                     PRINT_MEM "AllocMem from SV: flags %lx",d1
  323. NoSVMode
  324.                     ENDC
  325.                     ENDC
  326.  
  327.                     cmp.l     _MinVMAlloc,d0
  328.                     bcs       ForcePublic
  329.  
  330.                     tst.w     _VMD_NestCnt
  331.                     beq       TestChip
  332.  
  333. ForcePublic         bset.l    #MEMB_PUBLIC,d1
  334.                     bra       DoAlloc
  335.  
  336.                     ALIGN_LONG
  337.  
  338. TestChip            btst.l    #MEMB_CHIP,d1
  339.                     beq       ConsultHashTable
  340.                     bra       ForcePublic
  341.  
  342. ConsultHashTable    bsr       CheckHashTable
  343.                     PRINT_MEM "CheckHashTable returned %lx",d1
  344.  
  345. DoAlloc
  346.                     movem.l   d0-d1,-(sp)         ; save size and flags for
  347.                                                   ; repeated usage
  348.                     btst.l    #MEMB_CHIP,d1
  349.                     bne       DontSetFast
  350.                     bset.l    #MEMB_FAST,d1
  351.  
  352. DontSetFast
  353. RetryAlloc          btst.l    #MEMB_PUBLIC,d1
  354.                     beq       TryVM
  355.  
  356. ***************** Allocation of public mem ****************
  357.  
  358.                     PRINT_MEM "AllocMem: Trying PUBLIC"
  359.                     move.l    d1,-(sp)
  360.                     move.l    _OrigAllocMem,a0
  361.                     jsr       (a0)
  362.  
  363.                     PRINT_MEM "AllocMem PUBLIC: location %lx",d0
  364.  
  365.                     tst.l     d0
  366.                     bne       AllocSuccess
  367.                     bra       AllocFailed
  368.  
  369. ***************** Allocation of VM ************************
  370.  
  371. TryVM:              PRINT_MEM "AllocMem: Trying VM"
  372.  
  373.                     tst.w     _MemTracking
  374.                     beq       NoTracking
  375.  
  376.                     addq.l    #8,d0               ; for the header
  377.                     
  378.                     MEM_FORBID
  379.                     move.l    d1,-(sp)
  380.                     move.l    _OrigAllocMem,a0
  381.                     jsr       (a0)
  382.  
  383.                     PRINT_MEM "AllocMem VM: location %lx",d0
  384.  
  385.                     tst.l     d0
  386.                     beq       AllocFailedTracked
  387.  
  388.                     ; check if the allocated buffer is in public mem
  389.                     IN_VM     d0,BufIsPublic
  390.  
  391.                     move.l    4(sp),-(sp)          ; size of original request
  392.                     move.l    d0,-(sp)
  393.                     jsr       _CreateTrackInfo
  394.                     add.w     #8,sp
  395.                     MEM_PERMIT
  396.                     
  397.                     bra       AllocSuccess
  398.  
  399. AllocFailedTracked  MEM_PERMIT
  400.                     bra       AllocFailed
  401.  
  402. BufIsPublic:        ; The allocated buffer is not in virtual memory,
  403.                     ; i.e. it should not be tracked.
  404.                     ; Free the trailing 8 bytes
  405.  
  406.                     MEM_PERMIT
  407.                     move.l    d0,-(sp)
  408.                     move.l    8(sp),d1             ; size of original request
  409.                     addq.l    #7,d1
  410.                     and.b     #~7,d1               ; align to 8 byte boundary
  411.                     add.l     d0,d1                ; add start address
  412.  
  413.                     move.l    d1,a1
  414.                     moveq     #8,d0                    
  415.                     move.l    _OrigFreeMem,a0
  416.                     jsr       (a0)
  417.  
  418.                     ; restore buffer pointer
  419.                     move.l    (sp)+,d0
  420.                     bra       AllocSuccess
  421.  
  422. NoTracking
  423.                     MEM_FORBID
  424.                     move.l    d1,-(sp)
  425.                     move.l    _OrigAllocMem,a0
  426.                     jsr       (a0)
  427.                     MEM_PERMIT
  428.  
  429.                     PRINT_MEM "AllocMem VM: location %lx",d0
  430.  
  431.                     tst.l     d0
  432.                     beq       AllocFailed
  433.  
  434. AllocSuccess        add.w     #12,sp
  435.                     tst.l     d7
  436.                     beq       NoLowMem1
  437.                     sub.w     #1,_LowMem
  438. NoLowMem1           move.l    (sp)+,d7
  439.                     sub.w     #1,_AllocMemUsers
  440.                     tst.l     d0                  ; just to make bad programs work
  441.                     rts
  442.  
  443. AllocFailed         move.l    (sp)+,d1            ; restore flags
  444.                     btst.l    #MEMB_NO_EXPUNGE,d1
  445.                     bne       NoSuccess
  446.                     move.l    _NumPageFrames,d0
  447.                     asl.l     #8,d0
  448.                     asl.l     #(PAGESIZESHIFT-8),d0
  449.                     lea       _CurrentConfig,a0
  450.                     cmp.l     MinMem(a0),d0
  451.                     ble       CheckFlags
  452.                     move.l    (sp),d0             ; saved size
  453.                     bsr       FreeFrame
  454.                     tst.l     d0
  455.                     beq       CheckFlags
  456.                     move.l    (sp),d0             ; saved size
  457.                     bra       RetryAlloc
  458.  
  459. CheckFlags:         cmp.l     4(sp),d1            ; saved flags
  460.                     beq       NoSuccess
  461.                     move.l    4(sp),d1
  462.                     PRINT_MEM "Retrying with orig flags"
  463.                     move.l    (sp),d0             ; saved size
  464.                     bra       RetryAlloc
  465.  
  466. NoSuccess:          PRINT_MEM "Alloc failed"
  467.                     add.w     #8,sp
  468.                     moveq     #0,d0
  469.                     tst.l     d7
  470.                     beq       NoLowMem2
  471.                     sub.w     #1,_LowMem           
  472. NoLowMem2           move.l    (sp)+,d7
  473.                     sub.w     #1,_AllocMemUsers
  474.                     tst.l     d0                  ; just to make bad programs work
  475.                     rts
  476.  
  477.  
  478.                     *****************************************
  479.  
  480.                     ALIGN_LONG
  481.  
  482. FreeFrame:          * Function: Tries to make the pagehandler free one frame
  483.                     * Inputs: A6 = SysBase (not to be changed)
  484.                     *         D0: Size of request (may be destroyed)
  485.                     *         D1: Flags from AllocMem (not to be modified)
  486.                     * Outputs: d0 <> 0 indicates success
  487.  
  488.                     PRINT_MEM "Trying to free a frame"
  489.                     tst.l     d7
  490.                     bne       LowMemAlreadySet
  491.                     add.w     #1,_LowMem
  492. LowMemAlreadySet
  493.                     moveq     #1,d7
  494.                     movem.l   d1-d3/a2,-(sp)
  495.                     move.l    d0,d3
  496.                     moveq     #0,d2               * Success indicator:
  497.                                                   * No success
  498.                     lea       _Free,a0
  499.                     FORBID
  500.                     REMHEAD
  501.                     PERMIT
  502.                     tst.l     d0
  503.                     beq       NothingToBeDone
  504.                     move.l    d0,a2
  505.                     move.l    ThisTask(a6),TS_FaultTask(a2)
  506.                     clr.l     TS_FaultAddress(a2)
  507.                     move.l    d3,TS_RemFrameSize(a2)
  508.                     move.l    d1,TS_RemFrameFlags(a2)
  509.                     clr.w     TS_FramesRemoved(a2)
  510.  
  511.                     GET_SIGNAL
  512.                     ext.w     d0
  513.                     move.w    d0,TS_WakeupSignal(a2)      ; -1 for no signal
  514.  
  515.                     lea       _PageReq,a0
  516.                     move.l    a2,a1
  517.                     FORBID
  518.                     ADDTAIL
  519.                     PERMIT
  520.  
  521.                     move.w    _PageFaultSignal,d1
  522.                     move.l    _PageHandlerTask,a1
  523.                     moveq     #1,d0
  524.                     lsl.l     d1,d0
  525.                     jsr       _LVOSignal(a6)
  526.  
  527.                     moveq     #1,d0
  528.                     move.w    TS_WakeupSignal(a2),d1
  529.                     lsl.l     d1,d0
  530.  
  531.                     jsr       _LVOWait(a6)
  532.  
  533.                     PRINT_MEM "Received reply"
  534.  
  535.                     move.w    TS_WakeupSignal(a2),d0
  536.                     RELEASE_SIGNAL
  537.  
  538.                     move.w    TS_FramesRemoved(a2),d2
  539.                     PRINT_DEB "Frames removed: %lx",d2
  540.  
  541.                     lea       _Free,a0
  542.                     move.l    a2,a1
  543.                     FORBID
  544.                     ADDTAIL
  545.                     PERMIT
  546.  
  547. NothingToBeDone     move.l    d2,d0
  548.                     movem.l   (sp)+,d1-d3/a2
  549.                     rts
  550.  
  551. ****************************************************************
  552.  
  553.                     ALIGN_LONG
  554.  
  555. AskVMManager:       * Function: Call the VMManager to enter the current
  556.                     *           task into the hash table.
  557.                     * Inputs: A6 = SysBase (not to be changed)
  558.  
  559.                     PRINT_MEM "AllocMem: ExtCheckMem called"
  560.  
  561.                     move.l    a2,-(sp)
  562.                     move.l    #(MEMF_PUBLIC+MEMF_CLEAR),d1
  563.                     move.l    #VMM_SIZE,d0
  564.                     move.l    _OrigAllocMem,a0
  565.                     jsr       (a0)
  566.                     tst.l     d0
  567.                     bne       GotMsg
  568.                     move.l    (sp)+,a2
  569.                     rts
  570.  
  571. GotMsg              move.l    d0,a2          ; Msg for VM_Manager
  572.                     GET_SIGNAL
  573.                     move.l    ThisTask(a6),VMM_VMSender(a2)
  574.                     ext.w     d0
  575.                     move.w    d0,VMM_ReplySignal(a2)
  576.                     move.w    #VMCMD_AskAllocMem,VMM_VMCommand(a2)
  577.                     PRINT_DEB "Asking VM_Manager"
  578.                     move.l    _VMPort,a0
  579.                     move.l    a2,a1
  580.  
  581.                     jsr       _LVOPutMsg(a6)
  582.  
  583.                     move.w    VMM_ReplySignal(a2),d1
  584.                     moveq     #1,d0
  585.                     asl.l     d1,d0
  586.                     jsr       _LVOWait(a6)
  587.  
  588. FreeAll             move.w    VMM_ReplySignal(a2),d0
  589.                     RELEASE_SIGNAL
  590.                     move.l    a2,a1
  591.                     move.l    #VMM_SIZE,d0
  592.                     move.l    _OrigFreeMem,a0
  593.                     jsr       (a0)
  594.                     move.l    (sp)+,a2
  595.                     rts
  596.  
  597. ****************************************************************
  598.  
  599.                     ALIGN_LONG
  600.  
  601. CheckHashTable:     * Function: Checks, if the current task may use
  602.                     *           VM.
  603.                     * Inputs:  D0: size of desired allocation
  604.                     *          D1: flags of desired allocation
  605.                     *          A6 = SysBase (not to be changed)
  606.                     * Outputs: D0: size of desired allocation
  607.                     *          D1: modified flags for allocation
  608.  
  609.                     movem.l   d0-d1,-(sp)
  610.                     FORBID
  611.                     bsr       FindHashEntry       ; returns pointer to 
  612.                     movem.l   (sp)+,d0-d1         ; hash entry in a0
  613.  
  614.                     btst.l    #MEMB_PUBLIC,d1
  615.                     st        HE_Referenced(a0)   ; does not affect CCR
  616.                     beq       CheckNonPublic
  617.                     cmp.l     HE_MinPublic(a0),d0
  618.                     bcs       ThatsIt             ; unsigned blt
  619.                     bclr.l    #MEMB_PUBLIC,d1
  620. ThatsIt             PERMIT
  621.                     rts
  622.  
  623.                     ALIGN_LONG
  624.  
  625. CheckNonPublic:     cmp.l     HE_MinNonPublic(a0),d0
  626.                     bcc       ThatsIt             ; unsigned bge
  627.                     bset.l    #MEMB_PUBLIC,d1
  628.                     PERMIT
  629.                     rts
  630.  
  631. ****************************************************************
  632.  
  633. FindHashEntry:      * Function: Find a hash entry in the table
  634.                     *           If the corresponding entry could not be 
  635.                     *           found the VM_Manager is asked.
  636.                     *           Has to be called in forbidden state.
  637.                     * Inputs:  a6: SysBase
  638.                     * Outputs: a0: Pointer to hash entry
  639.  
  640. * Check if this is a CLI or another type of task
  641.  
  642.                     move.l    ThisTask(a6),a1
  643.                     cmp.b     #NT_TASK,LN_TYPE(a1)
  644.                     move.l    LN_NAME(a1),a0      ; does not affect CCR
  645.                     beq       IsNotCLI
  646.                     movea.l   pr_CLI(a1),a1
  647.                     tst.l     a1
  648.                     beq       IsNotCLI
  649.                     adda.l    a1,a1          ; BPTR --> PTR
  650.                     adda.l    a1,a1
  651.                     move.l    cli_CommandName(a1),a1
  652.                     tst.l     a1
  653.                     beq       IsNotCLI
  654.                     adda.l    a1,a1          ; BPTR --> PTR
  655.                     adda.l    a1,a1
  656.                     tst.b     1(a1)
  657.                     beq       IsNotCLI
  658.                     bra       IsCLI
  659.  
  660.                     ALIGN_LONG
  661.  
  662. IsNotCLI            move.l    a0,a1
  663.  
  664.                     * A1 contains pointer to name here
  665.  
  666. IsCLI               movem.l   a2-a3,-(sp)
  667.                     lea       _HashTab,a0
  668.                     move.l    a1,d0
  669.                     HASH_VAL  d0
  670.                     move.l    (a0,d0.w*4),a0
  671. loop                tst.l     a0
  672.                     bne       ValidEntry
  673.  
  674. NotFound:           movem.l   (sp)+,a2-a3
  675.                     bsr       AskVMManager
  676.                     bra       FindHashEntry
  677.  
  678.                     ALIGN_LONG
  679.  
  680. ValidEntry          move.l    a1,a3               ; pointer to name
  681.                     move.l    HE_Name(a0),a2
  682.                     move.w    HE_NumLongsM1(a0),d0
  683.  
  684. cmp_loop            cmp.l     (a2)+,(a3)+
  685.                     dbne      d0,cmp_loop
  686.                     beq       FoundIt
  687.  
  688. NextInChain:        move.l    HE_NextEntry(a0),a0
  689.                     PRINT_MEM "AllocMem: Next in chain used"
  690.                     bra       loop
  691.  
  692.                     ALIGN_LONG
  693.  
  694. FoundIt             movem.l   (sp)+,a2-a3
  695.                     rts
  696.  
  697.  
  698. ****************************************************************
  699.  
  700.                     ALIGN_LONG
  701.  
  702. _AvailMemPatch:     * inputs:
  703.                     * d1 : attributes
  704.                     * a6 : SysBase
  705.                     * outputs:
  706.                     * d0 : size
  707.  
  708.                     tst.w     _VMD_NestCnt
  709.                     beq       TestChip2
  710.  
  711.                     bset.l    #MEMB_PUBLIC,d1
  712.                     bra       CallOrig
  713.  
  714. TestChip2           btst.l    #MEMB_CHIP,d1
  715.                     bne       CallOrig
  716.  
  717. * New: Check if this task is permitted to use virtual mem.
  718. *      If not return only the amount PUBLIC free mem.
  719.                     move.l     #$7fffffff,d0
  720.                     bsr       CheckHashTable
  721.  
  722.                     move.l    _OrigAvailMem,a1
  723.                     MEM_FORBID
  724.                     jsr       (a1)
  725.                     MEM_PERMIT
  726.                     rts
  727.  
  728. CallOrig:           move.l    _OrigAvailMem,a1
  729.  
  730.                     jmp       (a1)
  731.  
  732. ****************************************************************
  733.  
  734. _DoOrigAllocMem     * Function to call the original AllocMem function
  735.                     * without going through the patch from C. It is safe
  736.                     * to call even when the patch has not yet been
  737.                     * installed.
  738.                     * C prototype is
  739.                     * void *DoOrigAllocMem (ULONG size, ULONG flags)
  740.  
  741.                     move.l    8(sp),d1
  742.                     move.l    4(sp),d0
  743.                     move.l    a6,-(sp)
  744.                     move.l    _OrigAllocMem,a0
  745.                     move.l    4,a6
  746.                     tst.l     a0
  747.                     beq       UseLVO
  748.                     jsr       (a0)
  749.                     move.l    (sp)+,a6
  750.                     rts
  751.  
  752. UseLVO              jsr       _LVOAllocMem(a6)
  753.                     move.l    (sp)+,a6
  754.                     rts
  755.  
  756. ****************************************************************
  757.  
  758. _DoOrigAvailMem     * Function to call the original AvailMem function
  759.                     * without going through the patch from C. It is safe
  760.                     * to call even when the patch has not yet been
  761.                     * installed.
  762.                     * C prototype is
  763.                     * void *DoOrigAvailMem (ULONG flags)
  764.  
  765.                     move.l    4(sp),d1
  766.                     move.l    a6,-(sp)
  767.                     move.l    _OrigAvailMem,a0
  768.                     move.l    4,a6
  769.                     tst.l     a0
  770.                     beq       UseLVO2
  771.                     jsr       (a0)
  772.                     move.l    (sp)+,a6
  773.                     rts
  774.  
  775. UseLVO2             jsr       _LVOAvailMem(a6)
  776.                     move.l    (sp)+,a6
  777.                     rts
  778.  
  779. ****************************************************************
  780.  
  781. _FreeMemAfterExit:  * a1 : location
  782.                     * d0 : size
  783.                     * a6 : SysBase
  784.  
  785. _PatchLoc1          cmp.l     #$ffffffff,a1   * Dummy for end, patched later
  786.                     bhi       NoVirtMemFree2
  787. _PatchLoc2          cmp.l     #$ffffffff,a1   * Dummy for start, patched later
  788.                     bcs       NoVirtMemFree2
  789.                     * Count down rest of allocated memory
  790.                     addq.l    #7,d0
  791.                     and.w     #$fff8,d0
  792.                     lea       _RemainingBytes(pc),a0
  793.                     sub.l     d0,(a0)
  794.                     bne       FreeReady
  795.  
  796.                     * There's no virtual memory allocated anymore.
  797.                     * Remove this routine.
  798.  
  799. _PatchLoc3          lea.l     $12345678,a0    * Dummy for first address in
  800.                                               * root table, patched later
  801.                     moveq     #NUM_PTR_TABLES-1,d0
  802.                     lea       _RootTableContents(pc),a1
  803. RestoreRootTab      move.l    (a1)+,(a0)+
  804.                     dbra      d0,RestoreRootTab
  805.  
  806.  
  807.                     move.l    a6,a1
  808.                     move.w    #-$d2,a0
  809.                     move.l    _ExecFreeMem(pc),d0
  810.                     FORBID
  811.                     jsr       _LVOSetFunction(a6)
  812.                     lea       _FreeMemAfterExit(pc),a1
  813.                     cmp.l     a1,d0
  814.                     beq       FunctionKilled
  815.                     move.l    a1,d0
  816.                     move.w    #-$d2,a0
  817.                     move.l    a6,a1
  818.                     jsr       _LVOSetFunction(a6)
  819.  
  820. FunctionKilled      PERMIT
  821. FreeReady           rts
  822.  
  823. NoVirtMemFree2:     move.l    _ExecFreeMem(pc),a0
  824.                     jmp       (a0)
  825.  
  826. _ExecFreeMem        dc.l      0
  827. _RemainingBytes     dc.l      0
  828. _RootTableContents  ds.l      NUM_PTR_TABLES
  829.  
  830. _FreeMemAfterExitEnd:
  831.  
  832.                     dc.l      0              ; dummy
  833.  
  834. GarbageCollName     GARBAGE_COLL_NAME
  835.  
  836.                     end
  837.