[comp.sys.handhelds] CHIP8.MACros, 3/3

SLSW2@cc.usu.edu (Roger Ivie) (09/20/90)

Here's PUZZLE.MAC, the infamous "15" puzzle for the calculator. I'm including
it mainly as an example of how to use my CHIP8 macros.

When running PUZZLE, the 4x4 keyboard area used by CHIP8 corresponds to the
screen in the obvious manner. Simply press the key corresponding to the
location that you want the hole to be moved and it will migrate there. The
hole is moved up, down, left, then right until it winds up at the requested
location.

Once the program is started, pressing ENTER causes the board to be randomized
(the magic of self-modifying code).

The program has absolutely no idea whether or not you've solved the puzzle,
so it doesn't do anything special.

Enjoy,

Roger Ivie
slsw2@cc.usu.edu

PS: I'll post a binary as soon as I can get to my local Unix box again (the
hardware hackers have taken over).

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< PUZZLE.MAC
	.XLIST
	INCLUDE CHIP8.MAC
	.LIST

; Register usage:
;
; V0 - Used to grab things from memory
; V1 - Current piece to be displayed
; V2 - X coordinate where it is to be displayed
; V3 - Y coordinate where it is to be displayed
; V4 - General work; new hole position for swap_hole
; V5 - General work
; V6 -
; V7 -
; V8 -
; V9 -
; VA -
; VB -
; VC - Number of random moves to insert into the puzzle
; VD - Desired position of the hole
; VE - Current position of the hole
; VF -

	CLS
START:
	LD VC,0			; Number of moves to randomize
	SKNE VC,0		; If first start, will skip
	LD VE,0FH		; Hole position when first started
	LD I,<START + 1>	; Plug the number of moves to randomize
	LD V0,32
	LD @I,V0
	CLS			; Clear the screen
LOOP:
	CALL GET_MOVE
	CALL MOVE_UP
	CALL MOVE_DOWN
	CALL MOVE_LEFT
	CALL MOVE_RIGHT
	JUMP LOOP

;------------------

XSTART	EQU 23				; Horizontal position of board
YSTART	EQU 4				; Vertical position of board
XOFF	EQU 5				; Horizontal offset to next piece
YOFF	EQU 6				; Vertical offset to next piece

DISPLAY:

; State 1: Initialize everything to be about the first piece on the board
; and go to state 2.

DISPLAY_1:
	LD V1,0
	LD V2,XSTART
	LD V3,YSTART

; State 2: If all pieces have been displayed, exit. Otherwise, go to state 3.

DISPLAY_2:
	SKNE V1,10H
	RET

; State 3: Get the next piece to be displayed. If it's the hole (and therefore
; shouldn't be displayed), go to state 5. Otherwise go to state 4.

DISPLAY_3:
	LD I,BOARD
	ADD I,V1
	LD V0,@I
	SKNE V0,0
	JUMP DISPLAY_5

; State 4: Display the current piece and go to state 5.

DISPLAY_4:
	CHAR V0
	SHOW V2,V3,5

; State 5: Advance the piece pointer and the horizontal position of the
; display to the next piece. If the new piece is the first in a new row,
; go to state 6. Otherwise go to state 2.

DISPLAY_5:
	ADD V1,1
	ADD V2,XOFF
	LD V4,3
	AND V4,V1
	SKE V4,0
	JUMP DISPLAY_2

; State 6: The piece is the first of a new row. Reinitialize the horizontal
; position to the first of the row and advance the vertical position to the
; next row. Go to state 2.

DISPLAY_6:
	LD V2,XSTART			; Start at beginning of next row.
	ADD V3,YOFF
	JUMP DISPLAY_2

;-------

MOVE_RIGHT:

; State 1: Check to see if the desired hole position and the current hole
; position are in the same column. If so, exit. Otherwise, go to state 2.

MOVE_RIGHT_1:
	LD V4,3			; Get horizontal position of hole
	AND V4,VE
	LD V5,3			; Get horizontal position of new hole
	AND V5,VD
	SKNE V4,V5
	RET

; State 2: If the hole cannot be moved any farther right, exit. Otherwise
; go to state 3.

MOVE_RIGHT_2:
	SKNE V4,3
	RET

; State 3: Move the hole right one position and go back to state 1.

MOVE_RIGHT_3:
	LD V4,1
	ADD V4,VE
	CALL SWAP_HOLE
	JUMP MOVE_RIGHT_1

;-------

MOVE_LEFT:

; State 1: Check to see if the desired hole position and the current hole
; position are in the same column. If so, exit. Otherwise, go to state 2.

