Commit Graph

858 Commits

Author SHA1 Message Date
asvitkine
84a6ec3a05 wrap init_sdl() in USE_SDL ifdef 2012-01-01 18:51:40 +00:00
asvitkine
df4342b6db fix compile error introduced by my recent refactoring 2012-01-01 18:50:01 +00:00
asvitkine
78ea64bbd9 fix ppc build breakage 2011-12-30 17:38:39 +00:00
asvitkine
4161b3d153 successfull built of x86 32/64 UB via xcode proj 2011-12-30 01:33:26 +00:00
asvitkine
dc0993ca6a trying to get xcode project to build a fat 32/64 bit binary - not yet there 2011-12-30 00:58:32 +00:00
asvitkine
d3ec12fc1c add utils_macosx.mm/h 2011-12-29 07:43:25 +00:00
asvitkine
dcf65b4d27 move NSAutoReleasePool_wrap() into its own file 2011-12-29 07:39:56 +00:00
asvitkine
c78c3046db refactor init_sdl() into a function 2011-12-28 23:33:04 +00:00
asvitkine
d58da945c6 refactor install_signal_handlers() into its own function 2011-12-28 23:30:25 +00:00
asvitkine
7930deea4d refactor load_mac_rom() into a function 2011-12-28 23:24:30 +00:00
asvitkine
cea73a29ed refactor get_system_info() into a function 2011-12-28 23:17:29 +00:00
asvitkine
57416ef7b4 add pre-generated config files for Xcode project
so far, only the x86-64 config
2011-12-28 22:38:03 +00:00
asvitkine
97c7aa5756 delete unused vars 2011-12-28 20:21:40 +00:00
asvitkine
fb4a2a6dc6 fix warning casting pointer to int 2011-12-28 20:15:08 +00:00
asvitkine
f11ad3129b fix release build 2011-12-28 18:17:10 +00:00
asvitkine
eebe0b0c13 don't deref desc after deleting it! 2011-12-28 18:14:58 +00:00
asvitkine
c2c88efcc3 first stab at xcode project for sheepshaver - this is still a work in progress 2011-12-28 18:01:17 +00:00
asvitkine
0f472ed95e use non-deprecated methods 2011-12-28 17:51:56 +00:00
asvitkine
a97df3c953 fix a warning 2011-12-27 07:22:18 +00:00
asvitkine
faadf4cbb1 correct whitespace 2011-12-26 22:44:22 +00:00
asvitkine
18729e6f07 [Douglas Mencken]
Add recognition for 970MP processors.

