Golden Gate

an Apple IIgs Compatibility Layer

Copyright 2011-2018, Kelvin W Sherlock. All Rights Reserved.

ORCA/C, ORCA/M, ORCA/Pascal, ORCA/Integer Basic, ORCA/Modula-2, and The Byte Works are trademarks of the Byte Works, Inc. GNO and GNO/ME are trademarks of Procyon Enterprises Incorporated. Apple IIgs, ProDOS, Macintosh, HFS, and GS/OS are registered trademarks of Apple, Inc.

Contents

Introduction

Golden Gate is not a traditional emulator. It is a compatibility layer that enables IIgs shell applications to run on your computer as if they were native command line utilities. Shell applications have neither Graphics nor Sound and are strictly text-based; yet there are many useful and unique shell applications – such as the ORCA compilers – which cannot be found elsewhere. Golden Gate is their bridge to the future.

Conventions

Golden Gate is the name of the compatibility layer. iix is the name of the command-line utility to invoke the Golden Gate compatibility layer.

In command examples, [bracketed text] is optional. Italic text is a user supplied file or parameter.

Installation

Golden Gate consists of a command line utility (iix, installed as /usr/local/bin/iix) plus additional support files stored in the $GOLDEN_GATE directory. The actual location of the $GOLDEN_GATE directory depends on your operating system:

iix -V will display your $GOLDEN_GATE directory. If Golden Gate is unable to find a suitable $GOLDEN_GATE directory, it will list the locations where it looked.

Contents of the $GOLDEN_GATE directory may include:

Utilities

ORCA utilities

Shell

ORCA support files

Languages

ORCA compilers and linkers

Libraries

ORCA Libraries and headers

Home

Home folder

System

ROM and other support files

bin

GNO binaries

etc

GNO support files

lib

GNO libraries

usr

GNO support files

var

GNO support files

This layout is based on ORCA and GNO installations and should be familiar to users of those systems. The actual contents will depend on which ORCA or GNO utilities and languages you have installed.

Windows

By default, the Windows installer will install the iix executable into %ProgramFiles(x86)%\GoldenGate\ and $GOLDEN_GATE files into %ProgramData%\GoldenGate\ (Usually C:\ProgramData\GoldenGate.) The %PATH% environment variable is also updated with the iix executable path.

You can override the iix binary location by using the command-line installer, msiexec:

msiexec /i GoldenGate.msi INSTALLDIR=c:\msys2\usr\local\bin\

OS X

The OS X installer will install the iix executable into /usr/local/bin/ and the $GOLDEN_GATE files into /Library/GoldenGate/.

Linux and Solaris

Due to the wide variety of package managers and architectures, compiled binaries are not currently provided. You will need to manually compile Golden Gate. gcc (4.8 or newer), cmake (3.1 or newer), git, and ragel are required. See the GitLab source repository for more information.

Care should also be taken when setting up your $GOLDEN_GATE directory as not all file systems provide adequate support. See the section on File Systems for more information.

Installing ORCA Components

ORCA components need to be manually installed in your $GOLDEN_GATE folder.

