Jump to content
IGNORED

Learning assembly - porting Thrust to the TI-99/4a


palmheads

Recommended Posts

Hi everyone

 

Just thought I'd post a wee update on my progress of porting 'Thrust' to the TI.

 

I got some sort of multi sprite collision detection working. Sprite rotation also.

 

Am using xdt99 & Js99'er, mini memory to load, plus various books like the Lottrup one, Editor Assembly Manual etc. Plus this amazing board!

 

Here is a small vid of progress

 

Source code below if anyone interested. Nothing spectacular at the moment, all a learning process for me

 

Will keep on working at it, and post updates to this thread. Am really enjoying the process!

 

cheers

Daryn

		aorg >a000		;starting loc for mini mem '7d00'
		lwpi >70b8		;load registers
		
		li r0,>0384
		li r1,>1100		;set background screen colour black
	   	blwp @>6024	
		
		li r0,>0420
		li r1,dataf		;sprite 0 def starting sprite
		li r2,412
		blwp @>6028
		
		li r0,>0300
		li r1,datat		;sprite 0 attr
		li r2,21
		blwp @>6028

		li r0,>01e2		;sprite magnify 3
		
		swpb r0			;once interupts enabled, need this
		movb r0,@>83d4		;and this because kscan is used
		swpb r0			;and this, because r1 is used
		blwp @>6034

		clr @>8374		;clearing for keyscan
		li r7,>0000		;record where sprite is
		li r13,00

loop		limi 2	
		limi 0

		bl @keyscan		;keyscan

		li r9,0
		bl @collsp

updatat		li r0,>0302		;rotate through sprites
		mov r13,r1
		sla r1,2
		ai r1,>84
		swpb r1
		li r2,2			;send 2 bytes
		blwp @>6024		;write bytes back 
		jgt loop

rotl		inc r13
		andi r13,7
		li r15,8000		;needed time delay
		dec r15			;for sprite rotation
		jne $-2
		jeq updatat

rotr		dec r13
		andi r13,7
		li r15,8000		;needed time delay
		dec r15			;for sprite rotation
		jne $-2
		jeq updatat


coll		swpb r8			;test thrust sprite about to collide
		swpb r10
		s r10,r8		;subtract registes
		abs r8			;absolute value
		ci r8,>000e		;compare with 0e
		b *11

collsp		inc r9			;check next sprite
		
		ci r9,>0005		;one more than num sprites on screen. find way of
					;counting this
		jeq loop		;start game loop again

		clr r8			;look at sprite attr table
		clr r10			;increments of 4
		mov r9,r5		;get next incr of r4/r5
		sla r5,2		;r5 being sprite # 1,2 etc
		li r0,>0300		;vdp 304 - 308
		a r5,r0			
		blwp @>602c
		movb r1,r10
		movb r14,r8
		bl @coll
		jgt collsp 		;not hitting, check next sprite

					;possible collision, check row
		clr r8			
		clr r10
		inc r0			;vdp 305 - 309 range
		blwp @>602c
		movb r1,r10
		movb r7,r8
		bl @coll
		jgt loop
					;got a collision here!
hit		li r0,>0302
		li r1,>a800		;char code of collision sprite
		blwp @>6024		;write bytes back 
		li r15,10000		;needed time delay
		dec r15			;for sprite rotation
		jne $-2
		b @>a000

keyscan		blwp @>6020		;keyscan
		clr r3
		mov @>8374,r3		;ascii key to r3
		
		li r0,>0300		;move along col
		clr r14			;prepare r7 for row value
		blwp @>602c		;read col value
		swpb r1
		movb r1,r14

					;up and down keys
		ci r3,69		;e key
		jne $+10
		ai r1,->0100		;move up
		blwp @>6024		;write to sprite attr
		ci r3,88		;x key
		jne $+10
		ai r1,>0100		;move down
		blwp @>6024		;write to sprite attr

		li r0,>0301		;move along row
		clr r7			;prepare r7 for row value
		blwp @>602c		;read row value
		movb r1,r7		;move to left byte of r1


					;left and right keys
		ci r3,83		;s key
		jne $+10
		ai r1,->0100		;move left
		blwp @>6024		;write to sprite attr
		ci r3,68		;d key
		jne $+10
		ai r1,>0100		;move right
		blwp @>6024		;write to sprite attr
		
					;rotate keys
		ci r3,90		;z key - rotate
		jne $+8
		jeq rotl
		blwp @>6024		;write to sprite attr
		ci r3,67		;c key - rotate
		jne $+8
		jeq rotr
		blwp @>6024		;write to sprite attr

