Differences between JSW48 and JSW128 0.02HL7


;--------------------------------------------------------------------------	
;(v0.00HL3) This code deals with having the scrolling title-screen message 
;as an ASCIIZ string in Bank 7 rather than as 256 bytes in Bank 2. 
;The principle is simple enough: each time the message is scrolled, copy 
;32 bytes of message to T8474 and pass that address to the print routine.
; 
;JSW48 stops scrolling when the count of characters scrolled reaches 
;0DFh. JSW128 keeps this variable below 80h until the end, and then 
;sets it to 0DFh when it sees the end of the string.
;
;
	;48k				;128k
	ORG	8474h			ORG	8474h

T8474:	DB '  JET-SET WILLY ' 	T8474:	DB	'  JET-SET WILLY '
	DB 'by Matthew Smith'		DB	'128k Version 0.0'
	DB '  ',7Fh,' 1984'	C8494:	DI
					LD	BC,7FFDh
					LD	A,17h	;Bank 7
					OUT	(C),A
	DB 'SOFTWARE PROJECTS'		LD	HL,(W84D0) ;visible section
					LD	DE,T8474
					LD	BC,20h	;32 characters
					LDIR
					LD	A,(HL)	;next char to print
					PUSH	AF
					LD	BC,7FFDh
					LD	A,10h	;Bank 0
	DB ' Ltd . . . . '		OUT	(C),A
					POP	AF
					OR	A
					JR	Z,R84C4	;End of message?
					LD	HL,(W84D0)
					INC	HL
					LD	(W84D0),HL ;increment ptr	
	DB '.Guide Willy'		LD	A,(B85E4)  ;This is set to 
					AND	7Fh	   ;0DFh at the end
					LD	(B85E4),A   ;of the string
					RET

				R84C4:	LD	HL,TD600   ;Start of message
	DB 'to collect'			LD	(W84D0),HL ;text in Bank 7
					LD	A,0DFh
					LD	(B85E4),A
					RET
			
				W84D0:	DW	TD600	;Current pos in msg.
;
;(v0.00HL6) Support for the extra guardian types
;
	;48k				;128k
				TYPE0	equ	91B6h	;Arrows
				TYPE3	equ	90D9h	;Ropes

	defb	' all the'	T84D2: 	defw	TYPE0	; Type 0
					defw	TYPE1	; Type 1 - horizontal
					defw	TYPE2	; Type 2 - vertical
					defw	TYPE3	; Type 3 - rope
	defb	' items a'		defw	TYPE0	; Type 4 - arrow
					defw	TYPE5	; Type 5 - diagonal 1
					defw	TYPE6	; Type 6 - diagonal 2
					defw	TYPE2C	; Type 7 - clr vert
	defb	'round th'		defw	TYPE0	; Type 8 - spare
					defw	TYPE1C	; Type 9 - clr horz
					defw	TYPE2	; Type 2 - vertical
					defw	TYPE0	; Type 11 - spare
	defb	'e house '		defw	TYPE0	; Type 12 - spare
					defw	TYPE5C	; Type 13 - clr diag 1
					defw	TYPE6C	; Type 14 - clr diag 2
					defw	TYPE2C	; Type 15 - clr vert 

	defb	'before mi'	TYPE1C:	call	CYCLE	;Cycle colours
				TYPE1:	call	SHGUARD	;Standard horizontal
					jp	TYPE0

	defb	'dnight so'	TYPE2C:	call	CYCLE	;Cycle colours
				TYPE2:	call	SVGUARD	;Standard vertical
					jp	TYPE0

	defb	'Maria will'	TYPE5C:	call	CYCLE	;Cycle colours
				TYPE5:	call	SHGUARD	;Standard horizontal
					bit	7,(ix+0)
	defb	' let'			jr	nz,MOVE_D
					jr	MOVE_U	;but with U/D additions

	defb	'you get to'	TYPE6C:	call	CYCLE	;Cycle colours
				TYPE6:	call	SHGUARD	;Standard vertical
					bit	7,(ix+0)
					jr	z,MOVE_D ;but with U/D additions

	defb	'your bed. . '	MOVE_U:	LD	A,(IX+3)	;Move up
					ADD	A,(IX+4)
					LD	(IX+3),A
					jp	TYPE0		;[HL7] bugfix	
