8

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

commit 364749edd19d2a70fec0db4554580afacb3c7254
parent afa0c4b36cb0fb70ae189a6a316823384ea74ca5
Author: Naveen Narayanan <zerous@nocebo.space>
Date:   Fri, 26 Jul 2024 00:34:51 +0200

Add some roms

Diffstat:
Aroms/15PUZZLE.SRC | 340+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroms/15PUZZLE.ch8 | 0
Aroms/AIRPLANE.ch8 | 0
Aroms/BLINKY.SRC | 1775+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroms/BLINKY.ch8 | 0
Aroms/BLITZ.ch8 | 0
Aroms/BREAKOUT.SRC | 256+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroms/BREAKOUT.ch8 | 0
Aroms/BRIX.SRC | 252+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroms/BRIX.ch8 | 0
Aroms/CAVE.ch8 | 0
Aroms/CONNECT4.ch8 | 0
Aroms/FIGURES.ch8 | 0
Aroms/FILTER.ch8 | 0
Aroms/GUESS.ch8 | 0
Aroms/HIDDEN.ch8 | 0
Aroms/HIDDEN.txt | 28++++++++++++++++++++++++++++
Aroms/INVADERS.ch8 | 0
Aroms/JOUST.txt | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroms/KALEID.ch8 | 0
Aroms/LANDING.ch8 | 0
Aroms/MAZE.SRC | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroms/MAZE.ch8 | 0
Aroms/MERLIN.ch8 | 0
Aroms/MISSILE.ch8 | 0
Aroms/PADDLES.ch8 | 0
Aroms/PONG(1P).ch8 | 0
Aroms/PONG.SRC | 237+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroms/PONG.ch8 | 0
Aroms/PONG2.SRC | 277+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroms/PONG2.ch8 | 0
Aroms/PUZZLE.ch8 | 0
Aroms/ROCKET.ch8 | 0
Aroms/SOCCER.ch8 | 0
Aroms/SPACEF.ch8 | 0
Aroms/SQUASH.ch8 | 0
Aroms/SYZYGY.SRC | 808+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroms/SYZYGY.ch8 | 0
Aroms/TANK.ch8 | 0
Aroms/TETRIS.ch8 | 0
Aroms/TICTAC.ch8 | 0
Aroms/TRON.ch8 | 0
Aroms/UFO.SRC | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroms/UFO.ch8 | 0
Aroms/VBRIX.SRC | 371+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroms/VBRIX.ch8 | 0
Aroms/VERS.ch8 | 0
Aroms/WALL.ch8 | 0
Aroms/WIPEOFF.ch8 | 0
49 files changed, 4623 insertions(+), 0 deletions(-)

