Jump to content
IGNORED

TI Basic + sprite games


ramidavis

Recommended Posts

Here is a program called FASTINIT that works with Morphy, at least in Win994a with a cassette. This initializer is set to give the normal size sprite used in Morphy, and sets the memory pointers to not reserve the disk buffer space.

Load this and save to cassette, then load morphy and save to cassette.

FASTINIT.ZIP

  • Like 1
Link to comment
Share on other sites

So to Casey, put that video back up please! I take exactly zero offense if you omitted my name.

(Now if there are sales involved, that is another story!)

I will re-upload the video. The URL may change, so if it does, I will make sure the proper link is included. (And no, I'm not planning on selling anything! :) )

 

I'm actually fascinated by the technique, though I don't understand it a bit (I just don't have the knowledge to know what it is doing). But it makes me wonder if something like this has been known in the days when TI BASIC programs were included in magazines like COMPUTE!, would we have seen it exploited to produce more interesting games? COMPUTE!'s TI Collection Vol 2 has a series of programs where they were able to figure out the object code format so you didn't need Editor/Assembler to use them. Seems like maybe this technique could have been used as well for some interesting programs with not much hardware required.

 

Edit: The video has been re-uploaded:

 

Edited by Casey
  • Like 3
Link to comment
Share on other sites

Earlier you said you had an idea for sprite automotion.

Anything more to share on that?

I don't think it is practical to do this. When I first mentioned it, I forgot that the sprite descriptor table has to be at v0300 for auto sprite motion to work. That is right where the color table for the screen colors resides, so that would have to be moved to character definitions above 128. Then the colors would indeterminate until you set them with a CALL CHAR which would not be simple if you cannot see the characters. But that is minor. The big problem is that when BASIC breaks, it writes D0 to v0300 which hides all the sprites, and there is no way in standard BASIC to write to this location to undo this. This is unlike the trick used by Morphy, which only works because BASIC does not reset the modified VDP registers.

  • Like 3
Link to comment
Share on other sites

Here is a program called FASTINIT that works with Morphy, at least in Win994a with a cassette. This initializer is set to give the normal size sprite used in Morphy, and sets the memory pointers to not reserve the disk buffer space.

Load this and save to cassette, then load morphy and save to cassette.

 

I can confirm is perfect working on the real computer + Morphy too :)

 

post-24673-0-21395300-1514053269.jpg

 

After 34 years, we have an updated version of the loader for have Sprite in TI BASIC :) Great Senior_Falcon

Edited by ti99iuc
  • Like 3
Link to comment
Share on other sites

This technique was too fascinating to me. I just had to do something with it :)

This works in Classic99, but it should work on console from tape/disk also (But i have not actually tried it on real hardware).

I made a tiny little "demo" of sorts.
From TI Basic, first load/(copy/paste) this program:

 

1 REM SETUP-PROGRAM
10 FOR I=1 TO 128
20 READ X
30 F$=F$&CHR$(X)
40 NEXT I
50 OPEN #1:F$
100 DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,248
110 DATA 55,215,158,200,0,255,0,0,0,0,0,159,34,0,0,0,33,111,0,0,0,0,0,0
120 DATA 32,0,33,224,42,93,3,179,216,32,131,186,131,212,215,224,131,189,215,224,131,188
130 DATA 215,224,131,191,215,224,131,190,4,224,131,196,216,32,131,187,140,0,4,91,0,0,0,0,0,0,0,0
140 DATA 226,208,133,15,71,128,53,103,0,0,131,144,0,0,33,111

 

 

RUN it, then load/(copy/paste) the following program:

 