;
	defb	'. . . . .++'	MOVE_D:	LD	A,(IX+3)	;Move down 
					SUB	(IX+4)
					LD	(IX+3),A
					jp	TYPE0		;[HL7] bugfix
;
	defb	'+++ Pres'	CYCLE:	ld	a,(ix+1)	;Cycle colours
					ld	c,a
					and	0F8h	;C = colour byte
					ld	b,a	;B = byte less ink
					ld	a,c
	defb	's ENTER t'		and	7	;A = ink
					inc	a
					cp	7	;Cycle 2,3,4,5,6
					jr	c,cyc1
					ld	a,2
	defb	'o sta'		cyc1:	or	b
					ld	(ix+1),a
					ret
;	
;  In JSW48, the remainder of the scrolling message follows. In JSW128,
; the space up to and including 8553h is currently unused.
;
;--------------------------------------------------------------------------	
;
;(v0.00HL1) This patch was the first to be written, and converts JSW48 to
;JSW128. It replaces messages printed by the password system with the code 
;necessary to access 64k of room data.
;
	;48k				;128k
	ORG	858Bh			ORG	858Bh
	DB 'Enter Code at'	L858B:	LD	A,(B8420)	;A=room no.
				L858E:	LD	E,1		;E:=bank	
					CP	40h
					JR	Z,R85A1
					LD	E,3
					CP	80h
	DB 'grid location    '		JR	Z,R85A1
					INC	E
					CP	0C0h
					JR	Z,R85A1
					LD	E,6
				R85A1:	LD	BC,7FFDh
					DI
					OUT	(C),E
					OR	0C0h
					LD	H,A	;HL:=source addr.
	DB ' Sorry, try code at'	LD	L,0
					LD	DE,T8000
					LD	BC,0100h
					LDIR
					LD	BC,7FFDh
					LD	A,10h	;Bank 0			
					OUT	(C),A
					LD	A,I	;Should ints be enabled?
	DB ' location     '		CP	3Eh
					JR	Z,R85C2
					EI
				R85C2:	
;
;(v0.02HL5) This patch was added to support dynamic switching on/off of the
;          "superjump" poke. The previous JSW128 code here was:
; 					;;;JP	L8922	;Return to JSW48 code
;					;;;DB	'      '
;It now reads:
					LD	HL,T80DE ;Border colour
					LD	DE,T8E34 ;Poke address
					JP	L8915	 ;Remainder of patch
;
;--------------------------------------------------------------------------	
;
;(v0.00HL2)
;
; In JSW48, this area holds the title screen tune and the in-game tune.
; In JSW128, this contains code to deal with the 128k music. 
;
; The flag B85FB is the "stop tune" flag. If it is set to 8, the current
;tune is stopped (in Ian Collier's original TUNE.BIN, ERRNO was used, so
;that a 9 STOP report would stop the music).
;
;TUNE.BIN works by having three pointers (6 bytes) to the three tune 
;channels at TFE8E. The I register will contain 0F8h if the tune is playing,
;or 3Eh if it has stopped.
;
	;48k				;128k
	ORG	85FBh			ORG	85FBh
	DB	51h		B85FB:	DB	51h
	DB	3Ch,33h		L85FC:	LD	A,8
	DB	51h,3Ch,33h		LD	(B85FB),A
	DB	51h,3Ch			LD	A,0F8h	
	DB	33h,51h			LD	I,A
	DB	3Ch			EI		;Ensure TUNE.BIN sees
	DB	33h			HALT		;the stop flag
	DB	3Ch,33h,51h		LD	HL,TF700 ;In-game tune
	DB	3Ch,33h,51h		LD	DE,TFE8E ;TUNE.BIN tune ptrs
	DB	3Ch,33h,51h		LD	BC,6
	DB	3Ch,33h			LDIR
	DB	4Ch			XOR	A
	DB	3Ch,33h,4Ch		LD	(B85FB),A ;Reset stop flag
	DB	3Ch,33h,4Ch		CALL	CFA00	  ;Start playing tune
	DB	39h			EI
	DB	2Dh,4Ch,39h		JP	L88FC     ;Start the game

	DB	2Dh,51h		C861E:	LD	A,8	  ;Stop tune
	DB	40h,2Dh,51h		LD	(B85FB),A
	DB	3Ch,33h,51h		LD	HL,4000h
	DB	3Ch			RET

	DB	36h,5Bh,40h,36h	T8627:	DB	0,0,0,0	  ;9 spare bytes
	DB	66h,51h,3Ch,51h		DB	0,0,0,0
	DB	3Ch			DB	0