I took these values from this kernel patch from year 2005:
http://lists.ozlabs.org/pipermail/linuxppc64-dev/2005-July/004688.html
2011-12-26 22:41:53 +00:00
asvitkine
39a3b75024 abort editing virtual machine name if any action is chosen 2010-12-28 02:57:46 +00:00
asvitkine
f1a2620576 - Add a prefix header which is used in place of SheepShaver's config.h to
allow correct compilation of the Universal Binary.
- Update project to work with Xcode on Snow Leopard.
- Add missing #include <unistd.h>
2010-12-28 02:50:55 +00:00
asvitkine
453f0e8a28 Add macro guards for config.h. 2010-12-28 02:36:09 +00:00
asvitkine
63cf1fadc3 [Geoffrey Brown]
VHD support
2010-10-19 22:20:01 +00:00
asvitkine
415e7d3f68 [Dave Dixon]
Patch file to fix JIT compiler on 64-bit Mac OS X 10.6 when using gcc 4.2.
This patch removes register rbx usage when compiling on 64-bit OS X.
2010-10-18 22:02:29 +00:00
asvitkine
59f51815f7 [Geoffrey Brown]
bin/cue support
2010-10-06 00:34:15 +00:00
asvitkine
b2d58d423e Fix compile problem with --enable-jit=no 2010-09-24 00:36:34 +00:00
asvitkine
bb627f28fe add braces around @interface declaration to compile with clang 2010-08-22 19:33:25 +00:00
asvitkine
14339fb01f add NULL return value to macho timer function 2010-08-22 19:31:36 +00:00
asvitkine
8a062fefdc fix printf safety warning 2010-08-22 18:57:11 +00:00
asvitkine
15b346b031 use setenv in preference of putenv 2010-08-22 18:56:11 +00:00
asvitkine
e03ad25362 Fixed for Snow Leopard build. 2010-07-27 03:14:34 +00:00
asvitkine
0973ee0e16 Fix compile on Snow Leopard. 2010-07-27 02:57:10 +00:00
asvitkine
da828ffc73 Fix prefs_macosx.mm compile issue with Snow Leopard. 2010-07-27 02:55:09 +00:00
asvitkine
efad3ba70a use linked list for timers to avoid running out of descriptors 2010-05-05 00:29:46 +00:00
asvitkine
614b33bcd8 [Joel Mauras]
Let makefile build relatives links between SheepShaver and BasiliksII so
they can be moved anywhere into the file system as long as they stay side
by side without having to rebuid the links.
2010-04-08 03:50:26 +00:00
asvitkine
78027e7a46 [Amadeusz Slawinski]
These patches fix the issues with using newer versions of autoconf,
which led to generating broken configure script.
2010-03-07 00:45:10 +00:00
asvitkine
b3c5b07f54 fix more platform compile failures caused by refactoring, based
on patch by Amadeusz Sławiński
2010-03-02 00:37:17 +00:00
cebix
4f28f70207 fixed warnings 2010-02-21 09:59:52 +00:00
cebix
c6a52b6eb2 fixed const-ness 2010-02-21 09:59:14 +00:00
cebix
23b0bda1a5 fixed const-ness and compiler warnings 2010-02-21 09:58:47 +00:00
asvitkine
2b03c79d48 fix dyngen.c breakage on non-MACHO platforms 2010-01-15 01:47:17 +00:00
asvitkine
5ca84603bc [ Tim Douglas <timdoug@gmail.com> ]
use an auto release pool around "Preferences..." menu item creation on Mac OS X
2010-01-02 22:08:51 +00:00
asvitkine
6677e5824c [ Tim Douglas <timdoug@gmail.com> ]
use an auto release pool around modal prefs dialog on Mac OS X
2010-01-02 19:24:24 +00:00
asvitkine
8e1a2f7f48 use correct variable name 2009-11-19 02:07:44 +00:00
asvitkine
ded367a176 [ Patch from Jean-Pierre <chombier@free.fr> ]
More changes to support mach-o x86_64.
2009-11-13 01:46:35 +00:00
asvitkine
f4705aa5e1 code whitespace cleanup and patch_relocations() function 2009-11-08 19:11:02 +00:00
asvitkine
df4aef1fba [ Patch from Jean-Pierre <chombier@free.fr> ]
Dyngen patch for Snow Leopard x86_64 compatibility.
This work is mostly based on the unofficial and incomplete x86_64 mach-o patch of qemu.
2009-11-08 18:16:31 +00:00
asvitkine
3856561935 Fix builds on platforms that may have gotten broken due to my vmdir changes. 2009-09-21 03:34:14 +00:00
asvitkine
c294074fa7 Launcher: Check if file exists. 2009-08-31 05:08:21 +00:00
asvitkine
63b4f8d704 better default prefs 2009-08-30 17:56:30 +00:00
asvitkine
f06f035428 Launcher: Renaming VMs in list. 2009-08-26 07:09:06 +00:00
asvitkine
868bb283d2 [Michael Schmitt]
Attached is a patch to SheepShaver, to fix a problem where the ROM file can only be found on the first boot.

When a user creates a new SheepShaver machine, there is no preference file, so there is not ROM path preference. SheepShaver has logic so that in this case, it will look for a ROM file named "ROM" or "Mac OS ROM" in the current directory.

The user starts SheepShaver in order to get to the built-in Preferences Editor, and changes various settings (such as creation of a hard disk). Then the user reboots.

If the user forgot to set the ROM path at this time, then SheepShaver can no longer boot. The only recourse is for the user to find and delete the preferences file, or use an external preferences editor to set the ROM path.

The fix is to change SheepShaver to use the default ROM names when either the rom path is null (no preference) OR an empty string (preference exists with no rom path).
2009-08-26 00:11:56 +00:00
asvitkine
0075c1faab [Michael Schmitt]
Attached is a patch to SheepShaver, to fix a SIGSEGV crash that occurs when booting a new machine with OS 7.5.