1 REM PARSEC "SPRITE" DEMO
2 CALL CLEAR
3 CALL SCREEN(2)
9 REM SETUP CHARACTERS
10 FOR X=65 TO 79 STEP 2
11 CALL CHAR(X,"")
12 NEXT X
13 RESTORE
14 FOR X=64 TO 78 STEP 2
15 READ X$
16 CALL CHAR(X,X$)
17 NEXT X
18 FOR X=80 TO 83
19 READ X$
20 CALL CHAR(X,X$)
21 NEXT X
49 REM SETUP "SPRITES"
50 CALL CHAR(144,"5760A10F5770A50F")
51 CALL CHAR(145,"5780A90F5790AD0F")
59 REM MOVE SHIP
60 FOR X=1 TO 31
61 READ X$
62 CALL CHAR(146,X$)
63 NEXT X
64 RESTORE 913
69 REM LOOP SHIP ANIMATION
70 GOTO 60
899 REM DATA
900 DATA 007C101010101010
901 DATA 0038101010101038
903 DATA 000000007C000000
904 DATA 003844443C040830
905 DATA 003844443C040830
906 DATA 0000040810204000
907 DATA 00081828487C0808
908 DATA 003844447C444444
909 DATA 0000003E1108FF80
910 DATA 47641820FF000000
911 DATA 000000000080F038
912 DATA 9C077C8000000000
913 DATA 4900B002D0
914 DATA 4908B002D0
915 DATA 4910B002D0
916 DATA 4918B002D0
917 DATA 4920B002D0
918 DATA 4928B002D0
919 DATA 4930B002D0
920 DATA 4938B002D0
921 DATA 4940B002D0
922 DATA 4948B002D0
923 DATA 4950B002D0
924 DATA 4958B002D0
925 DATA 4960B002D0
926 DATA 4968B002D0
927 DATA 4970B002D0
928 DATA 4978B002D0
929 DATA 4980B002D0
930 DATA 4988B002D0
931 DATA 4990B002D0
932 DATA 4998B002D0
933 DATA 49A0B002D0
934 DATA 49A8B002D0
935 DATA 49B0B002D0
936 DATA 49B8B002D0
937 DATA 49C0B002D0
938 DATA 49C8B002D0
939 DATA 49D0B002D0
940 DATA 49D8B002D0
941 DATA 49E0B002D0
942 DATA 49E8B002D0
943 DATA 49F0B002D0

 

 

All graphics seen on the screen are done using senior_falcon's method.
Enjoy.

Edited by notwhoyouthink
  • Like 7
Link to comment
Share on other sites

Ignore the above post. There is a much simpler way to do it with no memory expansion required:

 

Change one line in MORPHY-MM or add to MORPHY

15 CALL PEEKV(-31473,X) (It was -153,X which does not do anything in Classic99)

 

This will load from disk and runs fine in Classic99 using RXB. This also runs from cassette with MiniMemory

 

-31473 is >850F in hexadecimal which which assembly programmers will recognize as the value that is written to >8C02 to change vdp R5 to >0F

 

You can change any VDP register with this. Remember that if you want to change VR1 you must also put the value into >83D4.

Edited by senior_falcon
  • Like 2
Link to comment
Share on other sites

post-46238-0-72796800-1514280075_thumb.png

Here is an updated version of my parsec sprite demo.

The ship and "TI-99/4A" are still sprites and rendered using senior_falcon's method, but i have added a small landscape using traditional methods, plus you get to steer the ship now with the ESDX keys (Make sure alphalock is on.)

First, run this: parsec setup.txt

Then run this (I think line 8 is a little long to paste OK, but it is only a rem line.): parsec demo.txt

Your ship will disappear if you cross the text in the middle of the screen, but will reappear when you underneath it (the "text" is actually a row of 4 sprites).

Edited by notwhoyouthink
  • Like 5
Link to comment
Share on other sites

Excuse my ignorance, but why is it not possible to combine the two steps into one?

You mean the two separate programs?

I believe the first program contains, essentially, embedded assembly code.

I don't pretend to understand it myself, but apparently this assembly code manages to reset the basic interpreter after running?

That is what it seems to me to be doing.

After running the first program you are be back at a Ti Basic Ready prompt.

No basic program left in memory after the assembly code ran, but it managed to modify some VDP registers.

Senior_falcon could explain this better i think.

Edited by notwhoyouthink
Link to comment
Share on other sites

Hi Rasmus:

There is a bug in TI BASIC when it opens a file. It doesn't want to overwrite critical parts of the scratchpad, so it checks the length of the filename. If it is greater than around 10 bytes (I forget the exact length) it issues an error message.