delay		li r15,500		;needed time delay
		dec r15			;for sprite movement
		jne $-2
		b *11

dataf		data >0102,>0204,>0408,>0810	;sprite 0 - 4 cnrs
		data >1060,>8040,>2023,>1408	;main thrust sprite
		data >0080,>8040,>4020,>2010
		data >100c,>0204,>0888,>5020

		data >3028,>2423,>2020,>2020	;top left
		data >2020,>4080,>4132,>0a04
		data >0000,>0000,>8040,>3804
		data >0408,>0810,>d020,>0000

		data >0000,>0000,>0106,>1860	;left
		data >8060,>1806,>0100,>0000
		data >0020,>504c,>8201,>0204
		data >0404,>0201,>824c,>5020
		
		data >0000,>0102,>0202,>0408	;bottom left
		data >1010,>2040,>80ff,>0000
		data >0000,>8060,>1804,>0808
		data >0806,>0102,>04c4,>2810
		
		data >040a,>1110,>2040,>3008
		data >0804,>0402,>0201,>0100	;sprite 1
		data >1028,>c404,>0201,>0608	;reverse main sprite
		data >0810,>1020,>2040,>4080
		
		data >0000,>040b,>0810,>1020	;bottom right
		data >201c,>0201,>0000,>0000
		data >2050,>4c82,>0102,>0404
		data >0404,>0404,>c424,>140c
		
		data >040a,>3241,>8040,>2020	;right
		data >2040,>8041,>320a,>0400
		data >0000,>0080,>6018,>0601
		data >0618,>6080,>0000,>0000
		
		data >0000,>0000,>0102,>1c20	;top right
		data >2010,>1008,>0b04,>0000
		data >0c14,>24c4,>0404,>0404
		data >0404,>0201,>824c,>5020

		data >0007,>1820,>4040,>8080	;reactor
		data >8040,>4020,>ff80,>b0b0
		data >0c80,>6e1a,>0a0a,>0b0b
		data >0b0b,>0a0a,>fb01,>0101

		data >8163,>7f3f,>222e,>6ee6	;ship collision
		data >ee6e,>2e22,>3f7f,>6381
		data >81c6,>fefc,>d4d4,>b677
		data >77b6,>dcd4,>fcfe,>c681
		
		data >0000,>0000,>1966,>81f8	;gun turret
		data >0700,>0000,>0000,>0000
		data >0000,>0000,>c030,>8864
		data >1cc6,>3109,>0905,>0503
		
		data >1f60,>80b5,>a5b5,>a5a7	;fuel
		data >8080,>8080,>8080,>8080
		data >f806,>0169,>4969,>496d
		data >0101,>0101,>0101,>0101

		data >0000,>0000,>030c,>1126	;gun turret 2
		data >3863,>8c90,>90a0,>a0c0
		data >0000,>0000,>9866,>811f
		data >e000,>0000,>0000,>0000
		
datat		data >0000,>840a	;thrust ship
		data >5030,>a404	;reactor
		data >7080,>ac0d	;turret
		data >1010,>b007	;fuel
		data >9080,>b40d	;turret
		data >d000			 

		aorg >701c
		data >7d1e
		data >7fe0
		aorg >7fe0
		text 'COLLIM'		;name of program
		data >a000		;starting location
		end
  • Like 9
Link to comment
Share on other sites

Another Thrust port to a classic machine! :thumbsup:

 