;
;At 864Ch in JSW128 is the memory map. This is not used by the game 
;itself, but JSWED uses it to keep track of where sprites (60h), 
;guardian tables (2xh,4xh,4xh,4xh), and teleporter data (61h) have
;been stored, and what locations are reserved (80h or higher).
;
	DB	4Ch,3Ch,2Dh,28h		DB	00h,00h,80h,80h ;9800 
	DB	40h,33h,51h,40h		DB	60h,60h,60h,60h
	DB	33h,2Dh,40h,36h		DB	21h,41h,41h,41h ;A000
	DB	20h,40h,36h,3Dh		DB	80h,80h,60h,60h 
	DB	79h,3Dh,0FFh,80h	DB	60h,60h,60h,60h ;A800
	DB	72h,66h,60h,56h		DB	60h,60h,60h,60h
	DB	66h,56h,56h,51h		DB	60h,60h,60h,60h ;B000
	DB	60h,51h,51h,56h		DB	60h,60h,60h,60h
	DB	56h,56h,56h,80h		DB	60h,60h,60h,60h ;B800
	DB	72h,66h,60h,56h		DB	60h,60h,60h,60h
	DB	66h,56h,56h,51h		DB	80h,80h,80h,80h	;C000
	DB	60h,51h,51h,56h		DB	80h,22h,42h,42h
	DB	56h,56h,56h,80h		DB	42h,60h,60h,60h	;C800
	DB	72h,66h,60h,56h		DB	60h,60h,00h,60h
	DB	66h,56h,56h,51h		DB	60h,60h,60h,60h	;D000
	DB	60h,51h,51h,56h		DB	60h,60h,60h,60h
	DB	66h,56h,56h,80h		DB	00h,60h,00h,60h	;D800
	DB	72h,66h,60h,56h		DB	60h,60h,60h,60h
	DB	66h,56h,40h,56h		DB	00h,00h,00h,00h	;E000
	DB	66h,80h,66h,56h		DB	00h,00h,00h,00h
	DB	56h,56h,56h		DB	00h,00h,61h	;E800
;
;--------------------------------------------------------------------------	
;
;(v0.00HL1) This code replaces some of the copy-protection code. It deals 
;with 8-bit room numbers (as opposed to 6-bit) in the object locations table.
;
	;48k				;128k
	ORG	869Fh			ORG	869Fh
L869F:	LD	HL,4000h	L869F:	LD	A,H	;The object location
					ADD	A,1Ch	;table is now at C000h,
	LD	DE,4001h		LD	H,A	;ie A400h + 1C00h.
					LD	C,(HL)
	LD	BC,1AFFh		SUB	1Ch
					LD	H,A
	LD	(HL),0			LD	A,(B8420)	;Room
	LDIR				CP	C
					PUSH	AF
	LD	IX,T858B		LD	C,(HL)
					RES	7,C
					POP	AF
	CALL	C86C3			JP	NZ,L9452
	JP	Z,L87CA			BIT	6,C
	LD	IX,T85AB		JP	Z,L9452
	CALL	C86C3			JP	L93E2
;
;(v0.00HL1) This code (C86BB) is to extend the WRITETYPER teleport cheat 
;to use keys 7 and 8 as well.
;
				C86BB:	AND	1Ch
	JP	Z,L87CA			XOR	1Ch
					RLCA
	JP	0			RLCA
					RLCA
					RET

;--------------------------------------------------------------------------	
;(v0.00HL2) Some more of the protection system bites the dust. This code
;is entered from the cheat code in the C400h-C4FFh page; it cleans up 
;the stack and jumps to a new room.
;
	;48k				;128k
	ORG	87BEh			ORG	87BEh
	LD	(IX+21h),E		DB	0DDh,73h	;unused
				L87C0:	NOP
	LD	BC,18h			NOP
					NOP
					NOP
