udo-munk / z80pack

A Zilog Z80 and Intel 8080 systems emulation
MIT License
158 stars 37 forks source link

Implement the Cromemco 88-CCC Cyclops Camera Controller #59

Closed dmcnaugh closed 5 years ago

dmcnaugh commented 6 years ago

Reproductions of the worlds first digital camera, the Cromemco Cyclops 88-ACC have been shown at recent VCF events in the US. The Wikipedia page for the Cyclops has links to the manuals for both the camera and the controller at the bottom of the page https://en.m.wikipedia.org/wiki/Cromemco_Cyclops

I have already done a proof-of-concept to use a standard web-camera and process the video to produce the same bit-stream as the Cyclops. This happens in the browser and so will be usable with the webfrontend (see #38).

The interface controller needs to be implemented as a new iodevice so the bit-stream can be read by a simulator machine. Then the example code in the 88-CCC manual can be used to display the image on the Dazzler.

It would even be possible to implement the interface controller to work with a physical Cyclops camera using a cheap micro controller board to convert the Cyclops data to serial (probably via USB).

dmcnaugh commented 6 years ago

First signs of life... dazzler 2018-08-09t09_39_50 175z

This image is a screenshot from the webfrontend Dazzler window.

It begins being captured by my webcam, processed in the browser to be downsampled to 32x32 pixels and 16 shades of grey then sliced into the bit-stream equivalent to what the Cromemco 88-ACC Cyclops camera would transmit. An emulation of the Cromemco 88-CCC camera controller card requests then receives the bit-stream and copies it into the simulator's memory using dma_write(), in this case to the IMSAI 8080.

Using the original sample program from the Cromemco 88-CCC manual, titled CCC-3, the Dazzler and the 88-CCC are initialised, an image is requested from the camera, loaded into memory via DMA, processed by the program and displayed on the Dazzler, and repeated. The refresh rate is about 1 frame every 1 second when running at 4Mhz.

It is not running without problems. Firstly the listing of the CCC-3 program from the original manual contains mistakes, and I am guessing at one of the fixes until I reverse engineer the algorithm.

udo-munk commented 6 years ago

Very cool. Great for showing how this stuff worked 4 decades ago without the need to build the hardware replica.

dmcnaugh commented 6 years ago

This is working now and complete enough to add to the dev branch. It will take me a little time to prepare a pull-request because I need to clean up my local git repository as I added this on the wrong branch and have to now do some house keeping. I will also post a user guide when the PR is ready.

As indicated earlier, the refresh rate of video is about 1 frame-per-second on a 4Mhz CPU clock speed. At "unlimited" I am getting about 7 fps. The bottle neck is the simulated CPU processing the incoming bit-stream and converting it into the right format for the Dazzler to display in 16 shades of grey. The simulation of the 88-ACC Cyclops camera can easily run at higher frame rates if the CPU does nothing with the bit-stream after it is received.

dmcnaugh commented 6 years ago

The code for this is now available in PR #60 Notes:

acc The ACC: device window has the following features:

There is a new disk image in imsaisim/disks/library/cyclops.dsk that contains 3 demo programs.

So to run the demo:

  1. compile imsaisim with HAS_CYCLOPS defined in sim.h
  2. start imsaisim with either -f4 for a 1 frame-per-second experience or -f0 for higher fps
  3. launch the webfrontend
  4. mount the cyclops.dsk disk image
  5. click on the ACC: device to open its window
  6. click on the red 'connect' window widget to connect and start your web camera (you might be prompted by your browser the first time to allow access to your web camera)
  7. open the Dazzler window
  8. in your CP/M console change disk to the mounted cyclops.dsk
  9. run ccc-3b
  10. smile at your web camera and travel back in time to 1976 :-) P.S. The more you squint at the image reproduced on the Dazzler, the more photographic it looks. I'm guessing this is because your vision blurs/blends the blocky pixels and you 'see' something more realistic.
udo-munk commented 6 years ago

This is unbelievably cool, great work.

udo-munk commented 6 years ago

The thread for the DMA transfer from the 88-ACC can be canceled instead of waiting after the state change. In the video logics I had to use this workarround to avoid deadlocks under Cygwin, because protecting a cricical region with pthread_setcancelstate() doesn't work.

The msg structure is used uninitialzed if the Cyclops device wasn't connected, gcc 7.3 produces warnings about that:

../../iodevices/cromemco-88ccc.c: In Funktion »store_image«: ../../iodevices/cromemco-88ccc.c:56:4: Warnung: »msg.fields« könnte in dieser Funktion uninitialisiert verwendet werden [-Wmaybe-uninitialized] } msg; ^~~ ../../iodevices/cromemco-88ccc.c:97:24: Warnung: »msg.interval« könnte in dieser Funktion uninitialisiert verwendet werden [-Wmaybe-uninitialized] j = msg.fields (msg.interval +1) 2;

udo-munk commented 5 years ago

IMSAI 8080esp kit is shipping, so implementation completed.