Let me know if you need any information about game details. Probably I can help.

 

I suspect you would know something about porting thrust to a classic system....the famous Atari 2600 port! Amazing job! :)

 

Am sure as I get further into this project I'm gonna face stuff where I have no idea what todo!

 

Thank you so much for offering assistance - am smiling typing that!

 

cheers

Daryn

Link to comment
Share on other sites

Marvelous !!! :thumbsup:

 

And I've got to say I love your use of lowercase and semicolons for comments - have to look at it twice not to confuse it with my own code.

 

I'm beginning to have the labels on separate lines (no code) to more easily insert code and move blocks around - with or without the label.

 

 

 

Yeah that is an issue for sure with putting the comments the way I am. Am using vim on my ubuntu laptop to write code, so I can do block copy/moves, which helps to a certain extent.

 

Thanks for the encouragement. All a learning process at the moment, but loads of fun trying.

 

cheers

Daryn

Link to comment
Share on other sites

Nice start--and you're teaching me some here too, as sooner or later I'll actually learn Assembly! :)

 

Helps having good examples to get you started, thats for sure. Thats why I intend just having my source code available to look at. Am no doubt doing things in an inefficient way with the code, but the hardest thing is getting started half the time. And that includes the dev environment you choose.

 

cheers

Daryn

Link to comment
Share on other sites

Am currently working on getting main thrust sprite move in the direction the sprite is pointing (a la asteriods, thrust itself). So moving diagonally etc

 

Reckon I know what todo as well! Will try this weekend to get it going!

 

cheers

Daryn

  • Like 1
Link to comment
Share on other sites

Am currently working on getting main thrust sprite move in the direction the sprite is pointing (a la asteriods, thrust itself). So moving diagonally etc

 

Reckon I know what todo as well! Will try this weekend to get it going!

 

cheers

Daryn

 

I got this to (kinda) work in the weekend. However it looks ghastly (sprite jumping all over the show) so needs more work! ha

 

So no vid until it doesn't make your eyes bleed

 

cheers

Daryn

Link to comment
Share on other sites

One cool thing I've found is, with using xdt99 to compile an object I can then add to a disk image, then upload that disk image too js99'er for testing. Because I'm using the mini memory module to load object from DSK1, and because I'm actually starting my code at A000 so I using the 32k console ram (so not actually using the mini memory from 7d00), using DISK2 I can actually have the line by line assembler just sitting there as well. Its been quite handy if I want to see how many bytes to jump ahead with a JNE or something. I can enter the snippet of code (generally only 5-10 lines), & then I can actually see how many bytes from start to end of the code (as the LBLA assembles each line, it tells you how many bytes its jumped ahead for each statement).

 

cheers

Daryn

  • Like 1
Link to comment
Share on other sites

Hi!

 

OK, got sprite rotation working with moving sprite where its pointing (ie diagional movements, up/down, sideways etc)

 

Very much like Thrust & Asteroids etc

 

Here is a vid:

 

Next step, think I might get some sort of 'wall' collision working. Am not sure how this works. I assume the side of a 'wall' aren't sprites. I'd imagine its some sort of character/screen definition you define, and a "collision" is where you hit some sort of screen limit? Is that correct? Am not sure, will have todo some research.

 

If anyone wants to also have a play, here is my code so far

		aorg >a000		;starting loc for mini mem '7d00'
		lwpi >70b8		;load registers
		
		li r0,>0384
		li r1,>1100		;set background screen colour black
	   	blwp @>6024	
		
		li r0,>0420
		li r1,dataf		;sprite 0 def starting sprite
		li r2,412
		blwp @>6028
		
		li r0,>0300
		li r1,datat		;sprite 0 attr
		li r2,21
		blwp @>6028

		li r0,>01e2		;sprite magnify 3
		
		swpb r0			;once interupts enabled, need this
		movb r0,@>83d4		;and this because kscan is used
		swpb r0			;and this, because r1 is used
		blwp @>6034

		clr @>8374		;clearing for keyscan
		li r7,>0000		;record where sprite is
		li r13,00