R87C4:	DJNZ	R87C4			POP	BC
	DEC	C			POP	BC	
	JR	NZ,R87C4		JP	L858E
	RET	
;
;--------------------------------------------------------------------------	
;
;(v0.00HL1) The code to draw the title screen. JSW128 blanks the attributes 
;rather than copying them in from T9800.
;
	;48k				;128k
	ORG	8819h			ORG	8819h
	LD	BC,17FFh		LD	BC,1AFFh ;Clear attrs as well
	LD	(HL),0			LD	(HL),0
	LDIR				LDIR
	LD	HL,T9800		LD	HL,T9800
	LD	BC,300h			LD	BC,300h
	LDIR				NOP		;Don't use JSW48 attrs
					NOP
;
; Whereas JSW48 generates the triangle shape, JSW128 stores it as a bitmap 
;in Bank 7 and copies it in. The bitmap only covers the top 2/3 of the screen,
;so it is 4k in size.
;
; The JSW128 title screen has three sets of attributes, each 512 bytes. 
;These are stored immediately after the screen in Bank 7.
;
; After the title screen has been copied, JSW128 starts the title screen 
;tune.
;
	ORG	8841h			ORG	8841h
	LD	DE,5800h		DI
					LD	A,17h	;Bank 7
L8844:	LD	A,(DE)			LD	BC,7FFDh
	OR	A
	JR	Z,R888E			OUT	(C),A
	CP	0D3h			PUSH	BC
	JR	Z,R888E			LD	HL,TC000
	CP	9			LD	DE,T4000
	JR	Z,R888E
	CP	2Dh			LD	BC,1000h	;Top 2thirds
	JR	Z,R888E			LDIR
	CP	24h			LD	DE,6000h	;attrs*3
	JR	Z,R888E
	LD	C,0			LD	BC,600h		;512*3
	CP	8			LDIR
	JR	Z,R8871			POP	BC		;7FFDh
	CP	29h			LD	A,10h		;Bank 0
	JR	Z,R8871			OUT	(C),A
	CP	2Ch			DI
	JR	Z,R886E			LD	HL,6000h
	CP	5			LD	DE,5880h ;title attributes
	JR	Z,R8871			LD	BC,0200h
	LD	C,10h
	JR	R8871			LDIR

R886E:	LD	A,25h			LD	HL,TEC2A ;title screen tune
	LD	(DE),A
R8871:	LD	A,E			LD	DE,T752A ;29994
	AND	1
	RLCA				LD	BC,0AD6h ;2774
	RLCA
	RLCA
	OR	C			LDIR
	LD	C,A
	LD	B,0			LD	HL,T752A ;29994
	LD	HL,T8431 ;slope shape	LD	DE,TFE8E ;Tune pointers
	ADD	HL,BC
	PUSH	DE			LD	BC,6
	BIT	0,D
	LD	D,40h			LDIR
	JR	Z,R8888			XOR	A
	LD	D,48h			LD	(B85FB),A ;Reset "stop" flag
R8888:	LD	B,6			CALL	CFA00	;start tune
	CALL	C969B			XOR	A
	POP	DE			OUT	(0FEh),A ;Zap border
R888E:	INC	DE			NOP
	LD	A,D			NOP	;Unused in JSW128
	CP	5Ah			NOP
					NOP
	JP	NZ,L8844		NOP
					NOP
					NOP
	LD	BC,1Fh			LD	BC,1Fh
	DI				EI	;In JSW128, allow tune to play
;
; In JSW128, there is extra code when you decide to start the game, since
; the 128k music code has to be switched to play the in-game tune.
;
	ORG	88AEh			ORG	88AEh
	JP NZ,L88FC ;start game	R88AE:	JP	NZ,L85FC ; start game w/tune
;
; Do the scrolling message 128k-style. In JSW48, add an offset; in JSW128,
;read 32 characters into the message buffer and use them.
;
	ORG	88C8h			ORG	88C8h
	LD	IX,T8454		CALL	C8494
	LD	E,A			LD	IX,T8474
	LD	D,0
	ADD	IX,DE			NOP
					NOP
;
; The "start game" check here is a JR. So send it to a jump.
;
	ORG	88ECh			ORG	88ECh
	JR	NZ,L88FC;start game	JR	NZ,R88AE ;JSW128 start game