MOVE_LEFT_1:
	LD V4,3		; Get horizontal position of hole
	AND V4,VE
	LD V5,3		; Get horizontal position of new hole
	AND V5,VD
	SKNE V4,V5
	RET

; State 2: If the hole cannot be moved any farther left, exit. Otherwise
; go to state 3.

MOVE_LEFT_2:
	SKNE V4,0
	RET

; State 3: Move the hole left one position and go back to state 1.

MOVE_LEFT_3:
	LD V4,<LOW -1>
	ADD V4,VE
	CALL SWAP_HOLE
	JUMP MOVE_LEFT_1

;-------

MOVE_UP:

; State 1: Check to see if the desired hole position and the current hole
; position are in the same row. If so, exit. Otherwise, go to state 2.

MOVE_UP_1:
	LD V4,0CH		; Get vertical position of hole
	AND V4,VE
	LD V5,0CH		; Get vertical position of new hole
	AND V5,VD
	SKNE V4,V5
	RET

; State 2: If the hole cannot be moved any farther up, exit. Otherwise
; go to state 3.

MOVE_UP_2:
	SKNE V4,0
	RET

; State 3: Move the hole up one position and go back to state 1.

MOVE_UP_3:
	LD V4,<LOW -4>		; Up = left 4
	ADD V4,VE
	CALL SWAP_HOLE
	JUMP MOVE_UP_1

;-------

MOVE_DOWN:

; State 1: Check to see if the desired hole position and the current hole
; position are in the same row. If so, exit. Otherwise, go to state 2.

MOVE_DOWN_1:
	LD V4,0CH		; Get vertical position of hole
	AND V4,VE
	LD V5,0CH		; Get vertical position of new hole
	AND V5,VD
	SKNE V4,V5
	RET

; State 2: If the hole cannot be moved any farther down, exit. Otherwise
; go to state 3.

MOVE_DOWN_2:
	SKNE V4,0CH
	RET

; State 3: Move the hole down one position and go back to state 1.

MOVE_DOWN_3:
	LD V4,4			; Down = right 4
	ADD V4,VE
	CALL SWAP_HOLE
	JUMP MOVE_DOWN_1

;-------

SWAP_HOLE:
	LD I,BOARD		; Get the piece at the new hole position
	ADD I,V4
	LD V0,@I
	LD I,BOARD		; Put it at the old hole position
	ADD I,VE
	LD @I,V0
	LD V0,0			; Put a hole...
	LD I,BOARD		; ...at the new hole position
	ADD I,V4
	LD @I,V0
	LD VE,V4		; Move the hole marker to the new position
	RET

;-------

GET_MOVE:

; State 1: Check to see if there are any more random moves to select. If so,
; go to state 5. Otherwise go to state 2.
GET_MOVE_1:
	SKE VC,0
	JUMP GET_MOVE_5

; State 2: Prompt for and obtain a keystroke: display the board, wait for
; a keystroke, and then erase the board. Go to state 4.

GET_MOVE_2:
	CALL DISPLAY
	CALL MYKEY
	CALL DISPLAY

; State 3: <deleted>

; State 4: Translate the keystroke to the new hole position and exit.

GET_MOVE_4:
	LD I,KEYTABLE
	ADD I,VD
	LD V0,@I
	LD VD,V0
	RET

; State 5: Decrement the count of random moves remaining, select a random
; hole position, and exit.

GET_MOVE_5:
	ADD VC,<LOW -1>
	RANDOM VD,0FH
	RET

;-------

MYKEY:

; State 1: Continuously scan the keyboard until a key is pressed. When a
; key is pressed, go to state 2.

MYKEY_1:
	ADD VD,1		; Advance to next key number.
	LD V0,0FH		; Make certain that it's not bigger than 0FH
	AND VD,V0
	SKIFKEY VD		; If this key is down, go to state 2.
	JUMP MYKEY_1		; Otherwise stay in state 1.

; State 2: Wait for the key to be released. When it is, exit.

MYKEY_2:
	SKIFNOTKEY VD
	JUMP MYKEY_2
	RET

;-------

; The puzzle board

BOARD:
	DB 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0

; Translation table from key number to hole position

KEYTABLE:
	DB 0DH, 00H, 01H, 02H
	DB 04H, 05H, 06H, 08H
	DB 09H, 0AH, 0CH, 0EH
	DB 03H, 07H, 0BH, 0FH

	END
positio-- 
===============================================================================
Roger Ivie

35 S 300 W
Logan, Ut.  84321
(801) 752-8633
===============================================================================