loop		limi 2	
		limi 0

		bl @keyscan		;keyscan

updatat		li r0,>0302		;rotate through sprites
		mov r13,r1
		sla r1,2
		ai r1,>84
		swpb r1
		li r2,2			;send 2 bytes
		blwp @>6024		;write bytes back 
		jgt loop

rotl		inc r13
		andi r13,7
		li r15,8000		;needed time delay
		dec r15			;for sprite rotation
		jne $-2
		jeq updatat

rotr		dec r13
		andi r13,7
		li r15,8000		;needed time delay
		dec r15			;for sprite rotation
		jne $-2
		jeq updatat

coll		swpb r8			;test thrust sprite about to collide
		swpb r10
		s r10,r8		;subtract registes
		abs r8			;absolute value
		ci r8,>000e		;compare with 0e
		b *11

collsp		inc r9			;check next sprite
		
		ci r9,>0005		;one more than num sprites on screen. find way of
					;counting this
		jeq loop		;start game loop again

		clr r8			;look at sprite attr table
		clr r10			;increments of 4
		mov r9,r5		;get next incr of r4/r5
		sla r5,2		;r5 being sprite # 1,2 etc
		li r0,>0300		;vdp 304 - 308
		a r5,r0			
		blwp @>602c
		movb r1,r10
		movb r14,r8
		bl @coll
		jgt collsp 		;not hitting, check next sprite

					;possible collision, check row
		clr r8			
		clr r10
		inc r0			;vdp 305 - 309 range
		blwp @>602c
		movb r1,r10
		movb r7,r8
		bl @coll
		jgt loop

					;got a collision here!
hit		li r0,>0302
		li r1,>a800		;char code of collision sprite
		blwp @>6024		;write bytes back 
		li r15,10000		;needed time delay
		dec r15			;for sprite rotation
		jne $-2
		b @>a000		;reset game - back to start

keyscan		blwp @>6020		;keyscan
		clr r3
		mov @>8374,r3	;ascii key to r3
	
		ci r3,69		;e key
		jne $+42
		li r0,>0300		;move along col
		clr r14			;prepare r7 for row value
		blwp @>602c		;read row value
		movb r1,r14
		bl @thrustc
		blwp @>6024		;write to sprite attr

	
		li r0,>0301		;move along col
		clr r7			;prepare r7 for row value
		blwp @>602c		;read row value
		movb r1,r7		;move to left byte of r1
		bl @thrustr
		blwp @>6024		;write to sprite attr

					;rotate keys
		ci r3,90		;z key - rotate
		jne $+4
		jeq rotl
		
		ci r3,67		;c key - rotate
		jne $+4
		jeq rotr

delay		li r15,500		;needed time delay
		dec r15			;for sprite movement
		jne $-2

		li r9,0
		bl @collsp
		;b *11			;back to loop
						
					;different points of rotation
					;mean different pixel movements
thrustc 	ci r13,0
		jne $+6
		ai r1,->0100	
		
		ci r13,1
		jne $+6
		ai r1,->0100
		
		ci r13,2
		jne $+6
		ai r1,>0000	
		
		ci r13,3
		jne $+6
		ai r1,>0100
		
		ci r13,4
		jne $+6
		ai r1,>0100
		
		ci r13,5
		jne $+6
		ai r1,>0100
		
		ci r13,6
		jne $+6
		ai r1,>0000	
		
		ci r13,7
		jne $+6
		ai r1,->0100

		b *11
		
thrustr 	ci r13,0
		jne $+6
		ai r1,>0000	
		
		ci r13,1
		jne $+6
		ai r1,->0100
		
		ci r13,2
		jne $+6
		ai r1,->0100
		
		ci r13,3
		jne $+6
		ai r1,->0100
		
		ci r13,4
		jne $+6
		ai r1,>0000	
		
		ci r13,5
		jne $+6
		ai r1,>0100
		
		ci r13,6
		jne $+6
		ai r1,>0100
		
		ci r13,7
		jne $+6
		ai r1,>0100
		
		b *11

