Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

186 Excellent

About bogax

  • Rank

Profile Information

  • Gender
  1. 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)
  2. 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
  3. 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
  4. bogax

    Text Minikernel

    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
  5. here's one I flickered the pixel if you hold the fire button for couple seconds you cycle NUSIZE when the fire button is released (unless you hold it too long then the timer will roll over ) other wise you flip the pixel sprite_in_RAM.bas sprite_in_RAM.bas.bin
  6. player8x = (rand&123)+16 player8y = (rand&100)+40 will have similar issues in the case of rand & 123 you might be happy with rand & 124 which will produce mutiples of 4 0..124
  7. you can nest subroutines you just have to be mindfull of the limitations you've only got a few stack locations to work with and it varies with kernel options (I think its 6 for the standard kernel, 12 bytes, each gosub takes 2 bytes) functions, including bB's built in functions, are subroutines (and they may be nested) the (standard) kernel (drawscreen) goes 3 deep (if I recall correctly) complex expressions also use the stack (especially if you don't use parenthesis) while I agree with RT's specific example, if you were jumping around a hundred lines of code I think you'd be better off giving them a name and using a subroutine unless you're really really squeezed for cycles it will make your code much easier to read and follow and possibly tweak (more modular)
  8. rand & 6 will produce only even numbers 0..6 (inclusive) you'll never get 1,3,5
  9. here's one ; a = accumulator C = carry flag, I = INPT4, f = your flags, ; f7 = bit 7 of flags, the debounce (restrainer) bit (sort of, maybe you'd say that was C) ; f7 = previous I7 we want to check for !I7 & f7 = 1 lda flags and #$80 clc sbc INPT4 ; C = !I7 & f7, a7 = !I7 ^ f7 and #$80 eor flags ; a7 = !I7 eor #$80 sta flags bcc skip_audio
  10. I'd encourage you to make the locations consecutive and treat them as a table if possible If they need to be random and you're going to address them indirectly through a table then you don't need to use the lda (address),y mode unless you're going to change tables ie unless address is going to change (if the value in memory at location "address" needs to be changeable, that is the table location needs to be a variable) POINTER_VAR = VAR_TABLE + TABLE_HEIGHT - 1 has (POINTER_VAR),0 (ie y = 0) pointing at o the last byte of the VAR_TABLE table. (VAR_TABLE),3 (y = 3) isn't in the table re Nukey Shay's example if the table isn't going to change then you can load x (more) directly ldy #$03 ldx VAR_TABLE,y lda $00,x as Nukey Shay said "f" is an alias for a number in bB you'd do const f = $d6 $d6 is the location in memory of bB variable f (but of course it's predefined in bB in 2600basic.h)
  11. here's another one that searches in the column for a pixel to set dim pxpntr = temp1 dim cnt = temp2 COLUPF = $56 loop if !joy0fire || !f{0} then skip if !c then c = 11 : pfvline 31 0 10 off c = c - 1 : gosub setrndpix skip if joy0fire then f{0} = 0 else f{0} = 1 var40 = $55 : var32 = c drawscreen goto loop ; the screen in the standard kernel is an array of 48 bytes ; the bytes are named var0..var47 ; there are 4 bytes to a row ie every forth byte for a column ; some of the bytes are displayed in reverse ; in this case the last pfpixel column corresponds to ; bit 7 of the 4th byte which is byte 3 relative to var0 ; rand returns a number 0..255 we need a random number 0..10 ; to specify the row, and the column is every 4th byte ; in some other languages rand would return a number 0 to .99999 ; and we'd multiply by 11 to get a number in the range 0..10 ; we can think of 255 as .11111111 * 256 (.11111111 being the binary equivalent of .9999) ; so we can divide rand by 256 and multiply by 11 then multiply by 4 (every 4th byte) ; or just divide by 64. we only have 8 bits and fractional parts are truncated ; so here the division is differed as long as possible to keep the intermediates ; as large as possible so as not to lose accuracy in truncated fractional bits ; then OR with 3 'cause we need the 4th byte which is byte 3 ; could have referenced to var3 and set bits 0,1 to 0 ; the pfpixel is checked by ANDing the appropriate bit and testing for 0 ; (you can't use a variable with the bits{x} notation) ; if the bit is set the pixel pointer is incremented by three rows (to make it appear ; more random than just counting through the column of pixels)and wrapped ; in the column if neccesary could use a simple counter and a scatter table ; which would be faster and probably use roughly the same amount of code ; cnt keeps track of how many pixels we've searched through so we don't search ; forever for a pixel to set if all the pixels are already set set setrndpix pxpntr = rand/2 : pxpntr = (((pxpntr/2 + pxpntr)/4 + pxpntr)/4) | $03 : var36 = pxpntr ; rand * 11/64 and set bits 0,1 cnt = 11 pixloop cnt = cnt - 1 pxpntr = pxpntr + 12 : if pxpntr > 43 then pxpntr = pxpntr - 44 ; increment the pixel pointer by three rows and wrapp if necessary if !var0[pxpntr] & $80 then var0[pxpntr] = var0[pxpntr] | $80 : return ; if the pixel is clear set it and return if cnt then pixloop ; if that wasn't 11th try (try 0, we're counting down) try again return rnd_col_2.bas rnd_col_2.bas.bin
  12. you don't really give enough informations to know exactly what you want what's you're max? how many pixels in the column? what kernel? are the pf pixels going to be permanent or will they be removed too? do they need to be in some sort of sequence ie if you choose a pixel at random and it's already on then what? probably the simplest thing would be to choose a pixel at random and see if it's on if it is choose another until you find one that's not that could take a lot of time if there's a bunch of them already on here I've made a custom routine to count through a column of 11 pixels in a psuedo random fashion it's kind of messy and takes a fair amount of code about, 100 bytes press fire to fill in a pixel, when all the pixels in the column are filled it clears the column and reseeds with rand dim seed = s COLUPF = $56 loop if !joy0fire || !f{0} then skip if !c then seed = rand : c = 11 : pfvline 31 0 10 off c = c - 1 : gosub myrnd pfpixel 31 temp1 on skip if joy0fire then f{0} = 0 else f{0} = 1 var40 = $55 : var36 = seed/2 & $0F : var32 = c drawscreen goto loop ; bits 5, 6 are a parameter used to select an increment for a pseudo random counter ; the counter is used to select random number from the scatter table ; so it looks less like a counter and more like something random ; the scatter table is 2 tables of 22 random numbers interleaved ; one table for the odd counter numbers one for even counter numbers ; while counting we wont touch bit 0 of the counter so it will count ; through odd numbers or even numbers depending on how bit 0 is initalized ; if bit 7 of seed is set the counter is complemented for the scatter table look up ; 4 increments * 2 tables * 2 for complementing gives 16 possible sequences myrnd temp1 = (seed/32) & $03 ; get the current increment number temp2 = (seed & $1F) + rinc[temp1] ; increment the counter if temp2 > 21 then temp2 = temp2 - 22 ; mod 22 if seed{7} then temp1 = 21 - temp1 ; conditionally complement the pointer temp1 = scatter[temp2] ; randomize it seed = ((seed ^ temp2) & $E0) ^ temp2 ; put the new counter value back into bits 0..4 of seed return data scatter $07, $06 $08, $09 $03, $0A $00, $01 $05, $02 $0A, $00 $04, $05 $09, $08 $06, $03 $02, $04 $01, $07 end data rinc $06, $0A, $0E, $12 end rnd_col.bas rnd_col.bas.bin
  13. The processor (and therfore bB) doesn't really know about negative numbers You can subtract and there is a flag for negative numbers. The flag reflects the state of of bit 7 (There's also an overflow flag which is (the carry from bit 6) ^ (the carry from bit 7)) (It's a pity that bB doesn't give you access to the flags) But it's really how you interpret the numbers (go read about 2's complement (Wikipedia)) Your bytes go from 0..255 255 = -1, n + 255 = n - 1 (this is all MOD 256) if you want a range of say -17 to +17, your if statement would be something like If x >= 239 && x <= 17 then and in bB you can write that as if x >= -17 && x <= 17 then 239 = 256 - 17 Using 239 takes less time and code
  14. it never gets that far for me if I don't get rid of the tabs it stops on line 1107 musiccounter = musiccounter + 1 with "(1107): Error: Unknown keyword: = " without the tabs .L0421 in bB.asm 4599 in the .lst bB.asm fall10test.bas.lst
  15. after getting rid of those god cursed tabs and replacing them with decent spaces and changing the ";" to "rem" on line 1276 (WTF !?) it compiles for me using bB.1.1d.reveng41 on Win 8.1
  • Create New...