8

a CHIP-8 emulator
Log | Files | Refs | README

15PUZZLE.SRC (7856B)


      1 ; From: SLSW2@cc.usu.edu (Roger Ivie)
      2 ;
      3 ; Here's PUZZLE.SRC, the infamous "15" puzzle for the calculator. I'm including
      4 ; it mainly as an example of how to use my CHIP8 macros.
      5 ;
      6 ; When running PUZZLE, the 4x4 keyboard area used by CHIP8 corresponds to the
      7 ; screen in the obvious manner. Simply press the key corresponding to the
      8 ; location that you want the hole to be moved and it will migrate there. The
      9 ; hole is moved up, down, left, then right until it winds up at the requested
     10 ; location.
     11 ;
     12 ; Once the program is started, pressing ENTER randomizes the board (the magic
     13 ; of self-modifying code).
     14 ;
     15 ; The program has absolutely no idea whether or not you've solved the puzzle,
     16 ; so it doesn't do anything special.
     17 ;
     18 ; Enjoy,
     19 ;
     20 ; Roger Ivie
     21 ; slsw2@cc.usu.edu
     22 ;
     23 ; PS: I'll post a binary as soon as I can get to my local Unix box again (the
     24 ; hardware hackers have taken over).
     25 
     26 
     27 ; Register usage:
     28 ;
     29 ; V0 - Used to grab things from memory
     30 ; V1 - Current piece to be displayed
     31 ; V2 - X coordinate where it is to be displayed
     32 ; V3 - Y coordinate where it is to be displayed
     33 ; V4 - General work; new hole position for swap_hole
     34 ; V5 - General work
     35 ; V6 -
     36 ; V7 -
     37 ; V8 -
     38 ; V9 -
     39 ; VA -
     40 ; VB -
     41 ; VC - Number of random moves to insert into the puzzle
     42 ; VD - Desired position of the hole
     43 ; VE - Current position of the hole
     44 ; VF -
     45 
     46 
     47 option binary
     48 align off
     49 
     50 	CLS
     51 
     52 START:
     53     LD  VC, 0
     54     SNE VC, 0
     55     DB #6E      ; 6E0F -> VE = 15: number of moves to randomize
     56 START+1:
     57     DB  #0F
     58     LD  I, START+1  ; Plug the number of moves to randomize
     59     LD  V0, 32
     60     LD  [I], V0
     61     CLS             ; Clear the screen
     62 
     63 LOOP:
     64 	CALL GET_MOVE
     65 	CALL MOVE_UP
     66 	CALL MOVE_DOWN
     67 	CALL MOVE_LEFT
     68 	CALL MOVE_RIGHT
     69     JP LOOP
     70 
     71 ;------------------
     72 
     73 XSTART  EQU 23                          ; Horizontal position of board
     74 YSTART  EQU 4                           ; Vertical position of board
     75 XOFF    EQU 5                           ; Horizontal offset to next piece
     76 YOFF    EQU 6                           ; Vertical offset to next piece
     77 
     78 DISPLAY:
     79 
     80 ; State 1: Initialize everything to be about the first piece on the board
     81 ; and go to state 2.
     82 
     83 DISPLAY_1:
     84 	LD V1,0
     85 	LD V2,XSTART
     86 	LD V3,YSTART
     87 
     88 ; State 2: If all pieces have been displayed, exit. Otherwise, go to state 3.
     89 
     90 DISPLAY_2:
     91     SNE V1, #10
     92 	RET
     93 
     94 ; State 3: Get the next piece to be displayed. If it's the hole (and therefore
     95 ; shouldn't be displayed), go to state 5. Otherwise go to state 4.
     96 
     97 DISPLAY_3:
     98 	LD I,BOARD
     99 	ADD I,V1
    100     LD V0,[I]
    101     SNE V0,0
    102     JP DISPLAY_5
    103 
    104 ; State 4: Display the current piece and go to state 5.
    105 
    106 DISPLAY_4:
    107     LD  F,  V0
    108     DRW V2,V3,5
    109 
    110 ; State 5: Advance the piece pointer and the horizontal position of the
    111 ; display to the next piece. If the new piece is the first in a new row,
    112 ; go to state 6. Otherwise go to state 2.
    113 
    114 DISPLAY_5:
    115 	ADD V1,1
    116 	ADD V2,XOFF
    117 	LD V4,3
    118 	AND V4,V1
    119     SE V4,0
    120     JP DISPLAY_2
    121 
    122 ; State 6: The piece is the first of a new row. Reinitialize the horizontal
    123 ; position to the first of the row and advance the vertical position to the
    124 ; next row. Go to state 2.
    125 
    126 DISPLAY_6:
    127 	LD V2,XSTART                    ; Start at beginning of next row.
    128 	ADD V3,YOFF
    129     JP DISPLAY_2
    130 
    131 ;-------
    132 
    133 MOVE_RIGHT:
    134 
    135 ; State 1: Check to see if the desired hole position and the current hole
    136 ; position are in the same column. If so, exit. Otherwise, go to state 2.
    137 
    138 MOVE_RIGHT_1:
    139 	LD V4,3                 ; Get horizontal position of hole
    140 	AND V4,VE
    141 	LD V5,3                 ; Get horizontal position of new hole
    142 	AND V5,VD
    143     SNE V4,V5
    144 	RET
    145 
    146 ; State 2: If the hole cannot be moved any farther right, exit. Otherwise
    147 ; go to state 3.
    148 
    149 MOVE_RIGHT_2:
    150     SNE V4,3
    151 	RET
    152 
    153 ; State 3: Move the hole right one position and go back to state 1.
    154 
    155 MOVE_RIGHT_3:
    156 	LD V4,1
    157 	ADD V4,VE
    158 	CALL SWAP_HOLE
    159     JP MOVE_RIGHT_1
    160 
    161 ;-------
    162 
    163 MOVE_LEFT:
    164 
    165 ; State 1: Check to see if the desired hole position and the current hole
    166 ; position are in the same column. If so, exit. Otherwise, go to state 2.
    167 
    168 MOVE_LEFT_1:
    169 	LD V4,3         ; Get horizontal position of hole
    170 	AND V4,VE
    171 	LD V5,3         ; Get horizontal position of new hole
    172 	AND V5,VD
    173     SNE V4,V5
    174 	RET
    175 
    176 ; State 2: If the hole cannot be moved any farther left, exit. Otherwise
    177 ; go to state 3.
    178 
    179 MOVE_LEFT_2:
    180     SNE V4,0
    181 	RET
    182 
    183 ; State 3: Move the hole left one position and go back to state 1.
    184 
    185 MOVE_LEFT_3:
    186     LD V4, #FF  ; <LOW -1>
    187 	ADD V4,VE
    188 	CALL SWAP_HOLE
    189     JP MOVE_LEFT_1
    190 
    191 ;-------
    192 
    193 MOVE_UP:
    194 
    195 ; State 1: Check to see if the desired hole position and the current hole
    196 ; position are in the same row. If so, exit. Otherwise, go to state 2.
    197 
    198 MOVE_UP_1:
    199     LD V4, #0C               ; Get vertical position of hole
    200 	AND V4,VE
    201     LD V5, #0C               ; Get vertical position of new hole
    202 	AND V5,VD
    203     SNE V4,V5
    204 	RET
    205 
    206 ; State 2: If the hole cannot be moved any farther up, exit. Otherwise
    207 ; go to state 3.
    208 
    209 MOVE_UP_2:
    210     SNE V4,0
    211 	RET
    212 
    213 ; State 3: Move the hole up one position and go back to state 1.
    214 
    215 MOVE_UP_3:
    216     LD V4, #FC  ;<LOW -4>          Up = left 4
    217 	ADD V4,VE
    218 	CALL SWAP_HOLE
    219     JP MOVE_UP_1
    220 
    221 ;-------
    222 
    223 MOVE_DOWN:
    224 
    225 ; State 1: Check to see if the desired hole position and the current hole
    226 ; position are in the same row. If so, exit. Otherwise, go to state 2.
    227 
    228 MOVE_DOWN_1:
    229     LD V4, #0C               ; Get vertical position of hole
    230 	AND V4,VE
    231     LD V5, #0C               ; Get vertical position of new hole
    232 	AND V5,VD
    233     SNE V4,V5
    234 	RET
    235 
    236 ; State 2: If the hole cannot be moved any farther down, exit. Otherwise
    237 ; go to state 3.
    238 
    239 MOVE_DOWN_2:
    240     SNE V4, #0C
    241 	RET
    242 
    243 ; State 3: Move the hole down one position and go back to state 1.
    244 
    245 MOVE_DOWN_3:
    246 	LD V4,4                 ; Down = right 4
    247 	ADD V4,VE
    248 	CALL SWAP_HOLE
    249     JP MOVE_DOWN_1
    250 
    251 ;-------
    252 
    253 SWAP_HOLE:
    254 	LD I,BOARD              ; Get the piece at the new hole position
    255 	ADD I,V4
    256     LD V0,[I]
    257 	LD I,BOARD              ; Put it at the old hole position
    258 	ADD I,VE
    259     LD [I],V0
    260 	LD V0,0                 ; Put a hole...
    261 	LD I,BOARD              ; ...at the new hole position
    262 	ADD I,V4
    263     LD [I],V0
    264 	LD VE,V4                ; Move the hole marker to the new position
    265 	RET
    266 
    267 ;-------
    268 
    269 GET_MOVE:
    270 
    271 ; State 1: Check to see if there are any more random moves to select. If so,
    272 ; go to state 5. Otherwise go to state 2.
    273 GET_MOVE_1:
    274     SE VC,0
    275     JP GET_MOVE_5
    276 
    277 ; State 2: Prompt for and obtain a keystroke: display the board, wait for
    278 ; a keystroke, and then erase the board. Go to state 4.
    279 
    280 GET_MOVE_2:
    281 	CALL DISPLAY
    282 	CALL MYKEY
    283 	CALL DISPLAY
    284 
    285 ; State 3: <deleted>
    286 
    287 ; State 4: Translate the keystroke to the new hole position and exit.
    288 
    289 GET_MOVE_4:
    290 	LD I,KEYTABLE
    291 	ADD I,VD
    292     LD V0,[I]
    293 	LD VD,V0
    294 	RET
    295 
    296 ; State 5: Decrement the count of random moves remaining, select a random
    297 ; hole position, and exit.
    298 
    299 GET_MOVE_5:
    300     ADD VC, #FF ;<LOW -1>
    301     RND VD, #0F
    302 	RET
    303 
    304 ;-------
    305 
    306 MYKEY:
    307 
    308 ; State 1: Continuously scan the keyboard until a key is pressed. When a
    309 ; key is pressed, go to state 2.
    310 
    311 MYKEY_1:
    312 	ADD VD,1                ; Advance to next key number.
    313     LD V0, #0F               ; Make certain that it's not bigger than 0FH
    314 	AND VD,V0
    315     SKP VD              ; If this key is down, go to state 2.
    316     JP MYKEY_1            ; Otherwise stay in state 1.
    317 
    318 ; State 2: Wait for the key to be released. When it is, exit.
    319 
    320 MYKEY_2:
    321     SKNP VD
    322     JP MYKEY_2
    323 	RET
    324 
    325 ;-------
    326 
    327 ; The puzzle board
    328 
    329 BOARD:
    330 	DB 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0
    331 
    332 ; Translation table from key number to hole position
    333 
    334 KEYTABLE:
    335     DB #0D, #00, #01, #02
    336     DB #04, #05, #06, #08
    337     DB #09, #0A, #0C, #0E
    338     DB #03, #07, #0B, #0F
    339 
    340 	END