;Basic Sprite Hacker v1.01
;by Steve Smith - www.ProjectSPECCY.com - circa. 1991
;
;Incorporating suggestions for optimisation
;by Russ McNulty (Cheers Russ)
;
;Licence: Public Domain
;
;Pasmo 0.5.3 source
;
;Clear 25499, Load binary into 64000
;Load code to hack at 25500 and
;RANDOMIZE USR 64000 to start Sprite Hacker
;
;Keys:
;Q and A - Page up and down
;O and P - Increase and Decrease width
;S and W - Increase and Decrease height
;K and L - Line up and down
;M and N - Byte up and down
;C - Set address
;B - Drop to BASIC (or calling program)
;E - Toggle edit mode
;		Q - Cursor Up
;		A - Cursor Down
;		O - Cursor Left
;		P - Cursor Right
;	Space - Set/reset a pixel
;
;

start:

ORG	64000

INIT:	LD	HL,MEMPO
		LD	(HL),40
		INC	HL
		LD	(HL),61
		INC	HL
		LD	(HL),45
		INC	HL
		LD	(HL),2
		LD	HL,ENDIN-INIT
		LD	(23296),HL		;Load 23296 with compile time length of code
START:	CALL	CLS
TART:	CALL	DSPLY
KEYLP:	CALL	GETKY
		CP	226
		RET	Z
		AND	95
		CP	91
		JR	NC,KEYLP
		CP	65
		JR	C,KEYLP
		SUB	65
		ADD	A,A
		LD	HL,TABLE
		LD	E,A
		LD	D,0
		ADD	HL,DE
		LD	E,(HL)
		INC	HL
		LD	D,(HL)
		EX	DE,HL
SKP:	JP	(HL)
TABLE:	DEFW	UPBLK	;Up a block (page)
AB:		DEFW	BASIC	;Drop into BASIC
AC:		DEFW	CHMEM	;Set memory position
AD:		DEFW	KEYLP
AE:		DEFW	EDIT	;Edit mode
AAF:	DEFW	KEYLP
AG:		DEFW	KEYLP
AH:		DEFW	KEYLP
AI:		DEFW	KEYLP
AJ:		DEFW	KEYLP
AK:		DEFW	UPWID	;Up a line
AL:		DEFW	DNWID	;Down a line
AM:		DEFW	DNBTE	;Down a byte
AN:		DEFW	UPBTE	;Up a byte
AO:		DEFW	DNBWD	;Decrease width
AP:		DEFW	UPBWD	;Increase width
AQ:		DEFW	DNBLK	;Down a block (page)
AR:		DEFW	RESET	;Reset to Spectrum Character Set
AS:		DEFW	UPHGT	;Increase Height
AT:		DEFW	KEYLP
AU:		DEFW	KEYLP
AV:		DEFW	KEYLP
AW:		DEFW	DNHGT	;Decrease height
AX:		DEFW	KEYLP
AY:		DEFW	KEYLP
AZ:		DEFW	KEYLP
CLS:	LD	HL,16384
		LD	BC,6143
		LD	DE,16385
		LD	(HL),0
		LDIR
		RET
BLPRN:	PUSH	HL
		PUSH	BC
		PUSH	DE
BPLP1:	PUSH	DE
		CALL	CALC
		PUSH	BC
		LD	B,0
		LDIR
		POP	BC
		POP	DE
		INC	E
		DJNZ	BPLP1
		POP	DE
		POP	BC
		POP	HL
		RET
BLMAG:	PUSH	DE
		PUSH	BC
		CALL	CALC
		CALL	FILL
		LD	B,C
		INC	D
LP3:	CALL	T4X3
		INC	HL
		DJNZ	LP3
		DEC	D
		LD	B,4
LOOP:	LD	A,(DE)
		OR	128
		LD	(DE),A
		INC	D
		DJNZ	LOOP
		POP	BC
		POP	DE
		INC	E
		INC	E
		INC	E
		INC	E
		DJNZ	BLMAG
		CALL	CALC
		CALL	FILL
		LD	A,C
		SLA	A
		SLA	A
		ADD	A,E
		LD	E,A
		LD	A,(DE)
		OR	128
		LD	(DE),A
		RET
FILL:	PUSH	BC
		PUSH	DE
		PUSH	HL
		LD	H,D		;Russ McNulty
		LD	L,E		;------------
		LD	(HL),255
		INC	DE
		LD	B,0
		SLA	C
		SLA	C
		DEC	C
		LDIR
		POP	HL
		POP	DE
		POP	BC
		RET
T4X3:	PUSH	BC
		LD	C,(HL)
		LD	B,4
LP2:	CALL	TEST
		PUSH	BC
		LD	B,3
		PUSH	DE