One of the bytes in the xPRAM portion of the NVRAM controls which version of the system memory manager is used by OS 7.5: the legacy 680x0 memory manager or the PPC memory manager (aka the "Modern Memory Manager"). OS 7.5 is supposed to be able to use either one, but for some reason SheepShaver crashes on boot if the 680x0 version is used.

Later Mac OS versions don't have this problem. They don't support the 680x0 version, so they force the PPC version to be used.

The fix is to have SheepShaver initialize the NVRAM to use the PPC memory manager. Note: This is supposed to be the default in OS 7.5.

This affects when a new NVRAM file is used, or when it is initialized after doing zapping the PRAM.
2009-08-26 00:06:29 +00:00
asvitkine
53e416c4b7 Fix position of "browse" button for keycodes file when resizing prefs window 2009-08-18 18:30:19 +00:00
asvitkine
b3b5db5456 [Michael Schmitt]
Attached is a patch to SheepShaver to fix memory allocation problems when OS X 10.5 is the host. It also relaxes the 512 MB RAM limit on OS X hosts.


Problem
-------
Some users have been unable to run SheepShaver on OS X 10.5 (Leopard) hosts. The symptom is error "ERROR: Cannot map RAM: File already exists".

SheepShaver allocates RAM at fixed addresses. If it is running in "Real" addressing mode, and can't allocate at address 0, then it was hard-coded to allocate the RAM area at 0x20000000. The ROM area as allocated at 0x40800000.

The normal configuration is for SheepShaver to run under SDL, which is a Cocoa wrapper. By the time SheepShaver does its memory allocations, the Cocoa application has already started. The result is the SheepShaver memory address space already contains libraries, fonts, Input Managers, and IOKit areas.

On Leopard hosts these areas can land on the same addresses SheepShaver needs, so SheepShaver's memory allocation fails.


Solution
--------
The approach is to change SheepShaver (on Unix & OS X hosts) to allocate the RAM area anywhere it can find the space, rather than at a fixed address.

This could result in the RAM allocated higher than the ROM area, which causes a crash. To prevent this from occurring, the RAM and ROM areas are allocated contiguously.

Previously the ROM starting address was a constant ROM_BASE, which was used throughout the source files. The ROM start address is now a variable ROMBase. ROMBase is allocated and set by main_*.cpp just like RAMBase.

A side-effect of this change is that it lifts the 512 MB RAM limit for OS X hosts. The limit was because the fixed RAM and ROM addresses were such that the RAM could only be 512 MB before it overlapped the ROM area.


Impact
------
The change to make ROMBase a variable is throughout all hosts & addressing modes.

The RAM and ROM areas will only shift when run on Unix & OS X hosts, otherwise the same fixed allocation address is used as before.

This change is limited to "Real" addressing mode. Unlike Basilisk II, SheepShaver *pre-calculates* the offset for "Direct" addressing mode; the offset is compiled into the program. If the RAM address were allowed to shift, it could result in the RAM area wrapping around address 0.


Changes to main_unix.cpp
------------------------
1. Real addressing mode no longer defines a RAM_BASE constant.

2. The base address of the Mac ROM (ROMBase) is defined and exported by this program.

3. Memory management helper vm_mac_acquire is renamed to vm_mac_acquire_fixed. Added a new memory management helper vm_mac_acquire, which allocates memory at any address.

4. Changed and rearranged the allocation of RAM and ROM areas.

Before it worked like this:

  - Allocate ROM area
  - If can, attempt to allocate RAM at address zero
  - If RAM not allocated at 0, allocate at fixed address

We still want to try allocating the RAM at zero, and if using DIRECT addressing we're still going to use the fixed addresses. So we don't know where the ROM should be until after we do the RAM. The new logic is:

  - If can, attempt to allocate RAM at address zero
  - If RAM not allocated at 0
      if REAL addressing
         allocate RAM and ROM together. The ROM address is aligned to a 1 MB boundary
      else (direct addressing)
         allocate RAM at fixed address
  - If ROM hasn't been allocated yet, allocate at fixed address

5. Calculate ROMBase and ROMBaseHost based on where the ROM was loaded.

6. There is a crash if the RAM is allocated too high. To try and catch this, check if it was allocated higher than the kernel data address.

7. Change subsequent code from using constant ROM_BASE to variable ROMBase.