;--------------------------------------------------------------------------	
;
; (v0.00HL1) The other half of the original patch. This is the code to get 
; room data.
;
	;48k				;128k
	ORG	8912h			ORG	8912h
L8912:	LD	A,(B8420) ;room no.	JP	L858B	;Read 128k room data
;
; (v0.02HL5) Flow of execution returns here halfway through the Superjump 
;            patch. HL->border colour; DE=poke address
;            If bit 7 of the border colour is set, then the Superjump POKE
;            is turned on; otherwise it is turned off.
;
	OR	0C0h		L8915:	LD	A,0BCh	;Turn it off
	LD	H,A			LD	(DE),A
	LD	L,0			BIT	7,(HL)	;Bit 7 of border = flag
	LD	DE,T8000		JR	Z,R891F
	LD	BC,100h			LD	A,2Ch	;Turn it on
					LD	(DE),A
	LDIR			R891F:	RES	7,(HL)
					NOP	

;--------------------------------------------------------------------------	
;
;(v0.00HL2) Code to support multiple guardian tables.
;
	;48k				;128k
	ORG	8930h			ORG	8930h
	LD	H,14h			LD	H,0
	ADD	HL,HL			CALL	CC4B6	;Find table addr.
	ADD	HL,HL
	ADD	HL,HL
;
;--------------------------------------------------------------------------	
;
;(v0.00HL2) Add the cheat mode status to the lives display. 
;
	;48k				;128k
	ORG	8992h			ORG	8992h
	RET	Z			JP	LEB00
	LD	B,A ;B=lives count
R8994:	LD	C,0			NOP	;8995-899C spare
	PUSH	HL			NOP
	PUSH	BC			NOP
	LD	A,(B85E1)		NOP
					NOP
					NOP
	RLCA				NOP
	RLCA				NOP
	RLCA			L899D:	PUSH	BC	 ;Fix for PAUSE bug
	AND	60h			LD	HL,T9A00
	LD	E,A
	LD	D,9Dh			LD	DE,T5A00
	CALL	C9456			LD	BC,0100h
	POP	BC
	POP	HL			LDIR
	INC	HL
	INC	HL			POP	BC
	DJNZ	R8994			JP	L8B12
	RET
;--------------------------------------------------------------------------	
;
;(v0.00HL2) Restrict the keys that can cause a pause
;
	;48k				;128k
	ORG	8AC9h			ORG	8AC9h
	AND	1Fh			AND	1
	CP	1Fh	;A-G		CP	1	;A only

;--------------------------------------------------------------------------	
;
;(v0.00HL1) When restoring lower screen attributes after a PAUSE, save BC
;(this is a JSW48 fix relocated to an area made spare in JSW128)
;
	;48k				;128k
	ORG	8B07h			ORG	8B07h
	LD	HL,T9A00		JP	L899D ;need to save BC
						      ;up to 8B11h is spare
;--------------------------------------------------------------------------	
;
;(v0.00HL2) Modifications to support 128k in-game tune
;
	;48k				;128k
	ORG	8B3Ah			ORG	8B3Ah
	JR	NZ,R8B70		JR	NZ,R8B55
	XOR	A			LD	A,I	;Has tune stopped?
	LD	(B85E0),A		CP	3Eh
	LD	A,(B85E1)		JR	NZ,R8B55
	INC	A			LD	HL,TF700 ;In-game tune
	LD	(B85E1),A		LD	DE,TFE8E ;Tune pointers
	AND	7Eh			LD	BC,6
	RRCA
	LD	E,A
	LD	D,0			LDIR
	LD	HL,T865F		XOR	A
	ADD	HL,DE			LD	(B85FB),A ;Reset "stop" flag
	LD	A,(B85CC)		CALL	CFA00
	RLCA				EI
	RLCA			R8B55:	XOR	A
	SUB	1Ch			LD	(B85E0),A
	NEG				LD	A,(B85E1)
	ADD	A,(HL)
	LD	D,A			INC	A
	LD	A,(80DEh)		LD	(B85E1),A
	LD	E,D							
	LD	BC,3			LD	A,(B85E2)	;Stop tune?
R8B63:	OUT	(0FEh),A		AND	2
	DEC	E			JR	Z,R8B6F
	JR	NZ,R8B6B		LD	A,8
	LD	E,D
	XOR	18h			LD	(B85FB),A	;Set stop flag
