6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 11:21 pm

All times are UTC




Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Sat Nov 25, 2017 5:30 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8507
Location: Midwestern USA
resman wrote:
FWIW, the Apple II Super Serial Card (using the 6551) has this exact bug fix in its firmware. The false read would look like an access to the data register which would clear the 'character available' status register bit.

The false read potentially can raise havoc with any I/O device in which a read of a register causes a change of state in the device. My opinion is it is a bug in the 65C02, a pernicious one at that, in the same league as the JMP (<addr>) bug in the NMOS 6502. At least the latter is a documented bug, whereas this false read of the 65C02 is not.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 27, 2017 9:05 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
Page crossings during indexing were the cause of some rare but nasty headaches on the NMOS '02, so it may seem counterintuitive that floobydust's indexing problem was solved by invoking a page crossing. :shock: The explanation involves fixes that were applied when the 'C02 was designed. The 'C02 fix for page crossings during indexing successfully achieved a certain defined goal. But the designers missed the opportunity to fix a related and more obscure issue.

At issue are address modes such as abs,X abs,Y and (ind),Y which take a 16-bit base address and add to it an 8-bit index. The 16-bit result is available immediately if the lowbyte addition generates no carry. Otherwise an extra cycle is required, and what's immediately available is only a partially formed address -- one whose lowbyte is correct but whose highbyte needs to be incremented. Sometimes mysteriously referred to as an "invalid address," a partially formed address is actually entirely predictable. It's simply the intended address minus $100. And the cycle in which it appears is like a wait state, a delay inserted before the final cycle.

Unfortunately, an NMOS '02 will put the PFA on the address bus during the wait state. That means your program can, when indexing, inadvertently touch whatever is $100 below the intended address. If there's an I/O device there its internal status may be altered -- hence the nasty headaches! As bugs go, this one is especially bad because the cause and effect are entirely unrelated. (You could waste a lot of time believing the bug was in the I/O routine. :cry: )

AFAICT the 'C02 never places a PFA on the address bus. Instead (as loosely described in the doc) there's some sort of mechanism that places the Program Counter on the bus during any cycle which, on an NMOS '02, would have a PFA. IOW the fix can be said to achieve a goal of no PFA's. Instead the 'C02 harmlessly does a spurious read of the last instruction byte.

What apparently got overlooked is the case of an indexed STA. With STA -- a write operation -- the wait state aka extra cycle is no longer conditional. It's always included (and is always a read), whether or not the lowbyte addition produces a carry. This makes possible something which otherwise never happens (except as noted in the ps) : an extra indexing cycle during which the complete address is already present. :!:

Ideally that same mechanism would kick in and place the Program Counter on the bus. But that's where the 'C02 fix falls short. The mechanism only kicks in if there's a carry. With no carry, the complete address is allowed to appear on the bus, resulting in a spurious read from the same address which will be written in the following cycle.

Who knows; maybe the designers said, "Heck, it's not a PFA, so we don't need to do anything about it." Or maybe there's a solid reason they weren't able to take action. But, as floobydust discovered, a spurious read can cause trouble even when it doesn't involve a PFA / "invalid" address. And coaxing the mechanism to kick in is a viable workaround.

-- Jeff

ps: discussed here is another incomplete 'C02 fix, first brought to our attention by dclxvi. Again there may be an extra indexing cycle during which the complete address is already present, and again the mechanism's response depends on the presence or absence of a carry:
Quote:
Without a page crossing the extra cycle appears anyway, and the address is the same as that during the following cycle when the RMW actually commences. [...] With a page crossing there will be an extra cycle, during which PC appears on the address bus

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 28, 2017 9:27 am 
Offline

Joined: Sun Apr 10, 2011 8:29 am
Posts: 597
Location: Norway/Japan
Thanks Jeff.
With your explanation I finally understand the issue about the extra read. Very interesting.


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 29, 2017 4:48 am 
Offline

Joined: Wed Feb 12, 2014 1:39 am
Posts: 173
Location: Sweden
Well that explains that!