Changes to Other Programs
-------------------------
emul_op.cpp, main.cpp, name_registery.cpp, rom_patches.cpp, rsrc_patches.cpp, emul_ppc.cpp, sheepshaver_glue.cpp, ppc-translate-cpp:
Change from constant ROM_BASE to variable ROMBase.

ppc_asm.S: It was setting register to a hard-coded literal address: 0x40b0d000. Changed to set it to ROMBase + 0x30d000.

ppc_asm.tmpl: It defined a macro ASM_LO16 but it assumed that the macro would always be used with operands that included a register specification. This is not true. Moved the register specification from the macro to the macro invocations.

main_beos.cpp, main_windows.cpp: Since the subprograms are all expecting a variable ROMBase, all the main_*.cpp pgrams have to define and export it. The ROM_BASE constant is moved here for consistency. The mains for beos and windows just allocate the ROM at the same fixed address as before, set ROMBaseHost and ROMBase to that address, and then use ROMBase for the subsequent code.

cpu_emulation.h: removed ROM_BASE constant. This value is moved to the main_*.cpp modules, to be consistent with RAM_BASE.

user_strings_unix.cpp, user_strings_unix.h: Added new error messages related to errors that occur when the RAM and ROM are allocated anywhere.
2009-08-18 18:26:11 +00:00
asvitkine
3867b28037 load the VMSettingsWindow nib for prefs window in SheepShaver 2009-08-18 18:22:01 +00:00
asvitkine
c465e7239e Launcher: Use default settings from NIB for new VM. 2009-08-18 03:42:11 +00:00
asvitkine
bc7b9a6c4a MacOSX: Use the prefs editor from the Launcher project. 2009-08-18 03:27:50 +00:00
asvitkine
3e7168c78d allow settings controller to work in non-standalone mode 2009-08-18 03:26:17 +00:00
asvitkine
a98f16a1bd support both foo.sheepvm and foo.sheepvm/ command-line parameters 2009-08-18 02:36:59 +00:00
asvitkine
5a8dfa1b36 [Charles Srstka]
Attached is a set of patches to port the precise timer that is currently used in the Linux and BeOS builds of SheepShaver to Mac OS X (and any other Mach-based operating systems).

Currently, the Linux build uses the clock_gettime() function to get nanosecond-precision time, and falls back on gettimeofday() if it is not present. Unfortunately, Mac OS X does not currently support clock_gettime(), and gettimeofday() has only microsecond granularity. The Mach kernel, however, has a clock_get_time() function that does very nearly the same thing as clock_gettime(). The patches to BasiliskII cause the timing functions such as timer_current_time() to use clock_get_time() instead of gettimeofday() on Mach-based systems that do not support clock_gettime().

The changes to SheepShaver involve the precise timer. The existing code for Linux uses pthreads and real-time signals to handle the timing. Mac OS X unfortunately does not seem to support real-time signals, so Mach calls are again used to suspend and resume the timer thread in order to attempt to duplicate the Linux and BeOS versions of the timer. The code is somewhat ugly right now, as I decided to leave alone the pre-existing style of the source file, which unfortunately involves #ifdefs scattered throughout the file and some duplication of code. A future patch may want to clean this up to separate out the OS-specific code and put it all together at the top of the file. However, for the time being, this seems to work.