LP1:	LD	(DE),A
		INC	D
		DJNZ	LP1
		POP	DE
		POP	BC
		INC	DE
		RL	C
		RL	C
		DJNZ	LP2
		POP	BC
		RET
TEST:	LD	A,136
		BIT	7,C
		JR	NZ,SETQ
RESQ:	AND	143
		JR	DN1
SETQ:	OR	112
DN1:	BIT	6,C
		JR	NZ,SETR
RESR:	AND	248
		JR	DN2
SETR:	OR	7
DN2:	RET
CALC:	PUSH	HL
		PUSH	BC
		PUSH	DE
		LD	D,0
		LD	A,E
		CP	64
		JR	C,SCHIG
		CP	128
		JR	C,SCMID
		JR	SCLOW
SCHIG:	LD	HL,16384
		JR	PARTB
SCMID:	LD	HL,18432
		SUB	64
		JR	PARTB
SCLOW:	LD	HL,20480
		SUB	128
PARTB:	LD	E,A
		LD	B,3
CLOOP:	SRL	D
		SRL	E
		JR	NC,CSKP
		SET	2,D
CSKP:	DJNZ	CLOOP
		LD	A,E		;Russ McNulty
		RRCA		;
		RRCA		;
		RRCA		;
		AND	224		;
		LD	E,A		;------------
		ADD	HL,DE
		EX	DE,HL
		POP	HL
		LD	A,H
		ADD	A,E
		LD	E,A
		JR	NC,SKPA
		INC	D
SKPA:	POP	BC
		POP	HL
		RET
DECTB:	PUSH	BC
		PUSH	DE
		EX	DE,HL
		LD	B,5
		LD	HL,0
DECLP:	LD	A,(DE)
		CP	58
		JR	NC,DECED
		CP	48
DECCN:	SUB	48
		ADD	HL,HL
		PUSH	HL
		ADD	HL,HL
		ADD	HL,HL
		POP	BC
		ADD	HL,BC
		ADD	A,L
		LD	L,A
		JR	NC,DECSP
		INC	H
DECSP:	INC	DE
		JR	DECLP
DECED:	POP	DE
		POP	BC
		LD	(23296),HL
		RET
GETKY:	XOR	A
		LD	(23560),A
GETLP:	LD	A,(23560)
		OR	A
		JR	Z,GETLP
		RET
ENTNM:	PUSH	BC
		PUSH	DE
		LD	A,2
		CALL	5633
		LD	BC,11
		LD	DE,SPACE
		CALL	8252
		POP	DE
		LD	HL,NMBUF
		PUSH	HL
		LD	B,5
CLRLP:	LD	(HL),0
		DJNZ	CLRLP
		LD	B,5
		POP	HL
ENTLP:	CALL	GETKY
		CP	59
		JR	NC,ENTED
		CP	48
		JR	C,ENTED
		LD	(HL),A
		INC	HL
		RST	16
		DJNZ	ENTLP

ENTED:	POP	DE
		LD	HL,NMBUF
		CALL	DECTB
		RET
MEMPO:	DEFW	0
HGT:	DEFB	0
WID:	DEFB	0
DSPLY:	LD	HL,(MEMPO)
		PUSH	HL
		LD	DE,0
		LD	A,(HGT)
		LD	B,A
		LD	A,(WID)
		LD	C,A
		CALL	BLPRN
		POP	HL
		LD	D,11
		LD	E,0
		CALL	BLMAG
		LD	A,2
		CALL	5633
		LD	DE,DMSG
		LD	BC,EDMSG-DMSG
		CALL	8252
		LD	A,22
		RST	16
		LD	A,7
		RST	16
		LD	A,5
		RST	16
		LD	HL,(MEMPO)
		CALL	DSPLP
		LD	A,22
		RST	16
		LD	A,8
		RST	16
		LD	A,5
		RST	16
		CALL	LENDE
		EX	DE,HL
		CALL	DSPLP
		LD	A,22
		RST	16
		LD	A,9
		RST	16
		LD	A,5
		RST	16
		LD	A,(WID)
		LD	H,0
		LD	L,A
		CALL	DSPLP
		LD	A,22
		RST	16
		LD	A,10
		RST	16
		LD	A,5
		RST	16
		LD	A,(HGT)
		LD	H,0
		LD	L,A
		CALL	DSPLP
BASIC:	RET
DSPLP:	XOR	A
		PUSH	AF
DSLP3:	CALL	DIV10
		ADD	A,48
		PUSH	AF
		LD	A,H
		OR	L
		JR	NZ,DSLP3
DSLP4:	POP	AF
		RET	Z
		RST	16
		JR	DSLP4
DNBLK:	LD	HL,(MEMPO)
		CALL	LENDE
		SCF
		CCF
		SBC	HL,DE
		LD	(MEMPO),HL
		JP	TART
CHMEM:	CALL	ENTNM
		LD	(MEMPO),HL
		JP	TART
