                OPT L-,C+,D-,O+         ; Devpac Amiga stuff, skip this 
                                        ; for other assemblers 

*  MakeFastMem v1.0    891028      E. Lundevall 
*
*  A little program to provide folks with only chipmem some "fastmem" 
*  for programs that require fastmem (what's the point with that?!?). 
*

                INCDIR  Assembler:include/ 
;                INCLUDE mymacros.i  ; You don't have this one 
                INCLUDE exec/exec_lib.i           ; Library offsets in 
               INCLUDE intuition/intuition_lib.i ; those four files 
                INCLUDE libraries/dos_lib.i  
               INCLUDE workbench/icon_lib.i 
                INCLUDE exec/execbase.i 
               INCLUDE exec/alerts.i 
               INCLUDE exec/tasks.i 
                INCLUDE exec/memory.i 
               INCLUDE intuition/intuition.i 
               INCLUDE libraries/dosextens.i 
               INCLUDE workbench/startup.i 
               INCLUDE workbench/workbench.i 


; Necessary macros from "mymacros.i" 


jsrb           MACRO
               jsr     _LVO\1(a6) 
               XREF.L  _LVO\1 
               ENDM 
 

push           MACRO 
               movem.\0 \1,-(sp) 
               ENDM 

pop            MACRO 
               movem.\0 (sp)+,\1 
               ENDM 

openlib         MACRO 
                lea     \1,a1 
                move.l  \2,d0 
                jsrb    OpenLibrary 
                ENDM 


; Some symbol definitions 
 
VERSION                EQU     33      ; Use only v1.2 och higher 
REQHEIGHT      EQU     80      ; Height of the error requester 
REQWIDTH       EQU     300     ; Width of the error requester 
 

MakeFastMem     movea.l 4,a6 
               push.l  d0/a0   ; Save d0 & a0 in case we are run from the CLI 
               suba.l  a1,a1    
               jsrb    FindTask ; Find the address to our own process 
               movea.l d0,a4 
               pop.l   d0/a0 
               tst.l   pr_CLI(a4) ; Check if we are running from the CLI 
               beq     fromWB 


********************** Code for CLI part ********************************* 

fromCLI                subq.l  #1,d0   ; Decrement argument length to strip LF 
                beq     usage  ; No argument given, tell user how to use us 
                move.b  #0,0(a0,d0.l) ; Make argument string NULL-terminated 
                bsr     asctodec ; Convert string to binary value 
                bmi     usage  ; Not a positive number, display usage 
                bsr    CreateFast ; Do the real work 
               tst.l   d0       
               bne     .nosuccess ; Yack, something went wrong... 

                lea     okmess(pc),a0   ; We did it! Bring the news to 
                moveq   #okmesslen,d0   ; the world! 
                bra     WriteMess 

.nosuccess      lea     errmess(pc),a0  ; Hey, who stole the memory...;-) 
                moveq   #errmesslen,d0 
                bsr     WriteMess 
               tst.l   d0              ; Did we succeed in writing message? 
               bne.s   .nodos 
               moveq   #10,d0 
.nodos         rts 


usage           lea     usemess(pc),a0      ; Write the usage message 
                moveq   #usemesslen,d0 
                bra     WriteMess 



********************** Code for Workbench part *****************************

fromWB         lea     pr_MsgPort(a4),a0       ; Wait for WB startup message 
               jsrb    WaitPort 
               lea     pr_MsgPort(a4),a0       ; Get the message... 
               jsrb    GetMsg 
               push.l  d0                      ; ...and save it for later use 

               movea.l d0,a0 
               movea.l sm_ArgList(a0),a1       ; Get the first argument: 
               move.l  wa_Name(a1),-(sp)       ; Name of program 
               move.l  wa_Lock(a1),-(sp)       ; Lock to directory of program 

               openlib dosname,#VERSION        ; Open dos.library 
               tst.l   d0 
               beq     nodos                   ; Hey, where's DOS??!?

               movea.l d0,a6                   ; Change current directory to 
               pop.l   d1                      ; the directory of our program 
               jsrb    CurrentDir 

               movea.l a6,a1                   ; Close dos.library 
               movea.l 4,a6 
               jsrb    CloseLibrary 
        
