Lesson 7: Our first program!!

 

Well, I have decided it would be wrong to start with anything other than the most commonly written program in the world, the "Hello World!" program.
What I will do, is I will write it out, and then we can analyze it.

#include "usgard.h"


   .org 0
   .db  "Hello World!!",0

LetsBegin:
   call CLEARLCD
   ld   hl,&Text
   ld   de,$0301
   ld   ($800C),de
   call D_ZT_STR
Wait:
   call GET_KEY
   cp   $37
   jr   nz,Wait
   ret

Text:
   "Hello World!!!",0

   .end

OK- there is a lot of stuff you have not seen yet in here. Lets take it a piece at a time.

#include "usgard.h"

This line is required at the top of all Usgard programs. It contains all the necessary info, such as where all the rom functions are, scan codes, and other stuff.

.org 0
.db "Hello World!!",0

This is necessary of ALL TI-85 programs so far. The .org 0 tells the assembler that this is the beginning of the program, and it is locatd at 0h in the memory- not important to us now. The .db stands for data byte. There needs to be a .db right after the org, it will be used as the title displayed in the shell. A 0 is required after the name, because the string needs to be a special type of string called a null or zero terminated string.

call CLEARLCD

this is another rom call; and as you may have guessed, it clears the screen.

ld hl,&Text

This points HL to the Text label at the end of the program, where the text we want to print.

ld de,$0301
ld ($800C),de

this puts the coords (1,3) at $800C, so the calc knows where on the screen to print our string.

call D_ZT_STR

this is the rom call that Displays a Zero Terminated STRing. It displys the string that hl points to.

Wait:
call GET_KEY
cp $37
jr nz,Wait

You have seen this before; It is going to wait for a keypress. $37 is the scancode for exit.

ret

Were are done, time to go back to usgard.

Text:
"Hello World!!!",0

The label for the text, and then the text itself. Notice the 0 after, meaning the is a zero terminated string.

.end

It is required. I dont know why, but make sure there is at least one blank line after it.

Now just to compile it. There should have been compiling programs that came with Usgard when you downloaded it. There also is a batch file- c.bat that comes with Usgard. This will compile our program.. Lets name out program Hello.asm So, you type:

c Hello

It will calculate relocations, and then tasm will come in and check for errors. If thee are none, the compiling will link it into a string. Otherwise, TASM will display on what lines there are errors and whats wrong. Go back and fix it and try again. Once you have success, send it to your calc, and give it a try!

Ok, you know tons more than what this program does. So I say we make a game. I have chosen to reamke the first BASIC game I ever made. But before we do this, I have to teach you about 'variables'.

I Believe I mentioned it before, but you can assign a name to a memory address. And we are going to use these names as variables. But where are we going to store all these variables? The TEXT MEMORY. There you have 168 bytes of storage. To define a variable, type this at the top of your program:
Score = TEXT_MEM
Lets say theat the score is going to be a word in size. Lets define two more vars, one called X, and one Y.

Score = TEXT_MEM
X = TEXT_MEM+2
Y = TEXT_MEM+3

See, the score is a word in size, so it uses TEXT_MEM and TEXT_MEM+1. Then, we atart at the next byte, TEXT_MEM+2 and assign X to that. X is only 1 byte, so Y can go at TEXT_MEM+3.

If you look in Usgard.h, you will see a TEXT_MEM defined as $80DF.

Ok, Lets go at it. Here is our first version of BugCatcher.

   #include "usgard.h"

PlayerCoords = TEXT_MEM    ;A word to hold the x and y coords of the player
BugCoords    = TEXT_MEM+2  ;Another word to hold x+y coords of the bug
MoveCounter  = TEXT_MEM+4  ;How long until a move
CurMove      = TEXT_MEM+5  ;What move we are on


   .org 0                  ;Required- Say that this is the beginning of the prog.
   .db  "Bug Catcher",0    ;Title


   ld   hl,$0101           ;Put $0101 as the bug coords.
   ld   (BugCoords),hl
   ld   hl,$0A07           ;Put $0A07 as the players coords.
   ld   (PlayerCoords),hl
   call CLEARLCD           ;Clear the screen.
   ld   hl,&TitleScreen    ;point hl to the title screen text
   ld   de,$0000
   ld   ($800C),de         ;Put the cursor at 0,0
   call D_ZT_STR           ;Display The title screen
   ld   c,5                ;Our starting rate
ChangeRate:
   ld   de,$1002
   ld   ($800C),de         ;Put the cursor at 17,2
   ld   a,c                ;get a out of c
   add  a,'0'              ;make it a printable character
   call TR_CHARPUT         ;Print the char on the screen
   call GET_KEY            ;Get a key.
   cp   $37                ;See if the key is EXIT 
   ret  z                  ;Exit if it is 
   cp   9                  ;See if it is enter
   jr   z,ToGame           ;Start the game if it is
   cp   K_UP               ;See if the key is up
   jr   z,incit            ;increment the rate
   cp   K_DOWN             ;Check if the key is down
   jr   z,decit            ;dec the rate if it is.
   jr   ChangeRate         ;Not one of the keys; loop arond.
