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

All times are UTC




Post new topic Reply to topic  [ 182 posts ]  Go to page Previous  1 ... 7, 8, 9, 10, 11, 12, 13  Next
Author Message
PostPosted: Sat Nov 28, 2020 12:25 pm 
Offline
User avatar

Joined: Thu Apr 11, 2019 7:22 am
Posts: 40
Hi Drass, I suppose both approaches have pros and cons. Yours is cleaner and more to the point, and I think it's the way logisim is supposed to be used. I suspect I abused logisim by attempting to make a schematic with it, but it's not designed to be a schematics tool. I think I decided to do so because I'm not yet comfortable with Eagle or EasyEda, particularly Eagle. So far this approach worked for me, but I'm tempted to switch to something more akin what you did, particularly if I add more pipeline stages to the model (It's currently 2 stages at >16 MHz and I estimated it could be 30 MHz with 3 stages, but that's off topic here).

Ideally, there should be a tool where you can both draw the schematic and simulate the circuit, otherwise it's like redrawing it all which is prone to errors as you say. I suppose if this combined tool exists it must be expensive and reserved to field professionals. I know that Eagle has a 'spice' simulator, it's an analogic simulation, so in theory it should be able to catch a lot of real circuit issues, but the little that I tried it I found that it's very limited in available components and not usable for a project the size of a CPU. For pure digital simulation there's nothing as effective as logisim, I think.


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 28, 2020 5:18 pm 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
Now that the basic piping for the CPU is more or less worked out, it's time to consider the target operating environment. As with the C74-6502, we will want this CPU to be plug-compatible with various 6502 systems. Near and dear to my heart are the VIC20 and C64, so both 6502 and 6510 pinouts are required. Ideally, the CPU will be able to run using the host's clock for full compatibility, but then also let fly with an internal 100MHz clock.

The CPU should be accurate enough to run existing software at the host's native clock-rate. That means paying careful attention to various NMOS ideosyncracies, like cycle count, Undocumented Opcodes, Decimal Mode flags, RDY write cycles and Partially Formed Addresses. Meanwhile, we can afford to relax compatibility at high-speed, where simplicity and raw performance are paramount.

For example, it makes sense to execute Decimal Mode operations with an additional cycle at high-speed rather than delay the critical path to accomodate them "in-line". Similarly, certain NMOS Undocumented Opcodes would require additional hardware to execute with the correct cycle-count. It's simpler to emulate them in microcode with additional cycles instead. These are sensible compromises as long as we can remain compatible with NMOS systems at their native clock-rates.

A general mechanism to support this is allow the CPU to execute muiltiple microinstructions per external cycle at high speed. By synching the CPU to the external clock via RDY wait-states, one or more microinstructions can execute during a single external cycle as needed for compatibility with existing software. (Specific microinstructions in the NMOS microcode can be marked internally as immune to RDY to achieve this result). Meanwhile, these extra cycles execute only rarely so the impact on performance at high speed is negligible. The net result is compatibility at the system clock-rate without harming performance at high speed -- exactly the balance we're looking for.

On another note, it would be great to have a compute-intensive demo to go along with this CPU. We can do little better than a snappy Mandelbrot-set for this purpose. David Given has written a very nice Madelbrot on a BBC Micro. It manages to paint a convincing Mandelbrot in about 12 seconds at 2MHz. That's impressive, and it seems like a great target application to stress-test CPU performance.

Retro-Mandelbrotting requires a lot of lookup-math on multi-byte quantities, so 24-bit addressing and 16-bit registers would help matters substantially. I turns out that most 16-bit 65816 instructions can be cycle-accurate with an 8-bit internal datapath. There are exceptions (a 16-bit INX will take an extra cycle, for example), but taking a page from ttlworks' design book, we can go a long way toward extended 24-bit addressing and 16-bit registers with a little extra hardware and an alternate "K2416" instruction-set. Definitely something worth including in this design.

Finally, the CPU will need its own high-speed synch RAM to execute at 100MHz. Resources on the host will be accessed via a dedicated asynch bus with wait-states. Writes to the host can be buffered and shadowed to high-speed RAM so subsequent reads can execute without pause. Similarly, ROM may be copied to high-speed RAM for faster access. But reads from I/O must be wait-stated. Ideally, we will want to pause the CPU as little as possible, so address decoding must be sufficiently granular and configurable to describe the host's memory map in some detail. It must also be fast enough to pause the CPU in the same cycle at 100MHz.

