Jump to content
IGNORED

ASM or bBasic?


Recommended Posts

but, what does it have to do with the question of ASM or BASIC?

It shows, what you can accomplish in ASM, but not in bBasic. :P

 

However, it also shows that mere mortals cannot comprehend ASM. As a starting place BASIC lets you get familiar with coding. It also gives you a little instant gratification in getting a workable game up and running faster (for the novice). Finally, the ability to use inline assembly lets you ease into low level programming.

 

Clever ASM may look sexy, but when the beginner realizes he can't comprehend much less reproduce the result..

Edited by theloon
Link to comment
Share on other sites

It works!!

 

I've successfully gotten a routine running. I laid out graphics for digits 0-8 from $FE00 to $FE4B, and graphics for digit 9 & letters A-H from $FE4C to $FE97. You can add more very easily. I was too tired to do this for the demo, but you will get the idea. I am only doing a loop of 8 scanlines in height, but you can do more. I layed it out as bunch of equates to make it easier to read. I'll see what you guys think. Macro's would be a good idea as well as a command line utility as Spiceware suggested.

 

This saves 4 cycles, and a zero page ram location over a regular 48 bit display.

 

In the demo the top numbers are generated by a standard 48 bit display, and the bottom numbers are done by the faster (uses less cycles) 48 bit routine.

 

Very cool trick with the timer!

 

I thought a bit more of what you said in post #41 about using PLA and tried a variant that places the loop counter sequence in the stack. Instead of doing

 

 dec	loopCount
 ldy	loopCount

 

it uses

 

 pla
 tay

 

to restore the loop counter in Y. This only saves 2 cycles and requires 8 bytes in the zero page to store the counter sequence. On the plus side it works with the usual 7,...,0 sequence which may be required for some use case.

 

I took the liberty to add this variant to your example code. It's labeled ".loopMedium48bit".

 

post-27536-0-40910900-1337276400_thumb.png

testTIM8T_2.asm

Link to comment
Share on other sites

Watching two seasoned programmers figure things out is a privilege and genuinely interesting.. but, what does it have to do with the question of ASM or BASIC?

Nothing. An artist never knows when or where inspiration will strike, but knows it's best to take advantage of it when it does :)

 

I'll forgive both of them if they make this a bB minikernel! :P

While I won't be doing it, I have no problem with somebody else taking my routines and incorporating them into bB.

Link to comment
Share on other sites

Very cool trick with the timer!

 

I thought a bit more of what you said in post #41 about using PLA and tried a variant that places the loop counter sequence in the stack. Instead of doing

 

 dec	loopCount
 ldy	loopCount

 

it uses

 

 pla
 tay

Nice! I was thinking today about using a PHA to store the temp ram for digit 6, and then having the stack naturally decrement. I was trying to use LDA absolute,X and LDY absolute,X addressing. I forgot that tsx doesn't affect any flags though, so no looping off it, and loading the temp digit was a problem. Nothing I tried worked well so far.

 

 

You can always do something like this to loop:

TSX

DEX

TXS

 

 

I built a demo off of Eckhards 48 bit display (that you could move around) a few years ago. It scrolled the text in 4 directions as well as scrolled colors. The 48 bit display portion went something like this:

 

;each loop takes one scanline, but the exact cycle the
;loop starts on varies with the sprite positioning...


.loopDrawGfx
tsx						 ;2  @2
dex						 ;2  @4	 stack pointer holds the line color
txs						 ;2  @6
ldy	tempZero			 ;3  @9
lda	rgSix,Y			  ;4  @13	6th byte
sta	tempOne			  ;3  @16
lda	rgOne,Y			  ;4  @20	1st byte
sta	GRP0				 ;3  @23
lda	(displayPtrs),Y	  ;5  @28	2nd byte
sta	GRP1				 ;3  @31
lda	(displayPtrs+2),Y	;5  @36	3rd byte
sta	GRP0				 ;3  @39
stx	COLUP0			   ;3  @42
stx	COLUP1			   ;3  @45
lda	rgFour,Y			 ;4  @49	4th byte
ldx	rgFive,Y			 ;4  @53	5th byte
ldy	tempOne			  ;3  @56
sta	GRP1				 ;3  @59
stx	GRP0				 ;3  @62
sty	GRP1				 ;3  @65
sta	GRP0				 ;3  @68
dec	tempZero			 ;5  @73
bpl	.loopDrawGfx		 ;2³ @75/76

 

I was updating both player colors because the display moved around, and it was simpler this way then trying to figure out how to use the playfield or background for coloring.

 

 

While I won't be doing it, I have no problem with somebody else taking my routines and incorporating them into bB.

 

I feel the same way. If I didn't want people using my stuff I wouldn't post at all. As it is, the community here for the most part is very open and we like to share our ideas. Great things come out of it! :)

Link to comment
Share on other sites

I had it wrong. There are actually 3 bits in SWCHB that are free, not just two.

 

 

