Jump to content

Tutorial Apps

Sign in to follow this  

Programs to help you learn various aspects of the X16

4 files

  1. Falling Snake - Simple game in Basic

    A simple game fully in Basic.
     
    NOTE: If you just want to run the latest version of this game on the Web based emulator do like this.
    1. Copy the code from: https://github.com/JoystickAndCursorKeys/x16basic/blob/main/fallingsnake.v2.bas.txt (CTRL-C)
    2. Go here: https://www.commanderx16.com/emulator/x16emu.html  and paste the code. (CTRL-V)
    3. Press "Run"
     
    This (version 0 of the game) is a very little game I wrote on the commodore 64 ages ago, I changed it a little to work with vpeek, vpoke, the new color command, and the new screen resolution.
    To me starting with a simple game in basic is how I learned about the c64, and now the X16, before jumping in machine language. 
    In the code for this game you can see practical examples, on how to set characters on the screen, read characters from the screen, change colors for characters, listen to the keyboard, set a screen mode.
    What surprised me was that I needed a delay in the code in order to have it not run too fast.  This was not the case on the c64. 
     
    I really like the way you can use the emulator in the browser, as it allows you to type in basic inside the browser, using "regular key mappings", and the run it. 
    When I wanted to save it, I copy-pasted it into the installed emulator (hats off for who added he paste function there), and types the save command. 
    This was done, because in the browser you cannot save it, and see it on disk (as far as I know)
     
    I added many REMs in the code, in order so it can be understood, and it is more of a tutorial, then a "real" game.
    Below I will  go through the code.
    From line 5, the program initializes From line 9, the title screen is drawn From line 49, the game is initialized From line 199, the game loop starts From line 300, the game over screen is drawn Some miscelanious notes:
    The SCREEN command is used to set the screen in text mode (Petscii) 40x30 The color command is used to set character fore and background colors.  Unlike the c64 each char has its own background color. There is no "global" background color CHR$(113) is used to draw the Petscii circle character, used on the title screen.  Adding the actual character into the code listing, makes it hard to edit outside the emulator. CHR$(119) is another Petscii character VPOKE 0,0,x, pokes a character on the top level corner of the screen. So the text screen address = 0 (not like on the C64) On line 52 the bottom of the screen offset is calulated.  NOTE: Even though the screen is 40 chars long, to get to VPOKE address of the next line, you need to add 256 bytes. SI and PI (StoneImage and PlayerImage) are Petsci chars, that are used in the game. NOTE: Petscii chars have different values in the PRINT or the VPOKE commands. Reminder: In C64/Microsoft basic a variable name is only two characters long max. Reminder: Lines in Basic should not be longer then 80 chars. When you make them longer, the emulator ignores them. A good place to see all PETSCII character codes is here: https://www.commanderx16.com/forum/index.php?/files/file/23-vera-chars/ Have fun!  
    And the code itself:
    (it is easier to copy paste it in the browsers emulator and be able to modify it more easy here: https://www.commanderx16.com/emulator/x16emu.html
    ----- code below for copy & pasting, also you can get it by downloading FALLSNAKE.PRG or checked out at: https://github.com/JoystickAndCursorKeys/x16basic/blob/main/fallingsnake.v0.bas.txt----- 
    5 REM SET TO 40X30 CHARS SCREEN
    6 SCREEN 0
    7 HM$=CHR$(19)

    9 REM TITLE SCREEN -----------------
    10 REM SET COLORS TO BLACK AND WHITE, CLEAR SCREEN
    11 COLOR 1,0: CLS
    12 PRINT:PRINT:PRINT:PRINT : REM PRINT TITLE
    13 PRINT "             FALLING SNAKE": PRINT: COLOR 15
    14 PRINT "   YOU ARE FALLING DOWN A HOLE"
    15 PRINT "   AVOID ALL OBSTACLES"
    16 COLOR 7: PRINT "   PRESS SPACE TO START"
    17 BA$=CHR$(113):BB$=CHR$(119) : REM BALL SYMBOLS
    18 COLOR 2,0 : PRINT "    "+BA$
    19 PRINT "    "+BA$:PRINT "    "+BA$
    20 PRINT "    "+BA$+BA$+BA$+BA$+BA$+BA$+BA$+BA$+BA$;:COLOR 8:PRINT BB$
    25 GET A$: IF A$="" GOTO 25 : REM WAIT FOR KEY
    35 TS=0 : REM SET TOP SCORE

    49 REM START GAME -----------------
    50 COLOR 1,0: CLS
    51 FOR T=1TO29:PRINT:NEXT
    52 BO=29*256:SI=42:            : REM BOTTOMSCREENOFFSET, STONEIMAGE
    53 PO=15*256:PI=81:PC=2:PX=20  : REM PLAYEROFFSET, PLAYERIMAGE, PLAYERCOLOR
    54 DE=1000                     : REM DELAY VALUE
    55 S=0 : REM SET SCORE

    199 REM GAME LOOP -----------------
    200 GET A$
    201 IF A$=CHR$(29) AND PX<40 THEN PX=PX+1 : REM GO RIGHT
    202 IF A$=CHR$(157) AND PX>0  THEN PX=PX-1: REM GO LEFT
    210 X=INT(RND(1)*40)*2: C=INT(RND(1)*15)+1 : REM GET RANDOM STONE POSITION
    211 PE=VPEEK( 0, PO+(PX*2))
    212 IF PE=SI THEN GOTO 400
    220 VPOKE 0, BO+X, SI: VPOKE 0, BO+X+1, C
    221 VPOKE 0, PO+(PX*2), PI: VPOKE 0, PO+(PX*2)+1, PC
    296 FOR W=1 TO DE: NEXT : REM DELAY, SLOW DOWN CODE
    297 PRINT : S=S+1 : DE=DE-1 : IF DE<0 THEN DE=0
    298 GOTO 200

    399 REM GAME OVER -----------------
    400 IF S>TS THEN TS=S
    401 PRINT HM$:PRINT:PRINT:PRINT "             GAME OVER": PRINT
    402 PRINT "    SCORE: "+STR$(S);
    405 PRINT "    TOP SCORE="+STR$(TS)
    410 COLOR 7: PRINT: PRINT "         PRESS SPACE TRY AGAIN" : PRINT:PRINT
    420 GET A$
    421 IF A$ = "" OR A$=CHR$(29) OR A$=CHR$(157) THEN GOTO 420
    422 GOTO 50
    ---------------------------------------------------------- End of Code First Version ----------------------------------------------------------
    The way I normally work when creating a game, I create first the skeleton, and then add more and more niceties, like effects, and game play elements.
    Above, we have the skeleton, we have a minimal game. We have a title screen, we have a playable section, we have a score, a game over section, and a high score.
    Below I will show the improvements I made so far, and are saved in FALLSNAKE2.
     
    In the init section of the program, I rearranged the line numbers, so I would not overlap with the rest of the program, when adding two more lines. The added lines are in Bold/Underline. Line 3, I allocate an array called EX to store the "petscii picture" of an "explosion".  It is 9 chars. The "picture" is 3x3 chars. No colors. 3x3=9, which is how much we need to allocate with the DIM command.
    Line 4, reads data from the DATA statements at the end of the program into the array called "EX".
    0 REM SET TO 40X30 CHARS SCREEN
    1 SCREEN 0
    2 HM$=CHR$(19) : REM HOME CHARACTER
    3 DIM EX(9)
    4 FOR T=0TO8: READ C : EX(T)=C: NEXT : REM READ PETSCII EXPLOSION
    In the "Game over" section of the game, I added the drawing of the explosion picture, and a flashing color effect to go with it. Again, I renumbered the code around it a bit. We iterate through the characters in the EX array, by looping x and y from 0 to 2, and calculating the offset to EX (called DO, data offset).   We use VPOKE to put the bytes on the screen memory, at address SO (screen offset).  SO is calculated by using the xx + the player y coordinate, minus 1 (this will be XS). Similar will be done for y, but to calculate SO, we add XS*2 (each char takes two bytes) + YS*256 (from one row to the next the distance offset is 256 chars)
    401 REM DRAW EXPLOSION
    402 FOR XX=0TO2:FOR YY=0TO2
    403 XS=XX+PX-1: YS=YY+15-1 : REM SCREEN X,Y
    404 IF PX<1 THEN XS=XX+1   : REM CHECK PLAYER X TO BE ON SCREEN
    405 IF PX>38 THEN XS=XX+38
    406 DO=XX+(YY*3):SO=(XS*2)+(YS*256) : REM CALC DATA OFFSET, SCREEN OFFSET
    407 VPOKE 0,SO,EX(DO)      : REM WRITE TO SCREEN
    408 NEXT:NEXT
    Below there is a simple color cycling effect for the background, this is done by adding random values into palette register for color 0. The register is stored in two addresses, $FA00 and $FA01.  Actually some bytes are not used, but for a random effect we ignore that. If we want to have for example a red explosion flicker, we need to be more careful on the values we put into the register.
    410 REM EXPLOSION COLOR EFFECT
    411 FOR T=1 TO 50
    412 C0=INT(RND(1)*255)
    413 C1=INT(RND(1)*255)
    414 VPOKE 1,$FA00,C0: VPOKE 1,$FA01,C1
    415 NEXT: VPOKE 1,$FA00,0: VPOKE 1,$FA01,0
    and the last part (after renumbering even more lines of code), we added the data for the explosion petscii "picture".
    2000 REM PETSCI EXPLOSION
    2001 DATA $4D, $20 , $4E, $20, $D6, $20, $4E, $20, $4D
    The complete code can be found in FALLSNAKE1.PRG, or checked out at: https://github.com/JoystickAndCursorKeys/x16basic/blob/main/fallingsnake.v1.bas.txt
     
    One thing that keeps me going when creating a game, is but adding sessions where I make the game look nicer, without adding functionality.
    The changes below (1.0.2 version, FALLSNAKE2.PRG), is all about this.
    Just Renumber it
    To start off, we have been renumbering again the lines of the source code. 
    For those that are not used to using old school type basic, it is very easy to add extra code and run out of numbers.  And it is important to "reserve" numbers.  So for example if you make a program like this.
     
    1 PRINT "HELLO WORLD"
    2 GOTO 1
    And you want to add something between line 1 and 2, you cannot do it, unless you renumber the existing lines.  For that reason it is a better idea to start coding like this:
    10 PRINT "HELLO WORLD"
    20 GOTO 10
    This way you have some space in between,  and you could easily add a line 15 to print something else, if you want to.
    Nevertheless it can still happen even when you have reserve ranges, and they get to be "full".  This is especially the case when you add new sections of verbose code between other code.  And this is exactly why I am once more renumbering. 
    -- -- --
    To add sprites, you need to have the images stored some where.  The old school way of doing it, is to add "DATA" commands to the code, like below. I will not write it completely here, since it becomes very verbose, but it looks something like this:
    11000 DATA $00, $00, $22, $22, $22, $22, $00, $00
    11001 DATA $00, $22, $82, $82, $82, $82, $22, $00
    11002 DATA $02, $88, $88, $28, $28, $28, $28, $20
    11003 DATA $28, $08, $08, $22, $22, $22, $82, $8b
    11004 DATA $28, $88, $88, $20, $00, $28, $28, $b0
    11005 DATA $02, $82, $82, $00, $02, $82, $8b, $00
    11006 DATA $00, $22, $20, $00, $28, $22, $b0, $00
    ..... Many more lines of this
    NOTE: Only in the 80s would you type in lines and lines of DATA like this. Now there are easier ways, for example a sprite editor with an export function. There is many options, below is one of them. 
    The important thing is to export to a sprite data that the X16 understands. In this case 16x16 dimensions, 16 colors, so 4bpp (4 bits per pixel for color info), and basic support HEX numbers.

    And to use them, you write something like this.
    1000 REM READ SPRITE DATA  
    1001 FOR I=O TO 255
    1011 READ PX  : REM READ ONE NUMBER FROM THE DATA.
    1012 VPOKE $0,$4000+I,PX: REM USE VPOKE TO MOVE THE DATA IN VIDEO MEMORY
    1013 NEXT I
    1014 RETURN
    At the end of these lines of code, you see the command RETURN.  What is this about?
    Well, with basic we can simulate calling a function/subrouting, with GOSUB.  RETURN returns back to where it was called.
    The code is being called in the beginning, something like this:
    10 GOSUB 1000 : REM READ SPRITE DATA
    After the call to the subroutine at line 1000, it continues to the next line.   This is one way to organize the code inside Commodore/Micro$oft basic.
    I will not mention all the details of setting up the sprite here, you can check the code yourself, if you want to.  Later I will go deep into this topic, but not here.
    However to get the sprite in the right position we have another subroutine.
     
     1070 REM SET SPRITE 0,X0,Y0
     1171 VPOKE $1,$FC12,X0 AND $FF
     1172 VPOKE $1,$FC13,(X0 AND $0300)/$100 : REM MAGIC TO GET HI BYTE OF THE X COORDINATE
     1173 VPOKE $1,$FC14,Y0 : REM YPOS 128
     1174 VPOKE $1,$FC15,$00 : REM WE DON'T CALCULATE THE HI BYTE OF THE Y COORDINATE
     1175 RETURN
    Which I call in the title screen build up like this.
     
    75 X0=150: Y0=68: GOSUB 1070 : REM SET SPRITE X,Y
     
    Note that for calling the subroutine with parameters, we simply assign global variables. To keep from clashing with other global variables, use a naming convention.
    Here I used 0 (zero) as the second 'letter' in the name as the naming convention.
     
    In the game, the position changes all the time, so instead we do like this:
    295 X0=PX*8: Y0=122: GOSUB 1070 : REM SET SPRITE X,Y
    X0 is calculated.  Y0 is static, but X0 is PlayerX (PX) times 8 (the width of a character on screen in bits)
     
    Color effect
    Now for the colour effect, we chose one color to be the one that has the effect, and we draw our blinking characters with this color. Like below.
    60 PRINT "FALLING SNAKE";: COLOR 14: PRINT "**": PRINT: COLOR 15
    And we cycle / blink, by doing something like this.
    80 C0=C0+1: IF C0>2 THEN C0=0: C1=C1+1: IF C1>255 THEN C1=0:
    82 VPOKE 1,$FA1C,C1: VPOKE 1,$FA1D,C1
    Offset $FA1C and $FA1D in the VERA video ram, control the palette registers for color 14. Each color has two bytes, so if you want to find the color register for color 0, you just substract 28 decimal (2*14) from hex $FA1C.
    (Convert 28 to hex first)
    Feel free to check out the code or the PRG file, at this stage.
    Code: https://github.com/JoystickAndCursorKeys/x16basic/blob/main/fallingsnake.v2.bas.txt
    PRG file: FALLSNAKE2.PRG
    --
    In the next session we will concentrate a bit more on gameplay.  It is no use to pimp up the graphics, if the gameplay is boring.
    Since this is really a simple game, we easily can do a few things to spice it up.
    more coming soon..
     

    2 downloads

       (0 reviews)

    5 comments

    Updated

  2. Beginner 6502 Assembly Stuff

    *** THIS FILE IS ALSO NOW IN THE DEMO SECTION TO ENABLE THE "TRY IT NOW" FEATURE ***
    This may be of interest to absolute 6502 assembly beginners like me, although advanced 6502 programmers may cringe at the way I've done things here! This program does very little, but it is a repository of useful assembly routines for things like printing different bytes of memory (useful for debugging) as well as some basic math operations. I will keep adding to this as I progress through my assembly journey (I'm aiming to write my fractal BASIC programs in assembly).
    Thanks to the following YouTubers for their excellent tutorials on all things 6502: 
    Ben Eater - YouTube
    Matt Heffernan - YouTube
    ChibiAkumas - YouTube (and also his excellent website: Assembly Tutorials: Learn 6502 Assembly Programming... With ChibiAkumas!)
    Function usage: (notation for cc65 assembler)
       jsr print
    .byte (list of PETSCII character codes to print, ending in a $0 byte)
       jsr println
    .byte (list of PETSCII character codes to print, ending in a $0 byte)
       jsr print_mem
    .word (start address of memory dump)
    Set MEMDUMPLEN to the number of addresses you wish print_mem to display. 

    3 downloads

       (0 reviews)

    0 comments

    Updated

  3. Read Directory in BASIC

    This reads the disk directory in BASIC. This is a super simple example and doesn't actually parse the files... it's just smart enough to read "$" and print it to the screen. 
     

    21 downloads

       (0 reviews)

    0 comments

    Updated

  4. File Loader Tutorial

    Introduction
    Here is a little demo of how to dynamically load files in RAM bank in assembly.
    It's very simple to do but I think that it can be helpful for someone who don't know how to do this right away. In fact I personally would love to see more of this kind of programs in the download section 🙂
    How this loader works ?
    First thing to do is to tell the Kernal that we want to use a logical file. For this we need to use the SETLFS subroutine.
    From the "C64 Programmer Reference Guide" :
    Since we want to load from the disk (or filesystem) we'll need to use the device number 8. The logical file is not important so we use the file 0.
    Also, as we want to relocate the program into a bank at $A000, we'll set the Y register to #0 to activate secondary address mode.
    Next step is telling the Kernal which file we want to load. For this we'll use the SETNAME subroutine.
    From the "C64 Programmer Reference Guide" :
    For this we'll need to store our file names somewhere in our program so we write at the bottom of our file the names as a string of petscii characters. We then prepare our registers with the size of the filename to load, and then the address.
    Our final step to load a file is obviously the LOAD subroutine.
    From the "C64 Programmer Reference Guide" :
    As the Reference guide said, we want to load a file so we set our A register to 0 and since we want to load to banked RAM ($A000) we enter the address in our X and Y registers.
    One last thing that we need to do just after each of our LOAD calls, is to verify that our file has been successfully loaded. For this, we'll need to use the READST subroutine.
    From the "C64 Programmer Reference Guide" :
    As usual, following the Reference guide, all we need to do is call this subroutine just after our LOAD call, and check the content of the Accumulator. If zero, the load was successful.
    And that's all ! You can chain file loading as much as you need, and even you just need to call SETLFS once at the start of the chain.
    Note that you'll need to switch the bank between file loads to prevent overwriting previously added program. And since Bank 0 is also reserved you'll need to first switch to bank 1 and start from here.
    At the end you can also load a file in place of the loader, just avoid overwriting memory where the code is currently being executed. You can for example leave this kind of code in your first bank and at last run it to load a program from $0800 to $9EFF.
    Kernal Subroutines full documentation : https://www.pagetable.com/c64ref/kernal/
    Post Scriptum
    If you have any suggestions for the code or even want to change things in this description, don't hesitate to tell me !

    40 downloads

       (1 review)

    0 comments

    Updated

Sign in to follow this  
×
×
  • Create New...

Important Information

Please review our Terms of Use