; Ghostbusters Backscreen Copier Patch
;
; Mark Incley, 11th November 2023 (at ABUG South, Ely, Surrey)
;
; Patches Ghostbusters to replace the slow and shimmery backscreen-to-screen copier
; function with one a little faster and a bit less shimmery, particulary on the
; car-on-road section of the game. Mainly an excercise in patching games with
; Inkspector's assembler.
;
		; NB I'm specifying a MEMCOPYMODE of SPARSE (instead of using the default of NEW when assembling
		; from a file) so that it can be assembled directly on top of a running machine without clearing
		; its memory, so it can behave like a super-POKE.
		MEMCOPYMODE	SPARSE

		; Create listing and symbol files, so that Inkspector's debugger can reference them
		SAVELISTING
		SAVESYMBOLS

		; We'll create a .pok file for this patch too. Because we can!
		SAVEPOK 	"ghostbusters_screen_update.pok"
		POKTRAINER	"Patch the screen-update code to be ever-so slightly spiffier"

; The original back-screen copier code at $98C2 is a bog-standard LDIR type affair.
; Note how it copies all 192 lines of the bitmap, but only the first 21 of the 24 attribute rows.
;
;		ld	hl,$E000
;		ld	de,$4000
;		ld	bc,$1AA0
;		ldir
;		ret

		ORG	0x98C2
		; Jump to our replacement screen copier at some memory unused by the game
		jp	ReplacementBackscreenCopier

		ORG	0x9A1D

ReplacementBackscreenCopier:
		; Set up the bitmap pointer
		ld      de,$4000
		ld	b,e		; Clear B So we only need to set C for our LDIRs
		ld	ixl,e		; row #

		; Set up the attribute pointers
		exx
		ld	hl,$F800
		ld	de,$5800
		ld	b,e		; Clear B So we only need to set C for our LDIRs
		exx

		; Only the first 21 rows of attributes are copied (the last 3 are not)
.rowloop:	ld	a,ixl
		cp	21
		jr	nc,.bitmapline

		; Copy a row of attributes
		exx
		ld	c,32
		ldir
		exx

.bitmapline:	ld	a,d
		or	$A0
		ld	h,a
		ld	l,e

		ld	c,32

		push	de

.bitmaploop:	REPT	16
		ldi
		ENDR
		jp      pe,.bitmaploop

		; Rewind the destination pointer to the start of its line
		pop	de

		inc	d
		ld	a,d
		and	7
		jr	nz,.bitmapline

		; We've just copied the bottom pixel line of the current row, so move to the next row
		inc	ixl

		; Return if we've done all 24 rows of bitmap
		ld	a,ixl
		cp	24
		ret	nc

		ld	a,e
		cp	$E0
		ld	hl,-$6E0-256
		jr	nz,.add

		ld	hl,32-256

.add:		add	hl,de
		ex	de,hl
		jr	.rowloop

		END