But 128 bytes or more is less than 10 so it loads it into the scratchpad starting at >834A. This, of course, corrupts the scratchpad but I have included enough values so it can go to the NEW routine and reinitialize the computer, with one critical difference: the modified VDP registers do not get reset. Now when you load and run a BASIC program the new registers are in effect and you can use sprites..

 

I suspect that with some clever manipulation of the stack you could continue with the next line of the BASIC program which would let you do it all from one program. But I have not yet found a way to do this.

*128 BYTE LONG STRING FOR TI BASIC TO SET UP FOR SPRITES IN ORDINARY TI BASIC
	
	AORG 10000	AORG >FF66      

*If you aorg to 10000 you can peek and print the decimal values so you know what to put into the DATA statements
*Or you can make this BASIC program: 10 OPEN #1:"129 BYTE LONG STRING" and save it. (129 bytes to put the first byte on even address)
*If you have aorg'd to >ff66 you can load the program in XB, then CALL INIT, then CALL LOAD("DSK4.SETREGS.OBJ") and the code is plugged directly
*into the string.  Then save the program, quit, get back into TI BASIC, OLD DSK4.SETREGS, RUN and test it out. 	

HX834A	DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0    

HX8370	DATA >37D7              start of disk buffers.  Is >3FFF if using cassette.
	DATA >9E80		change stack pointer to >80 points to >8380.  >216F will do a NEW
	DATA >0000
	DATA >0000
HX8378	DATA >0000   
HX837A	DATA >0000,>0000,>0000,>216F,>0000,>0000,>0000    


HX8388	DATA 0,0,0,0     	NEW sets these to >2000,>21E0,>2A5D,>03B3
	
HX8390	MOVB @>83BA,@>83D4	will set sprite magnification when a key is pressed
	MOVB @>83BD,*R15	
	MOVB @>83BC,*R15	sets VR5 to OF
	
	MOVB @>83BF,*R15
	MOVB @>83BE,*R15
	CLR @>83C4
	MOVB @>83BB,@>8C00	write >0D to v0780 to hide sprites
	
BKINT 	B *R11

HX83A4	DATA 0,0,0,0

HX83BA	DATA >E3D0	lsb is sprite magnification
HX83BC	DATA >850F 	write 0F to VR5
HX83BE	DATA >4780	write D0 to v0780

HX83C0	DATA 0			rnd seed is set by new
	DATA >0000		interrupt options (quit off, sprite motion, etc)
	DATA >8390		address of interrupt routine
	DATA 0			
	DATA 0
	
	END
Edited by senior_falcon
  • Like 7
Link to comment
Share on other sites

It sets (according to E/A manual, pp. 404-406):

 

Address Value Use

>8370 >37D7 Highest address of VDP RAM available (buffer space)

>8372 >9E LSB of data stack pointer

>8373 >80 LSB of subroutine stack pointer

>8374 >00 Keyboard number to scan

>8375 >00 ASCII key code detected

>8376 >00 Joystick Y

>8377 >00 Joystick X

>8378 >00 Random number generator

>8379 >00 VDP interrupt timer

>837A >00 Number of sprites which can be in motion

>837B >00 VDP status byte

>837C >00 GPL status byte

>837D >00 Character buffer for VDP

>837E >00 Current screen row

>837F >00 Current screen column

>8380 >216F GPL subroutine stack up to >83BF

... >00

>8390 (assembly code to set registers)

...

>83A4 >00

>83A5 >00

>83A6 >00

>83A7 >00

... ?

>83BA >E3D0 (Values plugged by assembly routine)

>83BC >850F "

>83BE >4780 "

>83C0 >00 Random number seed

>83C2 >0000

>83C4 >8390 User-defined interrupt (ISR hook)

>83C6 >00

>83C7 >00

 

The hack hooks the console ISR to point to the routine in scratch pad RAM to set up the registers needed, then exits with a B *R11. My guess is that branch jumps back into the GPL interpreter which then pulls the address >216F from the stack and branches there, which in the comments is an explicit jump into the NEW command. "TI-99/4A Intern" page 137 leads this address with the comment "Begin Basic:".

 