OpenIconLib    openlib iconname,#VERSION       ; Open icon.library 
               tst.l   d0 
               beq     noiconlib 

               movea.l d0,a6                   ; Get the icon for our program 
               pop.l   a0 
               jsrb    GetDiskObject 
               tst.l   d0 
               beq     noobj 

               move.l  d0,d7                   ; Put away address to DiskObject
               movea.l d0,a0 
               movea.l do_ToolTypes(a0),a0 
               lea     tooltype(pc),a1         ; Search for ToolType 'FASTMEM' 
               jsrb    FindToolType 
               tst.l   d0 
               beq     notooltype 
 
               movea.l d0,a0 
               movea.l a0,a1           ; Calculate the length of the string 
               moveq   #-1,d0 
.strlen                addq.l  #1,d0 
               tst.b   0(a1,d0.l) 
               bne.s   .strlen 
               bsr     asctodec        ; Convert ASCII string to binary value 
               bmi     nomemsize 

               push.l  d0              ; Save memory size 
               bsr     FreeDO          ; Release the DiskObject 
               bsr     CloseIconLib    ; Ok, now close icon.libary 
               pop.l   d0 
               bsr     CreateFast      ; Do the real work 
               tst.l   d0 
               beq     exitWB          ; Yeah, we did it! 
                

*               
* Some error conditions, show an error requester 
*

nocreatefast   lea     wberrmess(pc),a0 
               bsr     ShowRequest 
               bra     goodbye 

noiconlib      lea     noiconlibmess(pc),a0    ; No icon.library available 
               bsr     ShowRequest 
               bra     goodbye 

nodos          ALERT   (AG_OpenLib!AO_DOSLib)  ; Hey, no dos.libary!! 
               bra     goodbye                 ; This is NOT good... 

noobj          bsr     CloseIconLib            ; No icon for our program 
               lea     noobjmess(pc),a0 
               bsr     ShowRequest 
               bra     goodbye 
 
notooltype     bsr     FreeDO                  ; No FASTMEM tooltype 
               bsr     CloseIconLib 
               lea     notooltypemess(pc),a0 
               bsr     ShowRequest 
               bra     goodbye 

nomemsize      bsr     FreeDO                  ; Release icon 
               bsr     CloseIconLib            ; Incorrect value for the 
               lea     nomemsizemess(pc),a0    ; FASTMEM tooltype 
               bsr     ShowRequest 

goodbye                moveq   #100,d0 
               bra     exitWB 

**** Close icon.library ***** 

CloseIconLib    movea.l        a6,a1           
               movea.l 4,a6 
               jsrb    CloseLibrary 
               rts 


**** Exit from Workbench ***** 

exitWB         jsrb    Forbid          ; Disable multitasking so that WB 
               pop.l   a1              ; won't unload us before we're ready 
               jsrb    ReplyMsg        ; Get the original WB startup message 
               rts                     ; and reply to it, then exit 
                


 
***************************************************************************** 
* FreeDO - Do a FreeDiskObject 
*      Input:  d7 - address to DiskObject 
*              a6 - address to IconBase 
*      Result: None 
***************************************************************************** 

FreeDO         movea.l d7,a0                   ; Release the allocated 
               jsrb    FreeDiskObject          ; resources for the icon 
               rts 


 
*************************************************************************** 
* ShowRequest - display a requester with an error message 
*      Input:  a0 - address to an IntuiText 
*              a6 - address to ExecBase 
*      Result: None 
*************************************************************************** 

ShowRequest    push.l  d2/d3/a2/a3 
               push.l  a0               
               openlib intuiname(pc),#VERSION 
               pop.l   a0 
               tst.l   d0 
               beq     .nointui 

               movea.l d0,a6 
               movea.l a0,a1 
               suba.l  a0,a0 
               lea     darnmess(pc),a2 
               movea.l a2,a3 
               moveq   #0,d0 
               moveq   #0,d1 
               move.l  #REQHEIGHT,d3 
               move.l  #REQWIDTH,d2 
               jsrb    AutoRequest 
               push.l  d0 
               movea.l a6,a1 
               movea.l 4,a6 
               jsrb    CloseLibrary 
               pop.l   d0 
