## trs80gp - A TRS-80 Model 1,2,3,4,12,16,6000,Tandy 10,MC-10,Color Computer,DT-1,Videotex Emulator

trs80gp primarily emulates the "gray" line of TRS-80 computers made by Tandy in the late 1970s and early 1980s. They are known as the Model I, Model II, Model III, Model 4, Model 4P, Model 4D, Model 12, Model 16 and Model 6000. It is generally easier to use ordinary digits for the Model 1, Model 2 and Model 3. The Model 1, 3 and 4 are a line of compatible computers as is the Model 2, 12, 16 and 6000.

Also emulated are the Tandy 10, TRS-80 Micro Color Computer Model MC-10, TRS-80 Color Computer, TRS-80 DT-1 Data Terminal, TRS-80 Videotex and Electric Crayon external colour display.

The emulator runs on Windows from XP all the way up to Windows 11. Included in the download are versions for MacOS, Linux and Raspberry Pi. They may not be at full feature parity with the Windows version but the emulator runs just fine under Wine. It should run well on any machine produced in the past decade.

trs80gp provides accurate and near complete emulation with excellent programmer support. The source code is fully organic and hand-crafted by myself and my brother Peter.

For older versions and checksums, please consult the release notes.

### Community

Bug reports, feature requests or other inquiries about the trs80gp emulator are best e-mailed to me (see bottom of this page for the address). There is a community of TRS-80 users still out there who can help with questions operating the machines (in both emulated or physical form) and even some amount of expertise on trs80gp itself.

I've created a trs80gp Facebook group and a trs80gp Discord server as venues for more interactive discussion. You may not find many people there but I will keep an eye on them myself.

The most active TRS-80 forum is the Tandy Radio Shack section of the Vintage Computing Federation forums. There is also a somewhat less busy Tandy Computers forum on AtariAge and a very lightly used TRS-80 subreddit. There are also a handful of facebook groups dedicated to the TRS-80 models that trs80gp emulates.

### Features

- Emulates floppy disk, hard drive, cassette, hires graphics, Orchestra 80/85/90 and printer.
- Window scalable to any size with realistic phosphor-dot rendering.
- Near perfect video emulation including beam drop-outs, wait states and various other subtle effects.
- Can visually indicate Z-80 video memory conflicts.
- Cycle perfect sub-instruction Z-80 and video timing.
- Built-in Z-80 debugger with source level debugging using zmac `.bds` output.
- 6809 debugger for Videotex and Color Computer
- 6800 debugger for Electric Crayon
- 6803 debugger for MC-10
- 68000 debugger for Model 16 and 6000
- Switchable turbo mode for high speed yet still accurate operation.
- Auto-turbo modes to go fast during slow operations (e.g., disk, cassette) and back to normal when typing.
- AVI and FLV (Flash) video capture.
- GIF and animated GIF screenshot capture.
- Audio capture to WAV file.
- Load programs directly from command line for fast development and testing.
- Can both "paste" and send files as input to keyboard (aka "fast type").
- "Copy" to copy the screen in ASCII, Unicode or graphics format.
- Keyboard selectable between normal and game mode.
- Software keyboard to get around limits of PC keyboards.
- Brightness, contrast and display colour controls.
- Batch mode and command line input to automate tasks.
- Can open files and disk images within .zip archives.
- Optional emulator extensions provide memory protection and timing to the Z-80. And emulator exit.
- Bus tracing, disassembling, profiling, memory dumping and other features for reverse engineering and debugging.

The emulator is still a work in progress. Much needs to be done to perfect the Model 2 timing and screen effects. Some obscure Model 3 and 4 video effects are not accurate. Videotex, Electric Crayon, MC-10 and Color Computer don't have authentic rendering modes.

### Overview

By default trs80gp comes up in Model 3 mode with a full 48K of memory and all supported hardware attached. Command line arguments are used to select different models, hardware configurations and startup options. Run "trs80gp -?" or use the "Help → Command Line Options..." menu to get the latest information on them.

Programs can be run directly on the command line. Doing so loads them much faster than reading from virtual cassette files and without the hassle of writing them to a virtual disk image. Files in "DOS" format (.cmd) are run at the TRS-DOS prompt. Other machine language files and BASIC programs are run at the ROM BASIC `READY` prompt or at machine boot for Model 2 and 4P which don't have a ROM BASIC.

It may not be obvious that this direct running of programs is not the way the TRS-80 normally loads and executes programs. Some programs may not work especially disk BASIC programs. However it is very useful for program development and is otherwise extremely handy when it does work.

To give it a try, download the emulator and also my bouncing ball demo program. You can run it directly from the .zip archive:

          trs80gp ball.zip

Which will prompt for which file to use. Or specify the file inside the .zip archive directly like so:

          trs80gp ball.zip?ball.cas

Or you can extract the virtual cassette file yourself and run it:

          trs80gp ball.cas

You can load machine language programs in `.cmd`, `.hex` and `.bds` formats. My Z-80 cross assembler zmac produces all three formats and with `.bds` you get full source-level debugging and memory fault detection (see Debug → Z-80 Debugger... and Debug → Source Code...).

It also can load BASIC programs in tokenized form or plain ASCII.

There's so much more! But I'll leave it at that and spend the rest of this page more in "reference manual" mode.

- Command Line Options
- Model Selection
- The Keyboard
- Light Pen and Joystick
- Floppy Disks
- Hard Drives
- Cassette Tapes
- Aculab Floppy Tapes
- Sound
- Memory
- Endpoints
- Printer
- Serial (RS-232) Ports
- Recording movies, pictures and audio.
- Turbo Mode
- Display
- File Import and Export
- Scripting
- Events
- Programming
- FreHD Emulation
- DT-1 Terminal
- TRS-80 Videotex
- Electric Crayon
- Color Computer
- Tandy 10
- Linux Notes
- MacOS Notes

### Command Line Option Summary