dataf		data >0102,>0204,>0408,>0810	;sprite 0 - 4 cnrs
		data >1060,>8040,>2023,>1408	;main thrust sprite
		data >0080,>8040,>4020,>2010
		data >100c,>0204,>0888,>5020

		data >3028,>2423,>2020,>2020	;top left
		data >2020,>4080,>4132,>0a04
		data >0000,>0000,>8040,>3804
		data >0408,>0810,>d020,>0000

		data >0000,>0000,>0106,>1860	;left
		data >8060,>1806,>0100,>0000
		data >0020,>504c,>8201,>0204
		data >0404,>0201,>824c,>5020
		
		data >0000,>0102,>0202,>0408	;bottom left
		data >1010,>2040,>80ff,>0000
		data >0000,>8060,>1804,>0808
		data >0806,>0102,>04c4,>2810
		
		data >040a,>1110,>2040,>3008
		data >0804,>0402,>0201,>0100	;sprite 1
		data >1028,>c404,>0201,>0608	;reverse main sprite
		data >0810,>1020,>2040,>4080
		
		data >0000,>040b,>0810,>1020	;bottom right
		data >201c,>0201,>0000,>0000
		data >2050,>4c82,>0102,>0404
		data >0404,>0404,>c424,>140c
		
		data >040a,>3241,>8040,>2020	;right
		data >2040,>8041,>320a,>0400
		data >0000,>0080,>6018,>0601
		data >0618,>6080,>0000,>0000
		
		data >0000,>0000,>0102,>1c20	;top right
		data >2010,>1008,>0b04,>0000
		data >0c14,>24c4,>0404,>0404
		data >0404,>0201,>824c,>5020

		data >0007,>1820,>4040,>8080	;reactor
		data >8040,>4020,>ff80,>b0b0
		data >0c80,>6e1a,>0a0a,>0b0b
		data >0b0b,>0a0a,>fb01,>0101

		data >8163,>7f3f,>222e,>6ee6	;ship collision
		data >ee6e,>2e22,>3f7f,>6381
		data >81c6,>fefc,>d4d4,>b677
		data >77b6,>dcd4,>fcfe,>c681
		
		data >0000,>0000,>1966,>81f8	;gun turret
		data >0700,>0000,>0000,>0000
		data >0000,>0000,>c030,>8864
		data >1cc6,>3109,>0905,>0503
		
		data >1f60,>80b5,>a5b5,>a5a7	;fuel
		data >8080,>8080,>8080,>8080
		data >f806,>0169,>4969,>496d
		data >0101,>0101,>0101,>0101

		data >0000,>0000,>030c,>1126	;gun turret 2
		data >3863,>8c90,>90a0,>a0c0
		data >0000,>0000,>9866,>811f
		data >e000,>0000,>0000,>0000
		
datat		data >0000,>840a	;thrust ship
		data >5030,>a404	;reactor
		data >7080,>ac0d	;turret
		data >1010,>b007	;fuel
		data >9080,>b40d	;turret
		data >d000			 

		aorg >701c
		data >7d1e
		data >7fe0
		aorg >7fe0
		text 'UPTHRU'		;name of program
		data >a000		;starting location
		end

up.asm

  • Like 1
Link to comment
Share on other sites

Are you getting collisions without actually having sprites touch or is it just the video?

 

haha - yeah...haven't optimised the sprite collision stuff. Its pretty accurate for the first sprite I put in the screen (the reactor), but for the others its more 'close enuff!'

 

I'II write something a bit better later on, just trying to get the idea of how things work at the moment.

 

cheers

Daryn

Link to comment
Share on other sites

Well it's cool and has a neat vector look. I might suggest that you check the collision bit and if it is set then do your proximity checks. Won't cost much code wise and will eliminate false hits.

 

Are you using the interrup for throttling or delays?

 