Un-corrupting the stack enough to make a program continue looks to be a good challenge. I suppose one would have to snapshot the scratch pad at the exact moment OPEN# is called, trace through, and manipulate the values in the stack area to fudge a continue to the next line number.

 

I am guessing you would need to restore some values to before the DSR is called to elicit the but. (Is it calling the DSR, or is the bug in GPL?)

 

Another question: pushing a value to R15 apparently pushes the value to the VDP. Where is R15 set, and does clearing the MSB of the ISR hook (CLR @>83C4) shut that hook off? (never mind, it clears the entire hook.)

  • Like 2
Link to comment
Share on other sites

Wow! All this is extremely interesting, but not practical for the more normal BASIC programmer. However, TI BASIC PLUS (TIB+) includes the full 32 sprite capability (thanks to Mark Wills) using CALL's to assembly language routines. It can be implemented using E/A, Mini Memory, or a GRAM device or a disk controller with the Myarc disk controller DSR that includes TI BASIC support. Currently the best solutions are an 80K MG GramKracker or HSGPL card, and hopefully, the FinalGROM99 will provide the ultimate solution. These three versions will allow the user to write TI BASIC programs of up to 40K and more with GROM base switching. Hopefully this is enough to "wet the appetites" of some of the would be BASIC programmers out there.

Link to comment
Share on other sites

Hmm I put out a version of RXB that switched GROMs using a second banks of GROM for EA Cart including the Editor, GPL Assembler, EA Assembler and EA support for TI Basic.

 

>9800 Any other page of GROM up to >983C

______________________________________________________________

RXB GROM 3 to 6 Editor/GPL Assember/Assembler/EA Support

REA GROM 7

 

When in REA Cart would switch GROM and load requested support routines into RAM.

Link to comment
Share on other sites

I do not remember which user on here originally made this, but it is a scrolling demo of a figure walking against a brick wall.

Just for the fun of it, i have converted it to run in TI Basic with a sprite. Just a bit slower then the XB original.

(Sorry, i really have no idea who the original poster was. It was found in some thread where people were showing off little odds and ends they had come up with.)

walking sprite in basic.txt

Edited by notwhoyouthink
  • Like 4
Link to comment
Share on other sites

I do not remember which user on here originally made this, but it is a scrolling demo of a figure walking against a brick wall.

Just for the fun of it, i have converted it to run in TI Basic with a sprite. Just a bit slower then the XB original.

(Sorry, i really have no idea who the original poster was. It was found in some thread where people were showing off little odds and ends they had come up with.)

attachicon.gifwalking sprite in basic.txt

I really think that useful programs can be developed with this technique using nothing but TI BASIC. Morphy is a good example.

 

For an encore, in the next day or so I will release a simple demo that has 3 moving sprites, using nothing but legal TI BASIC statements. (In theory you could use four if I could figure out a way to put a >DO at v0320.) Oh yes, also you can have 8x8 blocks in all 15 colors without using any character definitions!

 

I will expect to see a nice demo using this from "notwhoyouthink".

  • Like 5
Link to comment
Share on other sites

I present a little program to display all 15 colors inside of a 8 pixel by 8 pixel character area.
The CALL CHAR()'s in the program are displaying the 'period' character [CHR$(46)] at just the right places to form a 8x8 grid of colored dots.
Strobe effect used to fill in the last spot since one of the colors on the ti is not really a 'color' (transparent).
First run this:

10 FOR I=1 TO 128
20 READ X
30 F$=F$&CHR$(X)
40 NEXT I
50 OPEN #1:F$
100 DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,248
110 DATA 55,215,158,200,0,255,0,0,0,0,0,159,34,0,0,0,33,111,0,0,0,0,0,0
120 DATA 32,0,33,224,42,93,3,179,216,32,131,186,131,212,215,224,131,189,215,224,131,188
130 DATA 215,224,131,191,215,224,131,190,4,224,131,196,216,32,131,187,140,0,4,91,0,0,0,0,0,0,0,0
140 DATA 224,208,133,15,71,128,53,103,0,0,131,144,0,0,33,111