This has not been extensively tested, because I have not been able to get my hands on a good test-case app for the classic Mac OS that would run inside the emulator and try out the timer. However, performance does seem to be better than with the pre-existing code, and nothing seems to have blown up as far as I can tell. I did find a game via a Google search -  Cap'n Magneto - that is known to have problems with Basilisk/SheepShaver's legacy 60 Hz timer, and the opening fade-to-color for this game appears to run much more smoothly with the precise timer code in place.
2009-08-17 20:44:30 +00:00
asvitkine
8ac0507a39 re-arrange virtual machines by drag and drop
add a contextual menu that also allows to
reveal the selected virtual machine in finder
2009-08-12 02:18:19 +00:00
asvitkine
fbef7bcf22 more improvements to Launcher 2009-08-06 18:12:25 +00:00
asvitkine
7004db923a allow looking inside bundles and default disk location to inside bundle 2009-08-06 06:42:43 +00:00
asvitkine
61770c58eb keep track of running VMs 2009-08-02 23:46:44 +00:00
asvitkine
b67b983156 disable buttons when no selection 2009-08-02 23:17:18 +00:00
asvitkine
abbd1785b1 delete vm from list 2009-08-02 22:37:34 +00:00
asvitkine
b38bb12ab3 New Virtual Machine button working 2009-08-02 20:24:38 +00:00
asvitkine
820ae8100c misc changes 2009-08-02 19:51:15 +00:00
asvitkine
d38c755204 Launching VMs 2009-08-02 18:59:26 +00:00
asvitkine
07a2d906c4 add icon to launcher 2009-08-02 18:42:06 +00:00
asvitkine
e8e5440b31 initial import of SheepShaver Launcher project for Mac OS X (WIP) 2009-08-02 18:34:57 +00:00
asvitkine
80a7589e29 only if standalone 2009-08-01 15:31:54 +00:00
asvitkine
743888f407 fix PrefsEditor build 2009-08-01 15:31:31 +00:00
asvitkine
5cef748ac7 only "continue previous delay" if delay is 0 2009-08-01 07:02:41 +00:00
asvitkine
ccdb8ab3c0 correct implementation of PrimeTime(0) 2009-07-31 20:43:28 +00:00
asvitkine
57b64245ad handle one case of PrimeTime(0) 2009-07-31 19:41:50 +00:00
asvitkine
5b958defa7 support for .sheepvm bundles on macosx, containing "prefs" and "nvram" files 2009-07-23 19:12:51 +00:00
asvitkine
581ff8d86f add prefs option to ignore illegal instructions (ignoreillegal) 2009-07-20 18:50:28 +00:00
asvitkine
9c8387f8d0 more syncing 2009-04-14 00:52:15 +00:00
asvitkine
f2630f5e6a sync Makefile.in with Unix version 2009-04-14 00:36:13 +00:00
asvitkine
7fc0d3137b syncing Windows configure.ac file with the unix one 2009-04-14 00:17:56 +00:00
asvitkine
fceeb39d3c Restore OSX built-in prefs editor. Change the configure.ac check for
no_x to WANT_GTK=no since X may be installed when building on OS X,
but we probably don't want it!
2009-03-18 16:09:15 +00:00
asvitkine
da540a74f6 [patch by Mike Sliczniak]
Here is a patch to allow compiling of SS and B2 with an SDL Framework. You can
get this by downloading from:

http://www.libsdl.org/release/SDL-1.2.13.dmg

Here is how I tested on an intel 32-bit mac with Mac OS X 10.5.6:

SS ./autogen.sh --disable-standalone-gui --enable-vosf --enable-sdl-framework --enable-sdl-framework-prefix=/Users/mzs/Library/Frameworks --enable-sdl-video --disable-sdl-audio --enable-addressing=real
--without-esd --without-gtk --without-mon --without-x

SS /autogen.sh --disable-standalone-gui --enable-vosf --disable-sdl-framework --disable-sdl-video --disable-sdl-audio --enable-addressing=real --without-esd --without-gtk --without-mon --with-x

B2 ./autogen.sh --disable-standalone-gui --enable-vosf --enable-sdl-framework --enable-sdl-framework-prefix=/Users/mzs/Library/Frameworks --enable-sdl-video --enable-sdl-audio --enable-addressing=real --without-esd --without-gtk --without-mon --without-x --enable-jit-compiler

B2 ./autogen.sh --disable-standalone-gui --enable-vosf --disable-sdl-framework --disable-sdl-video --disable-sdl-audio --enable-addressing=real --with-esd --without-gtk --without-mon --with-x --enable-jit-compiler

(esound does not really work on mac, it needs some better coreaudio patches.)

configure.ac for SS has two little additional fixes so that the Cocoa prefs gui
does not get built if you are building for X11 and so that you can use esd, sdl,
or coreaudio for sound.
2009-03-03 08:07:22 +00:00
asvitkine
3e12a80a3b [Patch by Mike Sliczniak]
I was testing some other SS patches and I noticed that when I ran an X11
build of SS there were not all the video modes I expected in the the
control strip. Mac OS X 10.5 changed the form of the DISPLAY environment
variable. The reason for this is that the DISPLAY variable looks like
this in Leopard:

/tmp/launch-XXXXXX/:0

