Jump to content

Photo

A fatal bug


7 replies to this topic

#1 Omegamatrix OFFLINE  

Omegamatrix

    Quadrunner

  • 6,136 posts
  • Location:Canada

Posted Sun May 31, 2009 2:13 AM

Have any of you every encountered a fatal bug with bankswitching? I sure as heck just did. This one really had me stumped and I spent a few hours on it, so you might want to learn how I Eff'd it up so badly and avoid doing it yourself.

I'd really appreciate a couple of things too. I know some of you are very knowledgeable with the hardware, and while I *half* understand the problem now; I'd really like a correct technical understanding. I left my thoughts on it in the assembly, but it sure needs to be corrected.

Second I'd like to know if in this case the Krok cart is preforming as it should. I don't have the capabilty to burn eproms so I rely on the Krok for my hardware testing. Armin if you are reading this maybe you can pipe in.


Alright, now the low down. I ripped everything out of my program until all I had left was a black screen with a yellow bar in the middle. It should look like this:
Bug.PNG

That's a picture of a corrected rom in Stella. However the original rom did not work! Even more important for you to know is that the original (bugged) rom did work in Z26. It didn't work in Stella though, or on a Krok cart. It would start drawing the yellow bar, perform a unexpected bankswitch, and then crash. I left a detailed explanation of the problem in the assembly. This was an interesting one to figure out.


Attached File  TestBug.zip   2.15KB   204 downloads

#2 batari OFFLINE  

batari

    )66]U('=I;B$*

  • 6,666 posts
  • begin 644 contest

Posted Sun May 31, 2009 2:39 AM

Have any of you every encountered a fatal bug with bankswitching? I sure as heck just did. This one really had me stumped and I spent a few hours on it, so you might want to learn how I Eff'd it up so badly and avoid doing it yourself.

The nature of the problem is actually not hard to understand, and only occurs under very specific conditions: a taken reverse branch located at $FFxx jumps to $FEF8-9. On the 4th cycle, a read of $FFF8-9 will occur. This happens because the 6507 must perform a read or write every cycle, and it needs an extra cycle to fix the address, so it does dummy reads in these cases.

However, I will give you that this sort of issue never occurred to me, but I agree, it's definitely a hazard.

#3 Omegamatrix OFFLINE  

Omegamatrix

    Quadrunner

  • Topic Starter
  • 6,136 posts
  • Location:Canada

Posted Sun May 31, 2009 3:37 AM

This problem really stumped me because Z26 played the rom perfectly. I always thought between Stella and Z26, that Z26 was more accurate. I know that Stella will soon surpass Z26, but this problem was perplexing to me.

I kept convincing myself that it must be an emulator problem, and Z26 was working right while Stella wasn't. When the rom didn't work on the Krok I kept convincing myself that there was something fundamental about bankswitching I didn't understand...

If it hadn't been for Stella's debugger I would never have discovered what was happening. While I spent a few hours coming to terms with it, it might have taken a few days for the programmers of old. We are lucky to have the tools that we do. However, can Batari Basic can assemble a rom with this error, or is the rom laid out in a way that it will never happen? This type of error would be much harder to figure out if more banks were in play, like an F6 or F4 bankswitch. There you might move the code up or down a few lines and it'd still execute a BS on you. All you would know is that it crashed.

I sort of came to the same conclusion of what was going wrong, at least I knew what it had to do with. I only distantly remember the dummy reads. I looked in the Stella's programmer guide, and glanced at Machine Language for Beginners, but couldn't find the section where the cycles of a branch was explained, and what happened to the PC. I did read about it a long time ago though.

I was wondering if you could riddle me this and explain what it does on each cycle, or point me in the right direction. We studied a PIC18F452 in school and learned how it fetched, decoded, and fetched the next instruction while it was excuting the previous one. What does it do on the 6507?

#4 Kroko OFFLINE  

Kroko

    Moonsweeper

  • 408 posts
  • Location:Germany

Posted Sun May 31, 2009 5:41 AM

Armin if you are reading this maybe you can pipe in.

I have nothing to add :) The dummy reads are seen by the cartridge and so it is forced to trigger the bankswitch. I think it is good that Stella obviously emulates this in a quite realistic way already.

#5 stephena OFFLINE  

stephena

    River Patroller

  • 3,020 posts
  • Stella maintainer
  • Location:Newfoundland, Canada

Posted Sun May 31, 2009 8:26 AM

This behaviour confused me a little at first as well. I ran into a somewhat related problem with correctly emulating reads to the write port in SC roms (extended RAM). It seems every write does an intermediate read, and this read erases the RAM at that location. I didn't really matter, as the write was overwriting the erased value anyway, but it was counter-intuitive (at first) that a trapread would trigger on a write.