diff --git a/roms/15PUZZLE.SRC b/roms/15PUZZLE.SRC @@ -0,0 +1,340 @@ +; From: SLSW2@cc.usu.edu (Roger Ivie) +; +; Here's PUZZLE.SRC, 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 randomizes the board (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). + + +; 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 - + + +option binary +align off + + CLS + +START: + LD VC, 0 + SNE VC, 0 + DB #6E ; 6E0F -> VE = 15: number of moves to randomize +START+1: + DB #0F + 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 + JP 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: + SNE V1, #10 + 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] + SNE V0,0 + JP DISPLAY_5 + +; State 4: Display the current piece and go to state 5. + +DISPLAY_4: + LD F, V0 + DRW 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 + SE V4,0 + JP 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 + JP 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 + SNE V4,V5 + RET + +; State 2: If the hole cannot be moved any farther right, exit. Otherwise +; go to state 3. + +MOVE_RIGHT_2: + SNE 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 + JP 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 + SNE V4,V5 + RET + +; State 2: If the hole cannot be moved any farther left, exit. Otherwise +; go to state 3. + +MOVE_LEFT_2: + SNE V4,0 + RET + +; State 3: Move the hole left one position and go back to state 1. + +MOVE_LEFT_3: + LD V4, #FF ; <LOW -1> + ADD V4,VE + CALL SWAP_HOLE + JP 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, #0C ; Get vertical position of hole + AND V4,VE + LD V5, #0C ; Get vertical position of new hole + AND V5,VD + SNE V4,V5 + RET + +; State 2: If the hole cannot be moved any farther up, exit. Otherwise +; go to state 3. + +MOVE_UP_2: + SNE V4,0 + RET + +; State 3: Move the hole up one position and go back to state 1. + +MOVE_UP_3: + LD V4, #FC ;<LOW -4> Up = left 4 + ADD V4,VE + CALL SWAP_HOLE + JP 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, #0C ; Get vertical position of hole + AND V4,VE + LD V5, #0C ; Get vertical position of new hole + AND V5,VD + SNE V4,V5 + RET + +; State 2: If the hole cannot be moved any farther down, exit. Otherwise +; go to state 3. + +MOVE_DOWN_2: + SNE V4, #0C + 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 + JP 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: + SE VC,0 + JP 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, #FF ;<LOW -1> + RND VD, #0F + 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, #0F ; Make certain that it's not bigger than 0FH + AND VD,V0 + SKP VD ; If this key is down, go to state 2. + JP MYKEY_1 ; Otherwise stay in state 1. + +; State 2: Wait for the key to be released. When it is, exit. + +MYKEY_2: + SKNP VD + JP 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 #0D, #00, #01, #02 + DB #04, #05, #06, #08 + DB #09, #0A, #0C, #0E + DB #03, #07, #0B, #0F + + END diff --git a/roms/15PUZZLE.ch8 b/roms/15PUZZLE.ch8 Binary files differ. diff --git a/roms/AIRPLANE.ch8 b/roms/AIRPLANE.ch8 Binary files differ. diff --git a/roms/BLINKY.SRC b/roms/BLINKY.SRC @@ -0,0 +1,1775 @@ +; (S)Chip-48 Blinky V2.00 by Christian Egeberg 7/11-'90 .. 18/8-'91 +; EMail at egeberg@solan.unit.no +; +; Register usage: +; V0: Temporary data, may change during any call +; V1: Temporary data, may change during any call +; V2: Temporary data, may change during most calls +; V3: Temporary data, may change during most calls +; V4: Temporary data, may change during some calls +; V5: Temporary data, may change during some calls +; V6: Pill and score counter +; V7: Life and sprite direction register +; V8: Blinky X screen coordinate +; V9: Blinky Y screen coordinate +; VA: Packlett X screen coordinate +; VB: Packlett Y screen coordinate +; VC: Heward X screen coordinate +; VD: Heward Y screen coordinate +; VE: Temporary constant and flag storage +; VF: Flag register + +; DEFINE/UNDEF SUPER in line below to toggle between versions + + OPTION BINARY ; Let's compile this for non-HP computers... +; OPTION HPASC + + IFDEF SUPER + OPTION SCHIP10 + ELSE + OPTION CHIP48 + ENDIF + +MASKNIBB = $1111 +MASKBYTE = $11111111 + +DOWNKEY = #6 +RIGHTKEY = #8 +LEFTKEY = #7 +UPKEY = #3 +PRESSKEY = #F +LEVELKEY = #1 + +PILLNUM = 231 +SUPERNUM = 4 + +PILLTIME = 5 +SUPERTIME = 255 +CLSWAIT = 63 +EYEWAIT = 3 + +PILLADD = 1 +SUPERADD = 4 +HEWARDADD = 25 +PACKLETTADD = 50 +SCREENADD = 100 + +MASKLIFE = $01000000 +MASKHUNT = $10000000 +MASKCODE = $11 +DOWNCODE = $11 +RIGHTCODE = $10 +LEFTCODE = $01 +UPCODE = $00 + +BLINKYCODE = DOWNCODE +PACKLETTCODE = LEFTCODE +HEWARDCODE = RIGHTCODE +STARTCODE = HEWARDCODE < 4 | PACKLETTCODE < 2 | BLINKYCODE + +STARTLEVEL = $101 + + IFDEF SUPER + + SCREENHIGH = 64 + SCREENWIDE = 128 + SPRITEHIGH = 8 + SPRITEWIDE = 16 + SPRITEJUMP = 4 + + BLINKYX = 52 + BLINKYY = 24 + PACKLETTX = 112 + PACKLETTY = 0 + HEWARDX = 4 + HEWARDY = 52 + + GATELEFT = 0 + GATERIGHT = 116 + + SCXPOS = 36 + SCYPOS = 32 + HIXPOS = 36 + HIYPOS = 20 + EYEX1 = 0 + EYEX2 = 96 + EYEY1 = 1 + EYEY2 = 45 + + ELSE + + SCREENHIGH = 32 + SCREENWIDE = 64 + SPRITEHIGH = 4 + SPRITEWIDE = 8 + SPRITEJUMP = 2 + + BLINKYX = 26 + BLINKYY = 12 + PACKLETTX = 56 + PACKLETTY = 0 + HEWARDX = 2 + HEWARDY = 26 + + GATELEFT = 0 + GATERIGHT = 58 + + SCXPOS = 17 + SCYPOS = 16 + HIXPOS = 17 + HIYPOS = 10 + EYEX1 = 0 + EYEX2 = 48 + EYEY1 = 0 + EYEY2 = 22 + + ENDIF + + JP START + +COPYRIGHT: DA '2.00 C. Egeberg 18/8-''91' + USED COPYRIGHT + +START: IFDEF SUPER + HIGH + ENDIF + XOR V0, V0 + XOR V1, V1 + LD I, SCORE + LD [I], V1 + LD V0, STARTLEVEL + LD I, LEVEL + LD [I], V0 + XOR V7, V7 +REINIT: XOR V6, V6 + CALL COPYMAZE + CLS + CALL DRAWMAZE +RESTART: LD VE, MASKLIFE + AND V7, VE + LD VE, STARTCODE + OR V7, VE + LD V8, BLINKYX + LD V9, BLINKYY + LD VA, PACKLETTX + LD VB, PACKLETTY + LD VC, HEWARDX + LD VD, HEWARDY + CALL DRAWBLINKY + LD I, GHOST + DRW VA, VB, SPRITEHIGH + DRW VC, VD, SPRITEHIGH +GAMELOOP: CALL MOVEBLINKY + SE VE, 0 + JP ENCOUNTER +SPLITUP: LD I, LEVEL + LD V0, [I] + LD V5, V0 + RND V4, MASKBYTE + AND V4, V5 + CALL MOVEPACKLETT + RND V4, MASKBYTE + AND V4, V5 + CALL MOVEHEWARD + LD V0, LEVELKEY + SKNP V0 + CALL NEXTLEVEL + SE V6, PILLADD * PILLNUM + SUPERADD * SUPERNUM + JP GAMELOOP + LD VE, V6 + CALL ADDSCORE + LD VE, SCREENADD + CALL ADDSCORE + CALL NEXTLEVEL + JP REINIT +ENCOUNTER: LD V0, DT + SNE V0, 0 + JP GOTCHA + LD V0, V8 + SHR V0 + IFDEF SUPER + SHR V0 + ENDIF + LD V1, VA + SHR V1 + IFDEF SUPER + SHR V1 + ENDIF + SUB V0, V1 + SNE V0, 0 + JP HITPACKLETT1 + SNE V0, 1 + JP HITPACKLETT1 + SNE V0, -1 & MASKBYTE + JP HITPACKLETT1 + JP OOPSHEWARD +HITPACKLETT1: LD V0, V9 + SHR V0 + IFDEF SUPER + SHR V0 + ENDIF + LD V1, VB + SHR V1 + IFDEF SUPER + SHR V1 + ENDIF + SUB V0, V1 + SNE V0, 0 + JP HITPACKLETT2 + SNE V0, 1 + JP HITPACKLETT2 + SNE V0, -1 & MASKBYTE + JP HITPACKLETT2 + JP OOPSHEWARD +HITPACKLETT2: LD I, GHOST + DRW VA, VB, SPRITEHIGH + LD VA, PACKLETTX + LD VB, PACKLETTY + DRW VA, VB, SPRITEHIGH + LD VE, ~( MASKCODE < 2 ) & MASKBYTE + AND V7, VE + LD VE, PACKLETTCODE < 2 + OR V7, VE + LD VE, PACKLETTADD + CALL ADDSCORE +OOPSHEWARD: LD V0, V8 + SHR V0 + IFDEF SUPER + SHR V0 + ENDIF + LD V1, VC + SHR V1 + IFDEF SUPER + SHR V1 + ENDIF + SUB V0, V1 + SNE V0, 0 + JP HITHEWARD1 + SNE V0, 1 + JP HITHEWARD1 + SNE V0, -1 & MASKBYTE + JP HITHEWARD1 + JP SPLITUP +HITHEWARD1: LD V0, V9 + SHR V0 + IFDEF SUPER + SHR V0 + ENDIF + LD V1, VD + SHR V1 + IFDEF SUPER + SHR V1 + ENDIF + SUB V0, V1 + SNE V0, 0 + JP HITHEWARD2 + SNE V0, 1 + JP HITHEWARD2 + SNE V0, -1 & MASKBYTE + JP HITHEWARD2 + JP SPLITUP +HITHEWARD2: LD I, GHOST + DRW VC, VD, SPRITEHIGH + LD VC, HEWARDX + LD VD, HEWARDY + DRW VC, VD, SPRITEHIGH + LD VE, ~( MASKCODE < 4 ) & MASKBYTE + AND V7, VE + LD VE, HEWARDCODE < 4 + OR V7, VE + LD VE, HEWARDADD + CALL ADDSCORE + JP SPLITUP +GOTCHA: LD V0, CLSWAIT + CALL WAITKEY + CALL DRAWBLINKY + LD I, GHOST + DRW VA, VB, SPRITEHIGH + DRW VC, VD, SPRITEHIGH + LD VE, MASKLIFE + XOR V7, VE + LD V0, V7 + AND V0, VE + SE V0, 0 + JP RESTART + LD VE, V6 + CALL ADDSCORE + CALL NEWHIGH + CLS + LD V6, HIXPOS + LD V7, HIYPOS + LD I, HIGHSCORE + CALL PRINTDEC + LD V6, SCXPOS + LD V7, SCYPOS + LD I, SCORE + CALL PRINTDEC + LD V4, EYEX1 + LD V5, EYEX1 + SPRITEWIDE + LD V6, EYEY1 + LD V7, PRESSKEY +EYEX1LOOP: LD I, EYELEFT + IFDEF SUPER + DRW V4, V6, 0 + ELSE + DRW V4, V6, 9 + ENDIF + LD I, EYERIGHT + IFDEF SUPER + DRW V5, V6, 0 + ELSE + DRW V5, V6, 9 + ENDIF + LD V0, EYEWAIT + CALL WAITKEY + SE VE, 0 + JP EYEPRESS + LD I, EYELEFT + IFDEF SUPER + DRW V4, V6, 0 + ELSE + DRW V4, V6, 9 + ENDIF + LD I, EYERIGHT + IFDEF SUPER + DRW V5, V6, 0 + ELSE + DRW V5, V6, 9 + ENDIF + ADD V4, SPRITEJUMP + ADD V5, SPRITEJUMP + SE V4, EYEX2 + JP EYEX1LOOP +EYEY1LOOP: LD I, EYELEFT + IFDEF SUPER + DRW V4, V6, 0 + ELSE + DRW V4, V6, 9 + ENDIF + LD I, EYERIGHT + IFDEF SUPER + DRW V5, V6, 0 + ELSE + DRW V5, V6, 9 + ENDIF + LD V0, EYEWAIT + CALL WAITKEY + SE VE, 0 + JP EYEPRESS + LD I, EYELEFT + IFDEF SUPER + DRW V4, V6, 0 + ELSE + DRW V4, V6, 9 + ENDIF + LD I, EYERIGHT + IFDEF SUPER + DRW V5, V6, 0 + ELSE + DRW V5, V6, 9 + ENDIF + ADD V6, SPRITEJUMP + SE V6, EYEY2 + JP EYEY1LOOP +EYEX2LOOP: LD I, EYELEFT + IFDEF SUPER + DRW V4, V6, 0 + ELSE + DRW V4, V6, 9 + ENDIF + LD I, EYERIGHT + IFDEF SUPER + DRW V5, V6, 0 + ELSE + DRW V5, V6, 9 + ENDIF + LD V0, EYEWAIT + CALL WAITKEY + SE VE, 0 + JP EYEPRESS + LD I, EYELEFT + IFDEF SUPER + DRW V4, V6, 0 + ELSE + DRW V4, V6, 9 + ENDIF + LD I, EYERIGHT + IFDEF SUPER + DRW V5, V6, 0 + ELSE + DRW V5, V6, 9 + ENDIF + ADD V4, -SPRITEJUMP & MASKBYTE + ADD V5, -SPRITEJUMP & MASKBYTE + SE V4, EYEX1 + JP EYEX2LOOP +EYEY2LOOP: LD I, EYELEFT + IFDEF SUPER + DRW V4, V6, 0 + ELSE + DRW V4, V6, 9 + ENDIF + LD I, EYERIGHT + IFDEF SUPER + DRW V5, V6, 0 + ELSE + DRW V5, V6, 9 + ENDIF + LD V0, EYEWAIT + CALL WAITKEY + SE VE, 0 + JP EYEPRESS + LD I, EYELEFT + IFDEF SUPER + DRW V4, V6, 0 + ELSE + DRW V4, V6, 9 + ENDIF + LD I, EYERIGHT + IFDEF SUPER + DRW V5, V6, 0 + ELSE + DRW V5, V6, 9 + ENDIF + ADD V6, -SPRITEJUMP & MASKBYTE + SE V6, EYEY1 + JP EYEY2LOOP + JP EYEX1LOOP +EYEPRESS: LD I, EYERIGHT + IFDEF SUPER + DRW V5, V6, 0 + ELSE + DRW V5, V6, 9 + ENDIF + LD I, EYEBLINK + IFDEF SUPER + DRW V5, V6, 0 + ELSE + DRW V5, V6, 9 + ENDIF + JP START + +; MOVEBLINKY +; ->: Nothing +; <-: VE: Collision flag +; <>: V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, VE, VF, I + +MOVEBLINKY: LD V3, V7 + LD VE, MASKCODE + AND V3, VE + LD V4, V8 + LD V5, V9 + LD VE, DOWNKEY + SKNP VE + JP BLINKYDOWN + LD VE, UPKEY + SKNP VE + JP BLINKYUP + LD VE, RIGHTKEY + SKNP VE + JP BLINKYRIGHT + LD VE, LEFTKEY + SKNP VE + JP BLINKYLEFT +NOKEY: SNE V3, DOWNCODE + ADD V5, SPRITEJUMP + SNE V3, UPCODE + ADD V5, -SPRITEJUMP & MASKBYTE + SNE V3, RIGHTCODE + ADD V4, SPRITEJUMP + SNE V3, LEFTCODE + ADD V4, -SPRITEJUMP & MASKBYTE + LD V0, V4 + LD V1, V5 + CALL SPRITMAZE + LD V2, V0 + LD VE, GRAPHEDGE + AND V0, VE +DONEKEY: SE V0, 0 + JP STOPBLINKY + LD VE, GRAPHSPEC + LD V0, V2 + AND V2, VE + SNE V2, PL + JP EATPILL + SNE V2, SP + JP EATSUPER + SNE V2, GW + JP GATEWAY +DONEEAT: CALL DRAWBLINKY + LD VE, ~MASKCODE & MASKBYTE + AND V7, VE + OR V7, V3 + LD V8, V4 + LD V9, V5 + JP DRAWBLINKY +BLINKYDOWN: LD V0, V4 + LD V1, V5 + ADD V1, SPRITEJUMP + CALL SPRITMAZE + LD V2, V0 + LD VE, GRAPHEDGE + AND V0, VE + SE V0, 0 + JP NOKEY + LD V3, DOWNCODE + ADD V5, SPRITEJUMP + JP DONEKEY +BLINKYUP: LD V0, V4 + LD V1, V5 + ADD V1, -SPRITEJUMP & MASKBYTE + CALL SPRITMAZE + LD V2, V0 + LD VE, GRAPHEDGE + AND V0, VE + SE V0, 0 + JP NOKEY + LD V3, UPCODE + ADD V5, -SPRITEJUMP & MASKBYTE + JP DONEKEY +BLINKYRIGHT: LD V0, V4 + LD V1, V5 + ADD V0, SPRITEJUMP + CALL SPRITMAZE + LD V2, V0 + LD VE, GRAPHEDGE + AND V0, VE + SE V0, 0 + JP NOKEY + LD V3, RIGHTCODE + ADD V4, SPRITEJUMP + JP DONEKEY +BLINKYLEFT: LD V0, V4 + LD V1, V5 + ADD V0, -SPRITEJUMP & MASKBYTE + CALL SPRITMAZE + LD V2, V0 + LD VE, GRAPHEDGE + AND V0, VE + SE V0, 0 + JP NOKEY + LD V3, LEFTCODE + ADD V4, -SPRITEJUMP & MASKBYTE + JP DONEKEY +STOPBLINKY: CALL DRAWBLINKY + DRW V8, V9, SPRITEHIGH + LD VE, VF + RET +EATPILL: LD VE, ~MASKNIBB & MASKBYTE + AND V0, VE + OR V0, V3 + LD [I], V0 + LD I, PILL + DRW V4, V5, SPRITEHIGH + ADD V6, PILLADD + LD V1, PILLTIME + LD V0, DT + SNE V0, 0 + LD ST, V1 + JP DONEEAT +EATSUPER: LD VE, ~MASKNIBB & MASKBYTE + AND V0, VE + OR V0, V3 + LD [I], V0 + LD I, SUPER + DRW V4, V5, SPRITEHIGH + ADD V6, SUPERADD + LD V0, VA + LD V1, VB + CALL SPRITMAZE + LD VE, ~MASKNIBB & MASKBYTE + AND V0, VE + SE V0, 0 + JP SKIPPACKLETT + LD VE, MASKCODE < 2 + XOR V7, VE +SKIPPACKLETT: LD V0, VC + LD V1, VD + CALL SPRITMAZE + LD VE, ~MASKNIBB & MASKBYTE + AND V0, VE + SE V0, 0 + JP SKIPHEWARD + LD VE, MASKCODE < 4 + XOR V7, VE +SKIPHEWARD: LD V0, SUPERTIME + LD ST, V0 + LD DT, V0 + JP DONEEAT +GATEWAY: SNE V3, LEFTCODE + LD V4, GATERIGHT + SNE V3, RIGHTCODE + LD V4, GATELEFT + JP DONEEAT + +; MOVEPACKLETT +; ->: V4: Force random move if nonzero value +; <-: Nothing +; <>: V0, V1, V2, V3, V7, VA, VB, VE, VF, I + +MOVEPACKLETT: LD V2, V7 + LD V3, V7 + LD VE, MASKCODE < 2 + AND V2, VE + LD V0, VA + LD V1, VB + CALL SPRITMAZE + LD I, GHOST + LD VE, ~MASKNIBB & MASKBYTE + AND V0, VE + SE V0, 0 + JP LOOKPACKLETT +TURNPACKLETT: DRW VA, VB, SPRITEHIGH + SNE V2, DOWNCODE < 2 + ADD VB, SPRITEJUMP + SNE V2, UPCODE < 2 + ADD VB, -SPRITEJUMP & MASKBYTE + SNE V2, RIGHTCODE < 2 + ADD VA, SPRITEJUMP + SNE V2, LEFTCODE < 2 + ADD VA, -SPRITEJUMP & MASKBYTE + DRW VA, VB, SPRITEHIGH + RET +LOOKPACKLETT: LD VE, MASKHUNT + LD V1, DT + SE V1, 0 + JP RANDPACKLETT + SE V4, 0 + JP RANDPACKLETT + LD V1, V0 + SHL V3 + SE VF, 0 + JP HORISPACKLETT + LD V3, V9 + SUB V3, VB + SNE VF, 0 + JP PACKLETTLU + SE V3, 0 + JP PACKLETTLD + XOR V7, VE + LD V3, V8 + SUB V3, VA + SNE VF, 0 + JP PACKLETTLL + SE V3, 0 + JP PACKLETTLR + XOR V7, VE + JP RANDPACKLETT +HORISPACKLETT: LD V3, V8 + SUB V3, VA + SNE VF, 0 + JP PACKLETTLL + SE V3, 0 + JP PACKLETTLR + XOR V7, VE + LD V3, V9 + SUB V3, VB + SNE VF, 0 + JP PACKLETTLU + SE V3, 0 + JP PACKLETTLD + XOR V7, VE + JP RANDPACKLETT +PACKLETTLD: LD V3, MD + AND V1, V3 + SNE V1, 0 + JP RANDPACKLETT + DRW VA, VB, SPRITEHIGH + ADD VB, SPRITEJUMP + DRW VA, VB, SPRITEHIGH + LD VE, ~( MASKCODE < 2 ) & MASKBYTE + AND V7, VE + LD V2, DOWNCODE < 2 + OR V7, V2 + RET +PACKLETTLU: LD V3, MU + AND V1, V3 + SNE V1, 0 + JP RANDPACKLETT + DRW VA, VB, SPRITEHIGH + ADD VB, -SPRITEJUMP & MASKBYTE + DRW VA, VB, SPRITEHIGH + LD VE, ~( MASKCODE < 2 ) & MASKBYTE + AND V7, VE + LD V2, UPCODE < 2 + OR V7, V2 + RET +PACKLETTLR: LD V3, MR + AND V1, V3 + SNE V1, 0 + JP RANDPACKLETT + DRW VA, VB, SPRITEHIGH + ADD VA, SPRITEJUMP + DRW VA, VB, SPRITEHIGH + LD VE, ~( MASKCODE < 2 ) & MASKBYTE + AND V7, VE + LD V2, RIGHTCODE < 2 + OR V7, V2 + RET +PACKLETTLL: LD V3, ML + AND V1, V3 + SNE V1, 0 + JP RANDPACKLETT + DRW VA, VB, SPRITEHIGH + ADD VA, -SPRITEJUMP & MASKBYTE + DRW VA, VB, SPRITEHIGH + LD VE, ~( MASKCODE < 2 ) & MASKBYTE + AND V7, VE + LD V2, LEFTCODE < 2 + OR V7, V2 + RET +RANDPACKLETT: RND V1, ~MASKNIBB & MASKBYTE + AND V0, V1 + SE V0, 0 + JP SETPACKLETT +PACKLETTERR: LD VE, MASKCODE < 2 + XOR V7, VE + XOR V2, VE + JP TURNPACKLETT +SETPACKLETT: DRW VA, VB, SPRITEHIGH + SHL V0 + SNE VF, 0 + JP PACKLETTRD + LD V2, LEFTCODE < 2 + ADD VA, -SPRITEJUMP & MASKBYTE + JP PACKLETTSET +PACKLETTRD: SHL V0 + SNE VF, 0 + JP PACKLETTRR + LD V2, DOWNCODE < 2 + ADD VB, SPRITEJUMP + JP PACKLETTSET +PACKLETTRR: SHL V0 + SNE VF, 0 + JP PACKLETTRU + LD V2, RIGHTCODE < 2 + ADD VA, SPRITEJUMP + JP PACKLETTSET +PACKLETTRU: SHL V0 + SNE VF, 0 + JP PACKLETTERR + LD V2, UPCODE < 2 + ADD VB, -SPRITEJUMP & MASKBYTE +PACKLETTSET: DRW VA, VB, SPRITEHIGH + LD VE, ~( MASKCODE < 2 ) & MASKBYTE + AND V7, VE + OR V7, V2 + RET + +; MOVEHEWARD +; ->: V4: Force random move if nonzero value +; <-: Nothing +; <>: V0, V1, V2, V3, V7, VC, VD, VE, VF, I + +MOVEHEWARD: LD V2, V7 + LD V3, V7 + LD VE, MASKCODE < 4 + AND V2, VE + LD V0, VC + LD V1, VD + CALL SPRITMAZE + LD I, GHOST + LD VE, ~MASKNIBB & MASKBYTE + AND V0, VE + SE V0, 0 + JP LOOKHEWARD +TURNHEWARD: DRW VC, VD, SPRITEHIGH + SNE V2, DOWNCODE < 4 + ADD VD, SPRITEJUMP + SNE V2, UPCODE < 4 + ADD VD, -SPRITEJUMP & MASKBYTE + SNE V2, RIGHTCODE < 4 + ADD VC, SPRITEJUMP + SNE V2, LEFTCODE < 4 + ADD VC, -SPRITEJUMP & MASKBYTE + DRW VC, VD, SPRITEHIGH + RET +LOOKHEWARD: LD VE, MASKHUNT + LD V1, DT + SE V1, 0 + JP RANDHEWARD + SE V4, 0 + JP RANDHEWARD + LD V1, V0 + SHL V3 + SNE VF, 0 + JP HORISHEWARD + LD V3, V9 + SUB V3, VD + SNE VF, 0 + JP HEWARDLU + SE V3, 0 + JP HEWARDLD + XOR V7, VE + LD V3, V8 + SUB V3, VC + SNE VF, 0 + JP HEWARDLL + SE V3, 0 + JP HEWARDLR + XOR V7, VE + JP RANDHEWARD +HORISHEWARD: LD V3, V8 + SUB V3, VC + SNE VF, 0 + JP HEWARDLL + SE V3, 0 + JP HEWARDLR + XOR V7, VE + LD V3, V9 + SUB V3, VD + SNE VF, 0 + JP HEWARDLU + SE V3, 0 + JP HEWARDLD + XOR V7, VE + JP RANDHEWARD +HEWARDLD: LD V3, MD + AND V1, V3 + SNE V1, 0 + JP RANDHEWARD + DRW VC, VD, SPRITEHIGH + ADD VD, SPRITEJUMP + DRW VC, VD, SPRITEHIGH + XOR V7, VE + LD VE, ~( MASKCODE < 4 ) & MASKBYTE + AND V7, VE + LD V2, DOWNCODE < 4 + OR V7, V2 + RET +HEWARDLU: LD V3, MU + AND V1, V3 + SNE V1, 0 + JP RANDHEWARD + DRW VC, VD, SPRITEHIGH + ADD VD, -SPRITEJUMP & MASKBYTE + DRW VC, VD, SPRITEHIGH + XOR V7, VE + LD VE, ~( MASKCODE < 4 ) & MASKBYTE + AND V7, VE + LD V2, UPCODE < 4 + OR V7, V2 + RET +HEWARDLR: LD V3, MR + AND V1, V3 + SNE V1, 0 + JP RANDHEWARD + DRW VC, VD, SPRITEHIGH + ADD VC, SPRITEJUMP + DRW VC, VD, SPRITEHIGH + XOR V7, VE + LD VE, ~( MASKCODE < 4 ) & MASKBYTE + AND V7, VE + LD V2, RIGHTCODE < 4 + OR V7, V2 + RET +HEWARDLL: LD V3, ML + AND V1, V3 + SNE V1, 0 + JP RANDHEWARD + DRW VC, VD, SPRITEHIGH + ADD VC, -SPRITEJUMP & MASKBYTE + DRW VC, VD, SPRITEHIGH + XOR V7, VE + LD VE, ~( MASKCODE < 4 ) & MASKBYTE + AND V7, VE + LD V2, LEFTCODE < 4 + OR V7, V2 + RET +RANDHEWARD: RND V1, ~MASKNIBB & MASKBYTE + AND V0, V1 + SE V0, 0 + JP SETHEWARD +HEWARDERR: XOR V7, VE + LD VE, MASKCODE < 4 + XOR V7, VE + XOR V2, VE + JP TURNHEWARD +SETHEWARD: DRW VC, VD, SPRITEHIGH + SHL V0 + SNE VF, 0 + JP HEWARDRD + LD V2, LEFTCODE < 4 | MASKHUNT + ADD VC, -SPRITEJUMP & MASKBYTE + JP HEWARDSET +HEWARDRD: SHL V0 + SNE VF, 0 + JP HEWARDRR + LD V2, DOWNCODE < 4 + ADD VD, SPRITEJUMP + JP HEWARDSET +HEWARDRR: SHL V0 + SNE VF, 0 + JP HEWARDRU + LD V2, RIGHTCODE < 4 | MASKHUNT + ADD VC, SPRITEJUMP + JP HEWARDSET +HEWARDRU: SHL V0 + SNE VF, 0 + JP HEWARDERR + LD V2, UPCODE < 4 + ADD VD, -SPRITEJUMP & MASKBYTE +HEWARDSET: DRW VC, VD, SPRITEHIGH + LD VE, ~( MASKCODE < 4 | MASKHUNT ) & MASKBYTE + AND V7, VE + OR V7, V2 + RET + +; DRAWBLINKY +; -> V7: Sprite direction register +; -> V8: Blinky X screen coordinate +; -> V9: Blinky Y screen coordinate +; <- VE: Collision flag +; <- I: Blinky sprite pointer +; <> V0, V1, VE, VF, I + +DRAWBLINKY: LD V0, V7 + LD VE, MASKCODE + AND V0, VE + SHL V0 + LD V1, V8 + ADD V1, V9 + LD VE, SPRITEJUMP + AND V1, VE + SNE V1, 0 + ADD V0, 1 + SHL V0 + SHL V0 + IFDEF SUPER + SHL V0 + ENDIF + LD I, SPRITES + ADD I, V0 + DRW V8, V9, SPRITEHIGH + LD VE, VF + RET + +; COPYMAZE +; -> Nothing +; <- Nothing +; <> V0, V1, V2, V3, VE, VF, I + +COPYMAZE: LD VE, 0 +COPYLOOP: LD I, MAZE + ADD I, VE + ADD I, VE + ADD I, VE + ADD I, VE + LD V3, [I] + LD I, BUFFER + ADD I, VE + ADD I, VE + ADD I, VE + ADD I, VE + LD [I], V3 + ADD VE, 1 + SE VE, MAZEEND - MAZE \ 4 + JP COPYLOOP + RET + +; DRAWMAZE +; -> Nothing +; <- Nothing +; <> V0, V1, V2, V3, VE, VF, I + +DRAWMAZE: XOR V2, V2 + XOR V3, V3 + LD VE, 15 +DRAWLOOP: LD V0, V2 + LD V1, V3 + CALL GRAPHMAZE + AND V0, VE + SHL V0 + IFDEF SUPER + SHL V0 + ENDIF + LD I, GRAPHS + ADD I, V0 + DRW V2, V3, SPRITEJUMP + ADD V2, SPRITEJUMP + SE V2, SCREENWIDE + JP DRAWLOOP + XOR V2, V2 + ADD V3, SPRITEJUMP + SNE V3, SCREENHIGH + RET + JP DRAWLOOP + +; SPRITMAZE, GRAPHMAZE +; -> V0: X coordinate +; -> V1: Y coordinate +; <- V0: Maze data byte +; <- I: Maze data pointer +; <> V0, V1, VF, I + +SPRITMAZE: ADD V0, SPRITEJUMP + ADD V1, SPRITEJUMP +GRAPHMAZE: SHR V0 + IFDEF SUPER + SHR V0 + ENDIF + SHR V1 + IFDEF SUPER + SHR V1 + ENDIF + SHL V1 + SHL V1 + SHL V1 + SHL V1 + LD I, BUFFER + ADD I, V1 + ADD I, V1 + ADD I, V0 + LD V0, [I] + RET + +; NEXTLEVEL +; -> Nothing +; <- Nothing +; <> V0, VF, I + +NEXTLEVEL: LD I, LEVEL + LD V0, [I] + SHR V0 + LD [I], V0 + LD V0, LEVELKEY +LOOPLEVEL: SKNP V0 + JP LOOPLEVEL + RET + +; PRINTDEC +; -> V6: Print X coordinate +; -> V7: Print Y coordinate +; -> I: 16 bit value pointer +; <- Nothing +; <> V0, V1, V2, V3, V4, V5, V6, V7, VE, VF, I + +PRINTDEC: LD V1, [I] + LD VE, 1 + XOR V4, V4 + LD V2, V0 + LD V3, V1 +LOOPTENG: LD V5, 10000 % 256 + SUB V3, V5 + SNE VF, 0 + SUB V2, VE + SNE VF, 0 + JP SKIPTENG + LD V5, 10000 \ 256 + SUB V2, V5 + SNE VF, 0 + JP SKIPTENG + LD V0, V2 + LD V1, V3 + ADD V4, VE + JP LOOPTENG +SKIPTENG: IFDEF SUPER + LD HF, V4 + DRW V6, V7, 10 + ELSE + LD F, V4 + DRW V6, V7, 5 + ENDIF + ADD V6, SPRITEWIDE - SPRITEJUMP + XOR V4, V4 + LD V2, V0 + LD V3, V1 +LOOPTHOUS: LD V5, 1000 % 256 + SUB V3, V5 + SNE VF, 0 + SUB V2, VE + SNE VF, 0 + JP SKIPTHOUS + LD V5, 1000 \ 256 + SUB V2, V5 + SNE VF, 0 + JP SKIPTHOUS + LD V0, V2 + LD V1, V3 + ADD V4, VE + JP LOOPTHOUS +SKIPTHOUS: IFDEF SUPER + LD HF, V4 + DRW V6, V7, 10 + ELSE + LD F, V4 + DRW V6, V7, 5 + ENDIF + ADD V6, SPRITEWIDE - SPRITEJUMP + XOR V4, V4 + LD V2, V0 + LD V3, V1 +LOOPHUNDR: LD V5, 100 + SUB V3, V5 + SNE VF, 0 + SUB V2, VE + SNE VF, 0 + JP SKIPHUNDR + LD V0, V2 + LD V1, V3 + ADD V4, VE + JP LOOPHUNDR +SKIPHUNDR: IFDEF SUPER + LD HF, V4 + DRW V6, V7, 10 + ELSE + LD F, V4 + DRW V6, V7, 5 + ENDIF + ADD V6, SPRITEWIDE - SPRITEJUMP + XOR V4, V4 + LD V2, V0 + LD V3, V1 +LOOPTEN: LD V5, 10 + SUB V3, V5 + SNE VF, 0 + JP SKIPTEN + LD V1, V3 + ADD V4, VE + JP LOOPTEN +SKIPTEN: IFDEF SUPER + LD HF, V4 + DRW V6, V7, 10 + ELSE + LD F, V4 + DRW V6, V7, 5 + ENDIF + ADD V6, SPRITEWIDE - SPRITEJUMP + IFDEF SUPER + LD HF, V1 + DRW V6, V7, 10 + ELSE + LD F, V1 + DRW V6, V7, 5 + ENDIF + RET + +; ADDSCORE +; -> VE: Score count to add +; <- Nothing +; <> V0, V1, VE, VF, I + +ADDSCORE: LD I, SCORE + LD V1, [I] + ADD V1, VE + SE VF, 0 + ADD V0, 1 + LD I, SCORE + LD [I], V1 + RET + +; NEWHIGH +; -> Nothing +; <- Nothing +; <> V0, V1, V2, V3, VE, VF, I + +NEWHIGH: LD I, SCORE + LD V3, [I] + LD VE, V0 + SUB VE, V2 + SNE VF, 0 + RET + SE VE, 0 + JP STOREHIGH + LD VE, V1 + SUB VE, V3 + SNE VF, 0 + RET +STOREHIGH: LD I, HIGHSCORE + LD [I], V1 + RET + +; WAITKEY +; -> V0: Waitcount +; <- VE: Keypressed +; <> V0, V1, V2, V3, VE, VF + +WAITKEY: XOR VE, VE + LD V2, PRESSKEY + LD V3, -1 & MASKBYTE + LD V1, 16 +LOOPKEY: SKNP V2 + JP HITKEY + ADD V1, V3 + SE V1, 0 + JP LOOPKEY + LD V1, 16 + ADD V0, V3 + SE V0, 0 + JP LOOPKEY + RET +HITKEY: LD VE, 1 + RET + +SCORE DW 0 +HIGHSCORE: DW 0 + +LEVEL: DB STARTLEVEL + + ALIGN OFF + USED ON + +SPRITES = ? + + IFDEF SUPER + + UP: DB $........ + DB $..1...1. + DB $.11...11 + DB $.11...11 + DB $.111.111 + DB $.1111111 + DB $..11111. + DB $...111.. + + DB $........ + DB $...111.. + DB $...1111. + DB $.1.111.1 + DB $.1.111.1 + DB $.11.1111 + DB $..11111. + DB $...111.. + + LEFT: DB $........ + DB $..1111.. + DB $.111111. + DB $....1111 + DB $.....111 + DB $....1111 + DB $.111111. + DB $..1111.. + + DB $........ + DB $...111.. + DB $..1..11. + DB $.1111111 + DB $.1111111 + DB $.1111.11 + DB $.....11. + DB $...111.. + + RIGHT: DB $........ + DB $...1111. + DB $..111111 + DB $.1111... + DB $.111.... + DB $.1111... + DB $..111111 + DB $...1111. + + DB $........ + DB $...111.. + DB $..11..1. + DB $.1111111 + DB $.1111111 + DB $.11.1111 + DB $..11.... + DB $...111.. + + DOWN: DB $........ + DB $...111.. + DB $..11111. + DB $.1111111 + DB $.111.111 + DB $.11...11 + DB $.11...11 + DB $..1...1. + + DB $........ + DB $...111.. + DB $..11111. + DB $.11.1111 + DB $.1.111.1 + DB $.1.111.1 + DB $...1111. + DB $...111.. + + GHOST: DB $........ + DB $...111.. + DB $..11111. + DB $.1..1..1 + DB $.111.111 + DB $.1111111 + DB $.11...11 + DB $.1111111 + + PILL: DB $........ + DB $........ + DB $........ + DB $........ + DB $....1... + DB $........ + DB $........ + DB $........ + + SUPER: DB $........ + DB $........ + DB $........ + DB $........ + DB $....1... + DB $....1... + DB $........ + DB $........ + + ELSE + + UP: DB $........ + DB $.1.1.... + DB $.111.... + DB $..1..... + + DB $........ + DB $.1.1.... + DB $.111.... + DB $..1..... + + LEFT: DB $........ + DB $.11..... + DB $..11.... + DB $.11..... + + DB $........ + DB $.11..... + DB $..11.... + DB $.11..... + + RIGHT: DB $........ + DB $..11.... + DB $.11..... + DB $..11.... + + DB $........ + DB $..11.... + DB $.11..... + DB $..11.... + + DOWN: DB $........ + DB $..1..... + DB $.111.... + DB $.1.1.... + + DB $........ + DB $..1..... + DB $.111.... + DB $.1.1.... + + GHOST: DB $........ + DB $..1..... + DB $.111.... + DB $.111.... + + PILL: DB $........ + DB $........ + DB $..1..... + DB $........ + + SUPER: DB $........ + DB $........ + DB $........ + DB $........ + + ENDIF + +GRAPHS = ? + +; $0000 Trail up +; $0001 Trail left +; $0010 Trail right +; $0011 Trail down +; $0100 Empty space +; $0101 Ordinary pill +; $0110 Super pill +; $0111 Gateway +; $1000 Horisontal egde +; $1001 Invisible horisontal edge +; $1010 Vertical edge +; $1011 Invisible vertical edge +; $1100 Upper left corner +; $1101 Upper right corner +; $1110 Lower left corner +; $1111 Lower right corner + +GRAPHEDGE = $1000 +GRAPHSPEC = $0111 +ES = $0100 +PL = $0101 +SP = $0110 +GW = $0111 +LR = $1000 +ILR = $1001 +UD = $1010 +IUD = $1011 +UL = $1100 +UR = $1101 +DL = $1110 +DR = $1111 +MU = $00010000 +MR = $00100000 +MUR = $00110000 +MD = $01000000 +MDU = $01010000 +MDR = $01100000 +MDUR = $01110000 +ML = $10000000 +MUL = $10010000 +MRL = $10100000 +MURL = $10110000 +MDL = $11000000 +MDUL = $11010000 +MDRL = $11100000 +MDURL = $11110000 + + IFDEF SUPER + + DB $........ + DB $........ + DB $........ + DB $........ + + DB $........ + DB $........ + DB $........ + DB $........ + + DB $........ + DB $........ + DB $........ + DB $........ + + DB $........ + DB $........ + DB $........ + DB $........ + + EMPTY: DB $........ + DB $........ + DB $........ + DB $........ + + PILLGR: DB $1....... + DB $........ + DB $........ + DB $........ + + SUPERGR: DB $1....... + DB $1....... + DB $........ + DB $........ + + GATEGR: DB $........ + DB $........ + DB $........ + DB $........ + + HORIS: DB $1111.... + DB $........ + DB $........ + DB $........ + + INVHORIS: DB $........ + DB $........ + DB $........ + DB $........ + + VERT: DB $1....... + DB $1....... + DB $1....... + DB $1....... + + INVVERT: DB $........ + DB $........ + DB $........ + DB $........ + + UPLEFT: DB $1111.... + DB $1....... + DB $1....... + DB $1....... + + UPRIGHT: DB $1....... + DB $1....... + DB $1....... + DB $1....... + + DOWNLEFT: DB $1111.... + DB $........ + DB $........ + DB $........ + + DOWNRIGHT: DB $1....... + DB $........ + DB $........ + DB $........ + + ELSE + + DB $........ + DB $........ + + DB $........ + DB $........ + + DB $........ + DB $........ + + DB $........ + DB $........ + + EMPTY: DB $........ + DB $........ + + PILLGR: DB $1....... + DB $........ + + SUPERGR: DB $........ + DB $........ + + GATEGR: DB $........ + DB $........ + + HORIS: DB $11...... + DB $........ + + INVHORIS: DB $........ + DB $........ + + VERT: DB $1....... + DB $1....... + + INVVERT: DB $........ + DB $........ + + UPLEFT: DB $11...... + DB $1....... + + UPRIGHT: DB $1....... + DB $1....... + + DOWNLEFT: DB $11...... + DB $........ + + DOWNRIGHT: DB $1....... + DB $........ + + ENDIF + +MAZE = ? + + XREF OFF + +; ################################################################## +; #------------------------------- ------------------------------- # +; #| | | O | # +; #| ? . . . . ? . . ? . . . . ? | | ? . . . . ? . . ? . . .OOO? | # +; #| | | OOO | # +; #| . ------- . --- . ------- . --- . ------- . --- . ------- . | # +; #| | | | | | | | | | # +; #| . | ? x . ? | | ? . . ? | ? . . ? | ? . . ? | | ? . x ? | . | # +; #| | | | | | | | | | # +; #| . | . --------------- . ----------- . --------------- . | . | # +; #| | | | # +; #| ? . ? . . . . ? | ? . ? . ? . . ? . ? . ? | ? . . . . ? . ? | # +; #| | | | # +; #| . ----------- . | . ----- . --- . ----- . | . ----------- . | # +; #| | | | O | | | | # +; #| . | ? . . ? | ? ? ? | ? .O?O. . ? . ? | ? ? ? | ? . . ? | . | # +; # | | O O | | # +; #+ ? . ? --- . --- . --- . ----------- . --- . --- . --- ? . ? + # +; # | | # +; #| . | ? . . ? . . ? . . ? ----- ----- ? . . ? . . ? . . ? | . | # +; #| | | | | | # +; #| . ------- . --------- ? . ? | | ? . ? --------- . ------- . | # +; #| | | | | | | | | | # +; #| ? . x ? | . ------------- . --- . ------------- . | ? x . ? | # +; #| | | | # +; #| . --- . | ? . . . . ? . . ? . . ? . . ? . . . . ? | . --- . | # +; #| | | | | | | | # +; #| . --- . ----------- . --- . --- . --- . ----------- . --- . | # +; #| O | | | | | # +; #| ?OOO. ? . . . . . . ? | | ? . . ? | | ? . . . . . . ? . . ? | # +; #| OOO | | | | | # +; #------------------------- ----------- ------------------------- # +; # # +; ################################################################## + + DB UL, LR, LR, LR, LR, LR, LR, LR + DB LR, LR, LR, LR, LR, LR, LR, UR + DB UL, LR, LR, LR, LR, LR, LR, LR + DB LR, LR, LR, LR, LR, LR, LR, UR + + DB UD, MDR | PL, PL, PL, PL, PL, MDRL | PL, PL + DB PL, MDRL | PL, PL, PL, PL, PL, MDL | PL, UD + DB UD, MDR | PL, PL, PL, PL, PL, MDRL | PL, PL + DB PL, MDRL | PL, PL, PL, PL, PL, MDL | PL, UD + + DB UD, PL, UL, LR, LR, DR, PL, UL + DB UR, PL, LR, LR, LR, UR, PL, DL + DB DR, PL, UL, LR, LR, DR, PL, UL + DB UR, PL, LR, LR, LR, UR, PL, UD + + DB UD, PL, UD, MDR | PL, SP, PL, MUL | PL, UD + DB UD, MUR | PL, PL, PL, MDL | PL, UD + DB MUR | PL, PL, PL, MUL | PL + DB UD, MDR | PL, PL, PL, MUL | PL, UD + DB UD, MUR | PL, PL, SP, MDL | PL, UD, PL, UD + + DB UD, PL, DR, PL, LR, LR, LR, LR + DB LR, UL, LR, DR, PL, LR, LR, LR + DB LR, LR, DR, PL, LR, LR, UL, LR + DB LR, LR, LR, DR, PL, DR, PL, UD + + DB UD, MDUR | PL, PL, MURL | PL, PL, PL, PL, PL + DB MDL | PL, UD, MDR | PL, PL, MURL | PL, PL, + DB MDRL | PL, PL, PL, MDRL | PL + DB PL, MURL | PL, PL, MDL | PL, UD, MDR | PL + DB PL, PL, PL, PL, MURL | PL, PL, MDUL | PL, UD + + DB UD, PL, UL, LR, LR, LR, LR, UR + DB PL, DR, PL, UL, LR, DR, PL, LR + DB DR, PL, LR, LR, UR, PL, DR, PL + DB UL, LR, LR, LR, LR, UR, PL, UD + + DB DR, PL, DR, MDR | PL, PL, PL, MDL | PL, UD + DB MUR | PL, MDRL | PL, MUL | PL, UD, MDR | PL + DB PL, MURL, PL, PL, MURL | PL, PL + DB MDL | PL, UD, MUR | PL, MDRL | PL, MUL | PL + DB UD, MDR | PL, PL, PL, MDL | PL, DR, PL, DR + + DB GW, MDUR | ES, PL, MDUL | PL, LR, DR, PL, DL + DB DR, PL, LR, DR, PL, UL, LR, LR + DB LR, LR, UR, PL, LR, DR, PL, LR + DB DR, PL, LR, DR, MDUR | PL, PL, MDUL | ES, GW + + DB UD, PL, UD, MUR | PL, PL, PL, MDURL | PL, PL + DB PL, MURL | PL, PL, PL, MDUL | PL, LR, LR, UR + DB UL, LR, DR, MDUR | PL, PL, PL, MURL | PL, PL + DB PL, MDURL | PL, PL, PL, MUL | PL, UD, PL, UD + + DB UD, PL, LR, LR, LR, UR, PL, UL + DB LR, LR, LR, UR, MUR | PL, PL, MDL | PL, UD + DB UD, MDR | PL, PL, MUL | PL, UL, LR, LR, LR + DB UR, PL, UL, LR, LR, DR, PL, UD + + DB UD, MDUR | PL, PL, SP, MDL | PL, UD, PL, LR + DB LR, LR, LR, LR, LR, DR, PL, LR + DB DR, PL, LR, LR, LR, LR, LR, LR + DB DR, PL, UD, MDR | PL, SP, PL, MDUL | PL, UD + + DB UD, PL, UL, UR, PL, UD, MUR | PL, PL + DB PL, PL, PL, MDRL | PL, PL, PL, MDURL | PL, PL + DB PL, MDURL | PL, PL, PL, MDRL | PL, PL, PL, PL + DB PL, MUL | PL, UD, PL, UL, UR, PL, UD + + DB UD, PL, LR, DR, PL, LR, LR, LR + DB LR, LR, DR, PL, UL, UR, PL, LR + DB DR, PL, UL, UR, PL, LR, LR, LR + DB LR, LR, DR, PL, LR, DR, PL, UD + + DB UD, MUR | PL, PL, PL, MURL | PL, PL, PL, PL + DB PL, PL, PL, MUL | PL, UD, UD, MUR | PL, PL + DB PL, MUL | PL, UD, UD, MUR | PL, PL, PL, PL + DB PL, PL, PL, MURL | PL, PL, PL, MUL | PL, UD + + DB LR, LR, LR, LR, LR, LR, LR, LR + DB LR, LR, LR, LR, DR, LR, LR, LR + DB LR, LR, DR, LR, LR, LR, LR, LR + DB LR, LR, LR, LR, LR, LR, LR, DR + + XREF ON + +MAZEEND = ? + +EYES = ? + + IFDEF SUPER + + EYELEFT: DW $.......1111..... + DW $......1....1.... + DW $.....1..11..1... + DW $....1..1111..1.. + DW $....1.111111.1.. + DW $....1.111.11.1.. + DW $....1..1111..1.1 + DW $.....1..11..1..1 + DW $......1....1..11 + DW $.......1111..111 + DW $.............111 + DW $.......11.....11 + DW $......111111.... + DW $.......111111111 + DW $........11111111 + DW $..........111111 + + EYERIGHT: DW $....1111........ + DW $...1....1....... + DW $..1..11..1...... + DW $.1..1111..1..... + DW $.1.111111.1..... + DW $.1.111.11.1..... + DW $.1..1111..1..... + DW $..1..11..1...... + DW $1..1....1....... + DW $11..1111........ + DW $11.............. + DW $1.....11........ + DW $...111111....... + DW $11111111........ + DW $1111111......... + DW $11111........... + + EYEBLINK: DW $....1111........ + DW $...111111....... + DW $..11111111...... + DW $.1111111111..... + DW $.1111111111..... + DW $.1.11111111..... + DW $.1...111111..... + DW $..1.....11...... + DW $1..1....1....... + DW $11..1111........ + DW $11......1....... + DW $1.....1111...... + DW $...111111....... + DW $11111111........ + DW $1111111......... + DW $11111........... + + ELSE + + EYELEFT: DB $..1111.. + DB $.1....1. + DB $1..11..1 + DB $1..11..1 + DB $.1....1. + DB $..1111.. + DB $.......1 + DB $...1.... + DB $....1111 + + EYERIGHT: DB $.1111... + DB $1....1.. + DB $..11..1. + DB $..11..1. + DB $1....1.. + DB $.1111... + DB $........ + DB $...1.... + DB $111..... + + EYEBLINK: DB $.1111... + DB $111111.. + DB $1111111. + DB $1111111. + DB $1....1.. + DB $.1111... + DB $........ + DB $...1.... + DB $111..... + + ENDIF + + USED OFF + ALIGN ON + +BUFFER = ? diff --git a/roms/BLINKY.ch8 b/roms/BLINKY.ch8 Binary files differ. diff --git a/roms/BLITZ.ch8 b/roms/BLITZ.ch8 Binary files differ. diff --git a/roms/BREAKOUT.SRC b/roms/BREAKOUT.SRC @@ -0,0 +1,256 @@ +; This variant of BRIX, calles BREAKOUT, has larger bricks, +; making a wall like the BREAKOUT game on the Atari 2600. +; The only difference with brix is the brick sprite. +; +; Note: source of BRIX has been modified by David WINTER on 17 SEP 1997 +; (only the syntax changed: it has been converted in CHIPPER) +; +; The source could be optimized to save some bytes, but I didn't wanted +; to modify it since there is no specific interest in this. +; +; NOTE THAT THE ORIGINAL SOURCE HAD SEVERAL ERRORS !!! +; +; ------------------------------------------------------ +; +; Author: vervalin@AUSTIN.LOCKHEED.COM (Paul Vervalin) +; +; register contents +; ------------------------------------------------------ +; V0 scratch +; V1 scratch +; V2 scratch +; V3 X coordinate of score +; V4 Y coordinate of score +; V5 bricks hit counter +; V6 ball X coordinate +; V7 ball Y coordinate +; V8 ball X direction +; V9 ball Y direction +; VA X coordinate when generating bricks +; VB Y coordinate when generating bricks +; VC paddle X coordinate +; VD paddle Y coordinate +; VE ball counter +; VF collision detect + +option binary ; If you compile for HP48 use, remove this line + + + + LD VE, 5 ; Set number of balls to 5 + LD V5, 0 ; Initial number of hit bricks is 0 + LD VB, 6 ; Set Y position of first brick to draw + +Draw_Bricks: + LD VA, 0 ; Set X position of first brick to draw + +Draw_Brick_Row: + LD I, Brick ; I points on the brick sprite + DRW VA, VB, 1 ; Draw brick + ADD VA, 4 ; Move along X to next brick location + SE VA, 64 ; If location wrapped goto next row + JP Draw_Brick_Row ; Otherwise draw another + + ADD VB, 2 ; Move down Y to next row + SE VB, #12 ; If all rows drawn, continue on + + JP Draw_Bricks ; Otherwise draw next row + + LD VC, 32 ; Set X location of paddle + LD VD, 31 ; Set Y location of paddle + LD I, Paddle ; Get address of paddle sprite + DRW VC, VD, 1 ; Draw paddle + + CALL Draw_Score ; Call subroutine to draw score + + LD V0, 0 ; Set X coord of balls remaining + LD V1, 0 ; Set Y coord of balls remaining + LD I, Balls ; I points on balls sprite + DRW V0, V1, 1 ; Draw 4 of the five balls + ADD V0, 8 ; Set X location of the 5th ball sprite + LD I, Ball ; I points on ball sprite + DRW V0, V1, 1 ; Draw 5th ball + +Play: + LD V0, #40 ; Set V0 for delay + LD DT, V0 ; Set delay timer +Wait: + LD V0, DT ; Check status of delay timer + SE V0, 0 ; Skip next if delay timer is 0 + JP Wait ; Check again + + RND V6, #0F ; Get random coord for ball start + LD V7, 30 ; Set Y coord of ball start + LD V8, 1 ; Set X direction to RIGHT + LD V9, #FF ; Set Y direction to UP + + LD I, Ball ; I points on single ball sprite + DRW V6, V7, 1 ; Draw ball + +Loop: + LD I, Paddle ; Get address of paddle sprite + DRW VC, VD, 1 ; Draw paddle at loc. VC VD + + LD V0, 04 ; Set V0 to key 4 + SKNP V0 ; Skip next if key V0 not pressed + ADD VC, #FE ; Move paddle two pixels left + + LD V0, 06 ; Set V0 to key 6 + SKNP V0 ; Skip next if key V0 not pressed + ADD VC, 2 ; Move paddle two pixels right + + LD V0, #3F ; Set V0 right edge of screen + AND VC, V0 ; Wrap paddle around if needed + DRW VC, VD, 1 ; Draw paddle + + LD I, Ball ; Get address of ball sprite + DRW V6, V7, 1 ; Draw ball + ADD V6, V8 ; Move ball in X direction by V8 + ADD V7, V9 ; Move ball in Y direction by V9 + + LD V0, 63 ; Set highest X coord. + AND V6, V0 ; AND ball X pos. with V0 + + LD V1, 31 ; Set highest Y coord + AND V7, V1 ; AND ball Y pos. with V1 + + SNE V7, 31 ; If ball not at bottom, skip + JP Bottom ; Else check for paddle pos + + +Check_Paddle: + SNE V6, 0 ; If ball not at left side, skip + LD V8, 1 ; Set X direction to RIGHT + + SNE V6, 63 ; If ball not at right side, skip + LD V8, #FF ; Set X direction to LEFT + + SNE V7, 0 ; If ball not at top, skip + LD V9, 1 ; Set Y direction to DOWN + + DRW V6, V7, 1 ; Draw ball + SE VF, 1 ; If there was a collision, skip + JP Brick_Untouched + + SNE V7, 31 ; If ball not at bottom skip + JP Brick_Untouched + + LD V0, 5 ; Set V0 for 5 lines at screen top + SUB V0, V7 ; Check if ball was in this region + SE VF, 0 ; If it was not then skip + JP Brick_Untouched + + LD V0, 1 ; There was a collision + LD ST, V0 ; So beep + + LD V0, V6 ; Get X coord of ball + LD V1, #FC ; Compute postion of the brick + AND V0, V1 ; which was hit + + LD I, Brick ; I points on brick sprite + DRW V0, V7, 1 ; Erase brick sprite by drawing + LD V0, #FE ; reverse the Y direction of the + XOR V9, V0 ; ball sprite + + CALL Draw_Score ; Call subroutine to draw score + ADD V5, 1 ; Increments bricks hit counter by one + CALL Draw_Score ; Call subroutine to draw score + + SNE V5, 96 ; If all bricks have not been hit, skip + JP Over ; Else game ends, so stop + + +Brick_Untouched: + JP Loop + +Bottom: + LD V9, #FF ; Ball is at bottom, so set direction to UP + LD V0, V6 ; Get X location of ball + SUB V0, VC ; Intersect with paddle + SE VF, 1 ; If intersect then skip + JP Ball_Lost + + LD V1, 2 ; + SUB V0, V1 ; This portion calculates + SE VF, 1 ; the direction where the + JP Go_Left ; ball will bounce, + SUB V0, V1 ; depending on the position + SE VF, 1 ; of the ball on the paddle, + JP Paddle_Beep ; and the direction it had + SUB V0, V1 ; before hiting the paddle. + SE VF, 1 ; + JP Go_Right ; + + +Ball_Lost: + LD V0, 32 ; Set beep delay + LD ST, V0 ; Beep for lost ball + + LD I, Ball ; I points on ball sprite + ADD VE, #FF ; Remove 1 from balls counter + LD V0, VE ; Set V0 to ball counter + + ADD V0, V0 ; Compute location of ball to erase + LD V1, 0 ; Set Y location of top line + DRW V0, V1, 1 ; Erase ball from remaining + SE VE, 0 ; If no balls remain, skip + JP Play ; Prepare for a new ball to play + + +Over: + JP Over + + +Go_Left: + ADD V8, #FF ; Make ball go LEFT + SNE V8, #FE ; If ball was not going left, skip + LD V8, #FF ; Make it go LEFT by 1 not 2 + JP Paddle_Beep + + +Go_Right: + ADD V8, 1 ; Make ball go right + SNE V8, 2 ; If ball was not going right, skip + LD V8,1 ; Make it go RIGHT by 1 not 2 + + +Paddle_Beep: + LD V0, 4 ; Set beep time for paddle hit + LD ST, V0 ; Turn on beeper + LD V9, #FF ; Set ball direction to UP + JP Check_Paddle ; Then, continue playing and check for paddle move + + +Draw_Score: + LD I, Score ; Set address to BCD score location + LD B, V5 ; Store BCD of score + LD V2, [I] ; Read BCD of score in V0...V2 + LD F, V1 ; Get font for tens value from V1 + LD V3, 55 ; Set X location of score tens place + LD V4, 0 ; Set Y location of score + DRW V3, V4, 5 ; Draw tens place score # + ADD V3, 5 ; Set X location of score ones place + LD F, V2 ; Get font for ones value from V2 + DRW V3, V4, 5 ; Draw ones place score # + RET ; Return + + +Brick: + DW #F000 ; Brick sprite + + +Ball: + DW #8000 ; Ball sprite + + +Paddle: + DW #FC00 ; Paddle sprite + + +Balls: + DW #AA00 ; Balls remaining sprite + + +Score: + DW #0000 ; Score storage + DW #0000 ; diff --git a/roms/BREAKOUT.ch8 b/roms/BREAKOUT.ch8 Binary files differ. diff --git a/roms/BRIX.SRC b/roms/BRIX.SRC @@ -0,0 +1,252 @@ +; Note: this source has been modified by David WINTER on 17 SEP 1997 +; (only the syntax changed: it has been converted in CHIPPER) +; +; The source could be optimized to save some bytes, but I didn't wanted +; to modify it since there is no specific interest in this. +; +; NOTE THAT THE ORIGINAL SOURCE HAD SEVERAL ERRORS !!! +; +; ------------------------------------------------------ +; +; Author: vervalin@AUSTIN.LOCKHEED.COM (Paul Vervalin) +; +; register contents +; ------------------------------------------------------ +; V0 scratch +; V1 scratch +; V2 scratch +; V3 X coordinate of score +; V4 Y coordinate of score +; V5 bricks hit counter +; V6 ball X coordinate +; V7 ball Y coordinate +; V8 ball X direction +; V9 ball Y direction +; VA X coordinate when generating bricks +; VB Y coordinate when generating bricks +; VC paddle X coordinate +; VD paddle Y coordinate +; VE ball counter +; VF collision detect + +option binary ; If you compile for HP48 use, remove this line + + + + LD VE, 5 ; Set number of balls to 5 + LD V5, 0 ; Initial number of hit bricks is 0 + LD VB, 6 ; Set Y position of first brick to draw + +Draw_Bricks: + LD VA, 0 ; Set X position of first brick to draw + +Draw_Brick_Row: + LD I, Brick ; I points on the brick sprite + DRW VA, VB, 1 ; Draw brick + ADD VA, 4 ; Move along X to next brick location + SE VA, 64 ; If location wrapped goto next row + JP Draw_Brick_Row ; Otherwise draw another + + ADD VB, 2 ; Move down Y to next row + SE VB, #12 ; If all rows drawn, continue on + + JP Draw_Bricks ; Otherwise draw next row + + LD VC, 32 ; Set X location of paddle + LD VD, 31 ; Set Y location of paddle + LD I, Paddle ; Get address of paddle sprite + DRW VC, VD, 1 ; Draw paddle + + CALL Draw_Score ; Call subroutine to draw score + + LD V0, 0 ; Set X coord of balls remaining + LD V1, 0 ; Set Y coord of balls remaining + LD I, Balls ; I points on balls sprite + DRW V0, V1, 1 ; Draw 4 of the five balls + ADD V0, 8 ; Set X location of the 5th ball sprite + LD I, Ball ; I points on ball sprite + DRW V0, V1, 1 ; Draw 5th ball + +Play: + LD V0, #40 ; Set V0 for delay + LD DT, V0 ; Set delay timer +Wait: + LD V0, DT ; Check status of delay timer + SE V0, 0 ; Skip next if delay timer is 0 + JP Wait ; Check again + + RND V6, #0F ; Get random coord for ball start + LD V7, 30 ; Set Y coord of ball start + LD V8, 1 ; Set X direction to RIGHT + LD V9, #FF ; Set Y direction to UP + + LD I, Ball ; I points on single ball sprite + DRW V6, V7, 1 ; Draw ball + +Loop: + LD I, Paddle ; Get address of paddle sprite + DRW VC, VD, 1 ; Draw paddle at loc. VC VD + + LD V0, 04 ; Set V0 to key 4 + SKNP V0 ; Skip next if key V0 not pressed + ADD VC, #FE ; Move paddle two pixels left + + LD V0, 06 ; Set V0 to key 6 + SKNP V0 ; Skip next if key V0 not pressed + ADD VC, 2 ; Move paddle two pixels right + + LD V0, #3F ; Set V0 right edge of screen + AND VC, V0 ; Wrap paddle around if needed + DRW VC, VD, 1 ; Draw paddle + + LD I, Ball ; Get address of ball sprite + DRW V6, V7, 1 ; Draw ball + ADD V6, V8 ; Move ball in X direction by V8 + ADD V7, V9 ; Move ball in Y direction by V9 + + LD V0, 63 ; Set highest X coord. + AND V6, V0 ; AND ball X pos. with V0 + + LD V1, 31 ; Set highest Y coord + AND V7, V1 ; AND ball Y pos. with V1 + + SNE V7, 31 ; If ball not at bottom, skip + JP Bottom ; Else check for paddle pos + + +Check_Paddle: + SNE V6, 0 ; If ball not at left side, skip + LD V8, 1 ; Set X direction to RIGHT + + SNE V6, 63 ; If ball not at right side, skip + LD V8, #FF ; Set X direction to LEFT + + SNE V7, 0 ; If ball not at top, skip + LD V9, 1 ; Set Y direction to DOWN + + DRW V6, V7, 1 ; Draw ball + SE VF, 1 ; If there was a collision, skip + JP Brick_Untouched + + SNE V7, 31 ; If ball not at bottom skip + JP Brick_Untouched + + LD V0, 5 ; Set V0 for 5 lines at screen top + SUB V0, V7 ; Check if ball was in this region + SE VF, 0 ; If it was not then skip + JP Brick_Untouched + + LD V0, 1 ; There was a collision + LD ST, V0 ; So beep + + LD V0, V6 ; Get X coord of ball + LD V1, #FC ; Compute postion of the brick + AND V0, V1 ; which was hit + + LD I, Brick ; I points on brick sprite + DRW V0, V7, 1 ; Erase brick sprite by drawing + LD V0, #FE ; reverse the Y direction of the + XOR V9, V0 ; ball sprite + + CALL Draw_Score ; Call subroutine to draw score + ADD V5, 1 ; Increments bricks hit counter by one + CALL Draw_Score ; Call subroutine to draw score + + SNE V5, 96 ; If all bricks have not been hit, skip + JP Over ; Else game ends, so stop + + +Brick_Untouched: + JP Loop + +Bottom: + LD V9, #FF ; Ball is at bottom, so set direction to UP + LD V0, V6 ; Get X location of ball + SUB V0, VC ; Intersect with paddle + SE VF, 1 ; If intersect then skip + JP Ball_Lost + + LD V1, 2 ; + SUB V0, V1 ; This portion calculates + SE VF, 1 ; the direction where the + JP Go_Left ; ball will bounce, + SUB V0, V1 ; depending on the position + SE VF, 1 ; of the ball on the paddle, + JP Paddle_Beep ; and the direction it had + SUB V0, V1 ; before hiting the paddle. + SE VF, 1 ; + JP Go_Right ; + + +Ball_Lost: + LD V0, 32 ; Set beep delay + LD ST, V0 ; Beep for lost ball + + LD I, Ball ; I points on ball sprite + ADD VE, #FF ; Remove 1 from balls counter + LD V0, VE ; Set V0 to ball counter + + ADD V0, V0 ; Compute location of ball to erase + LD V1, 0 ; Set Y location of top line + DRW V0, V1, 1 ; Erase ball from remaining + SE VE, 0 ; If no balls remain, skip + JP Play ; Prepare for a new ball to play + + +Over: + JP Over + + +Go_Left: + ADD V8, #FF ; Make ball go LEFT + SNE V8, #FE ; If ball was not going left, skip + LD V8, #FF ; Make it go LEFT by 1 not 2 + JP Paddle_Beep + + +Go_Right: + ADD V8, 1 ; Make ball go right + SNE V8, 2 ; If ball was not going right, skip + LD V8,1 ; Make it go RIGHT by 1 not 2 + + +Paddle_Beep: + LD V0, 4 ; Set beep time for paddle hit + LD ST, V0 ; Turn on beeper + LD V9, #FF ; Set ball direction to UP + JP Check_Paddle ; Then, continue playing and check for paddle move + + +Draw_Score: + LD I, Score ; Set address to BCD score location + LD B, V5 ; Store BCD of score + LD V2, [I] ; Read BCD of score in V0...V2 + LD F, V1 ; Get font for tens value from V1 + LD V3, 55 ; Set X location of score tens place + LD V4, 0 ; Set Y location of score + DRW V3, V4, 5 ; Draw tens place score # + ADD V3, 5 ; Set X location of score ones place + LD F, V2 ; Get font for ones value from V2 + DRW V3, V4, 5 ; Draw ones place score # + RET ; Return + + +Brick: + DW #E000 ; Brick sprite + + +Ball: + DW #8000 ; Ball sprite + + +Paddle: + DW #FC00 ; Paddle sprite + + +Balls: + DW #AA00 ; Balls remaining sprite + + +Score: + DW #0000 ; Score storage + DW #0000 ; diff --git a/roms/BRIX.ch8 b/roms/BRIX.ch8 Binary files differ. diff --git a/roms/CAVE.ch8 b/roms/CAVE.ch8 Binary files differ. diff --git a/roms/CONNECT4.ch8 b/roms/CONNECT4.ch8 Binary files differ. diff --git a/roms/FIGURES.ch8 b/roms/FIGURES.ch8 Binary files differ. diff --git a/roms/FILTER.ch8 b/roms/FILTER.ch8 Binary files differ. diff --git a/roms/GUESS.ch8 b/roms/GUESS.ch8 Binary files differ. diff --git a/roms/HIDDEN.ch8 b/roms/HIDDEN.ch8 Binary files differ. diff --git a/roms/HIDDEN.txt b/roms/HIDDEN.txt @@ -0,0 +1,28 @@ + ---------------------------------------- + HIDDEN! + Copyright (1996) by David WINTER + ---------------------------------------- + + +HIDDEN is a "memory" game. It is very simple to play. + +The rules are as follow: your goal is to find all the identical cards +in a minimum time. + +You are playing in a 4*4 card grid. You can see only two cards at the +same time. Once this time passed, these two cards will remain shown +if they are identical, otherwise they will be hidden again. + +When the game is finished, two scores are shown: + SC is your score, corresponding to the number of tries + HI is the best score (smallest number of tries made to finish) + +The keys are: + + [2] : More DOWN + [4] : Move LEFT + [5] : Show card + [6] : Move RIGHT + [8] : Move UP + +Enjoy !!! diff --git a/roms/INVADERS.ch8 b/roms/INVADERS.ch8 Binary files differ. diff --git a/roms/JOUST.txt b/roms/JOUST.txt @@ -0,0 +1,83 @@ +Joust 1.0, a CHIP48 game by Zoom: + + Hoorah! Hoorah! Here it is, the latest CHIP48 game; my rendition +of the arcade game Joust. Both ->ASC and UUENCODE versions are attached. + +You can get ASC-> (an HP48sx program by Bill Wickes) by anonymous ftp +at seq.uncwil.edu (Wayne Scott's Mailserver archive, +path: hp48/util/ascii.encode.Z (set ftp to binary, use UNCOMPRESS in UNIX). + +A PC based version of UUDECODE is available on the HPBBS in the +user.programs conference. + +CHIP48v2.25 and documentation is available at seq.uncwil.edu +path: hp48/chip8/chip-48.Z (binary) + +The Game: + + 1) Download the file and use ASC-> on the string. + 2) The result of step 1 is taken as an argument by + CHIP, this runs the game. + 3) Check out the title screen then press 0 to play. + 4) The keys are: + + 0 = Down + 9 = Left + / = Right + + 5) The blank dots in the bottom left corner indicate + the number of players left, not including the current + player. Sorry, no bonus guys. Maybe in the future. + + 6) At the score screen press 0 to replay, else press drop + to exit to the stack. + + +If you feel the game is slow, then wait until you get to level 7! +The levels roll over at #Fh, I think. I haven't gotten that far! +Therefore there maybe unseen bugs. + +The game is novel. I'm not sure of its lasting qualities. +However, it was a good exercise in CHIP programming. Which +reminds me: + + - I claim no rights, its just a game. Anyway, what could I do? + Send the cops after you? On the other hand, please send me + email for comments, questions, bugs. On bugs, try to give + plenty of detail. Debugging these games is a nightmare, but + its a challenge I enjoy (contradiction?). + + my email address: catto@ecn.purdue.edu + + You can post on comp.sys.handhelds, but I only view once or + twice a week. + +CREDITS: + + 1) Andreas Gustafsson for his excellent interpreter, CHIP48v2.25. + 2) Gilles Kohl for his AS48 CHIP assembler. + +I haven't tried to run Joust on SuperCHIP. If I have enough energy I +will convert Joust to take advantage of the extended graphics. + +On Source Code: + +I will eventually post source code in AS48, soon if requested. I will +archive it at seq.uncwil.edu and the HPBBS along with Joust. + +However, I am more interested in posting some CHIP48 programming notes +to generate more interest in actually writing these games. This is the +fifth game posted since CHIP's release, how many assemblers? Assemblers +are great and Joust wouldn't have been possible without one, but I think +people must have difficulty programming in CHIP48 (it wasn't a cinch for +me). Sooooo, I will try to help with some programming notes. + + Enjoy! + + Zoom-> + +The real question: Should I by a Smith Corona card? + + +Joust string: Bytes: 1426 + Checksum: #87F2h diff --git a/roms/KALEID.ch8 b/roms/KALEID.ch8 Binary files differ. diff --git a/roms/LANDING.ch8 b/roms/LANDING.ch8 Binary files differ. diff --git a/roms/MAZE.SRC b/roms/MAZE.SRC @@ -0,0 +1,72 @@ +OPTION BINARY ; We want a binary file, not an HP48 one. +ALIGN OFF ; And we don't want auto alignement, as some + ; data can be made of bytes instead of words. + + +; Drawing a random maze like this one consists in drawing random diagonal +; lines. There are two possibilities: right-to-left line, and left-to-right +; line. Each line is composed of a 4*4 bitmap. As the lines must form non- +; circular angles, the two bitmaps won't be '/' and '\'. The first one +; (right line) will be a little bit modified. See at the end of this source. +; +; The maze is composed of 8 lines (as the bitmaps are 4 pixels high), each +; line consists of 16 bitmaps. +; Bitmaps are drawn in random mode. We choose a random value (0 or 1). +; If it is 1, we draw a left line bitmap. If it is 0, we draw a right one. + + +; Rsgister usage: +; +; V0: X-coordinate of the bitmap +; V1: Y-coordinate of the bitmap +; V2: Random number + + LD V0, 0 + LD V1, 0 + +LOOP: + LD I, LEFT ; We draw a left line by default, as the random number + ; is 0 or 1. If we suppose that it will be 1, we keep + ; drawing the left line. If it is 0, we change register + ; I to draw a right line. + + RND V2, 1 ; Load in V2 a 0...1 random number + + SE V2, 1 ; It is 1 ? If yes, I still refers to the left line + ; bitmap. + + LD I, RIGHT ; If not, we change I to make it refer the right line + ; bitmap. + + DRW V0, V1, 4 ; And we draw the bitmap at V0, V1. + + ADD V0, 4 ; The next bitmap is 4 pixels right. So we update + ; V0 to do so. + + SE V0, 64 ; If V0==64, we finished drawing a complete line, so we + ; skip the jump to LOOP, as we have to update V1 too. + + JP LOOP ; We did not draw a complete line ? So we continue ! + + LD V0, 0 ; The first bitmap of each line is located 0, V1. + + ADD V1, 4 ; We update V1. The next line is located 4 pixels doan. + + SE V1, 32 ; Have we drawn all the lines ? If yes, V1==32. + JP LOOP ; No ? So we continue ! + +FIN: JP FIN ; Infinite loop... + +RIGHT: ; 4*4 bitmap of the left line + + DB $1....... + DB $.1...... + DB $..1..... + DB $...1.... + +LEFT: ; 4*4 bitmap of the right line + ; And YES, it is like that... + DB $..1..... + DB $.1...... + DB $1....... + DB $...1.... diff --git a/roms/MAZE.ch8 b/roms/MAZE.ch8 Binary files differ. diff --git a/roms/MERLIN.ch8 b/roms/MERLIN.ch8 Binary files differ. diff --git a/roms/MISSILE.ch8 b/roms/MISSILE.ch8 Binary files differ. diff --git a/roms/PADDLES.ch8 b/roms/PADDLES.ch8 Binary files differ. diff --git a/roms/PONG(1P).ch8 b/roms/PONG(1P).ch8 Binary files differ. diff --git a/roms/PONG.SRC b/roms/PONG.SRC @@ -0,0 +1,237 @@ +; Note: this source has been modified by David WINTER on 17 SEP 1997 +; (only the syntax changed: it has been converted in CHIPPER) +; +; The source could be optimized to save some bytes, but I didn't wanted +; to modify it since there is no specific interest in this. +; +; NOTE THAT THE ORIGINAL SOURCE HAD SEVERAL ERRORS !!! +; +; --------------------------------------------------------------------------- +; +; From: vervalin@AUSTIN.LOCKHEED.COM (Paul Vervalin) +; +; +; OK folks here it is! PONG for the HP48SX written in CHIP-48. +; Some things you should know before you start playing are... +; 1) This is my first attempt at programming in CHIP-48, so I +; know there are probably a few things that could have been +; done better. +; 2) The game never ends. It keeps score, but only up to 9 for +; each player, then it will roll over to 0. Sorry, its the +; only way I could think of to do it. So, you have to play +; whoever gets to a number first, wins. +; 3) It is kind of slow, but then there are two paddles and ball +; moving around all at once. +; 4) The player who got the last point gets the serve... +; 5) Keys 7 and 4 (on the HP48) control the up and down of the +; left player and the / and * keys control the up and down of +; the right player. +; +; I think that's about it, so have fun! +; +; This is a detailed breakdown of the game, sooooooo, if anybody wants to +; make it better, or change it in some way, it might be a little easier. +; Also, about half of the code was in some way extracted from the BRIX +; program. So, thanks to whoever wrote the original BRIX game. +; +; +; Registers +; --------- +; V0-V3 are scratch registers +; V4 X coord. of score +; V5 Y coord. of score +; V6 X coord. of ball +; V7 Y coord. of ball +; V8 X direction of ball motion +; V9 Y direction of ball motion +; VA X coord. of left player paddle +; VB Y coord. of left player paddle +; VC X coord. of right player paddle +; VD Y coord. of right player paddle +; VE Score +; VF collision detection + + +option binary ; To assemble PONG for HP48 use, remove this option + + + LD VA, 2 ; Set left player X coord. + LD VB, 12 ; Set left player Y coord. + LD VC, 63 ; Set right player X coord. + LD VD, 12 ; Set right player Y coord. + + LD I, Paddle ; Get address of paddle sprite + DRW VA, VB, 6 ; Draw left paddle + DRW VC, VD, 6 ; Draw right paddle + + LD VE, 0 ; Set score to 00 + CALL Draw_Score ; Draw score + + LD V6, 3 ; Set X coord. of ball to 3 + LD V8, 2 ; Set ball X direction to right + + +Big_Loop: + + LD V0, #60 ; Set V0=delay before ball launch + LD DT, V0 ; Set delay timer to V0 +DT_loop: ; + LD V0, DT ; Read delay timer into V0 + SE V0, 0 ; Skip next instruction if V0=0 + JP DT_Loop ; Read again delay timer if not 0 + + RND V7, 23 ; Set Y coord. to rand # AND 23 (0...23) + ADD V7, 8 ; And adjust it to is 8...31 + + LD V9, #FF ; Set ball Y direction to up + LD I, Ball ; Get address of ball sprite + DRW V6, V7, 1 ; Draw ball + +Padl_Loop: + LD I, Paddle ; Get address of paddle sprite + DRW VA, VB, 6 ; Draw left paddle + DRW VC, VD, 6 ; Draw right paddle + + LD V0, 1 ; Set V0 to KEY 1 + SKNP V0 ; Skip next instruction if KEY in 1 is not pressed + ADD VB, #FE ; Subtract 2 from Y coord. of left paddle + + LD V0, 4 ; Set V0 to KEY 4 + SKNP V0 ; Skip next instruction if KEY in 4 is not pressed + ADD VB, 2 ; Add 2 to Y coord. of left paddle + + LD V0, 31 ; Set V0 to max Y coord. | These three lines are here to + AND VB, V0 ; AND VB with V0 | adjust the paddle position if + DRW VA, VB, 6 ; Draw left paddle | it is out of the screen + + LD V0, #0C ; Set V0 to KEY C + SKNP V0 ; Skip next instruction if KEY in C is not pressed + ADD VD, #FE ; Subtract 2 from Y coord. of right paddle + + LD V0, #0D ; Set V0 to KEY D + SKNP V0 ; Skip next instruction if KEY in D is not pressed + ADD VD, 2 ; Add 2 to Y coord. of right paddle + + LD V0, 31 ; Set V0 to max Y coord. | These three lines are here to + AND VD, V0 ; AND VD with V0 | adjust the paddle position if + DRW VC, VD, 6 ; Draw right paddle | it is out of the screen + + LD I, Ball ; Get address of ball sprite + DRW V6, V7, 1 ; Draw ball + + ADD V6, V8 ; Compute next X coord of the ball + ADD V7, V9 ; Compute next Y coord of the ball + + LD V0, 63 ; Set V0 to max X location + AND V6, V0 ; AND V6 with V0 + + LD V1, 31 ; Set V1 to max Y location + AND V7, V1 ; AND V7 with V1 + + SNE V6, 2 ; Skip next instruction if ball not at left + JP Left_Side ; + + SNE V6, 63 ; Skip next instruction if ball not at right + JP Right_Side ; + +Ball_Loop: + SNE V7, 31 ; Skip next instruction if ball not at bottom + LD V9, #FF ; Set Y direction to up + + SNE V7, 0 ; Skip next instruction if ball not at top + LD V9, 1 ; Set Y direction to down + + DRW V6, V7, 1 ; Draw ball + JP Padl_loop ; + +Left_Side: + LD V8, 2 ; Set X direction to right + LD V3, 1 ; Set V3 to 1 in case left player misses ball + LD V0, V7 ; Set V0 to V7 Y coord. of ball + SUB V0, VB ; Subtract position of paddle from ball + JP Pad_Coll ; Check for collision + +Right_Side: + LD V8, 254 ; Set X direction to left + LD V3, 10 ; Set V3 to 10 in case right player misses ball + LD V0, V7 ; Set V0 to V7 Y coord. of ball + SUB V0, VD ; Subtract position of paddle from ball + +Pad_Coll: + SE VF, 1 ; Skip next instruction if ball not above paddle + JP Ball_Lost ; + + LD V1, 2 ; Set V1 to 02 + SUB V0, V1 ; Subtract V1 from V0 + SE VF, 1 ; Skip next instr. if ball not at top of paddle + JP Ball_Top ; Ball at top of paddle + + SUB V0, V1 ; Subtract another 2 from V0 + SE VF, 1 ; Skip next instr. if ball not at middle of paddle + JP Pad_Hit ; Ball in middle of paddle + + SUB V0, V1 ; Subtract another 2 from V0 + SE VF, 1 ; Skip next instr. if ball not at bottom of paddle + JP Ball_Bot ; Ball at bottom of paddle + +Ball_Lost: + LD V0, 32 ; Set lost ball beep delay + LD ST, V0 ; Beep for lost ball + + CALL Draw_Score ; Erase previous score + ADD VE, V3 ; Add 1 or 10 to score depending on V3 + CALL Draw_Score ; Write new score + + LD V6, 62 ; Set ball X coord. to right side + SE V3, 1 ; Skip next instr. if right player got point + LD V6, 3 ; Set ball X coord. to left side + LD V8, #FE ; Set direction to left + SE V3, 1 ; Skip next instr. if right player got point + LD V8, 2 ; Set direction to right + JP Big_Loop ; + +Ball_Top: + ADD V9, #FF ; Subtract 1 from V9, ball Y direction + SNE V9, #FE ; Skip next instr. if V9 != FE (-2) + LD V9, #FF ; Set V9=FF (-1) + JP Pad_Hit + +Ball_Bot: + ADD V9, 1 ; Add 1 to V9, ball Y direction + SNE V9, 2 ; Skip next instr. if V9 != 02 + LD V9, 1 ; Set V9=01 + +Pad_Hit: + LD V0, 4 ; Set beep for paddle hit + LD ST, V0 ; Sound beep + + ADD V6, 1 ; + SNE V6, 64 ; + ADD V6, 254 ; + + JP Ball_Loop + +Draw_Score: + LD I, Score ; Get address of Score + LD B, VE ; Stores in memory BCD representation of VE + LD V2, [I] ; Reads V0...V2 in memory, so the score + LD F, V1 ; I points to hex char in V1, so the 1st score char + LD V4, #14 ; Set V4 to the X coord. to draw 1st score char + LD V5, 0 ; Set V5 to the Y coord. to draw 1st score char + DRW V4, V5, 5 ; Draw 8*5 sprite at (V4,V5) from M[I], so char V1 + ADD V4, #15 ; Set X to the X coord. of 2nd score char + LD F, V2 ; I points to hex char in V2, so 2nd score char + DRW V4, V5, 5 ; Draw 8*5 sprite at (V4,V5) from M[I], so char V2 + RET ; Return + +Paddle: + DW #8080 + DW #8080 + DW #8080 + +Ball: + DW #8000 + +Score: + DW #0000 + DW #0000 diff --git a/roms/PONG.ch8 b/roms/PONG.ch8 Binary files differ. diff --git a/roms/PONG2.SRC b/roms/PONG2.SRC @@ -0,0 +1,277 @@ +; Note: this source has been modified by David WINTER on 17 SEP 1997 +; (only the syntax changed: it has been converted in CHIPPER) +; +; 99% of this source is taken from Paul Vervalin's PONG game. The only +; changes are the position of the left paddle, and the vertical line on +; the middle of the screen. This, to have a correct game under the MS-DOS +; CHIP-8 emulator. Note that the modifications are quite archaic, as they +; were hand-made (i.e: no assembler/disassembler). +; +; --------------------------------------------------------------------------- +; +; From: vervalin@AUSTIN.LOCKHEED.COM (Paul Vervalin) +; +; +; OK folks here it is! PONG for the HP48SX written in CHIP-48. +; Some things you should know before you start playing are... +; 1) This is my first attempt at programming in CHIP-48, so I +; know there are probably a few things that could have been +; done better. +; 2) The game never ends. It keeps score, but only up to 9 for +; each player, then it will roll over to 0. Sorry, its the +; only way I could think of to do it. So, you have to play +; whoever gets to a number first, wins. +; 3) It is kind of slow, but then there are two paddles and ball +; moving around all at once. +; 4) The player who got the last point gets the serve... +; 5) Keys 7 and 4 (on the HP48) control the up and down of the +; left player and the / and * keys control the up and down of +; the right player. +; +; I think that's about it, so have fun! +; +; This is a detailed breakdown of the game, sooooooo, if anybody wants to +; make it better, or change it in some way, it might be a little easier. +; Also, about half of the code was in some way extracted from the BRIX +; program. So, thanks to whoever wrote the original BRIX game. +; +; +; Registers +; --------- +; V0-V3 are scratch registers +; V4 X coord. of score +; V5 Y coord. of score +; V6 X coord. of ball +; V7 Y coord. of ball +; V8 X direction of ball motion +; V9 Y direction of ball motion +; VA X coord. of left player paddle +; VB Y coord. of left player paddle +; VC X coord. of right player paddle +; VD Y coord. of right player paddle +; VE Score +; VF collision detection + + +option binary ; To assemble PONG for HP48 use, remove this option + + + CALL Middle ; Draws the vertical bar at center + + LD VB, 12 ; Set left player Y coord. + LD VC, 63 ; Set right player X coord. + LD VD, 12 ; Set right player Y coord. + + LD I, Paddle ; Get address of paddle sprite + DRW VA, VB, 6 ; Draw left paddle + DRW VC, VD, 6 ; Draw right paddle + + LD VE, 0 ; Set score to 00 + CALL Draw_Score ; Draw score + + LD V6, 3 ; Set X coord. of ball to 3 + LD V8, 2 ; Set ball X direction to right + + +Big_Loop: + + LD V0, #60 ; Set V0=delay before ball launch + LD DT, V0 ; Set delay timer to V0 +DT_loop: ; + LD V0, DT ; Read delay timer into V0 + SE V0, 0 ; Skip next instruction if V0=0 + JP DT_Loop ; Read again delay timer if not 0 + + RND V7, 23 ; Set Y coord. to rand # AND 23 (0...23) + ADD V7, 8 ; And adjust it to is 8...31 + + LD V9, #FF ; Set ball Y direction to up + LD I, Ball ; Get address of ball sprite + DRW V6, V7, 1 ; Draw ball + +Padl_Loop: + LD I, Paddle ; Get address of paddle sprite + DRW VA, VB, 6 ; Draw left paddle + DRW VC, VD, 6 ; Draw right paddle + + LD V0, 1 ; Set V0 to KEY 1 + SKNP V0 ; Skip next instruction if KEY in 1 is not pressed + ADD VB, #FE ; Subtract 2 from Y coord. of left paddle + + LD V0, 4 ; Set V0 to KEY 4 + SKNP V0 ; Skip next instruction if KEY in 4 is not pressed + ADD VB, 2 ; Add 2 to Y coord. of left paddle + + LD V0, 31 ; Set V0 to max Y coord. | These three lines are here to + AND VB, V0 ; AND VB with V0 | adjust the paddle position if + DRW VA, VB, 6 ; Draw left paddle | it is out of the screen + + LD V0, #0C ; Set V0 to KEY C + SKNP V0 ; Skip next instruction if KEY in C is not pressed + ADD VD, #FE ; Subtract 2 from Y coord. of right paddle + + LD V0, #0D ; Set V0 to KEY D + SKNP V0 ; Skip next instruction if KEY in D is not pressed + ADD VD, 2 ; Add 2 to Y coord. of right paddle + + LD V0, 31 ; Set V0 to max Y coord. | These three lines are here to + AND VD, V0 ; AND VD with V0 | adjust the paddle position if + DRW VC, VD, 6 ; Draw right paddle | it is out of the screen + + LD I, Ball ; Get address of ball sprite + DRW V6, V7, 1 ; Draw ball + + ADD V6, V8 ; Compute next X coord of the ball + ADD V7, V9 ; Compute next Y coord of the ball + + LD V0, 63 ; Set V0 to max X location + AND V6, V0 ; AND V6 with V0 + + LD V1, 31 ; Set V1 to max Y location + AND V7, V1 ; AND V7 with V1 + + SNE V6, 0 ; Skip next instruction if ball not at left + JP Left_Side ; + + SNE V6, 63 ; Skip next instruction if ball not at right + JP Right_Side ; + +Ball_Loop: + SNE V7, 31 ; Skip next instruction if ball not at bottom + LD V9, #FF ; Set Y direction to up + + SNE V7, 0 ; Skip next instruction if ball not at top + LD V9, 1 ; Set Y direction to down + + DRW V6, V7, 1 ; Draw ball + JP Padl_loop ; + +Left_Side: + LD V8, 2 ; Set X direction to right + LD V3, 1 ; Set V3 to 1 in case left player misses ball + LD V0, V7 ; Set V0 to V7 Y coord. of ball + SUB V0, VB ; Subtract position of paddle from ball + JP Pad_Coll ; Check for collision + +Right_Side: + LD V8, 254 ; Set X direction to left + LD V3, 10 ; Set V3 to 10 in case right player misses ball + LD V0, V7 ; Set V0 to V7 Y coord. of ball + SUB V0, VD ; Subtract position of paddle from ball + +Pad_Coll: + SE VF, 1 ; Skip next instruction if ball not above paddle + JP Ball_Lost ; + + LD V1, 2 ; Set V1 to 02 + SUB V0, V1 ; Subtract V1 from V0 + SE VF, 1 ; Skip next instr. if ball not at top of paddle + JP Ball_Top ; Ball at top of paddle + + SUB V0, V1 ; Subtract another 2 from V0 + SE VF, 1 ; Skip next instr. if ball not at middle of paddle + JP Pad_Hit ; Ball in middle of paddle + + SUB V0, V1 ; Subtract another 2 from V0 + SE VF, 1 ; Skip next instr. if ball not at bottom of paddle + JP Ball_Bot ; Ball at bottom of paddle + +Ball_Lost: + LD V0, 32 ; Set lost ball beep delay + LD ST, V0 ; Beep for lost ball + + CALL Draw_Score ; Erase previous score + ADD VE, V3 ; Add 1 or 10 to score depending on V3 + CALL Draw_Score ; Write new score + + LD V6, 62 ; Set ball X coord. to right side + SE V3, 1 ; Skip next instr. if right player got point + LD V6, 3 ; Set ball X coord. to left side + LD V8, #FE ; Set direction to left + SE V3, 1 ; Skip next instr. if right player got point + LD V8, 2 ; Set direction to right + JP Big_Loop ; + +Ball_Top: + ADD V9, #FF ; Subtract 1 from V9, ball Y direction + SNE V9, #FE ; Skip next instr. if V9 != FE (-2) + LD V9, #FF ; Set V9=FF (-1) + JP Pad_Hit + +Ball_Bot: + ADD V9, 1 ; Add 1 to V9, ball Y direction + SNE V9, 2 ; Skip next instr. if V9 != 02 + LD V9, 1 ; Set V9=01 + +Pad_Hit: + LD V0, 4 ; Set beep for paddle hit + LD ST, V0 ; Sound beep + + ADD V6, 1 ; + SNE V6, 64 ; + ADD V6, 254 ; + + JP Ball_Loop + +Draw_Score: + LD I, Score ; Get address of Score + LD B, VE ; Stores in memory BCD representation of VE + LD V2, [I] ; Reads V0...V2 in memory, so the score + LD F, V1 ; I points to hex char in V1, so the 1st score char + LD V4, #14 ; Set V4 to the X coord. to draw 1st score char + LD V5, 2 ; Set V5 to the Y coord. to draw 1st score char + DRW V4, V5, 5 ; Draw 8*5 sprite at (V4,V5) from M[I], so char V1 + ADD V4, #15 ; Set X to the X coord. of 2nd score char + LD F, V2 ; I points to hex char in V2, so 2nd score char + DRW V4, V5, 5 ; Draw 8*5 sprite at (V4,V5) from M[I], so char V2 + RET ; Return + +Paddle: + DW #8080 + DW #8080 + DW #8080 + +Ball: + DW #8000 + +Score: + DW #0000 + DW #0000 + +MiddleLine: + DW #C0C0 + DW #C000 + +HorizLine: + DB #FF + +Middle: + LD VB, 32 ; Set X coord. of middle line pixels + LD VC, 0 ; Set Y coord. of the first sprite to draw + LD I, MiddleLine ; I Points to the bitmap of the 6 pixels to draw + +Draw_Middle: + DRW VB, VC, 4 ; Draw 4 pixels of the line + ADD VC, 4 ; Increments Y of the next 4 pixels sprite + SE VC, 32 ; End loop if last pixels drawn + JP Draw_Middle ; Else draw next pixels + + LD VA, 0 ; Set VA to X location of horizontal lines + LD VB, 0 ; Set VB to Y location of upper horizontal line + LD VC, 31 ; Set VC to Y location of downer horizontal line + LD I, HorizLine ; I points on the bitmap of these lines... + +Draw_Horiz: + DRW VA, VB, 1 ; Draw 8 pixels of the first horizontal line + DRW VA, VC, 1 ; Draw 8 pixels of the second horizontal line + ADD VA, 8 ; Increments Y of the next 8 pixels sprites + SE VA, 64 ; End loop if last pixels drawn + JP Draw_Horiz ; Else draw next pixels of the lines + + LD I, MiddleLine ; I point again on the middle line sprite + LD VA, 0 ; Set player A (left side) X coord. + LD VB, 32 ; Set VB to first 2*1 sprite location of vertical line + DRW VB, VA, 1 ; Redraw this part which wad erased before... + + RET ; Return to program start + ; VA must be set to 0, this has already been done. diff --git a/roms/PONG2.ch8 b/roms/PONG2.ch8 Binary files differ. diff --git a/roms/PUZZLE.ch8 b/roms/PUZZLE.ch8 Binary files differ. diff --git a/roms/ROCKET.ch8 b/roms/ROCKET.ch8 Binary files differ. diff --git a/roms/SOCCER.ch8 b/roms/SOCCER.ch8 Binary files differ. diff --git a/roms/SPACEF.ch8 b/roms/SPACEF.ch8 Binary files differ. diff --git a/roms/SQUASH.ch8 b/roms/SQUASH.ch8 Binary files differ. diff --git a/roms/SYZYGY.SRC b/roms/SYZYGY.SRC @@ -0,0 +1,808 @@ +option binary ; Let's compile this for a non-HP computer... +align off ; And let's save some space with even-addresses allowed + +; From rtrevino@cpocd5.intel.com +; +; Several people have requested the source to syzygy, so here it is. +; Actually it's the listing file. It would have been posted sooner, +; but I wanted to add *some* comments at least, etc. Hopefully whoever +; sent mail to me will see it. Anyways, I guess we can all expect to +; see tons more chip-48 programs posted now, as there is so much interest +; in source code! :-) They are actually quite easy to write. +; +; Roy +; +; PS - has anyone used the shift instructions in chip48? The documentation +; does not correlate with the "opcodes". How do they really work? + + ; + ; SYZYGY is (c) copyright 1990 by Roy Trevino (RTT) + ; + ; Noncommercial distribution allowed, provided that this + ; copyright message is preserved, and any modified versions + ; are clearly marked as such. + ; + ; SYZYGY, via CHIP-48, makes use of undocumented low-level features + ; of the HP48SX calculator, and may or may not cause loss of data, + ; excessive battery drainage, and/or damage to the calculator + ; hardware. The Author takes no responsibility whatsoever for + ; any damage caused by the use of this program. + ; + ; THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + ; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + ; PURPOSE. + ; + ; + ; Register usage (primary usage, may be others): + ; + ; v0 - scratch + ; v1 - x position of head + ; v2 - y position of head + ; v3 - current direction of head + ; v4 - pointer to segment table entry for head + ; v5 - previous direction of head + ; v6 - x position of tail + ; v7 - y position of tail + ; v8 - direction of tail + ; v9 - pointer to segment table entry for tail + ; va - count of points being added to length + ; vb - x position of target + ; vc - y position of target + ; vd - flags if target is on or off + ; ve - random on time for target + ; vf - carry/borrow/collision detect + + +up = #3 ; (9) key for up +down = #6 ; (6) key for down +left = #7 ; (1) key for left +right = #8 ; (2) key for right + + ; + ; Start of a circular table to track each segment of the syzygy, + ; which consists of a direction and a length. + ; + ; The start of the table is at #800 instead of a label at the bottom + ; of the program (ie. base: end) because it seems to run faster + ; that way. + ; + +base = #800 ; base of segment table + + + jp start + + ; copyright notice + dw #8d8d ; ->-> + dw #20a9 ; (c) + dw #3139 ; 19 + dw #3930 ; 90 + dw #2052 ; R + dw #5454 ; TT + dw #208e ; <- + dw #8e00 ; <- +start: + call drawbord + call drawtitle +waitkp1: + ld v0,#f ; wait for (+) (keep border) + sknp v0 + jp starty + ld v0,#e ; wait for (-) (borderless) + sknp v0 + jp startn + jp waitkp1 +starty: + call drawtitle ; erase title (keep border) + jp initgame +startn: + cls ; erase everything (borderless) + jp initgame + ; + ; initialization routines + ; +initgame: + ; + ; initial head position near middle of screen + ; + rnd v1,#1f ; x-pos = rnd(16,47) + add v1,#10 + rnd v2,#f ; y-pos = rnd(8,23) + add v2,#8 + rnd v3,#3 ; direction = rnd(0,3) + ld v5,v3 ; last head direction + ; + ; compute initial tail position + ; + ld v6,v1 ; start out same as head + ld v7,v2 + ld v8,v3 ; tail direction + + sne v8,#0 ; up + add v7,#1 + sne v8,#1 ; down + add v7,#ff + sne v8,#2 ; left + add v6,#1 + sne v8,#3 ; right + add v6,#ff + ; + ; draw initial syzygy, save initial segment to table + ; + ld i,dot + drw v1,v2,#1 ; draw head + drw v6,v7,#1 ; draw tail + + ld v4,#f0 ; init ptr to head vector + ld v9,#f1 ; init ptr to tail vector + + ld i,base ; save direction + add i,v4 + ld v0,v3 + ld [i],v0 + add v4,#1 ; increment head ptr + ld i,base ; save segment count + add i,v4 + ld v0,#1 + ld [i],v0 + + ; + ; compute coordinates and value of first target + ; plus set up flag and time until target + ; + call rndtarg + + + ld va,#0 ; additional length + + ; + ; initial addition to syzygy for test purposes + ; + add va,#0 + ; + ; main loop begins here + ; +loop: + ld v0,dt ; check if a target is due + se v0,#0 + jp endtarg + se vd,#0 + jp targoff + + ld v0,#0 ; draw target + ld f,v0 + drw vb,vc,#5 + + se vf,#1 ; if on body, erase immediately + jp targon + drw vb,vc,#5 + call rndtarg ; set up new target + ld dt,v0 ; no delay though + jp endtarg ; process at least one move + +targon: + ld dt,ve ; set up on-time + ld vd,#1 ; set flag to denote on + ld ve,#0 ; number of points unless hit + jp endtarg + +targoff: + ld v0,ve ; erase old target + ld f,v0 + drw vb,vc,#5 + + call rndtarg ; set up new target + +endtarg: + ld v0,up ; check for user input + sknp v0 + ld v3,#0 ; new direction + + ld v0,down + sknp v0 + ld v3,#1 + + ld v0,left + sknp v0 + ld v3,#2 + + ld v0,right + sknp v0 + ld v3,#3 + ; + ; compute next head position + ; + sne v3,#0 ; up + add v2,#ff + sne v3,#1 ; down + add v2,#1 + sne v3,#2 ; left + add v1,#ff + sne v3,#3 ; right + add v1,#1 + ; + ; draw next head position + ; + ld i,dot + drw v1,v2,#1 + ; + ; check for collision + ; + se vf,#1 + jp chkhead + ; + ; if collision is due to target, add points (else die) + ; this also means no doubling back on self + ; + se vd,#1 ; check if target is even on + jp endgame + + ld v0,#3f ; mask off extra x and y bits + and v1,v0 + ld v0,#1f + and v2,v0 + + ld v0,vb ; check if < target on left + subn v0,v1 + se vf,#1 + jp endgame + + ld v0,vb ; check if > target on right + add v0,#3 + sub v0,v1 + se vf,#1 + jp endgame + + ld v0,vc ; check if < target on top + subn v0,v2 + se vf,#1 + jp endgame + + ld v0,vc ; check if > target on bottom + add v0,#4 + sub v0,v2 + se vf,#1 + jp endgame + ; + ; if made it this far, add points, erase target, etc + ; + ld v0,#4 ; beep (actually, a "bip") + ld st,v0 + + rnd ve,#7 ; award rnd(2,9) points + add ve,#2 ; + add va,ve ; add points + + ld i,dot ; temporarily erase head + drw v1,v2,#1 + ld v0,#0 ; erase target + ld f,v0 + drw vb,vc,#5 + ld v0,ve ; draw points instead + ld f,v0 + drw vb,vc,#5 + + ld v0,#30 ; delay for a while + ld dt,v0 +targwait: + ld v0,dt + se v0,#0 + jp targwait + + ld i,dot + drw v1,v2,#1 ; redraw head + ; + ; if direction changed, create a new segment record + ; +chkhead: + sne v3,v5 + jp conthead + + add v4,#1 ; new segment record + ld i,base + add i,v4 + ld v0,v3 ; save direction + ld [i],v0 + add v4,#1 ; point to counter + ld i,base ; initialize segment count to + add i,v4 + ld v0,#0 + ld [i],v0 + + ld v5,v3 ; reset previous direction + +conthead: + ld i,base ; simply add to current record + add i,v4 + ld v0,[i] + add v0,#1 ; increment head count + ld [i],v0 + ; + ; don't erase tail if adding points to length + ; + sne va,#0 + jp contpts ; if pts = 0, continue normally + + ld v0,#c ; delay just a little to compensate +delhead: + add v0,#ff + se v0,#0 + jp delhead + + add va,#ff ; decrement and loop + jp loop + +contpts: + ; + ; erase last tail position + ; + ld i,dot + drw v6,v7,#1 + + ; + ; compute next tail position + ; + sne v8,#0 ; up + add v7,#ff + sne v8,#1 ; down + add v7,#1 + sne v8,#2 ; left + add v6,#ff + sne v8,#3 ; right + add v6,#1 + + ld i,base ; get tail segment record + add i,v9 + ld v0,[i] + add v0,#ff ; decrement tail count + ld [i],v0 ; save + se v0,#0 ; if zero, get new record + jp loop + + add v9,#1 ; new segment record + ld i,base ; get new direction + add i,v9 + ld v0,[i] + ld v8,v0 + add v9,#1 ; point to new count + ; + ; end of main loop + ; + jp loop + ; + ; endgame routines + ; +endgame: + ld v0,#d ; beep + ld st,v0 + + ld v0,#b ; wait for (space) keypress +endkp: + skp v0 + jp endkp + ; + ; finish up tail to count points: digits are in vd:vc:vb format + ; note that it is theoretically possible to get 64*32=2048 points, + ; while three digits will only hold 999. Unlikely but possible. + ; + ld vb,#1 ; one's digit + ld vc,#0 ; ten's digit + ld vd,#0 ; hundred's digit + +endtail: + ; + ; increment score + ; + add vb,#1 + se vb,#a + jp endtailcont + ld vb,#0 + add vc,#1 + se vc,#a + jp endtailcont + ld vc,#0 + add vd,#1 + ; + ; compute next tail position to add up score + ; +endtailcont: + ld i,dot ; erase last tail position + drw v6,v7,#1 + + sne v8,#0 ; up + add v7,#ff + sne v8,#1 ; down + add v7,#1 + sne v8,#2 ; left + add v6,#ff + sne v8,#3 ; right + add v6,#1 + + ld i,base ; get tail segment record + add i,v9 + ld v0,[i] + add v0,#ff ; decrement tail count + ld [i],v0 ; save + se v0,#0 ; if zero, get new record + jp endtail + + sne v9,v4 ; done when pointers are equal + jp drawscore + + add v9,#1 ; new segment record + ld i,base ; get new direction + add i,v9 + ld v0,[i] + ld v8,v0 + add v9,#1 ; point to new count + jp endtail + ; + ; draw score + ; +drawscore: + cls + ld v6,#11 ; draw border + ld v7,#9 + ld v8,#2f + ld v9,#17 + ld i,vbar + drw v6,v7,#e + drw v8,v7,#e + add v7,#ff + ld i,hbar + drw v6,v7,#1 + drw v6,v9,#1 + add v6,#8 + drw v6,v7,#1 + drw v6,v9,#1 + add v6,#8 + drw v6,v7,#1 + drw v6,v9,#1 + add v6,#8 + ld i,hbar2 + drw v6,v7,#1 + drw v6,v9,#1 + + ld i,sc ; show score (not high score yet) + ld v6,#13 + ld v7,#11 + call showscore + ; + ; figure out if it's the high score, save it if it is + ; + ld i,high_score ; recover old high score into v3v2v1 + ld v3,[i] + + sne v3,vd ; if =, check next digit + jp conthigh1 + ld v0,v3 ; if borrow, it's a new high score! + sub v0,vd + se vf,#1 + jp savehigh + jp drawhigh + +conthigh1: + sne v2,vc ; etc. as above for other digits + jp conthigh2 + ld v0,v2 + sub v0,vc + se vf,#1 + jp savehigh + jp drawhigh + +conthigh2: + ld v0,v1 + sub v0,vb + se vf,#0 + jp drawhigh + +savehigh: + ld i,high_score + ld v3,vd ; save new high score + ld v2,vc + ld v1,vb + ld [i],v3 + ; + ; draw the high score + ; +drawhigh: + ld i,high_score + ld v3,[i] + ld v6,#13 + add v7,#f9 + ld vd,v3 + ld vc,v2 + ld vb,v1 + ld i,hi + call showscore + ; + ; random memory wasting stuff goes here + ; +waitkp2: + + rnd v1,#3f ; get random position + rnd v2,#1f + + ld v0,#d ; check left + sub v0,v1 + se vf,#0 + jp drawrand + + ld v0,#30 ; check right + subn v0,v1 + se vf,#0 + jp drawrand + + ld v0,#3 ; check top + sub v0,v2 + se vf,#0 + jp drawrand + + ld v0,#18 ; check bottom + subn v0,v2 + se vf,#0 + jp drawrand + jp chkkp2 + +drawrand: + rnd v3,#0f ; draw random number + ld f,v3 + drw v1,v2,#5 + +chkkp2: + ld v0,#f ; check for keypress + sknp v0 + jp conty + ld v0,#e + sknp v0 + jp contn + jp waitkp2 + +conty: + cls + call drawbord + jp initgame +contn: + cls + jp initgame + ; + ; function showscore: + ; digits in vd:vc:vb, descriptor in i, initial coords in v6,v7 + ; +showscore: + drw v6,v7,#5 + ld i,col + add v6,#2 + drw v6,v7,#4 + ld f,vd + add v6,#a + drw v6,v7,#5 + ld f,vc + add v6,#5 + drw v6,v7,#5 + ld f,vb + add v6,#5 + drw v6,v7,#5 + + ret + ; + ; function drawbord: + ; draw border, try to do it fast + ; +drawbord: + ld i,hbar + ld v1,#0 ; left + ld v2,#0 ; right + ld v6,#1f ; lower +horiz1: + drw v1,v2,#1 ; draw x,0 + drw v1,v6,#1 ; draw x,31 + add v1,#8 + se v1,#40 ; same as 0 + jp horiz1 + + ld i,vbar + ld v2,#1 + ld v5,#3f + drw v1,v2,#f + drw v5,v2,#f + add v2,#f + drw v1,v2,#f + drw v5,v2,#f + + ret + ; + ; function drawtitle: draws game title + ; +drawtitle: + ld v1,#c + ld v2,#7 + ld i,Title_s + drw v1,v2,#a + ld i,Title_y + add v1,#6 + drw v1,v2,#a + ld i,Title_z + add v1,#6 + drw v1,v2,#a + ld i,Title_y + add v1,#6 + drw v1,v2,#a + ld i,Title_g + add v1,#6 + drw v1,v2,#a + ld i,Title_y + add v1,#6 + drw v1,v2,#a + + ld v1,#e + ld v2,#18 + ld i,Title_v + drw v1,v2,#3 + ld i,vers + add v1,#8 + add v2,#ff + drw v1,v2,#4 + add v1,#9 + add v2,#fe + ld i,Title_r + drw v1,v2,#6 + add v1,#6 + add v2,#1 + ld i,Title_tt + drw v1,v2,#5 + + ret + ; + ; function rndtarg: + ; returns coords as (vb,vc) + ; 0 in vd + ; time until target in dt + ; on-time value ve + ; +rndtarg: + ; + ; x-pos = rnd(1,59) + ; + ld vd,#c5 ; -#3b (-59d) +rndx: rnd vb,#3f ; rnd (0,63) + ld ve,vb + add ve,vd ; check if > 58 + sne vf,#1 + jp rndx ; try again if too big + + add vb,#1 + ; + ; y-pos = rnd(1,26) + ; + + ld vd,#e6 ; -#1a (-26d) +rndy: rnd vc,#1f + ld ve,vc + add ve,vd + sne vf,#1 + jp rndy + add vc,#1 + ld vd,#0 ; flag marking new target + rnd ve,#3f ; random off delay (64 - 127) + add ve,#40 + ld dt,ve + rnd ve,#3f ; random on delay (64 - 127) + add ve,#40 + ret + +dot: dw #8000 ; dot for syzygy +hbar: dw #ff00 ; horizontal border segment +hbar2: dw #fe00 +vbar: dw #8080 ; vertical border segment + dw #8080 + dw #8080 + dw #8080 + dw #8080 + dw #8080 + dw #8080 + dw #8080 + ; + ; True memory wasting stuff goes here (but why not?) + ; +Title_s: ; s character + db $...11111 + db $...1.... + db $...1.... + db $...1.... + db $...11111 + db $.......1 + db $.......1 + db $.......1 + db $.......1 + db $...11111 + +Title_y: ; y character + db $...1...1 + db $...1...1 + db $...1...1 + db $...1...1 + db $...11111 + db $.....1.. + db $.....1.. + db $.....1.. + db $.....1.. + db $.....1.. + +Title_z: ; z character + db $...11111 + db $.......1 + db $......1. + db $......1. + db $.....1.. + db $.....1.. + db $....1... + db $....1... + db $...1.... + db $...11111 + +Title_g: ; g character + db $...11111 + db $...1...1 + db $...1.... + db $...1.... + db $...1.... + db $...1..11 + db $...1...1 + db $...1...1 + db $...1...1 + db $...11111 + +Title_v: ; v character for version + db $.....1.1 + db $.....1.1 + db $......1. + db $........ + +vers: ; version number characters + db $.111...1 + db $.1.1...1 + db $.1.1...1 + db $.111.1.1 + + +Title_r: ; R character for signature + db $....11.. + db $...1..1. + db $...1111. + db $...1.1.. + db $...1..1. + db $....1..1 + +Title_tt: ; tt characters for signature + db $...1.1.. + db $..11111. + db $...1.1.1 + db $...1.1.1 + db $..1.1.1. + db $........ + + +sc: ; sc characters for score + db $.111.111 + db $.1...1.. + db $..1..1.. + db $...1.1.. + db $.111.111 + db $........ + +hi: ; hi character for high score + db $.1.1.111 + db $.1.1..1. + db $.111..1. + db $.1.1..1. + db $.1.1.111 + db $........ + +col: dw #0001 ; : character for scores + dw #0001 + +high_score: + dw #0000 ; high score storage + dw #0000 diff --git a/roms/SYZYGY.ch8 b/roms/SYZYGY.ch8 Binary files differ. diff --git a/roms/TANK.ch8 b/roms/TANK.ch8 Binary files differ. diff --git a/roms/TETRIS.ch8 b/roms/TETRIS.ch8 Binary files differ. diff --git a/roms/TICTAC.ch8 b/roms/TICTAC.ch8 Binary files differ. diff --git a/roms/TRON.ch8 b/roms/TRON.ch8 Binary files differ. diff --git a/roms/UFO.SRC b/roms/UFO.SRC @@ -0,0 +1,124 @@ +option binary +align off + + LD I, l2CD + LD V9, #38 + LD VA, #08 + DRW V9, VA, 3 + LD I, l2D0 + LD VB, #00 + LD VC, #03 + DRW VB, VC, 3 + LD I, l2D6 + LD V4, #1D + LD V5, #1F + DRW V4, V5, 1 + LD V7, #00 + LD V8, #0F + CALL l2A2 +l21E: CALL l2AC + SNE V8, #00 +l222: JP l222 + LD V4, #1E + LD V5, #1C + LD I, l2D3 + DRW V4, V5, 3 + LD VE, #00 +l22E: LD V6, #80 + LD VD, #04 + SKNP VD + LD V6, #FF + LD VD, #05 + SKNP VD + LD V6, #00 + LD VD, #06 + SKNP VD + LD V6, #01 + SE V6, #80 + CALL l2D8 +l246: LD I, l2D0 + DRW VB, VC, 3 + RND VD, #01 + ADD VB, VD + DRW VB, VC, 3 + SE VF, #00 + JP l292 + LD I, l2CD + DRW V9, VA, 3 + RND VD, #01 + SE VD, #00 + LD VD, #FF + ADD V9, #FE + DRW V9, VA, 3 + SE VF, #00 + JP l28C + SNE VE, #00 + JP l22E + LD I, l2D3 + DRW V4, V5, 3 + SNE V5, #00 + JP l286 + ADD V5, #FF + ADD V4, V6 + DRW V4, V5, 3 + SE VF, #01 + JP l246 + LD VD, #08 + AND VD, V5 + SNE VD, #08 + JP l28C + JP l292 +l286: CALL l2AC + ADD V8, #FF + JP l21E +l28C: CALL l2A2 + ADD V7, #05 + JP l296 +l292: CALL l2A2 + ADD V7, #0F +l296: CALL l2A2 + LD VD, #03 + LD ST, VD + LD I, l2D3 + DRW V4, V5, 3 + JP l286 +l2A2: DW #A2F8 ;LD I, l2F8 as we cannot load an effective address + LD B, V7 + LD V3, #00 + CALL l2B6 + RET +l2AC: DW #A2F8 ;LD I, l2F8 as we cannot load an effective address + LD B, V8 + LD V3, #32 + CALL l2B6 + RET +l2B6: LD VD, #1B + LD V2, [I] + LD F, V0 + DRW V3, VD, 5 + ADD V3, #05 + LD F, V1 + DRW V3, VD, 5 + ADD V3, #05 + LD F, V2 + DRW V3, VD, 5 + RET + DB #01 +l2CD: DB #7C ; .11111.. + DB #FE ; 1111111. + DB #7C ; .11111.. +l2D0: + DB #60 ;.11..... + DB #F0 ;1111.... + DB #60 ;.11..... + +l2D3: DB #40 ;.1...... + DB #E0 ;111..... + DB #A0 ;1.1..... + +l2D6: DB #F8 ;11111... + DB #D4 ;11.1.1.. +l2D8: LD VE, #01 + LD VD, #10 + LD ST, VD + RET diff --git a/roms/UFO.ch8 b/roms/UFO.ch8 Binary files differ. diff --git a/roms/VBRIX.SRC b/roms/VBRIX.SRC @@ -0,0 +1,371 @@ +; **************************************************************************** +; **************************************************************************** +; *** Vertical Brix v1.0 (C) Paul Robson 1996 *** +; **************************************************************************** +; **************************************************************************** + +; **************************************************************************** +; +; r7 lives +; r8 score +; r9 bat y +; ra,rb location of ball +; rc,rd direction of ball +; re Number of brix remaining in wall +; +; **************************************************************************** + +TopLine:equ 0 ; top line of breakout +BottomLine:equ 31 ; bottom line of breakout +LeftSide:equ 0 ; left side of game area +RightSide:equ 63 ; right side of game area +BrickX:equ 34 ; brick start +BrickXCt:equ 7 ; number of bricks across , x +BrickYCt:equ 10 ; and y +BatX: equ 2 ; bat x position +Sound: equ 1 ; 1 sound,0 nosound +KeyUp: equ 1 ; up key +KeyDown:equ 4 ; down key +KeyStart:equ 7 ; start key + + cls + jsr Title +wstart: + mov v0,KeyStart ; wait for start + skpr v0 + jmp wstart + +begin: mov r8,0 ; score = 0 + mov r7,3 ; lives = 3 + jsr DrawBorder + jsr InitBat + jsr InitBall + jsr DrawBricks + jsr DrawScore + jsr DrawLives + key v0 +loop: jsr MoveBat + jsr MoveBat + jsr MoveBall + jsr Collide + skeq ra,0 + jmp loop + + mov rc,1 ; ball back out + jsr DrawLives ; dec lives + add r7,-1 + jsr DrawLives + + mov r0,120 ; wait 2 secs + sdelay r0 +wait: gdelay r0 + skeq r0,0 + jmp wait + + skeq r7,0 + jmp loop + jsr DrawLives ; erase lives,we've finished + + mov r0,KeyStart + skpr r0 + jmp .-2 + jmp begin + halt + +; **************************************************************************** +; *** initialise the bat *** +; **************************************************************************** +InitBat:mov r9,16 + mov v0,BatX + mvi BatSpr + sprite v0,v9,5 + rts +BatSpr: db $10000000 + db $10000000 + db $10000000 + db $10000000 + db $10000000 +; **************************************************************************** +; *** move the bat *** +; **************************************************************************** +MoveBat:mov r0,KeyUp + skup r0 + jmp MoveUp + mov r0,KeyDown + skup r0 + jmp MoveDown + rts + +MoveUp: mov r0,r9 ; move it up + add r0,-1 + skne r0,TopLine + rts + jmp MoveIt +MoveDown: + mov r0,r9 ; move it down + add r0,1 + skne r0,BottomLine-4 + rts + jmp MoveIt +MoveIt: mov r1,BatX ; redraw the graphic + mvi BatSpr + sprite r1,r9,5 + sprite r1,r0,5 + mov r9,r0 ; do the move + rts + +; **************************************************************************** +; *** has the bat hit the ball *** +; **************************************************************************** +Collide:mov v0,va ; va (x) must be batx + add v0,-2 + skeq v0,0 + rts + mov v0,vb ; v0 = bally-baty + sub v0,v9 + skne vf,0 ; if bally < baty exit + rts + mov v1,v0 ; if v0 >= 5 exit + mov v2,5 + sub v1,v2 + skeq vf,0 + rts + mvi dirtab ; get the new y direction + adi v0 ; out of the table + ldr v0-v0 + mov vd,v0 + + skne vb,TopLine+1 + mov vd,1 + skne vb,BottomLine-1 + mov vd,-1 + + mov rc,1 ; bounce back out + mov r0,10*sound + ssound r0 + rts +dirtab: db -1,-1,0,1,1 +; **************************************************************************** +; *** initialise the ball register *** +; **************************************************************************** +InitBall: + random vb,BottomLine-TopLine-1 + add rb,TopLine+1 + mov va,4 + mov vc,1 + mov vd,1 + mvi Pixel + sprite va,vb,1 + rts +; **************************************************************************** +; *** move the ball,bouncing off the walls *** +; *** destroys v0,v1,v2,v3,v4 *** +; **************************************************************************** +MoveBall: + mov v0,va ; save position in va,vb + mov v1,vb + add va,vc ; work out new position + add vb,vd + mvi Pixel + skne vb,TopLine+1 ; bounce off the walls + mov vd,1 + skne vb,BottomLine-1 + mov vd,-1 + skne va,RightSide-1 + mov vc,-1 + + skne va,0 ; DEBUGGING,NO LOSS OF BALL + mov vc,1 + + sprite v0,v1,1 ; Draw the ball,delete old ball + sprite va,vb,1 + skne vf,0 ; ball has hit something - stop + rts + mov v0,va ; if hit the bat,pass ! + mov v1,brickx-1 ; if < brickx forget it ! + sub v0,v1 + skne vf,0 + rts + mov v0,va ; ball position in v0,v1 + mov v1,vb + add v0,-brickx ; convert to ball coordinate + add v1,-topline-1 + mov v2,-1 ; v2,v3 will be the ball location + mov v3,-1 ; in logical coordinates. + mov v4,3 +div3x: add v2,1 ; divide v0 by 3 + sub v0,v4 + skeq vf,0 + jmp div3x +div3y: add v3,1 + sub v1,v4 + skeq vf,0 + jmp div3y + mov v0,v2 ; v0,v1 contain the ball coords (log) + mov v1,v3 + add v0,v2 ; convert them to physical coords + add r0,r2 + add v1,v3 + add v1,v3 + add v0,BrickX + add v1,TopLine+1 + mvi Brick ; erase the brick + sprite v0,v1,3 + add ve,-1 ; decrement bricks remaining counter + mov v0,0 ; bounce the ball + rsb vc,v0 ; xi = -xi + mov r0,2*sound + ssound r0 + jsr DrawScore ; increment the score + add v8,1 + jsr DrawScore + skeq ve,0 ; cleared the wall ? + rts + jsr DrawBricks ; redraw it + rts + +; **************************************************************************** +; *** Draw the border *** +; *** destroys r0,r1,r2,i *** +; **************************************************************************** +DrawBorder: + cls ; start with a clear screen + mov v0,LeftSide ; (r0,r1) and (r0,r2) are start pos + mov v1,TopLine ; of the horizontal lines + mov v2,BottomLine + mvi Pixel +DBLoop: sprite v0,v1,1 ; draw the vertical lines + sprite v0,v2,1 + add v0,1 + skeq v0,RightSide + jmp DBLoop +DBLoop2:sprite v0,v1,1 ; draw the horizontal lines + add v1,1 + skeq v1,BottomLine+1 + jmp DBLoop2 + rts +Pixel: db $10000000 ; pixel used for drawing walls. +; **************************************************************************** +; *** redraw all the bricks *** +; *** destroys r0,r1,r2,r3,i *** +; **************************************************************************** +DrawBricks: + mov v1,TopLine+1 + mov v3,BrickYCt + mvi Brick +DBXLoop:mov v0,BrickX + mov v2,BrickXCt +DBXLp2: sprite v0,v1,3 + add v0,3 + add v2,-1 + skeq v2,0 + jmp DBXLp2 + add v1,3 + add v3,-1 + skeq v3,0 + jmp DBXLoop + mov ve,BrickXCt*BrickYCt + rts +Brick: db $11100000 + db $10100000 + db $11100000 +; **************************************************************************** +; *** Draw the score (in r8) *** +; **************************************************************************** +DrawScore: + mvi Temp + bcd v8 + ldr v0-v2 + mov v3,3 + mov v4,TopLine+2 + font v0 + sprite v3,v4,5 + add v3,5 + font v1 + sprite v3,v4,5 + add v3,5 + font v2 + sprite v3,v4,5 + rts +Temp: dw 0,0,0 +; **************************************************************************** +; *** draw the number of lives *** +; **************************************************************************** +DrawLives: + mov r0,20 + mov r1,TopLine+2 + font r7 + sprite r0,r1,5 + rts +; **************************************************************************** +; *** draw the title *** +; **************************************************************************** +Title: mov r0,10 + mov r1,12 + mov r2,9 + mov r3,5 + mvi TitleSpr +TtlLoop:sprite r0,r1,5 + adi r3 + add r0,5 + add r2,-1 + skeq r2,0 + jmp TtlLoop + rts +TitleSpr: + db $10010000 + db $10010000 + db $10010000 + db $10010000 + db $01100000 + + db $11100000 + db $10010000 + db $11100000 + db $10010000 + db $11100000 + + db $11100000 + db $10010000 + db $11100000 + db $10010000 + db $10010000 + + + db $00100000 + db $00100000 + db $00100000 + db $00100000 + db $00100000 + + db $10010000 + db $10010000 + db $01100000 + db $10010000 + db $10010000 + + db $00000000 + db $00000000 + db $01100000 + db $00000000 + db $00000000 + + db $11110000 + db $10010000 + db $11110000 + db $10000000 + db $10000000 + + db $11110000 + db $10000000 + db $11110000 + db $00010000 + db $11110000 + + db $11100000 + db $10010000 + db $11100000 + db $10010000 + db $10010000 + + diff --git a/roms/VBRIX.ch8 b/roms/VBRIX.ch8 Binary files differ. diff --git a/roms/VERS.ch8 b/roms/VERS.ch8 Binary files differ. diff --git a/roms/WALL.ch8 b/roms/WALL.ch8 Binary files differ. diff --git a/roms/WIPEOFF.ch8 b/roms/WIPEOFF.ch8 Binary files differ.