Then run this:

10 CALL CLEAR
20 CALL CHAR(144,"53778E0153798E02")
30 CALL CHAR(145,"537B8E03537D8E04")
40 CALL CHAR(146,"55778E0555798E06")
50 CALL CHAR(147,"557B8E07557D8E08")
60 CALL CHAR(148,"57778E0957798E0A")
70 CALL CHAR(149,"577B8E0B577D8E0C")
80 CALL CHAR(150,"59778E0D59798E0E")
90 CALL CHAR(151,"597B8E0FD0")
100 FOR X=1 TO 16
110 CALL SCREEN(X)
120 NEXT X
130 GOTO 100
Edited by notwhoyouthink
  • Like 1
Link to comment
Share on other sites

gallery_34177_1071_873629.gif

 

To see the demo, copy and paste the first program into TI BASIC, save if desired and then RUN. Then copy and paste the second program into TI BASIC, save if desired and RUN. You will see 3 sprites and 15 unused character sets in all 15 colors. These are available for graphics. When the program breaks you will see some colorful things going on as the sprite motion routine changes the color table. This is not a crash and you can type BYE with the expected results.
10 FOR I=1 TO 128
20 READ X
30 F$=F$&CHR$(X)
40 NEXT I
50 OPEN #1:F$
100 DATA 0,0,0,0,0,0,0,0,227,0,131,150,216,32,131,82,131,212,200,32,131,84,131,196,16,40,0,0,0,0,0,0
110 DATA 0,0,0,0,0,0,55,215,158,128,0,0,0,0,0,0,0,0,0,0,0,0,33,111,0,0,0,0,0,0,0,0,0,0,0,0,0
120 DATA 0,0,0,0,0,0,0,136,32,131,36,131,190,22,11,16,1,0,0,215,224,1,40,215,224,0,0,216,32,0,144,131
130 DATA 122,4,224,131,196,4,91,0,0,0,0,0,0,0,0,7,216,0,0,0,0,131,86,0,0,0,0

The sprite magnification can be changed in line 100 - the 227 can be a value from 224 to 227 for sprite magnifications 1-4.


90 REM    1ST SPRITE:row=44;col=44;pattern=A4-60=44;white(16)  
100 CALL COLOR(1,5,5)
110 CALL COLOR(2,5,5)
120 CALL COLOR(3,11,5)
130 CALL COLOR(4,1,16)
140 REM   2nd Sprite: row=66;col=66;pattern=a8-60=48;Magenta(14)  
150 CALL COLOR(5,7,7)
160 CALL COLOR(6,7,7)
170 CALL COLOR(7,11,9)
180 CALL COLOR(8,1,14)
190 REM    3rd Sprite:row=88;col=88;pattern=AC-60=4C;dark red(7)early clock on(9) 
200 CALL COLOR(9,9,9)
210 CALL COLOR(10,9,9)
220 CALL COLOR(11,11,13)
230 CALL COLOR(12,9,7)
240 REM  4th Sprite: row=>D0 to hide higher sprites 
250 CALL COLOR(13,14,1)
260 REM  
270 CALL CHAR(144,"02000000F4")
280 CALL CHAR(145,"F5000000F6")
290 CALL CHAR(146,"0503000007F9")
300 CALL CHAR(147,"FCF4")
310 CALL CHAR(152,"1122334455667788")
320 CALL CHAR(153,"99AABBCCDDEEFF10")
330 CALL CHAR(154,"1010101010101010")
340 CALL CHAR(155,"1010101010101010")
350 CALL SOUND(600,110,30)
360 CALL SOUND(10,110,30)
365 CALL CHAR(144,"0")
370 CALL CHAR(145,"0")
380 FOR I=0 TO 255
390 PRINT CHR$(I);
400 NEXT I
410 GOTO 410

