Jump to content
kisrael

Bug Report Thread

Recommended Posts

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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

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 by Luigi301

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

 

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!!!" :D Been there, done that, wore the straitjacket!

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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!

Share this post


Link to post
Share on other sites
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!

:lol:

 

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.

Share this post


Link to post
Share on other sites
:lol:

 

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

Share this post


Link to post
Share on other sites

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 by Fort Apocalypse

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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!!!

Share this post


Link to post
Share on other sites

"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?

Share this post


Link to post
Share on other sites
"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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

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:

 

post-7456-1198881679_thumb.png

 

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:

 

post-7456-1198881915_thumb.png

 

Michael

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
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.

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