	IFND	BLIZKICKMODULE_I
BLIZKICKMODULE_I	SET	1
**
**	$VER: blizkickmodule.i 1.6 (25.2.2000)
**	Includes Release 1.6
**
**	Macros and defines for BlizKick's "modules" and "patches".
**
**	(C) Copyright 1996-2000 PitPlane Productions.
**	    All Rights Reserved
**

    IFND EXEC_TYPES_I
    INCLUDE "exec/types.i"
    ENDC ; EXEC_TYPES_I

    IFND EXEC_NODES_I
    INCLUDE "exec/nodes.i"
    ENDC ; EXEC_NODES_I

    IFND EXEC_RESIDENT_I
    INCLUDE "exec/resident.i"
    ENDC ; EXEC_RESIDENT_I


;
;   "Modules" are executable files that are loaded with LoadSeg(). Only the
; first segment can be used and the code *MUST* be PC-relative. Modules contain
; a LONG id and Resident Tag. This resident tag will be added to KS ROM. There
; are two macros defined in this file (BK_MOD and BK_MODA), which can be used
; (=should be used) to create "Modules".
;
;   "Module" can (from BlizKick V1.6 on) also be a patch, in which case macro
; called BK_PTC should be used to create it. See macro definition below for
; detailed information. Note that "patch" needn't be fully PC-relative (the
; patching code can be relocatable, it is loaded with LoadSeg() after all).
;
;
; bkm_Flags
; ~~~~~~~~~
; Normally modules can be installed multiple times, but if bkm_Flags has
; BKMB_SingleMode bit set then this module (RT_NAME and RT_PRI match) can be
; found from ROM only once.
;
; If bkm_Flags has BKMB_ReplaceMode bit set then the ROM is scanned for Resident
; Tag with same name (RT_NAME) and priority (RT_PRI) as in this "module". If
; such resident is found it'll be replaced (overwritten) by module's Resident
; Tag. This feature must be considered as "hackish", because resident tags don't
; always be in ROM as one big chunk, but are split into thousand and one little
; pieces... :-( Additionally there are usually code and data inside Resident Tag
; which has nothing to do with that Tag... :.-((. So, if you'd like like to
; safely(?) replace OS Resident Tags you should use this flag in conjugation
; with BKMB_ExtResBuf.
;
; With this feature you could, for example, replace 'exec.library' resident
; with better one, improve KS3.x 'alert.hook' or improve KS1.3 'bootstrap'...
; It's up to you, Coders...
;
; If you specify BKMB_ExtResBuf flag this module will require it to be installed
; to external Resident Tag buffer created by EXTRESBUF feature of the BlizKick.
; Using this makes only(?) sense with BKMB_ReplaceMode...
;
; It was one shiny day I got up with this *great* idea of "modules". Kickstart
; MapROM tools will never be the same again... ;-)
;



BKMODULE_ID	EQU	$707A4E75	; moveq #'z',d0; rts
BKEP_ID	EQU	$4E71		; nop ;-)

ERH_API_V1	EQU	1

	; bkm_Flags:

	BITDEF	BKM,ReplaceMode,0	; Turn on REPLACE MODE
	BITDEF	BKM,SingleMode,1	; Do *not* allow same "module" multiple times
	BITDEF	BKM,ExtResBuf,2		; Require EXTRESBUF for this module
BKMF_ALL EQU	BKMF_ReplaceMode!BKMF_SingleMode!BKMF_ExtResBuf

	STRUCTURE bkmodule,0
	ULONG	bkm_ID			; Must be BKMODULE_ID
	UWORD	bkm_Flags		; See above
	STRUCT	bkm_ResTag,RT_SIZE	; Resident Tag (not relocated!)
;;	LABEL	bkmodule_SIZEOF		; There's no SIZEOF!


;
; BK_MOD -- Create a simple ResidentTag without AUTOINIT
;
; mflags   - "Module" flags, see above.
; end      - ptr to end of this ResidentTag
; flags    - ResidentTag flags
; reqver   - required KS version for this module. This is *NOT*
;	     the ResidentTag version, but required version to use this
;	     module. ResidentTag version will be forced to current
;	     ROM version.
; type     - type of module (NT_XXXXXX)
; pri      - priority for this ResidentTag
; name     - ptr to name of this ResidentTag
; idstring - ptr to idstring of this ResidentTag
; init     - ptr to init code

; no-autoinit-module:
BK_MOD	MACRO	*mflags,end,flags<<24+reqver<<16+type<<8+pri,name,idstring,init
	IFGT	NARG-6
	FAIL	!!!! TOO MANY ARGUMENTS TO BK_MOD !!!!
	MEXIT
	ELSE
	IFGT	6-NARG
	FAIL	!!!! TOO FEW ARGUMENTS TO BK_MOD !!!!
	MEXIT
	ENDC
	ENDC
	dc.l	BKMODULE_ID
	dc.w	\1
.mod\@	dc.w	RTC_MATCHWORD
	dc.l	0
	dc.l	(\2)-.mod\@
	dc.l	(\3)&~(RTF_AUTOINIT<<24)
	dc.l	(\4)-.mod\@
	dc.l	(\5)-.mod\@
	dc.l	(\6)-.mod\@
	ENDM


;
; BK_MODA -- Create a complex ResidentTag with AUTOINIT (library/device/resource?)
;
; mflags   - "Module" flags, see above.
; end      - ptr to end of this ResidentTag
; flags    - ResidentTag flags
; reqver   - required KS version for this module. This is *NOT*
;	     the ResidentTag version, but required version to use this
;	     module. ResidentTag version will be forced to current
;	     ROM version.
; type     - type of module (NT_XXXXXX)
; pri      - priority for this ResidentTag
; name     - ptr to name of this ResidentTag
; idstring - ptr to idstring of this ResidentTag
; size     - see exec.library/InitResident
; funcs    - see exec.library/InitResident
; initstruct - see exec.library/InitResident
; initfunc - see exec.library/InitResident

; autoinit-module:
BK_MODA	MACRO	*mflags,end,flags<<24+reqver<<16+type<<8+pri,name,idstring,size,funcs,initstruct,initfunc
	IFGT	NARG-9
	FAIL	!!!! TOO MANY ARGUMENTS TO BK_MODA !!!!
	MEXIT
	ELSE
	IFGT	9-NARG
	FAIL	!!!! TOO FEW ARGUMENTS TO BK_MODA !!!!
	MEXIT
	ENDC
	ENDC
	dc.l	BKMODULE_ID
	dc.w	\1
.mod\@	dc.w	RTC_MATCHWORD
	dc.l	0
	dc.l	(\2)-.mod\@
	dc.l	(\3)!(RTF_AUTOINIT<<24)
	dc.l	(\4)-.mod\@
	dc.l	(\5)-.mod\@
	dc.l	.mod2\@-.mod\@
.mod2\@	dc.l	\6
	dc.l	(\7)-.mod\@
	dc.l	(\8)-.mod\@
	dc.l	(\9)-.mod\@
	ENDM


;
; BK_PTC -- Create a header for BlizKick external patch
;
;   Notes
;   ~~~~~
; Code is run with following incoming parameters:
;
; a0=ptr to ROM start (buffer)	eg. $1DE087B8
; a1=ptr to ROM start (ROM)	eg. $00F80000 (do *not* access!)
; d0=ROM lenght in bytes	eg. $00080000
; a2=ptr to _FindResident routine (will search ROM buffer for resident tag):
;    CALL: jsr (a2)
;      IN: a0=ptr to ROM, d0=rom len, a1=ptr to resident name
;     OUT: d0=ptr to resident (buf) or NULL
; a3=ptr to _InstallModule routine (can be used to plant a "module"):
;    CALL: jsr (a3)
;      IN: a0=ptr to ROM, d0=rom len, a1=ptr to module, d6=dosbase
;     OUT: d0=success
; a4=ptr to _Printf routine (will dump some silly things (errormsg?) to stdout ;-)
;    CALL: jsr (a4)
;      IN: a0=FmtString, a1=Array (may be 0), d6=dosbase
;     OUT: -
; d6=dosbase, a6=execbase
;
; Code should return:
;
; d0=true if succeeded, false if failed.
; d1-d7/a0-a6 can be trashed. a7 *must* be preserved! ;-)
;
; Code doesn't need to worry about cache flushing after it has done its
; modifications. If the patch code requires some new KS (3.x) features
; you *must* test for approriate KS version!! If patch code is run you
; can assume that you're running on at least AmigaOS 2.0 (V36). Note the
; difference between os version you're running atm and os version user
; is going to boot.
;
; Please, be as fast as possible because user might want to add *several*
; patches! Also note that _Printf output is supressed if user specifies
; QUIET switch.
;
; The macro is used like this:
;
;	SECTION	PATCH,CODE
;
;_SEGSTART_DUMMY:
;
;	BK_PTC
;
;patchcode:
;	cmp.w	#37,($C,A0)	; This patch requires V37 ROM (KS 2.04) or better...
;	blo.b	.fail
;
;	subq.l	#6,d0		; don't test past end
;	move.l	#$xxxxxxxx,d1	; Search for (xxxxxxxx,yyyyyyyy,zzzzzzzz):
;.find;	addq.l	#2,a0
;	subq.l	#2,d0
;	beq.b	.fail
;	cmp.l	(a0),d1
;	bne.b	.find
;	cmp.l	#$yyyyyyyy,(4,a0)
;	bne.b	.find
;	cmp.l	#$zzzzzzzz,(8,a0)
;	bne.b	.find
;	bra.b	.found
;
;.fail	moveq	#0,d0
;	rts
;
;.found	movem.l	d2-d7/a2-a6,-(sp)
;
;	do the patching...
;	...etc...
;
;	movem.l	(sp)+,d2-d7/a2-a6
;	moveq	#1,d0
;	rts
;