Cheers Mark! Will look into the collision stuff more soon I think. Am gonna see how todo a collision to a cavern wall next, then I'II optimise the collision stuff

 

Am using a small delay loop for the sprite movement

delay		li r15,500		;needed time delay
		dec r15			;for sprite movement
		jne $-2

 

Link to comment
Share on other sites

 

 

Cheers Mark! Will look into the collision stuff more soon I think. Am gonna see how todo a collision to a cavern wall next, then I'II optimise the collision stuff

 

Am using a small delay loop for the sprite movement

delay		li r15,500		;needed time delay
		dec r15			;for sprite movement
		jne $-2

 

 

 

 

I encourage you to look at the VDP status register and more acutely the sprite collision bit. You seem to be doing a proximity check which is perfect for squares but falls short for shaped sprites. The collision bit will tell you if one sprite is touching another sprite on a pixel bases. Check for this condition and if it is true then do the proximity check.

 

This will ensure that two sprites are visually touching before you spring your whammy.

 

I also encourage you to research framing your timing via the VDP interrupt. Will simplify your game programming experience.

 

Looks good so far. Keep plugging along, this will end up being pretty cool.

 

Thanks for taking the time and putting in the effort.

  • Like 1
Link to comment
Share on other sites

 

 

I encourage you to look at the VDP status register and more acutely the sprite collision bit. You seem to be doing a proximity check which is perfect for squares but falls short for shaped sprites. The collision bit will tell you if one sprite is touching another sprite on a pixel bases. Check for this condition and if it is true then do the proximity check.

 

This will ensure that two sprites are visually touching before you spring your whammy.

 

I also encourage you to research framing your timing via the VDP interrupt. Will simplify your game programming experience.

 

Looks good so far. Keep plugging along, this will end up being pretty cool.

 

Thanks for taking the time and putting in the effort.

 

Sounds like a plan! Will do some investigations, and see whats involved.

 

cheers

Daryn

Link to comment
Share on other sites

Hi all

 

Think I've found info about the VDP status register, & particular the collision bit. Actually not easy to find info about it.

 

http://www.unige.ch/medecine/nouspikel/ti99/tms9918a.htm

 

 

Maybe a typo below (should be Bit 2)

 

"...Bit 1 (weight >20) is the coincidence bit. It is set when two sprites or more have at least one overlapping "on" pixel. This occurs even if the sprite color is transparent. Note that coincidence is checked only every 1/60th of second (1/50th of a second for the TMS9929A), thus if you change sprite positions during that time a coincidence could be missed."

 

Just gotta figure out now how to read it

 

cheers

Daryn

Edited by palmheads
Link to comment
Share on other sites

Hi all

 

Think I've found info about the VDP status register, & particular the collision bit. Actually not easy to find info about it.

 

http://www.unige.ch/medecine/nouspikel/ti99/tms9918a.htm

 

 

Maybe a typo below (should be Bit 2)

 

"...Bit 1 (weight >20) is the coincidence bit. It is set when two sprites or more have at least one overlapping "on" pixel. This occurs even if the sprite color is transparent. Note that coincidence is checked only every 1/60th of second (1/50th of a second for the TMS9929A), thus if you change sprite positions during that time a coincidence could be missed."

 

Just gotta figure out now how to read it

 

cheers

Daryn

 

Looking at Editor Assembler manual (pg 169), and the Art of Assembly PDF, it looks like an instruction call 'STST' is the one to focus on?

 

Think I am on the right track

 

cheers

Daryn

Link to comment
Share on other sites

 

Looking at Editor Assembler manual (pg 169), and the Art of Assembly PDF, it looks like an instruction call 'STST' is the one to focus on?

 

Think I am on the right track

 

cheers

Daryn

 

I think I found it!

*------------------------------------------------------------
* VDP read status. Result will be in R0 MSB
*------------------------------------------------------------
VRDSTA MOV  @>8802,R0    Read status register, resets bits 0-2.
       B    *R11         Delay

Seem to work!! WOO!

 

cheers

Daryn

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...