post-7074-0-08411900-1337353773_thumb.png

 

 

To use them do this once in your code to adjust the DDR register:

 

 

lda #$34 ; 0011 0100 output on pins D5, D4, and D2

sta SWBCNT ; (1's set individual DDR bits to output, and 0's are for input)

 

Then you can read and write to SWCHB like a normal register.

 

 

The writes only affect pins you set to one. If you don't use some of the switches in your program (like the player difficulties) then you can make them 1's as well. Here is an old demo I did where I wrote and read to the unused pins in SWCHB.

 

 

TestSWCHB(rev1.1).zip

  • Like 1
Link to comment
Share on other sites

Omegamatrix,

 

looking at your reset-ram code from #39, it took me several minutes to figure out, why the code has to be this way.

 

Seeing your code at #60, I thought that you're one guy who fights for every byte.

 

Now I've learned, I'm wrong: you're fighting for every bit.

 

Respect! ;)

Link to comment
Share on other sites

And for all you ram minimalists, here is a demo for using TIM1T as a temporary storage. This program uses no ram, and yet it is doing looped 48 bit displays. :) 128 bytes of zero page ram free and never used. Enjoy!!

Cool, I can't wait for games that don't use RAM 8)

Link to comment
Share on other sites

A game that uses no ram is possible. To be fair I would say no zero page ram, but anything on the stock 2600 is fair game. That leaves you with a lot of resources:

 

Accumulator ( has to be used )

X register

Y register

Stack pointer

Timer ( all modes )

SWCHB ( up to eight bits available )

Interrupt bit in the status register

All collisions ( 15 bits )

REFP0, and REFP1 ( 1 bit each )

The GRPx registers, ENxx registers, and so and so on.

 

The idea with all these extra registers are simple. Imagine a game with a man running and jumping over a single Playfield block that appears at random. Keep the man (drawn by grp0) in the center of the screen, and position grp1 to the left or right of him on the side of the screen opposite the moving block. Make grp1 the same color as the background and it is hidden. After the screen is drawn test grp1 by deliberately positioning it on top of of an object and read the collision registers.

 

You could also just write a kernel that never has a collision and set manual collisions in the blanking part of the screen. Instant data storage. With redpx keep to sets of gfx, and manually keep the player orientated the same, and again test refpx off screen the same way, position objects during blanking time, read the collisions, and you know what bits have been set in refpx. Lots of registers could be extended the same way as a roundabout for data storage.

Link to comment
Share on other sites

I was thinking more about TIM64T today, and I found a way to make it work as a loop counter. :)

 

 

It requires the user to read the timer, and then store the value read back in. It takes the same amount of cycles as a regular 48 bit loop, but you save a temporary ram location, and you can ultimately leave the loop 4 cycles sooner, which might be good for tight coding. You do add 4 more cycles coming in though...

 

There is no special arrangement of ram, and you can have a counter value $00-$FF. As soon as you load the timer it immediately decrements, so you just have to make sure you store and load at the right times. If you wait to long you have a timer that decrements by 2, which could also be useful in the right situation. I ran a small test program that displays nothing. You just let it run and open Stella's debugger to see the values the timer had.

 

 

post-7074-0-63570600-1337389197_thumb.png

 

testTIM64T.zip

  • Like 1
Link to comment
Share on other sites

The writes only affect pins you set to one. If you don't use some of the switches in your program (like the player difficulties) then you can make them 1's as well.

Actually you can use the entire SWCHB register to store data and still being able to read all of the switches. You can store a value into the Data Register no matter how the bits are configured in the Data Direction Register (SWBCNT) and the value will be preserved even on subsequent changes to the DDR. You only need to set the bits to output when you need to read back the value you stored, or when using instructions that needs to read/modify/write data.

 

So you can store a value to SWCHB, set the port to input, read the switches, set the port to output and read back the value you stored before.

Note that this only works on port B, while port A value (SWCHA) may be affected by the controllers connected to the console even when the pins are set to output.

  • Like 1
Link to comment
Share on other sites

So you can store a value to SWCHB, set the port to input, read the switches, set the port to output and read back the value you stored before.

Note that this only works on port B, while port A value (SWCHA) may be affected by the controllers connected to the console even when the pins are set to output.

 

 

That is amazing! So you have an extra register available at all times. 8)

 

You are right about Port A. I remember testing it before with the joystick and it did affect the value.

Link to comment
Share on other sites

If you don't use some of the switches in your program (like the player difficulties) then you can make them 1's as well.

 

Personally I wouldn't recommend making any bit that is connected to an external switch into an output. Lets say you make a difficulty switch port bit into an output. If that difficulty switch is in the B position it will connect the corresponding RIOT pin directly to ground (for as long as its in the B position). If your code sets the difficulty port data register bit to a "1" then that pin on RIOT will try and drive a logic high straight into the ground plane (GND) because the switch is a permanent short circuit. This isn't good for RIOT and is best avoided.

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