Tiny Basic on the XGS PIC Gamestation-UPDATE

NOTE: please excuse the crudeness of the photos. I am photographing a cheap television screen with my iPhone. I promise better screen caps once I get the video grabber up on the PC I use.

IMG_2370It’s almost ready…XGS ARDBasic 1.0 is about ready to be unleashed on the public. Or, at least, anyone who owns an XGS PIC Gamestation product and would like to program on the device.

Since my last post, I’ve had a whale of a time tracking down a couple of showstopper bugs. Fortunately, I have fixed them and, while there is still a bug or two, I can run the interpreter, reliably, on the device itself.

I have also extended the tiny language to include:

  • primitive, TRS-80 like, graphics
  • sound
  • ability to utilize the SPI port
  • SD card files (Load, Save, Delete and directory listing)
  • Gamepad
  • ability to change foreground and background color for whole screen

GRAPHICS

IMG_2376So far, however, the graphics are very blocky, 20 across, by 22 down. I guess it is more like the old Vic-20 than the TRS-80.  I have a set of 13 special characters that can be set with the ‘GPRINT’ statement that mimic the character graphics of the TRS-80 Color Computer. I also plan to extend them to include things like a generic figure, plane, car, etc. I cannot go too crazy as it eats up memory.  The new screen oriented statements are:

  • SET x,y – sets a block
  • RESET x,y – turns a block ‘off’
  • LOCATE x,y – puts the next ‘print’ statement location at x and y where y is the ROW and x is COLUMN
  • GPRINT x,y,c – puts one of the 13 special characters at location x,y
  • COLOR f,b – changes the screen foreground color to f and the background to b

GAMEPAD

The XGS PIC has two gamepad ports. Both are readable via the PAD function. Each button on the gamepad returns a multiple of two, so it is easy to determine which button was pressed. For example, the SELECT button returns 32 for the value, so checking for PAD=32 will let you know if the SELECT was pressed. See the Etch-A-Sketch sample code at the end of this post.

MISCELLANEOUS

IMG_2378Full documentation will be forthcoming, I am still deciding of a few things but should have some kind of document ready in the coming weeks.  I have added support for the XGS’ SPI port and may add support for other ports as well (like the UART.) I have also changed the RND function, so I need to re-write that part of my document as well. So, holding off on the documentation until I nail down the rest of the design seems prudent.

One thing I plan to do, again, at a later date, is to post technical details about the design and some of the issues I’ve encountered (and how they were resolved) with the XGS and the interpreter. It’s been a ton of fun and loads of learning, or, rather, re-acquainting myself with C. 

In the meantime, I present a sample demo that I threw together. It is a very, very crude Etch-A-Sketch:

100 CLS                         clear the screen
110 PRINT "GAMEPAD DEMO"        show the folks what this is
111 LOCATE 0,22                 move print position to last line
112 PRINT "RED:SET YELLOW:RSET" show what the red and yellow buttons do
120 X=1:Y=1:S=1                 set our pointers to 1
130 P=PAD(0)                    read the gamepad
131 P=PAD(0)                    do this twice to ensure you get a value
135 IF P=0 GOTO 130             if nothing is pressed, loop back
140 IF P=8 Y=Y-1                DOWN was pressed
150 IF P=4 Y=Y+1                UP
160 IF P=1 X=X+1                RIGHT
170 IF P=2 X=X-1                LEFT
180 IF X<1 X=1                  check to see if we are
185 IF X>19 X=19                out of bounds
186 IF Y<1 Y=1
187 IF Y<20 Y=20
200 IF P=64 S=1                 RED means draw
210 IF P=128 S=-1               YELLOW means don’t draw
220 IF S>0 SET X,Y              draw on RED
230 IF S<0 RESET X,Y            don’t draw on YELLOW
240 IF P=32 RUN                 SELECT means start over
250 IF P=16 STOP                START means stop
260 LOCATE 13,0                 put up the cursor location
270 PRINT X,",",Y," "
280 P=0                         reset the gamepad pointer
290 GOTO 130                    do it again

PLEASE NOTE: the comments in the listing above are for the purposes, in this blog, of explaining the code, they are not part of the code.

Write your own BASIC programs on your XGS PIC

Since rediscovering the XGS PIC Gamestation board, I’ve been doing some developing for the kit. One of the things I’d wanted to be able to do is actually do some coding ON the device. However, there are currently no development tools that actually RUN ON the device, so…I have adapted a dialect of Tiny Basic to run on the board.