.nointui       pop.l   d2/d3/a2/a3 
               rts 


 

**************************************************************************** 
* CreateFast - Allocate a chunk of CHIPRAM and convert it to FASTRAM 
*      Input:  d0 - Size of the wanted FASTRAM chunk. 
*              a6 - pointer to ExecBase 
*      Result: d0 - NULL if successfull
**************************************************************************** 

CreateFast      push.l d2-d3 
               addq.l  #8,d0   ; Adjust size for the mem chunk header 
               move.l  d0,d3   ; Allocate the "fast" memory 
                move.l  #MEMF_CHIP+MEMF_PUBLIC+MEMF_CLEAR,d1 
                jsrb    AllocMem 
                move.l  d0,d2 
                beq     .error1 

                move.l  #MH_SIZE,d0     ; Allocate space for a MemHeader 
                move.l  #MEMF_CLEAR+MEMF_PUBLIC,d1 
                jsrb    AllocMem 
                tst.l   d0 
                beq     .error2 

                lea     MakeFastMem(pc),a0  ; Disconnect the DATA hunk 
                moveq   #0,d1               ; This is for the name field 
                move.l  d1,-4(a0)           ; of the MemHeader. 

                move.l  d0,a1 
                move.l  d2,MH_FIRST(a1) ; Use the first 8 bytes in the "fast" 
                movea.l d2,a0           ; memory for a MemChunk 
                addq.l  #8,d2 
                move.l  d2,MH_LOWER(a1) ; Init the MemHeader as fastmem 
                move.w  #MEMF_FAST+MEMF_PUBLIC,MH_ATTRIBUTES(a1) 
                                        ; We have made one big chunk 
                subq.l  #8,d3           ; Subtract the MemChunk size and 
                move.l  d3,MC_BYTES(a0) ; store the actual free size 
                move.l  d3,MH_FREE(a1) 
                add.l   d2,d3           ; Add size and lower address to get 
                move.l  d3,MH_UPPER(a1) ; the upper bound 
                moveq   #NT_MEMORY,d0   ; Store the node type 
                move.b  d0,LN_TYPE(a1) 
                lea     name,a0 
                move.l  a0,LN_NAME(a1)  ; Store the address to the name 
 
                push.l  a1 
                jsrb    Disable         ; Want to mess around by myself 
                pop.l   a1 
                lea     MemList(a6),a0  ; Add our memory node to the 
                ADDHEAD                 ; MemList in ExecBase 
                jsrb    Enable          ; Ok, let the others play 

               moveq   #0,d0           ; We were successful, return 0 to 
               bra.s   .fastfixed      ; to say it's ok. 
 
.error2         movea.l d0,a1           ; Trouble allocating memory, free 
                move.l  d3,d0           ; the stuff we already have
                swap    d0              ; allocated 
                jsrb    FreeMem
 
.error1        moveq   #-1,d0          ; Error, return -1 to say it's not ok. 
.fastfixed     pop.l   d2-d3 
               rts 


 
***************************************************************************** 
* WriteMess - Write a message to the CLI Window. 
*             Input:    a0 - pointer to message 
*                       d0 - length of message 
*                      a6 - pointer to ExecBase 
*             Result:  d0 - NULL if successful 
***************************************************************************** 
 
WriteMess       push.l d2-d3 
               move.l  d0,d3 
               push.l  a0 
                lea     dosname(pc),a1 
                jsrb    OldOpenLibrary  ; Open dos.library, any version 
                tst.l   d0 
                beq.s   .nomess 

                movea.l d0,a6 
                jsrb    Output          ; Write the appropriate message 
                move.l  d0,d1           ; in the CLI-window we were run 
                pop.l  d2              ; from. 
                jsrb    Write 
               pop.l   d2-d3 
               movea.l a6,a1 
               movea.l 4,a6 
               jsrb    CloseLibrary    ; Close dos.library 
               moveq   #0,d0 
.exitwrite     rts 


