Skip to content

Commit

Permalink
General 0.6 release fixes and improvements (#133)
Browse files Browse the repository at this point in the history
* Remove unnecessary files
* Flush audio buffer when leaving fast disk emlulation to avoid delay
* Styling fixes for widgets to better visualize checkbox and edit widgets
* Use nearest fit min/mag filtering for all textures used in the screen rendering pipeline
* WIP documentation
* Support fullscreen and debugger toggle in menu
* Allow card slot configuration
* Remove some debug logs
* Workflow name changes
* Using custom mpack flush and fill for compression prep
* disable mpack builder functions for better flush functionality and compression
* added sokol/sokol_gfx_ext.h for screen/read from texture
* Compressed snapshots and screen capture as PNG stored in snapshot
* make sure sokol_gfx_ext functions have C linkage
* Load snapshot GUI functional with image snapshots
* Partial WOZ CRC generation
  • Loading branch information
samkusin authored Jul 29, 2023
1 parent 6f0ebf5 commit c4c2db5
Show file tree
Hide file tree
Showing 54 changed files with 1,804 additions and 238 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CMake
name: Linux All Build

on:
push:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-macos.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CMake
name: macOS All Build

# macOS runners are time consuming - limit when we run workflows on them to
# pushes or version tags
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-windows.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CMake
name: Windows All Build

on:
push:
Expand Down
235 changes: 235 additions & 0 deletions MANUAL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
# Clemens IIGS Emulator

Clemens IIGS is an emulator for the Apple IIGS 16-bit system from the late 1980s.
Its components include its own implementation of the various emulated hardware
with a rich user frontend.

## Table of Contents

1. [Features](#section-support)
2. [Roadmap](#roadmap)
3. [Getting Started](#getting-started)
4. [Hotkeys](#hotkeys)
5. [Finding Software](#finding-roms)
5. [Debugger](#debugger)
6. [Troubleshooting](#troubleshooting)
7. [Missing Features](#known-issues)

## Features <a name="section-support"></a>

- Runs under Windows 10, macOS Catalina, or Linux 64-bit
- Standard Apple IIgs and IIx video modes
- Ensoniq and Mockingboard C audio (without SSI-263 voice)
- Joystick/Gamepad support
- Passes Self-Diagnostic Test
- Rich debugging features
- Load and save machine snapshots

**Hardware**

- 2.8 MHZ system speed
- 8 MB RAM
- ROM 3 Emulation
- 5.25", 3.5", Smartport and ProDOS peripheral hard drive emulation
- WOZ 2.0, DSK, DO, PO, 2IMG disk image formats

**User:**

- US keyboard layout
- Transfer of binary files to and from the system
- Paste text as keyboard input (at the BASIC/Monitor prompts)
- Debugging facilities (partial)

## Roadmap <a name="roadmap"></a>

- Serial/terminal emulation
- ROM 1
- French and other international keyboard layouts
- Serial Printers
- Transwarp Speeds

## Getting Started <a name="getting-started"></a>

Please see the [README](README.md) for the basics, installation and identifying
a ROM image for starting the emulator.

This section will briefly cover what's required to get a system up and running
once installed.

1. Launch Clemens
2. Select the directory to place data created by the emulator
3. On the configuration screen, select the ROM file loaded upon machine startup
4. Change any configuration options if desired
5. Press 'Power On'
6. Running Apple II and IIgs software

### Initial Launch and Setup

If this is the first time running Clemens on, you will be prompted to select
the location for the Clemens `data` directory. In most cases the user can just
select the default and continue.

![Setup Data](docs/manual-setup-data.png)

This data directory will contain items such as snapshots, traces and log files.
The selected location for this directory depends on the host's operating system
(i.e. Windows, macOS or Linux.)

> **NOTE**
>
> Typically this directory is hidden to users without explicitly making this
> directory visible by means specific to the OS. If you'd rather use another
> directory, when prompted navigate to the preferred directory location.
>
> See [Portable Installation] to control exactly where the data directory and
> configuration files are located.
### Configuration ROM

The user is next presented with options to configure the emulated machine.

![Setup Machine](docs/manual-setup.png)

The first thing to do is select a ROM file loaded once the machine is powered
on. **Currently only ROM 3 images are supported. They are 256K in size.**

See the section on [finding ROMs and Apple II software](#finding-roms) if you
do not have such files available on your system.

Once you have a ROM file, you can select it by pressing the folder button at the
top of the setup screen. If no ROM is selected, the machine will power on to a
screen filled with `@` characters.

### Power On

If the remaining configuration options are OK, press 'Power On'. The machine
should boot. If you didn't select a ROM image you'll see the `@` screen.

Unless you selected a disk image to boot, the emulator will stop at the
standard Apple IIgs "Check Startup Disk" screen. This is to be expected.

### Configuration Details

All configuration options are saved in a `config.ini` file located in a folder
reserved for Clemens on the system (typically the same as the default data
directory mentioned above.)

See [Portable Installation](#portable-installation) (as mentioned above) to
ensure configurations are saved in the folder you want if the defaults aren't
sufficient.

> **NOTE**
> Fast Disk Emulation is recommended unless floppy disk load times ca. 1987 are
> acceptable. Enabling this option as noted may result in audio glitches
> or other usability issues while the disk drive is powering down (as the
> emulator switches from 'fast' to 'normal' speed.)
### Using Disks

On the left hand side of the main emulator screen is a tray of buttons representing
each of the supported disk drives on the system. Once you have located software,
you can mount disks by pressing the appropriate drive button for the disk image you
with to use.

![Disk Selection](docs/disk-tray.png)

Typically IIgs applications use the "s5d1" and "s5d2" devices which represent the 3.5" disk
drives. Legacy Apple II disks can be mounted using the "s6d1" and "s6d2" device buttons.

Currently Clemens does not support DOS 13 sector disks. This restriction does not
apply to most Apple II titles from the 1980s.


## Operation (Hotkeys, etc.) <a name="hotkeys"></a>

This writeup isn't meant to be a complete tutorial on operating the Apple IIgs.
But you'll need to understand how to use the emulated Apple Desktop Bus Keyboard
(ADB) and how keys like `Open-Apple` and `Option` map to keys on your device.

Some of the below operations are available in the main menu. But it's important
to understand how to use the keyboard to run certain operations.

| Platform | Option | Open Apple | Reset | Control Panel |
|----------|------------|------------|-------|-------------------------------|
| Windows | Left Alt | Right Alt | F12 | Control + Right Alt + F1 |
| Linux | Left Alt | Right Alt | F12 | Control + Right Alt + Tux + 1 |
| macOS | Option | Command | F12 | Control + Command + F1 |


![Control Panel](docs/control-panel.jpg)

Common to all platforms is the `Escape Modifier` key. That is, when pressing
either Alt/Option/Command keys, F1 acts as the Escape key. This behavior is
due to how desktop environments typically treat Alt + Escape as a reserved
key combination.

### Windows

| Action | Key Combination |
|--------------------------------|---------------------------------------------|
| Break to BASIC | Control + F12 |
| System Reset + Options Screen | Control + Left Alt + F12 |
| System Reset | Control + Right Alt + F12 |
| Control Panel/Desk Accessories | Control + Right Alt + F1 |

As a rule, the `Left Alt` and `Right Alt` keys map to `Option and Apple` keys
on the **ADB keyboard** respectively.

### Macintosh

| Action | Key Combination |
|--------------------------------|---------------------------------------------|
| Break to BASIC | Control + F12 |
| System Reset + Options Screen | Control + Option + F12 |
| System Reset | Control + Command + F12 |
| Control Panel/Desk Accessories | Control + Command + F1 |

For Mac keyboards, `Option` and `Command` keys map to `Option and Apple` keys
on the **ADB keyboard** respecitvely.

### Linux

Depending on hardware, the Linux host's keyboard may also have a `Tux` key.
This is synonymous with the Windows key on a modern PC keyboard.

| Action | Key Combination |
|--------------------------------|---------------------------------------------|
| Break to BASIC | Control + Tux + `=` |
| System Reset + Options Screen | Control + Left Alt/Option + Tux + `=` |
| System Reset | Control + Command + Tux + `=` |
| Control Panel/Desk Accessories | Control + Command + Tux + `1` |

Because of how Linux desktop environments handle the Alt + Fn key combination,
Clemens also supports a method to mock function keys by pressing *both* `Tux` and
a number key to generate a function key. For example, a user can press `Control + Right Alt + Tux + 1`
which sends a `Control`, `Command` and `F1` key combination to the emulator.

## Finding ROM and Software Files <a name="finding-roms"></a>

Clemens doesn't distribute any IIgs ROMs or software since they are still copyrighted
by Apple. There are sites where one can find valid ROM files.

There are two good sources for ROMs and software:

* [Asimov](https://mirrors.apple2.org.za/ftp.apple.asimov.net/)
* [What is the Apple IIgs](https://www.whatisthe2gs.apple2.org.za/)

The [Internet Archive](https://archive.org/details/wozaday?tab=collection) also
contains WOZ disk images useful for copy protected software.

## Debugger <a name="debugger"></a>

## Troubleshooting <a name="troubleshooting"></a>

## Missing Features <a name="known-issues"></a>

* ROM 1 support
* Serial communication (over IP, then USB via emulation layer)
* Printer support
* International Keyboards
* Monochrome Graphics Modes
* Transwarp (8mhz+ native mode)
* Shadow bank bit 0 (Ninjaforce demo emulation)
* ROM 3 Mouse ADB Keypad emulation
* SHK, BXY disk image support

Binary file removed devices/S7SPHD
Binary file not shown.
1 change: 0 additions & 1 deletion devices/_FileInformation.txt

This file was deleted.

11 changes: 10 additions & 1 deletion docs/SCC.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,16 @@ Signal names followed by emulated port pin with peripheral.
The Zilog supports more signals that may be unused by the IIGS (i.e. like DCD.)
Implementation will depend on practical need.

## Interrupt and Timings
## Terminal Emulation

- Simple interrupts
- Device layer (like cards) with
- DTR
- CTS (HSKI)
- DCD (GPI)
- RTS (TX_D_HI)
- TxD
- RxD


## References
Expand Down
Binary file added docs/control-panel.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/disk-tray.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/manual-setup-data.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/manual-setup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions external/mpack.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

#define MPACK_AMALGAMATED 1
#define MPACK_RELEASE_VERSION 1
#define MPACK_BUILDER 0

#if defined(MPACK_HAS_CONFIG) && MPACK_HAS_CONFIG
#include "mpack-config.h"
Expand Down
2 changes: 1 addition & 1 deletion host/cinek/circular_buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ template <typename Element, size_t Size> bool CircularBuffer<Element, Size>::pop
if (current_head == _tail.load())
return false; // empty queue

item = _array[current_head];
item = std::move(_array[current_head]);
_head.store(increment(current_head));
return true;
}
Expand Down
12 changes: 12 additions & 0 deletions host/clem_assets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ ImageInfo loadImageFromPNG(const uint8_t *data, size_t dataSize) {
return image;
}

uintptr_t loadImageFromPNG(const uint8_t *data, size_t dataSize, int* width, int* height) {
auto image = loadImageFromPNG(data, dataSize);
*width = image.width;
*height = image.height;
return image.image.id;
}

// only call for images that will be thrown out (i.e. from loadImageFromPNG)
void freeLoadedImage(uintptr_t imageId) {
sg_destroy_image(sg_image{(uint32_t)imageId});
}

void initialize() {
// TODO: might make sense to make this a sprite sheet...
g_allImages[kPowerButton] = loadImageFromPNG(power_png, power_png_len);
Expand Down
7 changes: 7 additions & 0 deletions host/clem_assets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ float getImageAspect(ImageId imageId);
ImageId getImageFromName(std::string_view name);
void terminate();


// dynamically create images from PNG data
uintptr_t loadImageFromPNG(const uint8_t *data, size_t dataSize, int* width, int* height);
// only call for images that will be thrown out (i.e. from loadImageFromPNG)
void freeLoadedImage(uintptr_t imageId);


}; // namespace ClemensHostAssets

#endif
10 changes: 8 additions & 2 deletions host/clem_audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,15 @@ void ClemensAudioDevice::stop() {
unsigned ClemensAudioDevice::getAudioFrequency() const { return saudio_sample_rate(); }
unsigned ClemensAudioDevice::getBufferStride() const { return queuedFrameStride_; }

unsigned ClemensAudioDevice::queue(const ClemensAudio &audio) {
if (!audio.frame_count || !queuedFrameBuffer_)
unsigned ClemensAudioDevice::queue(const ClemensAudio &audio, bool flush) {
if (!audio.frame_count || !queuedFrameBuffer_ || flush) {
if (flush) {
std::lock_guard<std::mutex> lk(queuedFrameMutex_);
queuedFrameTail_ = 0;
queuedFrameHead_ = 0;
}
return 0;
}

// the audio data layout of our queue must be the same as the data coming
// in from the emulated device. conversion between formats occurs during
Expand Down
2 changes: 1 addition & 1 deletion host/clem_audio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class ClemensAudioDevice {

void start();
void stop();
unsigned queue(const ClemensAudio &audio);
unsigned queue(const ClemensAudio &audio, bool flush);

private:
static void mixAudio(float *buffer, int num_frames, int num_channels, void *user_data);
Expand Down
Loading

0 comments on commit c4c2db5

Please sign in to comment.