One means to achieve this is to allow RDY to pause the CPU as late as possible in the cycle, and use socketed GALs for address decoding. The GALs can manage wait-stating by snooping the address bus and tracking other signals that affect the host's memory map. The sky is the limit with this kind of thing, so this will be far from a general solution. The focus instead will be on a few key apps on the C64 to prove the point (Mandelbrot, of course, but perhaps also BASIC and GEOS).

So with all that in mind, here now is an "aspirational" spec for this project:

C74-100 CPU
  • 100MHz TTL 6502
  • Plug-compatible with 6502 and 6510 systems
  • NMOS 6502 instruction-set including Undocumented Opcodes
  • Alternate K2416 instruction-set with 24-bit addressing and 16-bit registers
  • On-board high-speed RAM and 100MHz internal clock
  • Configurable wait-state memory map for access to host resources
  • Synch to the host's clock for compatibility with timing-sensitive software
  • Snappy Mandelbrot, BASIC and GEOS demos

I'm currently adding Undocumented Opcodes to the NMOS microcode. The K2416 extensions will be next, and the rest is only at the concept stage. As ttlworks says, "it's a good thing we're not in a hurry". :)

Cheers for now,
Drass

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 28, 2020 5:52 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
Oh, very ambitious! Did you consider building a minimum viable spec? I do worry about scope creep, in case it converts nearly-finished into always-nearly-finished.

Having said which, of course the spec list is very interesting.

I would watch out for synchronisation trouble. If there's a high speed master clock, from which you can derive a low-speed platform clock for peripherals and the like, that might be fine. But if the high speed and low speed clocks are not synchronous, you can lose one or two cycles in crossing clock domains, and that increases the performance hit of the slow cycles. Or, if you don't get it right, you get something not quite reliable, which is even worse.


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 28, 2020 7:09 pm 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
BigEd wrote:
Oh, very ambitious! Did you consider building a minimum viable spec? I do worry about scope creep, in case it converts nearly-finished into always-nearly-finished.
It is ambitious, hence the “aspirational” qualifier. The minimum viable spec is the CPU running at 100MHz in a test SBC. This step needs to be completed in any case, so we can keep scope in check along the way. On the other hand, working with a host at speed is a very inspiring next step which completes the vision. I decided to include it at the outset for that reason, and as a guide for design decisions as we go.

Quote:
Having said which, of course the spec list is very interesting.
Yes, thinking about it has been a lot of fun! :D

Quote:
I would watch out for synchronisation trouble ... if the high speed and low speed clocks are not synchronous, you can lose one or two cycles in crossing clock domains, and that increases the performance hit of the slow cycles. Or, if you don't get it right, you get something not quite reliable, which is even worse.
You’re right to point this out. Things get tricky if the clocks are not synchronized, and there is potential for “lost” cycles when crossing clock domains. One of several potholes along the way here.

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 30, 2020 12:46 pm 
Offline
User avatar

Joined: Sun Nov 27, 2011 12:03 pm
Posts: 229
Location: Amsterdam, Netherlands
Drass wrote:
Near and dear to my heart are the VIC20 and C64, so both 6502 and 6510 pinouts are required.

Could such a 'plate of TTL with memory sauce' fit inside a VIC20 or C64 case ?


Top
 Profile  
Reply with quote  
PostPosted: Mon Nov 30, 2020 11:08 pm 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
Windfall wrote:
Could such a 'plate of TTL with memory sauce' fit inside a VIC20 or C64 case ?
It will be much too big! The CPU might as well have it’s own carrying case. :) It will connect to the host through a ribbon cable as shown in the pic of the C74-6502 below.
Attachment:
305BDCF0-E87F-4C38-953C-DDDB23EAFA08.jpeg
305BDCF0-E87F-4C38-953C-DDDB23EAFA08.jpeg [ 132.92 KiB | Viewed 2028 times ]
The asynch bus going to the host runs at the host’s native speed so signals should have no trouble making the journey across the ribbon.

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 01, 2020 1:31 am 
Offline
User avatar

Joined: Sun Nov 27, 2011 12:03 pm
Posts: 229
Location: Amsterdam, Netherlands
Drass wrote:
It will be much too big! The CPU might as well have it’s own carrying case. :)
Get your answer ready for the inevitable 'So what is it ?'. :shock: :D
Drass wrote:
It will connect to the host through a ribbon cable as shown in the pic of the C74-6502 below.
Or maybe you could consider a flex PCB version, so you can fold it up, and fit it inside after all.


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 01, 2020 1:09 pm 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
Windfall wrote:
Get your answer ready for the inevitable 'So what is it ?'. :shock: :D
Yeah, I know! It’s hard to fathom just how deliriously impractical this is! :)

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 01, 2020 3:06 pm 
Offline
User avatar

