; patch for Maze (cart 10) to work on Channel F multi-cart
; Sean Riddle 2004
; www.seanriddle.com

; Maze normally has 2102 SRAM on I/O ports
; 	this patches reads and writes to use the Schach RAM at $2800

; works on both versions of Maze
; main code needs patches at 887, 898 and adb:

; 887:	JMP patch1	;29 10 00
;
; 899:	LIS 0		;70
;
; adb:	DCI p25		;2a 2c 01
;		ST			;17
;		JMP patch2	;29 11 00

; then this code is added to the end

; the 2102 is attached to ports a and b of the 3851:
;               7   6   5   4   3   2   1   0
; port a (p24) OUT  -   -   -  IN  A2  A3  RW
; port b (p25) A9  A8  A7  A1  A6  A5  A4  A0

; these ports are latched, so a read of p25 returns what was last stored there

; IN and OUT invert the data, so RW=0 is read, RW=1 is write
; this doesn't matter for data because the read invert cancels out the write invert
; address bits don't have to match; physical and logical locations can be different

; p25 is easy because we only have to read/write the latch
; OUT p25 becomes	DCI p25, ST
; IN p25 becomes	DCI p25, LM

; p24 is harder; we need to update the latch on OUT, we have to calculate
; the RAM address and for a read we have to OR the data with the latch
;				      for a write we may need to store data in RAM if RW=1

; to do: 	save and restore QL? used at 9a6, 9b1, 9d1, a03, a20
;			save and restore DC?
;			(these 2 don't seem to matter)
;			simplify and shorten code
;			rewrite code for Schach RAM instead of emulating 2102 code

;start of code
; the ports have a latch; I use 2 bytes of RAM instead
p24: equ $2c00
p25: equ $2c01

org $1000			; just past the cart code

;this is called to initialize the RAM when a maze is being generated
;(this could be rewritten to just init all RAM locations to 1 instead of
;	exactly emulating what the original code did)
patch1:
	lis 0
	dci p24			; since RW=0, we just need to update the latch
	st
p1loop2:
	dci p25
	st
	lis $f
p1loop1:
	dci p24
	st
	lr qu,a			; temp storage for p24 value
	ni 1			; write if RW=1
	bt 4,p1notwrite
	lr a,qu			; p24
	ni 8			; data to write is in bit 3
	bt 4,p1write0	; branch to write 0
	lr a,qu			; p24
	sr 1
	ni 3			; mask address bits
	ai $28
	lr qu,a			; set the high RAM address bits
	lm				; p25
	lr ql,a			; set the low RAM address bits
	lis 1			; store a 1
	bf 0,p1write
p1write0:
	lr a,qu			; p24
	sr 1
	ni 3			; mask address bits
	ai $28
	lr qu,a			; set the high RAM address bits
	lm				; p25
	lr ql,a			; set the low RAM address bits
	lis 0			; store a 0
p1write:
	lr dc,q			; set the data pointer
	st
p1notwrite:
	dci p24
	lm
	ai $ff
	ci 7
	bf 4,p1loop1
	lm				; p25
	inc
	bf 4,p1loop2
	jmp $899		; get back to the cart code

org $1100
;this is called a lot to read/write to the RAM
patch2:
	lis 0
	as $0
	bf 1,patch2a
	sl 1			; this zero-fills bit 0, so RW=0, read
	dci p24			; so just update latch
	st
	sr 1			; set the data pointer for a RAM read
	ni 3			; mask address bits
	ai $28
	lr qu,a			; set the high RAM address bits
	lm				; p25
	lr ql,a			; set the low RAM address bits
	lr dc,q
	lm				; reads from RAM
	dci p24
	ci 1			; lm doesn't set status flags, so this compare is required
	bf 4,p2ret0
	lm
	oi $80			; OR the data with the latch
	pop
p2ret0:
	lm
	ni $7f			; clear the data bit
	pop

patch2a:	
	lis $f
p2loop1:
	dci p24
	st
	lr qu,a			; temp storage for p24 value
	ni 1
	bt 4,p2notwrite	; don't store if RW=0 meaning READ
	lr a,qu			; p24
	ni 8
	bt 4,p2write0
	lr a,qu			; p24
	sr 1
	ni 3			; mask address bits
	ai $28
	lr qu,a			; set the high RAM address bits
	lm				; p25
	lr ql,a			; set the low RAM address bits
	lis 1			; store a 1 in RAM
	bf 0,p2write
p2write0:
	lr a,qu			; p24
	sr 1
	ni 3			; mask address bits
	ai $28
	lr qu,a			; set the high RAM address bits
	lm				; p25
	lr ql,a			; set the low RAM address bits
	lis 0			; store a 0 in RAM
p2write:
	lr dc,q
	st
p2notwrite:
	dci p24
	lm
	ai $ff
	ci 7
	bf 4,p2loop1
	lr a,0
	sl 1
	dci p24
	st
	lr qu,a			; temp storage for p24 value
	ni 8			; look at data bit
	bt 4,p2awrite0	; if it's a 0, branch
	lr a,qu			; p24
	sr 1
	ni 3			; mask address bits
	ai $28
	lr qu,a			; set the high RAM address bits
	lm				; p25
	lr ql,a			; set the low RAM address bits
	lis 1			; store a 1 in RAM
	bf 0,p2exit
p2awrite0:
	lr a,qu			; p24
	sr 1
	ni 3			; mask address bits
	ai $28
	lr qu,a			; set the high RAM address bits
	lm				; p25
	lr ql,a			; set the low RAM address bits
	lis 0			; store a 0 in RAM
p2exit:
	lr dc,q
	st
	lr a,2
	inc
	lr 2,a
	pop

org $13f0	
	db $53,$45,$41,$4e,$20,$52,$49,$44,$44,$4c,$45,$20,$32,$30,$30,$34
	
