+batari Posted June 15, 2006 Share Posted June 15, 2006 the // division seems to freeze the compiler. I've added div_mul and div_mul16 to the includes file and it's simply refusing to compile if I don't rem out b = brickx // 2 I forgot until now that I had implemented // to save the remainder, so it's likely that later changes broke it! However, // uses a slow sort of binary long division that takes quite a few cycles. For some values, this is the best way, but for dividing by two, it's much slower than it needs to be. A much better and faster way to get the remainder would be this: b=brickx/2 temp1=brickx & 1 Quote Link to comment Share on other sites More sharing options...
Luigi301 Posted June 15, 2006 Share Posted June 15, 2006 I'm trying to divide by 3, actually, if that's possible within a reasonable number of cycles. Quote Link to comment Share on other sites More sharing options...
+batari Posted June 15, 2006 Share Posted June 15, 2006 I'm trying to divide by 3, actually, if that's possible within a reasonable number of cycles. It's around 200 cycles regardless of the divisor. It's reasonable as long as there aren't too many divisions in your program. I see the problem - it's the preprocessor. Since I forgot about //, the preprocessor thinks you've put in two divides in a row and screws up the compiler. For now, you can use some inline asm. For example, b=brickx//3 would turn into: asm LDA brickx LDY #3 jsr div16 STA b end Quote Link to comment Share on other sites More sharing options...
djmips Posted June 15, 2006 Share Posted June 15, 2006 I'm trying to divide by 3, actually, if that's possible within a reasonable number of cycles. If you're handy with the inline assembler or calling assembler routines you could also use this routine which will be 40 odd cycles, and so much faster. Unsigned divide by 3 routine (6502) change the usage of temp to temp1 in the code like so, and then perhaps put it at the end of your batari basic file. If you're just going to just use it one time then you can inline it as well. put LDA brickx at top and replace rts with STA b. asm ; unsigned divide by 3 div3unsigned: sta temp1 lsr lsr clc adc temp1 ror lsr clc adc temp1 ror lsr clc adc temp1 ror lsr clc adc temp1 ror lsr rts end and call it in your code asm LDA brickx jsr div3unsigned STA b end Also, depending on the range of your numbers you can get away with a small table to do a divide by 3. asm LDY brickx LDA div3table,Y STA b end and then somewhere at the end of your file asm ; table good from 0-9 div3table: .byte 0,0,0,1,1,1,2,2,2,3 end One other reasonable approach is to avoid doing the divide altogether. It's often possible to optimize it out of your loop Quote Link to comment Share on other sites More sharing options...
Luigi301 Posted June 16, 2006 Share Posted June 16, 2006 (edited) Times like these I wish I knew 6502 assembly. One more question so I know if I even need to divide by 3. How big in Atari pixels is one pfpixel? Edited June 16, 2006 by Luigi301 Quote Link to comment Share on other sites More sharing options...
djmips Posted June 16, 2006 Share Posted June 16, 2006 four if I recall correctly. Quote Link to comment Share on other sites More sharing options...
Luigi301 Posted June 16, 2006 Share Posted June 16, 2006 Okay, found another bug, this one's score-related. I'm trying to use the score to check some game variables, but setting the score is acting very oddly. I can do score = 6 and the score comes up as 6. But if I do value = 6 score = value then the score comes up as 70. Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted September 10, 2006 Share Posted September 10, 2006 I just found a minor bug in version 0.99c. It displays 264 lines instead of 262 lines. I checked, and versions 0.99a and 0.99b both displayed 262 lines, so something changed in 0.99c to cause this. I'll compare the files to see what it was, and post my findings. Also, the "const" keyword doesn't work anymore, but I haven't backtracked yet to see which version it stopped working in. MR Quote Link to comment Share on other sites More sharing options...
CurtisP Posted April 15, 2007 Share Posted April 15, 2007 Here's a bit operation bug I found in the getPosition routine of my code, the line temp1 = rand: position{1} = temp1(7) is generating the following code .skipL058 .L059 ; temp1 = rand : position{1} = temp1 ( 7 ) jsr randomize STA temp1 LDA temp1 AND #65536 PHP LDA position PLP .byte $D0, $03 AND #253 .byte $0C ORA #2 STA position I'm guessing it really wants to do an AND #128 for now I'm doing a work around Silhouette.bas Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted April 15, 2007 Share Posted April 15, 2007 Here's a bit operation bug I found in the getPosition routine of my code, the line temp1 = rand: position{1} = temp1(7) is generating the following code Did you actually mean to type temp1{7}? I changed the () to {} and it compiled correctly with 128 instead of 65536. By the way, I don't know which editor you're using, or what font you're using, but in Crimson Editor with Courier New 10 it was really hard to see the difference between () and {}, whereas it shows up easily in your AtariAge post. I was just checking my Crimson Editor screen font settings, and I think I've decided to go with Terminal 10. Michael "AAARRRGGGHHH!!! This computer program is driving me CRAZY!!! It keeps doing what I TELL it to do instead of what I WANT it to do!!!" Been there, done that, wore the straitjacket! Quote Link to comment Share on other sites More sharing options...
CurtisP Posted April 15, 2007 Share Posted April 15, 2007 Did you actually mean to type temp1{7}? I changed the () to {} and it compiled correctly with 128 instead of 65536. Doh! Thanks, I thought I hade checked this multiple times. I'm actually using 2600IDE. I probably need to switch to a real editor though. I should just set up PSPad to work with bAtari Basic. Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted April 15, 2007 Share Posted April 15, 2007 Did you actually mean to type temp1{7}? I changed the () to {} and it compiled correctly with 128 instead of 65536. Doh! Thanks, I thought I hade checked this multiple times. I'm actually using 2600IDE. I probably need to switch to a real editor though. I should just set up PSPad to work with bAtari Basic. 2600IDE lets you change the font, too. True, it isn't a full-featured editor, but it's very easy to use, and it's what I used when I started programming in batari Basic. I'm currently using Crimson Editor, but I've actually *purchased* Multi-Edit (a commercial IDE for professional programmers, which I happen to like), and every so often I pay to update it to the next version, so I really *ought* to be using that instead. Really, the only reason I'm using Crimson Editor at all is because I wanted a free IDE that I could tell people about in my posts, so I could help them with it if they have trouble. Michael Quote Link to comment Share on other sites More sharing options...
Robert M Posted October 10, 2007 Share Posted October 10, 2007 This seems like a bug to me. Is the language supposed to support use of bitwise operators in the conditional expressions of if-then statements? When I use the & operator I get incorrect code: .L0226 ; rem ** The upper nybble of playerStatus forms an invulnerability counter, .L0227 ; rem ** and bit 0 is set when the player is using the shield. .L0228 ; if playerStatus & %11110001 then SkipPlayerIsNotHurt LDA playerStatus CMP #%11110001 .L0229 ; playerHealth = playerHealth / 2 : rem Decrease the health bar by 1. LDA playerHealth lsr STA playerHealth .L0230 ; playerStatus = playerStatus | $F0 : rem Set invulnerability counter to max. LDA playerStatus ORA #$F0 STA playerStatus .SkipPlayerIsNotHurt ; SkipPlayerIsNotHurt Is this a bug or a feature Cheers! Quote Link to comment Share on other sites More sharing options...
+batari Posted October 11, 2007 Share Posted October 11, 2007 This seems like a bug to me. Is the language supposed to support use of bitwise operators in the conditional expressions of if-then statements? When I use the & operator I get incorrect code: .L0226 ; rem ** The upper nybble of playerStatus forms an invulnerability counter, .L0227 ; rem ** and bit 0 is set when the player is using the shield. .L0228 ; if playerStatus & %11110001 then SkipPlayerIsNotHurt LDA playerStatus CMP #%11110001 .L0229 ; playerHealth = playerHealth / 2 : rem Decrease the health bar by 1. LDA playerHealth lsr STA playerHealth .L0230 ; playerStatus = playerStatus | $F0 : rem Set invulnerability counter to max. LDA playerStatus ORA #$F0 STA playerStatus .SkipPlayerIsNotHurt ; SkipPlayerIsNotHurt Is this a bug or a feature Cheers! bB typically does a load and compare as shown, and determines from the operator what kind of branch to use, but if it's not found, it apparently it just does nothing if the operator isn't recognized as valid. I think it doesn't report an error because lack of a valid operator doesn't necessarily mean the statement is malformed (though that check could be done.) I've been meaning to allow any sort of operation in if/thens other than just a simple compare, but haven't got around to it. Maybe there's a case for adding & until I get around to it, as I've had a use for that kind of operation myself. Quote Link to comment Share on other sites More sharing options...
Robert M Posted October 12, 2007 Share Posted October 12, 2007 bB typically does a load and compare as shown, and determines from the operator what kind of branch to use, but if it's not found, it apparently it just does nothing if the operator isn't recognized as valid. I think it doesn't report an error because lack of a valid operator doesn't necessarily mean the statement is malformed (though that check could be done.) I've been meaning to allow any sort of operation in if/thens other than just a simple compare, but haven't got around to it. Maybe there's a case for adding & until I get around to it, as I've had a use for that kind of operation myself. My bad! I misread the online manual. I mistook the && operator for the & operator. Quote Link to comment Share on other sites More sharing options...
Fort Apocalypse Posted December 6, 2007 Share Posted December 6, 2007 (edited) Here is an interesting compiler bug or wierdness. I should learn not to start variable names with "joy", but it is strange what causes this one to happen. If you setup a variable that starts with joy and then later try to do an equals comparison to a variable it will fail with the error: ---------- Capture Output ----------> "C:\Atari2600\bB\2600bas.bat" C:\Atari2600\projects\bug.bas (13): invalid console switch/controller reference (13): Error: Unknown keyword: (whatever your variable name was that you were trying to compare the joy... variable to) Compilation failed. > Terminated with exit code 0. Code to reproduce compile bug attached. If you change all references to joybits to gamebits, it compiles. If you use greater than instead of equals, it compiles. Fun! bug.bas Edited December 6, 2007 by Fort Apocalypse Quote Link to comment Share on other sites More sharing options...
Fort Apocalypse Posted December 6, 2007 Share Posted December 6, 2007 On a somewhat related topic it would be nice to be able to do this: set kernel_options no_blank_lines set smartbranching on dim gamebits = temp4 mainloop gamebits = 0 gamebits{0} = joy0down gamebits{1} = joy0right gamebits{2} = joy0up gamebits{3} = joy0left temp3 = 4 if gamebits > temp3 then COLUBK = 15 else COLUBK = 0 goto mainloop but currently this produces the following compiler error because I guess switches aren't allowed to be assigned to a variable or bit. ---------- Capture Output ----------> "C:\Atari2600\bB\2600bas.bat" C:\Atari2600\projects\bug.bas 2600 Basic compilation complete. DASM V2.20.07, Macro Assembler ©1988-2003 C:\Atari2600\projects\bug.bas.asm (1529): error: Value in 'and #65536' must be <$100. C:\Atari2600\projects\bug.bas.asm (1541): error: Value in 'and #65536' must be <$100. C:\Atari2600\projects\bug.bas.asm (1553): error: Value in 'and #65536' must be <$100. C:\Atari2600\projects\bug.bas.asm (1565): error: Value in 'and #65536' must be <$100. bytes of ROM space left Unrecoverable error(s) in pass, aborting assembly! Complete. > Terminated with exit code 0. bug.bas Quote Link to comment Share on other sites More sharing options...
+batari Posted December 6, 2007 Share Posted December 6, 2007 On a somewhat related topic it would be nice to be able to do this: set kernel_options no_blank_lines set smartbranching on dim gamebits = temp4 mainloop gamebits = 0 gamebits{0} = joy0down gamebits{1} = joy0right gamebits{2} = joy0up gamebits{3} = joy0left temp3 = 4 if gamebits > temp3 then COLUBK = 15 else COLUBK = 0 goto mainloop but currently this produces the following compiler error because I guess switches aren't allowed to be assigned to a variable or bit. ---------- Capture Output ----------> "C:\Atari2600\bB\2600bas.bat" C:\Atari2600\projects\bug.bas 2600 Basic compilation complete. DASM V2.20.07, Macro Assembler ©1988-2003 C:\Atari2600\projects\bug.bas.asm (1529): error: Value in 'and #65536' must be <$100. C:\Atari2600\projects\bug.bas.asm (1541): error: Value in 'and #65536' must be <$100. C:\Atari2600\projects\bug.bas.asm (1553): error: Value in 'and #65536' must be <$100. C:\Atari2600\projects\bug.bas.asm (1565): error: Value in 'and #65536' must be <$100. bytes of ROM space left Unrecoverable error(s) in pass, aborting assembly! Complete. > Terminated with exit code 0. Yes, you can't currently start any variable with "joy." However, you can assign bits to joystick moves, though not in the way you noted. To do what you're asking, gamebits=((gamebits&$F0)|(SWCHA/16))^15 Bits 3 to 0 of gamebits will be set to right, left, down, and up respectively, without affecting other bits. Quote Link to comment Share on other sites More sharing options...
Fort Apocalypse Posted December 7, 2007 Share Posted December 7, 2007 However, you can assign bits to joystick moves, though not in the way you noted. To do what you're asking, gamebits=((gamebits&$F0)|(SWCHA/16))^15 Bits 3 to 0 of gamebits will be set to right, left, down, and up respectively, without affecting other bits. Cool! Thanks!!! Quote Link to comment Share on other sites More sharing options...
MausGames Posted December 7, 2007 Share Posted December 7, 2007 "To do what you're asking, gamebits=((gamebits&$F0)|(SWCHA/16))^15 Bits 3 to 0 of gamebits will be set to right, left, down, and up respectively, without affecting other bits." Can either of you give some examples of when that would be useful/possible applications? Quote Link to comment Share on other sites More sharing options...
+batari Posted December 7, 2007 Share Posted December 7, 2007 "To do what you're asking,gamebits=((gamebits&$F0)|(SWCHA/16))^15 Bits 3 to 0 of gamebits will be set to right, left, down, and up respectively, without affecting other bits." Can either of you give some examples of when that would be useful/possible applications? Try this: temp1=(SWCHA/16)^15:if temp1 then gamebits=(gamebits&$F0)|temp1 if gamebits{3} then player0x=player0x+1 if gamebits{2} then player0x=player0x-1 if gamebits{1} then player0y=player0y+1 if gamebits{0} then player0y=player0y-1 Quote Link to comment Share on other sites More sharing options...
Fort Apocalypse Posted December 7, 2007 Share Posted December 7, 2007 Can either of you give some examples of when that would be useful/possible applications? Here is an example I'm working on. If I could figure out how to make joystick1 return the exact same variable with bits in the same place, then I could save a few more lines of code. (Will start a thread on it, too so you can post there if interested in it.) atar0.1.bas atar0.1.bas.bin Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted December 28, 2007 Share Posted December 28, 2007 I found a slight timing bug in the standard kernel, when the last line of the playfield is being drawn: ifnconst no_blank_lines lastkernelline ifnconst PFcolors sleep 10 else ldy #124 lda (pfcolortable),y sta COLUPF endif ifconst PFheights ldx #1 sleep 4 else ldx playfieldpos sleep 3 endif jmp enterlastkernel else lastkernelline ifconst PFheights ldx #1 sleep 5 else ldx playfieldpos sleep 4 endif cpx #1 bne .enterfromNBL ; <----- This crosses a page boundary! jmp no_blank_lines_bailout endif if ((<*)>$d5) align 256 endif ; this is a kludge to prevent page wrapping - fix!!! .skipDrawlastP1 sleep 2 lda #0 jmp .continuelastP1 .endkerloop ; enter at cycle 59?? nop .enterfromNBL ifconst pfres ldy.w playfield+pfres*4-4 sty PF1 ; 3 ldy.w playfield+pfres*4-3 sty PF2 ; 3 ldy.w playfield+pfres*4-1 sty PF1 ; possibly too early? ldy.w playfield+pfres*4-2 sty PF2 ; 3 else ldy.w playfield+44 sty PF1 ; 3 ldy.w playfield+45 sty PF2 ; 3 ldy.w playfield+47 sty PF1 ; possibly too early? ldy.w playfield+46 sty PF2 ; 3 endif (I reformatted the line indentations for increased legibility, and included more lines than necessary in the quoted code to better show the location of the line in question-- the branch which crosses a page boundary.) When the kernel is drawing the last row of the playfield, the instructions to load/store the playfield data (in .enterfromNBL) are starting 1 cycle later than the corresponding load/store instructions for the other rows of the playfield, which causes the first pixel of PF1 to be drawn incorrectly, as shown below: I corrected the timing bug by changing the sleeps in the following two lines: ifnconst no_blank_lines lastkernelline ifnconst PFcolors sleep 10 else ldy #124 lda (pfcolortable),y sta COLUPF endif ifconst PFheights ldx #1 sleep 4 else ldx playfieldpos sleep 3 endif jmp enterlastkernel else lastkernelline ifconst PFheights ldx #1 ; sleep 5 ; <----- I reduced this by 1 cycle to fix the timing sleep 4 else ldx playfieldpos ; sleep 4 ; <----- I reduced this by 1 cycle to fix the timing sleep 3 endif cpx #1 bne .enterfromNBL jmp no_blank_lines_bailout endif if ((<*)>$d5) align 256 endif ; this is a kludge to prevent page wrapping - fix!!! .skipDrawlastP1 sleep 2 lda #0 jmp .continuelastP1 .endkerloop ; enter at cycle 59?? nop .enterfromNBL ifconst pfres ldy.w playfield+pfres*4-4 sty PF1 ; 3 ldy.w playfield+pfres*4-3 sty PF2 ; 3 ldy.w playfield+pfres*4-1 sty PF1 ; possibly too early? ldy.w playfield+pfres*4-2 sty PF2 ; 3 else ldy.w playfield+44 sty PF1 ; 3 ldy.w playfield+45 sty PF2 ; 3 ldy.w playfield+47 sty PF1 ; possibly too early? ldy.w playfield+46 sty PF2 ; 3 endif After recompiling with the updated std_kernel.asm file, the last playfield row is drawn correctly: Michael Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted December 28, 2007 Share Posted December 28, 2007 I found a slight timing bug in the standard kernel, when the last line of the playfield is being drawn: I've attached a .zip file containing the updated std_kernel.asm and std_kernel_SC.asm files. Michael std_kernel.zip Quote Link to comment Share on other sites More sharing options...
Fort Apocalypse Posted December 29, 2007 Share Posted December 29, 2007 I found a slight timing bug in the standard kernel, when the last line of the playfield is being drawn: I've attached a .zip file containing the updated std_kernel.asm and std_kernel_SC.asm files. Michael That's awesome. Thanks, Michael! It would be great if there could either be an official pinned patch thread where people could link to topics that included patches to the kernels (so patch and discussion would be contained in other threads) and it would be great if the best of the patches could be hosted on the batari basic site with links to the atariage forum threads that discuss the patches. Same with minikernels, etc. I'm having trouble at the moment finding the fix for pfcolors that Maus said was here in the forum somewhere so I thought it might be good to mention this here. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.