Here is a method that gives you up to 3 moving sprites using standard TI BASIC, using nothing but BASIC statements. It is similar to the earlier method that offers 32 sprites but no sprite motion. The challenge in making this work is that if you want to use automatic sprite motion the sprite attribute list must start at v0300. The only way TI BASIC can modify those memory locations is via CALL COLOR. In the color table, the first four sprite definitions cannot be accessed but sprites 5-8 can be. So there will be 8 sprites in all; the first 4 are invisible, the next 3 can move automatically, and the last one has its row set to >D0 to hide the remaining sprites.
Four character definitions from 144 to 147 are used for the sprite motion table. Since the program is using the color table for sprites then there has to be a new color table. I put it so it can be modified by changing the character definitions from 152 to 155.
As with the previous program that gives you 32 sprites, this one exploits a bug in OPEN that allows 128 bytes to be loaded into the scratchpad. Moving the color table by resetting VDP R3 to >1F is easy enough, but it reverts to the default value when you force a NEW. To get around that, the program sets up an interrupt routine that waits in the background. You can load a program and change it if desired. When you run the program it continues waiting until the program does a CALL CHAR(155,...) at which point it sets VDP R3 to use the new color table and enables motion for 7 sprites. This gives you a chance to set up the sprites and sprite motions in advance.
The second program above is an example showing how to set up the sprites and I will also give a short description below.
-----------------------------------------------------------------
CALL COLOR is used to define a sprite.
Sprite 1 is defined with COLOR 1-4
Sprite 2 is defined with COLOR 5-8
Sprite 3 is defined with COLOR 9-12
Sprite 4 is defined with COLOR 13-17 and should have a row of >D0 to hide all higher sprites
You have to think in hexadecimal for this. For row and column add 1 to each nybble. For Sprite #1
For a row of >83 it should be CALL COLOR(1,9,4)
For a row of >AB it should be CALL COLOR(1,11,12)
For a column of >83 it should be CALL COLOR(2,9,4)
To set the pattern to use, add 7 to the first nybble and 1 to the second.
To use the pattern for “A” (>41) it should be CALL COLOR(3,11,2)
To set the color of the sprite use the normal color value for BASIC. The first nybble should be 1 if you do not want to use the “early clock” or 9 if you want to set the early clock.
To set the color to white (16) it should be CALL COLOR(4,1,16)
To set the color to dark red with early clock on it should be (CALL COLOR(4,9,7)
-------------------------------------------------------------------
CALL CHAR 144 to 147 are used to set the sprite velocities.
I suggest using CALL CHAR(144,”02000000F4”) and CALL CHAR(145,”F4000000F6”)
Sprite motion is activated when you CALL CHAR(155,...) and you should follow that with CALL SOUND(600,110,30) and CALL CHAR(144,”0”) and CALL CHAR(145,”0”). This moves the 4 invisible sprites off the screen and stops them. This avoids having over 4 sprites on a line.
Now for the sprites we care about:
CALL CHAR(146,”0503000007F9”) sets sprite 1 to row velocity=5 and col velocity=3.
Sprite 2 has row velocity=7 and col velocity=-7
CALL CHAR(147,”FCF4”) sets sprite 3 row velocity=-4 and col velocity=-12
(If the row velocity is positive then motion is downward and if the column velocity is positive then motion is to the right.)
The new color table is set with CALL CHAR 152-155
I recommend using the values that are in the demo:
310 CALL CHAR(152,"1122334455667788")
320 CALL CHAR(153,"99AABBCCDDEEFF10")
330 CALL CHAR(154,"1010101010101010")
340 CALL CHAR(155,"1010101010101010")
The relocated color table lets you define the colors of all 256 characters. The unused characters from 0 to 23 and 160 to 255 can have their foreground and background colors set to the same color and that gives you an 8x8 block of all possible colors without using any of the normal characters. You can display these on the screen with HCHAR and VCHAR.
The first character of each character set is:
160 Black
168 Medium Green
176 Light Green
184 Dark Blue
192 Light Blue
200 Dark Red
208 Cyan
216 Medium Red
224 Light Red
232 Dark Yellow
240 Light Yellow
248 Dark Green
0 Magenta
8 Gray
16 White
When programming, do not use characters 144 - 147 or 152 – 155 for graphics because they are needed by the sprite routines.
Edited by senior_falcon
  • Like 8
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...