Program your own assembly game on HP48
 
You may know the saturn assembly language on hp48 and you want to start a game: this page is for you!
 You will need the ADS library or Jasm and a good string editor because you will program using your hp48.
Download the source code into your hp48, then try to understand it using this documentation web page.
 
 Please, make backup of your memories on disk before programming !! 
 
Download the game and source: Arkanoid.zip
   
Here is the ADS's Jasm commented source code. Try to understand then improve it :)
If you have liked this source and if you want to program a bigger and more complete game, then just purchase the wario source.

 
 Under Construction !!
 
 
ADS's Jasm Source
Comments
GOSBVL 0679B 
INTOFF CLRST 
LC F D0= 00128 DAT0=C.P 
LC 00990 GOSBVL 05B7D AD0EX ABIT=0.0 
LC 000CC A=A+C.A R0=A 
A=R0 D0=A A=0.W LC 87 
DO { DAT0=A.W D0=D0+ 16 C--.B } WHILENC 
A=R0 D0= 00120 DAT0=A.A 
Save registers D0,D1,A,B,C and D(a) 
Interruptions off ; STatus flags (0-11) CLeared 
Switch off the menu bar 
Create a #00990h string in memory ; @ in A(a) ;  
@ = @ + #CCh for security, in R0(a) 
D0 = string @ ; A(w) = 0 ; C(b) = #87h (#880h / #10h) - #1h  
The memory string is being cleared (#880h nibbles) 
Get memory @ ; It becomes the new in memory screen 
GOSUB EC 
LC 3 D0= 80108 DAT0=C.P
Go sub-program EC : It displays 11 * 7 bricks on the screen 
I store the number of lives: #3h into #80108h buffer memory 
*REPLAY 
LC 41 D0= 00 DAT0=C.B 
LC 36 D0= 02 DAT0=C.B 
LC 3D D0= 04 DAT0=C.B 
LC 3A D0= 06 DAT0=C.B 
GOSUB ¨BALL GOSUB ¨RAK 
A=R0 LC 0085E A=A+C.A D0=A A=0.W DAT0=A.W 
D1= 80108 C=DAT1.P D=C.P LC 7 
DO { DAT0=C.P D0=D0+ 1 D--.P } WHILENC 
*KEY GOSBVL 00E0B GOC KEY 
*STOP GOSBVL 00E0B GONC STOP 
GOSUB ¨BALL GOSUB ¨RAK
This label is where we restart when we lose a life 
X ball pos in the screen (#41h pix) into #80100h buffer mem 
Y ball pos in the screen (#36h pix) into #80102h buffer mem 
X rack pos in the screen (#3Dh pix) into #80104h buffer mem 
Y rack pos in the screen (#3Ah pix) into #80106h buffer mem 
Displays the ball and the racket time at the middle screen 
The lives indicator down of the screen is cleared 
D(p) = lives ; C(p) = #1110b ; prepare to display lives id 
Displaying the D(p) lives indicator 
If a key is being pressed, then we wait until it's released 
If a key is not pressed, then we wait until it is 
The ball and the racket are erased one time ; prepare to play
*LCD  
D0= 80102 A=DAT0.B 
LC 3A ?A=C.B { D0= 08 A=DAT0.P ?A=0.P { GOTO QUIT } 
ELSE { A--.P DAT0=A.P } GOTO REPLAY } 
GOSUB ¨BALL GOSUB ¨RAK 
LC 600 DO { C--.X } WHILENC 
GOSUB ¨CBALL 
?ST=0.2 { 
GOSUB ?D ?ST=0.0 { D0= 80100 A=DAT0.B LC 7D ?A<C.B { A++.B DAT0=A.B } ELSE { ST=1.0 }  } 
GOSUB ?G ?ST=1.0 { D0= 80100 A=DAT0.B C=0.B ?A>C.B { A--.B DAT0=A.B } ELSE { ST=0.0 } } 
ST=1.2 } ELSE { ST=0.2 } 
GOSUB ?H ?ST=0.1 { D0= 80102 A=DAT0.B C=0.B ?A>C.B { A--.B DAT0=A.B } ELSE { ST=1.1 }  } 
GOSUB ?B ?ST=1.1 { GOSUB ?B D0= 80102 A=DAT0.B LC 3A ?A<C.B { A++.B DAT0=A.B } ELSE { ST=0.1 } } 
GOSUB ¨RAK 
LC 004 GOSBVL 01EEC ?CBIT=1.1 { D0= 80104 A=DAT0.B 
LC 77 ?A<C.B { A++.B DAT0=A.B } } 
LC 004 GOSBVL 01EEC ?CBIT=1.3 { D0= 80104 A=DAT0.B C=0.B ?A>C.B { A--.B DAT0=A.B } } 
GOSUB TQ GOTO LCD
This label is the main game loop ; the most important ! 
A(b) = X pos. of the ball ; the @ is #80102h 
The ball is down of the screen #3Ah ? Then A(p) = lives 
? lives = 0 then GAME-OVER else lives = lives - 1 REPLAY 
The ball and the racket are displayed (Xor) 
This is the game waiting loop ; else the game is too fast ! 
The ball is erased of the screen (Xor) 
STatut flag n°2 is = 0 1/2 time ; 60° Vertical ball direction 
Go sub program to test right wall ; if a wall ST flag n°0 = 1 
If the ball is at right then it bounces ; else the ball goes right 
Go sub program to test left wall ; if a wall ST flag n°0 = 0 
If the ball is at left then it bounces ; else the ball goes left 
STatut flag n°2 is = 0 1/2 time ; 60° Vertical ball direction 
Go sub program to test up wall ; if a wall ST flag n°1 = 1 
If the ball is up then it bounces ; else the ball goes down 
Go sub program to test down (wall) ; if a wall ST flag n°1 = 0 
If the ball is down then it bounces ; else the ball goes up 
The racket is erased of the screen (Xor) 
Key [6] is tested ; if pressed then A(b) = X racket position 
C(b) = max #77h limit ; if X racket < then X = X + 1 ; right 
Key [4] is tested ; if pressed then A(b) = X racket position 
C(b) = min #00h limit ; if X racket > then X = X - 1 ; left 
Go sub program to test if we want to quit ; goto main loop
Sub-Programs
Comments
*TQ 
LC 010 OUT=C GOSBVL 01EEC ?CBIT=0.4 RTNYES 
*QUIT 
D0= 00128 LC 7 DAT0=C.P 
D0= 8068D A=DAT0.A D0= 00120 DAT0=A.A 
GOVLNG 05143
This label is where we will test if the player wants to quit 
If the [ENTER] key is not pressed then ReTurN 
If the [ENTER] key is being pressed then prepare to quit 
Switch on the menu bar 
The real stack screen at #8068Dh @ is replaced 
The game is finished !
*EC 
A=R0 R4=A LC A R2=C LC 6 R3=C 
*REP 
GOSUB BRK 
$FF701080DFF0DFF0DFF0EFF0 
*BRK 
C=RSTK D1=C A=R4 D0=A LC 5 
DO { A=DAT1.X DAT0=A.X D0=D0+ 34 D1=D1+ 4 C--.P } WHILENC 
C=R2 ?C=0.P { LA A R2=A A=R3 ?A=0.P { RTN } ELSE { A--.P R3=A A=R4 LC 000AE A=A+C.A R4=A GOTO REP  } A--.P R3=A } ELSE { C--.P R2=C A=R4 A=A+3.A R4=A } 
GOTO REP
This label is where we will display 11 * 7 bricks 
R4 = screen @ up and left 
This label is the main display loop 
Go sub program BRK to get brick's GRaphics OBject @ 
This is the GROB without prolog and with $ 
The BRK label where we will get the brick GROB @ 
Brick GROB @ in C(a) D1 = this @ ; D0 = screen @ C(p) = 5 
Displaying a 12*6 brick GROB in the screen ; @ = R4 
There are 6 lines to display ; 6 - 1 = 5 loops 
We have to display 11 bricks on one line 
There are 7 lines where we have to display 11 bricks 
When 11*7 bricks are displayed on the screen ReTurN 
Else goto main display loop until all bricks are displayed
*¨BALL 
GOSUB BALL 
$60D0F060 
*BALL 
C=RSTK D1=C 
C=R0 D0= 80100 A=0.A A=DAT0.B ASRB.B ASRB.B 
C=C+A.A D0= 80102 A=0.A A=DAT0.B 
B=A.A ASL.A A=A+B.A A=A+A.A C=C+A.A 
D0= 80100 A=DAT0.B B=A.B D0=C 
LC 3 D=C.P C=B.B DO { A=DAT1.B ?CBIT=1.0 { A=A+A.B } ?CBIT=1.1 { A=A+A.B A=A+A.B } B=C.B C=DAT0.B C=-C-1.B A=A&C.B C=DAT0.B A=A!C.B 
DAT0=A.B C=B.B D0=D0+ 34 D1=D1+ 2 D--.P } WHILENC 
RTN 
This label is where we will display the 4 * 4 ball 
Go sub program BRK to get brick's GRaphics OBject @ 
This is the GROB without prolog and with $ 
The BALL label where we will get the ball GROB @ 
Ball GROB @ in C(a) D1 = this @ 
C(a) = screen @ ; A(a) = X ball / 4 
screen @ = screen @ + X ball / 4 ; A(a) = Y ball 
Y ball = Y ball * 34 (or #22h) ; Y * 16 + 1 * 2 
D0 = (X;Y) ball @ in the screen ; B(b) = X ball 
D(p) = #3h lines ; C(b) = B(b) ; A(b) = ball's line ; if X = 1 
or X = 2 or X = 3 then scroll ; C(b) = screen's line ; inv 
logic AND between A(b) and C(b) ; C(b) = screen's line ; OR 
Displaying in the screen A(b) ; D0 read the next screen line 
D1 read the next ball line ; 4 loops to display a ball ; ReTurN
*¨RAK 
GOSUB RAK 
$EF703080FFB0EF70 
*RAK 
C=RSTK D1=C 
C=R0 D0= 80104 A=0.A A=DAT0.B ASRB.B ASRB.B   C=C+A.A D0= 06 A=0.A A=DAT0.B 
B=A.A ASL.A A=A+B.A A=A+A.A C=C+A.A 
D0= 80104 A=DAT0.B B=A.B D0=C 
LC 3 D=C.P C=B.B DO { A=DAT1.4 ?CBIT=1.0 { A=A+A.A } ?CBIT=1.1 { A=A+A.A A=A+A.A } B=C.B C=DAT0.4 C=-C-1.A A=A&C.A DAT0=A.4 C=B.B D0=D0+ 34 D1=D1+ 4 D--.P } WHILENC 
RTN 
This label is where we will display/erase 12 * 4 racket (Xor) 
Go sub program RAK to get racket's GRaphics OBject @ 
This is the GROB without prolog and with $ 
The RAK label where we will get the racket GROB @ 
Racket GROB @ in C(a) D1 = this @ 
C(a) = screen @ ; A(a) = X racket / 4 
screen @ = screen @ + X racket / 4 ; A(a) = Y racket 
Y racket = Y racket * 34 (or #22h) ; Y * 16 + 1 * 2 
D0 = (X;Y) racket @ in the screen ; B(b) = X racket 
D(p) = #3h lines ; C(b) = B(b) ; A(b) = racket's line ; if X = 1 
or X = 2 or X = 3 then scroll ; C(4) = screen's line ; inv 
logic AND between A(a) and C(a) ; Displays A(4)  
D0 read the next screen line ; D1 read the next racket line 
4 loops to display a racket ; ReTurN
*?H 
D0= 80102 A=DAT0.B ?A=0.B RTNYES 
GOSUB GET 
LA 00022 C=C-A.A D0=C A=DAT0.B 
?A‹0.B { ST=1.1 
D0= 80100 A=0.W A=DAT0.B C=0.W LC C GOSBVL 65807 C=A.A C=C+C.A C=C+A.A RSTK=C 
D0= 02 A=0.W A=DAT0.B C=0.W LC 6 GOSBVL 65807 
C=A.A A=A+A.A A=A+C.A A=A+A.A C=A.A ASL.A A=A+C.A A=A+A.A C=RSTK A=A+C.A C=R0 C=C+A.A 
LA 000CC C=C-A.A  D0=C A=0.X LC 5 
DO { DAT0=A.X D0=D0+ 34 C--.P } WHILENC } 
RTN 
This label is where we will test the brick up to the ball 
A(b) = Y ball ; If the ball is up then ReTurN 
GOto redondant SUB program called GET 
D0 read the lien up to the ball ; A(b) = this line 
If this line is a brick then erase it else RTN ; Bounces down 
A(w) = X ball ; X = X / 12 ; the brick X size in pixels 
C(a) = X / 12 ball ; C(a) = C(a) * 3 ; C(a) on memory stack 
A(w) = Y ball ; Y = Y / 6 ; the brick Y size in pixels 
C(a) = Y / 6 ball ; C(a) = C(a) * 6 ; C(a) = C(a) * 34 
A(a) = C(a) ; A(a) = A(a) + C(a)stack + @ screen 
A(a) = A(a) - 6 * 34 ; D0 read this @ ; A(x) = 0 ; C(p) = 5 
The brick is being cleared ; 6 loops 
ReTurN
*?B 
GOSUB GET 
LA 00088 C=C+A.A D0=C 
A=DAT0.B ?A‹0.B { ST=0.1 } 
RTN 
This label is where we will test the racket down to the ball 
GOto redondant SUB program called GET 
D0 read the line under the ball 
A(b) = this line ; if there is the racket then bounce 
else ReTurN
*?D 
D0= 80100 A=DAT0.B LC 76 ?A>C.B RTNYES 
GOSUB GET 
 LA 00022 C=C-A.A D0=C 
D0=D0+ 3 A=DAT0.B 
?A‹0.B { 
D0= 80100 A=0.W A=DAT0.B C=0.W LC C GOSBVL 65807 C=A.A C=C+C.A C=C+A.A RSTK=C 
D0= 02 A=0.W A=DAT0.B C=0.W LC 6 GOSBVL 65807
C=A.A A=A+A.A A=A+C.A A=A+A.A C=A.A ASL.A A=A+C.A A=A+A.A C=RSTK A=A+C.A 
C=R0 C=C+A.A C=C+3.A D0=C A=0.X LC 5 
DO { DAT0=A.X D0=D0+ 34 C--.P } WHILENC } 
RTN 
This label is where we will test the brick right to the ball 
A(b) = X ball ; C(b) = Xmax ball ; if X > Xmax then RTN  
GOto redondant SUB program called GET 
D0 = the line upper the ball
D0 = the line right to the ball ; A(b) = datas from D0 
IF data different 0 THEN there is a brick
A(w) = X ball ; X = X / 12 ; the brick X size in pixels 
C(a) = X / 12 ball ; C(a) = C(a) * 3 ; C(a) on memory stack 
A(w) = Y ball ; Y = Y / 6 ; the brick Y size in pixels 
C(a) = Y / 6 ball ; C(a) = C(a) * 6 ; C(a) = C(a) * 34 
A(a) = C(a) ; A(a) = A(a) + C(a)stack + @ screen 
A(a) = A(a) - 6 * 34 ; D0 read this @ ; A(x) = 0 ; C(p) = 5 
The brick is being cleared ; 6 loops 
ReTurN 
*?G 
D0= 80100 A=DAT0.B LC 0C ?A<C.B RTNYES 
GOSUB GET 
LA 00022 C=C-A.A D0=C 
D0=D0- 3 A=DAT0.B 
?A‹0.B { 
D0= 80100 A=0.W A=DAT0.B C=0.W LC C GOSBVL 65807 C=A.A C=C+C.A C=C+A.A RSTK=C 
D0= 80102 A=0.W A=DAT0.B C=0.W LC 6 GOSBVL 65807 C=A.A A=A+A.A A=A+C.A A=A+A.A C=A.A ASL.A A=A+C.A A=A+A.A C=RSTK A=A+C.A 
C=R0 C=C+A.A C=C-3.A D0=C A=0.X LC 5 
DO { DAT0=A.X D0=D0+ 34 C--.P } WHILENC } 
RTN 
This label is where we will test the brick left to the ball 
A(b) = X ball ; C(b) = Xmin ball ; if X < Xmin then RTN  
GOto redondant SUB program called GET 
D0 = the line upper the ball
D0 = the line left to the ball ; A(b) = datas from D0 
IF data different 0 THEN there is a brick
A(w) = X ball ; X = X / 12 ; the brick X size in pixels 
C(a) = X / 12 ball ; C(a) = C(a) * 3 ; C(a) on memory stack 
A(w) = Y ball ; Y = Y / 6 ; the brick Y size in pixels 
C(a) = Y / 6 ball ; C(a) = C(a) * 6 ; C(a) = C(a) * 34 
A(a) = C(a) ; A(a) = A(a) + C(a)stack + @ screen 
A(a) = A(a) - 6 * 34 ; D0 read this @ ; A(x) = 0 ; C(p) = 5 
The brick is being cleared ; 6 loops 
ReTurN
*¨CBALL 
C=R0 
D0= 80100 A=0.A A=DAT0.B ASRB.B ASRB.B   C=C+A.A 
D0= 80102 A=0.A A=DAT0.B 
B=A.A ASL.A A=A+B.A A=A+A.A C=C+A.A D0=C 
D1= 80100 A=DAT1.B LC 04 
*LOOP ?A>C.B { A=A-C.B GOTO LOOP } C=0.B 
?ABIT=0.0 { ?ABIT=0.1 { GOTO Y1 } ELSE { GOTO Y3 } } 
ELSE { ?ABIT=0.1 { GOTO Y2 } ELSE { GOTO Y4 } } 
*Y1 LA 3 DO { DAT0=C.P D0=D0+ 34 A--.P } WHILENC RTN 
*Y2 LA 3 DO { C=DAT0.B CBIT=0.1 CBIT=0.2 CBIT=0.3 CBIT=0.4 DAT0=C.B D0=D0+ 34 A--.P } WHILENC RTN 
*Y3 LA 3 DO { C=DAT0.B CBIT=0.2 CBIT=0.3 CBIT=0.4 CBIT=0.5 DAT0=C.B D0=D0+ 34 A--.P } WHILENC RTN 
*Y4 LA 3 DO { C=DAT0.B CBIT=0.3 CBIT=0.4 CBIT=0.5 CBIT=0.6 DAT0=C.B D0=D0+ 34 A--.P } WHILENC RTN
This label is where we will erase the 4 * 4 ball

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

*GET 
C=R0 D0= 80100 A=0.A A=DAT0.B ASRB.B ASRB.B   C=C+A.A 
D0= 80102 A=0.A A=DAT0.B 
B=A.A ASL.A A=A+B.A A=A+A.A C=C+A.A 
RTN 
@
This label is a redundant routine for other sub programs 
 
 
 
 

End of source

 
 
Back to my home page