UPWID:	LD	A,(WID)
		LD	HL,(MEMPO)
		ADD	A,L
		LD	L,A
		JR	NC,UPWDS
		INC	H
UPWDS:	LD	(MEMPO),HL
		JP	TART
DNWID:	LD	A,(WID)
		LD	HL,(MEMPO)
		LD	E,A
		LD	D,0
		SCF
		CCF
		SBC	HL,DE
		LD	(MEMPO),HL
		JP	TART
DNBTE:	LD	HL,MEMPO
		DEC	(HL)
		JP	TART
UPBTE:	LD	HL,MEMPO
		INC	(HL)
		JP	TART
UPBWD:	LD	A,(WID)
		CP	5
		JP	Z,START
		INC	A
		LD	(WID),A
		JP	START
DNBWD:	LD	A,(WID)
		CP	1
		JP	Z,START
		DEC	A
		LD	(WID),A
		JP	START
UPBLK:	LD	HL,(MEMPO)
		CALL	LENDE
		ADD	HL,DE
		LD	(MEMPO),HL
		JP	TART
RESET:	JP	INIT
DNHGT:	LD	A,(HGT)
		CP	1
		JP	Z,START
		DEC	A
		LD	(HGT),A
		JP	START
UPHGT:	LD	A,(HGT)
		CP	47
		JP	Z,START
		INC	A
		LD	(HGT),A
		JP	START
SPACE:	DEFB	22,7,5
		DEFM	"     "
		DEFB	22,7,5
NMBUF:	DEFS	5
DIV10:	PUSH	BC
		PUSH	DE
		LD	DE,0
		LD	BC,10
		XOR	A
ALOOP:	INC	DE
		SBC	HL,BC
		JR	NC,ALOOP
		ADC	HL,BC
		DEC	DE
		DEC	HL
		EX	DE,HL
		LD	A,E
		POP	DE
		POP	BC
		RET
LENDE:	LD	A,(WID)
		LD	E,A
		LD	A,(HGT)
		LD	B,A
		XOR	A
LENLP:	ADD	A,E
		DJNZ	LENLP
		LD	D,0
		LD	E,A
		RET
DMSG:	DEFB	22,7,0
		DEFM	"DAT: "
		DEFB	22,8,0
		DEFM	"LEN: "
		DEFB	22,9,0
		DEFM	"WID: "
		DEFB	22,10,0
		DEFM	"HGT: "
EDMSG:
EDIT:	LD	HL,LOC
		LD	(HL),0
		INC	HL
		LD	(HL),0
		INC	HL
		LD	(HL),128
EDLP1:	CALL	DSPLY
EDLP2:	CALL	EDGET
		CP	"Q"			;Cursor up
		JR	Z,EDUP
		CP	"A"			;Cursor down
		JR	Z,EDDN
		CP	"O"			;Cursor left
		JR	Z,EDLT
		CP	"P"			;Cursor right
		JR	Z,EDRT
		CP	" "			;Set/reset pixel in memory
		JR	Z,EDTOG
		CP	"E"			;Exit edit mode
		JP	Z,TART
		JR	EDLP2
EDUP:	LD	HL,(LOC)
		LD	A,(WID)
		LD	B,0
		LD	C,A
		SCF
		CCF
		SBC	HL,BC
		JR	C,EDLP2
		LD	(LOC),HL
		JR	EDLP2
EDDN:	LD	HL,(LOC)
		CALL	LENDE
		LD	A,(WID)
		LD	C,A
		LD	B,0
		ADD	HL,BC
		PUSH	HL
		SBC	HL,DE
		POP	HL
		JR	NC,EDLP2
		LD	(LOC),HL
		JR	EDLP2
EDLT:	LD	HL,LOC
		LD	A,(BITS)
		RLCA
		LD	(BITS),A
		JR	NC,EDLP2
		DEC	(HL)
		JR	EDLP2
EDRT:	LD	HL,LOC
		LD	A,(BITS)
		RRCA
		LD	(BITS),A
		JR	NC,EDLP2
		INC	(HL)
		JR	EDLP2
EDTOG:	LD	DE,(MEMPO)
		LD	HL,(LOC)
		ADD	HL,DE
		LD	A,(BITS)
		XOR	(HL)
		LD	(HL),A
		JR	EDLP1
LOC:	DEFW	0
BITS:	DEFB	0
EDGET:	XOR	A
		LD	(23560),A
		CALL	FLASH
		CALL	FLASH
		LD	A,(23560)
		OR	A
		JR	Z,EDGET
		RET
FLASH:	LD	HL,(MEMPO)
		LD	DE,(LOC)
		LD	A,(BITS)
		ADD	HL,DE
		XOR	(HL)
		LD	(HL),A
CALL	DSPLY
		RET
ENDIN:
end	start
