Jump to content
IGNORED

Geneve Clock Chip MM58274 source?


FarmerPotato

Recommended Posts

2 hours ago, mizapf said:

 

Preventing direct access to hardware is one of the reasons why the privileged mode was invented for processors. This could be done on the TMS99105 since it has such a mode. You cannot restrict the address access, but you could use a CRU bit to guard the clock hardware, and the TMS99105 allows access to CRU addresses 1C00 and higher only in privileged mode.

Yes, but it's still tricky to apply the tools to the problem at hand. Like you said, 99105 does not have "protected memory" features (The TM 990s with map feature with LMF instruction sort of do.)

 

I am going to place all of MDOS in user mode. (So the supervisor is invoked anytime MDOS does an XOP or there is an interrupt.) 

 

But it's MDOS itself reading and writing the clock. For instance to implement the DATE command, the XOPs for get/set date time, etc.

 

To present a hardware abstraction layer, the memory mapper (in the FPGA) would have to act when it sees certain addresses in certain modes.

 

I could do that... I've thought it all through. Some ways are:

 

1. Implement page faulting for certain mode bits+addresses. Raise INT2 for page fault. Handle faults in software. Really gross--essentially you have to decode the offending instruction to implement it.

 

2. Put a big ball of FPGA glue on those addresses, which synthesizes the expected read/write behavior at F130-F14F ports. If I'm doing that, I might as well use any clock chip behind the glue. 

 

3. I would prefer to use real chips, and just attach the MM58174 clock chip to the expected memory-mapped ports. These would be F130-F13F when MDOS mode is active.

The FPGA would barely get involved. It just  outputs the page register value to the bus like any other memory cycle. 

 

So my need is still to understand in detail what those clock memory-mapped ports are in MDOS mode. Why they seem to be read at F130-F13E but written at F130-F14E. And why I see MDOS write F13E as both the clock settings register CKSTRG and a data register.

 

 

Link to comment
Share on other sites

  • 2 months later...

I found some MM58174 clock chips for $0.75

 

The only difference vs the MM58274 that is the Geneve 9640, is that '174 does not have tens of years.

 

So it could be used, but with the tens-of-years register hard-wired to return '2'. It would be accurate
until 2030! And that's pretty far away!

 

On the other hand, Microchip MCP795W10 is $1.50, has SPI interface, and the FPGA memory-mapper could simulate the 58274
interface to it. To ensure compatibility.

 

MCP795W10 has the needed features, plus hundredths of seconds and year to 2399. Battery-backed SRAM, and helpfully records
when the power failed or came back on. Has a watchdog timer, two alarms, two external counters, square wave generator, 128 bytes EEPROM.
 

I'm inclined to use MCP795W10 or similar, connected to the memory mapper. So compatibility comes with a ball of FPGA glue, with wait states if needed.

 

  • Like 4
Link to comment
Share on other sites

You might also want to check here for the MM58274. One vendor on the list says they have nine of them and the other says they have one. Only the one with one lists a price ($26). Both are reliable vendors.

 

Of course, this one says they have 26,000 of them, but they are a Chinese source that sometimes plays a bit fast with their products. When they're good, they're really good, but when they're bad, the product is abysmal. I've bought a few things from them in the past and the results were mixed, so I've tended to avoid them unless they were one of the primary remaining sources for the item.

  • Like 1
Link to comment
Share on other sites

17 hours ago, Ksarul said:

You might also want to check here for the MM58274. One vendor on the list says they have nine of them and the other says they have one. Only the one with one lists a price ($26). Both are reliable vendors.

 

Of course, this one says they have 26,000 of them, but they are a Chinese source that sometimes plays a bit fast with their products. When they're good, they're really good, but when they're bad, the product is abysmal. I've bought a few things from them in the past and the results were mixed, so I've tended to avoid them unless they were one of the primary remaining sources for the item.

 

Yeah, I found utsource.com a while back.  It appears to go to Shenzhen and HK marketplace vendors, not their own stuff. I have worked with two on alibaba.com (who have sent me working 4464, 99105 and 9958). Polida2008 (eBay) has been good so far--Polida is part of a similar company.  

I've RFQed on utsource.com for some  thinly listed stuff and got a "sorry, we have no stock". 

 