.nomess                ALERT   (AG_OpenLib!AO_DOSLib)  ; No dos.library availab
e!!!
               moveq   #100,d0                 ; This is REAL bad... 
               bra     .exitwrite               






***************************************************************************** 
* asctodec - Convert an ASCII string (NULL-terminated) to a binary value 
*      Input:  a0 - pointer to ASCII string 
*              d0 - length of string 
*      Result: d0 - Binary value 
***************************************************************************** 

asctodec        push.l d2 
               move.l  d0,d2 
                subq.l  #1,d2               ; We will use nr of characters as a
 
                lsl.l   #2,d2               ; offset 
                moveq   #0,d1 
                move.l  d1,d0 
                lea     .Numbers(pc),a1     ; Get base address of offset table 
.loop1          move.b  (a0)+,d1 
                beq     .finished 
                subi.b  #$31,d1 
                bmi     .zero 
                cmpi.b  #NumBase-1,d1 
                bcs     .loop2 
                moveq   #-1,d0 
                bra     .finished 
.loop2          add.l   0(a1,d2.w),d0       ; Add value in table d1 times to d0
 
                dbra    d1,.loop2 
                moveq   #0,d1 
.zero           subq.w  #4,d2 
                bra     .loop1 
.finished       pop.l  d2 
               rts 

NumBase         EQU     10 
.Numbers        dc.l    1,10,100,1000,10000,100000,1000000,10000000,100000000 


 


****************** Some text & messages definitions ************************ 

dosname         dc.b    'dos.library',0 
iconname       dc.b    'icon.library',0 
               CNOP    0,2 
intuiname      dc.b    'intuition.library',0 
               CNOP    0,2 
tooltype       dc.b    'FASTMEM',0 
               CNOP    0,2 
errmess         dc.b    'P-p-p-pleeeaase... I need more memory!',10,0 
errmesslen      EQU     *-errmess 
                CNOP    0,2 
okmess          dc.b    'FastMem created!',10,0 
okmesslen       EQU     *-okmess 
                CNOP    0,2 
usemess         dc.b    'Usage: MakeFastMem  fastmemsize',10,0 
usemesslen      EQU     *-usemess 
               CNOP    0,2 
darntext       dc.b    'Darn!',0 
               CNOP    0,2 
noobjtext      dc.b    'No icon available',0 
               CNOP    0,2 
noiconlibtext  dc.b    'No icon.library',0,0 
               CNOP    0,2 
notooltypetext dc.b    'No FASTMEM ToolType',0  
               CNOP    0,2 
nomemsizetext  dc.b    'Error in FASTMEM value',0               
               CNOP    0,2 
wberrtext      dc.b    'Not Enough ChipRAM',0 
               CNOP    0,2 

*********** IntuiText structures for the error requester messages ********** 

noiconlibmess   dc.b    0,1        
                dc.b    RP_JAM1,0  
                dc.w    75,20        
                dc.l    0          
                dc.l    noiconlibtext 
                dc.l    0           
 
notooltypemess  dc.b    0,1        
                dc.b    RP_JAM1,0  
                dc.w    60,20        
                dc.l    0          
                dc.l    notooltypetext 
                dc.l    0           

nomemsizemess   dc.b    0,1        
                dc.b    RP_JAM1,0  
                dc.w    52,20        
                dc.l    0          
                dc.l    nomemsizetext 
                dc.l    0           

noobjmess       dc.b    0,1        
                dc.b    RP_JAM1,0 
                dc.w    60,20        
                dc.l    0          
                dc.l    noobjtext 
                dc.l    0           
 
wberrmess       dc.b    0,1        
                dc.b    RP_JAM1,0  
                dc.w    68,20        
                dc.l    0          
                dc.l    wberrtext 
                dc.l    0           

darnmess        dc.b    0,1             ; it_FrontPen, it_BackPen 
                dc.b    RP_JAM1,0       ; it_DrawMode, it_KludgeFill00 
                dc.w    6,3             ; it_LeftEdge, it_TopEdge 
                dc.l    0               ; it_ITextFont 
                dc.l    darntext        ; it_IText 
                dc.l    0               ; it_NextText 
 


                SECTION foo,DATA 
name            dc.b    'expansion ram',0 
                END 