R8B6B:	DJNZ	R8B63			NOP
	DEC	C			NOP
	JR	NZ,R8B63		NOP
;
;--------------------------------------------------------------------------	
;
;(v0.01HL4) The following patch is applied only if the teleporter overlay 
;has been added. It can be added to JSW128 or JSW48.
;
R8B70:	LD	BC,0EFFEh		CALL	CEA00	;Teleporter overlay

;--------------------------------------------------------------------------	
;
;(v0.00HL1) Extend WRITETYPER to keys 7 and 8.
;
	;48k				;128k
	ORG	8B7Ah			ORG	8B7Ah
	AND	10h			CALL	C86BB
	XOR	10h			NOP
	RLCA				NOP
;--------------------------------------------------------------------------	
;
;(v0.00HL2) Immediately after the check for WRITETYPER, check for the other 
;cheat mode command.
;
	;48k				;128k
	ORG	8B9Ch			ORG	8B9Ch
	JP	Z,L89AD			JP	Z,LC401
	LD	A,(B8420)		LD	A,(B8420)	;Room
	CP	1Ch			CP	1Ch
	JP	NZ,L89AD		JP	NZ,LC401
;
;--------------------------------------------------------------------------	
;
; (v0.00HL2) Before switching to the "game over" screen, turn off the tune.
;
	;48k				;128k
	ORG	8C4Ah			ORG	8C4Ah
	LD	HL,4000h		CALL	C861E
;
;--------------------------------------------------------------------------	
; (v0.00HL2) Hooked by the cheat mode - invincibility & antigravity toggles.
;
	;48k				;128k
	ORG	8E56h			ORG	8E56h
	LD	A,(B80A0)		CALL	CEC00
;--------------------------------------------------------------------------	
;(v0.00HL2) Keyboard limiting; probably so that a range of keys used by the 
;cheat mode don't get used in the normal course of events.
;
	;48k				;128k
	ORG	8F1Bh			ORG	8F1Bh
	DB	0E7h			DB	0EFh
;
;--------------------------------------------------------------------------	
;
;(v0.00HL2) Hooked by the cheat mode - fast inter-room teleportation.
;
	;48k				;128k
	ORG	8F6Dh			ORG	8F6Dh
	LD	BC,7EFEh		CALL	CC4BF
;
;--------------------------------------------------------------------------
;
;(v0.00HL6) Guardian animation completely rewritten. I have not provided
;          48k source for this bit.
;
; This code decides what type of guardian we are editing, and calls the 
;correct movement subroutine. 
;
	org	090CAh
;
	and	0Fh	;Treat bits 0-3 as type. This works as long as 
	ld	l,a	;vertical types are the same however bit 3 is set. 
	ld	h,0
	add	hl,hl
	ld	de,jtbl	;Sprite types jump table, 16 bytes
	add	hl,de
	ld	e,(hl)
	inc	hl
	ld	d,(hl)
	ex	de,hl
	jp	(hl)
;
;MUST END BEFORE 90D9h
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;(v0.0HL6) More rewrites to sprite movement
;
; The horizontal and vertical movement are now implemented as subroutines 
;called from TYPE1 and TYPE2.
;
	org	9133h		;Horizontal movement redone as subroutine

SHGUARD:
	BIT	7,(IX+0)	;Going right?
	JR	NZ,R915C
	LD	A,(IX+0)
	SUB	20H		;Next frame
	AND	7FH
	LD	(IX+0),A
	CP	60H
	RET	C
MOVE_L:	LD	A,(IX+2)	;Hit left bound?
	AND	1FH
	CP	(IX+6)
	JR	Z,R9156 ;$+07
	DEC	(IX+2)		;Move left
	RET

R9156:	
	LD	B,80h
	JR	REV1
;	LD	(IX+0),81H	;Reverse.
;	RET

R915C:	LD	A,(IX+0)
	ADD	A,20H		;Bits 5,6 of type = frame counter
	OR	80H
	LD	(IX+0),A
	CP	0A0H		;Wrapped round animation. Move sprite.
	RET	NC
MOVE_R:	LD	A,(IX+2)
	AND	1FH		;Is X within the horizontal bounds?
	CP	(IX+7)
	JR	Z,R9179		;Reached the end. Reverse.
	INC	(IX+2)		;Move.
	RET