The Xs are like in mktemp.
2009-02-19 07:09:35 +00:00
asvitkine
e083e0ac33 [Patch by Mike Sliczniak]
Here is a patch that has a shell script cpr.sh to recursively copy directories but
discarding things that cause problems at least on 10.4 when making the .app bundles.
2009-02-19 07:02:46 +00:00
asvitkine
04bec66567 don't re-declare sigsegv_info_t, instead use the one from the header 2009-02-11 20:44:49 +00:00
asvitkine
ca2b9b5832 [Patch from Mike Sliczniak]
This first patch gets B2 and SS to build under Leopard and Tiger.

I tested this on a 32-bit intel 10.5.6 mac like so:

B2
./autogen.sh --disable-standalone-gui --enable-vosf --enable-sdl-video --enable-sdl-audio --enable-addressing=real --without-esd --without-gtk --without-mon --without-x

SS
./autogen.sh --disable-standalone-gui --enable-vosf -enable-sdl-video --disable-sdl-audio --enable-addressing=real --without-esd --without-gtk --without-mon --without-x --enable-jit

There is also a little tweak so that you can use sdl audio in SheepShaver when building for Mac OS X.
2009-02-11 19:23:53 +00:00
asvitkine
d6db773362 [patch from Darik Horn <dajhorn@vanadac.com> ]
Makes SheepShaver compatible with Ubuntu Intrepid and
other distros that bundle the gcc-4.3 compiler.

The patch changes two things:

1. Renames the block_cache where its name collides with its class
definition.

2. Fixes the "explicit template specialization cannot have a storage
class" error in the ppc-dyngen-ops.cpp file.
2009-01-15 23:25:08 +00:00
asvitkine
06ac24df65 Fix Leopard build. 2008-11-21 01:09:28 +00:00
asvitkine
5505a5dc62 Change < to - in qsort compare functions to correctly return 0 for equality. 2008-09-14 19:54:36 +00:00
asvitkine
bf7408e151 Fix prefs 2008-07-20 07:29:46 +00:00
asvitkine
c23511080e [patch from Kelvin Delbarre]
Software cursor mode is now supported, although currently the existing hardware
cursor mode is used whenever possible. (Software mode will be used if you are
running with a recent version of SDL's Quartz video driver, since a bug in SDL
1.2.11 and later prevents the hardware cursor from working properly with that
driver.)

In hardware cursor mode, the hot-spot is now determined heuristically. Formerly
it could not be determined and was always (1,1), an annoyance for many cursors
other than the arrow.

In hardware cursor mode, the cursor will now be hidden when requested by the
emulated OS (such as when you are typing in a text field).

In hardware cursor mode, some cursor image formats that the code does not handle
correctly will now be rejected, causing the emulated OS to revert temporarily to
software cursor mode. Formerly you would just end up with random garbage for a
cursor. This typically happened for grayscale or color cursors; rejecting images
with rowBytes != 2 eliminates the worst cases.
2008-06-25 02:52:52 +00:00
asvitkine
d885e5ccf4 [patch from Kelvin Delbarre] SDL's Quartz video implementation maps command
clicks to right-clicks and option-clicks to middle-clicks, a feature intended
for Mac users with single-button mice who are running SDL-based games that
require a multi-button mouse. This is unhelpful in SheepShaver, where we want
command-clicks and option-clicks to be passed through unchanged to the emulated
Mac OS. We can disable the unwanted behavior by setting an environment variable
SDL_HAS3BUTTONMOUSE intended for this very purpose.

A similar change in main_windows.cpp is NOT required, because only the Quartz
video implementation is involved.

By SDL convention, putenv is used in preference to setenv, although for Unix
platforms it doesn't matter.
2008-06-22 20:30:12 +00:00
asvitkine
e8e2f3727a Don't profile by default - as this is no use to non-developers. 2008-06-20 00:50:33 +00:00
asvitkine
1002714623 Add frameskip 0 ("Dynamic") to MacOSX Prefs Editor, and fix line endings
and deprication warnings in the Objective-C code. Also, don't specify array
size with a macro in a header file.
2008-06-17 04:26:56 +00:00
gbeauche
b083b08fd1 Cope with recent run-time assembler changes. 2008-02-12 14:52:25 +00:00
gbeauche
b5746b4f68 Add SSSE3 optimizations (Intel Core 2 CPUs and newer) for LVX, STVX, VPERM.
This brings an overall +10% performance improvement in AltiVec Fractal Carbon.
2008-01-01 21:51:56 +00:00