TRS-80 Model III Emulator in Javascript

[Jun 22,2024: Version 1.6 news]


Programs to Try

Shoot asteroids into smaller asteroids for points
Navigate your submarine to the reactor.
Destroy unlicensed Klingon vessels and save the Federation
Shoot flying saucers. For points.
Shoot flying aliens. For points.
Shoot missiles. For kills.
Fight invaders in this brand-new TRS-80 game.
Defeat the Jovian space fleet.
A short song played via the cassette port.
Model III BASIC Interpreter
TRSDOS 1.3 Disk Operating System
Hires example diskette, "GLOAD GPICTURE"
Fill screen with test pattern. Not a game.

What is this?

The TRS-80 Model III is an old 8-bit home computer. This web page emulates it using only Javascript.

You'll need a web browser with a fast Javascript engine. The latest (mid 2010) versions of Chrome, Safari and Opera will work well on a reasonably fast machine (2 GHz processor) Firefox will run, but not real-time, and IE is very slow (both should get faster within a year or so).

Click on the Run button to start the BASIC interpreter. You will need to press ENTER twice to get the actual BASIC ready prompt.

You can also try out a few other programs by selecting them in the table above. Note that the backslash (\) key is the TRS-80 clear key, needed to start Super Nova.

Oh, and, sorry in advance, the backspace button won't leave the page because it is too useful for deleting characters. In fact, most short-cut keys won't work as the emulator needs to intercept most key presses.

Technical Details

This emulator is really a testament to the extreme speed of modern computers and the astounding new Javascript interpreters. The combination can easily emulate the function of the TRS-80 running at 2 MHz. That's well over 100,000 emulated instructions per second!

The code here came from converting the C code my twin brother wrote for trs80gp into Javascript. That would have been easy except that he used features of C (like pointers) and I had to spend some time undoing all that cleverness.

Most TRS-80 games had sound effects by using the cassette port. Version 1.6 of this emulator can play these using HTML5 sound. Back in 2013, only a very few browsers support Web Audio but now it is common for all browsers. Playing emulated sound requires the ability for Javascript to generate sound samples on the fly and a host machine fast enough to not fall behind.

I haven't spent a great deal of time testing it although I've ran about a dozen different programs with no noticable problems.

It was a hassle to get the emulator running on a selection of browsers. Some didn't support the <canvas> tag (IE and Opera) and the workaround version using CSS sprites required a horrific amount of fiddling. There's a bit of VBScript in here to allow IE to load binary data using AJAX. And, finally, the key codes generated varies a bit from browser to browser. I could have used JQuery or some other library but doing it by myself was educational. (Although I'll admit I haven't tried to cover a very wide range of browsers at all). At one point the emulator did function using Opera for the Wii and the PS3's internal browser--but far too slow to be usable. Owners of iPads or iPhone 3GS or better should be able to get the Cass? prompt going, again, a bit slowly.

About the keyboard. The original TRS-80 keyboard is somewhat different from contemporary PC keyboards and does not support as many keys. The emulator tries to map the key you press to the appropriate TRS-80 combination. The old BREAK key is available by typing ESC and the CLEAR key is available via backslash. Here's the original keyboard layout with the shift keys. (Assuming you have a PC keyboard--but it should work pretty similar on a Macintosh)

TRS-80 keyboard layout

1  2  3  4  5  6  7  8  9  0  :  -  BK
 ↑ Q  W  E  R  T  Y  U  I  O  P  @  ← →
  ↓ A  S  D  F  G  H  J  K  L  ;  EN CL
   sh Z  X  C  V  B  N  M  ,  .  / sh
           S P A C E B A R

Holding shift:

!  "  #  $  %  &  '  (  )  01 *  =  BK
 ↑ Q  W  E  R  T  Y  U  I  O  P  `  ← →2
  ↓ A  S  D  F  G  H  J  K  L  +  EN CL
   sh Z  X  C  V  B  N  M  <  >  ? sh
           S P A C E B A R

Notes:
  1. Shift-Zero toggles between upper case only/lower case input. Use underscore on your keyboard to get this function.
  2. Shift-right arrow switches to 32 character wide mode.

Use it on your own web page

Go ahead and put a TRS-80 on your own webpage! You'll need to copy the Javascript and some PNG files: A minimal page would look like the following. The performance graph is optional; drop the '.perf()' call if you don't want it.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="trsemu-1.6.js"></script> 
<head>
<body
onload="trsEmu.screen('scrn').button('btn').perf('graph').focus();"> 
<div id="scrn">
<canvas width="512" height="408" style="background:black">
</canvas></div><br>
<div id="graph">
<canvas width="512" height="100" style="background:black">
</canvas></div><br>
<input type="button"id="btn" value="Run"
  onClick="trsEmu.run('toggle');">
<input type="button" value="Reset"
  onClick="trsEmu.run('reset');">
<body>
<html>
	
Multiple emulators can be created on a page. Use trsEmu.mknew() to create a new emulator and then give it its own .screen(). You will have to deal with the focus, perhaps via an onclick callback.

Run binaries with the trsEmu.run() command. Just pass it a URL fragment and it will load the executable from your site using AJAX. It supports the .cmd, .hex (zmac output), .3bn (system tapes) and .bas formats. The .bas format is just an ASCII text version of a BASIC program.

Version 1.3 added support for the .cas cassette tape format and binary basic programs.

The .run() command also works as a macros if the string contains one of the |, [] or {} characters. Here are the meanings (and look at this page for examples):

For example, the following statement will reset, load foo.bas, and run it:
trsemu.run("|[1]_\r0\r[1]{foo.bas}RUN\r")
(Which, BTW, is done automatically when run is passed a string ending in .bas).

The trsEmu.run() command also supports several single-action strings:

For example, the following run command will set the emulator running at 4x speed:
trsemu.run('8MHz')

Special Thanks

willus.com for implementing the speedup, printer DAC and debug_on debug_off commands.

That's all

Comments or questions to the email at the bottom of the page.
Peter Phillips, September 16, 2024,