IMG_2184This exercise, however, has reminded me of why I dislike the C programming language. In a nutshell, POINTERS. Oh my. These things are horrid.  The rest of the language is fine, even cool at times. But…those bloody pointers.

Rather than setting about writing the dialect from scratch, I searched the Internet for an open source variation and, boy, are there plenty.  Most, however, did not lend themselves to the kinds of changes I’d need to do to make it work. Since the XGS PIC has no operating system (whatever code that runs on it BECOMES the ‘OS’, providing all I/O.

Fortunately, Nurve Networks provided a few very well documented API’s and demos that I could use to supply all of the I/O I’d need.

The XGS PIC is a really funky, game oriented device and, as such, has very minimal specs.  VGA or Composite video out, really simple audio, SD card interface, Serial communications, two Atari style controller ports and PS/2 keyboard/mouse interface.  Talking to each is rather laborious to code, but the API set eases the pain a bit.

The graphical ability is somewhat between an Atari 7800 and the original NES in appearance.

Also, memory is tight: 16k RAM and 256k Flash. Well, 256k is more than enough for the Tiny Basic code and the API libraries, it’s the 16k RAM that makes it tight as this memory is shared between the video and your program.

So, after some searching and pouring through code, I found something for the Arduino. Called Nanode Basic, it was a modification of a Tiny Basic someone (Mike Field – hamster@snap.net.nz) crammed into an Arduino.  The Nanode modification added some features for real world interfacing to temperature sensors and a few other things. The architecture of the interpreter is smart and was easily adaptable to the XGS PIC. Mr. Field allowed for serial I/O to a terminal OR for use on an Arduino with keyboard and screen.  He left the I/O generic enough for me to, quite literally, plug in the calls to the keyboard and graphic driver API’s that Nurve supplied.

Now, the XGS PIC has two graphical modes: bitmap and tile.  IMG_2185Text rendering is done via the tile mode, which has, for now, precluded the inclusion of any graphical statement additions to the Basic (which I named ArdBasic, short for Arduino Basic.) 

The original Arduino Basic did not include the ability to save or load programs nor did it have any control over the screen.  I have extended it to include these features.

Tiny Basic, for those who may not know, came into being in the mid 1970’s for use in very low power microcomputers. Flavors of Tiny Basic were available for wide range of chips (some of which even had the language burned into them) from the Intel 4004 (quite a challenge since its entire address range is 16k) to the Z80 and oddball chips like the RCA 1802, Signetics 2650 and the National Semiconductor SC/MP.  The TRS-80 Model 1 even came with an enhanced version (4k) of the language.  Most implementations used about 2k of RAM for the entire package: line editor and interpreter. Some of these flavors even introduced some advanced constructs that are common today, but not then. Most of them had the ability to interact, at some level, with the hardware that they ran on, doing things like turning relays on or off or collecting data from some kind of sensor.

IMG_2158Back to our XGS.

I examined the Nanode Tiny Basic source and began removing the Arduino/Nanode specific code. Next, I figured out all of the places in code I would need to add the XGS specific stuff. My biggest headache was trying to debug the keyboard code while, unknowingly, having a faulty keyboard. That was fun.  Getting the timing correct, between reading the keyboard and displaying text on screen was the next biggest issue.  Once I got those issues resolved, I began adding my enhancements.

Before discussing the enhancements, lets talk about what was already there.  Standard features include:

Commands:

  • LIST
  • LOAD
  • NEW
  • RUN
  • SAVE
  • FILES

Functions:

  • PEEK(address)
  • ABS(number)
  • RND(dummy)

New:

  • LOCATE x,y – puts cursor at location x,y on screen
  • ? short for PRINT
  • MEM – displays free memory
  • PLAY x-plays a sound (PLAY 0 turns it off)
  • CLS – clears the screen
  • FILES – displays a list of files on the SD card

Other:

  • Integer math
  • 26 integer variables
  • No strings
  • Line Numbers, no textual labels
  • 20 characters by 16 lines
  • Old School

Statements:

  • NEXT
  • LET
  • IF
  • GOTO
  • GOSUB
  • RETURN
  • REM
  • FOR
  • INPUT
  • PRINT or ?
  • POKE* (not fully implemented)
  • STOP
  • BYE
  • SLEEP
  • CLS
  • LOCATE
  • MEM
  • PLAY
  • FILES

Operators:

  • +, –, *, /
  • <,>,<>,=
  • (,)
  • comma, ‘, “”
  • colon for multi-statement

 

The standard stuff, like PRINT, GOTO and such are implemented straightforwardly.  In this dialect, however, the only abbreviation that is allowed is the question mark, short for PRINT. I may, at some point, add the other shortcuts (PR for PRint, INput, etc.) but, for now, I am concentrating on core functionality.

As memory is at a premium, I removed code from the Graphics driver that was not necessary. This included all of the bitmap and tile graphics code, except for code that was necessary for the text console handling, clipping code and the initialization code. The other API’s are stock from Nurve or Microchip (the SD file handling API.)

I also developed a new font, using the C64 font supplied by Nurve (the old Commodore 64 font was too fat, but, now I have too much spacing between characters, I’ll add it to my to do list.)

Currently, the interpreter still has a few bugs, chiefly the line editor is wonky and randomly will reset the board.  The SAVE code is also buggy.  Once these bugs are squashed, I plan to do some code optimizing.  Fortunately, the originally code base was pretty tight, so most of the optimizing will be from my own sloppy coding.

Stay tuned for more.

Sample ArdBasic ‘guess my number’ code:

100 REM ** Sample ArdBasic Code
110 CLS
120 LOCATE 6,10
130 PRINT "GUESS THE NUMBER"
140 N=RND(1)
150 C=1
160 PRINT "GUESS #",C
170 PRINT "ENTER YOUR GUESS:",
180 INPUT G
190 IF G=N GOTO 250
200 PRINT "SORRY, TOO ",
210 IF G>N PRINT "HIGH": PLAY 9
220 IF G<N PRINT "LOW": PLAY 2
230 C=C+1:PLAY 0
240 GOTO 160
250 PRINT "YOU GUESSED MY NUMBER!"

To-Do:

  • Fix bugs
  • Add ability to chain programs
  • Add file deletion
  • Add rudimentary text files to the language
  • Font
  • Code optimizing
  • Graphics?

For more information:

XGS PIC development with XGS Basic-getting started

xgs_pic_03Writing in XGS Basic is a task, but the results, when run on the XGS, can be satisfying.  However, the process is a bit cumbersome and the language is incomplete and the documentation was never finished. However, the source code is freely available, so there is a way to fix some of the issues. I am not, however, ready to tackle that just yet.

No, instead, I thought I would share my process for writing and then executing code from XGS Basic on the XGS.

First, you’ll need a good programmer’s editor and one that, preferably, understands BASIC.  I am using Notepad ++.

You will also need a micro SD card, which came with your board OR you can use the Serial port on your computer and the appropriate cable plugged into the board.  I do not have a physical Serial port on my desktop, so I have a USB to Serial cable. However, Windows 8 does not support the cable. I have to use the SD card method.

Next, you’ll need the XGS Basic package.  You can download from the XGamestation web site, but it is on the DVD you got with your board.  Unzip the 1_5 version to a location on your computer and fire up that editor.

Compiling your code and running it:

  1. Open up a CMD window, you will need this when you compile.
  2. Write your source in your favorite editor and save it to the XGS Basic directory where you unzipped the package. 
  3. Switch to the CMD window and type: basicVM <name of the source.BAS> and then hit ENTER. (Where <name of the source.BAS> is your program file.)
  4. Your source will compile, provided you have no errors. If there is an error, you will be told what and where it is. Fix it and compile again.
  5. A successful compile will result in a .bai file being created (And, if you use serial, the .bai file is downloaded and executed on the board.)
  6. If you use the SD card method, copy the .bai file to the SD card and name it AUTORUN.BAI.  Plug the card into the board and turn it on. Your code should execute automatically.

Notepad ++ will allow you to automate the compile part, but I like doing things the hard way. I remember the steps this way.

Getting to know the hardware:

xgs_gamepad1I am, by no means, an expert on this board. I am somewhat new to this board, but have a basic understanding (the manual for the board is superb) of the device and how to use it.  XGS Basic has a few rudimentary functions and statements that talk to the hardware.  The most useful, for games, will be the graphics, of course, and the gamepad. The gamepad uses an Atari 2600 like connector, but is internally compatible with the NES style gamepads.  They are small, but comfortable and somewhat cheap feeling.  Sound is also possible, but I’ll save that for another day.

My introductory exercise was just to interact with the gamepad and draw something on screen, kind of like a rudimentary Etch a Sketch.  Now, before I go on, I have to say that my code is crap. It is but an example of talking to the hardware and not some fine piece of art. That said, take a look at the code below:

// Set the target as bitmap (not tile)
option target = "bitmap"

// ------------------------------------------------------

def paddle_speed = 1

// Gamepad direction defines
def gp_right  = 0x01
def gp_left   = 0x02
def gp_down   = 0x04
def gp_up     = 0x08
def gp_start  = 0x10
def gp_select = 0x20
def gp_red    = 0x40
def gp_yellow = 0x80

// colors
def RED          = 5
def BLACK        = 0

// ------------------------------------------------------
// 
// ------------------------------------------------------
call clear(0)
call text(10, 5, "Draw!")


Start:
    // Check for player input
    buttons = gamepad(0)
    
    // if RED button pressed, clear the screen
    if (buttons & gp_red) then call clear(BLACK)
    
    // go up or down, depending on the button press
    if(buttons & gp_up) then
        player1_paddleX = player1_paddleX - paddle_speed
    else if(buttons & gp_down) then
        player1_paddleX = player1_paddleX + paddle_speed
    end if
    
    // go left or right, depending on the button press
    if(buttons & gp_left) then
        player1_paddleY = player1_paddleY - paddle_speed
    else if(buttons & gp_right) then
        player1_paddleY = player1_paddleY + paddle_speed
    end if
    
    // quit if Select is pressed
    if (buttons & gp_select) then goto NoMore
    
    // if Start is pressed, alternate the color
    if (buttons & gp_start) and pdColor = RED then
        pdColor = BLACK
        else
        pdColor = RED
    end if
    
    // if yellow button pressed, cycle the color
    if (buttons & gp_yellow) then
        pdColor = pdColor +1
        if pdColor > 16 then 
            pdColor = 0
        end if
    end if
    
    // let the system catch up before updating the screen
    waitforvsync
    
    // draw our dot
    plot (player1_paddleY, player1_paddleX, pdColor)
    
    // go back for more
    goto Start
NoMore:
// end

The things to note are:

  • gamepad( 0 )
  • plot(x,y,color)
  • waitforvsync
  • call clear( 0 )
  • call text( x, y, text)

Call CLEAR( 0 ) clears the screen to black and Call TEXT(x,y,text) will display a string at the x,y coordinates on the screen. Simple enough. Now, for the fun stuff.

gamepad( 0 ) refers to the ‘player one’ controller while gamepad( 1 ) refers to the ‘player 2’ controller.  For our purposes today, we only have a player one controller.

PLOT (x, y, color) puts a pixel of color at the x,y coordinates.

WaitForVSync halts execution until after vertical blanking occurs. This should be done before drawing to the screen.

Most of my demo code is made up of interpreting the gamepad, so lets talk about that.

In order to interpret which button the user has pressed, we must ‘AND’ the button press with the value of the button we want to check for, so…here’s the values we need:

// Gamepad direction defines

def gp_right  = 0x01

def gp_left   = 0x02

def gp_down   = 0x04

def gp_up     = 0x08

def gp_start  = 0x10

def gp_select = 0x20

def gp_red    = 0x40

def gp_yellow = 0x80

You can copy that table into your code, near the beginning and before you check the gamepad. The ‘def’ simply tells BASIC that you are DEFining some constant values. Now, remember, you have to ‘AND’ the gamepad return value with the button value, such as:

// Check for player input

    buttons = gamepad(0)

// quit if Select is pressed

    if (buttons & gp_select) then goto NoMore

Notice, we get the current state of the gamepad using the ‘gamepad( 0 )’ function.  It’s value goes into the variable ‘buttons’. Next, we check to see if the user has pressed the SELECT button and, if so, we goto the label ‘NoMore’ and continue execution from there.  Go back and look at the demo code above. Go on, I’ll wait.

Oh, back so soon?  Ok.  Now, if you notice, we check for the directions (up, down, left, right) and the select, start, red and yellow buttons.  Each one has a purpose: the directionals, of course, will change the direction we draw, start will alternate the color, select will end the demo, red will clear the screen to black and yellow will cycle the color (which, does not currently work because of the start button functionality. I’ll fix that in another post.)

See how easy it is to interpret the gamepad?  Next time, we will take a look at some of the graphics stuff and discuss the two modes available (bitmap and tile) in XGS Basic.

XGamestation, you still there? (Answer: Yes)

xgs_pic_03Three years ago, I purchased the XGamestation XGS PIC 16-bit video game development kit.  The XGS is a small, 16-bit microcomputer with 8-bit graphics and sound. It uses the PIC-24 microcontroller for its brains. I dabbled with it for a bit and then it got put aside while I dealt with some personal issues.  Eventually, it was packed up in a box (I bought a new home) and sat for another two years.  Recently, I unearthed the board and its accessories. The software still lived on my main desktop.  Surprisingly, everything survived the move two plus years ago and, it still works.

So, now I am playing around with some lower level coding on a very unsophisticated computer. The maker, Nurve Networks (XGamestation) calls it a video game console development kit. I think that might be a bit grandiose, it’s hardly a console but it does fit the bill for development and learning. It is a nice, clean design and fairly simple.

For getting reacquainted with the board, I’ve been doing some coding in the XGS Basic, which I want to use to help teach my son how to code Atari 2600 type games.  Well, the dialect of Basic is more akin to the Tiny Basic of the 1970’s than a more modern dialect like Visual Basic. And it is such that you must write and compile on your Windows PC and then either download it to the XGS via Serial OR to an SD card to run on the board itself.  Not difficult, but an added layer of complexity.  The XGS Basic runtime lives on the board (after, of course, sending it via the PIC 2 programmer.)

After messing around a bit, I had some questions and also wanted to get a second controller, for two player gaming, so, I went to XGAMESTATION.COM.  Funny thing happened, though…the web site was pretty much exactly as it was in 2010 when I was actively coding for this thing. I was participating in the forums and communicating with the owner.  I went back to the forums and…nothing. There were just a few message boards and few messages.  Several links appeared broken or were getting redirected to a nasty page. Worse, many of the downloads were just broken links. It appeared to me that the company was no longer in business.

On a whim, I sent an email to the support.  Low and behold, I got a response almost right away.  The response was a bit defensive, I think I offended someone by pointing out a few things I thought were wrong with the site (like the broken links, intercepted link and nearly empty forums.)  Well, after a few emails, the tone changed and the support person said that they would be fixing the links (well, the intercepted one, anyway.) The inquiries about the Basic, however, were met with some not so kind remarks about it and my desire to use it as well as the email address of the guy who developed it. (Who, by the way, seems to have completely washed his hands of it and has not answered any of my questions other than to reiterate that it is XGamestation’s software, was free and that the source code is on the DVD. I detected some bitterness between the two.)

Now, I have to say, I am a bit miffed that a product that I bought with the understanding that a certain aspect of it (the XGS Basic) was promised – and heavily promoted as a feature – has been swept under the rug.  The support person suggested I’m wasting my time with it and should use the more documented and better C language. Well, OK, C is nice and they have documented the hell out of developing with C, that’s not the point.  The reason I picked the XGS over the other products was because THEY made a big deal out of ‘ease of developing with XGS Basic.’ I figured I would have some fun with writing Atari like games for my kid as well as teaching him some programming and C is so NOT the way to teach programming to someone who is not bit twiddler. And the response from the developer of XGS Basic was NOT what the support person had promised. I think I very mistakenly thought that the developer actually worked for Nurve, but, apparently, he does not and is very bitter and unhelpful. 

I was thinking I might purchase the company’s ‘Hydra’ product, which is a somewhat morehydra_sml_annotated_01 advanced version of the XGS and has an on board development piece. However, I am having second thoughts.  I have to wonder how a company can go THREE YEARS without significantly updating its sight and having a customer point out obvious flaws…well, I’m not sure I would trust them. However, the support person did share that some bigger and better things were on the way. So, maybe I will just wait.

Web presentation, in my humblest of opinions, is key here.  If I had not actually taken the time to email this company, I might have seen the ‘pre-order before Christmas’ (of 2010!) and just left. I don’t know how they have stayed in business with content that has not been updated in three years. At least change the text.  There are numerous references to months that are long gone (January in August, etc.) or years that are long gone. It really seemed like they were long gone.

As for the XGS itself, I am going to have some fun. I have an idea for a Mario style side scroller that I am going to try in XGS Basic first.  I plan to share my adventures, again, with this cool little board, so stay tuned!

NOTE: to be fair to XGamestation, I went back to the site and it looks like the issues I spoke to them about are, in fact, gone. The download links seem to work, the hijacked link is gone (but, unfortunately, the feature I was trying to use is gone) and the forums seem to be fuller, but many of the posts are still gone. The support person explained that the forums were hacked, multiple times and that’s why the content is missing. Fair enough.   And the support person did respond, very quickly and has been helpful.