As you've seen, there are times that an inadvertent read touches a bankswitch hotspot. It can also happen that inadvertent reads touch a write port address, and erase the value at that location. The next version of Stella will correctly emulate this behaviour for all SC rom types (currently, it only does it for FASC, and even then, there's a bug that causes all SC RAM to be erased when toggling the debugger).

#6 batari OFFLINE  

batari

    )66]U('=I;B$*

  • 6,666 posts
  • begin 644 contest

Posted Sun May 31, 2009 11:43 PM

This problem really stumped me because Z26 played the rom perfectly. I always thought between Stella and Z26, that Z26 was more accurate. I know that Stella will soon surpass Z26, but this problem was perplexing to me.

I kept convincing myself that it must be an emulator problem, and Z26 was working right while Stella wasn't. When the rom didn't work on the Krok I kept convincing myself that there was something fundamental about bankswitching I didn't understand...

If it hadn't been for Stella's debugger I would never have discovered what was happening. While I spent a few hours coming to terms with it, it might have taken a few days for the programmers of old. We are lucky to have the tools that we do. However, can Batari Basic can assemble a rom with this error, or is the rom laid out in a way that it will never happen? This type of error would be much harder to figure out if more banks were in play, like an F6 or F4 bankswitch. There you might move the code up or down a few lines and it'd still execute a BS on you. All you would know is that it crashed.

I sort of came to the same conclusion of what was going wrong, at least I knew what it had to do with. I only distantly remember the dummy reads. I looked in the Stella's programmer guide, and glanced at Machine Language for Beginners, but couldn't find the section where the cycles of a branch was explained, and what happened to the PC. I did read about it a long time ago though.

I was wondering if you could riddle me this and explain what it does on each cycle, or point me in the right direction. We studied a PIC18F452 in school and learned how it fetched, decoded, and fetched the next instruction while it was excuting the previous one. What does it do on the 6507?

This just shows that z26 doesn't always do a cycle-accurate emulation. There will be a point very soon when Stella is in virtually all ways more accurate than z26, and I think the new TIA code will make this happen.

The cycle-by-cycle breakdown can be found in the 64doc.txt document (available multiple places on the net):
Relative addressing (BCC, BCS, BNE, BEQ, BPL, BMI, BVC, BVS)

		#   address  R/W description
	   --- --------- --- ---------------------------------------------
		1	 PC	  R  fetch opcode, increment PC
		2	 PC	  R  fetch operand, increment PC
		3	 PC	  R  Fetch opcode of next instruction,
						 If branch is taken, add operand to PCL.
						 Otherwise increment PC.
		4+	PC*	 R  Fetch opcode of next instruction.
						 Fix PCH. If it did not change, increment PC.
		5!	PC	  R  Fetch opcode of next instruction,
						 increment PC.

	   Notes: The opcode fetch of the next instruction is included to
			  this diagram for illustration purposes. When determining
			  real execution times, remember to subtract the last
			  cycle.

			  * The high byte of Program Counter (PCH) may be invalid
				at this time, i.e. it may be smaller or bigger by $100.

			  + If branch is taken, this cycle will be executed.

			  ! If branch occurs to different page, this cycle will be
				executed.
The above may be a little odd because there is no cycle 5 in a branch, and no cycle 4 if the page didn't wrap - that is actually the first cycle of the next instruction.

As for bB, it is certainly possible to produce this bug. I have never heard of it happening before, so it must be uncommon.

#7 e1will OFFLINE  

e1will

    Moonsweeper

  • 347 posts

Posted Mon Aug 17, 2009 9:28 PM

I just ran into this same issue. I had some code at $FEF6 that I was trying to jump to from $FF42, and kaboom! It switched banks from #5 to #2. I sure wasn't expecting that.

I'm glad somebody posted about this so I'd know what's going on. I presume this means that for F4 and similar bankswitching schemes, there's a certain chunk of ROM space in each bank where it's unsafe to put branching code, say around FF00-FF80?

--Will

#8 Omegamatrix OFFLINE  

Omegamatrix

    Quadrunner

  • Topic Starter
  • 6,136 posts
  • Location:Canada

Posted Tue Aug 18, 2009 10:59 PM

You will be generally safe except for a few very specific conditions. Lets look at the conditions using F8, as it is a lot shorter of an example.

lda $FFF8 ; switches to bank 0
lda $FFF9 ; switches to bank 1

Now if you were in between $FF00 - $FF78 (or so) and branching to either $FEF8 or $FEF9 you'd trigger a hotspot.

The two important elements are:
- You are in the last page of the 4k rom space (i.e. $1Fxx, $3Fxx, $5Fxx, .... $FFxx)
- The low nybble of the address you are branching to is also present in a hotspot (ie for F8 bankswithching, $xxF8, $xxF9)

Not to sure what would happen if you used JMP or JSR though. My brain is a little fried right now from matrix algebra, statistics, intermediate calculus, and chemistry.

Hope this helps. :)




0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users