                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 available!!!
		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 an
                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