For OS X users, the easiest way install is via the HFS-formatted OPUS ][ CD. Open the ByteWorks/ORCA/ directory and copy the Languages, Libraries, Shell, and Utilities folders to your $GOLDEN_GATE directory (/Library/GoldenGate/).

opus-extractor

The opus-extractor utility can extract and install the ORCA components from OPUS ][ (or any other disk image where they may be installed). On the OPUS ][ CD and USB Drive, a ProDOS order Disk Image containing a full ORCA install is located in For Emulators/ByteWorks. opus-extractor will copy the contents of the Language, Libraries, Shell, and Utilities directories.

opus-extractor [options] disk-image [destination]

--help, -h

Display help information

--verbose, -v

Be verbose

--no-clobber, -n

Don’t overwrite existing files

--source, -s path

Specify alternate source directory

By default, files are copied from the ORCA: directory (on the disk image) to the $GOLDEN_GATE directory. You may also provide an alternate source directory on the disk image with the --source= flag, for use with other disk images.

opus-extractor --source=lang:orca gno.2mg orca

Extracts files from lang:orca: to orca/

You may need to run with elevated permissions via sudo or runas:

sudo opus-extractor ByteWorks
Password:

Source     : ORCA:
Destination: /Library/GoldenGate

Scanning ORCA:Languages...
Scanning ORCA:Libraries...
Scanning ORCA:Libraries:AInclude...
Scanning ORCA:Libraries:AppleUtil...
Scanning ORCA:Libraries:APWCInclude...
Scanning ORCA:Libraries:ORCACDefs...
Scanning ORCA:Libraries:ORCAInclude...
Scanning ORCA:Libraries:ORCAPascalDefs...
Scanning ORCA:Libraries:RInclude...
Scanning ORCA:Libraries:Tool.Interface...
Scanning ORCA:Libraries:GSoftDefs...
Scanning ORCA:Libraries:m2defs...
Scanning ORCA:Shell...
Scanning ORCA:Utilities...
Scanning ORCA:Utilities:Help...

Usage

Golden Gate is a command-line utility that runs from a terminal shell (Terminal.app, cmd.exe, PowerShell, et cetera). The utility is invoked as:

iix [iix-flags] command [command arguments...]

where iix-flags may include:

--help, -h

Display help information

--version, -V

Display version information

-D name=value

Define an environment variable

--gno

Enable GNO libraries and headers

command may be a built-in command or external command.

External Commands

External commands can be specified by full path, partial path, or by name. If specified by name, Golden Gate will look for the command in the following locations:

Examples:

iix ./hello

Runs the hello program in the current directory

iix ls

Runs the ls program from $GOLDEN_GATE:bin:

The following external commands are provided with Golden Gate. See the manual pages (iix man name) for more information.

blist

iix blist file

Detokenize an Applesoft BASIC file.

chtyp

iix chtyp -t type [-a auxtype] file [, ...]
iix chtyp -l language file [, ...]

Sets the file type and aux type on a file. chtyp was included with GNO.

Examples:

iix chtyp -l cc *.c
iix chtyp -t s16 -a 0xdb03

getfileinfo

iix getfileinfo file  [, ...]

Display extended GS/OS information on a file.

gothic

iix gothic arbitrary text

Prints text in a Gothic font. gothic was ported to the IIgs by Tim Meekins.

ls

iix ls [flags] [file, ...]

Lists files and directories. Your operating system undoubtedly has a native ls or dir utility. iix ls displays IIgs-specific file information and will do GS/OS path expansion. ls was included with GNO.

Examples:

iix ls -l 13:

lseg

iix lseg [-d] file [, ...]

Development utility to list segments in an OMF file. lseg was included with GNO.

Examples:

iix lseg myfile.root

mkobj

iix mkobj segname infile outfile [loadname]

Development utility to convert arbitrary binary files into OMF format. mkobj was written by Tim Meekins.

nroff

iix nroff [flags] [file]

Manual page typesetter, used internally by iix man. nroff was included with GNO.

Examples:

iix nroff -man manualpage.1

prefix

iix prefix

Display GS/OS prefixes.

printenv

iix printenv [variable, ...]

Display ORCA/GNO environment variables.

rlist

iix rlist file

List resources in a file.

zip

iix zip file

Play Infocom Z-machine games. zip was written by Mark Howell and ported to the IIgs by Evan Day.

zip depends on Unix terminal control facilities which are not available under Windows.

Built-in Commands

Help / Man

iix help command
iix man [-S sections] command

Displays help information (if available) for command. ORCA Help files are stored in $GOLDEN_GATE:Utilities:Help:. GNO Manual pages are stored in $GOLDEN_GATE:usr:man: and $GOLDEN_GATE:usr:local:man:.

Examples:

iix help MDBASIC

Displays help on MDBASIC

iix man -S 1 chtyp

Displays the chtyp manual page from section 1

Compile

iix compile [flags] sourcefile [keep=objfile]

iix assemble [flags] sourcefile [keep=objfile]

Invokes the compiler (or assembler – the verbs can be used interchangeably) to compile sourcefile. The flags are compiler-specific and take the form +X or -X. iix compile --help will list the available flags.

The generated object files are generally named infile.root and infile.a.

You may specify an alternate filename using the keep=objfile parameter. Note that the extensions (.root, .a) will be appended and should not be included.

Golden Gate chooses which compiler to use based on the file type. If no file type has been explicitly set, it will guess based on the file extension. For non-standard file extensions, you will need to explicitly set the file type. Refer to the section on file types for more information.

You must have the appropriate language installed in $GOLDEN_GATE:Languages:.

Assembler Flags:

+E

abort to editor (unsupported)

+L

generate source listing

+M

write to memory

-P

suppress progress

+S

generate symbol listing

+T

treat all errors as terminal

+W

wait for keypress after error (unsupported)

CC Flags:

+D

generate debug code

+E

abort to editor (unsupported)

-I

ignore/do not generate .sym file

+L

generate source listing

+M

write to memory

+O

turn on optimizations

-P

suppress progress

-R

rebuild .sym file

+T

treat all errors as terminal

+W

wait for keypress after error (unsupported)

Pascal Flags:

+D

generate debug code

+E

abort to editor (unsupported)

+L

generate source listing

+M

write to memory

+O

turn on optimizations

-P

suppress progress

+T

treat all errors as terminal

+W

wait for keypress after error (unsupported)

Integer Basic Flags:

+D

generate debug code

+E

abort to editor (unsupported)

+L

generate source listing

+M

write to memory

+S

generate symbol listing

+W

wait for keypress after error (unsupported)

Modula-2 Flags:

+D

generate debug code

+E

abort to editor (unsupported)

+L

generate source listing

+M

write to memory

-P

suppress progress

+T

treat all errors as terminal

+W

wait for keypress after error (unsupported)

Please consult your ORCA manual for further information on compiler usage.

Examples:

iix compile hello.cc

Creates hello.root, hello.a

iix compile -P +D goodbye.pas keep=o/goodbye

Creates o/goodbye.root, o/goodbye.a

GNO support

GNO/ME (GNO’s Not ORCA/Multitasking Environment) is a Unix-like environment for the IIgs. It is upwardly compatible with ORCA; ORCA programs run under GNO but GNO programs do not necessarily run under ORCA. Golden Gate provides some support for GNO applications by implementing kernel toolcalls and namespacing.

Compiling and Linking

GNO uses the ORCA compilers and linkers. However, it uses modified headers and libraries. The --gno flag will enable GNO libraries and headers.

This is accomplished by changing prefix 13: from $GOLDEN_GATE:Libraries to $GOLDEN_GATE:lib. A Default.h file in $GOLDEN_GATE:lib:ORCACDefs: adjusts the header include path to use $GOLDEN_GATE:usr:include:.

The Golden Gate utility may also be invoked as gno which is equivalent to running iix --gno.

Examples:

iix compile hello.c; iix link hello keep=hello

Compiles and links hello.c using the ORCA headers and libraries.

iix --gno compile hello.c; iix --gno link hello keep=hello

Compiles and links hello.c using the GNO headers and libraries.

Namespacing

Many GNO utilities have hard-coded path dependencies. For example, zip depends on the /etc/termcap file and nroff depends on macro files in /usr/lib/tmac. For compatibility, the following directories are jailed within $GOLDEN_GATE:

  • /bin/

  • /etc/

  • /lib/

  • /usr/

  • /var/

Implementation Details

Golden Gate is powered by a 65816 emulator with a native implementation of the Toolbox and GS/OS.

In a traditional emulator, when you make a GS/OS call (_ReadGS, for example), it goes through the GS/OS dispatcher (emulated) which calls the FST (emulated) which calls a device driver (emulated) to read and write blocks on a disk – at which point native code is finally used to read or write a disk image. Similarly, if you make a Toolbox call (like _WriteLine), it calls the Toolbox dispatcher (emulated) which calls the Text Tool (emulated) which writes into I/O memory, at which point native code draws that text into a window.

Golden Gate is different. When you make a GS/OS call, native code immediately takes over and reads or writes the files directly. When you call _WriteLine, native code write the text to your terminal window. When you call _LongMul, native code does the multiplication for you (and much faster than emulated code ever will). By changing the boundary between emulated and native code, IIgs shell applications can run as if they were native.

The core 65816 emulator has 16 megabytes of RAM. Banks $E1 and $FF are used for ROM and parts parts of bank $01 ($c000$ffff) are reserved. All remaining memory is available for program use (allocating special memory with NewHandle requires the attrSpecial flag).

Toolbox and GS/OS calls are implemented via the COP instruction. There are no soft switches, video ram, mapped memory, Mega II, fast/slow memory, et cetera. While this makes it unsuitable for a general-purpose IIgs emulator, well behaved shell programs use the Toolbox and GS/OS for all input and output.

File Types

Apple IIgs software makes heavy use of file types and aux types. Golden Gate stores this information in a Finder info extended attribute / alternate data stream. (Refer to the section on file systems for more details.) If a file type has not been explicitly set, Golden Gate will guess the file type based on the name.

The ORCA compilers are very strict about file types so you may find it advantageous to use consistent file type extensions.

The chtyp utility can be used to explicitly set the file type and aux type of a file.

iix chtyp [-t ftype] [-a atype] [-l lang]  file [, ...]

Example:

iix chtyp -l cc *.cc

Sets the file type to $B0, aux type to $0008, an ORCA/C source file

iix chtyp -t 0xb0 -a 0x08 cc *.cc

Another way to do the same

iix chtyp -t txt myfile

Sets the filetype to $04, ASCII text

The getfileinfo utility will display GS/OS file information, including file type, aux type, and Finder info.

iix getfileinfo 13:ORCALib

   pathname: 13:ORCALib
     access: c3 (dr----wr)
   fileType: b2 (Apple IIgs Library file)
    auxType: 0000
storageType: 01 (seedling)
    created: 2014-01-09 01:38:47
   modified: 1996-03-15 00:00:00
        eof: 0000ee83 (61059)
     blocks: 00000078 (120)
    res eof: 00000000 (0)
 res blocks: 00000000 (0)
        fst: 06 (HFS)
 optionList:
  70 b2 00 00 70 64 6f 73 00 00 00 00 00 00 00 00   p...pdos........
  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................

File Type Extensions

The following file type extensions are recognized. Note that these are only used when the the filetype has not been explicitly set. Extensions are case-insensitive.

Extension

Type

m16.*

Text

e16.*

Text

*.asm

ORCA/M Source

*.aii

ORCA/M Source

*.b

Text (MD-Basic Source)

*.bas

ORCA/Integer Basic Source

*.c

ORCA/C Source

*.cc

ORCA/C Source

*.cpp

ORCA/C Source

*.equates

ORCA/M Source

*.gsoft

GSoft Source

*.h

ORCA/C Source

*.int

ORCA/Pascal Unit File

*.mac

ORCA/M Source

*.macro

ORCA/M Source

*.macros

ORCA/M Source

*.mod

ORCA/Modula2 Source

*.p

ORCA/Pascal Source

*.pas

ORCA/Pascal Source

*.pascal

ORCA/Pascal Source

*.r

Rez Source

*.rez

Rez Source

*.s

ORCA/M Source

*.txt

Text

*.text

Text

Text Files

The Apple IIgs used carriage return (\r) as an end of line character. Unix systems, including OS X, use a newline (\n) as an end of line character. Golden Gate will silently and automatically convert the end of line character when reading and writing. Conversion is based on the file type (either explicitly set or based on the file name). Windows uses both the carriage return and line feed (\r\n) as the end of line character. We recommend using a modern text editor that supports a single carriage return or line feed as the EOL character.

Pathname separators

GS/OS used : and / as directory separators. Most operating systems use / as a separator (the main exception, of course, is Windows which does everything backwards). Golden Gate automatically converts between : and /. Please avoid using : or / as character in your file names.

File Systems

Although GS/OS supported case-sensitive file systems, ProDOS and HFS were case insensitive. Many shell utilities assume they’re running on a case-insensitive file system. Source code often has case-sensitive problems as well (particularly C header files or assembly macro files). For this reason, it is best to keep your $GOLDEN_GATE directory on a case-insensitive file system. It’s also wise to keep any IIgs source code files on a case-insensitive file system as well since ORCA linker and ORCA assembler have a penchant for upper case file names.

GS/OS also supported Resource forks and advanced meta data (file type, aux type, and Finder info). Golden Gate uses extended attributes and alternate data streams for resource forks and Finder info. File types and aux types are stored in the Finder info, consistent with the HFS and AppleShare FSTs (in fact Golden Gate reports itself as HFS in the GetFileInfo option list).

Finder information and Resource forks are stored as extended attributes or alternate data streams. Not all operating systems and file systems have full support for extended attributes.

Macintosh

By default, HFS+ is case insensitive. HFS also provides first class support for Resource forks and Finder info. APFS, Apple’s next generation file system is expected to be the default file system for OS X 10.13. APFS provides first-class support for Resource forks and Finder info and supports case-insensitive volumes.

Windows

By Default, NTFS is case insensitive. NTFS also provides first class support for extended attributes. FAT filesystems are untested and not recommended.

Solaris

ZFS is, unless told otherwise, case sensitive. We recommend creating a case insensitive pool for use with Golden Gate (zpool create -o casesensitivity=insensitive ...). ZFS has first class support for extended attributes.

Linux

We recommend using the JFS filesystem as it has good support for extended attributes and can be created as case insensitive (jfs-mkfs -O ...). Other file systems are untested and unsupported. Resource forks are not fully supported in Linux at this time.

Prefixes

The following prefixes are pre-defined. When used at the start of a pathname, they will be expanded. Note that prefixes 1-7 are only populated if less than 64 characters long for compatibility with ProDOS 16.

*

$GOLDEN_GATE

@

$GOLDEN_GATE:Home

1

(Directory of current program)

3

(Native temporary directory)

9

(Directory of current program)

13

$GOLDEN_GATE:Libraries

14

(Native temporary directory)

15

$GOLDEN_GATE:Shell

16

$GOLDEN_GATE:Languages

17

$GOLDEN_GATE:Utilities

31

$GOLDEN_GATE

You can use the prefix utility to list prefixes:

iix prefix

Prefix Path
------ ----
    *: :Library:GoldenGate
    @: :Library:GoldenGate:Home
    1: :Library:GoldenGate:usr:local:bin
    2: :Library:GoldenGate:Libraries
    3: :tmp
    4: :Library:GoldenGate:Shell
    5: :Library:GoldenGate:Languages
    6: :Library:GoldenGate:Utilities
    9: :Library:GoldenGate:usr:local:bin
   13: :Library:GoldenGate:Libraries
   14: :tmp
   15: :Library:GoldenGate:Shell
   16: :Library:GoldenGate:Languages
   17: :Library:GoldenGate:Utilities
   31: :Library:GoldenGate

Environment Variables

The following environment variables are automatically defined. Additional variables may be defined using the iix -D key=value flag.

TERM

(Native $TERM)

HOME

$GOLDEN_GATE/Home

TMPDIR

(Native temporary directory)

LINES

(Native $LINES)

COLUMNS

(Native $COLUMNS)

You can use the printenv utility to list environment variables:

iix -Dabc=def printenv

TERM=xterm
HOME=/Library/GoldenGate/Home
TMPDIR=/tmp/
abc=def

Debugging

Golden Gate is not only useful for developing new programs; it can also be used to test programs and algorithms. In fact, Golden Gate’s original purpose was for testing small bits of code.

The following Golden Gate flags are available to assist with debugging:

--trace-gsos

Log GS/OS and ORCA system calls.

--trace-cpu

Log the CPU state before each instruction. For large (or long-running) utilities, the output is overwhelming and will adversely affect performance.

--trace-tools

Log Toolbox calls.

--trace-tool number

Log a specific Tool Set.

--trace-gno

Log GNO kernel calls

--trace-debug-names

Log inline debug names (see Apple IIgs Technical Note #103: Inline Procedure Name Format for more details).

--cycles

Prints a count of emulated CPU cycles. Note that is not accurate when Toolbox or GS/OS calls are involved. Nonetheless, it may be useful in checking for algorithm improvements.

--profile

Print profiling information. This requires you compile your code with profiling enabled (#pragma debug 4).

-g

Enable the interactive debugger. This requires you compile your code with source level debugging enabled (#pragma debug 2). See the debugger guide for more information.

--memcheck

Enable memory checking.

Note: some GS/OS and Toolbox calls are not logged because they are too noisy.

Memory Checking

The --memcheck flag enables some memory checking. Currently, this entails:

  • Unallocated memory is initialized to 0xaa (instead of 0x00).

  • Memory is wiped (with 0xaa) when a handle is disposed.

  • When the program finishes, all unallocated memory is checked for non-0xaa bytes.

  • When the program finishes, the amount of stack/direct page used is reported. This is only meaningful for “stack-frame” languages like ORCA/C and ORCA/Pascal. Assembly code that uses the direct page as-is won’t be accurate. Additionally, the IIgs toolbox may use more stack space than the Golden Gate toolbox.

GSBug Compatibility

The GSBug tool is supported and has been extended with new toolcalls to make testing and debugging software easier. The following toolcalls are supported:

DebugStatus

C:

extern pascal Word DebugStatus(void)
inline(0x06ff,dispatcher);

Assembly:

ldx #$06ff
jsl $e10000

Returns -1 (active).

DebugVersion

C:

extern pascal Word DebugVersion(void)
inline(0x04ff,dispatcher);

Assembly:

ldx #$04ff
jsl $e10000

Returns 1.

DebugStr

C:

extern pascal void DebugStr(const Byte *string)
inline(0x09ff,dispatcher);

Assembly:

ldx #$09ff
jsl $e10000

Prints a pascal string.

DebugSetMileStone

C:

extern pascal void DebugSetMileStone(const Byte *string)
inline(0x0aff,dispatcher);

Assembly:

ldx #$0aff
jsl $e10000

This call is has no effect.

DebugHexDump

C:

extern pascal void DebugHexDump(const Byte *address, Word count)
inline(0x0fff,dispatcher);

Assembly:

ldx #$0fff
jsl $e10000

Prints a hexdump of count bytes of memory at address.

DebugGetTrace

C:

extern pascal Word DebugGetTrace(void)
inline(0x10ff,dispatcher);

Assembly:

ldx #$10ff
jsl $e10000

Returns the current value of the CPU trace flag.

DebugSetTrace

C:

extern pascal Word DebugSetTrace(Word value)
inline(0x11ff,dispatcher);

Assembly:

ldx #$11ff
jsl $e10000

Set The CPU trace flag and returns the previous value of the trace flag. When active, CPU information will be displayed before each instruction executes.