R9179:
;
;	LD	(IX+0),61H - changes sprite type, Bad Thing.
;
	LD	B,60h
REV1:	LD	A,(IX+0)
	AND	01Fh
	OR	B
	LD	(IX+0),A	;Reset frame.
	RET
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Vertical
;
SVGUARD: LD	A,(IX+0)	;Flip bit 3 (vertical tick?)
	XOR	8
	LD	(IX+0),A
	AND	18H		;If bit 4 set, animate every frame.
	JR	Z,SVNANI	;otherwise, animate every other frame.
	LD	A,(IX+0)
	ADD	A,20H		;Bump frame
	LD	(IX+0),A
SVNANI:
	LD	A,(IX+3)	;Height / position
	ADD	A,(IX+4)	;Direction, U/D, and speed
	LD	(IX+3),A
	CP	(IX+7)		;At limit?
	JR	NC,REVU ;$+0F
	CP	(IX+6)
	JR	Z,R91A8 ;$+04
	RET	NC
R91A8:	LD	A,(IX+6)
	LD	(IX+3),A
;
;Vertical reverse
;
REVU:	LD	A,(IX+4)	;Reverse direction
	NEG
	LD	(IX+4),A
	RET
;
;MUST END BEFORE 91B6h
;
;--------------------------------------------------------------------------	
;
;(v0.00HL1) The other half of the 8-bit object locations patch
;
	;48k				;128k
	ORG	93D7h			ORG	93D7h
R93D7:	LD	C,(HL)			JP	L869F
	RES	7,C	
	LD	A,(B8420)		NOP	;Spare
					NOP
					NOP
	OR	40h			NOP
					NOP
	CP	C			NOP
;
;--------------------------------------------------------------------------	
;
;(v0.01HL4) The Sprite Override patch. Rooms now have a Sprite Override 
;flag at ROOM+0EDh, and if it is >80h then it contains the page for Willy's 
;sprite.
;
;This replaces the previous special-case code for the Nightmare Room.
;
	;48k				;128k
	ORG	9653h			ORG	9653h
	LD	A,(B8420)		LD	A,(B80ED)
	CP	1Dh	;Nightmare?	CP	80h
	JR	NZ,R9660		JR	C,R9660
	LD	D,0B6h			LD	D,A
					NOP
;
;--------------------------------------------------------------------------	
;(v0.00HL2) Replace the Spectrum font with a user-defined one
;
	;48k				;128k
	ORG	9691h			ORG	9691h
	LD	H,7 ;3800 / 800		LD	H,18h ; C000 / 800
	LD	L,A			LD	L,A
	SET	7,L ;3C00 / 800		NOP
					NOP
;
;--------------------------------------------------------------------------	
;(v0.00HL2) Replace the intro tune beeper routine with code to animate
;the opening screen by rotating the three sets of attributes. 
;
	;48k				;128k
	ORG	96A2h			ORG	96A2h
C96A2:	LD	A,(HL)		C96A2:	NOP
	CP	0FFh			LD	HL,6000h
	RET	Z
	LD	BC,64h		L96A6:	LD	DE,5800h
	XOR	A			LD	BC,200h
	LD	E,(HL)
	LD	D,E
R96AC:	OUT	(0FEh),A		LDIR
	DEC	D			LD	B,0Ah	;Wait 1/5 sec.
	JR	NZ,R96B4	R96B0:	LD	A,I	;3Eh if tune stopped
	LD	D,E
	XOR	18h			CP	3Eh
R96B4:	DJNZ	R96AC			RET	Z
					HALT
	EX	AF,AF'			DJNZ	R96B0
	LD	A,C			
	CP	32h			NOP
					NOP
	JR	NZ,R96BE		NOP
	RL	E			LD	A,H	;62h, 64h or 66h
					CP	66h	;Just done no. 3?
R96BE:	EX	AF,AF'			JR	NZ,R96C2
	DEC	C
	JR	NZ,R96AC		LD	H,60h
	CALL	C96C9			CALL	C96C9	;Check for key
	RET	NZ			RET	NZ
	INC	HL			JP	L96A6
	JR	C96A2
;
;--------------------------------------------------------------------------