incit:
   ld   a,c                
   cp   9                  ;If c is 9, go back- its our max
   jr   z,ChangeRate
   inc  c                  
   jr   ChangeRate
decit:
   ld   a,c
   cp   1                  ;If c is 1, its our min so go back
   jr   z,ChangeRate
   dec  c
   jr   ChangeRate
ToGame:
   ld   a,c
   ld   (MoveCounter),a    ;Save the rate
   call &DrawScreen        ;Draw!
Game_Loop:                 ;The game loop.  This is the game's main loop.
   call GET_KEY            ;Get a key
   ld   hl,PlayerCoords    ;Point hl to the player coords, will be useful later
   cp   K_UP               ;\
   jr   z,Up               ; \ 
   cp   K_DOWN             ;  \
   jr   z,Down             ;  You should know 
   cp   K_LEFT             ;  what all these do.
   jr   z,Left             ;  /
   cp   K_RIGHT            ; /
   jr   z,Right            ;/
   cp   $37                ;$37 is the scancode for exit.
   ret  z
   jr   Game_Loop
P_Moved:                   ;Game will come here after a move has been made.
   ld   hl,(MoveCounter)   ;l is the move counter; h is the curmove
   ld   a,h
   inc  a
   cp   l                  ;See if it is time to move the bug
   call z,&MoveBug         ;Move now if time
   ld   (CurMove),a        ;save a for next time.
   call &DrawScreen        ;Draw!
   ld   hl,(PlayerCoords)  ;get the player coords in hl
   ld   de,(BugCoords)     ;get the bug coords in de
   call CP_HL_DE           ;only if cp  hl,de was a legal command..
   jr   nz,Game_Loop        ;Oh well, this rom call does the same exact thing
   call CLEARLCD
   set  3,(IY+05)          ;Display white on black
   ld   hl,&Win            ;point hl the the win text
   ld   de,0
   ld   ($800C),de         ;cursor=(0,0)
   call D_ZT_STR           ;Display you win
   res 3,(IY+05)           ;Display black on white (normal)   
wait:
   call GET_KEY            ;\
   cp   K_EXIT             ; Wait for exit
   jr   nz,wait            ;/
   ret                     ;Back to Usgard for us.

Up:
   ld   a,(hl)             ;I told you pointg hl earlier would be useful
   cp   0                  ;Find out if the val hl points to is 0.
   jr   z,Game_Loop        ;Go back if it is.
   dec  (hl)               ;dec the mem hl points at
   jr   P_Moved
Down:
   ld   a,(hl)
   cp   7                  ;7- bottom row
   jr   z,Game_Loop
   inc  (hl)
   jr   P_Moved
Left:
   inc  hl                 ;inc hl so it points to the x coord
   ld   a,(hl)
   cp   0
   jr   z,Game_Loop
   dec  (hl)
   jr   P_Moved
Right:
   inc  hl
   ld   a,(hl)
   cp   20                  ;20 is the furthest right we can go.
   jr   z,Game_Loop
   inc  (hl)
   jr   P_Moved

DrawScreen:
   call CLEARLCD            ;Clear the screen
   ld   hl,(BugCoords)      ;
   ld   ($800C),hl          ;Copy the bug coords to the cursor location
   ld   a,'*'               
   call TR_CHARPUT          ;put a "*" there.
   ld   a,'#'
   ld   hl,(PlayerCoords)   ;Copy the bug coords to the cursor loc
   ld   ($800C),hl          ;
   call TR_CHARPUT          ;Display a "#" there.
   ret                      ;Go back to where we came

MoveBug:
   call RANDOM              ;This is an Usgard function
   and  %111                ;You don't know this yet.
   ld   l,a
   push hl                  ;push hl away; random destroys it.
G_I_B:
   call RANDOM
   and  %11111
   cp   20
   jr   nc,G_I_B
   pop  hl                  ;Get hl back.
   ld   h,a
   ld   (BugCoords),hl
   ld   a,0
   ret                      ;I will walk you through this section next lesson
      

;All the DB's for the game

TitleScreen:
        ;123456789012345678901
   .db  "     BugCatcher!     "
   .db  "Use up/down arrows to"
   .db  "Change 'Speed':",0

Win:
   .db  "      YOU WIN!!      ",0

.end                        ;Required by TASM

Copy it and put it in to a file; I called it bugcatch.txt.

You will see that this is pretty well commented, so I hope you understand it. You do know everything, except for the ramdom section. Well, when you compile this out, I should come to something like 360 bytes. Pretty small. Even though there is a lot of enhancemnts we are going to make throughout the lessons, I bet it will still be smaller than the 2200 byte TI-BASIC version. I use a lot of new ROM calls too. If you refer back to those listings I gave you last lesson you can find out exactly what they all do.

How to play:
When you start the string, you will be prompted by it waning to know the speed. That number actually is how many moves you, the '#' moves until the '*' moves. When you land on the smae square, you win. Pretty easy.

This is a good time to review, but you can do that on your own. When you are ready, go on to lesson 8.