shithub: pokered

Download patch

ref: 032f961ef26a94caf385f6d5ae5823a0066d4d66
parent: 52bb07ca18f5475eb9a11c69bf8fee75bcb1abff
author: dannye <corrnondacqb@yahoo.com>
date: Sun Jul 31 09:04:04 EDT 2016

Split macros.asm

--- a/constants.asm
+++ b/constants.asm
@@ -29,5 +29,4 @@
 INCLUDE "constants/tilesets.asm"
 INCLUDE "constants/starter_mons.asm"
 INCLUDE "constants/event_constants.asm"
-INCLUDE "constants/event_macros.asm"
 INCLUDE "constants/text_constants.asm"
--- a/constants/event_macros.asm
+++ /dev/null
@@ -1,441 +1,0 @@
-;\1 = event index
-;\2 = return result in carry instead of zero flag
-CheckEvent: MACRO
-event_byte = ((\1) / 8)
-	ld a, [wEventFlags + event_byte]
-
-	IF _NARG > 1
-		IF ((\1) % 8) == 7
-			add a
-		ELSE
-			REPT ((\1) % 8) + 1
-				rrca
-			ENDR
-		ENDC
-	ELSE
-		bit (\1) % 8, a
-	ENDC
-	ENDM
-
-;\1 = event index
-CheckEventReuseA: MACRO
-	IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld a, [wEventFlags + event_byte]
-	ENDC
-
-	bit (\1) % 8, a
-	ENDM
-
-;\1 = event index
-;\2 = event index of the last event used before the branch
-CheckEventAfterBranchReuseA: MACRO
-event_byte = ((\2) / 8)
-	IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld a, [wEventFlags + event_byte]
-	ENDC
-
-	bit (\1) % 8, a
-	ENDM
-
-;\1 = reg
-;\2 = event index
-;\3 = event index this event is relative to (optional, this is needed when there is a fixed flag address)
-EventFlagBit: MACRO
-	IF _NARG > 2
-		ld \1, ((\3) % 8) + ((\2) - (\3))
-	ELSE
-		ld \1, (\2) % 8
-	ENDC
-	ENDM
-
-;\1 = reg
-;\2 = event index
-EventFlagAddress: MACRO
-event_byte = ((\2) / 8)
-	ld \1, wEventFlags + event_byte
-	ENDM
-
-;\1 = event index
-CheckEventHL: MACRO
-event_byte = ((\1) / 8)
-	ld hl, wEventFlags + event_byte
-	bit (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-CheckEventReuseHL: MACRO
-IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld hl, wEventFlags + event_byte
-	ENDC
-
-	bit (\1) % 8, [hl]
-	ENDM
-
-; dangerous, only use when HL is guaranteed to be the desired value
-;\1 = event index
-CheckEventForceReuseHL: MACRO
-event_byte = ((\1) / 8)
-	bit (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-;\2 = event index of the last event used before the branch
-CheckEventAfterBranchReuseHL: MACRO
-event_byte = ((\2) / 8)
-IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld hl, wEventFlags + event_byte
-	ENDC
-
-	bit (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-CheckAndSetEvent: MACRO
-event_byte = ((\1) / 8)
-	ld hl, wEventFlags + event_byte
-	bit (\1) % 8, [hl]
-	set (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-CheckAndResetEvent: MACRO
-event_byte = ((\1) / 8)
-	ld hl, wEventFlags + event_byte
-	bit (\1) % 8, [hl]
-	res (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-CheckAndSetEventA: MACRO
-	ld a, [wEventFlags + ((\1) / 8)]
-	bit (\1) % 8, a
-	set (\1) % 8, a
-	ld [wEventFlags + ((\1) / 8)], a
-	ENDM
-
-;\1 = event index
-CheckAndResetEventA: MACRO
-	ld a, [wEventFlags + ((\1) / 8)]
-	bit (\1) % 8, a
-	res (\1) % 8, a
-	ld [wEventFlags + ((\1) / 8)], a
-	ENDM
-
-;\1 = event index
-SetEvent: MACRO
-event_byte = ((\1) / 8)
-	ld hl, wEventFlags + event_byte
-	set (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-SetEventReuseHL: MACRO
-	IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld hl, wEventFlags + event_byte
-	ENDC
-
-	set (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-;\2 = event index of the last event used before the branch
-SetEventAfterBranchReuseHL: MACRO
-event_byte = ((\2) / 8)
-IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld hl, wEventFlags + event_byte
-	ENDC
-
-	set (\1) % 8, [hl]
-	ENDM
-
-; dangerous, only use when HL is guaranteed to be the desired value
-;\1 = event index
-SetEventForceReuseHL: MACRO
-event_byte = ((\1) / 8)
-	set (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-;\2 = event index
-;\3, \4, ... = additional (optional) event indices
-SetEvents: MACRO
-	SetEvent \1
-	rept (_NARG + -1)
-	SetEventReuseHL \2
-	shift
-	endr
-	ENDM
-
-;\1 = event index
-ResetEvent: MACRO
-event_byte = ((\1) / 8)
-	ld hl, wEventFlags + event_byte
-	res (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-ResetEventReuseHL: MACRO
-	IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld hl, wEventFlags + event_byte
-	ENDC
-
-	res (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-;\2 = event index of the last event used before the branch
-ResetEventAfterBranchReuseHL: MACRO
-event_byte = ((\2) / 8)
-IF event_byte != ((\1) / 8)
-event_byte = ((\1) / 8)
-		ld hl, wEventFlags + event_byte
-	ENDC
-
-	res (\1) % 8, [hl]
-	ENDM
-
-; dangerous, only use when HL is guaranteed to be the desired value
-;\1 = event index
-ResetEventForceReuseHL: MACRO
-event_byte = ((\1) / 8)
-	res (\1) % 8, [hl]
-	ENDM
-
-;\1 = event index
-;\2 = event index
-;\3 = event index (optional)
-ResetEvents: MACRO
-	ResetEvent \1
-	rept (_NARG + -1)
-	ResetEventReuseHL \2
-	shift
-	endr
-	ENDM
-
-;\1 = event index
-;\2 = number of bytes away from the base address (optional, for matching the ROM)
-dbEventFlagBit: MACRO
-	IF _NARG > 1
-		db ((\1) % 8) + ((\2) * 8)
-	ELSE
-		db ((\1) % 8)
-	ENDC
-	ENDM
-
-;\1 = event index
-;\2 = number of bytes away from the base address (optional, for matching the ROM)
-dwEventFlagAddress: MACRO
-	IF _NARG > 1
-		dw wEventFlags + ((\1) / 8) - (\2)
-	ELSE
-		dw wEventFlags + ((\1) / 8)
-	ENDC
-	ENDM
-
-;\1 = start
-;\2 = end
-SetEventRange: MACRO
-event_start_byte = ((\1) / 8)
-event_end_byte = ((\2) / 8)
-
-	IF event_end_byte < event_start_byte
-		FAIL "Incorrect argument order in SetEventRange."
-	ENDC
-
-	IF event_start_byte == event_end_byte
-		ld a, [wEventFlags + event_start_byte]
-		or (1 << (((\2) % 8) + 1)) - (1 << ((\1) % 8))
-		ld [wEventFlags + event_start_byte], a
-	ELSE
-event_fill_start = event_start_byte + 1
-event_fill_count = event_end_byte - event_start_byte - 1
-
-		IF ((\1) % 8) == 0
-event_fill_start = event_fill_start + -1
-event_fill_count = event_fill_count + 1
-		ELSE
-			ld a, [wEventFlags + event_start_byte]
-			or $ff - ((1 << ((\1) % 8)) - 1)
-			ld [wEventFlags + event_start_byte], a
-		ENDC
-
-		IF ((\2) % 8) == 7
-event_fill_count = event_fill_count + 1
-		ENDC
-
-		IF event_fill_count == 1
-			ld hl, wEventFlags + event_fill_start
-			ld [hl], $ff
-		ENDC
-
-		IF event_fill_count > 1
-			ld a, $ff
-			ld hl, wEventFlags + event_fill_start
-
-			REPT event_fill_count + -1
-				ld [hli], a
-			ENDR
-
-			ld [hl], a
-		ENDC
-
-		IF ((\2) % 8) == 0
-			ld hl, wEventFlags + event_end_byte
-			set 0, [hl]
-		ELSE
-			IF ((\2) % 8) != 7
-				ld a, [wEventFlags + event_end_byte]
-				or (1 << (((\2) % 8) + 1)) - 1
-				ld [wEventFlags + event_end_byte], a
-			ENDC
-		ENDC
-	ENDC
-	ENDM
-
-;\1 = start
-;\2 = end
-;\3 = assume a is 0 if present
-ResetEventRange: MACRO
-event_start_byte = ((\1) / 8)
-event_end_byte = ((\2) / 8)
-
-	IF event_end_byte < event_start_byte
-		FAIL "Incorrect argument order in ResetEventRange."
-	ENDC
-
-	IF event_start_byte == event_end_byte
-		ld a, [wEventFlags + event_start_byte]
-		and ~((1 << (((\2) % 8) + 1)) - (1 << ((\1) % 8))) & $ff
-		ld [wEventFlags + event_start_byte], a
-	ELSE
-event_fill_start = event_start_byte + 1
-event_fill_count = event_end_byte - event_start_byte - 1
-
-		IF ((\1) % 8) == 0
-event_fill_start = event_fill_start + -1
-event_fill_count = event_fill_count + 1
-		ELSE
-			ld a, [wEventFlags + event_start_byte]
-			and ~($ff - ((1 << ((\1) % 8)) - 1)) & $ff
-			ld [wEventFlags + event_start_byte], a
-		ENDC
-
-		IF ((\2) % 8) == 7
-event_fill_count = event_fill_count + 1
-		ENDC
-
-		IF event_fill_count == 1
-			ld hl, wEventFlags + event_fill_start
-			ld [hl], 0
-		ENDC
-
-		IF event_fill_count > 1
-			ld hl, wEventFlags + event_fill_start
-
-			; force xor a if we just to wrote to it above
-			IF (_NARG < 3) || (((\1) % 8) != 0)
-				xor a
-			ENDC
-
-			REPT event_fill_count + -1
-				ld [hli], a
-			ENDR
-
-			ld [hl], a
-		ENDC
-
-		IF ((\2) % 8) == 0
-			ld hl, wEventFlags + event_end_byte
-			res 0, [hl]
-		ELSE
-			IF ((\2) % 8) != 7
-				ld a, [wEventFlags + event_end_byte]
-				and ~((1 << (((\2) % 8) + 1)) - 1) & $ff
-				ld [wEventFlags + event_end_byte], a
-			ENDC
-		ENDC
-	ENDC
-	ENDM
-
-; returns whether both events are set in Z flag
-; This is counter-intuitive because the other event checks set the Z flag when
-; the event is not set, but this sets the Z flag when the event is set.
-;\1 = event index 1
-;\2 = event index 2
-;\3 = try to reuse a (optional)
-CheckBothEventsSet: MACRO
-	IF ((\1) / 8) == ((\2) / 8)
-		IF (_NARG < 3) || (((\1) / 8) != event_byte)
-event_byte = ((\1) / 8)
-			ld a, [wEventFlags + ((\1) / 8)]
-		ENDC
-		and (1 << ((\1) % 8)) | (1 << ((\2) % 8))
-		cp (1 << ((\1) % 8)) | (1 << ((\2) % 8))
-	ELSE
-		; This case doesn't happen in the original ROM.
-		IF ((\1) % 8) == ((\2) % 8)
-			push hl
-			ld a, [wEventFlags + ((\1) / 8)]
-			ld hl, wEventFlags + ((\2) / 8)
-			and [hl]
-			cpl
-			bit ((\1) % 8), a
-			pop hl
-		ELSE
-			push bc
-			ld a, [wEventFlags + ((\1) / 8)]
-			and (1 << ((\1) % 8))
-			ld b, a
-			ld a, [wEventFlags + ((\2) / 8)]
-			and (1 << ((\2) % 8))
-			or b
-			cp (1 << ((\1) % 8)) | (1 << ((\2) % 8))
-			pop bc
-		ENDC
-	ENDC
-	ENDM
-
-; returns the complement of whether either event is set in Z flag
-;\1 = event index 1
-;\2 = event index 2
-CheckEitherEventSet: MACRO
-	IF ((\1) / 8) == ((\2) / 8)
-		ld a, [wEventFlags + ((\1) / 8)]
-		and (1 << ((\1) % 8)) | (1 << ((\2) % 8))
-	ELSE
-		; This case doesn't happen in the original ROM.
-		IF ((\1) % 8) == ((\2) % 8)
-			push hl
-			ld a, [wEventFlags + ((\1) / 8)]
-			ld hl, wEventFlags + ((\2) / 8)
-			or [hl]
-			bit ((\1) % 8), a
-			pop hl
-		ELSE
-			push bc
-			ld a, [wEventFlags + ((\1) / 8)]
-			and (1 << ((\1) % 8))
-			ld b, a
-			ld a, [wEventFlags + ((\2) / 8)]
-			and (1 << ((\2) % 8))
-			or b
-			pop bc
-		ENDC
-	ENDC
-	ENDM
-
-; for handling fixed event bits when events are inserted/removed
-;\1 = event index
-;\2 = fixed flag bit
-AdjustEventBit: MACRO
-	IF ((\1) % 8) != (\2)
-		add ((\1) % 8) - (\2)
-	ENDC
-	ENDM
--- a/macros.asm
+++ b/macros.asm
@@ -1,767 +1,5 @@
-
-percent EQUS "* $ff / 100"
-
-lb: MACRO ; r, hi, lo
-	ld \1, (\2) << 8 + ((\3) & $ff)
-	ENDM
-
-
-; Constant enumeration is useful for monsters, items, moves, etc.
-const_def: MACRO
-const_value = 0
-ENDM
-
-const: MACRO
-\1 EQU const_value
-const_value = const_value + 1
-ENDM
-
-
-homecall: MACRO
-	ld a, [H_LOADEDROMBANK]
-	push af
-	ld a, BANK(\1)
-	ld [H_LOADEDROMBANK], a
-	ld [MBC1RomBank], a
-	call \1
-	pop af
-	ld [H_LOADEDROMBANK], a
-	ld [MBC1RomBank], a
-	ENDM
-
-farcall EQUS "callba"
-
-callba: MACRO
-	ld b, BANK(\1)
-	ld hl, \1
-	call Bankswitch
-	ENDM
-
-callab: MACRO
-	ld hl, \1
-	ld b, BANK(\1)
-	call Bankswitch
-	ENDM
-
-jpba: MACRO
-	ld b, BANK(\1)
-	ld hl, \1
-	jp Bankswitch
-	ENDM
-
-jpab: MACRO
-	ld hl, \1
-	ld b, BANK(\1)
-	jp Bankswitch
-	ENDM
-
-bcd2: MACRO
-	dn ((\1) / 1000) % 10, ((\1) / 100) % 10
-	dn ((\1) / 10) % 10, (\1) % 10
-	ENDM
-
-bcd3: MACRO
-	dn ((\1) / 100000) % 10, ((\1) / 10000) % 10
-	dn ((\1) / 1000) % 10, ((\1) / 100) % 10
-	dn ((\1) / 10) % 10, (\1) % 10
-	ENDM
-
-coins equs "bcd2"
-money equs "bcd3"
-
-validateCoords: MACRO
-	if \1 >= SCREEN_WIDTH
-		fail "x coord out of range"
-	endc
-	if \2 >= SCREEN_HEIGHT
-		fail "y coord out of range"
-	endc
-	endm
-
-;\1 = r
-;\2 = X
-;\3 = Y
-;\4 = which tilemap (optional)
-coord: MACRO
-	validateCoords \2, \3
-if _NARG >= 4
-	ld \1, \4 + SCREEN_WIDTH * \3 + \2
-else
-	ld \1, wTileMap + SCREEN_WIDTH * \3 + \2
-endc
-	ENDM
-
-;\1 = X
-;\2 = Y
-;\3 = which tilemap (optional)
-aCoord: MACRO
-	validateCoords \1, \2
-if _NARG >= 3
-	ld a, [\3 + SCREEN_WIDTH * \2 + \1]
-else
-	ld a, [wTileMap + SCREEN_WIDTH * \2 + \1]
-endc
-	ENDM
-
-;\1 = X
-;\2 = Y
-;\3 = which tilemap (optional)
-Coorda: MACRO
-	validateCoords \1, \2
-if _NARG >= 3
-	ld [\3 + SCREEN_WIDTH * \2 + \1], a
-else
-	ld [wTileMap + SCREEN_WIDTH * \2 + \1], a
-endc
-	ENDM
-
-;\1 = X
-;\2 = Y
-;\3 = which tilemap (optional)
-dwCoord: MACRO
-	validateCoords \1, \2
-if _NARG >= 3
-	dw \3 + SCREEN_WIDTH * \2 + \1
-else
-	dw wTileMap + SCREEN_WIDTH * \2 + \1
-endc
-	ENDM
-
-;\1 = r
-;\2 = X
-;\3 = Y
-;\4 = map width
-overworldMapCoord: MACRO
-	ld \1, wOverworldMap + ((\2) + 3) + (((\3) + 3) * ((\4) + (3 * 2)))
-	ENDM
-
-;\1 = Map Width
-;\2 = Rows above (Y-blocks)
-;\3 = X movement (X-blocks)
-EVENT_DISP: MACRO
-	dw (wOverworldMap + 7 + (\1) + ((\1) + 6) * ((\2) >> 1) + ((\3) >> 1)) ; Ev.Disp
-	db \2,\3 ;Y,X
-	ENDM
-
-FLYWARP_DATA: MACRO
-	EVENT_DISP \1,\2,\3
-	db ((\2) & $01) ;sub-block Y
-	db ((\3) & $01) ;sub-block X
-	ENDM
-
-; external map entry macro
-EMAP: MACRO ; emap x-coordinate,y-coordinate,textpointer
-; the appearance of towns and routes in the town map, indexed by map id
-	; nybble: y-coordinate
-	; nybble: x-coordinate
-	; word  : pointer to map name
-	dn \2, \1
-	dw \3
-	ENDM
-
-; internal map entry macro
-IMAP: MACRO ; imap mapid_less_than,x-coordinate,y-coordinate,textpointer
-; the appearance of buildings and dungeons in the town map
-	; byte  : maximum map id subject to this rule
-	; nybble: y-coordinate
-	; nybble: x-coordinate
-	; word  : pointer to map name
-	db \1 + 1
-	dn \3, \2
-	dw \4
-	ENDM
-
-; tilesets' headers macro
-tileset: MACRO
-	db BANK(\2)   ; BANK(GFX)
-	dw \1, \2, \3 ; Block, GFX, Coll
-	db \4, \5, \6 ; counter tiles
-	db \7         ; grass tile
-	db \8         ; permission (indoor, cave, outdoor)
-	ENDM
-
-INDOOR  EQU 0
-CAVE    EQU 1
-OUTDOOR EQU 2
-
-; macro for two nibbles
-dn: MACRO
-	db (\1 << 4 | \2)
-	ENDM
-
-; macro for putting a byte then a word
-dbw: MACRO
-	db \1
-	dw \2
-	ENDM
-
-dba: MACRO
-	dbw BANK(\1), \1
-	ENDM
-
-dwb: MACRO
-	dw \1
-	db \2
-	ENDM
-
-dab: MACRO
-	dwb \1, BANK(\1)
-	ENDM
-
-dbbw: MACRO
-	db \1, \2
-	dw \3
-	ENDM
-
-; data format macros
-RGB: MACRO
-	dw (\3 << 10 | \2 << 5 | \1)
-	ENDM
-
-; text macros
-text   EQUS "db $00," ; Start writing text.
-next   EQUS "db $4e," ; Move a line down.
-line   EQUS "db $4f," ; Start writing at the bottom line.
-para   EQUS "db $51," ; Start a new paragraph.
-cont   EQUS "db $55," ; Scroll to the next line.
-done   EQUS "db $57"  ; End a text box.
-prompt EQUS "db $58"  ; Prompt the player to end a text box (initiating some other event).
-
-page   EQUS "db $49,"     ; Start a new Pokedex page.
-dex    EQUS "db $5f, $50" ; End a Pokedex entry.
-
-TX_RAM: MACRO
-; prints text to screen
-; \1: RAM address to read from
-	db $1
-	dw \1
-	ENDM
-
-TX_BCD: MACRO
-; \1: RAM address to read from
-; \2: number of bytes + print flags
-	db $2
-	dw \1
-	db \2
-	ENDM
-
-TX_LINE    EQUS "db $05"
-TX_BLINK   EQUS "db $06"
-;TX_SCROLL EQUS "db $07"
-TX_ASM     EQUS "db $08"
-
-TX_NUM: MACRO
-; print a big-endian decimal number.
-; \1: address to read from
-; \2: number of bytes to read
-; \3: number of digits to display
-	db $09
-	dw \1
-	db \2 << 4 | \3
-	ENDM
-
-TX_DELAY              EQUS "db $0a"
-TX_SFX_ITEM_1         EQUS "db $0b"
-TX_SFX_LEVEL_UP       EQUS "db $0b"
-;TX_ELLIPSES          EQUS "db $0c"
-TX_WAIT               EQUS "db $0d"
-;TX_SFX_DEX_RATING    EQUS "db $0e"
-TX_SFX_ITEM_2         EQUS "db $10"
-TX_SFX_KEY_ITEM       EQUS "db $11"
-TX_SFX_CAUGHT_MON     EQUS "db $12"
-TX_SFX_DEX_PAGE_ADDED EQUS "db $13"
-TX_CRY_NIDORINA       EQUS "db $14"
-TX_CRY_PIDGEOT        EQUS "db $15"
-;TX_CRY_DEWGONG       EQUS "db $16"
-
-TX_FAR: MACRO
-	db $17
-	dw \1
-	db BANK(\1)
-	ENDM
-
-TX_VENDING_MACHINE         EQUS "db $f5"
-TX_CABLE_CLUB_RECEPTIONIST EQUS "db $f6"
-TX_PRIZE_VENDOR            EQUS "db $f7"
-TX_POKECENTER_PC           EQUS "db $f9"
-TX_PLAYERS_PC              EQUS "db $fc"
-TX_BILLS_PC                EQUS "db $fd"
-
-TX_MART: MACRO
-	db $FE, _NARG
-	rept _NARG
-	db \1
-	shift
-	endr
-	db $FF
-	ENDM
-
-TX_POKECENTER_NURSE        EQUS "db $ff"
-
-; Predef macro.
-predef_const: MACRO
-	const \1PredefID
-	ENDM
-
-add_predef: MACRO
-\1Predef::
-	db BANK(\1)
-	dw \1
-	ENDM
-
-predef_id: MACRO
-	ld a, (\1Predef - PredefPointers) / 3
-	ENDM
-
-predef: MACRO
-	predef_id \1
-	call Predef
-	ENDM
-
-predef_jump: MACRO
-	predef_id \1
-	jp Predef
-	ENDM
-
-tx_pre_const: MACRO
-	const \1_id
-	ENDM
-
-add_tx_pre: MACRO
-\1_id:: dw \1
-ENDM
-
-db_tx_pre: MACRO
-	db (\1_id - TextPredefs) / 2 + 1
-ENDM
-
-tx_pre_id: MACRO
-	ld a, (\1_id - TextPredefs) / 2 + 1
-ENDM
-
-tx_pre: MACRO
-	tx_pre_id \1
-	call PrintPredefTextID
-ENDM
-
-tx_pre_jump: MACRO
-	tx_pre_id \1
-	jp PrintPredefTextID
-ENDM
-
-WALK EQU $FE
-STAY EQU $FF
-
-DOWN  EQU $D0
-UP    EQU $D1
-LEFT  EQU $D2
-RIGHT EQU $D3
-NONE  EQU $FF
-
-;\1 sprite id
-;\2 x position
-;\3 y position
-;\4 movement (WALK/STAY)
-;\5 range or direction
-;\6 text id
-;\7 items only: item id
-;\7 trainers only: trainer class/pokemon id
-;\8 trainers only: trainer number/pokemon level
-object: MACRO
-	db \1
-	db \3 + 4
-	db \2 + 4
-	db \4
-	db \5
-	IF (_NARG > 7)
-		db TRAINER | \6
-		db \7
-		db \8
-	ELSE
-		IF (_NARG > 6)
-			db ITEM | \6
-			db \7
-		ELSE
-			db \6
-		ENDC
-	ENDC
-ENDM
-
-StopAllMusic: macro
-	ld a, $ff
-	call PlaySound
-	endm
-
-Ch0    EQU 0
-Ch1    EQU 1
-Ch2    EQU 2
-Ch3    EQU 3
-Ch4    EQU 4
-Ch5    EQU 5
-Ch6    EQU 6
-Ch7    EQU 7
-
-audio: MACRO
-	db (_NARG - 2) << 6 | \2
-	dw \1_\2
-	IF _NARG > 2
-		db \3
-		dw \1_\3
-	ENDC
-	IF _NARG > 3
-		db \4
-		dw \1_\4
-	ENDC
-	IF _NARG > 4
-		db \5
-		dw \1_\5
-	ENDC
-ENDM
-
-unknownsfx0x10: MACRO
-	db $10
-	db \1
-ENDM
-
-unknownsfx0x20: MACRO
-	db $20 | \1
-	db \2
-	db \3
-	db \4
-ENDM
-
-unknownnoise0x20: MACRO
-	db $20 | \1
-	db \2
-	db \3
-ENDM
-
-;format: pitch length (in 16ths)
-C_: MACRO
-	db $00 | (\1 - 1)
-ENDM
-
-C#: MACRO
-	db $10 | (\1 - 1)
-ENDM
-
-D_: MACRO
-	db $20 | (\1 - 1)
-ENDM
-
-D#: MACRO
-	db $30 | (\1 - 1)
-ENDM
-
-E_: MACRO
-	db $40 | (\1 - 1)
-ENDM
-
-F_: MACRO
-	db $50 | (\1 - 1)
-ENDM
-
-F#: MACRO
-	db $60 | (\1 - 1)
-ENDM
-
-G_: MACRO
-	db $70 | (\1 - 1)
-ENDM
-
-G#: MACRO
-	db $80 | (\1 - 1)
-ENDM
-
-A_: MACRO
-	db $90 | (\1 - 1)
-ENDM
-
-A#: MACRO
-	db $A0 | (\1 - 1)
-ENDM
-
-B_: MACRO
-	db $B0 | (\1 - 1)
-ENDM
-
-;format: instrument length (in 16ths)
-snare1: MACRO
-	db $B0 | (\1 - 1)
-	db $01
-ENDM
-
-snare2: MACRO
-	db $B0 | (\1 - 1)
-	db $02
-ENDM
-
-snare3: MACRO
-	db $B0 | (\1 - 1)
-	db $03
-ENDM
-
-snare4: MACRO
-	db $B0 | (\1 - 1)
-	db $04
-ENDM
-
-snare5: MACRO
-	db $B0 | (\1 - 1)
-	db $05
-ENDM
-
-triangle1: MACRO
-	db $B0 | (\1 - 1)
-	db $06
-ENDM
-
-triangle2: MACRO
-	db $B0 | (\1 - 1)
-	db $07
-ENDM
-
-snare6: MACRO
-	db $B0 | (\1 - 1)
-	db $08
-ENDM
-
-snare7: MACRO
-	db $B0 | (\1 - 1)
-	db $09
-ENDM
-
-snare8: MACRO
-	db $B0 | (\1 - 1)
-	db $0A
-ENDM
-
-snare9: MACRO
-	db $B0 | (\1 - 1)
-	db $0B
-ENDM
-
-cymbal1: MACRO
-	db $B0 | (\1 - 1)
-	db $0C
-ENDM
-
-cymbal2: MACRO
-	db $B0 | (\1 - 1)
-	db $0D
-ENDM
-
-cymbal3: MACRO
-	db $B0 | (\1 - 1)
-	db $0E
-ENDM
-
-mutedsnare1: MACRO
-	db $B0 | (\1 - 1)
-	db $0F
-ENDM
-
-triangle3: MACRO
-	db $B0 | (\1 - 1)
-	db $10
-ENDM
-
-mutedsnare2: MACRO
-	db $B0 | (\1 - 1)
-	db $11
-ENDM
-
-mutedsnare3: MACRO
-	db $B0 | (\1 - 1)
-	db $12
-ENDM
-
-mutedsnare4: MACRO
-	db $B0 | (\1 - 1)
-	db $13
-ENDM
-
-;format: rest length (in 16ths)
-rest: MACRO
-	db $C0 | (\1 - 1)
-ENDM
-
-; format: notetype speed, volume, fade
-notetype: MACRO
-	db $D0 | \1
-	db (\2 << 4) | \3
-ENDM
-
-dspeed: MACRO
-	db $D0 | \1
-ENDM
-
-octave: MACRO
-	db $E8 - \1
-ENDM
-
-toggleperfectpitch: MACRO
-	db $E8
-ENDM
-
-;format: vibrato delay, rate, depth
-vibrato: MACRO
-	db $EA
-	db \1
-	db (\2 << 4) | \3
-ENDM
-
-pitchbend: MACRO
-	db $EB
-	db \1
-	db \2
-ENDM
-
-duty: MACRO
-	db $EC
-	db \1
-ENDM
-
-tempo: MACRO
-	db $ED
-	db \1 / $100
-	db \1 % $100
-ENDM
-
-stereopanning: MACRO
-	db $EE
-	db \1
-ENDM
-
-volume: MACRO
-	db $F0
-	db (\1 << 4) | \2
-ENDM
-
-executemusic: MACRO
-	db $F8
-ENDM
-
-dutycycle: MACRO
-	db $FC
-	db \1
-ENDM
-
-;format: callchannel address
-callchannel: MACRO
-	db $FD
-	dw \1
-ENDM
-
-;format: loopchannel count, address
-loopchannel: MACRO
-	db $FE
-	db \1
-	dw \2
-ENDM
-
-endchannel: MACRO
-	db $FF
-ENDM
-
-
-;\1 (byte) = current map id
-;\2 (byte) = connected map id
-;\3 (byte) = x movement of connection strip
-;\4 (byte) = connection strip offset
-;\5 (word) = connected map blocks pointer
-NORTH_MAP_CONNECTION: MACRO
-	db \2 ; map id
-	dw \5 + (\2_WIDTH * (\2_HEIGHT - 3)) + \4; "Connection Strip" location
-	dw wOverworldMap + 3 + \3 ; current map position
-	IF (\1_WIDTH < \2_WIDTH)
-		db \1_WIDTH - \3 + 3 ; width of connection strip
-	ELSE
-		db \2_WIDTH - \4 ; width of connection strip
-	ENDC
-	db \2_WIDTH ; map width
-	db (\2_HEIGHT * 2) - 1 ; y alignment (y coordinate of player when entering map)
-	db (\3 - \4) * -2 ; x alignment (x coordinate of player when entering map)
-	dw wOverworldMap + 1 + (\2_HEIGHT * (\2_WIDTH + 6)) ; window (position of the upper left block after entering the map)
-ENDM
-
-;\1 (byte) = current map id
-;\2 (byte) = connected map id
-;\3 (byte) = x movement of connection strip
-;\4 (byte) = connection strip offset
-;\5 (word) = connected map blocks pointer
-;\6 (flag) = add 3 to width of connection strip (why?)
-SOUTH_MAP_CONNECTION: MACRO
-	db \2 ; map id
-	dw \5 + \4 ; "Conection Strip" location
-	dw wOverworldMap + 3 + (\1_HEIGHT + 3) * (\1_WIDTH + 6) + \3 ; current map position
-	IF (\1_WIDTH < \2_WIDTH)
-		IF (_NARG > 5)
-			db \1_WIDTH - \3 + 3 ; width of connection strip
-		ELSE
-			db \1_WIDTH - \3 ; width of connection strip
-		ENDC
-	ELSE
-		db \2_WIDTH - \4 ; width of connection strip
-	ENDC
-	db \2_WIDTH ; map width
-	db 0  ; y alignment (y coordinate of player when entering map)
-	db (\3 - \4) * -2 ; x alignment (x coordinate of player when entering map)
-	dw wOverworldMap + 7 + \2_WIDTH ; window (position of the upper left block after entering the map)
-ENDM
-
-;\1 (byte) = current map id
-;\2 (byte) = connected map id
-;\3 (byte) = y movement of connection strip
-;\4 (byte) = connection strip offset
-;\5 (word) = connected map blocks pointer
-WEST_MAP_CONNECTION: MACRO
-	db \2 ; map id
-	dw \5 + (\2_WIDTH * \4) + \2_WIDTH - 3 ; "Connection Strip" location
-	dw wOverworldMap + (\1_WIDTH + 6) * (\3 + 3) ; current map position
-	IF (\1_HEIGHT < \2_HEIGHT)
-		db \1_HEIGHT - \3 + 3 ; height of connection strip
-	ELSE
-		db \2_HEIGHT - \4 ; height of connection strip
-	ENDC
-	db \2_WIDTH ; map width
-	db (\3 - \4) * -2 ; y alignment
-	db (\2_WIDTH * 2) - 1 ; x alignment
-	dw wOverworldMap + 6 + (2 * \2_WIDTH) ; window (position of the upper left block after entering the map)
-ENDM
-
-;\1 (byte) = current map id
-;\2 (byte) = connected map id
-;\3 (byte) = y movement of connection strip
-;\4 (byte) = connection strip offset
-;\5 (word) = connected map blocks pointer
-;\6 (flag) = add 3 to height of connection strip (why?)
-EAST_MAP_CONNECTION: MACRO
-	db \2 ; map id
-	dw \5 + (\2_WIDTH * \4) ; "Connection Strip" location
-	dw wOverworldMap - 3 + (\1_WIDTH + 6) * (\3 + 4) ; current map position
-	IF (\1_HEIGHT < \2_HEIGHT)
-		IF (_NARG > 5)
-			db \1_HEIGHT - \3 + 3 ; height of connection strip
-		ELSE
-			db \1_HEIGHT - \3 ; height of connection strip
-		ENDC
-	ELSE
-		db \2_HEIGHT - \4 ; height of connection strip
-	ENDC
-	db \2_WIDTH ; map width
-	db (\3 - \4) * -2 ; y alignment
-	db 0 ; x alignment
-	dw wOverworldMap + 7 + \2_WIDTH ; window (position of the upper left block after entering the map)
-ENDM
-
-tmlearn: MACRO
-x = 0
-	rept _NARG
-IF \1 != 0
-x = x | (1 << ((\1 - 1) % 8))
-ENDC
-	shift
-	endr
-	db x
-ENDM
+INCLUDE "macros/asm_macros.asm"
+INCLUDE "macros/data_macros.asm"
+INCLUDE "macros/text_macros.asm"
+INCLUDE "macros/audio_macros.asm"
+INCLUDE "macros/event_macros.asm"
--- /dev/null
+++ b/macros/asm_macros.asm
@@ -1,0 +1,188 @@
+
+lb: MACRO ; r, hi, lo
+	ld \1, (\2) << 8 + ((\3) & $ff)
+ENDM
+
+homecall: MACRO
+	ld a, [H_LOADEDROMBANK]
+	push af
+	ld a, BANK(\1)
+	ld [H_LOADEDROMBANK], a
+	ld [MBC1RomBank], a
+	call \1
+	pop af
+	ld [H_LOADEDROMBANK], a
+	ld [MBC1RomBank], a
+ENDM
+
+farcall EQUS "callba"
+
+callba: MACRO
+	ld b, BANK(\1)
+	ld hl, \1
+	call Bankswitch
+ENDM
+
+callab: MACRO
+	ld hl, \1
+	ld b, BANK(\1)
+	call Bankswitch
+ENDM
+
+jpba: MACRO
+	ld b, BANK(\1)
+	ld hl, \1
+	jp Bankswitch
+ENDM
+
+jpab: MACRO
+	ld hl, \1
+	ld b, BANK(\1)
+	jp Bankswitch
+ENDM
+
+validateCoords: MACRO
+	IF \1 >= SCREEN_WIDTH
+		fail "x coord out of range"
+	ENDC
+	IF \2 >= SCREEN_HEIGHT
+		fail "y coord out of range"
+	ENDC
+ENDM
+
+;\1 = r
+;\2 = X
+;\3 = Y
+;\4 = which tilemap (optional)
+coord: MACRO
+	validateCoords \2, \3
+	IF _NARG >= 4
+		ld \1, \4 + SCREEN_WIDTH * \3 + \2
+	ELSE
+		ld \1, wTileMap + SCREEN_WIDTH * \3 + \2
+	ENDC
+ENDM
+
+;\1 = X
+;\2 = Y
+;\3 = which tilemap (optional)
+aCoord: MACRO
+	validateCoords \1, \2
+	IF _NARG >= 3
+		ld a, [\3 + SCREEN_WIDTH * \2 + \1]
+	ELSE
+		ld a, [wTileMap + SCREEN_WIDTH * \2 + \1]
+	ENDC
+ENDM
+
+;\1 = X
+;\2 = Y
+;\3 = which tilemap (optional)
+Coorda: MACRO
+	validateCoords \1, \2
+	IF _NARG >= 3
+		ld [\3 + SCREEN_WIDTH * \2 + \1], a
+	ELSE
+		ld [wTileMap + SCREEN_WIDTH * \2 + \1], a
+	ENDC
+ENDM
+
+;\1 = X
+;\2 = Y
+;\3 = which tilemap (optional)
+dwCoord: MACRO
+	validateCoords \1, \2
+	IF _NARG >= 3
+		dw \3 + SCREEN_WIDTH * \2 + \1
+	ELSE
+		dw wTileMap + SCREEN_WIDTH * \2 + \1
+	ENDC
+ENDM
+
+;\1 = r
+;\2 = X
+;\3 = Y
+;\4 = map width
+overworldMapCoord: MACRO
+	ld \1, wOverworldMap + ((\2) + 3) + (((\3) + 3) * ((\4) + (3 * 2)))
+ENDM
+
+; macro for two nibbles
+dn: MACRO
+	db (\1 << 4 | \2)
+ENDM
+
+; macro for putting a byte then a word
+dbw: MACRO
+	db \1
+	dw \2
+ENDM
+
+dba: MACRO
+	dbw BANK(\1), \1
+ENDM
+
+dwb: MACRO
+	dw \1
+	db \2
+ENDM
+
+dab: MACRO
+	dwb \1, BANK(\1)
+ENDM
+
+dbbw: MACRO
+	db \1, \2
+	dw \3
+ENDM
+
+; Predef macro.
+predef_const: MACRO
+	const \1PredefID
+ENDM
+
+add_predef: MACRO
+\1Predef::
+	db BANK(\1)
+	dw \1
+ENDM
+
+predef_id: MACRO
+	ld a, (\1Predef - PredefPointers) / 3
+ENDM
+
+predef: MACRO
+	predef_id \1
+	call Predef
+ENDM
+
+predef_jump: MACRO
+	predef_id \1
+	jp Predef
+ENDM
+
+tx_pre_const: MACRO
+	const \1_id
+ENDM
+
+add_tx_pre: MACRO
+\1_id:: dw \1
+ENDM
+
+db_tx_pre: MACRO
+	db (\1_id - TextPredefs) / 2 + 1
+ENDM
+
+tx_pre_id: MACRO
+	ld a, (\1_id - TextPredefs) / 2 + 1
+ENDM
+
+tx_pre: MACRO
+	tx_pre_id \1
+	call PrintPredefTextID
+ENDM
+
+tx_pre_jump: MACRO
+	tx_pre_id \1
+	jp PrintPredefTextID
+ENDM
--- /dev/null
+++ b/macros/audio_macros.asm
@@ -1,0 +1,277 @@
+
+StopAllMusic: MACRO
+	ld a, $ff
+	call PlaySound
+ENDM
+
+Ch0    EQU 0
+Ch1    EQU 1
+Ch2    EQU 2
+Ch3    EQU 3
+Ch4    EQU 4
+Ch5    EQU 5
+Ch6    EQU 6
+Ch7    EQU 7
+
+audio: MACRO
+	db (_NARG - 2) << 6 | \2
+	dw \1_\2
+	IF _NARG > 2
+		db \3
+		dw \1_\3
+	ENDC
+	IF _NARG > 3
+		db \4
+		dw \1_\4
+	ENDC
+	IF _NARG > 4
+		db \5
+		dw \1_\5
+	ENDC
+ENDM
+
+unknownsfx0x10: MACRO
+	db $10
+	db \1
+ENDM
+
+unknownsfx0x20: MACRO
+	db $20 | \1
+	db \2
+	db \3
+	db \4
+ENDM
+
+unknownnoise0x20: MACRO
+	db $20 | \1
+	db \2
+	db \3
+ENDM
+
+;format: pitch length (in 16ths)
+C_: MACRO
+	db $00 | (\1 - 1)
+ENDM
+
+C#: MACRO
+	db $10 | (\1 - 1)
+ENDM
+
+D_: MACRO
+	db $20 | (\1 - 1)
+ENDM
+
+D#: MACRO
+	db $30 | (\1 - 1)
+ENDM
+
+E_: MACRO
+	db $40 | (\1 - 1)
+ENDM
+
+F_: MACRO
+	db $50 | (\1 - 1)
+ENDM
+
+F#: MACRO
+	db $60 | (\1 - 1)
+ENDM
+
+G_: MACRO
+	db $70 | (\1 - 1)
+ENDM
+
+G#: MACRO
+	db $80 | (\1 - 1)
+ENDM
+
+A_: MACRO
+	db $90 | (\1 - 1)
+ENDM
+
+A#: MACRO
+	db $A0 | (\1 - 1)
+ENDM
+
+B_: MACRO
+	db $B0 | (\1 - 1)
+ENDM
+
+;format: instrument length (in 16ths)
+snare1: MACRO
+	db $B0 | (\1 - 1)
+	db $01
+ENDM
+
+snare2: MACRO
+	db $B0 | (\1 - 1)
+	db $02
+ENDM
+
+snare3: MACRO
+	db $B0 | (\1 - 1)
+	db $03
+ENDM
+
+snare4: MACRO
+	db $B0 | (\1 - 1)
+	db $04
+ENDM
+
+snare5: MACRO
+	db $B0 | (\1 - 1)
+	db $05
+ENDM
+
+triangle1: MACRO
+	db $B0 | (\1 - 1)
+	db $06
+ENDM
+
+triangle2: MACRO
+	db $B0 | (\1 - 1)
+	db $07
+ENDM
+
+snare6: MACRO
+	db $B0 | (\1 - 1)
+	db $08
+ENDM
+
+snare7: MACRO
+	db $B0 | (\1 - 1)
+	db $09
+ENDM
+
+snare8: MACRO
+	db $B0 | (\1 - 1)
+	db $0A
+ENDM
+
+snare9: MACRO
+	db $B0 | (\1 - 1)
+	db $0B
+ENDM
+
+cymbal1: MACRO
+	db $B0 | (\1 - 1)
+	db $0C
+ENDM
+
+cymbal2: MACRO
+	db $B0 | (\1 - 1)
+	db $0D
+ENDM
+
+cymbal3: MACRO
+	db $B0 | (\1 - 1)
+	db $0E
+ENDM
+
+mutedsnare1: MACRO
+	db $B0 | (\1 - 1)
+	db $0F
+ENDM
+
+triangle3: MACRO
+	db $B0 | (\1 - 1)
+	db $10
+ENDM
+
+mutedsnare2: MACRO
+	db $B0 | (\1 - 1)
+	db $11
+ENDM
+
+mutedsnare3: MACRO
+	db $B0 | (\1 - 1)
+	db $12
+ENDM
+
+mutedsnare4: MACRO
+	db $B0 | (\1 - 1)
+	db $13
+ENDM
+
+;format: rest length (in 16ths)
+rest: MACRO
+	db $C0 | (\1 - 1)
+ENDM
+
+; format: notetype speed, volume, fade
+notetype: MACRO
+	db $D0 | \1
+	db (\2 << 4) | \3
+ENDM
+
+dspeed: MACRO
+	db $D0 | \1
+ENDM
+
+octave: MACRO
+	db $E8 - \1
+ENDM
+
+toggleperfectpitch: MACRO
+	db $E8
+ENDM
+
+;format: vibrato delay, rate, depth
+vibrato: MACRO
+	db $EA
+	db \1
+	db (\2 << 4) | \3
+ENDM
+
+pitchbend: MACRO
+	db $EB
+	db \1
+	db \2
+ENDM
+
+duty: MACRO
+	db $EC
+	db \1
+ENDM
+
+tempo: MACRO
+	db $ED
+	db \1 / $100
+	db \1 % $100
+ENDM
+
+stereopanning: MACRO
+	db $EE
+	db \1
+ENDM
+
+volume: MACRO
+	db $F0
+	db (\1 << 4) | \2
+ENDM
+
+executemusic: MACRO
+	db $F8
+ENDM
+
+dutycycle: MACRO
+	db $FC
+	db \1
+ENDM
+
+;format: callchannel address
+callchannel: MACRO
+	db $FD
+	dw \1
+ENDM
+
+;format: loopchannel count, address
+loopchannel: MACRO
+	db $FE
+	db \1
+	dw \2
+ENDM
+
+endchannel: MACRO
+	db $FF
+ENDM
--- /dev/null
+++ b/macros/data_macros.asm
@@ -1,0 +1,220 @@
+
+; Constant enumeration is useful for monsters, items, moves, etc.
+const_def: MACRO
+const_value = 0
+ENDM
+
+const: MACRO
+\1 EQU const_value
+const_value = const_value + 1
+ENDM
+
+; data format macros
+
+percent EQUS "* $ff / 100"
+
+bcd2: MACRO
+	dn ((\1) / 1000) % 10, ((\1) / 100) % 10
+	dn ((\1) / 10) % 10, (\1) % 10
+ENDM
+
+bcd3: MACRO
+	dn ((\1) / 100000) % 10, ((\1) / 10000) % 10
+	dn ((\1) / 1000) % 10, ((\1) / 100) % 10
+	dn ((\1) / 10) % 10, (\1) % 10
+ENDM
+
+coins equs "bcd2"
+money equs "bcd3"
+
+;\1 = Map Width
+;\2 = Rows above (Y-blocks)
+;\3 = X movement (X-blocks)
+EVENT_DISP: MACRO
+	dw (wOverworldMap + 7 + (\1) + ((\1) + 6) * ((\2) >> 1) + ((\3) >> 1)) ; Ev.Disp
+	db \2,\3 ;Y,X
+ENDM
+
+FLYWARP_DATA: MACRO
+	EVENT_DISP \1,\2,\3
+	db ((\2) & $01) ;sub-block Y
+	db ((\3) & $01) ;sub-block X
+ENDM
+
+; external map entry macro
+EMAP: MACRO ; emap x-coordinate,y-coordinate,textpointer
+; the appearance of towns and routes in the town map, indexed by map id
+	; nybble: y-coordinate
+	; nybble: x-coordinate
+	; word  : pointer to map name
+	dn \2, \1
+	dw \3
+ENDM
+
+; internal map entry macro
+IMAP: MACRO ; imap mapid_less_than,x-coordinate,y-coordinate,textpointer
+; the appearance of buildings and dungeons in the town map
+	; byte  : maximum map id subject to this rule
+	; nybble: y-coordinate
+	; nybble: x-coordinate
+	; word  : pointer to map name
+	db \1 + 1
+	dn \3, \2
+	dw \4
+ENDM
+
+; tilesets' headers macro
+tileset: MACRO
+	db BANK(\2)   ; BANK(GFX)
+	dw \1, \2, \3 ; Block, GFX, Coll
+	db \4, \5, \6 ; counter tiles
+	db \7         ; grass tile
+	db \8         ; permission (indoor, cave, outdoor)
+ENDM
+
+INDOOR  EQU 0
+CAVE    EQU 1
+OUTDOOR EQU 2
+
+RGB: MACRO
+	dw (\3 << 10 | \2 << 5 | \1)
+ENDM
+
+WALK EQU $FE
+STAY EQU $FF
+
+DOWN  EQU $D0
+UP    EQU $D1
+LEFT  EQU $D2
+RIGHT EQU $D3
+NONE  EQU $FF
+
+;\1 sprite id
+;\2 x position
+;\3 y position
+;\4 movement (WALK/STAY)
+;\5 range or direction
+;\6 text id
+;\7 items only: item id
+;\7 trainers only: trainer class/pokemon id
+;\8 trainers only: trainer number/pokemon level
+object: MACRO
+	db \1
+	db \3 + 4
+	db \2 + 4
+	db \4
+	db \5
+	IF (_NARG > 7)
+		db TRAINER | \6
+		db \7
+		db \8
+	ELSE
+		IF (_NARG > 6)
+			db ITEM | \6
+			db \7
+		ELSE
+			db \6
+		ENDC
+	ENDC
+ENDM
+
+;\1 (byte) = current map id
+;\2 (byte) = connected map id
+;\3 (byte) = x movement of connection strip
+;\4 (byte) = connection strip offset
+;\5 (word) = connected map blocks pointer
+NORTH_MAP_CONNECTION: MACRO
+	db \2 ; map id
+	dw \5 + (\2_WIDTH * (\2_HEIGHT - 3)) + \4; "Connection Strip" location
+	dw wOverworldMap + 3 + \3 ; current map position
+	IF (\1_WIDTH < \2_WIDTH)
+		db \1_WIDTH - \3 + 3 ; width of connection strip
+	ELSE
+		db \2_WIDTH - \4 ; width of connection strip
+	ENDC
+	db \2_WIDTH ; map width
+	db (\2_HEIGHT * 2) - 1 ; y alignment (y coordinate of player when entering map)
+	db (\3 - \4) * -2 ; x alignment (x coordinate of player when entering map)
+	dw wOverworldMap + 1 + (\2_HEIGHT * (\2_WIDTH + 6)) ; window (position of the upper left block after entering the map)
+ENDM
+
+;\1 (byte) = current map id
+;\2 (byte) = connected map id
+;\3 (byte) = x movement of connection strip
+;\4 (byte) = connection strip offset
+;\5 (word) = connected map blocks pointer
+;\6 (flag) = add 3 to width of connection strip (why?)
+SOUTH_MAP_CONNECTION: MACRO
+	db \2 ; map id
+	dw \5 + \4 ; "Conection Strip" location
+	dw wOverworldMap + 3 + (\1_HEIGHT + 3) * (\1_WIDTH + 6) + \3 ; current map position
+	IF (\1_WIDTH < \2_WIDTH)
+		IF (_NARG > 5)
+			db \1_WIDTH - \3 + 3 ; width of connection strip
+		ELSE
+			db \1_WIDTH - \3 ; width of connection strip
+		ENDC
+	ELSE
+		db \2_WIDTH - \4 ; width of connection strip
+	ENDC
+	db \2_WIDTH ; map width
+	db 0  ; y alignment (y coordinate of player when entering map)
+	db (\3 - \4) * -2 ; x alignment (x coordinate of player when entering map)
+	dw wOverworldMap + 7 + \2_WIDTH ; window (position of the upper left block after entering the map)
+ENDM
+
+;\1 (byte) = current map id
+;\2 (byte) = connected map id
+;\3 (byte) = y movement of connection strip
+;\4 (byte) = connection strip offset
+;\5 (word) = connected map blocks pointer
+WEST_MAP_CONNECTION: MACRO
+	db \2 ; map id
+	dw \5 + (\2_WIDTH * \4) + \2_WIDTH - 3 ; "Connection Strip" location
+	dw wOverworldMap + (\1_WIDTH + 6) * (\3 + 3) ; current map position
+	IF (\1_HEIGHT < \2_HEIGHT)
+		db \1_HEIGHT - \3 + 3 ; height of connection strip
+	ELSE
+		db \2_HEIGHT - \4 ; height of connection strip
+	ENDC
+	db \2_WIDTH ; map width
+	db (\3 - \4) * -2 ; y alignment
+	db (\2_WIDTH * 2) - 1 ; x alignment
+	dw wOverworldMap + 6 + (2 * \2_WIDTH) ; window (position of the upper left block after entering the map)
+ENDM
+
+;\1 (byte) = current map id
+;\2 (byte) = connected map id
+;\3 (byte) = y movement of connection strip
+;\4 (byte) = connection strip offset
+;\5 (word) = connected map blocks pointer
+;\6 (flag) = add 3 to height of connection strip (why?)
+EAST_MAP_CONNECTION: MACRO
+	db \2 ; map id
+	dw \5 + (\2_WIDTH * \4) ; "Connection Strip" location
+	dw wOverworldMap - 3 + (\1_WIDTH + 6) * (\3 + 4) ; current map position
+	IF (\1_HEIGHT < \2_HEIGHT)
+		IF (_NARG > 5)
+			db \1_HEIGHT - \3 + 3 ; height of connection strip
+		ELSE
+			db \1_HEIGHT - \3 ; height of connection strip
+		ENDC
+	ELSE
+		db \2_HEIGHT - \4 ; height of connection strip
+	ENDC
+	db \2_WIDTH ; map width
+	db (\3 - \4) * -2 ; y alignment
+	db 0 ; x alignment
+	dw wOverworldMap + 7 + \2_WIDTH ; window (position of the upper left block after entering the map)
+ENDM
+
+tmlearn: MACRO
+x = 0
+	REPT _NARG
+IF \1 != 0
+x = x | (1 << ((\1 - 1) % 8))
+ENDC
+	SHIFT
+	ENDR
+	db x
+ENDM
--- /dev/null
+++ b/macros/event_macros.asm
@@ -1,0 +1,441 @@
+;\1 = event index
+;\2 = return result in carry instead of zero flag
+CheckEvent: MACRO
+event_byte = ((\1) / 8)
+	ld a, [wEventFlags + event_byte]
+
+	IF _NARG > 1
+		IF ((\1) % 8) == 7
+			add a
+		ELSE
+			REPT ((\1) % 8) + 1
+				rrca
+			ENDR
+		ENDC
+	ELSE
+		bit (\1) % 8, a
+	ENDC
+	ENDM
+
+;\1 = event index
+CheckEventReuseA: MACRO
+	IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld a, [wEventFlags + event_byte]
+	ENDC
+
+	bit (\1) % 8, a
+	ENDM
+
+;\1 = event index
+;\2 = event index of the last event used before the branch
+CheckEventAfterBranchReuseA: MACRO
+event_byte = ((\2) / 8)
+	IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld a, [wEventFlags + event_byte]
+	ENDC
+
+	bit (\1) % 8, a
+	ENDM
+
+;\1 = reg
+;\2 = event index
+;\3 = event index this event is relative to (optional, this is needed when there is a fixed flag address)
+EventFlagBit: MACRO
+	IF _NARG > 2
+		ld \1, ((\3) % 8) + ((\2) - (\3))
+	ELSE
+		ld \1, (\2) % 8
+	ENDC
+	ENDM
+
+;\1 = reg
+;\2 = event index
+EventFlagAddress: MACRO
+event_byte = ((\2) / 8)
+	ld \1, wEventFlags + event_byte
+	ENDM
+
+;\1 = event index
+CheckEventHL: MACRO
+event_byte = ((\1) / 8)
+	ld hl, wEventFlags + event_byte
+	bit (\1) % 8, [hl]
+	ENDM
+
+;\1 = event index
+CheckEventReuseHL: MACRO
+IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld hl, wEventFlags + event_byte
+	ENDC
+
+	bit (\1) % 8, [hl]
+	ENDM
+
+; dangerous, only use when HL is guaranteed to be the desired value
+;\1 = event index
+CheckEventForceReuseHL: MACRO
+event_byte = ((\1) / 8)
+	bit (\1) % 8, [hl]
+	ENDM
+
+;\1 = event index
+;\2 = event index of the last event used before the branch
+CheckEventAfterBranchReuseHL: MACRO
+event_byte = ((\2) / 8)
+IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld hl, wEventFlags + event_byte
+	ENDC
+
+	bit (\1) % 8, [hl]
+	ENDM
+
+;\1 = event index
+CheckAndSetEvent: MACRO
+event_byte = ((\1) / 8)
+	ld hl, wEventFlags + event_byte
+	bit (\1) % 8, [hl]
+	set (\1) % 8, [hl]
+	ENDM
+
+;\1 = event index
+CheckAndResetEvent: MACRO
+event_byte = ((\1) / 8)
+	ld hl, wEventFlags + event_byte
+	bit (\1) % 8, [hl]
+	res (\1) % 8, [hl]
+	ENDM
+
+;\1 = event index
+CheckAndSetEventA: MACRO
+	ld a, [wEventFlags + ((\1) / 8)]
+	bit (\1) % 8, a
+	set (\1) % 8, a
+	ld [wEventFlags + ((\1) / 8)], a
+	ENDM
+
+;\1 = event index
+CheckAndResetEventA: MACRO
+	ld a, [wEventFlags + ((\1) / 8)]
+	bit (\1) % 8, a
+	res (\1) % 8, a
+	ld [wEventFlags + ((\1) / 8)], a
+	ENDM
+
+;\1 = event index
+SetEvent: MACRO
+event_byte = ((\1) / 8)
+	ld hl, wEventFlags + event_byte
+	set (\1) % 8, [hl]
+	ENDM
+
+;\1 = event index
+SetEventReuseHL: MACRO
+	IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld hl, wEventFlags + event_byte
+	ENDC
+
+	set (\1) % 8, [hl]
+	ENDM
+
+;\1 = event index
+;\2 = event index of the last event used before the branch
+SetEventAfterBranchReuseHL: MACRO
+event_byte = ((\2) / 8)
+IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld hl, wEventFlags + event_byte
+	ENDC
+
+	set (\1) % 8, [hl]
+	ENDM
+
+; dangerous, only use when HL is guaranteed to be the desired value
+;\1 = event index
+SetEventForceReuseHL: MACRO
+event_byte = ((\1) / 8)
+	set (\1) % 8, [hl]
+	ENDM
+
+;\1 = event index
+;\2 = event index
+;\3, \4, ... = additional (optional) event indices
+SetEvents: MACRO
+	SetEvent \1
+	rept (_NARG + -1)
+	SetEventReuseHL \2
+	shift
+	endr
+	ENDM
+
+;\1 = event index
+ResetEvent: MACRO
+event_byte = ((\1) / 8)
+	ld hl, wEventFlags + event_byte
+	res (\1) % 8, [hl]
+	ENDM
+
+;\1 = event index
+ResetEventReuseHL: MACRO
+	IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld hl, wEventFlags + event_byte
+	ENDC
+
+	res (\1) % 8, [hl]
+	ENDM
+
+;\1 = event index
+;\2 = event index of the last event used before the branch
+ResetEventAfterBranchReuseHL: MACRO
+event_byte = ((\2) / 8)
+IF event_byte != ((\1) / 8)
+event_byte = ((\1) / 8)
+		ld hl, wEventFlags + event_byte
+	ENDC
+
+	res (\1) % 8, [hl]
+	ENDM
+
+; dangerous, only use when HL is guaranteed to be the desired value
+;\1 = event index
+ResetEventForceReuseHL: MACRO
+event_byte = ((\1) / 8)
+	res (\1) % 8, [hl]
+	ENDM
+
+;\1 = event index
+;\2 = event index
+;\3 = event index (optional)
+ResetEvents: MACRO
+	ResetEvent \1
+	rept (_NARG + -1)
+	ResetEventReuseHL \2
+	shift
+	endr
+	ENDM
+
+;\1 = event index
+;\2 = number of bytes away from the base address (optional, for matching the ROM)
+dbEventFlagBit: MACRO
+	IF _NARG > 1
+		db ((\1) % 8) + ((\2) * 8)
+	ELSE
+		db ((\1) % 8)
+	ENDC
+	ENDM
+
+;\1 = event index
+;\2 = number of bytes away from the base address (optional, for matching the ROM)
+dwEventFlagAddress: MACRO
+	IF _NARG > 1
+		dw wEventFlags + ((\1) / 8) - (\2)
+	ELSE
+		dw wEventFlags + ((\1) / 8)
+	ENDC
+	ENDM
+
+;\1 = start
+;\2 = end
+SetEventRange: MACRO
+event_start_byte = ((\1) / 8)
+event_end_byte = ((\2) / 8)
+
+	IF event_end_byte < event_start_byte
+		FAIL "Incorrect argument order in SetEventRange."
+	ENDC
+
+	IF event_start_byte == event_end_byte
+		ld a, [wEventFlags + event_start_byte]
+		or (1 << (((\2) % 8) + 1)) - (1 << ((\1) % 8))
+		ld [wEventFlags + event_start_byte], a
+	ELSE
+event_fill_start = event_start_byte + 1
+event_fill_count = event_end_byte - event_start_byte - 1
+
+		IF ((\1) % 8) == 0
+event_fill_start = event_fill_start + -1
+event_fill_count = event_fill_count + 1
+		ELSE
+			ld a, [wEventFlags + event_start_byte]
+			or $ff - ((1 << ((\1) % 8)) - 1)
+			ld [wEventFlags + event_start_byte], a
+		ENDC
+
+		IF ((\2) % 8) == 7
+event_fill_count = event_fill_count + 1
+		ENDC
+
+		IF event_fill_count == 1
+			ld hl, wEventFlags + event_fill_start
+			ld [hl], $ff
+		ENDC
+
+		IF event_fill_count > 1
+			ld a, $ff
+			ld hl, wEventFlags + event_fill_start
+
+			REPT event_fill_count + -1
+				ld [hli], a
+			ENDR
+
+			ld [hl], a
+		ENDC
+
+		IF ((\2) % 8) == 0
+			ld hl, wEventFlags + event_end_byte
+			set 0, [hl]
+		ELSE
+			IF ((\2) % 8) != 7
+				ld a, [wEventFlags + event_end_byte]
+				or (1 << (((\2) % 8) + 1)) - 1
+				ld [wEventFlags + event_end_byte], a
+			ENDC
+		ENDC
+	ENDC
+	ENDM
+
+;\1 = start
+;\2 = end
+;\3 = assume a is 0 if present
+ResetEventRange: MACRO
+event_start_byte = ((\1) / 8)
+event_end_byte = ((\2) / 8)
+
+	IF event_end_byte < event_start_byte
+		FAIL "Incorrect argument order in ResetEventRange."
+	ENDC
+
+	IF event_start_byte == event_end_byte
+		ld a, [wEventFlags + event_start_byte]
+		and ~((1 << (((\2) % 8) + 1)) - (1 << ((\1) % 8))) & $ff
+		ld [wEventFlags + event_start_byte], a
+	ELSE
+event_fill_start = event_start_byte + 1
+event_fill_count = event_end_byte - event_start_byte - 1
+
+		IF ((\1) % 8) == 0
+event_fill_start = event_fill_start + -1
+event_fill_count = event_fill_count + 1
+		ELSE
+			ld a, [wEventFlags + event_start_byte]
+			and ~($ff - ((1 << ((\1) % 8)) - 1)) & $ff
+			ld [wEventFlags + event_start_byte], a
+		ENDC
+
+		IF ((\2) % 8) == 7
+event_fill_count = event_fill_count + 1
+		ENDC
+
+		IF event_fill_count == 1
+			ld hl, wEventFlags + event_fill_start
+			ld [hl], 0
+		ENDC
+
+		IF event_fill_count > 1
+			ld hl, wEventFlags + event_fill_start
+
+			; force xor a if we just to wrote to it above
+			IF (_NARG < 3) || (((\1) % 8) != 0)
+				xor a
+			ENDC
+
+			REPT event_fill_count + -1
+				ld [hli], a
+			ENDR
+
+			ld [hl], a
+		ENDC
+
+		IF ((\2) % 8) == 0
+			ld hl, wEventFlags + event_end_byte
+			res 0, [hl]
+		ELSE
+			IF ((\2) % 8) != 7
+				ld a, [wEventFlags + event_end_byte]
+				and ~((1 << (((\2) % 8) + 1)) - 1) & $ff
+				ld [wEventFlags + event_end_byte], a
+			ENDC
+		ENDC
+	ENDC
+	ENDM
+
+; returns whether both events are set in Z flag
+; This is counter-intuitive because the other event checks set the Z flag when
+; the event is not set, but this sets the Z flag when the event is set.
+;\1 = event index 1
+;\2 = event index 2
+;\3 = try to reuse a (optional)
+CheckBothEventsSet: MACRO
+	IF ((\1) / 8) == ((\2) / 8)
+		IF (_NARG < 3) || (((\1) / 8) != event_byte)
+event_byte = ((\1) / 8)
+			ld a, [wEventFlags + ((\1) / 8)]
+		ENDC
+		and (1 << ((\1) % 8)) | (1 << ((\2) % 8))
+		cp (1 << ((\1) % 8)) | (1 << ((\2) % 8))
+	ELSE
+		; This case doesn't happen in the original ROM.
+		IF ((\1) % 8) == ((\2) % 8)
+			push hl
+			ld a, [wEventFlags + ((\1) / 8)]
+			ld hl, wEventFlags + ((\2) / 8)
+			and [hl]
+			cpl
+			bit ((\1) % 8), a
+			pop hl
+		ELSE
+			push bc
+			ld a, [wEventFlags + ((\1) / 8)]
+			and (1 << ((\1) % 8))
+			ld b, a
+			ld a, [wEventFlags + ((\2) / 8)]
+			and (1 << ((\2) % 8))
+			or b
+			cp (1 << ((\1) % 8)) | (1 << ((\2) % 8))
+			pop bc
+		ENDC
+	ENDC
+	ENDM
+
+; returns the complement of whether either event is set in Z flag
+;\1 = event index 1
+;\2 = event index 2
+CheckEitherEventSet: MACRO
+	IF ((\1) / 8) == ((\2) / 8)
+		ld a, [wEventFlags + ((\1) / 8)]
+		and (1 << ((\1) % 8)) | (1 << ((\2) % 8))
+	ELSE
+		; This case doesn't happen in the original ROM.
+		IF ((\1) % 8) == ((\2) % 8)
+			push hl
+			ld a, [wEventFlags + ((\1) / 8)]
+			ld hl, wEventFlags + ((\2) / 8)
+			or [hl]
+			bit ((\1) % 8), a
+			pop hl
+		ELSE
+			push bc
+			ld a, [wEventFlags + ((\1) / 8)]
+			and (1 << ((\1) % 8))
+			ld b, a
+			ld a, [wEventFlags + ((\2) / 8)]
+			and (1 << ((\2) % 8))
+			or b
+			pop bc
+		ENDC
+	ENDC
+	ENDM
+
+; for handling fixed event bits when events are inserted/removed
+;\1 = event index
+;\2 = fixed flag bit
+AdjustEventBit: MACRO
+	IF ((\1) % 8) != (\2)
+		add ((\1) % 8) - (\2)
+	ENDC
+	ENDM
--- /dev/null
+++ b/macros/text_macros.asm
@@ -1,0 +1,80 @@
+
+; text macros
+text   EQUS "db $00," ; Start writing text.
+next   EQUS "db $4e," ; Move a line down.
+line   EQUS "db $4f," ; Start writing at the bottom line.
+para   EQUS "db $51," ; Start a new paragraph.
+cont   EQUS "db $55," ; Scroll to the next line.
+done   EQUS "db $57"  ; End a text box.
+prompt EQUS "db $58"  ; Prompt the player to end a text box (initiating some other event).
+
+page   EQUS "db $49,"     ; Start a new Pokedex page.
+dex    EQUS "db $5f, $50" ; End a Pokedex entry.
+
+TX_RAM: MACRO
+; prints text to screen
+; \1: RAM address to read from
+	db $1
+	dw \1
+ENDM
+
+TX_BCD: MACRO
+; \1: RAM address to read from
+; \2: number of bytes + print flags
+	db $2
+	dw \1
+	db \2
+ENDM
+
+TX_LINE    EQUS "db $05"
+TX_BLINK   EQUS "db $06"
+;TX_SCROLL EQUS "db $07"
+TX_ASM     EQUS "db $08"
+
+TX_NUM: MACRO
+; print a big-endian decimal number.
+; \1: address to read from
+; \2: number of bytes to read
+; \3: number of digits to display
+	db $09
+	dw \1
+	db \2 << 4 | \3
+ENDM
+
+TX_DELAY              EQUS "db $0a"
+TX_SFX_ITEM_1         EQUS "db $0b"
+TX_SFX_LEVEL_UP       EQUS "db $0b"
+;TX_ELLIPSES          EQUS "db $0c"
+TX_WAIT               EQUS "db $0d"
+;TX_SFX_DEX_RATING    EQUS "db $0e"
+TX_SFX_ITEM_2         EQUS "db $10"
+TX_SFX_KEY_ITEM       EQUS "db $11"
+TX_SFX_CAUGHT_MON     EQUS "db $12"
+TX_SFX_DEX_PAGE_ADDED EQUS "db $13"
+TX_CRY_NIDORINA       EQUS "db $14"
+TX_CRY_PIDGEOT        EQUS "db $15"
+;TX_CRY_DEWGONG       EQUS "db $16"
+
+TX_FAR: MACRO
+	db $17
+	dw \1
+	db BANK(\1)
+ENDM
+
+TX_VENDING_MACHINE         EQUS "db $f5"
+TX_CABLE_CLUB_RECEPTIONIST EQUS "db $f6"
+TX_PRIZE_VENDOR            EQUS "db $f7"
+TX_POKECENTER_PC           EQUS "db $f9"
+TX_PLAYERS_PC              EQUS "db $fc"
+TX_BILLS_PC                EQUS "db $fd"
+
+TX_MART: MACRO
+	db $FE, _NARG
+	REPT _NARG
+	db \1
+	SHIFT
+	ENDR
+	db $FF
+ENDM
+
+TX_POKECENTER_NURSE        EQUS "db $ff"