Joined: Sun Nov 27, 2011 12:03 pm
Posts: 229
Location: Amsterdam, Netherlands
Drass wrote:
Yeah, I know! It’s hard to fathom just how deliriously impractical this is! :)
It's a (technical) work of art. Some become one. Some are by design. :wink:


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 12, 2020 6:57 pm 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
I'm making progress working down the spec list published above, and I'm happy to report that the Logisim model for the CPU now supports the NMOS quirky behaviours we've all come to know and love! :)

Here is a summary of items considered:
  • The modify cycle of RMW instructions is a write cycle
  • RDY will not pause write cycles
  • Decimal Mode flags other than the C flag are left in an "invalid" state
  • Decimal Mode results for invalid BCD inputs (i.e., digits > 9) match those generated by the NMOS 6502 and 65816 CPUs (see http://www.6502.org/tutorials/decimal_mode.html)
  • Partially Formed Addresses (PFAs) are generated during Dead Cycles, as outlined here: https://c74project.files.wordpress.com/ ... cycles.pdf
  • Vector addresses of JMP Indirect instructions ($6C) wrap on a page boundary
  • Undocumented Opcodes are supported (with certain limitations)
  • An NMI will either hijack an IRQ in progress, interrupt the IRQ ISR or be ignored depending on the timing and length of the NMI signal.

The "NMOS Quirks and Quarks" PDF attached below provides greater detail on these items, including on the implementation of various NMOS Undocumented Opcodes. (For those interested, this document is an excellent reference for NMOS 6502 Undocumented Opcodes in general).

NMOS compatibility has been road-tested extensively using the C74-6502 with a wide variety of C64 games, demos, applications and cartridges. We can expect that this CPU will likewise be able to run lots of NMOS 6502 software as well. This implementation takes a few additional shortcuts with the "Unstable" Undocumented Opcodes (details in the pdf below), but I am hoping these compromises will have no practical impact on operation (I know, I know, famous last words! :roll: ). The changes were made to eliminate dedicated logic in the CPU which would be rarely if ever used, so it's a sensible compromise even at the cost of minor incompatibilities.

I used my own simple test suite to exercise the Undocumented Opcodes with the Logisim Model. This is a basic set of tests where each opcode is executed and the results compared to anticpated values. There is no attempt to be comprehensive in these tests, nor otherwise to test boundary conditions. Still, it's quite effetive in catching basic errors. The code for the tests is attached below.

Attached also is the updated Logisim file. This version has now passes the following tests:
  • Dormann 6502 Test Suite
  • Bruce Clark 6502 Decimal Mode Tests (http://www.6502.org/tutorials/decimal_mode.html, code attached below)
  • Drass Simple Undocumented Opcode Test Suite (6502_ufo_test)
  • All unit tests for the other NMOS specific functions

Alright, next up is the K2416 instruction-set, which adds support for a 24-bit address space and 16-bit registers. Nearly all 65816 instructions and addressing modes are included, and the CPU will be able to switch between NMOS and K2416 modes on the fly (much like the 65816 does between Emulation and Native Modes). More on that later.

Cheers for now,
Drass


Attachments:
Attachments.zip [84.64 KiB]
Downloaded 125 times
C74-100 NMOS Quirks and Quarks.pdf [154.28 KiB]
Downloaded 100 times

_________________
C74-6502 Website: https://c74project.com
Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 26, 2020 11:28 pm 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
In for a penny, in for a pound!

The K2416 microcode is largely done, but it's so close to a full Native Mode 65816 implementation that it seems a shame to stop short. After kicking it around with Dr Jefyll and ttlworks, it seems worthwhile to consider "software compatibility" with the 65816. Most of the required registers are in the design already by virtue of K2416, so the main issue is the 65816's wider internal datapath.

Taking the TTL ALU to a full 16-bits is not realistic. Instead, the approach must be to add cycles as necessary to deal with 16-bit quantities. The 65816 itself does this in many situations. For instance, instructions that access data memory add a cycle when 16-bit memory is enabled. That behaviour can be easily matched with an 8-bit internal datapath. But there are definitely situations where the wider path beneficial. Most notably, the 65816 is able to adjust the high-byte of addresses without an additional cycle. Absolute Indexed instructions, for example, take the same number of cycles whether or not a bank boundary is crossed. Similarly, a 16-bit value that straddles a bank boundary does not force an extra cycle.

In these and other situations, the TTL CPU would need an extra cycle to do the same job. If we're careful, this extra cycle would need to be added only if the specific circumstances arise (that is, only if a boundary is indeed crossed). The TTL CPU already has mechanisms that check the internal carry during address calculation, and to add an extra cycle if necessary. Extending this mechanism to a new set of conditions will take some effort, but the approach seems promising.

An initial review suggests that an 8-bit ALU would require extra cycles as listed below (to be clear, extra cycles above and beyond the cycle-count that the 65816 would use in the same circumstances). Specifically, would need an extra cycle when:
  1. The DL register triggers a page-crossing,
  2. Stack-relative addressing triggers a page-crossing,
  3. A 16-bit increment or decrement instruction overflows or underflows the low-byte (e.g. INY),
  4. A 16-bit value straddles a bank boundary (when the M flag = 0),
  5. A 16-bit register is transferred (e.g. TXA when the M flag = 0),
  6. 16-bit indexing is used with Direct Indexed Addressing, or with Absolute, Long or Indirect Indexed Addessing and a bank boundary is crossed,
  7. 8-bit Direct Indexed Addressing crosses a page boundary,
  8. A Decimal Mode operation is used (which is unrelated to the 16-bit datapath but still an exception).

As an example of how this might play out, consider an ORA (dir),Y instruction where the DL register set to a non-zero value and both the M and X flags set to 0 (i.e. Direct Page is offset and we have 16-bit memory and registers). Here we have three possible additional cycles. The first is required if the sum of DL and the operand crosses a page boundary, a second if indexing with Y crosses a bank boundary, and a third if the 16-bit data value being accessed straddles a bank boundary. So, whereas the 65816 takes 8 cycles to complete this instruction, the TTL CPU would take 11 cycles if all boundary conditions were triggered (and 8 if none were).

The same penalties would apply to various other addressing modes (see table below), but not to stack push and pull operations. For those we can use the 16-bit incrementer to manipulate the stack pointer in a single cycle. The current incrementer circuit would work as is for pull operations, and with a small change as a decrementer for push operations. The CPU would then be cycle-accurate for all instructions that require these stack operations (including BRK, RTI, JSR, RTS, and all register pushes and pulls).

Another potential exception is, oddly enough, the block move instrutions -- MVN and MVP. They each take 7 cycles to iterate through every byte to be moved. The looping action can be implemented by inhibiting FetchOpcode while the block move is in progress, essentially re-executing the same opcode for every byte until the block is done. The X, Y and C registers are used as 16-bit loop variables to maintain the source address, destination address and loop-count respectively; and DBR is used as a temporary register to hold the destination bank. Honestly, the opcode feels more than a little awkward, but you can't argue with the economy of it all.

Ok, so what extra hardware is required for all this? Here is what I see so far:
  • The 16-bit incrementer needs to also handle decrement operations,
  • A dedicated incrementer is required for the upper 8-bits of the address bus (the existing incrementer is fixed to the lower 16-bits and cannot be reused without adding signficant switchig delay),
  • The incrementer carry must be tested (in addition to the ALU carry) to determine if an additional cycle is needed,
  • The cycle-adding mechanism needs detect the various conditions listed above (including the ability to inhibit FetchOpcode for MVN/MVP),
  • The datapath needs to be extended to support direct transfers from X and Y to the address bus for MVP and MVN.

This is a fairly contained set of changes to hardware. There is a lot of microcode gymnastics involved (and squeezing yet more control signals onto an already full control RAM gives me some pause), but on the whole nothing here looks prohibitive. Interestingly, the erosion in performance seems tolerable, which is to say that the additional cycles strike me as a very reasonable tradeoff. A little bit of care while programming would minimize them, but we're not likely to quibble about a cycle or two at 100MHz! :wink:

One interesting variation is that Emulation Mode in this case would be fully NMOS compatible. This would allow the CPU to run fussy C64 software on boot up. The downside of course is that existing software that relies on the 65816's extended Emulation Mode would not work correctly. (I suppose to be truly general one would need to be able to select between 65816, 65C02 and NMOS 6502 compatible Emulation Modes ... hmmm).

Alright, so is it full-steam ahead with the 65816? Well, I'm not sure yet. I'm still working things out and a show-stopper may yet materialize (or perhaps a collection "show-dampers" that amount to a show-stopper). I thought I would share the progress to date nevertheless. Let me know if I'm missing something obvious (which is likely given that I've never programmed a 65816). As always, any and all input is very much welcome! (Thanks Dr. Jefyll for working through a couple of issues with me).

Cheers for now,
Drass

P.S. By way of illustration, the table below compares 65816 cycle counts with those of the TTL CPU in Native Mode. The opcode in question is an ORA, although the same cycle counts apply to several other opcodes.
Code:
MODE      65816        TTL CPU
--------- ----------- -------------
(dir,X)   7-m+w       +x0, +dx, +mx 
stk,S     5-m         +sx
dir       4-m+w       
[dir]     7-m+w       +mx
imm       3-m         
abs       5-m         +mx
long      6-m         +mx
(dir),Y   7-m+w-x+x*p +ix, +dx, +mx
(dir)     6-m+w       +mx
(stk,S),Y 8-m         +ix, +mx
dir,X     5-m+w       +x0, +mx
[dir],Y   7-m+w       +ix, +dx, +mx
abs,Y     6-m-x+x*p   +ix, +mx
abs,X     6-m-x+x*p   +ix, +mx
long,X    6-m         +ix, +mx

Legend:
--------------------------------------
m    = 1 if m flag is on
x    = 1 if x flag in on
w    = 1 is DL != 0
p    = 1 if a page boundary is crossed
x0   = 1 of X Flag = 0
dx   = 1 if DL + Operand crosses a page boundary
mx   = 1 if the 16-bit data value straddles a bank boundary
sx   = 1 if stack-relative addressing crosses a page boundary
ix   = 1 if indexing crosses a bank boundary

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 27, 2020 10:53 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
Interesting, and hopeful!

I had a thought. If we ignore MVN for now, the nature of the bank byte in DBR is that we either need to produce the present value, or the incremented value.

So, if we add an 8 bit incrementer to the DBR, and add a carry-select kind of mux, the increment can always be performed, and at a relatively low time cost, we only need to
- use the carry in to select either DBR or DBR+1
- possibly write back the DBR+1 to DBR in the next cycle. Actually, we could just always write back whichever value we output, whether it is incremented or not.

Does that work out?

Not sure about PBR, not sure about MVN.


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 27, 2020 6:37 pm 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
What a great idea Ed! :D

Indeed, with lookahead for the first 16 bits, a carry-select incrementer can manage a 24-bit increment within the required 6.5ns. So that eliminates the additional cycle in these two situations:
  • A 16-bit value straddles a bank boundary (when the M flag = 0),
  • 16-bit indexing is used with Absolute, Long or Indirect Indexed Addessing and a bank boundary is crossed.

Ok, we're on a roll now ... we could add a 16-bit incrementer to the ALU and adjust the flags logic to cope with 16-bits. The lower 8-bit of the Z flag could be calculated within the EXECUTE stage and the upper 8-bits during the WRITEBACK stage. That would eliminate the extra cycles for these two:
  • A 16-bit increment or decrement instruction overflows or underflows the low-byte (e.g. INY),
  • A 16-bit register is transferred (e.g. TXA when the M flag = 0).

You know, it's tempting ... there is almost enough time to use a carry-select incrementer in the ALU to adjust the high-byte during address calculation. The 8-bit FET adder takes 5.9ns. The the carry-select with a 74AUC2G53 would be 7ns. That's just 500ps too long! I'm tempted to run a test PCB to try it. If it works, then the following additional cycles would also be removed:
  • The DL register triggers a page-crossing,
  • 16-bit indexing is used with Direct Indexed Addressing and DH = 0
  • Stack-relative addressing triggers a page-crossing,
  • 8-bit Direct Indexed Addressing crosses a page boundary.

That would leave only two situation where an extra cycle was added:
  • 16-bit indexing is used with Direct Indexed Addressing and DH != 0,
  • A Decimal Mode operation is used.

Dang! That's pretty close to a 65816! :shock:

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 27, 2020 6:44 pm 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
Quote:
Not sure about PBR, not sure about MVN.
Oh, yeah, I forgot ...

PC always wraps on a bank boundary as far as I know. Maybe someone can correct me if I'm wrong? I thought MVN/MVP also wrapped on bank boundaries but I'm now thinking I must br wrong about that. I'll have to check it. Either way, the 24-bit carry-select incrementer could still manage it I think.

Honestly, I'm amazed we can get this close to a 65816 with an 8-bit ALU. Wow ...

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 27, 2020 6:52 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
Wow indeed!

(One of the things which stands out when you look at the 65816 die shot is that the datapath is really long and the 'PLA' really wide. For the datapath to be so long, without empty space, there could be a few extra bits in there which make a big difference - such as, more than one incrementer... and indeed, it turns out there are details in the now-expired patents, see the thread.)


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 182 posts ]  Go to page Previous  1 ... 7, 8, 9, 10, 11, 12, 13  Next

All times are UTC


Who is online

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