Option | Effect
--- | ---
Hardware Selection
-m1 | Emulate Model I
-mj | Emulate Japanese Model I
-m2 | Emulate Model II
-m3 | Emulate Model III (default)
-m3n | Emulate Norcom Model III clone that fit in a Model I case
-m4 | Emulate Model 4 (same as -m4a)
-m4a | Emulate Model 4 with 2 wait states per instruction
-m4b | Emulate Model 4 with 1 wait state per instruction
-m4c | Emulate Model 4 with no wait states per instruction
-m4ga | Emulate Model 4 Gate Array
-m4p | Emulate Model 4P
-m4d | Emulate Model 4D
-m4ss | Emulate Model 4 Student Station
-m12 | Emulate Model 12
-m16 | Emulate Model 16
-m6000 | Emulate Model 6000
-m10 | Emulate Tandy 10
-mc10 | Emulate Micro Color Computer Model MC-10
-mc | Emulate Color Computer
-mdt1 | Emulate DT-1 Terminal
-mv | Emulate Videotex Terminal
-mec | Emulate Electric Crayon
-mx70 | Act like MX-70 Printer
-l1 | Run Level I BASIC ROM (Model I or III)
-l2 | Run Level II BASIC ROM (default) (Model I or III)
-rN | Use ROM revision N (-r0, -r1, -r2, ...)
-nlc | No lowercase for Model I
-lld | Load Model I lowercase driver from cassette on startup
-nld | Do not load Model I lowercase driver from cassette
-nsc | Do not try to set the clock for the boot OS
-alt | Use alternate character set
-charrom file | Use character generator ROM from file
-50 | Set frame rate to 50 Hz
-gX | Hires graphics: -g0 none, -gt Tandy (default), -gg Grafyx, -gc Grafyx clone
| -gtp for Tandy with fixed PROMs for Model 2,3,12,16,6000.
| -gl for Model 1 Lowe Electronics 18
-ddTYPE | Select Model I floppy doubler: -ddx none, -ddp Percom,
| -ddr Radio Shack, -ddrp RS+Percom, -ddd detect at boot)
-dx | Disable floppy disk controller (boot into ROM BASIC).
-dNss | Set drive N (0,1,2,3) single-sided only.
-dNds | Set drive N (0,1,2,3) double-sided only.
-dNas | Set drive N (0,1,2,3) to automatically act as single or double-sided.
-hx | Disable hard drive controller
-mem n | Emulate n KB of RAM
-mem type:n | Emulate n KB of hyper/super/mega expansion RAM.
-mem16 n | Emulate n KB of 68000 RAM
-memgap16 b n | Unmap an n KB gap in 68000 RAM starting at KB b
-mmu16 bits | Set number of extension bits in 68000 MMU (default 3)
-z180 | Use Z-180 as main CPU (Model 2) with XLR8er support (Model 4)
-mhz16 n | Run 68000 at n MHz (default 8)
-rom file | Use ROM image from file
-rom1 file | Map ROM image from file to $3000 (Model 1 only)
-aft | Aculab floppy tape (Model I only)
-80-grafix | 80-Grafix hires character generator (Model I only)
-80-grafix+ | 80-Grafix+ hires character generator (Model I only)
-pcg-80 | PCG-80 hires character generator (Model I only)
-80-grafix3 | 80-Grafix3 hires character generator (Model III only)
-omikron | Omikron Mapper for Model I (for Omikron CP/M)
-omikron-a | Omikron Mapper using version A ROM
-pak file | Use Colour Computer Program Pak (cartridge) ROM from file.
-pakq file | As -pak but Program Pak won't auto start
Program/Media Selection
-c file.cas | Insert cassette file.cas
-w file.tape | Insert floppy tape wafer file.tape into next free drive
-dN file.dsk | Insert disk into drive N (0,1,2,3 or A,B)
-d file.dsk | Insert disk into next free drive
-d dmk | Insert unformatted disk into next free drive (.dmk format)
| (add -ds for double-sided and #N for tracks)
-d imd | Insert unformatted disk into next free drive (.imd format)
-d :name | Insert internal diskette ":name" into next free drive
-td | Boot TRS-DOS (default)
-ld | Boot LDOS or LS-DOS
-ad | Boot ADOS (Tandy 10 only)
-d0 - | Don't insert TRS-DOS or other boot disk (or -dA -)
-h file.hdv | Attach hard drive to next free slot
-hN file.hdv | Attach hard drive to slot N
-cs -csx | Enable/disable cassette auto save
-csd N | Set cassette auto-save delay in 1/10ths of a second.
-cix | Disable cassette I/O is happening/CMD"T" warning.
file.dsk | Insert disk into next free drive (also .dmk, .imd)
file.tape | Insert floppy tape wafer into next free drive
file.ccc | Insert Colour Computer Program Pak ROM (CoCo only)
:name | Insert internal diskette or wafer into next free drive
file | One or more files to load and execute after auto-boot
| .cmd files are run from dos prompt
| .cas, .bas and .bds files are loaded into ROM BASIC
| Files starting with #! are command scripts
Serial Port (RS-232) Options
-rx | Disable RS-232
-r host:port | Connect serial port to TCP/IP host, port endpoint.
-r @port | Listen for TCP/IP connections on port for serial line.
| (also -rB for second and -rA for first serial port)
-r :mouse | Emulate 2 button mouse on serial port
-r :mouse3 | Emulate 3 button mouse on serial port
-r :dt1 | Run DT-1 emulator attached to serial port.
-r :v | Run Videotex emulator attached to serial port.
-r :loop | Loopback device on serial port.
-r endpoint | Hook serial port an endpoint (see Endpoint section).
Printer Port Options
-p host:port | Connect printer port to TCP/IP host, port endpoint.
-p @port | Listen for TCP/IP connections on port for printer.
-p :mx70 | Run MX-70 emulator attached to printer port.
-p :ec | Run Electric Crayon emulator attached to printer port.
-p endpoint | Hook printer port an endpoint (see Endpoint section).
-poff | Printer appears powered off
-pp -ppx | Enable/Disable printer window pop-up on print.
View Options
-va | Authentic display (default)
-vs | Sharp display
-vi | Sharp display but only allows integer scaling
-vh | Cheap display
-vN | Scale cheap or sharp display up by N times
-vf | Start in full-screen mode (use Alt+Enter to go windowed)
-vc #RRGGBB | Set display colour to 24 bit colour value ("-vc - " for default)
-vd #RRGGBB | Set beam conflict colour ("-vd -" for default)
-vb #RRGGBB | Set border colour ("-vb -" for default)
-vr type | Set 256 x 192 artifact colours, x off, s swapped, - default
-win WxH | Set window width and height
-win full | Start in full-screen mode (use Alt+Enter to go windowed)
-bd | Turn beam debugging on
-na | Turn off authentic display
-vpfon | Turn Tandy 10 PRINT FORM switch on
-vpfoff | Turn Tandy 10 PRINT FORM switch off
-vrev | Tandy 10 reverse video
-vnorm | Tandy 10 normal video (white background)
-wtfs N | Update window title only every Nth frame.
Sound Options
-s hardware | Enable third party audio for model 1,3 or 4.
| orch80 Orchestra 80
| orch85 Orchestra 85
| orch90 Orchestra 90
| - Disable third party audio
-mute | Start with audio muted.
-vol N | Set audio volume percentage (0 to 100; -sv is synonymous)
-su | Turn off audio filtering (faster; slightly less accurate)
-sx | Disable all audio output
-s1 | Force mono sound
-s2 | Force stereo sound
-sbg | Mute audio if trs80gp does not have the focus
-sfg | Audio and sound effects always play (unlike -sbg)
-sfmute | Mute sound effects
-sfv N | Set sound effect volume percentage
-sf fx file.wav | Use file.wav for named sound effect fx:
| spin-empty empty floppy drive motor on
| spin-floppy floppy spinning in drive
| step floppy drive seeking
| relay-on cassette motor relay activating
| relay-off cassette motor relay turning off
Automation Options
-turbo | Run at top speed
-haste | Run fast by drawing once per second (graphics/timing inaccurate)
-batch | Have "Record" menu save files without prompting.
-fa hex | Update FPS when Z-80 hits address
-ta hex | Turbo for 5 frames at Z-80 address
-rand | Initialize RAM and the R register with random data.
-ct -ctx | Enable/disable cassette auto turbo
-dt -dtx | Enable/disable floppy disk auto turbo
-ht -htx | Enable/disable hard drive auto turbo
-wt -wtx | Enable/disable wafer drive auto turbo
-pt -ptx | Enable/disable printer auto turbo
-iat -iatx | Enable/disable input/paste auto turbo
Keyboard, Joystick and Light Pen Input
-jx | Disable joystick input
-js | Swap joystick inputs
-kl log|phys|typ Set keyboard layout to logical, physical, typing
-kg -kgx | Enable/disable key ghosting on keyboard input
-kt -ktx | Enable/disable keyboard auto de-turbo
-kc | Clustered key layout in software keyboard (Model 4 only)
-ks -ksx | Enable/disable soft capslock (Model 2/12/16/6000 only)
-i str | Send str as keyboard input (as if it were pasted)
-iy str | Send str with current date/time substitution
| %m,%d,%y - month, day, year, %h,%i,%s - hour, minute, second
| %Y - 4 digit year
-if file | Send file contents as keyboard input
-ifr file | Send untranslated file contents as keyboard input
-iw str | Wait until str appears on screen
-ik row mask | Set keyboard matrix row to mask
-ictl reset | Reset the TRS-80
-id N | Delay N frames
-itime N | Give up on input after N frames of waiting (0 to never give up)
-ix | Exit emulator when command line input has been sent
-ib file | Run trs80gp commands from file
-is | Save a screenshot
-ics | Save a clean screenshot (no beam interference dropouts)
-it | Write text VRAM to file
-ig | Write hires graphics VRAM to file
-ic | Write programmable character generator VRAM to file
-im dump N file | Save ASCII image of disk N to file.
-im wp N on|off | Enable or disable write protect on disk N
-im trackdump N file
| Save ASCII image of disk track data of disk N to file
-im insert N file
| Insert disk image file into drive N
-im eject N 1 | Eject disk image in drive N with no prompting
-ip host:port | Read keyboard input from TCP/IP host, port endpoint.
-ip @port | Listen for TCP/IP connections on port for keyboard.
-ip endpoint | Hook input to an endpoint (see Endpoint section).
-ir audio | Toggle audio recording (turn on if off, off if on)
-ir flash | Toggle flash video recording
-ir video | Toggle AVI video recording
-ir gif | Toggle animated GIF recording
-ir mhz | Toggle MHz recording
-lp | Enable light pen emulation (1,3,4)
-esc-exits | Pressing the escape key exits trs80gp
Programmer Help
-b hex | Set debugger breakpoint (can use "-b hex" up to 4 times).
-b label | Set breakpoint at label (if .bds file loaded)
-b start:end | Set breakpoints from start to end (0:ffff can be handy)
-bm hex/label | Set Z-80/6800/6809 memory access breakpoint
| also -bmr or -bmw to trap only reads or writes
-bio hex/label | Set Z-80 I/O access breakpoint
| also -bior or -biow to trap only reads or writes
-b16 hex | Set 68000 debugger breakpoint
-b16m hex/label | Set 68000 memory access breakpoint
| also -b16mr or -b16mw to trap only reads or writes
-l file | Load file into memory but don't run it
-ls file.bds | Load symbols from file but don't load its data.
-ee | Enable emulator extensions (debugging oriented)
-trace | Start with tracing on (Record → Trace)
-tr addrset | Start with tracing when PC in given address set.
-trpr name,nm2 | Device values to output in trace log.
-nrs | Don't load any built-in symbols/source code.
-8z | Use Zilog mnemonics when disassembling 8080 code.
-8i | Use Intel mnemonics when disassembling 8080 code.
FreHD Emulation
-frehd | Enable FreHD emulation
-frehd_dir dir | Set directory used for FreHD external file import/export
| Also enables FreHD emulation
-frehd_load fl | Use boot block in file instead of the built-in one
-frehd_patch | Apply FreHD auto-start patches to the ROM
-frehd_menu | Use built-in FreHD menu program rather than frehd.rom
| in the -frehd_dir
Becker Port Options (CoCo only)
-bck host:port | Connect Becker port to TCP/IP host, port endpoint.
-bck @port | Listen for TCP/IP connections on port for Becker port.
-bck :v | Run Videotex emulator attached to Becker port.
-bck endpoint | Hook Becker port to an endpoint (see Endpoint section).
Scripting and Customization
-menu name cmd | Add "name" to Custom menu executing to execute cmd
| -menu Soft [ postmsg keyboard_soft ]
| -menu "Debug Source" [
| [ postmsg debug ]
| [ postmsg source_code ] ]
-cmd cmd | Commands to run at program start
Endpoint Syntax
host:port | Connect to TCP/IP host name and port number.
:port | Connect to TCP/IP port number on localhost.
@port | Listen for TCP/IP connection on port number.
/file/path | Unix serial port like "/dev/ttyUSB0" or a fifo.
>filename | Write all output to a file.
<filename | Read input from file.
<infile>outfile | Read from infile and write to outfile.
|command %p | Run command that will connect to %p TCP/IP port.
:loop | Loopback device on serial port.
:mouse | Emulate 2 button mouse device.
:mouse3 | Emulate 3 button mouse device.
:dt1 | DT-1 emulator.
:v | Videotex emulator.
:mx70 | MX-70 printer emulator.
:ec | Electric Crayon emulator.
[ :model args ] | Pass arguments to :mx70, etc. e.g., [ :mx70 -mute ]
Esoterica
-event endpoint | Send high level system events to an endpoint.
-sync | Try to maintain frame rate exactly (uses excessive CPU)
-trsnic | Preliminary trsnic emulation (model 1,3,4 only)
-time render|frame|emulation | Show timing in title bar
-showkey | Show Windows key code in title bar
-showframe | Show the frame number in title bar
-writerom | Make ROM writeable (Model 1 and 3 only)
-m1_vblank | VBLANK readable as bit 0 of port $FF (Model I only)
-x1hack | Temporary fix for Xenix 1 boot error (and TRSDOS-16)
| (disables 68000 to Z-80 interrupt request through CTC1)
-rtc16 | Enable real time clock for Model 16,6000 (default)
-rtc16x | Disable real time clock for Model 16,6000
-mmu9f | Model I 16 RAM bank 0 when bit 0 of port $9F set.
-t1hack | Modification to when FDC switches to Type I status.
| Only useful to make TRSDOS-II RESTORE work.

### Model Selection

The various `-m*` options and the File → Change Model menu form quite a wide variety of different computers, terminals and printers to emulate. When trs80gp is run from the command line the model will default to `-m3`. When run from a GUI the model will be whatever was last selected by the menu. In either case various preferences like display mode defaults are recalled based on the model.

Many of the command line arguments may not be applicable depending on the model. For example, printers and terminals do not have cassette or disk storage and ignore those options. One meaningful difference is the `-r0, -r1, -r2, etc.` ROM revision. The lower the revision number the earlier the original release of that ROM. The ROMs are also selected by level. Both the Model I and Model III have Level I and Level II BASIC ROMs selected with `-l1` and `-l2` respectively. Level I was a very small and simple version of BASIC. For the Color Computer, `-l1` and `-l2` select Color BASIC and Extended Color BASIC. Here is a table of levels and revisions for each model which have more than one:

Model | Level | Revision | Default? | Version
--- | --- | --- | --- | ---
I (more info) | -l1 | n/a |  | Level I BASIC
-l2 | -r0 |  | 1.0 - earliest version with a few bugs
-r1 |  | 1.1 - most bugs fixed
-r2 |  | 1.2 - nearly identical to 1.1
-r3 | yes | 1.3 - shortened `MEM SIZE?` prompt; some new features
II,12 16,6000 | n/a | -r0 |  | Early boot rom; no hard-drive boot.
-r1 | yes | Checksum $1BBE with hard-drive boot.
III | -l1 | n/a |  | Level I BASIC
-l2 | -r0 |  | No shift-down control keys; prints screen if S+P pressed at same time
-r1 | yes | Most common version
4 | n/a | -r0 | yes | Usual Model 4 ROM
-r1 |  | Later "international" ROM; default for `-m4ga`
Tandy 10 | n/a | n/a | n/a | Using ROM coded for emulator.
CoCo | -l1 | -r0 |  | Color Basic 1.0
-r1 |  | Color Basic 1.1
-r2 |  | Color Basic 1.2
-r3 | yes | Color Basic 1.3
-l2 | -r0 |  | Extended Color Basic 1.0
-r1 | yes | Extended Color Basic 1.1
n/a | -r0 |  | Disk Basic 1.0 (warning: serious bugs)
-r1 | yes | Disk Basic 1.1

See the Color Computer section for how to mix and match combinations of ROM versions.

### Keyboard

The Keyboard menu lets you select between Logical Layout (the default), Physical Layout and Typing Layout. There is also Experimental Logical Layout which is (hopefully) temporary. It is identical to Logical Layout except for a slight difference in handling shift key state to work better with a custom CP/M BIOS.

Enable ghosting for a truly authentic experience. Due to the way the keyboard matrix works on the Model 1, 3 and 4 it is possible for a 4th key to appear pressed when 3 others are down. For example, if you press and hold `F`, `G` and `O` in that order you will see `FGN` on screen as those keys ghost with `N`. On the Color Computer `O`, `G`, `N` will result in `OGF` showing up.

#### Logical Layout

Logical Layout means that what you see on the key is what gets sent to the TRS-80. This is as you would expect but there are two things to keep in mind. None of the TRS-80 Models sport the full variety of keys on a modern PC. The Model 2 comes closest where the Model 1,3,4 machines lack even square brackets, curly braces and many others. They did, however, have some keys which have no analogue on the PC. Both had a `BREAK` key for interrupting programs. Models 1,3,4 had `CLEAR` to clear the screen. The Model 2 had `HOLD` to pause display. The Model 4 and 4P have a CAPS key for switching between upper and lower-case input.

To Get | Model 1,3,4 Press | Model 2 Press | Color Computer
--- | --- | --- | ---
`BREAK` | `Esc, Pause/Break, End` | `ctl-C, Pause/Break, End` | `Esc, Pause/Break, End`
`CLEAR` | `Home, \` | n/a | `Home`
`CAPS` | `CapsLock, PageUp` | n/a | `CapsLock`
`HOLD` | n/a | `ctl-shift-@, Scroll Lock` | n/a

Model 2, 12, 16, 6000 and Tandy 10 have a soft capslock option activated with the `-ks` option or the Keyboard → Soft Capslock. It acts like capslock without using the real capslock key. It can save a lot of trouble switching between the emulator another other applications. It is remembered as a preference and will be activated automatically if you run TRSDOS on the Model 2 or 12 as it requires that all commands use upper case.

#### Physical Layout

With Physical Layout the emulator is set up so TRS-80 keys are activated by PC keys in roughly the same relative position on the keyboard. Most of the symbols on your keyboard will correspond to the same key on the TRS-80. The letters, numbers, arrow keys and Enter will do what you expect and `!#$%;<>,.` are in the same spot, otherwise:

To Get |  | Press
--- | --- | ---
``` |  | `shift [`
`@` |  | `[`
`&` |  | `shift 6`
`*` |  | `shift -`
`(` |  | `shift 8`
`)` |  | `shift 9`
`-` |  | `=`
`+` |  | `shift ;`
`=` |  | `shift =`
`:` |  | `-`
`'` |  | `shift 7`
`"` |  | `shift 2`
`Left` |  | `], Left`
`Right` |  | `\, Right`
`Up` |  | ``, Up`
`Down` |  | `Tab, Down`
`Break` |  | `Backspace, Esc, Pause/Break, End`
`Clear` |  | `', Home`
`Caps` |  | `CapsLock, PageUp`

Physical Layout is generally only needed for games where a key activated at a different position can make the game unplayable. Note that the Model 2 does not support Physical Layout.

#### Typing Layout

Typing layout is optimized for regular keyboard input like inputting BASIC programs or word processing. Other layouts try to report all the keys held down in the host keyboard to the TRS-80. That works well with games where keys can be held down for long periods to move or control a video game player. But it is of no help in typing text. In fact, sophisticated keyboard input routines on the TRS-80 side will support N-key rollover to compensate for the multiple keys held down that come from a fast typist.

Like Logical layout, Typing layout will attempt to input keys as they appear on your keyboard. It also massages the keyboard input so that only one normal key is held down at a time. If a shift or control key is needed it will ensure those modifier keys are down before the regular key and only go back up after the regular key is released. In addition the key is held down for a fixed amount of time which is long enough for even large key-bounce delays to recognize it. If the key is held down longer the auto-repeats from the host system will be sent as key presses. As such, even TRS-80 programs that don't support auto-repeat will have that feature.

Keys are also buffered allowing type-ahead even if the TRS-80 is not polling the keyboard fast enough to keep up.

Typing layout is not recommended for games (though the automatic key repeat may be a rapid fire cheat in some games). It is quite helpful for Model 1 and 3 Level 1 BASIC, TRSDOS 2.3 on the Model 1 and CP/M on the Model 1, 3 and 4.

#### Special Keys

`F9` will pause and resume the emulation. You can hold `F12` to make the TRS-80 run faster. Pressing `shift-F12` will keep it in fast (turbo) mode without having to hold `F12`. Tapping `F12` will put the emulator back to normal speed. The `-turbo` command line option has the same effect.

In turbo mode keyboard input can get very difficult with characters repeated frequently. trs80gp addresses this by dropping out of turbo mode whenever a key is pressed. This automated return to normal speed can be turned on or off by Keyboard → Auto De-Turbo menu.

The Typing keyboard layout usually works better in Turbo mode as there is no problem with repeats generated by the TRS-80. Try using that layout in turbo mode with Auto De-Turbo turned off.

`Ctrl-Alt-C` and `Ctrl-Insert` and `Ctrl-Alt-V` and `Shift-Insert` are shortcuts for "Copy" and "Paste" respectively.

Use `F11` to save a screenshot and `Shift-F11` to save a cleanshot which is a screenshot without any beam drop-outs that appear as they do on the real Model I.

`Alt-F5` activates the machine's reset button. The Model I's reset button is not a hard reset and will not reboot the machine in the case of an especially bad crash. In that case use `Ctrl-Alt-F5` to do a warm restart to reboot the emulated Model I or File → Warm Restart. `Shift-Ctrl-Alt-F5` or File → Cold Restart is the same as a warm restart but it also re-initializes all RAM.

`Alt-Enter` will toggle between windowed and full screen mode.

`Alt-F4` is the standard Windows shortcut to exit the program which may not be familiar to Wine users. For that matter `Alt` by itself will move focus to the menu where you can use the keyboard to navigate and `Alt-F`, `Alt-E` will active the `File`, `Edit` and `View` menus respectively and so on for other top-level menus.

#### Software Keyboard

In unusual circumstances you may need to use the Keyboard → Software Keyboard... in order to press several keys at once. Most PC keyboards can only show 3 or 4 keys held down at once but some TRS-80 games have easter eggs that require holding down as many as 8 keys. The software keyboard makes this easy as each keyboard button stays pressed when clicked and only releases when clicked again. Or if the corresponding PC key is released.

If nothing else it is laid out the same as the original TRS-80 keyboard so you can see the idea behind Physical Layout mode. And the buttons go up and down as you type. Put the software keyboard window underneath the main one and you'll feel like you're on a real TRS-80. Minutes of fun.

The software keyboard also has an orange reset button. There's also a "RAM Badge" showing how much memory is installed. Incidentally, the Model 1 and Model 4P didn't have RAM badges and the reset key was in a different location.

#### Automatic Input (aka Pasting)

Keyboard input can be pasted into the emulator with the Edit → Paste menu entry, "`-i`" command line flags, `Ctrl-Alt-V` or `Shift-Insert` keyboard shortcuts, or Edit → Paste Macro N menu entries. How it is passed to the emulator depends on the Paste Mode which defaults to "OS Injection". The mode can be changed with Edit → Paste Mode or on the command line with `-icmd [ input mode ]` as in the table below:

Paste Mode | Command | What it Does | When to Use
--- | --- | --- | ---
Inject into OS | input char | Hooks into the standard ROM or DOS routines for keyboard input. | Robust, fast and supported by built-in DOSes and BASIC. Can input characters that can't normally be typed. Won't work at all on unsuppored DOSes like CP/M on the Model 4 or any program like games with custom keyboard scanning routines.
Typing | input key | Characters are translated to individual key presses in the same way as the `Typing` keyboard layout. | Best for word processors or operating systems not supported by "Inject" mode. Delays may be needed if the program takes extra time on some input (e.g., after ENTER). Can be OK for games but a single key down at a time is often too limiting. Not all characters can be typed and programs will use different key chords for special characters like square brackets or curly braces. In short, pased input may be lost because it cannot be translated into keystrokes or due to timing difficulties.
Toggle | input toggle | Like "Typing" but each character toggles the up/down state of the key it translates into. Allows for many keys to be pressed at once and how long each are held down. | Generally needed for games where two keys down at once are needed for diagonal movement. Or other programs where key "chords" are required. The need to repeat characters for press and release of keys means that text simply copied from elsewhere won't work when pasted into the emulator.

Automated input is a convenient way to "fast-type" a BASIC program or run a series of TRS-DOS commands.

For example, the following command will go into BASIC, set the top of memory to 60000 and then input and run a short BASIC program.

        trs80gp -i "BASIC\r\r60000\r10 ?7*5\rRUN\r"

Note on the Model 2 that trs80gp sends the input to the keyboard hardware and TRS-DOS clears the buffer before reading each command leading to most input being lost (hence the `-iw` option).

On the Model 2 we must wait for the "Date" prompt to appear thus making the exercise a bit more complicated:

        trs80gp -m2 -iw Date -iy "%m/%d/%Y\r%h.%i.%s\rBASIC\r10 ?7*5\rRUN\r"

The contents of entire files can be sent using `-if filename` or the Edit → Paste File.. menu.

The emulator automatically goes into turbo mode when processing input fed in from the command line or pasted directly into it. The speed boost is nice when pasting in BASIC source listing or other large input. It can be turned off with the `-iatx` on the command line or put on explicitly with `-iat`. Or use the Edit → Auto Turbo menu entry.

##### Input Translation

Input sent with `-i` will interpret the usual C-style backslash escapes. Unlike C, you'll use `\r` much more than `\n` since TRS-80's most often use carriage return (character 13) to end a line.

Escape | Output | Character #
--- | --- | ---
\a | beep | 7
\b | backspace | 8
\e | escape | 27
\f | form-feed | 12
\n | newline | 10
\r | carriage return | 13
\t | tab | 9
\v | vertical tab | 11
\`ooo` | octal value (1, 2 or 3 digits) | `ooo` in octal
\x`hh` | hexadecimal value (1 or 2 digits) | `hh` in hexadecimal

Pasted input, pasted files or files sent via `-if` have line endings converted to make host input more compatible with what a TRS-80 expects. CR followed by LF is replaced with CR. Otherwise LF is replaced with CR. This handles both Windows style text with CR+LF as a line ending and Unix style with NL as the line ending.

Input fed in with `-ifr` is not translated at all.

##### OS Inject Mode

Since the characters are fed to keyboard input routines you can enter graphics characters and other data that normally can't be typed in with a real keyboard. Consider this a handy way to put graphics characters inside string literals in BASIC. Normally that requires magic incantations of `VARPTR` and has been the subject of countless 80 Microcomputer magazine articles.

If the TRS-80 is not calling the standard keyboard input routine then trs80gp will time-out and give up trying to send input after about one minute. Specifically, 3600 frames which is one minute at 60 Hz and one minute and 12 seconds at 50 Hz. Mind you, the emulator automatically switches to turbo mode during automated input so the real time will be less. The timeout value can be changed with the `-itime N` option or disabled entirely with `-itime 0`.

A few of the options such as `-id N` (wait N frames) and any which generate screenshots (`-is`, `-ic`), exit the emulator (`-ix`) or write to files (`-it`, `-im`) do not wait for keyboard polling and can be used to grab screenshots of games. Generally they are of most use in writing the automated tests used by trs80gp's authors. The `-showframe` option is useful for screenshots as it shows the current emulator frame in the title bar. Thus you needn't guess how many frames to wait before a program is ready for its screenshot.

The `-ik` will explicitly set individual keys in the keyboard matrix. This can be used to control games and other programs which do not use the standard ROM or DOS keyboard input routines. But you do need to know they keyboard matrix layout and carefully time the input make the whole exercise rather tedious. A better facility for entering input to games and other uncooperative programs is being considered.

##### Typing Mode

This mode uses the same emulator mechanism as the keybord "Typing" layout to translate characters into keystrokes that are sent one at a time to the emulator. Not supported by machines which do not have keyboard matrix emulation like the Model 2 line, DT-1 and Tandy 10.

Unlike the OS Injection they keys are not held back until the program scans the keyboard matrix. Keyboard input can thus be lost if the steady rate the keys are fed to the emulator is too fast for the current program. In those cases you will need to add delays with `-id` or use `-iw` to wait until the program is known to be looking for keyboard input again.

Each key press and release happens over several frames so there is normally no need to delay when sending a line of text.

##### Toggle Mode

The most tedious mode to use as every character ultimately is repeated to trigger the press and release of each key. Here the software keyboard can be of great help as it reflects any keyboard input and will indicate if any keys are "stuck" down because you missed sending a second character to pull the key back up.

There is no delay between each key up and down in toggle mode. Even typing "ABC" will require delays between the down key press and up. For example:

trs80gp -m1 -icmd [ input toggle ] -iw READY -i A -id 4 -i A -id 1 -i B -id 4 -i B -id 1 -i C -id 4 -i C

Awkward, but it is much easier than issuing `-ik` to directly control the keyboard matrix. Toggle mode will consume characters until a nul is reached which will induce a single frame delay. The above command can be written equivalently as:

trs80gp -m1 -icmd [ input toggle ] -iw READY -i "A\0\0\0\0A\0B\0\0\0\0B\0C\0\0\0\0C"

#### Paste Macros

The Edit → Define Macro... menu allows you to create up to 10 paste shortcuts. The strings entered can be pasted either through the Edit → Paste Macro 0 though 9 menu entires or by pressing Alt-0 though Alt-9. Each macro is automatically saved and there is a different set of macros for each TRS-80 model.

The mechanism is exactly the same as other automatic input so you can use `\` escapes to enter control and graphics characters. This is particularly useful for Xenix's virtual console feature where entering `\xFC` followed by `0` though 9 will switch to that console. For example, to have Alt-4 switch to console 4 set up the macro to send `\xFC\x34` or `\xFC4` (\x hex escapes consume at most 2 digits). Also, like `-iy`, "%" substitutions for date and time can be used.

### Light Pen and Joystick

The Windows version supports joystick input on the Model 1, 3, 4 and Color Computer and light pen input on the Model 1. The light pen must be enabled with the `-lp` option; the joystick can be disabled with the `-jx` option.

An Alpha products joystick is emulated using any of the standard joysticks attached to your computer. The actual joystick was a bus hog that would respond to reads on practically any I/O port. Most programs use port $00, $13 or $F7 so only those are mapped by trs80gp.

For the Color Computer the `-js` option or Keyboard → Joystick → Swapped will use the second gamepad on your PC as the primary joystick and vice-versa.

With the light pen enabled pressing the mouse button down will simulate the light pen making contact with that position on screen. Releasing the mouse button acts as if the pen were removed from the screen. Very few programs were found that have light pen support so please report any problems you see. We'd be very much interested to run some test programs if you have an original light pen.

### Working With Floppies

The Diskette menu shows all 4 floppy drives and what disk image is inserted in them or `<empty>` if there is none. Any disk file name enclosed in `<< .. >>` is a built-in disk image. If the name has an asterisk (`*`) before it the disk has been modified and must be saved. For non-internal disk images the changes are saved automatically, but changes to internal disk images or disk images loaded from .zip archives must be explicitly saved to another file. trs80gp will remind you to do this if you try to eject a disk with changes or exit the emulator with unsaved changes.

All built-in disk images have a short name that starts with a colon. This is displayed in parenthesis on each entry in the "Insert disk..." menu as a reminder that the short name can be used on the command line to insert the floppy when starting trs80gp.

Each drive has a sub-menu that lets you eject diskettes, replace diskettes, insert diskettes, save them to a new file or toggle their write protection. This isn't the read-only flag of the PC file system but an internal one corresponding to the physical write protect notch on the real floppy disks. Besides saving a copy of a disk image file, Diskette → ... → Export... can write out the disk image in ASCII format or as a track dump in ASCII format for debugging purposes.

The internal diskettes `unformatted dmk` and `unformatted imd` are single-sided unformatted diskettes in `DMK` and `IMD` format. Equivalent to the `-d dmk` and `-d imd` command line options. Your currently running DOS will need to format them before they can be used. `unformatted dmk DS` and `unformatted imd DS` are double-sided disk images also accessible from the command line as `-d dmk-DS` and `-d imd-DS`.

The `-d0, -d1, -d2, -d3, -td and -ld` command line options allow you to select disks to insert into the floppy drives when the emulator starts. The default is to put a TRS-DOS floppy in drive `:0` so that the TRS-80 will boot into TRS-DOS (which is the same as the `-td` option). You can just use `-d file.dsk` to have a floppy disk inserted in the next available drive or just the name of the floppy disk image if it ends in one of the known suffixes (`.dmk`, `.dsk`, `.imd`, `.hfe`, `.jv1` or `.jv3`).

Whenever a floppy is accessed trsg80p will go into turbo mode automatically. This can be enabled or disabled with the Diskette → Auto Turbo menu. Running in turbo mode has no harmful effect on diskette usage as the necessary relative timing remains the same. Generally you'd only want to turn the feature off to experience the original pace of the machine or when faster disk operations make it hard to read text. Or to keep the TRS-80's real time clock in sync with the current time.

Unlike actual floppy drives, the emulated drives operate in a special any-sided mode. If a double-sided disk image is inserted, the drive will become double-sided. If the drive has a single-sided disk image and the operating system attempts to format a track on side 2, the drive and disk image will automatically upgrade to double-sided.

To control this behaviour, the The `-dNss`, `-dNds` and `-dNas` command line options allow you to force drive N in the system to behave as single-sided, double-sided or any-sided. Alternatively, you can enable or disable any-sided mode via the Diskette → Drive → Emulate only ... menu option.

Because of problems with CP/M auto-detecting drive sides during FORMAT, the any-sided drive behaviour is not the default on the Model II family. The index hole position is different between single and doubled sided 8" diskettes. Real 8" double-sided disk drives use the position change to actively detect doubled-sided or single-sided diskettes. As a result (unless `-dNas` is used), the emulator will signal `NOT READY` from the 8" drive in the follow cases:

- Double-sided image used in a single-sided drive
- Access the second side of single-sided image in a double-sided drive

Note that in this strict mode if you wish to format a double-sided disk image you must insert a double-sided blank as the single-sided blank will not be promoted to double-sided.

Like the original machines, the Model II (`-m2`) will have single-sided 8" drives and the Models 12, 16, 6000 and Tandy 10 (`-m12 -m16 -m6000 -m10`) will have double-sided 8" drives.

#### Internal Floppy Images

A handy table listing all the available internal floppy image files and how they may be accessed from the command line. trs80gp only shows floppies made for the current model in the menu which is generally helpful but you can't use them to boot a Model 4 with a Model III TRSDOS like `trs80gp -m4 :td3` will do from the command line. Unless you export the internal `:td3` image to a file in Model III mode and then insert that file in Model 4 mode.

Model | DOS | Menu Entry | Type | Command Line
--- | --- | --- | --- | ---
I | TRSDOS 2.3 | << TRSDOS23.dmk >> | Boot | :td1 or -td
<< m1-trsdos-blank.dmk >> | Blank | :tb1
<< m1-trsdos-util.dmk >> | Utilities | :tu1
<< TRSDOS2.3jp.dmk >> | Boot | :tj1 `-m1j` default
LDOS 5.3.1 | << ld531-1.dsk >> | Boot | :ld1 or -ld (also inserts :ld1e)
<< ld531-2.dsk >> | Extras | :ld1e
<< m1-ldos-blank.dmk >> | Blank | :lb1
<< m1-ldos-util.dmk >> | Utilities | :lu1
<< ld531-1j.dmk >> | Boot | :lj1 `-m1j` for `-ld`
II 12 16 6000 | TRSDOS 2.0a | << TSDOS20A.IMD >> | Boot | :td2 or -td
<< m2-trsdos-blank.dmk >> | Blank | :tb2
<< m2-trsdos-util.dmk >> | Utilities | :tu2
LS-DOS 6.3.1a | << l2-631a.dmk >> | Boot | :ld2 or -ld
<< m2-lsdos-blank.dmk >> | Blank | :lb2
<< m2-lsdos-util.dmk >> | Utilities | :lu2
TRSDOS II 4.2 | << m2-trsdos4-blank.dmk >> | Blank | :t4b2
<< m2-trsdos4-util.dmk >> | Utilities | :t4u2
III | TRSDOS 1.3 | << TRSDOS13.DSK >> | Boot | :td3 or -td
<< m3-trsdos-blank.dmk >> | Blank | :tb3
<< m3-trsdos-util.dmk >> | Utilities | :tu3
LDOS 5.3.1 | << ld3-531.dsk >> | Boot | :ld3 or -ld
<< m3-ldos-blank.dmk >> | Blank | :lb3
<< m3-ldos-util.dmk >> | Utilities | :lu3
4 | TRSDOS 6.2.1 | << TRS621.DSK >> | Boot | :td4 or -td
<< m4-trsdos-blank.dmk >> | Blank | :tb4
<< m4-trsdos-util.dmk >> | Utilities | :tu4
LS-DOS 6.3.1 | << ld4-631.dsk >> | Boot | :ld4 or -ld
<< m4-lsdos-blank.dmk >> | Blank | :lb4
<< m4-lsdos-util.dmk >> | Utilities | :lu4
Tandy 10 | ADOS | << ados-system.imd >> | Boot | :ad
<< ados-blank.imd >> | Blank | :adb
CoCo | DECB 1.1 | << mc-dos-blank.dmk >> | Blank | :cb
Any | Any | << Unformatted dmk >> | Unformatted | :dmk
<< Unformatted imd >> | Unformatted | :imd
<< Unformatted dmk DS >> | Unformatted | :dmk-ds
<< Unformatted imd DS >> | Unformatted | :imd-ds

Type | Description
--- | ---
Boot | Boot floppy for the given DOS. Must go into drive `:0`
Blank | Formatted floppy for the given DOS.
Utility | Utility programs for copying files to and from emulated floppies.
Unformatted | Floppy image without any data. Will require a `FORMAT` before it can be used by a particular DOS.
Extras | Second floppy for Model I LDOS which doesn't have the space for everything on a single floppy.

### File Import and Export

For relatively small files using the Edit → Paste menu is an easy way to get a file into the emulator. For example, a BASIC program file can be pasted into the emulator and then saved to diskette or other emulated media in the usual way (e.g., `SAVE"PROG/BAS"`).

Conversely BASIC programs can be exported by simply listing them to the printer with `LLIST` and then copying the output seen in the Printer → Printer... window. Or for very short files a File → Copy of what is on the screen will suffice.

The File → Load... menu entry can load a program file into memory. Most of the TRS-80's have either a `DUMP` or `SAVEM` command you could use to subsequently save the program to diskette. Debuggers and other system utilities often have similar capabilities. However, you'll need to know where the file loads into memory and the execution address if it is a program file.

For exporting binary data keep the Record → RAM command in mind. A `LOAD PROG/CMD` or `LOADM` can bring a file into memory which can then be extracted from the saved copy of RAM.

Another approach is to use some kind of file transfer program in the emulator that can send or receive files over the RS-232. Since the RS-232 can be hooked to a TCP/IP connection it should be possible to get some kind of utility than can speak xmodem or the kermit protocol or what have you. Or even something of your own devising.

These may not be the most desirable approaches but I mention them as they can be surpisingly handy. Pasting in a basic program from your PC editor and then capturing local edits with LLIST is a fairly decent if somewhat hand-crank development environment. Or sometimes you just need to get something in once to bootstrap a more powerful technique. And some of the tedium can be automated with trs80gp's automatic input facilities.

#### Model 1,2,3,4,12,16,6000

The built-in utilities floppy has `IMPORT2` and `EXPORT2` commands to bring files into and out of the emulator. They use the FreHD emulation so trs80gp must be run with the `-frehd` option for them to work or activated by the Hard Drive → FreHD menu. Otherwise they will say `No FreHD attached` and exit. Most Model II operating systems will require the hard drive controller to be disabled (`-hx`) for the utilities to function.

`IMPORT2` reads a file from the host computer and writes it to a TRS-80 disk file.

Usage: `IMPORT2 [-lnepvr] hostfile [trs80file]`

If the trs80file parameter is omitted the last component of the `hostfile` is used with '.' changed to '/'. If this is not a legal TRS-80 file name you will get an error message.

Options:

-l
  Convert the host file name to lower case. This is needed for NEWDOS/80 which insists on uppercasing the command line.
-n
  Change all newlines ('\n') in the host file to carriage return ('\r')
-e
  Most Models: Use the NEWDOS/80 end of file convention. This is required for DOSes such as DOSPLUS which use the NEWDOS/80 convention but are not detected by IMPORT2.
  Model II: Write the file with a logical record length of 1. This is required for JCL files and some other text files.
-p
  Model II TRS-DOS only - write a program rather than a data file. This must be speficied when importing executables (i.e., `/CMD` files).
-v
  Model II TRS-DOS only - write input text file as a variable length record file. Lines longer than 255 characters will be split up.
-r
  Model II TRS-DOS only - input file is a raw a variable length record file. This is required if the file was originally exported with the `-r` option.

`EXPORT2` reads a file from the TRS-80 and writes it to the host computer.

Usage: `EXPORT2 [-lner] trs80file [hostfile]`

If the `hostfile` parameter is omitted the `trs80file` is used with '/' changed to '.'.

Options:

-l
  Convert the host file name to lower case. This is needed for NEWDOS/80 which insists on uppercasing the command line.
-n
  Change all carriage returns ('\r') in the TRS-80 file to newlines ('\n')
-e
  Use the NEWDOS/80 end of file convention. This is required for DOSes such as DOSPLUS which use the NEWDOS/80 convention but are not detected by EXPORT2.
-r
  Model II TRS-DOS only - if the export file has variable length records it will be written in raw variable length record format. This allows guaranteed preservation of variable length record files on export and import. The default translation of them to text files could introduce errors if, for some reason, the file type was not holding a text file.

`IMPORT2` and `EXPORT2` are my modified versions of Frederic Vecoven's modified version of Timothy Mann's originals. `VHDUTL` is a modified version of Frederic Vecoven's original. My main change was to add support for the Model II operating systems. Note that although there is a utility floppy image for each DOS and model the executables are all identical. The copies are only required because of their incompatible file systems and floppies. The executables themselves detect the DOS they are run under and use the correct system calls.

Except for the Model II they should work on a real machine with a FreHD hard drive emulator. I have not tested this.

For bulk import and export I recommend either creating a `/JCL` (batch/script file) containing all the commands or using the `-i` options to have trs80gp do all the typing. There are also command line and GUI utilities to read and write files for many TRS-80 floppy image formats. I recommend the graphical TRSTools utility or the command line trsread & trswrite utilities. Neither have any support for the Model II which was the primary motivation to add `IMPORT2` and `EXPORT2` to trs80gp.

#### Variable Length Record Files

Model II TRS-DOS variable length record files show up with `V` as the "FILE TYPE" in a `DIR`. They are an unusual feature of Model II TRS-DOS. Instead of consisting of a set of fixed-size records they are a series of records of length anywhere between 0 and 255 bytes. A Model II program can only read or write them sequentially.

Normally they are exported and imported as text files in the standard TRS-80 format with carriage return (character 13) terminated lines. It appears that these variable length record files are primarily used for program source code with each record holding a single line.

When they are exported in raw format each record is preceeded by a length byte which gives the size of the record including the length byte. A length byte of 1 will have no following data. A length of 44 will be followed by 43 bytes of data. A length of 0 is followed by 255 bytes of data.

#### Model 16, 6000 Xenix Import and Export

A pretty good way to get files into or out of Xenix is the xtar utility. It works like the usual unix `tar` command except that it knows how to read and write floppy disk images. xtar can take an entire directory and write out multiple floppy disk images that Xenix's tar will know how to extract. Or it can take the multiple floppy disk images that a Xenix tar can create and extract the files.

There is also the xfile utility. It can read (but not write) Xenix hard drive images. Once trs80gp has been shut down xfile can list or extact files directly from the hard drive image file.

For truly massive file import and export there is a technique where tar archives can be placed into hard drive images. Credit to John Elliott IV for the technique and these instructions on how to do it.

Make a copy of your root filesystem DSK (both the DSK & CFG). Name it something else like `scratch.dsk` and `scratch.cfg`. Launch trs80gp, and use the Hard Drive menu to mount the new image on a free drive. On my system, I have HD0 as root and HD1 as /home, so I mount on HD2. On the emulator’s Hard Drive menu, that’s root on :4, home on :5, and ‘scratch’ my extra drive on :6.

Boot XENIX & login. `su` to root.

To bring files in, on your host system you create a tar file with the items you wish to import. Next, on your host system, you run this command:

    	dd if=my-stuff.tar of=/path-to/scratch.DSK obs=512 seek=34

What that does is skip the boot tracks on the HD image and write the tar file to the data portion of the HD image. On your XENIX system, just run `tar xvf /dev/hd2`. You’ll see the files extracted that you tar’d up on your host system.

To transfer files OUT of the emulator, create a tar file on /tmp or wherever. Next, DD the tar file to /dev/hd2 (in my case, or wherever your ‘scratch’ drive is). So, for example, let’s say I want to get something out of my source directory:

         % su –
         Password:
         # cd /home/iv/src
         # tar cvf /tmp/vim-4.5.tar vim-4.5

         [tar outputs stuff]
         # dd if=/tmp/vim-4.5.tar of=/dev/hd2 obs=512
         iiii blocks in
         oooo blocks out

Now, you may be wondering why not tar directly to HD2? The reason is, to extract on the host system side we need the exact number of 512 blocks, and dd gives that to us, the `oooo` before `blocks out`.

Next, on your host system, extract your tar file with dd:

        % dd if=scratch.DSK of=/tmp/vim-4.5.tar ibs=512 skip=34 count=oooo

Voila, you have fast in and out. The only limit is the size of the scratch HD image you’re using. Well, that and the free space wherever you’re going to extract it.

### Working With Hard Drives

The Hard Drive menu can attach up to 4 drives. There are only unformatted hard drive images built-in so you will have to either supply your own or go through the process of formatting and otherwise setting up the emulated hard drive for use under your choice of emulated operating system.

Selecting Hard Drive → :slot → << unformatted hdv >> (or "emu" or "DREM") will connect an unformatted hard drive image to the selected controller slot. It will immediately prompt for a file to save the hard drive data. This is unlike the diskettes which will track changes internally and only ask to save when they are ejected.

On the command line use `-h :hdv` (or `:emu` or `:drem`) to attach a blank hard drive image and `-hx` to disable the hard drive controller.

The "drem" format is compatible with the DREM hard drive emulator available at https://www.drem.info/. It stores hard drive images as a pair of files. A `file.cfg` which gives the geometry and other information and a `file.dsk` which holds the data for all the blocks.

The "emu" format is compatible with the Gesswein MFM emulator available at https://www.pdp8online.com/mfm/mfm.shtml. Both the "drem" and "emu" formats allow for convenient copying of hard drive images to or from real TRS-80's.

FreHD emulation is not generally compatible with the Model II hard drive. Model II operating systems like the built in TRSDOS-2.0a which are unaware of the hard drive can import and export files using the FreHD utilities. But TRSDOS-II will fail to boot with `-frehd` enabled.

### Working With Cassettes

Cassette tape image files in the standard `.cas` format can be inserted into the virtual cassette drive with the Cassette → Insert... menu or the `-c` command line option. Upon insertion trs80gp adds entries to the Cassette menu corresponding to each cassette file found in the `.cas` image. Normally there is only one file. You can "fast forward" or "rewind" the cassette by selecting the menu entry for a file. Each menu entry gives information on each cassette file: counter position, format, name (if any), baud rate and length in seconds.

When the TRS-80 goes to read the cassette (usually as the result of a `CLOAD` or `SYSTEM` command) the emulator will send the data to the TRS-80 and go into turbo mode to load the data as quickly as possible. Cassette → Auto Turbo can be used to disable this feature.

When the TRS-80 saves a cassette file (e.g., a `CSAVE"A"` command is entered) the emulator switches to turbo mode. It will prompt you for a PC file in which to save the `.cas` image when the save is done. If you'd rather just hear the cassette send to the speaker turn off Cassette → Save → Auto.

When auto save is on the emulator waits a fifth of a second after the cassette has stopped before prompting to save the output. In some cases, like when BASIC saves variables to tape, the auto save triggers too quickly. Use the `-csd N` command line option to increase this delay (given in tenths of a second) or choose one of the presets under the Cassette → Save menu.

When loading a cassette file the emulator displays the cassette counter in the title bar as `Cr|123|`. When writing the title bar will show `Cw|001|`. If the counter stops when reading then the emulator has reached the end of the inserted cassette tape image. If the TRS-80 hasn't finished loading then the load has likely failed.

### Working With Aculab Floppy Tapes

The Wafer menu shows all 8 tape drives and what wafer image is inserted in them or `<empty>` if there is none. Any wafer name enclosed in `<< .. >>` is a built-in wafer image. If the name has an asterisk (`*`) before it the wafer has been modified and must exported to be saved. For non-internal wafer images the changes are saved automatically. trs80gp will prompt to save modified wafer images when you try to eject them or exit the emulator.

All built-in wafer images have a short name that starts with a colon. This is displayed in parenthesis on each entry in the "Insert wafer..." menu as a reminder that the short name can be used on the command line to insert the wafer when starting trs80gp.

Each drive has a sub-menu that lets you eject, replace, insert, export to a new file or toggle the write protection of a wafer image. This isn't the read-only flag of the PC file system but an internal one corresponding to the physical write protect sticker on real floppy tapes.

You can also use the Wafer menu to manage files on the image. The menu shows a list of files on the wafer. Selecting one will prompt to save it to your PC. A Delete sub-menu also lists the files and selecting an entry will delete that file from the wafer. Finally, the Import... menu lets you copy files from the PC into the wafer image. Because the Aculab firmware may have a copy of a sector in memory is best to `@LIST` a drive before and after doing any file imports or deletes.

Whenever a wafer is accessed trs80gp will go into turbo mode automatically. This can be enabled or disabled with the Wafer → Auto Turbo menu.

The Wafer → Manual... brings up brief instructions how to activate and use the Aculab Floppy and access the files from within the TRS-80.

#### Internal Wafer Images

Description | Command Line
--- | ---
5 foot (14 sectors) | :a5
10 foot (30 sectors) | :a10
20 foot (64 sectors) | :a20
30 foot (104 sectors) | :a30
50 foot (180 sectors) | :a50
75 foot (252 sectors) | :a75
Maximum (256 sectors) | :amax

#### .tape File Format

Aculab floppy tape wafers are stored in `.tape` format which is designed to hold not only those images but also Exatron Stringy Floppy images and cassette tapes in various formats. It maintains 99% backwards compatibility by putting an identifying trailer at the end of the file. Simple formats such as `.cas` will see the trailer as noise at the end of the tape while others will simply ignore it.

The trailer can be up to 255 bytes long and has the following format:

Size | Type | Description
--- | --- | ---
4 bytes | Magic string | Assist in identifying `.tape` format.
1 byte | Trailer length | Currently 9 bytes. Will be longer if `.tape` format extended.
2 bytes | Trailer checksum | Computed by setting checksum to 0 and for each trailer byte doing `checksum = checksum * 2 + trailer[i];` Stored little-endian and trailer bytes are treated as unsigned.
1 byte | Flags | bit 0 - write protected if set bit 1 - has `.ESF` header bit 2 - Aculab floppy tape
1 byte | Data type | Character indicating the encoding of the data before the trailer. 'w' - waveform (e.g., audio from cassette) 't' - bit level (i.e., `.cas` format) 'p' - pulse (`.cpt` compatible) 'b' - byte stream like bit but without leaders or start bits 'd' - data - high level like sector data or files

trs80gp only creates and understands a specific variant of `.tape` files for Aculab Floppy Tape emulation — flag bit 2 set, data type `'d'` and data consisting of concatenated 256 byte sectors from 0 to the tape size.

When Extratron Stringy Floppy emulation is added to trs80gp it is expected it will be capable of `.esf` wrapping and bit level encoding.

### Sound

Output to the cassette, Orchestra 80/85/90 or built-in speaker on the Model 4) is played as audio on your PC. Unless the cassette motor is turned on in which case trs80gp will convert cassette output to data (if Cassette → Auto Save is on).

Use Audio → Mute to toggle sound on and off.

### Memory

The `-mem` option is used to set the main memory size in kilobytes. It defaults to the maximum standard RAM for the model. On Model 16 and 6000 systems there is `-mem16` for the 68000 processor's available memory. It defaults to 1 MB as earlier versions of Xenix would crash if more memory was available. In the Record menu and debugger memory is referred to as RAM and `ram[]` in Bus Trace output.

The standard maximum RAM on a Model 4 was 128 KB. HyperMEM expands that up to a megabyte with `-mem hyper:1024` and is represented as a larger RAM in the debugger, recording and trace. For memory sizes greater than 128 K hyperMEM is assumed. `-mem 256` is equivalent to `-mem hyper:256` on a Model 4.

The Model 4 also features two expansion RAMs, `-mem super:1024` and `-mem mega:16384`. These don't extend main memory but provide a new tranche of banked RAM. The Record menu and the debugger refer to them as "Expansion RAM" and accesses to it show up as `expram[]` in the trace log.

The Model 4 can have an additional 256K with the XLR8er mod installed via the `-z180` flag. The Record menu and the debugger refer to them as "XLR8er RAM" and accesses to it show up as `xlr8er_ram[]` in the trace log.

### Endpoints

Many emulated devices such as the printer port and serial ports naturally process streams of data. Whether on the command line or through menus trs80gp lets you connect these devices to endpoints which can be other programs (via TCP/IP) or files or built-in devices.

Some of these connections would not make physical sense on a real machine. The printer port can be hooked up to the RS-232 serial port. Or the built-in mouse emulation can be tied to the keyaboard input endpoint. trs80gp does not generally limit the possiblities.

Here are all the possible endpoints as they would be written on the command line. When a command line option says it will take an `enpoint` then any one of these may be written in.

Endpoint | Operation
--- | ---
:port | Connect to the given TCP/IP port on the local host. For example, `:8900` to connect to port 8900. trs80gp will keep trying to connect so it will still work if the server is not immediately listening on The port.
@port | Listen for connections on then given TCP/IP port.
host:port | Connect to the given TCP/IP host and port. Like the `:port` syntax but allows connection to remote machines.
|command %p | trs80gp will listen for TCP/IP connections and put the port number in place of `%p` in the command line given and run that command. For instance, this will connect a Model 3 to an emulate MX-70 printer: `trs80gp -p "|trs80gp -mx70 -p :%p"` This is how trs80gp does `trs80gp -p :mx70` internally.
/dev/ttyname | Hook device to the Unix hardware serial port (e.g., `/dev/ttyUSB0`) or named pipe. If hooked to a trs80gp serial port the emulator will control the real serial port baud rate and other communcation parameters.
>filename | Output to the device is written to the given file.
<filename | Input from the device is read from the given file.
<infile>outfile | Combine the <infile and >outfile to specify both where to read input and where to write output.
:loop | Connect a loopback device that will echo any input it receives as output. This will operate like a physical loopback on bidirectional devices like serial ports.
:mouse | Emulated 2 button mouse. Normally only connected to a serial port.
:mouse3 | Emulated 3 button mouse. Normally only connected to a serial port.
:dt1 | Connect to an emulated DT-1 terminal.
:v | Connect to a Videotex emulator.
:mx70 | Connect an emulated MX-70 printer. Normally only attached to printer or serial ports.
:ec | Connect an Electric Crayon Emulator.

Here are the devices that can be hooked up to endpoints, the command line argument for that device hookup and the menu entry that can be used to check the connection status or make a new connection.

Device | Command Line Option | Menu
--- | --- | ---
printer port | `-p` | Printer → Connection...
serial port | `-r` or `-rA` | Serial → Port A...
second serial port | `-rB` | Serial → Port B...
keyboard input | `-ip` | Keyboard → Connection...
Becker port | `-becker` | Serial → Becker...
Events | `-event` | Debug → Event...

### The Printer

Many different types of printers could be attached to a TRS-80. The emulator supports a simple text mode printer. Use Printer → Printer... to see the current output in a "Printer Output" window. There's a Save button to save the output to a file.

The printer window can automatically pop up when the emulator prints something. Use Printer → Auto Popup to enable this feature. You can also simulate a powered-down (or disconnected) printer with Printer → On. The printer window is a simple ASCII view of the printer output. It works great for BASIC listings and such but for more complex output see below for how to fully emulate a printer.

As a convenience the emulator goes into turbo mode whenever output is sent to the printer. This "printer auto-turbo" can be turned off and on with the `-pt` and `-ptx` command line options or via the Printer → Auto Turbo menu entry.

Like the serial ports the printer port can be mapped to a TCP/IP connection. To listen for a connection use `-p @port` or the "TCP/IP Listen" option in the Printer → Connection... dialog. To make a connection use `-p host:port` or "TCP/IP Connect" in the connection dialog.

To attach an emulated MX-70 printer use `-p :mx70` on the command line or use Printer → Connection... and select it from the drop-down.

The Electric Crayon colour display actually attaches via the printer port. The idea was to make it easy to program. For example, a BASIC `LPRINT"ERS"` will erase the screen. See the section on the Electric Crayon for some details on how to use it.

In batch mode any TRS-80 printer output is written to a file called `trs80-printer.txt`.

### Serial (RS-232) Ports

trs80gp can map serial ports to TCP/IP connections or emulate 2 and 3 button serial mice. To have a serial port connect to a TCP/IP server use `-r host:port` or open Serial → Port A, fill in the hostname and port and choose "TCP/IP Connect". Or the serial port can listen on a TCP/IP port with `-r @port` or use "TCP/IP Listen" in the serial port dialog box. Most machines have a single serial port, the Model 2 line has two ports accessible on the command line with `-rA` and `-rB`.

trs80gp instances can now be "wired" together through serial ports. The ultimate setup is one trs80gp running Model 16 Xenix with two trs80gp's attached running DT-1 terminals. But here's a simple example of hooking two DT-1 terminal emulations together.

         trs80gp -mdt1 -r :4000
         trs80gp -mdt1 -r @4000

Characters typed on one of the DT-1's will appear on the second one. Assuming everything is working. If it does not work check the "Status" indicator of each serial port. Both sides should note they are "connected". But the "@" side may only show "Listening..." or the other side "Connecting..." both indicating no connection has been made. Or "-unbound-" if there has been some error.

To break a connection unselect the "Enable" checkbox in the dialog box. The other side may not see the loss of connection so you may need to manually manage "unplugging" on both sides. trs80gp is not quite ready to be an internet "dial-up" BBS.

The status will also show the current transmission settings of the serial port. Baud rate, bits per word, parity and number of stop bits. These do not affect TCP/IP connections but the emulation will limit transmit and receive speeds based on port setup. Most original TRS-80 hardware could be set up to have different transmit and receive speeds. That unlikely configuration will be hidden from view. In the Model 2 line the higher baud rate settings are not exact. trs80gp will display the exact baud rate (feature or bug? You tell me).

As a convenience trs80gp can launch DT-1 and Videotex terminals directly from the command line or in the serial port connection dialog. For example, you might launch a two terminal Xenix system with:

         trs80gp -m6000 -h xenix33.cfg -rA :dt1 -rB :dt1

Or you can choose the desired terminal from the dropdown in the serial port connection dialog and then click the "Enabled" checkbox to launch it. Either way, these terminals will act as a unit with the main trs80gp emulator. If you exit the main emulator the terminals will also be forced to exit.

On Linux and Mac a serial port can be hooked up to a hardware serial port by specifying the device name. trs80gp cannot do this on Windows as yet. In most cases:

        trs80gp -r /dev/ttyUSB0

will hook the serial port up to the first USB to serial port converter on the hoat machine. When the emulated machine changes the baud rate or other communication parameters of the emulated serial port they will be propagated to the real serial port.

Serial port devices cannot be opened by most ordinary (non-root) users by default in linux. There are various ways around this problem but one way is to add yourself to the `dialout` group with:

        sudo usermod -a -G dialout $USER

#### Model 1 RS-232 Sense Switches

The Model 1 RS-232 board had 8 DIP switches the manual refers to as "sense switches". These do not directly control the hardware but serve as a way to set communication defaults like the baud rate. Model I programs have the option of reading them to set defaults. On the Model 1 the Serial menu has extra entries to control each switch individually and some convenience menus to set the baud rate directly. The sense switch settings are saved automatically and will appear the same the next time trs80gp is run again in Model 1 mode.

### Recording

The screen display and sound of the emulator can be written to a file using the Record → Flash Video and Record → Video menus the start and stop recording. The window title will flash either `*flv*` or `*avi*` to remind that that recording is in progress. The "Flash Video" option is recommended as the resulting file size is much smaller than "Video"'s uncompressed `.AVI` output.

Use Record → Animated GIF to start and stop recording of the screen in animated GIF format. The window title will flash `*gif*` to let you know GIF recording is in progress. The resulting files are large and not exactly the same frame rate as the TRS-80.

For a screen shot you can use Edit → Copy which copies ASCII text, Unicode and bitmap versions of the screen to the clipboard. Or use the `Ctrl-Alt-C` and `Ctrl-Insert` keyboard shortcuts. You can then paste it in Notepad or Paint (or pretty much anything else).

There is also Record → Screenshot to save the screen display as a GIF image (shortcut: `F11`). Record → Cleanshot or `Shift-F11` will save a clean screenshot (or "cleanshot") that does not have the beam drop-outs as normally appeared on the Model I and Model III.

Audio output can be captured in `.WAV` format using Record → Audio with `*wav*` flashing in the title bar to let you know it is recording. This is fine for sound effects but unfortunately does not work as a way to create files that can be loaded on real TRS-80's. Instead you should rely on the automatic Cassette → Auto Save feature and use my trld program to convert the `.CAS` file to `.WAV` format.

The rest of the Record menu entries are meant for programmers and are documented in the programming section. I will note that Record → MHz Audio records audio files with a very high sampling rate equal to the Z-80 processor speed. Most times you do not need that level of fidelity.

The `-batch` command line option causes all the Record menu entries to save to a specific file name to allow for fully automated testing of trs80gp itself. It also can be thought of as a way for the emulated TRS-80 to act as a batch processor. More on this in the programming section.

### Turbo Mode

trs80gp can be explicitly or manually told to enter turbo mode where the emulated TRS-80 is run faster than real time, sometimes as much as 8 times faster. The entire system and not just the Z-80 is sped up so any virtual I/O between cassette and diskette is not affected nor are any active recordings. It will try to record faster but the resulting recording will be at normal speed. Turn off authentic rendering with View → Authentic Display of the `-na` command line option to let the TRS-80 run a bit faster.

Use the `-turbo` command line option to have it run constantly in turbo mode. Or hold the `F12` key for a temporary speed boost. `shift-F12` will keep turbo mode active without having to hold `F12` and will turn off when you release `F12`.

In order to let you experience the TRS-80 in the best light trs80gp automatically enters turbo mode when doing cassette of diskette I/O. That can be turned off with the Cassette → Auto Turbo and Diskette → Auto Turbo menus.

Normally a turbo mode would cause massive key repeats because your normal typing speed will appear to the TRS-80 as if each key has been held down for a very long time. This is mitigated by trs80gp dropping out of turbo mode whenever a key is pressed. Use Keyboard → Auto De-turbo to turn off this feature if it isn't a problem for your application. Typically games still work fine and you can challenge yourself by playing them at high speed.

At the expense of graphical and timing accuracy the emulator can run up to twice as fast as turbo mode with the `-haste` command line argument (or by using the File → Haste menu item). As the old saying goes, haste makes waste so only use this when speed is vital. Besides only updating the display once per second, "haste" skips wait state calculations which will throw off the timing of a program that accesses the display. Any video capture will also be distorted.

### Display

By default trs80gp starts in authentic display mode. This mode looks most like the original TRS-80 display and scales very well to fit any window size. It is selected with `-va` or View → Authentic Display.

For a less realistic but still scalable display there is View → Sharp Display or the `-vs` flag. In this mode pixels are drawn as tiny rectangles in a single colour rather than the fuzzy dots that are brightest in the middle used in authentic mode.

Since the sharp display doesn't look as good at some scales due to poorer antialiasing there is View → Fixed Sharp Display or `-vi`. While the window can be resized in this mode the display will only use whole number scales (e.g., 1X, 2X, 3X, etc.) to make the display look as sharp as possible.

Finally there is View → Cheap Display or `-vh`. It will scale up in whole number jumps it always maintains a correspondence between TRS-80 pixels and PC display pixels even if the aspect ratio is not the same as the original TRS-80 display. The Model I mode is particularly distorted and the window size will change when a Model 4 switches between 80 and 64 character modes. This mode is mainly of benefit to PCs with small displays or less processing power. It is also useful for testing since the mapping from the resulting pixels to TRS-80 graphics is simpler.

While ignored in authentic mode, `-vN` can be used on the command line to start the emulator at a fixed display scale (e.g., `-v3` for 3X scaling). In any mode `-win WxH` can set the starting window size to W x H.

trs80gp can start in full screen mode (showing no menu bar, window borders or system elements) using `-vf` or `-win full`. Use the View → Fullscreen menu entry to switch to full screen mode at any time or toggle between fullscreen and windowed with the `Alt-Enter` keyboard shortcut. Or use the right-click context menu. Full screen mode is nice for those whose eyesight isn't what it used to be or if you want your PC to feel more like a real TRS-80 instead of an emulation.

The View → Controls dialog allows additional control over the display. There are sliders to adjust the brightness and contrast of the display much like the original TRS-80. It even permits adjustments that leave the display dimmed or brightened beyond readability.

The display colour can be changed from the usual bluish-white to any colour you like with quick presets for Green, Amber and white. Similarly the colour used to show beam conflicts (a programmer feature, more on that below) can also be changed from the default blue. Changes to colours become the default on a per-model basis. I personally like my Model 4 display green and amber for the Model 2. The `-vc` and `-vd` command line options can change the display colour without saving it as a default. Or they can specify the factory default by using `-` as the colour (e.g., `-vc -`).

Under Windows trs80gp remembers the display mode and window positions for each particular model. The windows can be set up just the way you like them and will be in those positions the next time you run. If you run more than one trs80gp emulator for a model at once the second and subsequent instances will have their own set of window positions and display settings. They will also indicate the instance as a `#2`, `#3`, etc. in the window title bar.

#### Beam Debug

View → Beam Debug (or `-bd`) turns on beam debug mode which is used to illustrate when the Z-80 and video circuitry conflict over access to display memory. When this happens on a real TRS-80 the video display will show short black streaks (or white in hires) instead of the actual data displayed. This was most prevalent on the Model I and was colloquially referred to as "screen hash" or "snow" or "raster lines". The Model 3 has this to a generally lesser extent. It should appear in Model 4 hires modes and on the Model 2 but, much to my shame, I have not written that emulation yet.

In "Beam Debug" mode these dropouts are instead coloured in blue to made them even more noticeable but yet show what would have been displayed had there been no conflict in shades of blue. This is very helpful for getting the timing right when development programs that write to the display with very precise timing to increase effective display resolution. For instance, see my bouncing ball demo. Beam debug mode reveals how it secretly writes to the display where it is already black so beam conflict remains hidden from view.

This mode also shows the V-Blank and H-Blank portions of the display as rectangular regions below and to the right of the usual display respectively. Z-80 access to video memory during those times will show up as beam conflicts even though there is no actual conflict. Instead they function as a sort of oscilloscope to show when the Z-80 is accessing video memory. H-Blank or "Horizontal Blank" is the short time when the CRT electron beam is moving from the end of a display line to the start of the next one. V-Blank or "Vertical Blank" is a longer interval when the beam is moving from the bottom of the display to the top.

Beam Debug is not supported by the authentic display mode so if activated it will automatically switch the TRS-80 to cheap display mode.

### FreHD Emulation

The FreHD is a modern-era TRS-80 Model 1, 3 and 4 peripheral which emulates a hard drive using image files on an SD card. It was designed by Frédéric Vecoven in 2013 and is fully open source but most users purchase kits or pre-assembled versions from Ian Mavric. The open source hardware TRS-IO (for Model 1, 3 and 4) also operates in a hardware compatible fashion to the FreHD.

Since trs80gp can emulate a hard drive itself, FreHD emulation just means the other handy features of the FreHD such as the real time clock and access to the host file system for file import and export. It also means you can experience TRS-80 video and test your own FreHD files without needing a real TRS-80 or FreHD.

There are only two FreHD features not implemented. The `VHDUTL` cannot set the clock and you cannot mount floppy disk images through the FreHD using the special `DSK/DTC` device driver.

In most cases all that's needed is to copy the contents of a FreHD SD card to a directory (or simply mount the SD card on your PC) and run:

         trs80gp -m4 -frehd_dir frehd_file_directory

Or use the Hard Drive → FreHD → Directory... menu to accomplish the same thing through the GUI.

FreHD setups often come with patched versions of the TRS-80 Model 1, 3 or 4 ROMs that will boot from the FreHD when the machine is powered on. Normally they will only boot from floppy disk and require a special boot floppy that boots with the hard drive active. Add the `-frehd_patch` option or use Hard Drive → FreHD → ROM Patches to have trs80gp act the same way.

When FreHD emulation is enabled trs80gp will try to connect the image files `hard4-0`, `hard4-1`, `hard4-2` and `hard4-3` in the root of the FreHD directory as hard drives 0 through 3 respectively. But it will only do it when the respective hard drive has no image connected.

The built-in FreHD loader block can be overriden with a custom 256 byte boot block using `-frehd_load file.bin` or the Hard Drive → FreHD → Loader... menu entry. FreHD's auto-boot normally tries to load the FreHD menu from a `frehd.rom` file in the FreHD directory. For convenience, trs80gp has a version of the FreHD menu program built-in and you can activate it with `-frehd_menu` or Hard Drive → FreHD → Built-in Menu.

#### The FreHD Boot Sequence

On a real FreHD changing the loader block requires a rebuild of the firmware. It is far easier to experiment with such changes on trs80gp. However, the FreHD boot sequence is not widely understood so I will go over it in some detail to help anyone debugging or developing for the FreHD.

The Model 4P is the only TRS-80 in the 1,3,4 line that has hard drive boot code in its ROM. A properly configured hard drive image will boot on the 4P without any FreHD auto-start patches to the 4P's 4K ROM.

The FreHD auto-start patches do not add direct hard-drive booting to the Model 1, 3 or 4. Instead, just before trying to boot off the floppy, they load and execute 256 byte FreHD loader block into RAM location $5000. If the space-bar is held the loader block will return to the ROM and the boot will proceed normally. Otherwise, the loader block will then try to load and execute the `frehd.rom` menu program from the SD card. Despite it's suffix, the `frehd.rom` file is actually in `/CMD` format.

The FreHD menu program displays a nice splash screen which includes the version number of the FreHD firmware (as determined by querying the FreHD itself). It then uses the FreHDs extended facilities to list available hard drive images to boot. When the user selects one it instructs the FreHD to mount that hard drive image and proceeds to boot it.

Booting is mostly a matter of loading the second sector from the hard drive into $4300 (or $4200 on the Model 1) and executing it. Before doing so the FreHD menu will write the current time and date into a few locations. Most TRS-80 operating systems will check for a valid date in these locations when they boot and not prompt for one.

Here is where I am not entirely clear on the exact operation for the FreHD menu program. It will also try to make patches to the boot block and perhaps even the operating system itself. I believe the intent of these patches it to allow certain TRS-80 operating system to accept the pre-initialized time and date. There may well be other purposes.

#### Boot Sequence in Depth

Note that you could write your own `frehd.rom` menu program. And in the general sense it could do anything you want. It could just be a game that auto-boots on the FreHD. But if you aim to improve the menu or even make a different loader block then you'll want to consult the source code. And continue reading as I have a few more details on how it all hangs together.

On the Model 3 a fairly short sequence of ROM BASIC commands can be used to mimic the auto-start ROM patch:

         POKE 16912,16
         10 OUT 197,3
         20 IF INP(196)<>254 THEN PRINT"No frehd":END
         30 FORI=0TO255:POKE20480+I,INP(196):NEXT
         RUN
         SYSTEM
         /20480

The same code will work on the Model 4, just change line 10 to output 4. And on the Model 1 don't do the initial `POKE` and change line 10 to output 1. The initial poke turns on `EXTIO` in the shadow register of port $EC. Without that the FreHD will not see accesses to it. Note that the program will not work in Disk BASIC since the POKEs will scramble the extra code loaded by Disk BASIC and crash the program.

Notice that the loader block must start with $FE or it will be ignored by the auto-start patch. That's so the auto-start patch has no effect when there is no FreHD attached. It is actually bytes 1 through 255 of loader block that are put into RAM $5000 (20480). The last byte at $50FF is the first byte which is $FE. The initial `OUT` to port 197 ($C5) serves two purposes. It tells the FreHD to start feeding byte 0 and on of the load block when reads come in on port 196 ($C4). And it outputs that value as byte 2 of the loader block. Since execution begins at byte 1 the loader block must put an instruction there which effectively skips byte 2. As such, loader blocks have byte 1 set to $FE which is the Z-80 `CP A,n` instruction.

This byte is used by the auto-start patch to indicate to the FreHD menu program what type of TRS-80 it is running on. Hence the 1 for Model 2, 3 for Model 3 and 4 for Model 4. The Model 4P auto-start patch puts in a 5.

If the loader block cannot find a `frehd.rom` file on the SD card it will simply return and the TRS-80 will boot as normal.

Once the FreHD menu program is loaded it will load the model number from location $5001. Initially it uses the model number to decide if it should use the ROM routine to read the keyboard (1, 2, 3, 4) or its own keyboard scanning for model 5, the 4P. It then scans the root directory of the SD card looking for hard drive image files in HDV format. A file must start with the bytes $56 $CB, have bit 0 of byte 8 set (indicating autoboot) and byte 11, the OS type must be one of:

         0 for LS-DOS 6.3.1
         1 for LDOS 5.3.1
         2 for CP/M
         3 for Newdos 2.5
         4 for Model I LDOS 5.3.1
         5 for Model I NEWDOS 2.5

trs80gp's built-in FreHD menu also experimentally accepts 6 for MULTIDOS. Files meeting these criteria will be listed for the user to select but with one more condition for model number 5 (Model 4P). An OS type of 1 or 3 will only be listed if a 'modela.iii' is on the SD card. That's because those are Model III OS's and will only work on the 4P if the ROM image has been loaded.

As mentioned before, once an image is selected it will be mounted as hard drive 0 and the menu will kick off the boot by loading sector 2 from the hard drive into $4300 (or $4200 if the model number is 1).

It will also write the current date and time into one or more memory locations depending on the model number and OS type. This will make most TRS-80 operating systems skip prompting of the date and time as they are already initalized.

Before executing the boot block the FreHD menu system may patch the hard drive boot block (or even, I think, some of the code loaded by the boot block) for unclear purposes. I suspect it is to allow some of the OS's to accept an initialized date. And maybe even patch the OS to load from the hard drive instead of diskette. The menu will also load the `modeala.iii` from the SD card on the Model 4P if the OS type is 1 or 3 so those Model 3 operating systems will work on a 4P which does not have the necessary BASIC ROM to support them.

After that the FreHD system is out of the picture and the operating systems boots as it would off a regular hard drive.

The diligent programmer can make use of the various memory locations and I/O ports to set breakpoints to inspect the boot process at any point in its various steps. Special FreHD operations such as opening and reading files on the SD card are recognized and displayed clearly in the bus trace allowing a high level view of what a program is doing with the FreHD.

### Scripting

Options like `-icmd`, `-menu` and `-cmd` take a command or list of commands as a parameter. A command may be a single word like `reset` which will reset the emulator. Or it can be a list, for example `[ poke 3c00 45 ]` which puts an "A" in the top left of the Model 1 screen. The square brackets may also be used to create a list of commands. For instance, `[ [ poke 3c00 45 ] [ poke 3fff 5b ] ]` is two commands which put "A" in the top left of the Model 1 screen and "Z" in the bottom right.

The `-ib file` option takes a script file which is a series of commands, one per line. Here are the two `poke` commands in a file:

         poke 3c00 45
         poke 3fff 5b

If the file starts with `#!` then it will be recognized as a script and its commands will run if passed directly on the command line or dragged and dropped onto the main window.

On Linux and MacOS trs80gp can be used as a script processor using the usual `#!` (hash bang) file start. For example, if trs80gp is in /user/george/trs80gp then this script will launch it emulating the Color Computer and have the software keyboard and debugger start up.

        #!/user/george/trs80gp -mc
        postmsg debug
        postmsg soft_keyboard

Unix only allows a single command line argument which we use up specifying the model to emulate. A mechanism to provide more command line arguments in this case is planned.

Generally speaking commands will alter the state of the emulator machine or the emulator itself. Here is a list of all the commands for reference each linked to their full description.

- input - change automated input injection method
- poke - put byte data into memory
- pokew - put word data into memory
- pokestr - put strings into memory
- pokefile - put raw file data into memory
- postmsg - operate the emulator user interface
- reset - reset the emulated machine

#### input command

`input`

Changes the input mode for automated input.

#### poke command

`poke`
address-set value .. value

Set one or more memory locations to the given values. If address-set can be a single memory location values are put there and in following addresses until they are used up. If it is a range then the values are repeated until the entire range is filled. If there are no values then the entire range is filled with zeros. The address-set can be multiple comma-separated ranges. Values may be hexadecimal or symbol names. By default data is put into the memory space view of the main processor. The optional argument can select different memory spaces like `-ram` for the main random access memory or `-vram` for the display.

`poke 3c00 21` will put a `!` in the top left of the Model 1 or 3 screen.
`poke 3c00:3fff 21` will fill the screen with `!`.
`poke -vram 0:200 41` will fill the top half of the screen with `A`

#### pokew command

`pokew`
address-set value .. value

The same as the poke command except that two byte word values are poked into memory. These values will be poked with the correct endian for the CPU the TRS-80 uses. Little endian for Z-80, Z-180 and 8080, Big endian for 6800, 6803, 6809 and 68000.

#### pokestr command

`pokestr`
address-set string .. string

The same as the poke command except that the strings are poked into memory. The strings can have escape codes such as `\xFF`.

`poke -vram 0:3ff Hey!` fills the screen with `Hey!`

#### pokefile command

`pokefile`
address-set file .. file

As with poke but the contents of one or more files are put into memory. The files are loaded as raw data unlike the (upcoming) `load` command which interprets `/CMD` files and other binary executable formats.

#### postmsg command

`postmsg`

Sends a message to the user interface. Messages have various effects, usually popping up a dialog box or choosing a setting.

Ultimately this command should be replaced with sets of better controlled commands to trigger the various UI elements and settings. But it is too irresistable as it is easy to implement and powerful.

A full reference needs to be written up but some of the more useful ones are:

- soft_keyboard - bring up the software keyboard
- debug - bring up the debugger window
- exit - exit trs80gp
- copy - copy the screen to the clipboard
- paste - paste the clipboard as input
- printer - bring up the printer window
- source_code - bring up the source code window

#### reset command

Causes a warm restart of the TRS-80.

### Events

Events are messages sent to the event endpoint (`-event` or Debug → Event...) about various emulated physical devices like the drives, cassette or keyboard. You might want to watch them for high-level debugging or send them to a program which blinks real LEDs or something.

Event messages are send one per line and are simple ASCII text:

dN
  Floppy drive N is now active. `d-1` means no floppy drive is active.
sN
  The active floppy drive has seeked to track N.
hN
  Hard drive N is now active. `h-1` means no hard drive is active.
eN
  The active hard drive has seeked to track N.
c1
  The cassette relay has turned on.
c0
  The cassette relay has turned off.
p1
  Data is being send to the printer.
p0
  No data is being send to the printer.
kRCS
  The key at row R and column C has been pressed (S=1) or released (S=0). For example, if the `A` key is tapped on a Model 1 a `k011` message will be sent followed closely by a `k010`. See the keyboard matrices below for how to map row and column numbers to keys for each model.
r1
  The reset button has been pressed.
r0
  The reset button has been released.

#### Keyboard Matrices

Not all models have keyboards and others like the DT-1 and Model 2/12/16/6000 family are not yet emulated at the keyboard matrix level. These models do not generate keyboard events.

Model I Keyboard Matrix

| Column
--- | ---
Row | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
0 | @ | A | B | C | D | E | F | G
1 | H | I | J | K | L | M | N | O
2 | P | Q | R | S | T | U | V | W
3 | X | Y | Z
4 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
5 | 8 | 9 | : | ; | , | - | . | /
6 | Enter | Clear | Break | ↑ | ↓ | ← | → | Space-Bar
7 | Shift

Model III Keyboard Matrix

| Column
--- | ---
Row | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
0 | @ | A | B | C | D | E | F | G
1 | H | I | J | K | L | M | N | O
2 | P | Q | R | S | T | U | V | W
3 | X | Y | Z
4 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
5 | 8 | 9 | : | ; | , | - | . | /
6 | Enter | Clear | Break | ↑ | ↓ | ← | → | Space-Bar
7 | Left Shift | Right Shift

Model 4 Keyboard Matrix

| Column
--- | ---
Row | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
0 | @ | A | B | C | D | E | F | G
1 | H | I | J | K | L | M | N | O
2 | P | Q | R | S | T | U | V | W
3 | X | Y | Z
4 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
5 | 8 | 9 | : | ; | , | - | . | /
6 | Enter | Clear | Break | ↑ | ↓ | ← | → | Space-Bar
7 | Left Shift | Right Shift | Ctrl | Caps | F1 | F2 | F3

Japanese Model I Keyboard Matrix

| Column
--- | ---
Row | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
0 | ﾟ @ ﾞ | A ﾁ | B ｺ | C ｿ | D ｼ | ｨ E ｲ | F ﾊ | G ｷ
1 | H ｸ | I ﾆ | J ﾏ | K ﾉ | L ﾘ | M ﾓ | N ﾐ | O ﾗ
2 | P ｾ | Q ﾀ | R ｽ | S ﾄ | T ｶ | U ﾅ | V ﾋ | Wﾃ
3 | X ｻ | Y ﾝ | ｯ Z ﾂ | 0 | 1 | 2 | 3 | 4
4 | ｦ 0 ﾜ | ! 1 ﾇ | " 2 ﾌ | # ｧ 3 ｱ | $ ｩ 4 ｳ | % ｪ 5 ｴ | & ｫ 6 ｵ | ' ｬ 7 ﾔ
5 | ( ｢ 8 ﾕ | ( ｮ 9 ﾖ | * ｢ : ｹ | + ; ﾚ | < ､ , ﾈ | = - ﾎ | > ｡ . ﾙ | ? ･ / ﾒ
6 | Enter | ｣ clearﾑ | Break | ↑ | ↓ | ← | → ﾛ | Space-Bar
7 |  | ｰ ¥ ﾍ | 5 | 6 | 7 | 8 | 9 | .
8 | Shift
9 | 英数 カナ

Note the keys marked 0 .. 9 and . are on the numeric keypad which can be read independently on the Japanese Model I. The numeric keybord is wired in parallel with the main keyboard on the original Model I (and 3 and 4).

Videotex/CoCo matrix

| Column
--- | ---
Row | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
0 | @ | A | B | C | D | E | F | G
1 | H | I | J | K | L | M | N | O
2 | P | Q | R | S | T | U | V | W
3 | X | Y | Z | ↑ | ↓ | ← | → | Space-Bar
4 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
5 | 8 | 9 | : | ; | , | - | . | /
6 | Enter | Clear | Break |  |  |  |  | Shift

MC-10 Keyboard Matrix

| Column
--- | ---
Row | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
0 | @ | A ▚ | B | C ▖ | D ▟ | E ▜ | F ▞ | G ▐
1 | H | I | J | K | L | M | N | O
2 | P | Q █ | R ▀ | S ▘ | T ▙ | U | V ▗ | W ▛
3 | X ▄ | Y ▌ | Z ▝ |  |  |  | Enter | Space-Bar
4 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
5 | 8 | 9 | : | ; | , | - | . | /
6 | Control |  | Break |  |  |  |  | Shift

### Programming

Whether you're writing programs for the TRS-80 or simply wish to dissect existing programs trs80gp has much to offer. As such this section is rather brief on details. Please do get in touch with me if you have questions.

#### Running Programs

Normally on a TRS-80 programs are run either as `/CMD` files at the TRS-DOS prompt or loaded from cassette with CLOAD or SYSTEM commands. This is the best way to test programs you write but only needs to be done as a final test. For development trs80gp will directly load programs from the command line or via the File → Run... menu or via drag and drop. This is largely similar to standard procedure but does has its differences. Existing TRS-80 games often work well when run directly but there's no guarantee.

Files that start with `#!` are considered to be script commands. When given on the command line they operate almost identically to `-ib file` except the commands will be done after all other command-line automated input. The File → Run... menu or dragging and dropping the file will also execute the commands in the script.

#### Batch Mode

Activate batch mode using the `-batch` command line option. In this mode many operations (most in the Record menu) will not prompt for a file name but will instead simple write the file to some fixed file name. This may seem odd but is very useful for testing your programs or trs80gp itself. One way to use this is to have your program write status information to the printer (out $F8 will do on Model 3,4) and use the emulator extensions to make trs80gp exit. You can then run it using:

         trs80gp -m4 -ee program.cmd

And it will go through its paces writing output to `trs80-printer.txt`. If trs80gp doesn't exit then you know your program went wrong.

In batch mode many of the menu entries switch to saving files without prompting. In most cases those files are named in sequence starting with `file-0.txt`, `file-1.txt` and so on. Those are represented by `file-%d.txt`.

Menu | Output file(s)
--- | ---
Bus Use | bus-use-%d.txt
Backtrace | backtrace-%d.txt
Text VRAM | trs80-text-%d.bin
Character Generator VRAM | trs80-char-%d.bin
Graphics VRAM | trs80-graphics-%d.bin
RAM | trs80-ram-%d.bin
RAM16 | trs80-ram16-%d.bin
Expansion RAM | trs80-expram-%d.bin
XLR8er RAM | trs80-xlr8er-ram-%d.bin
Cassette → Auto Save | trs80-cassette-%d.bin
Audio | trs80-%d.wav
MHz Audio | trs80-%d-mhz.wav
CPU Profile | profile-%d.txt
Trace | bus-trace-%d.txt
Flash Video | trs80-%d.flv
Video | trs80-%d.avi
Animated GIF | trs80-%d.gif
Screenshot | trs80-%d.gif
Printer | trs80-printer.txt
Diskette (on exit) | trs80-drive%d-%d.dsk
Hard Drive | trs80-hard-disk-%d.dsk
Wafer (on exit) | trs80-wafer%d-%d.tape

It is worth re-iterating that automated input options are tantamount to scripting control over the emulated TRS-80 and can be used to build up automated tests of your TRS-80 programs.

#### The Z-80 (and other CPUs) Debugger

To keep this section concrete it often refers to the Z-80 debugger. But rest assured there is also full 6800, 6803, 6809 and 68000 debuggers in trs80gp.

The Z-80 debugger may be activated at any time using Debug → Z-80 Debugger... It will also come up automatically when a breakpoint is hit. Breakpoints can be set interactively in the debugger window in the section just below the "Go" button. A breakpoint can be at a single address or cover a range of addresses using "addr1:addr2" syntax. Make sure to tick the checkbox next to the address/label to enable the breakpoint. PC breakpoints can also be toggled by double-clicking a line in the Disassembly sub-window.

You may set up to 4 breakpoints of each type. A "PC Breakpoint" is the traditional kind which is triggered whenever a program executes in the given address range. Other types trigger whenever memory is read or written in the range or I/O is performed. These types are useful to find when particular variables are changed or accessed and finding when devices are accessed.

Breakpoints may also be set on the command line by the `-b`, `-bm`, `-bio` and related options. For Z-80 machines use `-b 0` to start the debugger immediately at machine startup or reset. On 6800, 6803 and 6809 machines use `-bmr fffe` to achieve the same effect.

A `>` appears in the disassembly window to indicate the next instruction to execute and an asterisk (`*`) to show any active PC breakpoints.

Memory and I/O breakpoints show extra information in the debug window when they are triggered. The Disassembly sub-window will show a `!` to indicate the instruction that caused the fault and additional letter codes indicating what kind of fault or faults occurred. The `>` will point to the next instruction to execute as usual.

           R      Read protected memory
           W      Write protected memory
           E      Execute protected memory
           S      Stack protected memory
           I      Input protected I/O
           O      Output protected I/O

The debugger window title will indicate the CPU has stopped, give the memory or I/O address involved and the breakpoint that triggered the stoppage, if any. Programs loaded in `.bds` form come with memory protection and the debugger will show "`.bds file`" as the source of a fault. Or "`program`" if the program itself set up protected memory with emulator extensions.

Various sub-windows show the current Z-80 register contents with them displayed in red if they changed during the previous step. All values are displayed in hexadecimal except for the T-state and cycles counters. There is also a view of the top of the stack and a T-state counter which can be changed as desired to measure intervals interactively.

The Step button moves execution forward a single instruction. Step Over sets a breakpoint after the current instruction and resumes execution. This is useful for `CALL`s to run quickly though a subroutine. Grizzled Z-80 programmers know there's no guarantee a `CALL` will return right after itself so caveat emptor. "Go" resumes execution until the next breakpoint or protection violation. The "Emulator Extensions" checkbox may be turned off to disable protection checks.

When single stepping the display will turn gray to give an indication where the CRT beam is at that moment in execution. There are also boxes in the lower left which give the CRT beam raster Y and X coordinates. The debugger is still operational when the TRS-80 is running. You can change registers and memory locations which will show a light-blue background to indicate you've frozen your view of them so you may change it.

Since the screen shows the contents of the previous frame and the drawing of the current frame you will not usually see an immediate change when writing to screen memory. It only shows up when the CRT beam reads and draws it. The debugger memory view gives you the ability to see immediate changes to the various different RAM systems. The defaults is "Z-80 Memory" which shows the Z-80's view of its 65536 memory locations. In the Model 1 and 3 this will show the BASIC ROM in the first 12 or 14 K or memory, the keyboard matrix from $3800 to $3BFF, the video RAM from $3C00 to $3FFF and ordinary RAM from $4000 up to $FFFF or less if a value lower than 48 was given to the `-mem` command line option. There may be no memory for some of the address space (e.g., $3000 .. $37FF on the Model I). Such regions will display as `~ff` (or `~00` on the Model II) and cannot be changed.

You can also select just the RAM to focus on the 48K of memory. But keep in mind these other views use their own addressing. The RAM view starts at 0 but that is seen (by the Model 1 and 3) as starting at $4000. The amount and type of each varies depending on the Model but you'll typically see Text VRAM for the usual character display, and Hires VRAM for the high resolution graphics option (which is usually only accessible to the Z-80 through I/O ports).

You can search through memory by typing a string into the search box. The usual backslash escapes can be used for control and graphics characters: `\n`, `\r`, `\t` and `\HH` for any hexadecimal value. If the string starts with `$` then the rest is taken to be hexadecimal digits with spaces ignored. The `<` and > buttons cycle through the matches which are highlighted in the memory window below.

In a clunky way RAM can be changed. The easiest approach to to select a memory byte and write a new hexadecimal value for it. The emulator simply reads back the memory dump so you can also delete a line and enter any address followed by a colon and a series of space-separated hexadecimal bytes to change memory locations without having to look at them.

A few pseudo-memory regions are viewable but not changeable. They are intended to give a partial view of the TRS-80 hardware state.

       Z-80 Device        What the Z-80 would return if an I/O were read.
       Z-80 Port Writes   The last value written by the Z-80 to a port.
       Z-80 Port Reads    The last value read from an I/O port by the Z-80.

At the bottom of the window are line of check boxes and drop-downs to control bus tracing which is discussed later.

Most of the Z-80 register state shown is familiar to Z-80 programmers and can be directly altered by Z-80 programs. The `IFF1` checkbox is checked when interrupts are enabled (by an `EI`) instruction and not when they are disabled by a `DI` instruction or entry into an interrupt routine. Relatedly, `IM` shows the interrupt mode of the processor which pretty much has to be 1 for Model 1, 3 and 4 computers and 2 for the Model 2 line. The `I` register is mostly only relevant in interrupt mode 2.

Other state is not directly accessible and pretty much just showing off how accurate trs80gp's Z-80 emulation is.

`WZ` is an internal temporary register used by Z-80 during various 16 bit operations. In an officially undocumented but reliable quirk of implementation bits 3 and 5 of this register are put into bits 3 and 5 of the flag register `F` whenever a `BIT` test is done on `(HL))`. Early investigators of this called the register MEMPTR. Google "Z80 MEMPTR" or try this link to learn more.

`EXX`, `AFAF'`, `DEHL` and `DE'HL'` show the state of internal flip-flops that select different banks of registers when `EXX`, `EX AF,AF'` and `EX DE,HL` instructions are executed. Effectively they show the number of times modulo 2 each instruction has been executed but the Z-80 program and trs80gp's Z-80 debugger show the currently active sets are you would expect.

The dropdown shows special Z-80 processor states and will spend 99.999% of its time in `Normal` mode. The other modes are:

- IntrDis - An `EI` instruction was just executed so the Z-80 will not respond to a maskable interrupt until the next instruction finishes execution.
- Halt - The Z-80 has executed a `HALT` instruction and will not resume execution until an interrupt occurs. During this time it will continue to fetch and ignore the opcode of the current instruction.
- Pfix, PfIy - The Z-80 is in the middle of a series of `$DD` and `$FD` bytes. The Z-80 only pays attention to the last byte in such a series to determine if it has an `IX` ($DD) or `IY` ($FD) instruction. The Z-80 cannot be interrupted during this processing but for practical reasons trs80gp breaks such sequences down to a progression of artificial `pfix` and `pfiy` instructions.
- PostIff2 - The Z-80 has just executed a `LD A,I` or `LD A,R` instruction which will read the wrong value of `IFF2` if an interrupt occurs at the same time as the instruction. This is to emulate a Z-80 bug and, unlike the others, does not correspond to a real internal state latch.

The debugger also provides a sub-window for watching expressions. For each expression you choose what result to show: The memory byte or word at the calculated value, or the value itself (or the high/or low byte of the value)

Expressions use C-like syntax consisting of:

- Decimal constants (use `$` or `0x` to prefix hexadecimal constants)
- Parenthesis to control order of evaluation
- C number operations: `+ - * / %`
- C bit operations: `! ~ << >> & ^ |`
- C comparisons: `== != < > <= >=`
- C logical and/or: `&& ||`
- Register names: e.g. `A B C AF HL IX AF'`
- Register flags: e.g. `F.C, F.N`
- Source code symbol values (if loaded)

There is a special syntax for reading memory inside an expression. The expressions `(expr)b` and `(expr)w` return the value of the byte or word at the memory location inside the expression.

#### Source Level Debugging

My zmac cross assembler will output machine language programs in `.bds` format. It is a text format so by looking at it and the zmac source code you can probably figure out how to generate it yourself. But the important part here is that loading `.bds` files from the command line will enable source level debugging.

Use Debug → Source Code to bring up the source code that has been loaded. It will look a bit like an assembler listing file. The current program location will be highlighted and follow the execution of the Z-80.

The format also defines symbolic labels so you can type these labels in to the breakpoint or register windows instead of having to look up the hexadecimal values yourself. You can also use labels for the `-b` and other command line option to set breakpoints.

In certain situations you may want to have symbols available for a program but don't wish to load it into memory. The `-ls` command line option and File → Load Symbols... menu entry are used to only load the symbols from a `.bds` file. Doing so allows you to use symbolic names in the debugger but does not alter RAM contents in case the program is already underway.

Some models have built-in symbols and source code which are automatically loaded. While often helpful this sometimes gets in the way of debugging programs. Use the `-nrs` option or File → Unload Symbols to stop this. Though "Unload Symbols" will drop any other symbols or source code you have loaded.

trs80gp also uses the memory protection information in `.bds` files to trigger breakpoints if your program attempts to overwrite itself, read program memory or execute data. If the program runs out of control it will at least trigger a breakpoint before it has destroyed itself making it easier to recognize and track down the problem.

This can get in the way if your program intentionally modifies itself. For example, this oode saves `HL` to an `HL` load instruction.

              org   $8000
       start: ld    (save+1),hl
              ; ... use HL but just a NOP for now
              nop
       save:  ld    hl,0
              jr    $
              end   start

Running the `.bds` version of the program will cause it to stop at the `NOP` because the previous instruction tried to write to its code. You can work around this problem by checking and unchecking the "Emulator Extensions" in the debugger window. It has the side effect of disabling the `.bds` memory protection.

The proper fix is to tell zmac that the last two bytes of the of the `ld hl,0` instruction can be treated as data. The idiom for this is to assemble both code and data at that location:

              org   $8000
       start: ld    (save),hl
              nop
              ld    hl,0
              org   $-2
       save:  defw  0
              jr    $
              end   start

The makes the code is a bit better. There isn't a magic `+1` added to `save`. When looking at `save` the use of self-modifying code is explicit. Though obvious in this simple example it would not be apparent in large program.

#### Disk Viewer

Under the Debug menu there is a Disk Viewer which allows you to browse through all the floppy and hard drive images inserted and examine their data. There is a search feature to look for strings or binary data. The usual backslash escapes can be used for control and graphics characters: `\n`, `\r`, `\t` and `\HH` for any hexadecimal value. If the string starts with `$` then the rest is taken to be hexadecimal digits with spaces ignored. The `<` and `>` buttons will cycle through all the matches.

Use the drop downs to select disk images, sides, tracks and sectors. The sector dropdown presents both the physical and logical sector numbers. The logical number is the value written on the disk and is what is used when we generically refer to reading or writing sector N. The physical number is the relative position of the sector in the track.

#### Device Map

The debug menu also features the somewhat experimental "Device Map" feature. It gives you a quick overview of the current mappings of Z-80 address and I/O space to RAM and devices. In short, something like the typical memory map seen in programmer guides. Do keep in mind that it shows the mapping when it was brought up. If the program subsequently switches memory maps the window will not be updated.

The feature is experimental mainly because it doesn't yet display all the emulator implicitly knows about the address space. For example, the Model I does not have any memory mapped from $3000 to $36FF but the map will display that as read-only RAM. And it says nothing at all about the memory mapped printer and floppy disk devices accessible in the $3700 - $37FF range. In other words, the map can be incomplete or misleading. But it seems more handy having it around even with its current shortcomings.

#### Advanced Recording

Sometimes examining memory in the debugger is too cumbersome. The "Text VRAM", "Graphics VRAM", "RAM", "RAM16" and "Expansion RAM" entries in the "Record" menu will save those RAM areas to a file where you can use external tools to do a more thorough analysis.

The normal recording options can assist debugging. It may be helpful to step through a video a frame at a time to see some graphical glitch in detail. The "MHz Audio" option takes this to the extreme by recording audio output a sample rate equal to the speed of the Z-80. In effect this lets you see exactly when the audio changes.

The Trace option is the most useful so I've dedicated section to it. The other options attempt to self-document in their output. Unlike the Trace option these other options don't record everything. Typically they'll just track the PC values to keep overhead low. When they do their final output the use whatever value is in RAM at the time for the disassembly. If the program changes you may seen confusing output. This gets even worse if the memory mapping changes.

All these recording options can be activated and stopped at any time. It is useful and often desirable to start them when the program is stopped in the debugger and then stop them at the next breakpoint after an interesting subroutine or full step of a game simulation has run.

Record → Z-80 Profile tracks every instruction executed and shows you a list of those instructions, the number of times each instruction was executed and the total T-States spent on each instruction. It is intended to help measure where your program spends its time to be used as a guide for optimization. It can also be used to simply track what a program as done during an interval. However, "Bus Use" is better for that task and Trace will show every instruction in order.

Record → Backtrace show the last 65536 instructions executed. In theory you can use this to respond to a crash. But practically speaking that many instructions is at most a tenth of a second so you're not likely to be quick enough to catch it.

Record → Bus Use tracks the execution of a program. The output is much like a disassembler but with markup indicating how memory was accessed: read, written, executed, jumped to, called and so on. The disassembly tends to be better than a static disassembly since it uses the Z-80's execution path to point out what is code and what is data.

The disassembly will be entirely commented out except for any areas where a program was loaded by the command line (or using File → Load/Run) into memory. The intent here is to distinguish the loaded program from the ROM or operating system routines it uses. If the program is sufficiently put through its paces the result should be a good disassembly that can be assembled to produce the original code. Unlike the other trace options any data uncommented in the disassembly is based on the original data loaded so it won't be fooled by simple self-modifying code. However, this is a problem if the program relocates itself. In which case you'll have to get a relocated version of the program loaded. At least "Bus Use" will help understand the relocator code.

#### Emulator Extensions

These are enabled by the `-ee` command line option. They can be turned off using the "Emulator Extensions" checkbox in the Z-80 Debugger. A Z-80 program accesses them by sending a function code to I/O port $47. Here is a brief overview:

         0     Set bus permissions for address HL to DE to B
         2     Trigger bus fault B
         3     Disable (B=0) or enable (B=1) bus permissions
         4     Trigger execute fault (i.e., drop into the debugger)
         5     Reset (B=0) or get (B=1, into DEHL) T-state counter
         6     Control recording
                  B=$41 - toggle audio recording
                  B=$4D - toggle Mhz Audio recording
                  B=$47 - toggle animated GIF recording
                  B=$46 - toggle Flash video recording
                  B=$56 - toggle video recording
                  B=$53 - take screenshot
                  B=$47 - take cleanshot
       64..127 Set parameter (see below)
         128   exit emulator with return code BC
         255   set carry flag (to detect if extensions active)

Function 5 allows for automated profiling of Z-80 code. Function 128 is typically used to end a test in batch mode. The bus permissions are very helpful in tracking down nasty bugs. For example, you can set your code section to execute-only. The emulator will trap into the debugger the instant something tries to overwrite over your code. Or even read it. Another useful technique is turning off stack permissions at the bottom and top of your stack to detect stack overflow or underflow.

For function 0 the lower 7 bits in B are set to indicate what Z-80 operation is allowed on that memory location. Or for the first 256 addresses what I/O operation is allowed on a port. Those bits are:

       Mask    Operation  Z-80 Debugger letter indicator
         1     Read       R
         2     Write      W
         4     Execute    E
         8     Stack      S
         16    In         I
         32    Out        O
         64    DMA        D

Stack permission is required for CALL, RET, PUSH, POP, RETI and RETN.

##### Using Emulator Extensions in BASIC

For BASIC where `OUT` is readily available but setting register contents is difficult there a way to trigger any function with just OUT commands.

`OUT 71,32+n` will trigger function `n` using whatever parameters were previously set. A parameter is set by first doing an `OUT 71,64+p` where `p` is the parameter number and then doing `OUT 71,x` to set the value. If a command requires a register then the parameter triggered version of the command will read parameter 2 for register B, parameter 3 for register C, parameter 8 for H and so on. Or put another way, you select the parameter for register R by sending the ascii value of the register letter.

For example, this will toggle animated GIF recording:

        OUT 71,66:OUT 71,71:OUT 71,32+6

`INP(71)` is used to get results from emulator extensions. Only detection (code 255) and T-state counter read (code 7, B=1) return results. Here is a simple Model III example that checks the emulator extensions are installed. If so, it then reads the number of T-States to execute the little `FOR` loop and shows them as a raw value and translated to milliseconds.

    10 OUT 71,255:IF INP(71)<>1 THEN ?"You forgot -ee":END
    20 OUT 71,66:OUT 71,0:OUT 71,37
    30 FOR I=1 TO 10:NEXT
    40 OUT 71,66:OUT 71,1:OUT 71,37
    50 T=0:FOR I=0 TO 3:T=T*256:T=T+INP(71):NEXT
    60 ?T;"T states";T/2027.52;"ms"

#### Bus Trace

The Record → Trace feature is a very powerful and comprehensive tool for debugging Z-80 programs and the emulator itself. It can log every instruction executed, memory access, interrupt and I/O port access the Z-80 or any DMA device does. It also places markers in the output file to indicate when a frame has ended and when one second of execution has finished. It can be activated a program start with the `-trace` option. The full log is recorded in the output file. The last frame or two of the log can be viewed using Debug → Trace Log...

The output can be voluminous. You'll want to use breakpoints to turn tracing on and off for as short a period as possible. The "Tracing" checkpoint in the Z-80 Debugger is a convenient shortcut. And there are additional check boxes to enable or disable tracing for Z-80 instruction, I/O accesses, memory accesses and interrupts.

For even finer control I/O logging can be enabled on a per-device basis. This is handled by the device drop-down. The interface is awkward. As you select each device in the drop-down the checkmark to the right changes to indicate if that device is being logged. But you still must check the I/O box to enable I/O logging. To make it more confusing but usable the best course is to turn I/O off, select the device you're interested in, enable it and then turn I/O back on. If you turn I/O on first it will enable all devices by default.

Yes, it's bad but at least it gives some way to target particular devices. Obviously these controls should be in some other window but the debugger happened to be handy at the time. trs80gp wasn't built in a day.

The actual logging looks something like this:

       8033317 @3018 z ex       jp     $35c2
       8033327 @35c2 z ex       push   af
           +11 @35c2 z wr _ffb4 00 ram[ffb4]
           +11 @35c2 z wr _ffb3 44 ram[ffb3]
       8033338 @35c3 z ex       in     a,($e0)
           +11 @35c3 z in _e0 fb
       8033349 @35c5 z ex       rra
       8033353 @35c6 z ex       jp     nc,$3365
       8033363 @35c9 z ex       rra
       8033367 @35ca z ex       jp     nc,$3369
       8033377 @35cd z ex       push   bc
           +11 @35cd z wr _ffb2 38 ram[ffb2]
           +11 @35cd z wr _ffb1 80 ram[ffb1]

The first column is the T-State counter. The second is the PC of the Z-80 when the operation occurred. Next a letter code shows the device responsible ('z' for Z-80 and 'd' for DMA chip). The type of access follows. Most are "ex" for instruction execution with a disassembly of the instruction following. But for reads, writes, ins and outs (rd, wr, in, ot) the memory or I/O address is shown followed by the value read or written. Other possible operations are:

         ht     Fetch during Z-80 halt
         i0     Interrupt mode 0 bus read
         i1     Interrupt mode 1 bus read
         i2     Interrupt mode 2 bus read
         ni     NMI (non-maskable interrupt) bus read

After any access there may be a description of what the value means to that device and possibly the internal state of the device. A good example is the CRTC video controller chip used in the Model 2 and 4. An I/O write (out) to its address register will be annotated with the name of the register selected. An I/O write will show the name of the register changed and its current value. Some devices are very simple in that any byte read or written can only have one meaning. But for the CRTC a write to a register depends on which register was previously selected. Without the annotation you would have to search backwards for the last register selection. And if the register is 16 bits wide you'd also have to look back for the last time that other 8 bits were changed. This is tedious and may not even appear in the bus trace you've made.

Not all devices provide annotations. If they do then you can bet they were giving us trouble in developing the emulator. Most of the Model 2 devices have annotations.

By the way, the underscore and @ signs in front of addresses are intentional and useful. vi (and maybe other editors) make it easy to search on words. So starting a search on _ffb2 will only find other references to that memory location being read or written. But searching the word ffb2 will find instructions that reference the address. Or you can search for @ffb2 explicitly to restrict your search to only instructions executed at that address.

### DT-1 Terminal

The TRS-80 DT-1 (Data Terminal 1) is not a computer but a terminal and as such can do very little without being connected to a computer. It does have a built-in SET-UP screen that needs the DT-1 User's Manual to be understood. Do note that you must press Page-Up on trs80gp to access the setup screen as Ctrl+Shift+Enter will not work. And if you're in the setup screen use Page-Down to show "KL" on the screen rather than pressing Ctrl+Shift-4. Since it has no obvious purpose, the "KL" display is assumed to be an easter egg. Perhaps the initials of the firmware programmer.

The trs80gp Setup menu provides all the functionality of the DT-1 SET-UP screen in a somewhat more descriptive format. It will also change the SET-UP screen if you're in it so you can learn the cryptic settings. Use Setup → Duplex → Half to put the DT-1 into a mode where you will see each character you type. If you're feeling really adventurous type `<ESC>G2Blinking<ESC>G0text` to see some blinking text.

trs80gp's DT-1 emulation is missing a few features of the original. There's no way to attach a printer, not all input keycodes can be generated, there's no half-intensity text mode and no beep. If you have a real DT-1 please get in touch as a few tests could go along way to implementing the missing features.

### TRS-80 Videotex

The TRS-80 Videotex terminal was an early foray into online information access. It had a 300 baud modem allowing it to get the latest news and information. The built-in software is very minimal and trs80gp itself hasn't been polished enough yet to help round off the rough edges.

The Videotex could run in an offline mode. It lets you enter pages of text and it was possible to later upload that data to an online service. To experience this, run `trs80gp -mv` or use File → Change Model → Videotex. Press almost any key (except escape) and you'll be entering text in the offline mode. Take time to be amazed that it word-wraps text as you type.

If you press escape (which is the emulated BREAK key) it will then prompt you with "PLACE CALL". On the real machine you'd pick up your phone, dial the information service. When in answered you'd put the phone down and press ENTER to let it know you're connected.

When you hung up the phone (or the server hung up) the terminal will print `OFF LINE` indicating this. There was also an LED, I gather. There must be some way to proceed from this point but either I don't know what it is or trs80gp doesn't quite emulate it yet. You can reset the emulator if necessary. You can use another terminal to act as the online service. See the Serial section for general information on how to virtually hook up two trs80gp emulators. Here's a quick rundown of how to see it in action.

1. Start a Videotex with a DT-1 attached: `trs80gp -mv -r :dt1` (or select "DT-1 Data Terminal" from the dropdown in the Serial port dialog box and click the "enable" checkbox).
2. Press escape on the Videotex to see the "PLACE CALL" prompt.
3. Wait a second or two.
4. Press Enter on the Videotex.
5. Typing in the Videotex should now cause characters to appear on the DT-1 side and vice-versa.
6. Not really a step, but you can use paste on either one as another way to enter text.
7. Close the DT-1 window and see the Videotex say "OFF LINE".

You may find the Videotex manual and technical documentation helpful. It does support a monochrome 128 x 96 graphics mode. And there was even a way to download 6809 code. At which point trs80gp's built-in 6809 debugger may come in handy.

### Electric Crayon

The Electric Crayon is an external device that provides a colour video display. It can work with practically any computer as it connects via the printer port. It was primarily targeted at Model 1 and 3 users as the machines did not have a colour display nor high resolution graphics.

You may attach an emulated Electric Crayon to trs80gp by using `-p :ec` on the command line or bringing up the Printer → Connection... dialog box and choosing "Electric Crayon" from the dropdown. In either case a new instance of trs80gp will run acting as an Electric Crayon emulator. When launched this way the Electric Crayon emulator will go away when you quit the main trs80gp program.

Even with an Electric Crayon attached trs80gp still records the output to the printer in the normal window. This can be very handy to capture a drawing or debug a program using the Electric Crayon.

You can also just run a standalone Electric Crayon emulation via `trs80gp -mec` and hook it to another trs80gp emulator using the `-p` command line options to map TCP/IP connections to the printer port. The Printer section gives some more details on how to do that.

Although the owner had no direct control over the real Electric Crayon, trs80gp supports pasting text to its command processor. Thus even run standalone you can draw using the usual paste methods: Edit → Paste, the input macros or `-i` on the command line. For example:

           trs80gp -mec -i "A 10 4 HELLO WORLD\r"

Not many programs were written for the Electric Crayon. Here's quick overview of the available commands so you can write some yourself. You can get more detail from the January 1981 issue of 80 Microcomputer. However, don't miss out on the fun of playing with the commands and figuring it out yourself.

Command |  | Operation
--- | --- | ---
`A x y string` |  | Display text string.
`C n` |  | Select colour.
`ERS` |  | Erase display.
`H x y len` |  | Draw horizontal line.
`M n` |  | Change graphics mode.
`I` |  | Invert. (swap between the two palettes)
`LD*` |  | Load data or code in S record format.
`P n` |  | Set semigraphics value written when drawing.
`R x y string` |  | Display string in reversed colours.
`S x y` |  | Set pixel (or P pattern if in semigraphics)
`V x y len` |  | Draw vertical line.

        Graphics Modes:

        0	alphanumerics and semigraphics-4
        1	2 x 3 semigraphics-6
        2	 64 x  64 x 4 graphics
        3	128 x  64 x 2 graphics
        4	128 x  64 x 4 graphics
        5	128 x  96 x 2 graphics
        6	128 x  96 x 4 graphics
        7	128 x 192 x 2 graphics
        8	128 x 192 x 4 graphics
        9	256 x 192 x 2 graphics

The Electric Crayon's 6800 CPU is fullly emulated. There's a debugger and the usual trs80gp programming features.

### Color Computer

A fully configured Color Computer's BASIC ROM is in 3 parts, Color BASIC, Extended Color BASIC and Disk BASIC. In order to select the different revisions of each ROM the `-rN` is divided into 3 parts. The units place selects the Color BASIC revision, the tens place the Extended Color BASIC revision and the hundreds place the Disk BASIC revision.

For example, `-r102` will choose Color BASIC 1.2, Extended Color BASIC 1.0 and Disk BASIC 1.1. Generally there's little need to use anything but the default latest versions of each ROM but it can be very useful when testing program compatibility or investigating the ROMs themselves.

Color BASIC has 4 versions numbered 0 .. 3: 1.0, 1.1, 1.2 and 1.3. Extended Color BASIC and Disk BASIC only have two versions each, 1.0 and 1.1.

### Tandy 10

The Tandy 10 was a rebadged ADDS System 50 system sold from 1978 to 1980 by Radio Shack Computer Centers. A relatively small number were sold.

trs80gp's emulation of the Tandy 10 is based on one set of dumped diskettes and an ADOS and BASIC manual. The operation system it runs, ADOS, is a slightly different flavour of CP/M where programs load at hex `$1100` rather than `$100` and system calls are `CALL $1009` instead of `CALL 5`.

The Tandy 10 has a number of special keys. Many of them are similar in function to modern PCs. Here's how they are mapped:

Tandy 10 key | Host Key | Action
--- | --- | ---
HOME | Home | go to start of line
ERASE | End | delete to end of line (or clear screen if shifted)
← | ← | cursor left
→ | → | cursor right
BACK TAB | shift ← | move back one word
FWD TAB | shift → | move forward one word
↑ | ↑ |
↓ | ↓ |
DEL CHAR | Delete | delete character
INS CHAR | Insert | toggle insert mode
PRINT LOCAL | Print Screen | send screen to printer

No examples of `PREV PAGE`, `CURR PAGE`, `NEXT PAGE`, `SET ATTR`, `INS LINE`, `DEL LINE`, `FORM SELECT` or `STATUS LINE` being used have been found. The emulator does not know what key codes they generate.

As ADOS is essentially CP/M, menus and error messages use `A:` and `B:` to refer to the drives rather than `:0` and `:1` as is the TRS-DOS family convention.

Input scripting with the `-i` family of options works but ADOS will tend to abort commands in progress upon any input. Either `-iw` waits until data is availble or `-id` frame delays are needed in order to issue multiple commands.

Auto-run of `.com` or BASIC programs has not been implemented. Nor has FreHD extensions for file import/export.

While the emulation is very functional there are some inaccuracies due to a lack of information:

- Actual boot firmware.
- The exact shape of screen characters.
- The video cursor appearance.
- Exact video timing.
- Speed of blinking.
- Some keys not implemented.
- Serial port (we think it has one).

If you can help with any of these things, please do get in touch.

### Linux Notes

Version 2.4 was the first wide release of the Linux version of trs80gp. It has had several releases since there but likely has a small user base. Please get in touch if you run into problems.

Per-user preferences are stored in `$XDG_CONFIG_HOME/.config/trs80gp/prefs.ini` if the `XDG_CONFIG_HOME` environment variable is set and not empty. Otherwise `$HOME/.config/trs80gp/prefs.ini` is used if the `HOME` environment variable is set. If not, then no preferences will be saved.

### MacOS Notes

Some trs80gp features are only available through the command line. The easiest way to run from the command line is use the `open` command. For example, here is how to start trs80gp in Model I mode with the PCG-80 programmable character graphics generator enabled:

        open trs80gp.app --args -m1 -pcg-80

You can run the executable directly which may be preferable in some cases. Just use the path to it inside the trs80gp.app directory. Here's how to start a Model II in turbo mode:

        trs80gp.app/Contents/MacOS/trs80gp -m2 -turbo

### The End

Pretty much anything else depends on knowing how to operate a TRS-80 or program a Z-80. While it surely would be good to provide links to documentation I'll just leave you with your prior knowledge and good hunting in your web searches.

George Phillips, June 1, 2025. george -at- 48k.ca