home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 458.lha / MoveSSP_v1.1 / MoveSSP.a < prev    next >
Text File  |  1990-12-12  |  8KB  |  349 lines

  1. ; MoveSSP.a
  2. ; Copy the system's stack from Chip RAM to Fast RAM, generally to be called
  3. ; as part of one's Startup-Sequence.
  4. ;
  5. ; Written by Christoper A. Wichura (caw@miroc.chi.il.us)
  6. ; Created: 3/4/90
  7. ;
  8. ; Version 1.1 modified by J. Edward Hanway (jeh) - 4/18/90
  9. ; - Frees the 6K of chip memory used by the original SSP.
  10. ; - Treats memory outside of 24-bit address space as FAST RAM.
  11. ; - User Supervisor() instead of SuperState()/UserState() so it can (and should)
  12. ;   be run ahead of SetPatch 1.34.
  13. ; (Assemble with A68K & BLINK)
  14. ;
  15. ; This is really a conversion of MoveSSP.c by Roger Uzun into 68k code,
  16. ; with various `optimizations' being made as well.
  17. ;
  18. ; The arp library is required to use this program.  I used it for its
  19. ; FPrintf function as well as getting an easy way out of not having to
  20. ; decide if I needed to close the stdout filehanle, which is opened with
  21. ; ArpOpen() and closed (if needed) by ArpExit().
  22. ;
  23. ; It is fully residentiable, though to do so would be stupid as it will
  24. ; not do anything after the first invocation.
  25. ;
  26. ; This file supports being called by WorkBench.  However, you will have
  27. ; to supply your own `.info' file for it (if anyone comes up with a really
  28. ; nice looking one then UUencode it and send it to me).
  29. ;
  30. ; I moved it to ML to make it smaller (i.e., no longer needed the Lattice
  31. ; startup code which eats a bunch of memory up).  I also added some
  32. ; messages to let you know what has happened, which MoveSSP.c didn't do.
  33. ;
  34. ; I have not noticed any tremendous speed increase in using this program,
  35. ; but it can't really hurt.  The people who will get the biggest benefit
  36. ; from it are those with 32 bit RAM.
  37. ;
  38. ; The UserState() function is broken in 1.3 and earlier, but SetPatch for 1.3.2
  39. ; fixes it. However, it's best to run this thing before SetPatch so that the
  40. ; old stack space can be merged into a larger region of CHIP RAM. (SetPatch
  41. ; allocates a few bytes at the very top of CHIP RAM.) So this function uses the
  42. ; Supervisor() function instead.
  43.  
  44.  NOLIST
  45.  INCLUDE "libraries/ArpBase.i"
  46.  INCLUDE "exec/execbase.i"
  47.  INCLUDE "exec/memory.i"
  48.  INCLUDE "libraries/dosextens.i"
  49.  LIST
  50.  
  51.  XREF _LVOOpenLibrary
  52.  XREF _LVOCloseLibrary
  53.  XREF _LVOForbid
  54.  XREF _LVOWaitPort
  55.  XREF _LVOGetMsg
  56.  XREF _LVOReplyMsg
  57.  XREF _LVOAllocMem
  58.  XREF _LVODisable
  59.  XREF _LVOEnable
  60.  XREF _LVOSupervisor
  61.  XREF _LVOFreeMem
  62.  
  63. CALL    MACRO
  64.     jsr _LVO\1(a6)
  65.     ENDM
  66.  
  67.   SECTION MoveSSP,CODE
  68.  
  69. ; arp resident tag goes here
  70.     RESIDENT 4*1024
  71.  
  72. init:
  73.     movem.l    d2-d7/a2-a5,-(sp)
  74.     movea.l    4,a6
  75.     lea    ARPlib(pc),a1
  76.     moveq    #39,d0
  77.     CALL    OpenLibrary
  78.     tst.l    d0
  79.     bne.s    __main
  80.  
  81.     lea    DOSlib(pc),a1
  82.     CALL    OpenLibrary
  83.     tst.l    d0
  84.     beq.s    bomb
  85.  
  86.     move.l    d0,a6
  87.     CALL    Output
  88.     move.l    d0,d1
  89.     beq.s    bomb
  90.  
  91.     lea    Msg1(pc),a0
  92.     move.l    a0,d2
  93.     moveq    #Msg1Len,d3
  94.     CALL    Write
  95.  
  96.     move.l    a6,a1
  97.     movea.l    4,a6
  98.     CALL    CloseLibrary
  99.     moveq    #0,d0
  100.  
  101. bomb:
  102.     addq.l    #8,sp
  103.     rts
  104.  
  105. WBMSG    EQUR    d7
  106. LOMEM    EQUR    d6
  107. HIMEM    EQUR    d5
  108. SIZE    EQUR    d4
  109. STDOUT    EQUR    d3
  110. NEWMEM    EQUR    a2
  111. MYPROC    EQUR    a3
  112.  
  113. __main:
  114.     movea.l    a6,a5        ; save exec base pointer
  115.     movea.l    d0,a6        ; put arp base where we can use it
  116.  
  117.     CALL    Output        ; get stdout handle
  118.     move.l    d0,STDOUT
  119.  
  120.     move.l    ThisTask(a5),MYPROC    ; get pointer to our process
  121.  
  122. ; check for workbench
  123.     moveq    #0,WBMSG    ; clear wb flag
  124.  
  125.     tst.l    pr_CLI(MYPROC)
  126.     bne.s    FromCLI
  127.  
  128.     exg    a5,a6        ; get exec base
  129.     lea    pr_MsgPort(MYPROC),a0
  130.     CALL    WaitPort
  131.     lea    pr_MsgPort(MYPROC),a0
  132.     CALL    GetMsg
  133.     move.l    d0,WBMSG    ; save wbench startup message
  134.     exg    a5,a6        ; get back arp base
  135.  
  136. ; we need a console window for workbench users
  137.  
  138.     lea    Console.MSG(pc),a0
  139.     move.l    a0,d1
  140.     move.l    #MODE_NEWFILE,d2
  141.  
  142. ; we use arpopen to get the console.  thus the ArpExit call at the end of
  143. ; this file will free it for us automatically if we got it.
  144.  
  145.     CALL    ArpOpen
  146.  
  147.     move.l    d0,STDOUT    ; did we get the console
  148.     beq    Exit    ; no so die
  149.  
  150.     lsl.l    #2,d0
  151.     movea.l    d0,a0
  152.  
  153.     move.l    fh_Type(a0),pr_ConsoleTask(a3)
  154.  
  155. FromCLI:
  156.     lea    Banner.MSG(pc),a0    ; print a blurb
  157.     move.l    STDOUT,d0    ; get stdout
  158.     CALL    FPrintf
  159.  
  160.     move.l    SysStkLower(a5),LOMEM    ; get low stack ptr
  161.     move.l    SysStkUpper(a5),HIMEM    ; get high stack ptr
  162.  
  163. ; check if we are already in fast memory
  164.     cmpi.l    #$200000,HIMEM
  165.     bcs.s    1$        ; in chip memory
  166.     cmpi.l    #$C00000,HIMEM
  167.     bcs.s    3$        ; in FAST autoconfig memory
  168.     cmpi.l    #$1000000,HIMEM
  169.     bcs.s    1$        ; in slow $C00000 memory
  170.  
  171. 3$    lea    AlreadyFast.MSG(pc),a0
  172.     move.l    STDOUT,d0    ; get stdout
  173.     CALL    FPrintf
  174.     bra    Exit
  175.  
  176. ; we need to move the thing over so figure out its size.  we will print
  177. ; its current start address before moving it, though.
  178.  
  179. 1$:    move.l    HIMEM,SIZE
  180.     sub.l    LOMEM,SIZE
  181.  
  182.     move.l    SIZE,-(sp)    ; push size  onto stack for printf
  183.     move.l    HIMEM,-(sp)    ; push himem onto stack for printf
  184.     move.l    LOMEM,-(sp)    ; push lomem onto stack for printf
  185.  
  186.     movea.l    sp,a1        ; get address of args array
  187.     lea    OldLoc.MSG(pc),a0    ; get message to print
  188.     move.l    STDOUT,d0    ; get stdout
  189.     CALL    FPrintf        ; call ARP print command
  190.     lea    12(sp),sp    ; pop values off stack
  191.  
  192. ; we need to allocate a new stack in fast memory for these folks
  193.  
  194.     move.l    SIZE,d0
  195.     move.l    #MEMF_FAST|MEMF_CLEAR,d1
  196.     exg    a5,a6
  197.     CALL    AllocMem
  198.     exg    a5,a6
  199.  
  200.     tst.l    d0
  201.     bne.s    2$
  202.  
  203.     lea    NoFast.MSG(pc),a0
  204.     move.l    STDOUT,d0    ; get stdout
  205.     CALL    FPrintf
  206.     bra    Exit
  207.  
  208. 2$    movea.l    d0,NEWMEM
  209.  
  210. ; ok we have new memory so now we need to copy the stack over
  211.  
  212.     exg    a5,a6    ; get execbase in a6
  213.     CALL    Disable    ; freeze the system while we do the copy
  214.  
  215.     movea.l    LOMEM,a0
  216.     movea.l    NEWMEM,a1
  217.     move.l    SIZE,d0
  218.     lsr.l    #2,d0    ; size in longwords
  219.  
  220. ; now fix pointers in exec base
  221.  
  222.     move.l    NEWMEM,HIMEM    ; make new himem pointer
  223.     add.l    SIZE,HIMEM
  224.  
  225.     move.l    NEWMEM,SysStkLower(a6)
  226.     move.l    HIMEM,SysStkUpper(a6)
  227.  
  228.     move.l    a5,-(sp)
  229.     lea.l    SuperCode(pc),a5
  230.     CALL    Supervisor    ; go to supervisor mode
  231.     move.l    (sp)+,a5
  232.  
  233. ; now find the free CHIP memory list and change its upper bound
  234.  
  235.     move.l    LOMEM,HIMEM    ; get HIMEM again
  236.     add.l    SIZE,HIMEM
  237.  
  238.     move.l    MemList+LH_HEAD(a6),d0    ; first MemHeader node of free memory list
  239. WalkMemList:
  240.     move.l    d0,a0
  241. ; test for chip memory -- commented out so that $C00000 memory will also be freed
  242. ;    btst.b    #MEMB_CHIP,MH_ATTRIBUTES+1(a0)    ; is it a chip memory node?
  243. ;    beq.s    1$
  244.     cmp.l    MH_UPPER(a0),LOMEM    ; SSP should have been at the top of CHIP RAM
  245.     bne.s    1$
  246.     move.l    HIMEM,MH_UPPER(a0)    ; Extend the CHIP memory region
  247.     bra.s    ReEnable
  248.  
  249. 1$:    move.l    (a0),d0        ; try next node
  250.     bne.s    WalkMemList
  251.     moveq    #0,HIMEM    ; indicate that memory wasn't freed
  252.  
  253. ReEnable:
  254.     CALL    Enable        ; re-enable interrupts
  255.     exg    a5,a6        ; reload ARP base
  256.  
  257. ; ok we have fixed everything up so print new address of stack
  258.  
  259.     move.l    NEWMEM,-(sp)    ; push new location onto stack for printf
  260.     movea.l    sp,a1        ; get address of args array
  261.     lea    NewLoc.MSG(pc),a0    ; get message to print
  262.     move.l    STDOUT,d0    ; get stdout
  263.     CALL    FPrintf        ; call ARP print command
  264.     addq    #4,sp        ; pop value off stack
  265.  
  266. ; if the original stack can't freed, print a warning
  267.  
  268.     tst.l    HIMEM
  269.     beq.s    1$
  270.  
  271. ; free the old stack space.
  272.  
  273.     move.l    LOMEM,a1    ; address of MemChunk
  274.     move.l    SIZE,d0
  275.  
  276.     exg    a5,a6
  277.     CALL    FreeMem
  278.     exg    a5,a6
  279.     bra.s    Exit
  280.  
  281. 1$:    lea    CantFree.MSG(pc),a0
  282.     move.l    STDOUT,d0    ; get stdout
  283.     CALL    FPrintf
  284.     
  285. Exit:
  286.     tst.l    WBMSG        ; started from workbench?
  287.     beq.s    1$
  288.  
  289. ; if we started from workbench then call dos' Delay() function to give
  290. ; them time to see what we said
  291.  
  292.     move.l    #300,d1
  293.     CALL    Delay
  294.  
  295.     exg    a5,a6        ; get exec base
  296.     CALL    Forbid        ; forbid and return startup message to
  297.     movea.l    WBMSG,a1    ; workbench
  298.     CALL    ReplyMsg
  299.     exg    a5,a6        ; get back arp base
  300.  
  301. 1$    movem.l    (sp)+,d2-d7/a2-a5
  302.     moveq    #0,d0
  303.     CALL    ArpExit
  304.  
  305. ; The supervisor code which actually adjusts the ssp
  306.  
  307. SuperCode:
  308.     bra.s    2$
  309. 1$:    move.l    (a0)+,(a1)+    ; copy the entire stack
  310. 2$:    dbra    d0,1$
  311.  
  312.     sub.l    LOMEM,sp    ; find position in old stack
  313.     add.l    NEWMEM,sp    ; get position in new stack
  314.     rte
  315.  
  316. ; here we have all the text and whatnot for this program
  317.  
  318. DOSlib    dc.b "dos.library",0
  319.  
  320. Msg1    dc.b "You need "
  321. ARPlib    dc.b "arp.library",0
  322.     dc.b " V39+",10,0
  323. Msg1Len    EQU *-Msg1
  324.  
  325. Console.MSG:
  326.     dc.b    'CON:40/30/560/45/MoveSSP',0
  327.  
  328. Banner.MSG:
  329.     dc.b    'MoveSSP v1.1 ',$a9,' 1990 by Christoper A. Wichura '
  330.     dc.b    '(caw@miroc.chi.il.us)',10
  331.     dc.b    'Modifications by J. Edward Hanway',10,0
  332.  
  333. AlreadyFast.MSG:
  334.     dc.b    'SSP is already located in fast memory.',10,0
  335.  
  336. NoFast.MSG:
  337.     dc.b    'Could not allocate fast memory for new SSP.',10,0
  338.  
  339. OldLoc.MSG:
  340.     dc.b    'SSP currently located at $%08lx-$%08lx (%ld bytes).',10,0
  341.  
  342. NewLoc.MSG:
  343.     dc.b    'Moved to $%08lx in fast memory.',10,0
  344.  
  345. CantFree.MSG:
  346.     dc.b    'Could not free the original SSP memory.',10,0
  347.  
  348.     END
  349.