; external patch:
BK_PTC	MACRO
	IFGT	NARG
	FAIL	!!!! BK_PTC DOES NOT TAKE ANY ARGUMENTS !!!!
	MEXIT
	ENDC
	dc.l	BKMODULE_ID
	dc.w	0,BKEP_ID
	ENDM


; Following macros can be used to create function tables for devices, libraries
; and resources:

BK_INITFUNCS	MACRO	*label
	IFGT	NARG-1
	FAIL	!!!! TOO MANY ARGUMENTS TO BK_INITFUNCS !!!!
	MEXIT
	ELSE
	IFGT	1-NARG
	FAIL	!!!! TOO FEW ARGUMENTS TO BK_INITFUNCS !!!!
	MEXIT
	ENDC
	ENDC
	CNOP	0,2
\1
_BKM_FB_GLOBAL\@
	dc.w	-1
.BKM_FUNCBASE	EQU	*-2
	ENDM

BK_FUNC	MACRO	*funclabel
	IFGT	NARG-1
	FAIL	!!!! TOO MANY ARGUMENTS TO BK_FUNC !!!!
	MEXIT
	ELSE
	IFGT	1-NARG
	FAIL	!!!! TOO FEW ARGUMENTS TO BK_FUNC !!!!
	MEXIT
	ENDC
	ENDC
	dc.w	(\1)-.BKM_FUNCBASE
	ENDM

BK_ENDFUNCS	MACRO
	IFGT	NARG
	FAIL	!!!! BK_ENDFUNCS DOES NOT TAKE ANY ARGUMENTS !!!!
	MEXIT
	ENDC
	dc.w	-1
	ENDM

	ENDC	; BLIZKICKMODULE_I
