General Information
WinAPE - The Windows Amstrad Plus Emulator

Version 2.0 Beta 2

Program written by Richard Wilson using Borland Delphi 7.

WinAPE is the most comprehensive Amstrad CPC and Amstrad Plus emulator for Windows. It features fast emulation without sacrificing accuracy to the original machine, allowing most programs and games developed for the CPC and Amstrad Plus machines to be enjoyed on your PC. Also included is a fully featured debugger and extremely fast Maxam compatible Z80 assembler.

WinAPE is Freeware. You are free to distribute this program.

A number of ROM images supplied with WinAPE are still copyright to Amstrad Plc and Locomotive Software. Amstrad and Locomotive have given permission for these ROM images to be distributed with CPC emulators, but retains the copyright. They are therefore freely distributable with WinAPE.

Software for use with this emulator is available on the internet at a number of sites. An archive containing most of the games and utilities ever made for the CPC can be found at ftp://ftp.nvg.ntnu.no/pub/cpc or The Amstrad CPC Games Resource web site http://tacgr.emuunlim.com.

For more information on Amstrad CPC related issues, go to http://genesis8.free.fr and look for the FAQ.

The latest version of WinAPE, Amstrad Plus cartridge games and other products I have produced for the CPC are available at http://www.winape.net.

Any queries regarding WinAPE or the web site, please contact me through The CPC Wiki (http://www.cpcwiki.eu)


Buttons on the Tool Bar

	Run (Leave Debug mode) When in debug mode, this button will start emulation and hide all debug windows.
	Pause (Enter Debug mode) When running, this button will pause emulation and display the debug windows.
	Single-Step (Enter Debug mode) When running, this button will pause emulation and display the debug windows. When in debug mode, this button will execute a single instruction or part of a repeating instruction, following into call instructions.
	Step-Over (Enter Debug mode) When running, this button will pause emulation and display the debug windows, unless a prior instruction is already in step-over mode. When in debug mode, this button will execute a single instruction. Executing repeating instructions to completion and executing entire routines on call or rst instructions.
	Display Register Window Displays information about the current state of the various support chips of the CPC including the VGA (Video Gate Array), CRTC (Cathode Ray Tube Controller), PSG (Programmable Sound Generator) and ASIC (The Amstrad Plus chip comprising the VGA, CRTC and various extras).
	Assembler Displays the assembler IDE. This allows programs to be written in Maxam compatible Z80 assembly language and assembled either directly to the emulator memory, or output to a PC disc, hard disc or disc image.
	Select Disc(s) Selects the disc image to be used in the emulated CPC floppy disc drives. Formats supported are .DSC/.HDR (from RWCPC), .DSK (from Marco Veith CPCEMU, the most common format) or .ARC (Xexor archive).
	Select Cartridge Selects an Amstrad Plus cartridge. Selecting a cartridge will reset the emulation and start the cartridge program immediately. If a cartridge fails to work it is most likely due to a ROM conflict. Select Disable all ROMs in the Memory Settings screen. Formats supported are .CPR (RIFF format image) and .CRT (Binary cartridge data).
	Tape Monitor Displays the Tape Monitor. This can be used to load and play CDT, TZX, VOC or WAV format tape files.
	Load a Snapshot Loads a snapshot file and begins execution. A snapshot file contains information about the state of the CPC emulator at the time it was saved. This can be a convenient way to load previously saved games.
	Save a Snapshot Saves a snapshot file. Saves the state of the CPC emulator at the time this button is pressed. This can be a convenient way to save a game to avoid loading times, or to save the current position in the game.
	Configuration Configures the various options for WinAPE. These options include display settings, sound settings, keyboard layout configuration and ROMs loaded.
	Pokes Allows entry and editing of game cheats and pokes.
	Toggle Full Screen Mode Toggles between normal (running within a window) and full screen mode.
	Display this Help File


Keyboard Usage

The keys used to control WinAPE are as follows:

Key	Function
F1	Help
F2	Select Disc(s)
F3	Show Assembler (from Emulation Window)
F3	Find Again (Debugger and Assembler)
F4	Run To Cursor (Debugger)
F5	Load Snapshot
F6	Save Snapshot
F7	Single-Step (Enter Debug mode)
F8	Step-Over (Enter Debug mode)
F9	Run (Leave Debug mode)
F10	Toggle Full Screen Mode
F11	Multiface Stop
F12	Configuration
SHIFT+F1	Flip Disc in Drive A:
SHIFT+F2	Flip Disc in Drive B:
SHIFT+F3	Set Emulation to Normal Speed (100%)
SHIFT+F4	Set Emulation to High Speed (1000%)
CTRL+F1	Insert Disc Image in Drive A:
CTRL+F2	Insert Disc Image in Drive B:
CTRL+F3	Insert Cartridge
CTRL+F4	Insert Tape Image
CTRL+F5	Auto-Type
CTRL+F6	Update the last saved Snapshot
CTRL+F7	Save Screenshot
CTRL+F8	Pokes
CTRL+F9	Reset
CTRL+F12	Toggle AMX Mouse Emulation
SHIFT+CTRL+F1	Edit the Disc in Drive A:
SHIFT+CTRL+F2	Edit the Disc in Drive B:
SHIFT+CTRL+F3	Swap the Discs in Drive A: and Drive B:
SHIFT+CTRL+F9	Cold Reset (Clear all RAM)

See Buttons On The Tool Bar for a more detailed description of these functions.

The key layout of the Amstrad CPC keyboard is somewhat different to that of the PC keyboard. For this reason, all Amstrad keys can be mapped to any keys on the PC keyboard, and keyboard mappings can be saved and loaded as required. See Input Settings for more information.


Menu Options

The Main Menu and Right-Click Menu of the WinAPE main emulation screen provide all the functions available from buttons or the keyboard function keys. The functions are:

File Menu

Menu	Sub-Menu	Key	Description
Drive A:	Insert Disc Image	CTRL+F1	Select a disc image for Drive A:
	New Blank Disc		Create a new blank disc image for Drive A:
	Format Disc Image		Format the disc in Drive A:
	Edit Disc	SHIFT+CTRL+F1	Edit the disc in Drive A:
	Flip Disc	SHIFT+F1	Flip to the alternate disc in Drive A:
	Remove Disc		Remove the disc in Drive A:
Drive B:	Insert Disc Image	CTRL+F2	Select a disc image for Drive B:
	New Blank Disc		Create a new blank disc image for Drive B:
	Format Disc Image		Format the disc in Drive B:
	Edit Disc	SHIFT+CTRL+F2	Edit the disc in Drive B:
	Flip Disc	SHIFT+F2	Flip to the alternate disc in Drive B:
	Remove Disc		Remove the disc in Drive B:
Swap Discs A: and B:		SHIFT+CTRL+F3	Swap the disc in Drive A: and Drive B:
Drive Setup		F2	Select discs for all drives and sides.
Load Cartridge		CTRL+F3	Select an Amstrad Plus Cartridge.
Tape	Show Tape Control		Show the Tape Monitor/Control window.
	Insert Tape Image	CTRL+F4	Load a Tape Image (CSV, TZX, VOC or WAV) as the emulated tape.
	Rewind Tape		Remove the current tape Image.
	Press Play		Start the emulated tape player.
	Press Record		Select a WAV file and record the tape signal to it.
Load Snapshot		F5	Load a Snapshot of the entire emulation state.
Save Snapshot		F6	Save a Snapshot of the entire emulation state.
Update Snapshot		CTRL+F6	Overwrite the previously saved Snapshot with a new one using the current emulation state.
Playback Session			Play back a previously recorded Session Recording.
Record Session			Create a Session Recording of the current session, starting with a snapshot and all key presses or changes until the recording is stopped.
Save Screenshot		CTRL+F7	Save a Screenshot of the emulator screen.
Record AVI			Record a video of the emulator including the audio to an AVI file.
Record WAV			Record the audio output of the emulator to a WAV file.
Record YM			Record the audio output of the emulator to a YM file (requires a YM Player).
Pokes		CTRL+F8	Create or Enter Pokes to modify running code or a game.
Auto-Type		CTRL+F5	Use Auto Type to enter text and keystrokes or copy data from Windows into the emulated Amstrad.
Paste		CTRL+F11	Copy text from the Windows Clipboard into the emulated Amstrad.
Exit		ALT+F4	Close WinAPE.

Settings Menu

Menu	Key	Description
General		Show the General Settings screen.
Display		Show the Display Settings screen.
Sound		Show the Sound Settings screen.
Memory		Show the Memory Settings screen.
Input		Show the Input Settings screen.
Other		Show the Other Settings screen.
Normal Speed (100%)	SHIFT+F3	Set the emulation speed to the normal speed at which an Amstrad operates.
High Speed (1000%)	SHIFT+F4	Set the emulation speed to ten times the normal speed at which an Amstrad operates. Useful for loading tapes quickly.
Full Screen	F10	Switch between Windowed and Full Screen modes.
Reset	CTRL+F9	Reset the emulator.
Cold Reset	SHIFT+CTRL+F9	Reset the emulator and clear all memory bytes to zero.
AMX Mouse	CTRL+F12	Toggle the AMX Mouse emulation on or off.
Multiface Stop	F11	Press the Stop button on the Multiface (only if it is enabled and has a ROM selected).

Debug Menu

Menu	Key	Description
Run	F9	Continue the emulation.
Pause	F7	Pause the emulation and show the debugger.
Registers		Show the Register Window.
Breakpoints		Show the Breakpoints Window.
Data Areas		Show the Data Areas Window.
Timers		Show the Timers Window.
Find Graphics		Show the Graphics Finder Window.

Assembler Menu

Menu	Key	Description
Show Assembler	F3	Show the Assembler Window.

Help Menu

Menu	Key	Description
Contents	F1	Show the Contents page of this Help file.


Using Discs
Selecting and Using Discs

The Drive Setup window allows disc images to be selected for each of the floppy drives supported by the CPC.

Click the Open button for the required drive. Select a disc file (.DSK, .DSC or .ARC), then click Ok.

See Running Programs for more information on running programs and games from disc images.

If you select a Floppy drive * (Floppy A: or Floppy B:) you must select a Format so WinAPE can read and write directly to the floppy drive as there is currently no support for auto-detection of formats.

* Limited direct use of floppy drives may be supported depending on your version of Windows and the availability of fdrawcmd.sys. You can install the floppy driver for free from the Official fdrawcmd.sys site (http://simonowen.com/fdrawcmd/), thanks to Simon Owen for providing this great driver.

Allow Single-sided read forces the FDC (Floppy Disc Controller) to read head 0 of a disc during reading even if the FDC read/read deleted command specified head 1 if the selected track is not formatted. This can be useful for some demos and games which output head 1 for the standard CPC floppy drive which is only single sided.

Allow Temporary Writes allows WinAPE to write to a read-only disc image. The changes will be discarded when the disc image is removed or WinAPE is closed. This can be useful for using some games and applications which require the disc to be not write-protected for protection or saving of high score tables etc, even if you are running from an archive or operating system read-only file.

Prompt to Save Changes will cause WinAPE to ask if you want to save changes to a disc image if it has been changed when it is removed or WinAPE is closing.

The Edit button will show the Disc and File Editor for the currently selected disc allowing you to manage the files or sectors on the disc.

The Flip button allows you to quickly switch between two different disc setups on the current drive. This option allows you to have two different discs and flip between them during emulation by pressing SHIFT-F1 (Drive A:) or SHIFT-F2 (Drive B:).

The Swap button allows you to quickly swap discs between Drive A: and Drive B:

Although WinAPE officially supports 4 disc drives (when enabled), very little software for the CPC (including AMSDOS) makes use of the full drive select capabilities of the floppy disc controller, and you are restricted to drives A: and B: only.


Running Programs

Note:	Many users have problems getting to the BASIC command prompt in order to run CPC programs from disc or tape. If you see the following in the centre of the screen: press the 1 key on the PC numeric keypad with Num Lock switched on. This key on the PC numeric keypad is mapped to the F1 key on the CPC keyboard.

WinAPE can use disc images, tape images or cartridge images containing Amstrad CPC software programs. With the help of the CPCDOS ROM image provided, programs can also be loaded and saved directly to the Windows file system.

Disc Images
WinAPE accepts DSK, ARC and DSC files. DSK images of most of the games for the Amstrad can be found at http://tacgr.emuunlim.com/ in the form of ZIP files.

To use disc games (DSK etc) click the disc button [image] (or press F2). Click the Select Disc button for drive A:, select the file, then select Ok.

Most disc games require you to type run disc to get them started. You can get the  by holding SHIFT and pressing the 2 key. Other games require you to type run "disk", and others require you to type |cpm. You can get the | symbol by holding SHIFT and pressing the [ key.

Some programs and demos do not use any of the above methods. For these you must get a directory listing of the disc. Type cat to do this. Look at the file names listed. The most likely file names to be able to run are either files with no extension or .BAS files. To run these, simply type run "filename".

Tapes
Tape images can be loaded by clicking the tape button [image]. For more information see Tape Monitor.

Cartridges
Most of the CPC+ cartridge games are also available for download through the download page of the WinAPE web site http://www.winape.net in the form of ZIP files.

To use cartridge games, simply click the cartridge icon on the bottom of the screen [image], select the file and you should be able to play the game straight away.


Command Line Parameters

When starting WinAPE a disc image filename can be specified as a parameter (without the slash option). The following parameters can be specified on the command line:

Parameter	Function
filename	Specify the filename for the disc image to be used in Drive A:
/A	Automatically run the program in Drive A:. To specify the name of the program to run use /A:filename. To start a disc using a CP/M boot sector use /A:|CPM
/T:filename	Automatically start typing from the given Auto-type file.
/SN:filename	Specify a Snapshot file to be loaded and automatically started.
/SYM:filename	Load a file containing assembler/debugger symbols.
/SHUTDOWN	Shut down Windows when WinAPE is closed. Use /SHUTDOWN:FORCE to force shutdown if required.

For example, to start WinAPE using the disc image frogger.dsk contained within a Zip file frogger.zip and run the program named frogger use:

WinAPE frogger.zip\:frogger.dsk /a:frogger


The History of WinAPE

The current version of WinAPE is a Borland Delphi 7 application making use of DirectX through the Delphi DirectX conversion performed by the Delphi Jedi project team.

WinAPE started life as a DOS based emulator called CPCEMU (not to be confused with CPCEMU by Marco Veith) which is still available on the archives, now commonly known as RWCPC.

CPCEMU was written in Turbo Pascal 6. It contained an integrated debugger, used VGA 640x200, 16 colour mode, supported 128K of memory plus 17 16K ROMs and ran a lot of CPC games which did not do screen splits. Sound support was limited to beeps on the internal CPC speaker, and there was no integrated assembler.

CPCEMU was originally developed in early 1994 making it one of, if not the first CPC emulator ever produced.

A short time after Delphi 1 became available under Windows 3.x, CPCEMU was converted to run under Windows using Windows DIB's (Device Independent Bitmaps) to render the display, and introducing a Windows based debugger including memory dump, stack dump, VGA and PSG register display, and an integrated assembler. Most of the existing DOS-based emulation code was re-used, but the rendering engine and memory mapping system was completely re-written. This was the first, and probably the only Windows 16-bit CPC emulator ever developed.

A number of significant improvements were made in the Windows 16-bit version:

 •  Support for scan-line based CRTC emulation.

 •  Support for much more memory (64K base memory + 32 16K banks of expanded memory + 17 16K ROMs)

 •  Support for additional disc formats (.DSK and Xexor .ARC), smart caching.

 •  Integrated Assembler

 •  Improved Debugger

 •  Windows Multi-Media based sound (updated on a per-frame basis).

In early 1998 CPCEMU for Windows got migrated to Windows 95. Using Borland Delphi 3 and the early versions of the DirectX conversions from DGC (The Delphi Games Creator). The name WinAPE (Windows Amstrad Plus Emulator) was given in January 1999. Since early 1998, WinAPE has progressed a long way. Some of the major features implemented in the 32 bit version have been:

 •  Support for the Amstrad Plus range. Hardware Sprites, DMA sound, 4096 colour palette, hardware split-screen and cartridges (an extra 32 16K banks of memory and new memory mapping schemes).

 •  DirectDraw support with 256 or 16-bit colour.

 •  Timing improvements

 •  DirectSound support (updated at the selected frequency), supports digitised samples, noise and envelope register support.

 •  Keyboard re-mapping

 •  Much better CRTC emulation (now runs almost all games, and most demos)

 •  Support for Windows NT/2000/XP

 •  Enhancements to assembler, and integration with emulator to allow assembler programs to be entered, assembled and tested in the emulator.

 •  Version 1, 2


The Future of WinAPE

The following items may be implemented before the first non Beta release:

 •  Support for PC file systems without the use of the CPCDOS ROM image. I'm open to suggestions on how to change directories from the Amstrad command line without using RSX (|) commands.

 •  Amstrad parallel port mapping to Windows printers, using the Protext default control codes for bold, underline etc, and DMP-2000 compatible graphics modes.

 •  Support for Amstrad serial interface emulation through the PC serial ports.

 •  Better support for full-screen mode. (Involves creating a new tool bar that can be used in full screen mode with back-buffer flipping).

The following items may be implemented after the first non Beta release:

 •  Object oriented extensions to the assembler.

 •  SSA-1 speech emulation (I need some documentation and the phoneme ROM).

 •  Emulator extensions (The ability to control Windows etc from the Z80!)

 •  Device drivers to allow floppy drives to be used to read, write and format CPC discs.

 •  Object Pascal Z80 compiler. (Sorry no C/C++ compiler, I hate the language)

That lot should see me working on WinAPE for the next 20 years or so.


General Settings

The General section allows control of emulation and general program features including timing and CRTC type to be selected.

The Version Information box contains information about what's new in the current version of WinAPE.

Options
The CRTC Type combo box allows you to select the type of cathode ray tube controller to be emulated. Various versions of the Amstrad CPC used different versions of the CRTC. Some demos, and a very few games may require a certain type of CRTC, or may act differently with different types of CRTC (Get Dexter/Crafton

Enable Plus Features enables or disables emulation of Amstrad Plus features, including changes to the Z80 interrupt vector which may affect some software which uses Z80 interrupt mode 2. These programs are rare, and will usually work with the setting turned on.

Plus PPI Emulation affects the way the emulated PPI 8255 behaves. When switched on it behaves more like the ASIC emulation of the device.

Enable Four Drives will allow the emulator to use four drives (A: to D:) under CP/M Plus and some other software.

Fast Disc Emulation makes disc access much faster by reducing the step time to 0.4ms, reducing inter-sector wait times significantly and reducing sector skipping times. Some original disc protection schemes will not work correctly with Fast Disc emulation enabled.

Save Screenshot on Frame Flyback causes all screenshots to be saved on the monitor frame flyback. This provides a better picture without tearing or missing sprites etc. The ability to disable this is only provided to allow developers to save a screenshot part-way through a frame for testing.

Disable Automatic Update allows the automatic update to be turned off. Automatic update causes WinAPE to attempt to query the latest version from the WinAPE site. This is done once after a few seconds of running.

Check for updates now will query the WinAPE site to see if a newer version of WinAPE is available, and allow you to download and install the newer version.

Timing
WinAPE allows control of emulation speed in two ways:

1. When Display Every is not checked, the slider can be set at the required emulation speed. This can be anywhere from 5% to 1000%. Higher values may cause frames to be skipped on slower PCs.

2. When Display Every is checked, the value in the box next to it determines how many frames are skipped. The value can be set anywhere between 1 and 50. If this is set to 1 the emulation will run as fast as possible displaying every frame of emulation. If set to 50, only one frame of every 50 will be displayed, resulting in very fast emulation.

Turbo Mode causes the emulation of the Z80 chip itself to use less cycles per instruction (1us for every instruction except OUT which takes 2us). This is very non-standard and will cause most demos and some games to function incorrectly, but can improve the performance of some software effects without changing the overall frame timing.


Display Settings

The Display section allows various display options to be set.

The Colour, Green and Greyscale options select the type of monitor to be emulated.

V Hold allows the vertical hold of the monitor emulation to be changed. Many demos, and some games use CRTC settings which vary the number of lines in a frame. These may cause the screen to roll (as with a TV). Adjust this setting to stop the screen rolling.

Brightness allows the monitor brightness to be adjusted.

Options
A number of options can now be specified separately for Windowed and Full Screen modes. This makes it easier to have one set up for general use (eg. Developing or debugging in Windowed mode) and another for a better experience when in Full Screen mode (eg. Hide everything in Full Screen to make for a more realistic experience when playing games).

Half Size Display sets the output display to 384 x 270 pixels. This is half the normal horizontal resolution of a real CPC, but may be the best option to use if you're having performance problems. This mode also produces a better output (using anti-aliasing) when producing AVIs which use the CPC's MODE 2 graphics mode if the AVI is also not full size.

Render both lines determines if every second pixel row is rendered in full size mode. Performance may be better if only every second pixel row is rendered, and many users think this appears more like a real CPC. No display information is lost since a normal CPC pixel takes two rows to display.

Hide Mouse Pointer allows the Windows mouse pointer to be hidden when the mouse is over the emulation display.

Hide Control Panel hides the control panel at the bottom of the display which normally contains buttons and emulation performance information.

Hide Menus hides the menus at the top of the main emulator window.

No Right-Click Menu disables the right-click mouse menu which normally appears when the right mouse button is clicked on the emulator display. This is useful when running programs that use the mouse (eg. SymbOS).

DirectX Stretch determines if the DirectX API's are used to render both pixel lines by stretching the image. This may provide the best rendering performance when Render both pixel lines is selected. The DirectX Stretch mode also allows the emulator window to be stretched to any size or aspect ratio when running in Windowed mode.

PAL Emulation Anti-aliases pixels within each scan line and displays alternate scan lines at half brightness.

Linear Palette Linear palette provides a palette with linear increments between intensity 0 and intensity 15. On a standard CPC the intensity of the half-tones is close to half that of the bright version of the colour (for example the dark blue background at boot time has an RGB value of approximately #000080, but for the Plus this value is darker, approximately #000066). Switch off the linear palette to give a more accurate representation of standard CPC colours.

Full Screen Colour Depth allows the number of colours used to be set to either 8 Bit (256 colours) or 16 bit (65536 colours). With some PC display adapters the 8 bit mode may provide better performance in full screen mode. 256 colours is not enough to display the entire Amstrad Plus palette (which is 4096 colours), so some Amstrad Plus games and programs will look better in 16 bit mode.


Sound Settings

The Sound section determines the way in which the CPC sound chip output is emulated on the PC.

Sound Output
This set of buttons determines the type of sound output.

None will disable sound output altogether.

PC Speaker will produce sound from the internal PC speaker. The internal PC speaker can only produce beeps of a single tone, no white noise and only a single channel. The CPC has three sound channels so they must be merged into one for the PC speaker.

DirectSound will produce the most accurate emulation of the programmable sound generator in the CPC.

DirectSound Options
Sample Rate selects the sample rate for DirectSound emulation. The 44kHz setting is the most accurate setting but has the highest impact on emulation performance.

Bits Per Sample sets the number of bits used in each sound sample. The 8 bit setting will use 8 bits per sample (256 output levels) and the 16 bit setting will use 16 bits per sample (65536 output levels). The CPC is only capable of 16 different output levels, so there may be no noticeable difference between 8 bit and 16 bit output except at very low volume levels. 16 bit samples have the highest impact on emulation performance.

Sample Channels allows the number of sample channels to be selected. The Mono setting causes all three CPC sound channels to be combined into one. The Stereo setting causes Channel A of the PSG to be heard on the left, Channel C to be heard on the right and Channel B to be heard in the middle. The stereo setting has the highest impact on emulation performance.

Note: Some combinations may not be available depending on the sound hardware in the PC.

The Volume control allows the volume of the output through DirectSound to be controlled. Setting 0 is the lowest at the bottom of the slider (no sound) and setting 15 is the loudest.

The Sound Buffer Synchronisation control may be used if the sound output appears to either lag behind the display, or to appear to repeat unnecessarily. This usually only happens when using DirectSound emulation under Windows NT. It may not be possible to get the setting perfect in this environment, but it should be possible to adjust to a reasonable lag by adjusting the buffer sync.

Other Sounds
Some other sounds that can be heard when using a real CPC and other devices are also emulated.

Disc Drive Sounds plays a whirring sound while the drive motor is running and a gentle clicking sound as the drive head seeks from track to track.

Tape Loading Sounds plays the output from the tape through the speakers so you can hear loading progress.

AmDrum enables emulation of a device call AmDrum which is an 8 bit Digital to Analogue converter which can play various sound effects or digital music. When enabled the output of the device can be controlled directly by outputting a value to ports in the range #FF00 through #FFFF. Digiblaster emulation is also provided through the printer port, this can be configured through the Other settings tab. If both AmDrum and Digiblaster are used together the output is combined, so you will not hear both.


Memory Settings

RAM
WinAPE can be configured to emulate a CPC with or without expansion memory. Use this setting to determine the amount of expansion memory available.

64K can be used to emulate a standard CPC464, CPC664 or Amstrad 464 Plus.

128K can be used to emulate a standard CPC6128 or Amstrad 6128 Plus.

4M Expansion can be used to emulate Yarek's 4 Meg expansion. This uses extended Output port addressing (#78xx through to #7Exx) to select banks from alternate zones of 512K each.

256K Silicon Disc adds the top 16 banks of 16K (selections #7fe1 through #7fff) as used by Dk'Tronics Silicon Disc.

The RAM Expansion emulation emulates Dk'Tronics RAM expansions and Silicon Discs providing up to a total of 576K RAM memory, or the full 4M expansion providing 4160K of memory.

Multiface
WinAPE can emulate a Multiface II. To enable this option, select Enable Multiface and select the location of the Multiface ROM.

Cartridge
Cartridges as used in Amstrad Plus and GX4000 machines can be enabled or disabled and selected using this option.

ROMs
CPC compatible ROM images (Read-Only Memory) can be selected for the Lower ROM and each of the Upper ROM slots available. ROM images placed in the ROM folder in the WinAPE folder will be displayed without the full path. Use this folder to store frequently used ROM images. The last option in the drop-down list when selecting a ROM for any slot is Select a file... which allows a file to be used from any other folder under Windows.

Although the ROM selection takes place immediately, the CPC firmware will not register the ROM immediately. Resetting the emulator after selecting ROM images will allow the CPC firmware to register the change. Hold CTRL and press F9 to reset the emulator.

Enable 32 ROMs allows up to 32 ROM slots to be populated. Most ROM boards developed for the CPC only allowed a maximum of 16 ROMs to be used, and the standard CPC firmware will only scan the first 16 ROMs for background ROMs, however, some software may be able to access the higher ROM numbers directly and a recent modified firmware is available which allows 32 ROMs to be used properly.

Disable all ROMs disables all external ROMs, including the lower (firmware) ROM. This setting is generally only useful if the cartridge is enabled, otherwise there will be no operating system available.

Disable all but Lower, 0 and 7 allows the emulator to run with all non-standard ROM slots disabled. This can be useful of some programs won't run with ROMs enabled, without the need to update your ROM configuration.

Standard CPC Emulation
* WinAPE has been designed to be capable of emulating the Amstrad Plus range of computers. It can, however, be set up quite simply to emulate any of the computers in the standard CPC range. To do this, un-check the Enable Plus Features check box in the General Settings section, then select the following ROM images and settings on this section:

CPC464	- Select 64K for the RAM setting. Select OS464 as the Lower ROM and BASIC1-0 as Upper ROM number 0. Remove any other ROM images.
CPC664	- Select 64K for the RAM setting. Select OS664 as the Lower ROM and BASIC664 as Upper ROM number 0. Select AMSDOS as Upper ROM number 7 and remove all other ROM images.
CPC6128	- Select 128K for the RAM setting. Select OS6128 as the Lower ROM and BASIC1-1 as Upper ROM number 0. Select AMSDOS as Upper ROM number 7 and remove all other ROM images.

* Later versions of WinAPE support Profiles, and come with a number of standard profiles included which provide the above configurations.


Input Settings

The Input section allows each key on the Amstrad CPC keyboard to be mapped to keys on the PC keyboard. By clicking any of the keys, the keys mapped on the PC keyboard will be shown in the combo boxes below allowing the CPC key to be mapped to any PC keys.

The Num Lock key on the PC keyboard allows different sets of keys to be toggled. For example, with the default keyboard mapping the 2 key on the PC numeric keypad is mapped to F2 on the CPC keyboard when Num Lock is turned on, but when Num Lock is turned off it is mapped to the down direction of the joystick.

Up to three PC keys can be mapped to each CPC keyboard key in each state. This allows mapping of the two PC SHIFT and CTRL keys to the single CPC SHIFT and CONTROL keys. (The CPC keyboard actually has two SHIFT keys, but both are connected to the same circuit inside the CPC. It is impossible for the CPC to know which of the SHIFT keys is pressed).

Keyboard layouts can be saved using the Save button or loaded using the Load button. When the emulator starts, the last loaded keyboard layout is re-loaded.

Enable Joystick allows joystick emulation to be enabled ot disabled. Normally WinAPE uses DirectX to emulate the Amstrad joystick and this can cause characters to be displayed on the screen if not calibrated properly.


Other Settings

The Other section contains settings for other emulated devices.

Symbiface II
The Symbiface II provides IDE, Real-time clock and PS/2 mouse support for the CPC.

Enable IDE Devices enables or disables IDE emulation. Master and Slave allow a logical drive or IDE file to be used for emulation of the Master and Slave IDE devices.

WARNING: If you use a Logical Drive without Read Only checked you give the emulator write access to your entire logical drive. I accept no responsibility for badly written CPC IDE software which may corrupt your hard drive!

NOTE: The WinAPE installation comes with a blank 10GB FAT32 hard drive image (blank.ide). This file is read-only. In order to create a usable blank IDE drive image, simply make a writable copy of this file.

Enable Real-Time Clock enables or disables Real-Time clock emulation.

Enable PS/2 Mouse enables or disables PS/2 mouse emulation.

Adjust Mouse for Screen Mode causes mouse movements to be scaled depending on the current CPC screen mode.

Printer
Printer output can be either Disabled or sent to a Printer, File or a tab in the WinAPE assembler.

Digiblaster gives the option to emulate a Digiblaster, an 8-bit Digital to Analogue converter module which can be plugged into the printer port on a real CPC. Some software uses this to produce digital sound effects. WinAPE also supports AmDrum which can be enabled in the Sound settings tab. Using both together sends the last value written to either port to a single sound channel, so it is not possible to play both at the same time.

Other Devices
WinAPE also has some support for Dobbertin SmartWatch emulation. Currently the time can only be read, and there is no support for this device in Snapshots or Session Recording.


Using the Debugger

WinAPE features a fully integrated Z80 debugger. This allows you to pause the emulation at any time, examine or modify the values of Z80 registers, view the running Z80 program and edit, load and save regions of emulator memory.

To start the debugger at any time while the emulator is running, click the pause button [image] or press F7 or F8.

To resume emulation click the play button [image] or press F9.

While in debug mode the F7 key allows you to single step through executing Z80 instructions. Pressing this key will execute a single instruction or part of an instruction. Single stepping repeating instructions (eg. LDIR, LDDR) will cause one execution cycle of that instruction to be performed. Single stepping through CALL instructions will continue stepping into the called location.

The F8 key allows you to step over certain instructions. Step over works in much the same way as single stepping, but repeating instructions are executed as a whole, and CALL instructions are not followed, but performed. If the F8 key is pressed with a CALL instruction which does not return to the address immediately after the call instruction the emulator will continue to run until it is paused, the F8 key will be disabled.

The F4 key allows the emulator to run until it reaches the currently selected instruction in the Disassembler Pane.

The debugger disassembly, memory and stack values displayed are in the region of memory currently selected in the Memory Selection section of the debugger.

Multiple breakpoints can be set and the emulator will stop and enter debug mode whenever these instructions are reached.

The T value is a representation of the current number of elapsed microsecond cycles since the last time the value was reset using the adjacent button.

The Follow PC check box causes the disassembler pane to follow the current Program Counter (PC) value.

The Hide On Run check box causes the debugger to be hidden when the emulator leaves debug mode and resumes running normally.

The Breakpoints check box allows all breakpoints to be enabled or disabled with a single click.

The Break Instructions check box allows WinAPE to use a special BRK instruction (ED FF) as a breakpoint.

The [image] button displays The Breakpoints Window, allowing breakpoints to be modified and have conditions set.

The [image] button displays The Data Areas window, allowing areas of emulator memory to be marked as data and displayed using db or dw instructions in the disassembler.

The [image] button displays the Timers window, which shows Timers which have been used in Breakpoints.

The [image] button displays the The Graphics Finder window, allowing areas of memory to be viewed and edited graphically.

The [image] button loads a file to the currently selected location in the Memory Dump Pane.

The [image] button saves the currently selected region in the Memory Dump Pane to a file.

The [image] button allows you to position either the disassembler pane or memory dump pane to a specific address, depending on which was last clicked.

The [image] button allows you to find data in memory starting at the address selected in either the disassembler pane or memory dump pane, depending on which was last clicked.

For more information on each section see:

The Disassembler Pane
The Memory Dump Pane
The Stack Pane
The Breakpoints Window
The Data Areas Window
The Graphics Finder
The Register Window


The Disassembler Pane

The Disassembler pane allows you to view regions of the running CPC emulator memory in Z80 assembly language format.

Each line represents a single Z80 instruction. The first column is the start address for the instruction followed by the Z80 assembly language instruction. The second column is the hexadecimal byte values for the memory occupied by the instruction, the third column (shown in green) is an ASCII representation of the memory, and the final part shows any assembler symbols which have the value of the current address.

Clicking on the grey area to the left of an instruction will toggle a breakpoint at the selected address.

Any region of the CPC memory can be selected for viewing. See Memory Selection for more information.
Dragging the mouse or holding the SHIFT key while clicking allows you to select a range of instructions.

Right-clicking the disassembler will provide options to:

Find	CTRL+F	Find Instructions, Text or Data.
Goto	CTRL+G	Position the disassembler to a given hexadecimal address.
Run To Cursor	F4	Run emulation up until the selected address.
Toggle Breakpoint	F5	Toggle a Breakpoint at the selected address.
Disassemble		Disassemble the selected range of instructions.
Mark as Data		Mark a region as a Data Area.
Clear Data Area		Clear a previously set Data Area.


The Memory Dump Pane

The Memory Dump pane allows you to view, edit, load, save or search regions of the running CPC emulator memory.

Each line represents 16 bytes of memory. The first four digits are the start address for the line, the second section contains 16 hexadecimal numbers showing the value of the 16 bytes from the given start address, and the third section is an ASCII representation of the same 16 bytes. Editing of hex bytes or ASCII data can be toggled by clicking on the appropriate section or pressing CTRL+TAB.

Memory Breakpoints are displayed with a green background for Read, red background for Write or a yellow background if the region contains both a read and a write breakpoint.

Any region of the CPC memory can be selected for viewing or editing. See Memory Selection for more information.

Right-clicking the memory dump pane will provide options to:

Find	CTRL+F	Find Instructions, Text or Data.
Goto	CTRL+G	Position the cursor to a given hexadecimal address.
Select Block		Select a region of memory by entering a start and end address.
Load	F5	Load a file starting at the current selection start.
Save		Save the selected region to a file.
Breakpoint on Read		Mark the selected region as a Breakpoint which will trigger when the memory is read from.
Breakpoint on Write		Mark the selected region as a Breakpoint which will trigger when the memory is written to.
Compare To		Compare the selected region to another address or the contents of a file.
Fill		Fill the selected region of memory with hex data or a string.
Disassemble		Disassemble the selected area of memory.
Mark as Data		Mark a region of memory as a Data Area.
Clear Data Area		Clear a previously set Data Area.


The Stack Pane

The stack pane shows the current contents of the stack. Each call, push, pop, ret or rst instruction executed by the emulated Z80 causes the stack pointer to add or remove a 16 bit word on the stack. The stack window will follow the current position of the SP register when in debug mode. Double-clicking an item in the stack will cause the disassembler to display the code at the selected address.


The Breakpoints Window

The Breakpoints window displays all current breakpoints, their type, pass count and any associated conditions. The Address displayed also indicates which area of memory or the Input/Output range the breakpoint is in.

All breakpoints can be given a Pass Count and Condition by double-clicking in the appropriate column in this window. The Count displays the number of times the breakpoint has been valid. If a pass count has not been set the breakpoint will interrupt the emulation every time, but if a pass count has been set this will also show the pass count so you can keep track of how many passes have occurred so far, and the emulation will not be interrupted until the valid count reaches the set pass count. See Breakpoint Properties for more information.

There are three types of Breakpoint:

Code Breakpoints

Code Breakpoints can be set using the Disassembler Pane of the debugger, or from assembler source code in the Assembler. Since the CPC memory map allows blocks of 16K to be switched in and out, the address shown is always relative to the start of the actual block in which the breakpoint was set. For example, a breakpoint set at #C006 in an Upper ROM would show as 0006:Upper n.

Memory Breakpoints

Memory Breakpoints can be set by selecting a section of memory in the Memory Dump Pane of the debugger, then clicking either Breakpoint on Read or Breakpoint on Write. They are similar to code breakpoints except they will only occur when the selected area of memory is read from or written to.

The variables address, value and previous can be used within memory breakpoint conditions to determine which address in the range was read or written, the value read or written, and the previous value in the case of a memory write.

Input/Output Breakpoints

Input/Output Breakpoints allow the emulation to be interrupted when a particular device is read from or written to. They can be set using the Add button on the Breakpoints Window, which will present the following screen:

On this screen, you can easily select from one of the predefined port mappings by selecting the device using the combo box, or you can select User Defined Port and enter your own Port value and Mask. The Port is a 4 digit hex I/O port address and can be entered using the X character to represent any value, automatically specifying the appropriate Mask. For example, entering BCXX will automatically enter a mask of FF00.

For user defined port mappings you must also specify either Input, Output or both. The Breakpoint Condition and Pass Count can also be set here, see Breakpoint Properties for more information.

Input/Output breakpoints also have access to the address and value variables to determine the exact port being read or written and the value read or written.


The Data Areas Window

Data Areas are regions of emulator memory that are defined as data rather than code so that they are displayed in the disassembly pane and any output disassembly using either db or dw instructions.

Each data area can be marked as Bytes (displayed using db) or Words (displayed using dw) by selecting the appropriate option in the Type column.
There is also an option to allow assembler symbols to be used to populate matching values when the Label column is ticked.


The Graphics Finder

The Graphics Finder window is used to display and edit regions of emulator memory in a graphical format.

While a program is running it is possible to view a region of memory as varied width and height tiles using a number of different data formats to help locate the graphics data for the program.

By selecting the Paintbrush or Fill Bucket buttons it is also possible to draw directly into the emulator memory.


The Register Window

The Register window displays the current values of CPC registers on the various support chips inside the CPC.

The registers are:

Palette	The palette registers on the VGA (Video gate array). The light blue highlight shows the last selected register.
PSG	The registers in the PSG (Programmable Sound Generator). The light blue highlight shows the last selected register.
CRTC	The registers in the CRTC (Cathode Ray Tube Controller). The blue highlight shows the last selected register.
VCC	The Vertical Character Counter (an internal CRTC register). Keeps track of the current vertical character number. When this value equals R6 of the CRTC (vertical displayed), display output is disabled. When this value equals R4 of the CRTC (vertical total), display output is enabled and the display base address is reset. When this value equals R7 of the CRTC (vertical sync position) a Vertical Sync occurs, the display will start drawing from the top if the current VDUR value is within a threshold range.
VLC	The Vertical Line Counter (an internal CRTC register). Keeps track of the current raster line within the character. When this equals R9 (maximum scan line) of the CRTC the VCC will be incremented next line.
R52	The Raster 52 divider counter (an internal VGA register). This triggers interrupts on the CPC. After the maximum value of 51 is reached an interrupt request is made and the counter is reset to zero. Bit 5 of this register can be reset by various events.
VSC	The Vertical Sync counter (an internal emulator register). When a Vertical Sync occurs this register is set to zero. When a frame flyback is active this will be displayed in light blue and count the lines in the frame flyback period.
HDC	The Horizontal Display Counter shows the current horizontal position on the monitor being drawn.
VTAC	The Vertical Total Adjust Counter is shown in light blue when the end of the current CRTC frame is reached (after VCC = R4) and CRTC Register 5 has a value other than zero. This counts up to the value in CRTC register 5 before the next frame is started.
HCC	The Horizontal Character Counter (an internal CRTC register). Keeps track of the current horizontal character number. When this value equals R1 of the CRTC (horizontal displayed) display output is disabled for the rest of the current line. When this value equals R0 of the CRTC (horizontal total), display output is enabled and this value is reset to zero. When this value equals R2 of the CRTC (horizontal sync position) a new scan line may be started depending on the current HSYNC position of the monitor.
HSC	The Horizontal Sync Counter counts the number of cycles during a HSYNC. This is shown in light blue when the CRTC Horizontal Sync period is active.
VMA	The Video display address. This is derived from the MA register in the CRTC, the horizontal character count HCC and the current row address (RA) register in the CRTC. This is effectively the CPC memory address of the data displayed on the monitor.
VDUR	The Video Display Unit Raster line (an internal emulator register). This determines the current drawing offset within the emulator display. When a Vertical Sync occurs, this register is set to a negative value determined by the current vertical position. For values between 0 and 269 (010D Hex) video data will be displayed in the emulator display.
Mode	The current display mode.
ICSR	Interrupt Control Status Register. This determines the state of pending Z80 interrupts. Bit 7 indicates that a standard CPC raster interrupt has occurred and not yet been acknowledged (eg. If interrupts are currently disabled). Other bits are used for ASIC DMA interrupts.

The Row Highlight check box will cause the current line and column on the emulator window to be shown when in debug mode.

See ASIC Registers for information on the ASIC button.


Using the Assembler

WinAPE has a fully featured Maxam compatible Z80 assembler built in. To access the assembler at any time click the Assembler button [image] or press F3.

The assembler allows you to open and create multiple assembly language files, to write Z80 assembly language code, and to assemble the code into Z80 machine code directly into the emulator memory, or to a file.

The window consist of a menu bar with options to create, open, save and assemble files, the main file editor area with tabs below for each open file, and an error message display area.

Files which have been modified and not yet saved will show an asterisk beside their name.

Clicking on the left grey gutter section in the code editor allows you to set or clear Breakpoints.

Double-clicking an error message will take you to the source line with the error.

To assemble an open file either select Assemble from the Assemble menu or hold CTRL and press F9. To run a Z80 program either select Run from the Assemble menu or press F9. Note: It is only possible to run programs if they contain the run directive.

While assembling a program, a window will appear containing information on the assembly process, and a listing of the output code. The listing can be turned on or off using the list and nolist keywords.

After a program has been assembled it is possible to get a list of all symbols labelled in the program. Choose Symbols from Assemble menu.

You can filter the displayed symbols by typing text in the Filter box, load or save symbols by right-clicking, or go to the source, code or memory location of the symbol.

The Z80 assembly language format is backwards compatible with Maxam 1.5 for the CPC, with a few extensions to the syntax. See Assembler Syntax for more information.

For information on the assembler Find and Replace commands, see Assembler Find/Replace Winfow.


Assembler Syntax

The WinAPE assembler is designed to be compatible with Maxam 1.5 with some extensions to the standard Maxam assembler.

The supports all Z80 Instructions, a number of Assembler Directives for functionality other than pure Z80 code, and the ability to use Labels and Comments. Each line of code can contain multiple instructions separated by the colon character (:), although generally most people use one line per instruction for readability.

Code Origin
All assembler code needs to be given a starting point in memory. Without defining the origin for the code, WinAPE will assume that the code starts at address #0000, and the code will most likely overwrite the lower region of memory used for restart instructions and interrupts. The assembler directive used to set the origin of code is org, and is usually one of the first lines in an assembly language program. For example:

org #4000

The above line tells the assembler to start producing code from memory address #4000. All instructions and directives which produce code output starting at the given address, and the current assembler code address can be used in expressions by using the $ symbol.

Labels
A label is used to define a symbol at the current assembly address. This can be useful for naming looping points, subroutines or variables. Labels must start with either an underscore character or an alphabetic character, and can only contain letters, numbers or underscore. A label definition can be a single word which is not a reserved word (Z80 or directive) either in a line on its own or immediately preceding another Z80 instruction or directive. Labels can also be preceded by a dot (.), which is not included as part of the symbol itself, and can also allow reserved words to be used as labels. For example:

org #4000

ABC
def:ghi ld a,b
.jkl ld c,d:mno
pqr: ld b,a
_stu:
jp pqr

The above code will define ABC, def and ghi all as having the current address #4000. Code will be generated for the instruction ld a,b which is one byte, so the next label .jkl will create a symbol named jkl which will have the value #4001. Code will be generated for the instruction ld c,d which is also one byte, so the next two labels mno and pqr will have the value #4002. Code will be generated for the instruction ld b,a which is another single byte so the final label _stu will be given the value #4003. The jp pqr instruction uses the value of pqr to assemble a Z80 jump instruction with the address of the symbol.

The actual output from the assembler shows these values in the listing as below:

000001  0000  (4000)        org #4000
000002  4000                ABC
000003  4000                def
000003  4000  78            ghi ld a,b
000004  4001  4A            .jkl ld c,d
000004  4002                mno
000005  4002                pqr
000005  4002  47             ld b,a
000006  4003                _stu
000007  4003  C3 02 40      jp pqr

The columns shown are the line number in the current file, the current assembly address, generated code (or expression value) and the final column is the actual partial line of code since the last line or colon character.

Assigning Values to Symbols
By default symbols defined by labels are given the current code address as their value. It is possible to assign different values to symbols using the equ directive. For example:

.int_vector equ #38

free_space  equ end_addr + 20

.print      equ 6 * 3 + jump_table

The code above assigns the value of #38 to the symbol int_vector, the second line assigns the value of end_addr + 20 to the symbol free_space, and the third line assigns the value 6 * 3 + jump_table to the symbol print. Note that the assembler does not currently (as per Maxam) support operator precedence, so the expression is evaluated left-to-right, and jump_table + 6 * 3 would be produce a totally different result. For example:

x equ 3

y equ 2 * 4 + x

z equ x + 2 * 4

The code above assigns the value 3 to x, then the value for y is evaluated as 2 * 4 = 8 then 8 + x = 11 so the result will be a value of 11.
The final value for z is also evaluated left-to-right as x + 2 = 5, then 5 * 4 = 20 so the final value for z will be 20.

The LET directive
By default, symbols can only be defined to have one value in any assembler program. Symbols are not the same as BASIC variables, and it is very rare that their values need to be changed.

The let directive allows a symbol to be redefined to have different values in different parts of an assembler program. As a general rule you should never use let in your programs except in special circumstances.

Including other source files
The WinAPE assembler allows mutiple files to be assembled at once by including other source files using the read or incbin directives.

read allows the inclusion of another assembler source file. This may contain symbol definitions, macro definitions and source code in any combination, just as the main source file. Files included with read may also be nested, and the included file has access to all symbols within the parent source files in the same way as code within the main source file.

incbin allows the inclusion of binary data in the assembler output. This may be any arbitrary binary data generated from any source, such as graphics data, sound data or code generated by another compiler.

Files included with read or incbin are searched for beginning with the directory of the current file, then all other directories specified in the Library Path.


Assembler Z80 Support
WinAPE Assembler Z80 Support

Z80 Registers
The assembler supports all standard Z80 8 bit registers A, B, C, D, E, H, L and special 8 bit registers I and R. It also supports all standard Z80 16 bit registers AF, BC, DE, HL and SP and index registers IX and IY. For one instruction EX AF,AF' the alternate AF' register is also supported.

WinAPE also supports the undocumented use of the 8 bit portions of the IX and IY registers, these registers may be entered as HX or IXh, LX or IXl, HY or IYh and LY or IYl. References below will use the first versions (HX, LX, HY and LY) although they apply equally to the alternate version.

Z80 Conditions
The assembler supports all Z80 conditions NZ, Z, NC, C, PO, PE, P and M.

Z80 Instructions
All the standard Z80 instructions are supported with some additional support for undocumented instructions or register usage. The following table lists all Z80 instructions supported. The assembler is NOT case-sensitive.

Instruction	Description
ADC A,r	Add with Carry (r = A, B, C, D, E, H, L, HX, HY, LX or LY)
ADC A,n	n is a byte
ADC A,(HL)
ADC A,(IX + d)	d is signed displacement
ADC A,(IY + d)
ADC HL,ss	(ss = BC, DE, HL or SP)
ADD A,r	Add (r = A, B, C, D, E, H, L, HX, HY, LX or LY)
ADD A,n	n is a byte
ADD A,(HL)
ADD A,(IX + d)	d is signed displacement
ADD A,(IY + d)
ADD HL,ss	(ss = BC, DE, HL or SP)
ADD IX,pp	(pp = BC, DE, IX or SP)
ADD IY,rr	(pp = BC, DE, IY or SP)
AND A,r	(r = A, B, C, D, E, H, L, HX, HY, LX or LY)
AND A,n	n is a byte
AND A,(HL)
AND A,(IX + d)	d is signed displacement
AND A,(IY + d)
BIT b,r	Test Bit b (b = 0 .. 7, r = B, C, D, E, H, L or A)
BIT b,(HL)
BIT b,(IX + d)
BIT b,(IY + d)
CALL nn	Call Subroutine at nn
CALL cc,nn	Call on Condition (cc = NZ, Z, NC, C, PO, PE, P or M)
CCF	Complement Carry Flag
CP A,r	Compare (r = A, B, C, D, E, H, L, HX, HY, LX or LY)
CP A,n	n is a byte
CP A,(HL)
CP A,(IX + d)	d is signed displacement
CP A,(IY + d)
CPD	Compare with Decrement
CPDR
CPI	Compare with Increment
CPIR
CPL	Complement Accumulator
DAA	Decimal Adjust Accumulator
DEC r	Decrement (r = A, B, C, D, E, H, L, HX, HY, LX or LY)
DEC (HL)
DEC (IX + d)
DEC (IX + d)
DEC ss	(ss = BC, DE, HL, SP, IX or IY)
DI	Disable Interrupts
DJNZ e
EI	Enable Interrupts
EX AF,AF'
EX DE,HL	Can also be written as EX HL,DE
EX (SP),HL
EX (SP),IX
EX (SP),IY
EXX
HALT
IM 0	Interrupt Mode 0
IM 1	Interrupt Mode 1
IM 2	Interrupt Mode 2
IN A,(n)	Input from Port n. The A register is used for the top 8 bits of the address bus.
IN r,(C)	Input from Port BC (r = B, C, D, E, H, L or A)
INC r	Increment (r = A, B, C, D, E, H, L, HX, HY, LX or LY)
INC (HL)
INC (IX + d)
INC (IX + d)
INC ss	(ss = BC, DE, HL, SP, IX or IY)
IND	Input with Decrement
INDR
INI	Input with Increment
INIR
JP nn	Jump to Address nn
JP cc,nn	Jump on Condition (cc = NZ, Z, NC, C, PO, PE, P or M)
JP (HL)	Jump to HL
JP (IX)	Jump to IX
JP (IY)	Jump to IY
JR e	Jump Relative, calculated address must be within -126 to +130 of instruction address.
JR ss,e	(ss = NZ, Z, NC or C)
LD r,r'	Load register (r/r' = A, B, C, D, E, H, L, HX, HY, LX or LY)
LD r,n	Load register (r = A, B, C, D, E, H, L, HX, HY, LX or LY)
LD r,(HL)	(r = A, B, C, D, E, H or L)
LD r,(IX + d)	(r = A, B, C, D, E, H or L)
LD r,(IY + d)	(r = A, B, C, D, E, H or L)
LD (HL),r	(r = A, B, C, D, E, H or L)
LD (IX + d),r	(r = A, B, C, D, E, H or L)
LD (IY + d),r	(r = A, B, C, D, E, H or L)
LD (HL),n
LD (IX + d),n
LD (IY + d),n
LD A,(BC)
LD A,(DE)
LD A,(nn)
LD (BC),A
LD (DE),A
LD (nn),A
LD A,I
LD A,R
LD I,A
LD R,A
LD dd,nn	(dd = BC, DE, HL, SP, IX or IY)
LD dd,(nn)	(dd = BC, DE, HL, SP, IX or IY)
LD (nn),dd	(dd = BC, DE, HL, SP, IX or IY)
LD SP,HL
LD SP,IX
LD SP,IY
LDD	Load with Decrement
LDDR
LDI	Load with Increment
LDIR
NEG	Negate Accumulator
NOP	No Operation
OR A,r	(r = A, B, C, D, E, H, L, HX, HY, LX or LY)
OR A,n	n is a byte
OR A,(HL)
OR A,(IX + d)	d is signed displacement
OR A,(IY + d)
OTDR	Repeated Output with Decrement
OTIR	Repeated Output with Increment
OUT (n),A	Output to Port n. The A register is used for the top 8 bits of the address bus.
OUT (C),r	Output to Port BC (r = B, C, D, E, H, L or A)
OUTD	Output with Decrement
OUTI	Output with Increment
POP qq	(qq = BC, DE, HL, AF, IX or IY)
PUSH qq	(qq = BC, DE, HL, AF, IX or IY)
RES b,r	Reset Bit b (b = 0 .. 7, r = B, C, D, E, H, L or A)
RES b,(HL)
RES b,(IX + d)
RES b,(IY + d)
RET	Return from Subroutine
RET cc	Return if Condition met (cc = NZ, Z, NC, C, PO, PE, P or M)
RETI	Return from Interrupt
RETN	Return from Non-maskable Interrupt
RLA	Rotate Left Accumulator (through Carry)
RL r	(r = B, C, D, E, H, L or A)
RL (HL)
RL (IX + d)
RL (IY + d)
RLCA	Rotate Left Accumulator, copy bit 7 to Carry
RLC r	(r = B, C, D, E, H, L or A)
RLC (HL)
RLC (IX + d)
RLC (IY + d)
RLD	Rotate Left BCD
RRA	Rotate Right Accumulator (through Carry)
RRCA	Rotate Right Accumulator, copy bit 0 to Carry
RRC r	(r = B, C, D, E, H, L or A)
RRC (HL)
RRC (IX + d)
RRC (IY + d)
RRD	Rotate Right BCD
RST p	Call Subroutine (Restart) (p = 0, 8, 16, 24, 32, 40 or 48)
RST p,nn	Equivalent to RST p:DW nn
SBC A,r	Subtract with Carry (r = A, B, C, D, E, H, L, HX, HY, LX or LY)
SBC A,n	n is a byte
SBC A,(HL)
SBC A,(IX + d)	d is signed displacement
SBC A,(IY + d)
SBC HL,ss	(ss = BC, DE, HL or SP)
SCF	Set Carry Flag
SET b,r	Set Bit b (b = 0 .. 7, r = B, C, D, E, H, L or A)
SET b,(HL)
SET b,(IX + d)
SET b,(IY + d)
SLA r	Shift Left Arithmetic (r = B, C, D, E, H, L or A)
SLA (HL)
SLA (IX + d)
SLA (IY + d)
SLL r	Shift Left and set bit 0 (r = B, C, D, E, H, L or A)
SLL (HL)
SLL (IX + d)
SLL (IY + d)
SRA r	Shift Right Arithmetic (r = B, C, D, E, H, L or A)
SRA (HL)
SRA (IX + d)
SRA (IY + d)
SRL r	Shift Right Logical (r = B, C, D, E, H, L or A)
SRL (HL)
SRL (IX + d)
SRL (IY + d)
SUB A,r	Subtract (r = A, B, C, D, E, H, L, HX, HY, LX or LY)
SUB A,n	n is a byte
SUB A,(HL)
SUB A,(IX + d)	d is signed displacement
SUB A,(IY + d)
XOR A,r	(r = A, B, C, D, E, H, L, HX, HY, LX or LY)
XOR A,n	n is a byte
XOR A,(HL)
XOR A,(IX + d)	d is signed displacement
XOR A,(IY + d)

 Indicates that an alternative short format is available without the A, eg. ADC H is the short version of ADC A,H
 Indicates a displacement ranging from -128 to +127. The assembler accepts (IX + d), (IX + -d) or (IX - d), similarly for IY. eg. LD B,(IY - 5)
 Load instructions using HX or LX cannot use H, L, HY or LY as the other register. Similarly, Load instructions using HY or LY cannot use H, L, HX or LX.
 Indicates an undocumented instruction.
 The relative address is calculated by the assembler from the supplied absolute address. If the value is outside the range -128 to 127 from the current instruction address plus the two bytes offset fetched by the Z80, the assembler will produce an error.
 The restart instruction can also use the values 0 to 7 which are multiplied by 8, so RST n is equivalent to RST p where p = n * 8 (n >= 0 and n <= 7). eg. RST 3 is the same as RST #18


Assembler Directives

The integrated assembler in WinAPE is fully backwards compatible with Maxam 1.5, but provides some extensions to the syntax.

Command	Description
align boundary[,fill]	Align code to a given boundary and fill the space with the given fill. If fill is not specified it will be filled with 0 bytes. eg. align 256,#ff will insert #ff bytes up to the next 256 byte page boundary. If the code is already aligned, no bytes will be generated.
brk	Generates an rst #30 Maxam style breakpoint.
byte value,value...	Equivalent to defb.
charset [string,value|byte,value|start,end,value]	Allows the value of characters or characters in strings to be assigned alternative values. There are 4 forms of this directive. charset on its own defines all 256 characters to have their original ASCII values. charset string,value allows each character in the given string to be assigned consecutive values starting at value. charset byte,value allows a single character to be redefined, and finally charset start,end,value allows the characters starting with start to and ending at end to be assigned consecutive values starting at value. For more information see Redefining Characters.
checksum reset [initial value]	Reset checksum generation with the given initial value or 0 if not specified.
close	Closes the output from a write or write direct directive.
code	Enables code generation. See nocode below.
db value,value...	Alternative short form of defb.
defb value,value...	Takes a list of byte or string values and generates a byte for each value or for each character in a string. Strings may be enclosed in double or single quotes. eg. defb "Hello",32,"t" - 32,'here',10 would generate the bytes (hexadecimal) 48 65 6C 6C 6F 20 54 68 65 72 65 0A
label defl value	Equivalent to equ.
defm value,value...	Equivalent to defb.
defs size[,fill],size[,fill]...	Generate size bytes of fill or 0 bytes if fill is not specified. A number of consecutive regions can be specified with individual fill bytes. eg. defs 3,#ff,4,0,5,#80,2 would generate the bytes (hexadecimal) FF FF FF 00 00 00 00 80 80 80 80 80 00 00
defw value,value...	Takes a list of values which are written out as 16 bit little-endian words. eg. defw #1234, #abcd, 1, 2000 would generate the bytes (hexadecimal) 34 12 CD AB 01 00 D0 07
dm value,value...	Equivalent to defb.
ds size[,fill],size[,fill]...	Alternative short form of defs.
dump	Not currently implemented. Maxam used it to write symbol information.
dw value,value...	Alternative short form of defw.
else	Conditionally assembles the following section up until another else, elseif or endif if another previous if or elseif at the same depth has not been assembled.
elseif condtion	Conditionally assembles the following section up until another else, elseif or endif if another previous if or elseif at the same depth has not been assembled and the condition evaluates to a non-zero value.
end	Marks the end of an assembler program. All following code will be ignored. An end directive found inside a file included with read also causes all following code to be ignored both inside the include file, and every parent file.
endif	Marks the end of a conditional code section.
endm	Equivalent to mend.
label equ value	Defines a symbol label and assigns it a value. The value must be fully able to be evaluated on the second pass of the assembler. eg. MC_WAIT_FLYBACK equ &BD19
if condtion	Conditionally assembles the following section up until an else,elseif or endif if the given condition evaluates to a non-zero value.
ifdef symbol	Conditionally assemblers the following section up until an else,elseif or endif if the given symbol has already been defined.
ifndef symbol	Conditionally assemblers the following section up until an else,elseif or endif if the given symbol has not already been defined.
ifnot condtion	Conditionally assembles the following section up until an else,elseif or endif if the given condition evaluates to zero.
incbin filename[,offset[,size[,offset_high]]]	Includes the file with the given filename in the assembly as binary data. The offset within the file is calculated as offset_high * 65536 + offset, and the size can be up to 65535 (#ffff) bytes. Multiple incbin directives can be used to read more of the file. The file may contain any binary data and is simply output byte by byte to the generated output. See Including other source files for more information.
let symbol = value	The let directive is similar to equ except it allows symbols to be redefined. Most assembler symbols should only ever have a single value and should usually be defined with equ. Do not redefine symbols with let unless you are aware of the way the assembler will treat the symbol in all parts of the code where it is used.
limit address	Sets the maximum code address to the value specified by address. If the generated code address goes beyond the limit an error will be raised. This can help ensure sections of your program remain within a certain region of memory and don't get too big to fit. The address is the code address, not the output address, and emulator memory beyond that point will be protected.
list	Enables output listing in the assembly output window. See nolist below for more information.
macro name [parameter,parameter...]	Defines a Macro with the given name taking the given optional list of parameters. A macro is a re-usable section of code that can be passed parameters. For more information see Assembler Macros.
mend	Marks the end of a macro definition.
nocode	Disables code generation. For all instructions and assembler directives which generate data, the output code is normally written to the current output (emulator memory or file). The nocode directive allows code output to be switched off, producing no output until the next code directive. The source is still assembled, and this can be useful for testing, or for including another file in order to determine its symbol values without generating code.
nolist	Disables output listing in the assembly output window. Large assembly language programs can contain thousands of lines each of which generate quite verbose output showing line numbers, symbol values, generated output bytes and the line of source code itself. For most larger programs, it is usually better to see only the important sections of code you are currently working on listed or important symbols, so most larger assembly programs have nolist near the start, and important sections enclosed in list and nolist directives.
org code_address[,output_address]	Sets the current assembly origin to code_address. The origin is the base address used to determine the value of labels, and code is normally written to memory starting at that address unless the output_address is specified, allowing the actual generated code to be stored in a different region of emulator memory.
pause	Currently not implemented. In Maxam the assembly is paused so you can read the output, but WinAPE has all the output in a scrolling window so you can go back at any time to read it.
print [string|value]	Outputs a string or evaluated value to the assembly output window. When output is a string the syntax has been extended from Maxam to allow other symbol values to be displayed in decimal (using &) or hexadecimal (using $). eg. print "Start: $start, Count: &count" with start = 500 and count = 10 would output Start: 01F4, Count: 10
read filename	Includes the file with the given filename in the assembly. The file may contain symbol definitions, macro definitions and/or assembly code. See Including other source files for more information.
rend	Marks the end of a repeat loop
repeat count	Assembles the following code up until a rend directive count times. repeat directives are similar to macros, and can contain local (@) labels.
relocate_end	Mark the end of a relocatable section of code.
relocate_start	Mark the start of a relocatable section of code.
relocate_table [byte|word] [base_address]	Generate a relocation table. By default a table of word sized offsets is generated, override this by specifying byte for small code sections. The base_address specifies the relative origin for the values in the table.
rmem size[,fill],size[,fill]...	Equivalent to defs.
run address[,breakpoint]	The run directive allows the program to be executed immediately after successful assembly starting execution at the given address. An optional breakpoint can be set at address given by breakpoint.
save [direct] filename,address,size...[,exec_address]	Saves regions of emulator memory to a file with the given filename. The direct option allows data to be saved directly to a disc image. Each of the regions starting at address with the given size are appended to the file, then optionally the execution address is set to exec_address for files on disc images.
stop	Stops assembly immediately, producing an Assembly Stopped error.
str	The str directive allows a list of strings to be generated with each character of the string except the last output as a single byte character and the last character of each string output as its character byte value with bit 7 set. eg. str "ABC", "def" will generate the bytes (hexadecimal) 41 42 C3 44 45 C6
text value,value...	Equivalent to defb.
title	Not currently implemented. Maxam used it to set the title for printed output.
word value,value...	Equivalent to defw.
wend	Marks the end of a while loop
while condition	Assembles the following code (up until a wend directive while the condition evaluates to non-zero. while directives are similar to macros, and can contain local (@) labels.
write [direct] filename[,exec_address]	Direct generated code output to a file. For write direct the output is sent to a file on a disc image, and an optional execution address exec_address can be specified. For write without direct the output is sent to a file in the Windows file system.
write direct [lower_rom[, upper_rom[, ram_bank]]]	Allows direct output to emulator memory. The current emulator write memory is used by default but the optional parameters allow ROMs to be enabled or RAM banks to be selected. lower_rom should be -1 to disable or 0 to enable the Lower ROM, upper_rom should be -1 to disable, or an upper ROM number, and ram_bank can be an expansion bank number #C0 to #FF (or #8C0 to #EFF for Yarek 4MB style bank mapping).
write direct sectors sector_range	Allows the assembler to write its output directly to a range of sectors on a disc image. The sector range is a string and must be of the form [A:|B:] track[-last_track]:sector[-last_sector]... where track specifies a single track, or a range of tracks with last_track, and sector specifies a single sector, or a range of sectors with last_sector. Tracks are decimal and sectors are always hexadecimal. eg. write direct sectors "10:c4-c9 11-20:c1-c9 21:c1-c3" could be used to write the generated output to the sectors starting at track 10 sector C4 and ending at track 21 sector C3.

The WinAPE assembler contains a few reserved symbols and functions with special meanings. These can be used inside any expression, including defb and defw values. They are:

checksum([start,count])	Evaluate the sum of either generated bytes since the last checksum reset directive or of a region of emulator memory starting at address start for count bytes.
checksum(style[,poly,initial,reverse][,start,count])	Evaluate a sum or Cyclic Redundancy Check (CRC) or either generated bytes since the last checksum_reset directive or a region of emulator memory starting at address start for count bytes. The style parameter is a string specifying one of the following defined CRC styles: crc-8, crc-8-ccitt, crc-8-darc, crc-8-i-code, crc-8-itu, crc-8-maxim, crc-8-rohc, crc-8-wcdma, crc-8-custom, crc-16, crc-16-buypass, crc-16-ccitt, crc-16-dds-110, crc-16-dect, crc-16-dnp, crc-16-en-13757, crc-16-genibus, crc-16-maxim, crc-16-mcrf4xx, crc-16-riello, crc-16-t10-dif, crc-16-teledisk, crc-16-usb, x-25, xmodem, modbus, kermit, crc-ccitt, crc-ccitt-false, crc-aug-ccitt, crc-16-custom. The poly, initial and reverse parameters are only used with crc-8-custom or crc-16-custom and specify the polynomial, initial value and reversal (reversed if not zero).
memory(address)	Reads a word value from emulator memory at the given address. The Lower ROM, Upper ROM and RAM Bank can be previously defined by a write direct directive. Be aware that if this location is inside the assembly output range its value may be determined by the assembly output itself on the last pass.
relocate_count	The number of entries in the relocation table.
relocate_size	The size of the relocation table, assuming the table is using word entries.

The following code will write directly to the emulator memory, run when assembled and break when the instruction at the .break label is reached.

org #4000
write direct
run start, break

relocate_start        ;Start relocatable code section
dw relocate_count     ;Number of entries in the relocation table
relocate_table start  ;Generate a relocation table relative to start

ld de,#40

;Emulator will start running from the ld hl,break instruction
.start
ld hl,break

;Emulator will stop at the following NOP instruction
.break
nop
relocate_end          ;End of relocatable code section


Assembler Macros

The WinAPE assembler provides Macros to allow complex or repeated code to be generated easily by defining custom directives which can optionally include parameters.

Macro definition
Macros are defined using the format:

macro name [parameter,parameter...]

A macro can contain any valid code, including labels and local labels (prefixed with @).

The macro name and all parameters must be defined using valid symbol characters ('A'..'Z', 'a'..'z', '_', '0'..'9').

Each parameter passed is substituted literally into the code inside the macro when it is encountered as a whole word. For this reason, it is preferable to use parameter names which are not normally used in either text strings or as register names. The example below shows a bad macro definition since it uses register names:

macro test a, b, c
  print a
  print "hello a bc"
  print 'c'
  db a, b, c
  db a + b, c + 'a'
  LD H,A
mend

testit 1, '2', 3

The output produced by this would be:

1
hello 1 bc
3
000010  0000  01 32 03        db 1, '2', 3
000010  0003  33 34           db 1 + '2', 3 + '1'
000010  0005  26 01           LD H,1

Notice that the value 1 has been substituted for all A words in the macro definition, including the a inside the string "hello a bc" which has been converted to "hello 1 bc", the 'a' inside quotes in the second db a + b, c + 'a' which has been converted to db 1 + '2', 3 + '1' and also the valid Z80 instruction LD H,A which has been converted to LD H,1. The bc inside the second print is not substituted since there is no parameter called bc.

Overriding Reserved Words
A macro can redefine standard directives or even Z80 instructions. At any time in the assembler, in order to use the standard version simply precede it with an exclamation mark. For example:

macro ld dest,src
  if "dest" = "de"
    if "src" = "bc"
      !ld d,b
      !ld e,c
    elseif "src" = "hl"
      !ld d,h
      !ld e,l
    else
      !ld dest,src
  else
    !ld dest,src
  endif
mend

As a general rule it is not advisable to redefine the function of standard directives or Z80 instructions as it can make your code very hard to maintain.

Local Labels
If a macro contains a label and it is used more than once the assembler will attempt to redefine the same symbol, which will cause an error. For example:

macro decnz_bad
  or a
  jr z,silly1
  dec a
  .silly1
mend

decnz_bad
decnz_bad  ;; <- This line will cause a Duplicate Definition error

By using a local label (a symbol prefixed with an @ character) the assembler will scope the label to the current macro only. So a correct definition for a macro to decrement A if it's not zero could be:

macro decnz_a
  or a
  jr z,@leave
  dec a
  @leave
mend

decnz_a
decnz_a

The output of the above decnz_a two lines would be:

000008  0000                decnz_a
000008  0000  B7              or a
000008  0001  28 01           jr z,@leave
000008  0003  3D              dec a
000008  0004                  @leave
000009  0004                decnz_a
000009  0004  B7              or a
000009  0005  28 01           jr z,@leave
000009  0007  3D              dec a
000009  0008                  @leave

Curly Brackets
Curly brackets allow parameters to be included in the middle of another word. For example, consider the following macro:

macro curly param
  print "Hparamo"
mend

curly ell

The assembler would print out the word Hello.

Nested Macros
Macros can use previously defined macros internally. For example:

macro swap reg1, reg2
  ld a,reg1
  ld reg1,reg2
  ld reg2,a
mend

macro swap_bcde
  swap b,c
  swap d,e
mend

swap_bcde

The assembler output for the swap_bcde line is:

000012  0000                swap_bcde
000012  0000                  swap b,c
000012  0000  78              ld a,b
000012  0001  41              ld b,c
000012  0002  4F              ld c,a
000012  0003                  swap d,e
000012  0003  7A              ld a,d
000012  0004  53              ld d,e
000012  0005  5F              ld e,a

Combining Macros with the LET directive
Since let allows a symbol to be redefined, global symbols can be shared between multiple macros. For example:

macro pixel_address x, y
  @y7 equ y and 7 * #800
  @addr equ y / 8 * #50 + #c000 + @y7
  let pix_addr = x / 8 + @addr
  let pix_mask = #80
  repeat x and 7
    let pix_mask = pix_mask / 2
  rend
mend

macro get_pixel_address addr_reg, mask_reg, x_pos, y_pos
  pixel_address x_pos,y_pos
  ld addr_reg,pix_addr
  ld mask_reg,pix_mask
mend

get_pixel_address hl,e,233,36

The assembler output for the get_pixel_address hl,e,233,36 line of code is:

000017  0000                get_pixel_address hl,e,235,36
000017  0000                  pixel_address 235,36
000017  0000  (2000)          @y7 equ 36 and 7 * #800
000017  0000  (E140)          @addr equ 36 / 8 * #50 + #c000 + @y7
000017  0000  (E15D)          let pix_addr = 235 / 8 + @addr
000017  0000  (0080)          let pix_mask = #80
000017  0000                  repeat 235 and 7
000017  0000                    let pix_mask = pix_mask / 2
000017  0000                  rend
000017  0000  (0040)            let pix_mask = pix_mask / 2
000017  0000  (0020)            let pix_mask = pix_mask / 2
000017  0000  (0010)            let pix_mask = pix_mask / 2
000017  0000  21 5D E1        ld hl,pix_addr
000017  0003  1E 10           ld e,pix_mask
000019  0005                end

That's the equivalent of ld hl,#e15d:ld e,#10 but the assembler works out the address and mask rather than you doing it manually. Unfortunately, the above code won't cope with expressions being passed in as parameters (eg. pixel_address left + 10, top + 20) because the assembler expression evaluation is always performed left-to-right with no support for parenthesis. This is as a result of maintaining Maxam source compatibility, so we would have to modify the macro definition using more local symbols or let to re-assign. For example:

macro pixel_address x, y
  @y1 equ y
  @y7 equ @y1 and 7 * #800
  @addr equ @y1 / 8 * #50 + #c000 + @y7
  let pix_addr = x;
  let pix_addr = pix_addr / 8 + @addr
  let pix_mask = #80
  repeat x and 7
    let pix_mask = pix_mask / 2
  rend
mend

Note that repeat and while are also treated as macros and have their own local symbols. It is not currently possible to access the local symbols of the parent macro, so it would not be possible to modify @y1, @y7 or @addr inside the repeat loop.

String Comparisons
The WinAPE assembler has basic string comparison support, allowing conditional compilation by comparing macro parameters to string values. For example:

macro get_edge_address edge
  if "edge" = "left"
    ld hl,#c050
  elseif "edge" = "top"
    ld hl,#c028
  elseif "edge" = "right"
    ld hl,#c09e
  else
    ld hl,#c0c8
  endif
mend

get_edge_address right


Assembler Options

The options are as follows:

Library Path provides a list of locations where the assembler will search for included source files. When locating files for the read or incbin directives the search order is to use the path of the current file followed by each path listed in the Library Path separated by semi-colon characters (;).

Push PC to stack when running program allows return address pushing to be enabled or disabled when an assembler run directive is included in the source file and the Run option is used. When enabled (default) the current Z80 PC value will be pushed onto the stack.

Automatically hide assembler output on success allows the Output window to be hidden automatically after a successful assembly, making it faster to build or test without having to click the OK button each time.


Assembler Find/Replace Window

The options are as follows:

Text to find The text you want to find.

Replace with The text you want to replace it with.

Case sensitive If checked, only match if the text has the same (upper/lower) case.

Whole words only Only match the whole word. If there are other letters or numbers surrounding the word it will not match.

Prompt on replace Ask to replace each occurrence that is found.

Direction Either search Forward from the selected position towards the end of the file or Backward towards the start of the file.

Scope Either Global (the entire file) or only Selected Text will be searched.

Origin Start searching from the current cursor position if From cursor is selected, or from the start or end of the file or selection if Entire Scope is selected, depending on the direction.


Assembler - Redefining Characters
Redefining Characters in the Assembler

The WinAPE assembler allows characters used in string and character constants within the source files to generate non-standard values. This allows programs to be written which may have either a subset of the ASCII character set or an alternative character set. Some examples follow.

Example 1 - High Score Table
A game may use the bytes 0 to 9 as characters in a score display routine for a high score table rather than the standard ASCII values 48 through 57. The charset directive can be used in a number of ways to achieve this mapping:

Using a start and end range:

charset '0','9',0

Using a string containing the characters

charset "0123456789",0

or each character individually.

charset '0',0:charset '1',1:charset '2',2:charset '3',3:charset '4',4
charset '5',5:charset '6',6:charset '7',7:charset '8',8:charset '9',9

Later in the code, the high score values themselves could be defined as:

.highscores
db "0204", "0183", "0156"

And the assembler would generate the values (hexadecimal):

00 02 00 04 00 01 08 03 00 01 05 06

Example 2 - A limited character set
A game has it's own character set defined using multi-coloured MODE 0 characters. To save memory the graphics data for the characters only includes the uppercase characters 'A' through 'Z', a space character a full stop character and the numbers '0' through '9'. The routine uses null (0) terminated strings, so the first character ('A') has the value 1. Code to do this mapping may be as follows:

charset 'A','Z',1    ;; 1 through 26
charset 'a','z',1    ;; We can also use lower case strings
charset ' ',27
charset '.',28
charset '0','9',29

Later we have a call to display a message in the game

ld hl,message1
jp print

.print
ld a,(hl)
dec a
ret m
inc hl
call print_char
jr print

.message1
db "Welcome to my game. You have 3 lives to start. Good luck.",0

The output generated for the above db directive would be:

17 05 0C 03 0F 0D 05 1B 14 0F 1B 0D 19 1B 07 01
0D 05 1C 1B 19 0F 15 1B 08 01 16 05 1B 20 1B 0C
09 16 05 13 1B 14 0F 1B 13 14 01 12 14 1C 1B 07
0F 0F 04 1B 0C 15 03 0B 1C 00


Breakpoint Properties

All WinAPE Breakpoints can be given a Condition and/or Pass Count.

The Pass Count specifies a number of times the emulator can run past the breakpoint before the emulation is interrupted. If it is set, it is shown in the Breakpoints Window as count / pass count in the Count column.

The Condition field allows an expression to be entered which determines if the breakpoint will interrupt the emulation or not. If the expression evaluates to a non-zero value the emulation will be interrupted (if the pass count is reached if also set).

Breakpoint conditions can use register values (including the use of 8-bit portions of index registers, for example IYh or LX), comparisons (<, <=, =, >=, >), mathematical operators (+, -, *, /, mod, and, or, xor, not, =), decimal numbers, hexadecimal numbers prefixed by # or &, binary numbers prefixed by %, assembler symbols from the last code assembly, brackets ( and ). Conditions also have access to a number of pre-defined variables and functions.

Note: All operators are bitwise and not logical operators, for example, 4 and 2 will evaluate to zero, not #fffffffe will evaluate to 1.

Breakpoint Variables
address	The address or port read or written for a Memory or Input/Output breakpoint.
ay_select	The currently selected PSG (AY) register.
cartridge_bank	The cartridge bank mapped to Lower ROM.
crtc_select	The currently selected CRTC (6845) register.
false	the value 0.
fdc_motor	true if the floppy disc motor is turned on.
lower_enabled	true if the Lower ROM is enabled
mode	The currently selected screen MODE.
mouse_buttons	The current state of mouse buttons.
mouse_wheel	The current mouse wheel value.
mouse_x	The current mouse horizontal value.
mouse_y	The current mouse vertical value.
palette_select	The currently selected palette register.
ppi_a	The current PPI (8255) port A value.
ppi_b	The current PPI (8255) port B value.
ppi_c	The current PPI (8255) port C value.
ppi_control	The current PPI (8255) control value.
previous	The previous value in the memory location given by address in a Memory Write breakpoint.
psg_select	The currently selected PSG (AY) register.
ram_bank	The currently selected extended RAM bank.
rtc_select	The currently selected Symbiface RTC register.
secondary_rom	ASIC secondary ROM select register.
tape_motor	true if the tape motor is turned on.
true	The value #ffffffff.
upper_enabled	true if the Upper ROM is enabled
upper_rom	The currently selected Upper ROM.
value	The value read or written for a Memory or Input/Output breakpoint.

  The value of these variables is undetermined in all other cases.

Breakpoint Functions
ay([register])	Reads either the currently selected PSG (AY) register, or the one specified by register.
byte(value)	The low-order (lease significant) byte of the given value. (Bits 0..7).
crtc([register])	Reads either the currently selected CRTC (6845) register, or the one specified by register
ga_palette([pen[,value]])	Gets the Gate Array palette value for either the currently selected pen, or the one specified by pen. If a value is also specified, the palette for the selected pen is set to the hardware ink in value.
hibyte(value)	The high-order byte of the low-order word of the given value. (Bits 8..15).
hiword(value)	The high-order (most significant) word of the given value. (Bits 16..31).
palette(pen[,grb])	Gets or sets the ASIC palette value for the given pen.(eg. palette(2) would return the value for pen 2, palette(3, #fff) would set pen 3 to white)
peek(addr)	Reads the byte from current readable memory at the given address
poke(addr,n)	Writes values into write memory at the given address (eg. poke(#1000,#10,#20,#30) would place the values #10, #20 and #30 at address #1000)
psg([register])	Reads either the currently selected PSG (AY) register, or the one specified by register.
reset_cycles([value])	Resets the cycle count (T) in the main debugger window to either zero or the value specified.
rtc([register])	Reads either the currently selected Symbiface Real Time Clock register, or the one specified by register.
timer_start([id])	Starts or resets the Timer with the given id, or id of 0. Always returns 0.
timer_stop([id])	Stops the Timer with the given id and returns the number of cycles since the timer was started, up to a maximum of #ffff.
word(value)	The low-order (least significant) word of the given value. (Bits 0..15).


Using Timers

WinAPE Breakpoints allow two Timer functions to be used in the breakpoint condition. They are timer_start and timer_stop. The functions have a single parameter which is a unique identifier (word), and measure the time in microseconds between a timer_start and the each subsequent timer_stop.

The same timer identifier can be used multiple times, allowing multiple sections to be timed using the same timer, or multiple exit points to be set for a routine.

Timer functions can also be used in breakpoints set in the Assembler window.

The timer_start function always returns zero, so the breakpoint won't trigger unless you use an expression to make the result evaluate to non-zero (eg. timer_start(1) = 0), but the timer will always reset, regardless of the result of the condition.

The timer_stop function returns the number of cycles since the last timer_start with the same identifier, up to a maximum of 65535. This will always be non-zero, so the breakpoint will always be triggered unless an expression is used to make sure it isn't (eg. timer_stop(1) and 0). It is not good practice to use the not operator since it is a bitwise operator, so if the result of timer_stop(1) was 66 (#0042), then not timer_stop(1) would evaluate to -67 (#ffbd), which is still non-zero and treated as a true value.

By clicking the [image] button in the main debugger window, you will be able to view the current state of all timers in the Timers window.

This window shows the identifier of the Timer, the number of times the timer has been triggered, the number of microseconds last time it was triggered, along with the minimum, maximum and average times in microseconds.


The Tape Monitor

The Tape Control window allows tape images to be inserted, played, rewound, or positioned to any valid block. Tapes can also be controlled through the menus in the main emulator window.

To run a tape program or game:

Open the required Tape image (CDT, TZX, VOC or WAV file) using the Open button on the Tape Control window.

If you have a disc ROM inserted (or are using the standard Amstrad Plus cartridge), you may need to type |tape. You can get the | symbol by holding SHIFT and pressing the [ key.

Type run" then press Return. (You can get the quotes shown by holding SHIFT and pressing the 2 key).

You will get a message saying:

Press PLAY then any key

Click the play button [image] on the Tape Control window, then press any key in the emulator window and the selected program should load and run. If you are using DirectSound sound emulation you will hear the data being read from the tape image.

You can rewind the tape image, or position it to any data block using the Tape Control window.


Using Snapshots

Snapshots are images of the running emulation at a point in time. Clicking the Save Snapshot button [image] at any time will allow you to save the current emulator state to a snapshot (.SNA) file.

Version 1
Version 3 has been developed by myself, Kevin Thacker (author of Arnold) and Ulrich Doewich (author of Caprice32). It supports Amstrad Plus snapshots and much more accurate emulation information allowing snapshots to be created for demos and later games.

If the program you are running uses the first 64K of expansion memory, select First 128K.

To load a snapshot file click the Load Snapshot button [image] and select a snapshot file.

Version 3 snapshots allow individual areas of expanded memory to be included, and stored in an RLE compressed format. Select the Custom memory setting to change what's saved.


Emulator Configuration
Configuration

The configuration screen for WinAPE is accessed by either pressing the F12 key or clicking the configuration button

The sections on the configuration screen are detailed in the following sections:

General Settings
Display Settings
Sound Settings
Memory Settings
Input Settings
Other Settings

Profiles provide a partial or complete copy of the configuration options which can be loaded and saved as a unit.

Custom profiles can be created and a number of preset profiles are provided to make it easy to emulate the various models of the standard Amstrad CPC range.


Using Pokes
Pokes

The Pokes windows allows you to easily enter cheats or pokes for your favourite games. WinAPE can automatically detect the current running game and will provide you with a list of valid pokes for that game. Click on the game in the top section, and the Poke in the bottom section, then click the Poke button to patch the current running game.

Using this interface you can also enter new cheats for games as you find them, if you're an expert Z80 debugger.

Running Game uses a region of memory selected for each game to detect which game is currently running.

To add a new game, or edit a game click the top Add or Edit button, and you will be presented with the Game Editing screen.

With a game selected in the top list, to add a new poke, or edit a poke for that game, click the Add or Edit button in the bottom section and you will be presented with the Poke Editing screen.


Configuration Profiles

At the top of the WinAPE configuration screen is a combo box allowing you to easily select a custom group of settings called a Profile. The values shown are a list of WPF files contained in the Profiles folder under the WinAPE installation folder, along with an option to select any other file.

The standard profiles provide an easy way to select from standard Amstrad CPC and Plus range settings, but any combination of settings can be saved as a profile.

Clicking the Save button will allow you to select which settings you would like to include in the profile

Then these settings are save to a selected file when you Click the OK button.


Memory Selection

The Memory Dump and Disassembler panes in the WinAPE debugger allow any area of the CPC emulator memory to be selected.

The first set of radio buttons in the Memory section allow you to view or edit the current 64K region of memory that the emulation would normally read or write, or to select a custom view of memory. Select Read to view the memory that the emulation sees for reading, Write to view the memory that the emulation sees for writing, or Any to select a custom memory mapping.

When Any is selected it is possible to view or edit any region of emulator memory.

The ROM section allows lower and upper ROMs to be enabled or disabled, and an upper ROM to be selected. When the upper ROM is enabled, the selected upper ROM will appear in the address ranges #C000 to #FFFF. When the lower ROM is enabled, the selected lower ROM will be visible. The address range of the lower ROM is dependant on the secondary ROM mapping selection, but is normally in the address range #0000 to #3FFF.

The RAM section allows expansion RAM banks to be shown. The RAM selection allows banks of memory to be selected in the same way as they would be on an expanded CPC using the out  command from BASIC. The default RAM bank selection is #C0.
Expansion RAM banks can be mapped to the address range #4000 to #7FFF using values #C4-#C7, #CC-#CF, #D4-#D7, #DC-#DF, #E4-#E7,#EC-#EF, #F4-#F7 or #FC-#FF.
The values #C2, #CA, #D2, #DA, #E2, #EA, #F2 and #FA allow a full 64K section to be mapped (address ranges #0000 to #FFFF).
The values #C1, #C9, #D1, #D9, #E1, #E9, #F1 and #F9 map the first 16K of the block at address range #C000 to #FFFF, and the values #C3, #CB, #D3, #DB, #E3, #EB, #F3 and #FB also map the first 16K block at #C000 to #FFFF, but remap the standard memory from #C000 to #FFFF at address range #4000 to #7FFF.

The Secondary ROM Mapping section allows Amstrad Plus features to be applied to the memory view. The Amstrad Plus can map the lower ROM (or selected cartridge bank) to any of the address ranges #0000 to #3FFF, #4000 to #7FFF or #8000 to #BFFF. It can also enable a special bank of memory called the ASIC RAM. The ASIC RAM can be mapped to #4000 to #7FFF with the lower ROM enabled at address range #0000 to #3FFF. The Lower ROM Base/ASIC Enable option allows the above mapping to be selected. The Amstrad Plus can select one of the first 8 16K cartridge banks to be used as the lower ROM. This can be done in the memory view using the Cartridge Bank option.


Searching in the Debugger

The Find function in the debugger may be activated by the right-click menu on either the disassembly pane or the memory dump pane, by pressing F3, or clicking the [image] button. It allows you to search for data in three ways:

Find Text

Search for a given string in memory. Either case-sensitive or not, with the ability to enter wildcard characters.

Find Hex Data

Search for a byte sequence by entering multiple hexadecimal byte values separated by space.

Find Assembler

Search for particular Z80 instructions. This is not case sensitive, and accepts either ? for a single character wildcard, or * for a multiple character wildcard. The above example would match LD (#B7C4),HL for example.


Disassemble Output

Both the disassembler and memory dump panes of the debugger allow a selected area of memory to be disassembled.

The options allow output to be directed to either a New Assembler Tab, which will create a new file in the disassembler, an Existing Assembler Tab which can be selected from the list, or a File.

The output will normally replace the existing contents of the selected file, unless you click the Append Output check box.


File Editor

The WinAPE File Editor allows files on emulator discs and disc images to be manipulated and copied between the emulator and the Windows file system or other emulator discs. It also allows sectors to be edited directly by selecting the Sector Editor tab.

Files can be selected individually, or multiple files selected using SHIFT or CTRL, then either dragged between windows or Cut, Copied and Pasted between the Disc Editor and Windows Explorer.

Options are available to Show System files which shows hidden files on the disc with their System flag set, and an option to Add/Remove AMSDOS headers which can add the 128 byte AMSDOS header to files that are copied from Windows, or remove it when copying to Windows.

Clicking on a file that is already selected allows it to be renamed in place, and pressing the Delete key allows the selected files to be deleted.

The right-click menu also allows files to be Renamed, Deleted, Cut or Copied, and also has an option to view Properties of the file:

Using this window, you can rename the file and change it's Read-only and System (Hidden) state.


Sector Editor

The WinAPE Disc Editor also allows sectors to be edited directly by switching to the Sector Editor tab.
The current track and sector can be selected using the Track and Sector controls at the top of the screen, or by holding CTRL and using the cursor keys left and right to move between sectors, and up or down to move between tracks.

Double-clicking the sector description ((00 00 C5 02) above) allows certain sector properties to be modified (for non read-only discs).

This screen allows you to change the ID fields of the sector, change the Deleted Data flag and ID/Data Error flags. It also allows the actual sector size to be modified, and displays the bit offset on the track of the sector. Most of these properties should never be modified unless you are creating your own protected disc format or attempting to fix a bad disc image dump.

For advanced formats where multiple copies of sectors are present, you can click the small [+] and [-] buttons near the sector information to add or remove a copy from the disc image.


Using Auto-Type
Auto-Type

The WinAPE Auto-Type feature allows text to be automatically typed into the emulator. The text is free format text with control keys represented by the ~ character. The available control keys are as follows:

~COPY~	The COPY key
~CONTROL~	The CONTROL key
~CLR~	The CLR key
~CAPS LOCK~	The CAPS LOCK key
~DEL~	The DEL key
~DECIMAL~ or ~DOT~	The . key on the numeric keypad
~DOWN~	The down cursor key
~ENTER~	The ENTER key on the numeric keypad
~ESC~	The ESC key
~FIRE~ or ~FIRE1~	The joystick FIRE button
~FIRE2~	The second joystick FIRE button
~FIRE3~	The third joystick FIRE button
~JOY LEFT~	Left on the joystick
~JOY RIGHT~	Right on the joystick
~JOY UP~	Up on the joystick
~JOY DOWN~	Down on the joystick
~LEFT~	The left cursor key
~RIGHT~	The right cursor key
~RETURN~	The RETURN key
~SHIFT~	The SHIFT key
~SPACE~	The SPACE bar
~TAB~	The TAB key
~UP~	The up cursor key

Two tilde (~) characters together will produce a single tilde character.

Keys can be set as pressed using ~+key~, for example ~+A~ will hold down the A key. To release a previously held key use ~-key~, for example ~-A~.

There is also a special command to pause typing, ~PAUSE n~, where n is the number of frames to pause (at 50 frames per second). For example ~PAUSE 50~ will pause for one second.

The script shown in the screen shot above will press F1 on the numeric keypad (to get past the Amstrad Plus BASIC/Burning Rubber prompt), delete the 1 typed if the emulator was already at the BASIC prompt, wait for the BASIC Ready prompt (for 50 frames), type the RETURN key, then type run â€œdiscâ€� followed by RETURN again.

The Auto-Type feature is also available using Paste from the File menu, or by pressing CTRL+F11.


Comparing Memory Regions

From the memory dump pane of the debugger, it is possible to select a region of memory, then compare that region with either another region of memory or a file.

Simply select the region you want to compare, then from the right-click menu select Compare Memory and enter the address with which to compare the selected region.

Select the region you want to compare in the memory dump pane, then from the right-click menu select Compare Memory and select the File tab. Enter a filename or click the ... button to select one.

The Comparison Results screen will show all areas of memory which are different, the size of the difference, and the data at each location.


Filling Memory With Data

The Fill function in the debugger may be accessed by the right-click menu of the memory dump pane. It allows you to fill memory with either repeated Hexadecimal data, or repeated strings.

The above example would fill a 10 byte selected region of memory with the bytes (hexadecimal)
01 02 03 01 02 03 01 02 03 01.

The above example would fill a 20 byte selected region of memory with the bytes (hexadecimal)
48 65 6C 6C 6F 20 57 6F 72 6C 64 21 48 65 6C 6C 6F 20 57 6F


Formatting Discs

Simply select a Format and click the OK button to instantly format a disc image to the selected format.

Clear unused tracks forces the tracks which aren't formatted (eg. Side 2 and Tracks above 40 for a single-sided 40 track disc) to be cleared.

WARNING: Formatting a disc will completely erase all existing data on the disc and there may be no way to recover it.


Recording Sessions

WinAPE allows emulation sessions to be recorded, starting either from a Snapshot of the current state, or from a Cold Reset.

There are two types of session recording files, SNP and SNR. The SNP file type is a simple recording, containing only keypresses and a type 2 snapshot. It does not support many configuration settings or mouse and real-time-clock updates.

The SNR session file uses a type 3 snapshot, and records all key presses, mouse movements (when a read has occurred), and the state of the Symbiface Real-Time-Clock which updates once per second).

This type of session also contains more information about the configuration settings of the emulator, including which discs and ROMs are inserted, but it does not add the original disc image into the recording, so if any changes are made during, or after the session they can cause errors in the playback.

During playback, WinAPE displays a timer in the bottom toolbar which shows the current time in the recording with a green background when everything is synchronised properly or a red background when something has cause the recording to go out of synchronisation.


Screenshots

WinAPE allows you to save screen shots of the current running emulator screen. There is an option in General Settings to force the screen to be saved when the monitor is performing a frame-flyback to prevent tearing of the image.

Screenshots can be saved in many graphics formats including BMP, PCX, PNG, JPEG and TIFF, and can be saved as either full size of Half Size, and either full height or Half Height. Since Amstrad pixels are two pixels high and may be more than a single pixel wide depending on the current screen MODE, this can make the image files smaller.


Pokes - Game Editor
Game Editor

The Pokes system Edit Game screen allows you to enter a name for a game, then select an area of RAM memory which should uniquely identify that the game is currently running. Click the Indentify button to provide a hex memory viewer with a Search and Goto facility, allowing you to highlight the identifier.

You could, for example use the text search to find the name of the game, or find a unique graphic object using the Graphic Finder first and select that area of memory. As a general rule the areas should only be a small size (6 - 20 bytes) so you don't accidentally select an area containing variables which may be modified while the game is running.


Edit Pokes

Every Poke must have a Description, which is shown in the main Pokes screen, and may have an optional Comment which will be shown if the user has to enter a value. If required the value will be entered below in the Data section using ? characters instead of the normal hexadecimal values.

The Value Type can be one of the following:

Decimal	A decimal number occupying either a single byte or a word
Hex	A hexadecimal number occupying either a single byte or a word
BCD	A binary coded decimal number with two digits for each byte
Numeric (Zero based)	A decimal number occupying a single byte for each digit, where the digit entered is poked as the value 0..9
Decimal (ASCII)	A decimal number occupying a single byte for each digit, where the digit entered is poked as the ASCII value '0'..'9'
Long	A decimal number occupying up to 4 bytes
String	Each value is poked with the ASCII byte character value entered

All long or word data is little-endian, and the numeric and BCD types pad the left-most digits with zeroes.

The actual data to be poked into memory when the Poke is activated is entered using a number of Address and Data values (in Hex) which may be in an extended memory RAM Bank address space.

The example above is the poke for entering the Time in Burnin' Rubber, and has a single byte entered by the user in BCD, but the one below is for infinite everything in Dark Side:


ASIC Registers

The ASIC Register section of the Register window displays the current values of Amstrad Plus registers on the ASIC.

The registers are:

Palette	The palette registers. These are the colours used for inks 0 to 15 (0 to #F) and the border (#10). Move the mouse cursor over the colour square to see the RGB (Red, Green and Blue) values for the colour.
Sprite Palette	The sprite palette registers. These are the colours used for inks 1 to 15 (1 to #F) in sprites.
ASIC Unlocked	Displays a tick mark if the ASIC has been unlocked.
ASIC RAM Enabled	Displays a tick mark if the ASIC RAM is enabled.
LRB	Lower ROM Base Address. Shows the mapped base address for the lower ROM.
Cart Bank	Shows the cartridge bank used for the lower ROM.
DCSR	DMA Control/Status Register.
Sprite	Shows an image of the selected Sprite. Use the scroll bar to select a sprite (0 to 15)
X	The X position of the selected sprite.
Y	The Y position of the selected sprite.
Mag X	The magnification factor for the width of the selected sprite.
Mag Y	The magnification factor for the height of the selected sprite.
PRI	Programmable raster interrupt scan line. If this is non zero an interrupt will occur when the value VCC * 8 + VLC equals this value.
SSS	Split Screen Scan. If this is non zero, a split screen will occur after VCC * 8 + VLC equals this value.
SSSA	Split Screen Start Address. The base address for the second screen in a split-screen.
SSC	Soft Scroll Control.
IVR	Interrupt Vector. Controls the vector supplied to mode 2 (IM 2) Z80 interrupts.
DMA Chan n	Shows information for each DMA Channel.
The DMA Channel information is as follows:
Enabled	Displays a tick mark if the DMA channel is enabled.
Addr	The address from which to get the next DMA instruction.
Pause	The pause value for the DMA channel.

The purple value at the bottom is the next instruction to be executed. Moving the mouse cursor anywhere over the DMA Channel box will display the current pause counter, loop start address and loop count.