I had the same problem with the 28L92 and assumed I was doing something horribly wrong.


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 29, 2017 4:06 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
I now have a stable working BIOS for the 2691 UART. It's been tested for for over a hundred hours so far and has not failed (yet). It provides a fair amount of function in a small code size, 672 bytes. This includes a 32-entry JUMP table of which 13 entries are currently in use. It also has 96 bytes of configuration data space (in the I/O page), of which 49 bytes are currently in use. It provides interrupt-driven support for transmit/receive with 128-byte FIFO buffers in memory, timer/counter support for a 10ms jiffyclock and supports received break via interrupt. All IRQ handlers are working without issue. I'm using the jiffyclock for RTC and delays, which the Monitor program uses. A simple memory map is:

$F800 - $FDFF = BIOS code ($F9EB-$FDFF is free)
$FE00 - $FE9F = I/O space (5- I/O selects at 32-bytes wide. $FE80-$FE9F is the SCC2691)
$FEA0 - $FEFF = 96-bytes of Configuration Data space (vectors, init/reset data)
$FF00 - $FFFF = JUMP table, main boot/init routine, BIOS message, pre/post IRQ/BRK/NMI handlers ($FF95-$FFDF is free)
Page Zero usage: $E0 - $FF (last 4 bytes are unused/reserved)

I also added my existing Monitor program with a few changes to interface to the BIOS. Changes to the delay routines were required in addition to the EEPROM program function. Some internal delays functions were changed in the Xmodem support and I was able to delete a few bits of code there as well. I also added an exclusion range for the full I/O address range so the Hex/Text memory display and Hex/Text Search functions will bypass the I/O devices and return with $FE as the default data. This prevents some core Monitor functions from tripping up any I/O device. There are still some memory operations (Fill, Move, Compare) that can clobber the I/O space if the parameters are entered to cross into that range. The Monitor also has it's own 32-entry JUMP table of which 21 are currently in use. Monitor memory space:

$E000 - $F7FF = 6KB ($F0D2-$F7FF is free)

I'll continue doing additional testing with the Monitor and make the initial release of code available along with the WinCUPL code for programming the ATF22V10CQ Glue chip. It's been a fun project so far... and I can continue extending this design for newer UARTs and additional I/O devices beyond the usual 65xx ones. Thanks to the usual suspects out here for feedback and insight as I've found some problems to work through!

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 03, 2017 2:23 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
I have found one last caveat with the SCC2691 for finishing up the BIOS. There are two test modes with the 2691; BRG Test Mode and X1/X16 Test Mode.

The first one is fairly straightforward and is documented in the datasheet. If a read is done to this register (shared address with the Command Register) it switches (toggles) between two Baud Rate tables. If the selected baud rate is 19.2K or 38.4K the two tables are the same and there's no issue. If the default baud rate is other than these two rates, then the baud rate changes and needs to be tracked. As I use 38.4K as the default baud rate, it's not a problem.

The second one is more problematic. The X1/X16 Test Mode doesn't appear to be documented in the datasheet or AN405. It's register location is shared with the Aux Command Register and operates as a toggle between test mode and normal mode. In test mode, the UART will not operate normally, i.e., no console capability. There are only two ways to exit the test mode; either read the X1/X16 Test Mode register a second time or a hardware Reset signal. As it's possible to have a program or memory operation of a monitor program perform a read function of this register, it's possible to have the system appear to lock up, meaning the console is dead.

As a workaround, I've decided to add a register read instruction for this to the NMI/Panic routine. If one manages to lock up the console or system, one push of the panic button will toggle the X1/X16 Test mode (in addition to saving registers, re-init of vector and I/O, etc.). If this doesn't bring it back, then a second push of the panic button might, which assumes the X1/X16 mode got toggled on the first push. It's unfortunate, but there's no easy way to track this and it's not really worth adding code to the monitor to ensure an accidental read is not done. It's also worth noting that the 2691 only uses 8 memory locations (for it's registers). As the Pocket SBC reserves 32-bytes per I/O select, it's possible to read the registers 4 times if a read is done for sequential addresses.

With the above now sorted, I have an initial version of the BIOS completed. A bit more testing will be done while I finish up the first release of the Monitor code to match up to the BIOS. I'm almost there :mrgreen:

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2

All times are UTC


Who is online

Users browsing this forum: No registered users and 16 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron