Jump to content

bogax

Members
  • Posts

    942
  • Joined

  • Last visited

Everything posted by bogax

  1. depends on what you're trying to do this is probably what you want
  2. This is all pretty basic Go read some stuff Memory is like a bunch of little boxes or slots with coins in them The coins can be heads or tails If it's heads it's a 1 if it's tails it's a 0 The boxes are numbered (the number is its address) and you refer to a particular box by its number Being restricted to values of 0, 1 isn't very convenient so the boxes hold groups of coins (call them bits) In the 2600 processor the groups are 8 bits each bit has two possible values 0,1 so the total possibilities for the group are 2**8 or 256 or 0..255 (that's where the 0..255 for a variable comes from) Go read about binary numbers The groups are ordered and individual bits are refered to by a number. You could call it the bit address The bits correspond between groups, bit 0 in this group corresponds to bit 0 in that group, b1 to b1, b2 to b2 etc Each bit can have (will usually have) a particular meaning/signifigance depending on its "position" (number, bit address, whatever) We generally refer to the group of eight bits as a byte. If I say a = b the processor looks at bit 0 in b and sets bit 0 in a to be the same. If it's coins, if coin 0 in b is tails then coin 0 in a gets set to tails if b0 is heads a0 gets set to heads Likewise for the other bits in the group/byte So in effect b is copied to a Actually, the processor has a special box in it, the accumulator, that it uses for temporary stuff and what actually happens is b gets copied to the accumulator and then the accumulator is copied to a a and b are just names for the box numbers (the addresses) It happens that a, b, c have a sequence, an order (alphabetical) and the addresses have an order (numerical order) bB is set up so they correspond if you index a variable a = a[3] it takes a as corresponding to index 0 and adds 3 (a is an address, a name for a location where a number is stored) so a[0] is a and a[3] and d are two different ways of refering to the same location I could impliment a stack in bB as dim stack_pointer = s ; makes stack_pointer another name for location s dim stack = a s = 0 push_z stack_pointer = stack_pointer + 1 : stack[stack_pointer] = z pull_z z = stack[stack_pointer] : stack_pointer = stack_pointer - 1 of course you don't want a dedicated routine for each variable, you'd have a macro or a function that took z as a parameter so it might be push z pull z The stack is a way of squeezing access to a bunch of locations into a single location Go read about stacks I'm not very familiar with DPC+ but I think it's something like this the ARM processor has it's own memory and the 2600 doesn't have much And the 2600 doesn't have much of it's address space exposed and not much to share The stack is a way of using the same address for a bunch of different locations so the 2600 can use some of the ARM memory without using much of the 2600's space The ARM does something similar to the above code with its memory and the 2600 just sees/uses a single location, the stack (which is virtual, it's really the ARM running the routines, although there maybe an actuall location associated with the stack, like I said I'm not that familiar with it)
  3. yes, but you can't calculate the bit specified the number in the brackets has to be a number literal not a variable or an expression and it doesn't always show an error if eg you use a variable you don't have to do all eight bits if you use the table dim bitstoswap = b dim idx = i const sbits0 = setbyte + 8 ; set a bit var31 = var31 | sbits0[idx] ; clear a bit var31 = (sbits0[idx] ^ %11111111) & var31 ; swap in bits 2, 3, 6 var31 = ((sbits0[idx] ^ var31) & %01001100) ^ var31 ; swap in bits 2, 3, 6 var31 = ((var31 ^ bitstoswap) & %01001100) ^ var31 it would be nice to build macros but bB macros are just DASM macros and DASM wouldn't understand the indexing so it would have to be done in ASM dim idx = i const sbits0 = setbyte + 8 def set_bit = callmacro stb_m def clear_bit = callmacro clb_m ; parameters target variable, number of bit to set macro stb_m asm ldx {2} lda sbits0,x ora {1} sta {1} end end ; parameters target variable, number of bit to clear macro clb_m asm ldx {2} lda sbits0,x eor #$FF and {1} sta {1} end end ; usage set_bit var31 idx clear_bit var31 idx
  4. I didn't explain very well Perhaps some of this is not as obvious as I think (I'm thinking) we're optimizing for time First thing I note is that you test for counter values and when you find one, you set var31 then test for more values that you know it can't be. Usually I think of a table look up as (probably) trading ROM space for speed. In this case you said you'd chosen "weird counter numbers" for timing so I regularized The intervals and added a guard condition for multiples of 8 ie if counter & 7 then .. so now 7 out of 8 times you only do one if test If you really needed the weird numbers you could still eg test for values between say, 40 and 100 and skipped 40% of the time (if your counter went 0..100) and done only two tests That's more code and more time but it's probably a net gain You could go farther and test for numbers that are eg equal to - greater than an even multiple of 4 but less than the next odd multiple (if that fit the values you were looking for) that would add another test but cut out half the possibilities if counter & 4 then You might do a binary search if you had more weird values Or you might use a look up table, but then you'd need like 60 entries if the values could be anything 40..100 A look up table would still be lot faster even if it didn't save any space I didn't really figure it out, but I think in this case you'd still save a few bytes of ROM And tables can be completely arbitrary none of this needs assembly except perhaps to have an idea of the time and space I would certainly encourage you to learn the assembly and read the list file to see what you're getting and a bit of assembly can be really useful even if you're using bB I especially like RevEng's suggetion (somewhere in this forum) of getting the assembler to print the difference (amount of code) between two lables
  5. it's true it uses less ROM but the point is it uses less time (and something closer to only the time necessary)
  6. the kernel has a table called setbyte that it uses for setting pixels in the playfield and other stuff it varies depending on how the playfield is structured in this case it would be (in bB) something like data setbyte $80, $40, $20, $10, $08, $04, $02, $01, $01, $02, $04, $08, $10, $20, $40, $80, $80, $40, $20, $10, $08, $04, $02, $01, $01, $02, $04, $08, $10, $20, $40, $80 end I just made v31_data an alias for setbyte (which was totally unnecessary) playfield statements get their own tables for the whole playfield
  7. my point was that you're doing a bunch of if statements that you don't need to do most of the time actually this makes more sense and if that last byte in the table is meant to be a 1 then you could use the table the kernel uses const v31_data = setbyte if counter & 7 then skip_v31 temp1 = counter/8 - 5 if temp1 < 8 then var31 = v31_data[temp1] skip_v31
  8. do fewer if statements temp1 = counter/8 - 5 if !counter & 7 && temp1 < 8 then var31 = dat[temp1] data dat $80, $40, $20, $10, $08, $04, $02, $00 end
  9. presumably you want to switch characters the first time you see the switch is pressed and ignore it if it's still pressed ie you need to remember the switch state from last time and then change characters only if it wasn't pressed last time and is pressed this time. something like this if switchselect && enable then gosub change_character if switchselect then enable = 0 else enable = 1
  10. here's one. not perfect temp1 = rand/2: temp1 = (((((temp1/2 + temp1)/2 + temp1)/2 +temp1)/2 + temp1)/4 + temp1)/8 + temp1 + 4
  11. perhaps you could keep the sprites in the same page and just flip the lo byte of the pointer something like AreWeChanging: lda P0FrameCounter cmp #10 bne SkipFlip FlipSpritePointer: lda #0 sta P0FrameCounter lda P0SpritePtr; lo byte pointer for P0 Sprite eor #<P0Sprite1 ^ <P0Sprite2 sta P0SpritePtr SkipFlip: or if a power of 2 will do for the count let the counter run and AND with a 2**n - 1 and bne
  12. tay and #%000000111 tax tya lsr lsr lsr tay lda dis_solid,y and number_to_bit,x rts
  13. I would expect that you'll find it easiest to maintan a seperate variable for your velocity One, the player positions are in increments of a pixel and that's probably too coarse. Your velocities would be 1 pixel, 2 pixels, 3 pixels etc per frame ie speed across the screen in the x direction in (rougly) 3 seconds, 1.5 seconds, 1 second You'll probably want fractional velocities (and acceleration). And two you will need to remember your velocities for your inertia effects You could probably contrive something with flags and counters but you would still be using extra variables (but they might serve additional purposes) If you are willing to unravel the bits yourself you dont need to use bBs built in 8.8 math, you might eg pack two 1.3 (4 bit) variables into a byte which would give you velocities 0..2 (0..1.875 actually) pixels/frame and velocities in increments of 1/8 pixel/frame
  14. also the lda temp1 it's not as accurate as [similar] asm could be here's some javascript ranged rand generator the asm it produces asm jsr randomize sta temp1 lsr adc temp1 ror lsr lsr lsr lsr lsr sta temp1 end
  15. another possibility temp1 = rand & 63 : temp1 = temp1 * 3 / 32 produces jsr randomize AND #63 STA temp1 ; complex statement detected LDA temp1 asl clc adc temp1 lsr lsr lsr lsr lsr STA temp1
  16. Yes. this is the asm result jsr randomize lsr STA temp1 ; complex statement detected LDA temp1 lsr CLC ADC temp1 lsr lsr lsr lsr lsr STA temp1
  17. temp1 = rand/2 : temp1 = (temp1/2 + temp1)/32
  18. how about sta lo lda #0 sta hi asl lo rol hi asl lo rol hi
  19. You're using a Fibonacci LFSR Here's the Galois LFSR from Batari BASIC randomize lda rand lsr bcc noeor eor #$B4 noeor sta rand rts
  20. I didn't try to work it out but.. 1/3 is 1/4 + 1/16 + 1/64 + 1/256 ... You're multiplying by reciprocal 3 $15 is the first three of those That will (roughly) have the effect of rounding up if the fractional part is > .66 ie you're multiplying by .3333... and adding .333 (approximately, I've not accounted for truncation and rounding)
  21. Can't say I've studied on it any, but I'd just add an lsr at the end, that way you keep the most bits for the divide by 3
  22. I'm thinking it would be useful to have the facility to (optionally) jump out of the kernel. So eg you might have a construct like this at the end of the kernel ifconst .kernel_exit jmp .kernel_exit .never_mind endif so you could jump to your minikernel and thence back to where you goto'd drawscreen (or back to .nevermind if you were so minded) and free up a couple of stack locations for those tricky text minikernels where you cant find enough pointers
  23. this uses fewer lines/cycles but probably a lot more ROM I have no idea how it would get along with other than the standard kernel I think it uses every possible free variable
×
×
  • Create New...