I think the MM58274 is out of the running. Even at $7 it would be a bad choice. I'd rather go to the effort to make a memory-mapped interface around a $1.50 chip, that is still in production.

 

Link to comment
Share on other sites

On 11/9/2020 at 7:33 PM, FarmerPotato said:

The MM58167 has several interesting features that the '274 does not. However, it's not register-compatible AND it has no years (why?)

The clock I designed myself, for my TI 99/4A, uses the MM58167. Back then, that one had thousands of a second. There was some other type (don't remember the number) that had years, but only full seconds. I wanted the resolution.

Link to comment
Share on other sites

2 hours ago, apersson850 said:

The clock I designed myself, for my TI 99/4A, uses the MM58167. Back then, that one had thousands of a second. There was some other type (don't remember the number) that had years, but only full seconds. I wanted the resolution.

I like the MM58167 for that reason, too. 

 

Microchip has 0.01s.  For my first TI digital watch, I picked the one that had 0.01s on stopwatch. Used the .01 as a random number generator, instead of dice!

 

Details are here, for each chip I have compared:

https://docs.google.com/spreadsheets/d/1LGUA2ZyWv_TxHcGTVgS_4XnP801m3evRI5krbs0MbAg/edit?usp=sharing

 

I think the Microchip has a programmable oscillator output, which you can connect to the event counter input, so you could have your own adjustable timer.

 

Link to comment
Share on other sites

  • 1 year later...

Today my brain delivered a “duh!” solution to a clock chip. 
 

when I surveyed chips, I liked the MCP795W10 except it breaks compatibility. Fixing that with FPGA glue is complicated. 
 

But my brain told me “User programs have no business setting the clock! It is only set in BIOS at startup!”
 

GeneveOS and GPL are user-mode programs. 
 

So I don’t implement write access to the clock. Make them read-only addresses. 


The BIOS has its own code to read/set the clock. 
 

I can implement read-only compatibility. The FPGA will read the clock chip about every 1s, and cache that. The rest is just wiring the right bits to the data bus. 
 


 

 

 

  • Like 3
Link to comment
Share on other sites

I am copying @InsaneMultitasker on this.  It has been awhile since I chased around the code on the multi-task swapping in MDOS, however I think you are going to run into issues caching at every 1 second.  I think the Geneve sees every 0.1 second, and maybe even finer detail than that for the task swapping.

 

I think code in the MDOS\HEAD\xxx files in the OSHEAD1S and I think the OSTASKS file may give you some info.  Another thing to review would be MAME's updating of the clock chip information in the Geneve emulation.

 

FYI, the Geneve is always task swapping, even when running an application as the CLI is a task by itself, but just put to "sleep" during the running of another program.  Several programs "waken" the CLI as a drop back to the CLI program allowing an exit back to the program when returning back to the program.

 

Beery

 

 

 

2 hours ago, FarmerPotato said:

Today my brain delivered a “duh!” solution to a clock chip. 
 

when I surveyed chips, I liked the MCP795W10 except it breaks compatibility. Fixing that with FPGA glue is complicated. 
 

But my brain told me “User programs have no business setting the clock! It is only set in BIOS at startup!”
 

GeneveOS and GPL are user-mode programs. 
 

So I don’t implement write access to the clock. Make them read-only addresses. 


The BIOS has its own code to read/set the clock. 
 

I can implement read-only compatibility. The FPGA will read the clock chip about every 1s, and cache that. The rest is just wiring the right bits to the data bus. 
 

 

  • Like 2
Link to comment
Share on other sites

4 hours ago, 9640News said:

I am copying @InsaneMultitasker on this.  It has been awhile since I chased around the code on the multi-task swapping in MDOS, however I think you are going to run into issues caching at every 1 second.  I think the Geneve sees every 0.1 second, and maybe even finer detail than that for the task swapping.

 

I think code in the MDOS\HEAD\xxx files in the OSHEAD1S and I think the OSTASKS file may give you some info.  Another thing to review would be MAME's updating of the clock chip information in the Geneve emulation.

 

FYI, the Geneve is always task swapping, even when running an application as the CLI is a task by itself, but just put to "sleep" during the running of another program.  Several programs "waken" the CLI as a drop back to the CLI program allowing an exit back to the program when returning back to the program.

 

Beery

I am not sure if we're all thinking along the same lines with respect to the Geneve clock chip.   Some background for context switching:

 

From a multitasking perspective, there is no context switching while the OS itself is executing its own code (ie, an XOP, interrupt handling, etc) except for the task handling routines.  Level 1 interrupts are prioritized in order of importance as defined by the OS:  bus interrupt->video Interrupt->key interrupt.   There are a few programs that chain or intercept the interrupt handler, similar to how you chain the /4A user interrupts at 0x834c; the difference is that you cannot (easily) override the /4a ISR in ROM whereas on the Geneve it is simple to replace the address in RAM.   In typical situations, the video interrupt routine manages the slice count for the current task; if the current task's slice count expires, the context is switched to the next task.  Resolution is equivalent to the task's slice timer * vdp interrupt frequency.  If a task is allocated 6 slices and VDPINT is 1/60th second, the task will run 6 * 1/60th second = 6/60=1/10th of a second before yielding to the next task. 

 

The short version is that the clock chip does not factor into context switches.  It seems that @FarmerPotato's approach to cache the date/time would be more than adequate for file operations and display of the date/time.  Hopefully, I didn't misinterpret what you were driving at. 

  • Like 2
Link to comment
Share on other sites

1 hour ago, InsaneMultitasker said:

 

The short version is that the clock chip does not factor into context switches.  It seems that @FarmerPotato's approach to cache the date/time would be more than adequate for file operations and display of the date/time.  Hopefully, I didn't misinterpret what you were driving at. 


Yeah, I’m only thinking of how to implement the real time clock. The necessary thing is for the read addresses to look just like the 58274, for the XOP to work, and for any programs which access it directly. And that’s for time stamps mostly. 
 

GeneveOS sees a Hardware Abstraction Layer at all times. It can read the RTC, it’s just the writes to it that won’t do anything. 
 

VDP interrupts also will look as expected.
 

Except …  there is a supervisor behind GeneveOS or GPL, so it has layers like this:

 

9958 fires interrupt

9901 prioritizes it as INT1

99105 exits user mode, turns off memory mapping, enters supervisor mode, vectors through BIOS ROM INT1. 

 

BIOS  might do its own stuff in there first…
 

Then, If GeneveOS was the interrupted process, great. It forwards the INT1 back to it. 

To do it, BIOS copies R13-R15 back to GeneveOS’ INT1 workspace, copies GeneveOS INT1 vector into R13-14, and does a RTWP back into user mode. (Memory map switches back to the user map.)

 

GeneveOS is unaware that anything weird happened, though a few cycles were lost. Can afford that on our faster 99105.

 

 

IF GeneveOS had issued a LIMI 0, then the INT1  just marks a flag in the process record, and immediately returns.

The INT1 is delivered later when GeneveOS does a LIMI 4.

 

(Any LIMI from user space causes a PRIVOP interrupt to BIOS, which figures out what to do.) 

summary: GeneveOS doesn’t  get INT1 directly but it gets it pretty quickly.

 

 


There are also weird corner cases. Not going into that now.  But I know how TX990 and RX operating systems solved the problems. 

Link to comment
Share on other sites

9 hours ago, InsaneMultitasker said:

In typical situations, the video interrupt routine manages the slice count for the current task; if the current task's slice count expires, the context is switched to the next task. 

Oh, we have preemptive multitasking in GeneveOS? Round-Robin scheduling?

 

I never really exploited the multitasking capabilities, sadly.

 

Link to comment
Share on other sites

9 hours ago, InsaneMultitasker said:

I am not sure if we're all thinking along the same lines with respect to the Geneve clock chip.   Some background for context switching:

 

From a multitasking perspective, there is no context switching while the OS itself is executing its own code (ie, an XOP, interrupt handling, etc) except for the task handling routines.  Level 1 interrupts are prioritized in order of importance as defined by the OS:  bus interrupt->video Interrupt->key interrupt.   There are a few programs that chain or intercept the interrupt handler, similar to how you chain the /4A user interrupts at 0x834c; the difference is that you cannot (easily) override the /4a ISR in ROM whereas on the Geneve it is simple to replace the address in RAM.   In typical situations, the video interrupt routine manages the slice count for the current task; if the current task's slice count expires, the context is switched to the next task.  Resolution is equivalent to the task's slice timer * vdp interrupt frequency.  If a task is allocated 6 slices and VDPINT is 1/60th second, the task will run 6 * 1/60th second = 6/60=1/10th of a second before yielding to the next task. 

 

The short version is that the clock chip does not factor into context switches.  It seems that @FarmerPotato's approach to cache the date/time would be more than adequate for file operations and display of the date/time.  Hopefully, I didn't misinterpret what you were driving at. 

OK, I was thinking the task switching was tied to the clock, not to the video interrupts.  Makes sense for the video interrupts.

 

8 minutes ago, mizapf said:

Oh, we have preemptive multitasking in GeneveOS? Round-Robin scheduling?

 

I never really exploited the multitasking capabilities, sadly.

 

Yeah, there is a fair amount of potential.  I demonstrated with the TIPI from MDOS mode, it was possible to launch multiple tasks such as multiple copies of BBS software.  It would be possible as well to have multiplayer games running as well.

 

When I wrote Windows 9640, it was possible to be running multiple programs and switching between one and another.  Now looking back on it, it wasn't all that great and I would do things differently if I had the time.  I have played around with the GEME code Michael Riccio wrote over the last year as I really liked his task handling capabilities to see if I could develop something from it's core routines, but nothing has come of it thus far. 

 

Beery

 

  • Like 1
Link to comment
Share on other sites

5 hours ago, mizapf said:

Oh, we have preemptive multitasking in GeneveOS? Round-Robin scheduling?

 

I never really exploited the multitasking capabilities, sadly.

 

Round-robin.  Some programs use variations of the multitasking to launch a command line shell (Directory Manager, PORT, a few others) or spawn one task from another.  Of course, the programs must all allow a context switch to take place.  

  • Like 1
Link to comment
Share on other sites

On 8/5/2022 at 10:31 AM, InsaneMultitasker said:

Of course, the programs must all allow a context switch to take place.  

Ever since I dreamed about 2 VDPs, I wondered how two programs could ever get along without clobbering each other in VDP. Without totally rewriting them.
 

What if one process sets up VDPWA and then gets interrupted? (I know, you guard against that, but still.)

 

I guess that for a program to be a good multitask-ee in GeneveOS, it must use LIMI 0/LIMI 4 around any direct VDP access. 


What I came up with for Geneve 2020 hardware: Use a unique memory map for each running process.  If any hardware can be mapped anywhere or nowhere, these problems can be solved. 

 

A physical resource like VDP is in the memory map of  only ONE process at a time.

 

The memory mapper FPGA keeps a separate data area for each process.  (This year's design where I started with a Xilinx XC9564.) The TI 990/10 with memory mapper option had 6 words defining the memory map of a process; I can get a lot more. 

(Still doesn’t help GeneveOS multitaskers share the VDP though. It walls off GeneveOS and other running processes.)
 

So imagine a Geneve2020 running multiple processes, one with control of a VDP and keyboard, others owning a dedicated serial port and maybe a VDP. If you have two VDPs, you can have both GeneveOS and GPL on separate screens. You can have a serial console with no VDP. 


1. Suppose the BIOS launches GeneveOS, and configures its memory map with a VDP. The memory mapper connects the virtual address 8C02 or F102, VDPWA,  etc, etc to a physical port (just call it the VDP) when that process is running. 

2. On the other hand, a background process has the memory-mapped device addresses 8C02 etc connected nowhere. So it can’t possibly clobber anybody else. However, it might call XOP WRITETTY and the BIOS would buffer it somewhere for display later. (I imagine just  like Unix shells.)

 

3. Same deal for the keyboard.   When a background process is configured, Hardware abstraction layer just omits the keyboard port (and CRU bits) from the memory map. 

 

4. Same deal for serial port bases. At first I thought of bits to rearrange ports  so that a physical port could respond at 1340 or 1380 or 1540 to fool a process. Then I imagined it could just go into a virtual memory map: a process might have its 1300 block map to any physical serial port or it might have nothing.  (CTS bit at 130A is tricky.)


So:

 

With two VDPs, suppose they have physical base addresses  8C42 and 8C82. (VDPWA: the rest are relative.) In any process’ memory map, 8C02 is mapped to 8C42, 8C82, or nothing.  (I'm using GPL logical addresses for simplicity--skipping implementation details.)

 

BIOS is going to use VDP1 itself at startup, then launch GeneveOS giving it VDP1.  Meanwhile, BIOS leaves a serial console running. From there, you can type the command to launch a second GPL environment. That one gets connected to VDP2.

 

Somehow, you switch the keyboard to one or the other. 

 

Memory Maps

Logical addresses 0000-FFFE map through bank registers, which replace the top 4 bits with a 16 bit base.  Result: 28 bit address on the bus.  (Geneve 9640 replaces 3 bits with 8.  TI's 74610, in SAMS, takes away 4 bits and puts in up to 12.)

 

CRU addresses also go through a map! That is configured in blocks of >40.  (CRU cycles are also transformed into regular memory cycles on the bus. 1 bit or 16 bit access.)

 

Sample memory maps:

GPL Logical addresses -> physical bus addresses:

(See note at end for explanation of 32-bit looking physical bus addresses.)


Process 1: GeneveOS

8400 -> Fx50 841C. one 76489 Sound chip. 

F100 -> Fx40 8C40. VDP1. 
 

CRU: Serial port 1.

1300 -> Fx10 1300.  First two serial ports base. 

1340 -> Fx10 1340. First serial port on I/O card.

1380 -> Fx10 1380. Second serial port. 

 

Process 2: serial console

No VDP etc. Serial port 2 only. 

CRU:

1300 -> Fx00 13C0

1380 -> Fx00 1380 (CPU card's own 9902 -> serial console 6-pin connector)

 

(Base 13C0 is a kludge to mask one of 2 CTS bits; at 130A or C)

 

Only the BIOS can freely scan all the hardware bases.

 

NuBus cards with 32-bit physical addresses

 

In Texas Instruments’ NuBus, there are 32 address/data bits on the backplane. A 32-bit address like FN00 0000 is dedicated to physical slot N's ROM or memory-mapped ports, up to 16MiB.

 

I’m only using 28 bits. So I leave 4 physical address bits undecoded. 256 MiB total address space (not 4GiB), with the top 1/16th dedicated to cards.  I choose to write FxN0 0000 where x is not decoded.

 

Internally, there are NO bits stored to put into the 'x' nibble. A 16-bit bank register loaded with >1234 will yield a physical address 1x23 4yyy (where yyy come from the logical address.)

 

A card slot could have up to 1MiB dedicated, but practically it just needs 64K.  It has a 32K EEPROM at 0000, some CRU in 1000-1FFE , and some memory mapped ports above 8000. The 99105 has 8 or 16 bit parallel CRU above 8000.  I choose to unify CRU with CPU memory address space.  So, a memory access to 8C02 looks just like a CRU byte access to CRU 8C02. (but CRU incurs an extra wait state.)

 

RAM starts at the "uncommitted" address 0x00 0000.  With 32MiB it goes up to 1xFF FFFE.

 

Notation decisions

 

I've not decided if those 4 unused lines correspond to bus AD28:25 or AD24:21, in notation FxN0 or FNx0. It doesn't really matter today. 

 

FxN0:

Good:

Makes it clear that every 1 MiB begins a new card. 

Fx is a neat prefix. 

 

Bad:

Clashes horribly with NuBus standard.  Forbids expansion to 32 bits. 

RAM 16 MiB begins at 0x00. The next 16 MiB address rolls over to 1x00.

 

 

 

FNx0:

Good:

Fits neatly into NuBus standard.  Compatible if bus expands to 32 bits.  Each card space repeats 16 times. 

Bad:

RAM 1 MiB begins at 00x0. Each MiB increments the top 8 bits. Uncommitted RAM

 

Definitions

 

Public: responds to all requests that come from the backplane.

Dedicated: an address range that only the card in physical slot N responds to. Discovered at startup time. 

Uncommitted: addresses that are not hard-coded to anything. Configured at startup time. 

Private: addresses that map to chips internal to a card only.  Card does not these addresses on the backplane, nor are they reachable from outside. 

 

"Private" space

NuBus standard says that FN00 is dedicated public space of slot N. In the past, up to 16 MiB of the motherboard's built-in RAM or ROM could be publicly addressed by cards (over DMA) starting at FM00 where M is motherboard slot#.

 

Suppose I want to put 2 MiB built-in to my CPU card. Doesn't fit in my dedicated slot space.  I need the memory mapper on my card to unify the built-in space and external space.


It would be nice to expand the dedicated space FNx0 to 16 MiB by defining x internally. But that would not unify with the 28-bit universe.

 

I could use uncommitted space 0x00 for private ROM and 1x00 for private RAM.  Given that the CPU runs the BIOS anyway, it is free to configure external RAM to begin at 0x00 or 2x00.

 

 

So go ahead; define 0x00 and 1x00 as "private". That's room for 32 MiB. External RAM card gets configured in uncommitted space starting at 2x00.

 

 

 


 

Conclusion

 

I think FNx0 is a better notation and bus interface.   If I put all this effort into the hardware, I'd like someone (me?) to be able to re-use the peripherals and backplane with a 32-bit Cpu (say a 68000).

 

Think of the address space as 256 megabytes with a megabyte being the bulk unit, number before the x. 

 

Then 00x0 is a private megabyte on the CPU card. Probably the ROM! 01x0 is the private RAM. In a future 32-bit world, the uncommitted addresses are aliased 16 times.

 

 

Edited by FarmerPotato
Expanded the NuBus definitions greatly
  • Like 3
Link to comment
Share on other sites

On 8/5/2022 at 2:06 PM, FarmerPotato said:

With two VDPs, suppose they have physical base addresses  8C42 and 8C82. (VDPWA: the rest are relative.) In any process’ memory map, 8C02 is mapped to 8C42, 8C82, or nothing. 

I am not sure that I follow the reason or purpose for the two VDPs.  I walked back through the topic but either missed the info or didn't absorb it.  Is it primarily for compatibility with the F18A?  

 

Since existing programs won't know what to do with a second VDP, is there any merit to using a CRU bit to toggle between the two, or to set a single VDP/dual VDP mode?   For example, if I wanted to run a F18A program, set the bit to use the second VDP?   Maybe in the same range as the other /9640 bits in the >1Exx range.  

 

Any plans to emulate the FinalGROM or other TI-centric hardware, for GPL mode?  

Link to comment
Share on other sites

On 8/8/2022 at 11:37 AM, InsaneMultitasker said:

I am not sure that I follow the reason or purpose for the two VDPs.  I walked back through the topic but either missed the info or didn't absorb it.  Is it primarily for compatibility with the F18A?  

 

Since existing programs won't know what to do with a second VDP, is there any merit to using a CRU bit to toggle between the two, or to set a single VDP/dual VDP mode?   For example, if I wanted to run a F18A program, set the bit to use the second VDP?   Maybe in the same range as the other /9640 bits in the >1Exx range.  

 

I proposed the thought-experiment, because I take 2 screens for granted today. 

 

The usefulness of putting reference information on one monitor while working on the other. Being able to list a directory and refer to it while working in the other. Editing some graphics in one screen, while assembling and running in the other. 

 

A process would still only know about 1 VDP, but you could have 2 processes loaded. 


For one, GeneveOS with its display. Then a second standalone GPL (and there can be interaction through the file system.)

 

Or, a BIOS Forth prompt on VDP1, where you can query any kind of system performance parameter, while GeneveOS runs on the VDP2.   (You could just as well use a serial console to BIOS.)

 

So, imagine you can run two screens, independently attached to any two of the below: (even same two)

  1. GeneveOS (with its GPL)
  2. Standalone GPL
  3. Forth console prompt
  4. Anything else

This is all possible through abstracting the hardware, loading some address bases into a memory-map, and starting the process. 

 

One concept enables all sorts of capabilities. Looked at one way, it is easier to build a clean hardware system BECAUSE you do everything through a memory-mapper. 

 

  • Like 2
Link to comment
Share on other sites

17 minutes ago, FarmerPotato said:

One concept enables all sorts of capabilities. Looked at one way, it is easier to build a clean hardware system BECAUSE you do everything through a memory-mapper

I could only begin to count how often I wish i had a second screen or way to share the current screen, so the concept has a lot of appeal.

 

What I don't quite get is how it would come to fruition.  Would you run two instances of the Geneve OS as separate 'systems'? For  existing programs, except for those that run from the command line, you will have a lot of direct access to contend with.  Definitely some interesting possibilities with new programs and those we can easily modify. I am looking forward to seeing how this all comes together!

  • Like 3
Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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