6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 10:49 pm

All times are UTC




Post new topic Reply to topic  [ 41 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Fri Dec 31, 2010 5:19 am 
Offline

Joined: Fri Dec 31, 2010 5:05 am
Posts: 9
I've been working on a logic-based emulator - with gcc -Os it compiles into less than 4K (not counting 'shell'), which means it'll be a good choice for running on an AVR or ARM Corrtex. In theory one could make a one-chip Apple I with this on a very cheap LPC 111x.

EDIT: I haven't commented it enough yet to make sense, but it's now an Apple I emulator and can run at least basic BASIC programs. The stripped -Os i386 a.out (including basic and woz mon) is ~14K.

Check it out here: http://code.google.com/p/chadslab/sourc ... nk%2Fm6502 (2-clause BSD licensed)

What I really want to do is make a tight Verilog version and see if I can make something smaller than even Arlet's core (EDIT: I doubt I can make one that's worth the effort, but I might look into optimizing Arlet's...)


Last edited by happycube on Sat Jan 01, 2011 11:51 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 31, 2010 9:54 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
Nice! I'm sure an approach which takes advantage of the regularity in the instruction set - and leaves to chance(*) the behaviour of unspecified opcodes - will result in a small and tidy implementation.

I've collected a few pointers and notes to test programs here - note that Ruud's zip file update contains a later version of TTL6502.ASM than the one he links to direct.

Cheers
Ed
(*) by which I mean the high level source doesn't over-specify, and the compiler or synthesis tool will do whatever costs least (hopefully.)


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 31, 2010 12:30 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
happycube wrote:
What I really want to do is make a tight Verilog version and see if I can make something smaller than even Arlet's core ;)


Do you have a similar structure in mind for the Verilog version, or do you intend to rewrite the whole design ?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 31, 2010 6:33 pm 
Offline

Joined: Fri Dec 31, 2010 5:05 am
Posts: 9
@BigEd - thanks! I actually used your page to find rb65 (I don't have an assembler for the latest version) I'm having issues with the stack stuff near the end of it and can't figure out what it's supposed to do in the first place. (This probably means BCD is still wrong ;) )

@arlet - yeah, aside from the natural differences in going to HW... address generation would be a bit different for instance. (edit: This assumes that I can actually wrap my head around it...)

I posted a version with some debug statements removed and it's just over 3K with 32-bit gcc's -Os, and a bit under 3K compiled for AVR. So if you don't have much ROM code and an external serial/SPI SRAM chip, this could easily work with even an 8K AVR. :)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 31, 2010 7:40 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
Hmm, looking briefly at the latter part of the tests, I see that this test of Ruud's fails on a real NMOS 6502:
Code:
      lda   #0
      pha      
      plp
      php
      pla
      cmp   #$20
M382
      bne   M381

and, sadly, neither run6502 or lib65816 get the right answer either, which is that the final value of A is #$30 - is that one of your failing cases? py65 gets this one right!

(Of course, Ruud's tests are for his implementation, and it's possible that he didn't intend to model this detail. Later versions of his test suite mask this test.)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 31, 2010 7:49 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
My 6502 model doesn't get this right either. I only set bit 4 when the P register is pushed in a BRK, but not during a regular PHP. Bit 5 is never set.

Both are easy to fix, if anybody cares.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 31, 2010 7:54 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
The nice thing about fixing these little things is that the same tests can run and pass on all models. Probably these niggles wouldn't break software, and they must be very low on the priority list.

The rule on B is that it's always written as a 1, unless it's being written as a response to IRQ(*). This is because there's no storage for it, just a pull-down(**) which is generally inactive, and so generally it behaves like the unused bit.

Cheers
Ed

(*) aargh, see later: I may not have this right. It's right that there's no storage, but the exact situations which affect the pushed value might not be as I say. I'll re-edit when I know more. My earlier test was on a real NMOS 6502 using PHP/PLP, so the result for that specific case remains valid.

(**) aargh, not a pulldown, a bit more subtle than that.


Last edited by BigEd on Sat Jan 01, 2011 6:17 am, edited 3 times in total.

Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 31, 2010 8:18 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
BigEd, perhaps you can answer this with the Visual6502 stuff you've done. Since most hardware will hold the -IRQ line in the asserted state until the source of the interrupt has been addressed, it's easy to see that B can just reflect the state of the -IRQ line as-is. I wonder, though, what will happen if the -IRQ line is asserted just long enough for the CPU to register an interrupt, and negated afterwards?

That is, if IRQ is treated like ABORT or NMI, will B continue to be 0 when the flags are pushed? I'm wondering this because when the flags are pushed, -IRQ will be high again.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 31, 2010 8:48 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
The quick answer is that there are several bits of state on the way from IRQ the pin to the B bit pulldown, so I'd very much expect the right thing to happen - it's not a direct connection, but a saved status (which is also subject to RDY stalling the pipeline)

The longer answer is that I'm not sure, and I've lost confidence in my earlier answer! I'm not even sure if visual6502 is behaving correctly, which would be very interesting indeed. URLs like these are what's needed to explore this question:
http://visual6502.org/JSSim/expert.html ... ,DPControl

where
- a and d are the address and data for a test program
- irq0 and irq1 are the half-cycles in which IRQ is changed to 0 then 1

I'll have to look at this more deeply when I have a slightly clearer head, with reference to this tutorial and also this statement
Quote:
software instructions BRK & PHP will push the B flag as being 1.
hardware interrupts IRQ & NMI will push the B flag as being 0.
made elsewhere.

It's a shame that I've added confusion instead of clarity, to an area where confusion is easily come by.

Cheers
Ed

Edit: silly me: I was trying to test IRQ without first using CLI, so I was never IRQing, just falling off the end of my program into a BRK.


Last edited by BigEd on Sat Jan 01, 2011 5:34 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 31, 2010 10:20 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
Ok, I've fixed my model's handling of the B flag.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jan 01, 2011 12:04 am 
Offline

Joined: Fri Dec 31, 2010 5:05 am
Posts: 9
Yup, that's where I was stopped - thanks for the tips, that got me moving again and now the entire test passes! (it's 3181 bytes now...)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jan 01, 2011 12:04 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Nice! Arlet... And you fixed decimal mode too?...

Thank God for forums!

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jan 01, 2011 12:09 am 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
Yes, decimal mode is also implemented. See this post and the replies:

http://forum.6502.org/viewtopic.php?p=12534#12534


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jan 01, 2011 6:03 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
OK, I've found my silly error: I was running the visual6502 simulator and thought I was testing IRQ, but hadn't used CLI so in fact I was running off the end of my test program and actually seeing BRK.

Short answer again: B is affected by the pending interrupt pipeline control signal, not by the 'live' input from the IRQ pin.

Here's an URL which uses CLI and sets off a very short IRQ pulse:
http://visual6502.org/JSSim/expert.html ... ,DPControl
You'll see that the D1x1 signal (as named by Balazs in his giant schematic) latches the pending interrupt, causes the pushed B to be zero, and is then cleared during the vector pull. This same signal is gated by 'Fetch' to produce 'ClearIR' which is what causes the sequencer to act as if it just fetched a BRK in handling any of the cases IRQ, NMI, RESET.

Note that the visual6502 sim reports the P register as if B was a storage element: in fact it is observing the node which conditionally drives the data bus during a push of P. See here:
http://visual6502.org/JSSim/expert.html ... &zoom=10.7
This node is the output of an inverter (I was wrong about the pulldown), and is a doubly-inverted D1x1. There are only 6 storage elements written by PLP.

Brad Taylor's statements:
Quote:
software instructions BRK & PHP will push the B flag as being 1.
hardware interrupts IRQ & NMI will push the B flag as being 0.
which I quoted earlier are now borne out by what I see in visual6502. I notice that RESET also uses D1x1 and therefore would push a zero for the B flag, except in the NMOS 6502 the three pushes in this case are masked out (as discussed previously) - I imagine that the 65C02 will push with B as 0.

Cheers
Ed

(Edit: link to production version as it has been updated)


Last edited by BigEd on Mon Jan 03, 2011 4:43 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jan 01, 2011 6:21 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
BigEd wrote:
Brad Taylor's statements:
Quote:
software instructions BRK & PHP will push the B flag as being 1.
hardware interrupts IRQ & NMI will push the B flag as being 0.
Except, it seems, in another case: if an NMI interrupts a BRK, D1x1 does not register a pending interrupt and B is pushed as 1. The vector used is the NMI vector. So, if an NMI handler inspects the pushed P it will normally see B as 0, but not always.


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 24 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: