diff --git a/AltairZ80/CMakeLists.txt b/AltairZ80/CMakeLists.txt
index 242085e8..0e5f8591 100644
--- a/AltairZ80/CMakeLists.txt
+++ b/AltairZ80/CMakeLists.txt
@@ -18,6 +18,7 @@ add_simulator(altairz80
SOURCES
altairz80_cpu.c
altairz80_cpu_nommu.c
+ s100_jair.c
sol20.c
s100_vdm1.c
mmd.c
diff --git a/AltairZ80/altairz80_sys.c b/AltairZ80/altairz80_sys.c
index f50841b1..473a0ce1 100644
--- a/AltairZ80/altairz80_sys.c
+++ b/AltairZ80/altairz80_sys.c
@@ -79,6 +79,10 @@ extern DEVICE m2sio0_dev;
extern DEVICE m2sio1_dev;
extern DEVICE pmmi_dev;
extern DEVICE hayes_dev;
+extern DEVICE jair_dev;
+extern DEVICE jairs0_dev;
+extern DEVICE jairs1_dev;
+extern DEVICE jairp_dev;
extern DEVICE mmd_dev;
extern DEVICE mmdm_dev;
extern DEVICE sol20_dev;
@@ -171,6 +175,11 @@ DEVICE *sim_devices[] = {
&pmmi_dev,
/* HAYES MODEM */
&hayes_dev,
+ /* JAIR SBC */
+ &jair_dev,
+ &jairs0_dev,
+ &jairs1_dev,
+ &jairp_dev,
/* Vector Graphic Devices */
&fw2_dev, &vfdhd_dev,
/* Single-Board Computers */
diff --git a/AltairZ80/s100_jair.c b/AltairZ80/s100_jair.c
new file mode 100644
index 00000000..6635cd63
--- /dev/null
+++ b/AltairZ80/s100_jair.c
@@ -0,0 +1,1815 @@
+/*** s100_jair.c: Josh's Altair / IMASI Replacement CPU & SBC
+
+ Created by Patrick Linstruth (patrick@deltecent.com)
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ PETER SCHORN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Except as contained in this notice, the name of Patrick Linstruth shall not
+ be used in advertising or otherwise to promote the sale, use or other dealings
+ in this Software without prior written authorization from Patrick Linstruth.
+
+ Devices:
+
+ JAIR - ROM and SD Card
+ JAIRS0 - COM1
+ JAIRS1 - COM2
+ JAIRP - Printer Port
+
+ The serial and printer ports support TMXR which allow these
+ ports to be attached to real serial ports and sockets. If no TMXR
+ interfaces are attached, JAIRS0 will use the SIMH console for
+ both input and output, JAIRS1 and JAIRP will use the SIMH console
+ for output.
+*/
+
+#include "altairz80_defs.h"
+#include "sim_imd.h"
+#include "sim_tmxr.h"
+
+/********/
+/* SIMH */
+/********/
+
+extern uint32 sim_map_resource(uint32 baseaddr, uint32 size, uint32 resource_type,
+ int32 (*routine)(const int32, const int32, const int32), const char* name, uint8 unmap);
+extern t_stat set_dev_enbdis(DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr);
+extern t_stat set_cmd(int32 flag, CONST char *cptr);
+extern void PutBYTEWrapper(const uint32 Addr, const uint32 Value);
+extern uint32 nmiInterrupt;
+
+/* Debug flags */
+#define VERBOSE_MSG (1 << 0)
+#define ERROR_MSG (1 << 1)
+#define STATUS_MSG (1 << 2)
+
+/* Debug Flags */
+static DEBTAB jair_dt[] = {
+ { "VERBOSE", VERBOSE_MSG, "Verbose messages" },
+ { "ERROR", ERROR_MSG, "Error messages" },
+ { "STATUS", STATUS_MSG, "Status messages" },
+ { NULL, 0 }
+};
+
+/*****************************/
+/* Local function prototypes */
+/*****************************/
+
+static t_stat jair_reset(DEVICE *dptr);
+static t_stat jair_port_reset(DEVICE *dptr);
+static t_stat jair_svc(UNIT *uptr);
+static t_stat jair_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
+static t_stat jair_boot(int32 unitno, DEVICE *dptr);
+static t_stat jair_attach(UNIT *uptr, CONST char *cptr);
+static t_stat jair_detach(UNIT *uptr);
+static t_stat jair_attach_mux(UNIT *uptr, CONST char *cptr);
+static t_stat jair_detach_mux(UNIT *uptr);
+static const char* jair_description(DEVICE *dptr);
+static t_stat jair_config_line(DEVICE *dev, TMLN *tmln, int baud);
+static const char* jairs0_description(DEVICE *dptr);
+static const char* jairs1_description(DEVICE *dptr);
+static const char* jairp_description(DEVICE *dptr);
+static int jair_set_mc(TMLN *tmln, uint8 data);
+static int jair_new_baud(UNIT *uptr);
+static t_stat jair_set_baud(UNIT *uptr, int32 value, const char *cptr, void *desc);
+static t_stat jair_show_baud(FILE *st, UNIT *uptr, int32 value, const void *desc);
+static t_stat jair_show_ports(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
+static int32 jairio(int32 addr, int32 rw, int32 data);
+static uint8 jair_io_in(uint32 addr);
+static uint8 jair_io_out(uint32 addr, int32 data);
+static t_stat jair_set_rom(UNIT *uptr, int32 value, CONST char *cptr, void *desc);
+static t_stat jair_set_norom(UNIT *uptr, int32 value, CONST char *cptr, void *desc);
+static int32 jair_shadow_rom(int32 Addr, int32 rw, int32 data);
+
+/***********/
+/* RAM/ROM */
+/***********/
+
+#define JAIR_ROM_BASE 0x0000
+#define JAIR_ROM_SIZE 8192
+#define JAIR_ROM_MASK (JAIR_ROM_SIZE-1)
+
+#define JAIR_ROM_READ FALSE
+#define JAIR_ROM_WRITE TRUE
+
+static uint8 jair_rom_v25[JAIR_ROM_SIZE] = {
+ 0x3e, 0x02, 0x21, 0x00, 0x00, 0x01, 0x01, 0x00,
+ 0x09, 0xd2, 0x08, 0x00, 0x3d, 0xc2, 0x02, 0x00,
+ 0x3e, 0x80, 0xd3, 0x23, 0xd3, 0x2b, 0x3e, 0x0c,
+ 0xd3, 0x20, 0xd3, 0x28, 0x3e, 0x00, 0xd3, 0x21,
+ 0xd3, 0x29, 0x3e, 0x03, 0xd3, 0x23, 0xd3, 0x2b,
+ 0xd3, 0x24, 0xd3, 0x2c, 0xdb, 0x20, 0x21, 0x34,
+ 0x00, 0xc3, 0xa4, 0x04, 0x0d, 0x0a, 0x41, 0x4c,
+ 0x54, 0x41, 0x49, 0x52, 0x2f, 0x49, 0x4d, 0x53,
+ 0x41, 0x49, 0x20, 0x38, 0x30, 0x38, 0x30, 0x20,
+ 0x43, 0x50, 0x55, 0x20, 0x42, 0x4f, 0x41, 0x52,
+ 0x44, 0x20, 0x42, 0x4f, 0x4f, 0x54, 0x20, 0x4c,
+ 0x4f, 0x41, 0x44, 0x45, 0x52, 0x20, 0x2d, 0x20,
+ 0x4a, 0x6f, 0x73, 0x68, 0x20, 0x42, 0x65, 0x6e,
+ 0x73, 0x61, 0x64, 0x6f, 0x6e, 0x20, 0x76, 0x32,
+ 0x2e, 0x35, 0x20, 0x53, 0x65, 0x70, 0x20, 0x33,
+ 0x2c, 0x20, 0x32, 0x30, 0x31, 0x38, 0x0d, 0x0a,
+ 0x3c, 0x44, 0x3e, 0x20, 0x2d, 0x53, 0x44, 0x20,
+ 0x43, 0x61, 0x72, 0x64, 0x20, 0x44, 0x69, 0x72,
+ 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x0d, 0x0a,
+ 0x3c, 0x52, 0x3e, 0x20, 0x2d, 0x52, 0x41, 0x4d,
+ 0x20, 0x54, 0x65, 0x73, 0x74, 0x0d, 0x0a, 0x3c,
+ 0x56, 0x3e, 0x20, 0x2d, 0x56, 0x69, 0x65, 0x77,
+ 0x20, 0x4c, 0x6f, 0x61, 0x64, 0x0d, 0x0a, 0x3e,
+ 0x20, 0x00, 0xaf, 0x32, 0x24, 0xfd, 0x01, 0x03,
+ 0x00, 0x1e, 0x05, 0x21, 0x00, 0x00, 0xdb, 0x25,
+ 0xe6, 0x01, 0xca, 0xd2, 0x00, 0xdb, 0x20, 0xc3,
+ 0xe4, 0x00, 0xdb, 0x00, 0xe6, 0x02, 0xca, 0x03,
+ 0x01, 0xdb, 0x01, 0xb7, 0xca, 0x03, 0x01, 0xfe,
+ 0xff, 0xca, 0x03, 0x01, 0xd3, 0x20, 0xd3, 0x01,
+ 0xfe, 0x1b, 0xca, 0xb6, 0x04, 0xfe, 0x20, 0xca,
+ 0x07, 0x01, 0xe6, 0x5f, 0xfe, 0x44, 0xca, 0x1c,
+ 0x01, 0xfe, 0x52, 0xca, 0xcc, 0x01, 0xfe, 0x56,
+ 0xca, 0x14, 0x01, 0x09, 0xd2, 0xc6, 0x00, 0x3e,
+ 0x2e, 0xd3, 0x20, 0xd3, 0x01, 0x1d, 0xc2, 0xc3,
+ 0x00, 0xc3, 0xb6, 0x04, 0x3e, 0x01, 0x32, 0x24,
+ 0xfd, 0xc3, 0xc1, 0x00, 0x31, 0x00, 0xfd, 0xcd,
+ 0x90, 0x07, 0x0d, 0x0a, 0x49, 0x4e, 0x49, 0x54,
+ 0x5f, 0x46, 0x41, 0x54, 0x20, 0x00, 0xcd, 0xd8,
+ 0x09, 0xcd, 0x90, 0x07, 0x0d, 0x0a, 0x44, 0x49,
+ 0x52, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x3a,
+ 0x0d, 0x0a, 0x00, 0xcd, 0xe9, 0x07, 0xca, 0x87,
+ 0x01, 0x7e, 0xfe, 0x21, 0xfa, 0x81, 0x01, 0xfe,
+ 0x7f, 0xf2, 0x81, 0x01, 0xe5, 0x01, 0x1a, 0x00,
+ 0x09, 0x7e, 0x23, 0xb6, 0xe1, 0xca, 0x81, 0x01,
+ 0xcd, 0xaf, 0x0d, 0x3a, 0x35, 0xfd, 0xfe, 0x40,
+ 0xfa, 0x71, 0x01, 0xcd, 0x90, 0x07, 0x0d, 0x0a,
+ 0x00, 0x3a, 0x35, 0xfd, 0xe6, 0x0f, 0xca, 0x81,
+ 0x01, 0x3e, 0x20, 0xcd, 0xc3, 0x07, 0xc3, 0x71,
+ 0x01, 0xcd, 0xff, 0x07, 0xc3, 0x46, 0x01, 0xcd,
+ 0x90, 0x07, 0x0d, 0x0a, 0x45, 0x4e, 0x54, 0x45,
+ 0x52, 0x20, 0x38, 0x2e, 0x33, 0x20, 0x46, 0x49,
+ 0x4c, 0x45, 0x20, 0x4e, 0x41, 0x4d, 0x45, 0x3e,
+ 0x20, 0x00, 0x21, 0x6d, 0xfd, 0x06, 0x0b, 0x3e,
+ 0x20, 0xcd, 0x51, 0x0e, 0x0e, 0x2e, 0x06, 0x08,
+ 0xcd, 0x89, 0x0d, 0xda, 0x87, 0x01, 0xfe, 0x0d,
+ 0xca, 0xc3, 0x01, 0x21, 0x75, 0xfd, 0x06, 0x03,
+ 0xcd, 0x89, 0x0d, 0xcd, 0x90, 0x07, 0x0d, 0x0a,
+ 0x00, 0xc3, 0x0d, 0x05, 0x21, 0x00, 0x00, 0x01,
+ 0x01, 0x00, 0x09, 0xd2, 0xd2, 0x01, 0x21, 0xdc,
+ 0x01, 0xc3, 0xa4, 0x04, 0x0d, 0x0a, 0x54, 0x65,
+ 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x53, 0x59,
+ 0x53, 0x54, 0x45, 0x4d, 0x20, 0x52, 0x41, 0x4d,
+ 0x20, 0x40, 0x46, 0x30, 0x30, 0x30, 0x2d, 0x46,
+ 0x46, 0x46, 0x46, 0x0d, 0x0a, 0x52, 0x41, 0x4d,
+ 0x20, 0x50, 0x41, 0x47, 0x45, 0x20, 0x4d, 0x41,
+ 0x52, 0x43, 0x48, 0x00, 0x1e, 0xff, 0x21, 0x00,
+ 0xf0, 0x7b, 0x2f, 0x77, 0x2c, 0xc2, 0x13, 0x02,
+ 0x7c, 0x24, 0xfe, 0xff, 0xc2, 0x11, 0x02, 0x16,
+ 0xf0, 0x62, 0x3e, 0x2e, 0xd3, 0x20, 0xd3, 0x01,
+ 0x7a, 0x2f, 0xd3, 0xff, 0x73, 0x2c, 0xc2, 0x2c,
+ 0x02, 0x21, 0x00, 0xf0, 0x7c, 0xba, 0x7b, 0xca,
+ 0x3b, 0x02, 0x2f, 0xbe, 0xc2, 0x26, 0x04, 0x2c,
+ 0xc2, 0x3b, 0x02, 0x7c, 0x24, 0xfe, 0xff, 0xc2,
+ 0x34, 0x02, 0x62, 0x7b, 0x2f, 0x77, 0x2c, 0xc2,
+ 0x4d, 0x02, 0x7a, 0x14, 0xfe, 0xff, 0xc2, 0x21,
+ 0x02, 0x1c, 0xca, 0x0e, 0x02, 0x21, 0x63, 0x02,
+ 0xc3, 0xa4, 0x04, 0x50, 0x41, 0x53, 0x53, 0x45,
+ 0x44, 0x0d, 0x0a, 0x52, 0x41, 0x4d, 0x20, 0x42,
+ 0x59, 0x54, 0x45, 0x20, 0x4d, 0x41, 0x52, 0x43,
+ 0x48, 0x20, 0x41, 0x00, 0x05, 0xc2, 0x7c, 0x02,
+ 0x1e, 0xff, 0x26, 0xf0, 0x2e, 0x00, 0x7c, 0x2f,
+ 0xd3, 0xff, 0x3e, 0x2e, 0xd3, 0x20, 0xd3, 0x01,
+ 0x7b, 0x2f, 0x77, 0x2c, 0xc2, 0x92, 0x02, 0x16,
+ 0x00, 0x6a, 0x7b, 0x77, 0x2f, 0x2e, 0x00, 0xbe,
+ 0xca, 0xaf, 0x02, 0x2f, 0xbe, 0xc2, 0x26, 0x04,
+ 0x7d, 0xba, 0xc2, 0x26, 0x04, 0x7b, 0x2f, 0x2c,
+ 0xc2, 0x9f, 0x02, 0x6a, 0x7b, 0x2f, 0x77, 0x14,
+ 0xc2, 0x99, 0x02, 0x7c, 0x24, 0xfe, 0xff, 0xc2,
+ 0x84, 0x02, 0x1c, 0xca, 0x82, 0x02, 0x21, 0xcc,
+ 0x02, 0xc3, 0xa4, 0x04, 0x50, 0x41, 0x53, 0x53,
+ 0x45, 0x44, 0x0d, 0x0a, 0x52, 0x41, 0x4d, 0x20,
+ 0x42, 0x59, 0x54, 0x45, 0x20, 0x4d, 0x41, 0x52,
+ 0x43, 0x48, 0x20, 0x42, 0x00, 0x1e, 0xff, 0x16,
+ 0x00, 0x21, 0x00, 0xf0, 0x7b, 0x2f, 0x77, 0x2c,
+ 0xc2, 0xee, 0x02, 0x7c, 0x24, 0xfe, 0xff, 0xc2,
+ 0xec, 0x02, 0x7a, 0x2f, 0xd3, 0xff, 0xe6, 0x0f,
+ 0xc2, 0x09, 0x03, 0x3e, 0x2e, 0xd3, 0x20, 0xd3,
+ 0x01, 0x26, 0xf0, 0x6a, 0x73, 0x7c, 0x24, 0xfe,
+ 0xff, 0xc2, 0x0c, 0x03, 0x2e, 0x00, 0x26, 0xf0,
+ 0x7d, 0xba, 0xca, 0x2d, 0x03, 0x7b, 0x2f, 0xbe,
+ 0xc2, 0x26, 0x04, 0x7c, 0x24, 0xfe, 0xff, 0xc2,
+ 0x1d, 0x03, 0xc3, 0x39, 0x03, 0x7b, 0xbe, 0xc2,
+ 0x26, 0x04, 0x7c, 0x24, 0xfe, 0xff, 0xc2, 0x2d,
+ 0x03, 0x2c, 0xc2, 0x16, 0x03, 0x26, 0xf0, 0x6a,
+ 0x7b, 0x2f, 0x77, 0x7c, 0x24, 0xfe, 0xff, 0xc2,
+ 0x40, 0x03, 0x14, 0xc2, 0xfa, 0x02, 0x1c, 0xca,
+ 0xe7, 0x02, 0x21, 0x58, 0x03, 0xc3, 0xa4, 0x04,
+ 0x50, 0x41, 0x53, 0x53, 0x45, 0x44, 0x0d, 0x0a,
+ 0x52, 0x41, 0x4d, 0x20, 0x42, 0x49, 0x54, 0x20,
+ 0x4d, 0x41, 0x52, 0x43, 0x48, 0x20, 0x00, 0x1e,
+ 0x01, 0x21, 0x00, 0xf0, 0x7b, 0x2f, 0xd3, 0xff,
+ 0x3e, 0x2e, 0xd3, 0x20, 0xd3, 0x01, 0x7b, 0x77,
+ 0x2c, 0xc2, 0x7f, 0x03, 0x7c, 0x24, 0xfe, 0xff,
+ 0xc2, 0x7e, 0x03, 0x21, 0x00, 0xf0, 0x7b, 0xbe,
+ 0xc2, 0x26, 0x04, 0x2c, 0xc2, 0x8f, 0x03, 0x7c,
+ 0x24, 0xfe, 0xff, 0xc2, 0x8e, 0x03, 0x7b, 0x17,
+ 0x7b, 0x07, 0x5f, 0xfe, 0x01, 0xc2, 0xad, 0x03,
+ 0x2f, 0x5f, 0xc3, 0x71, 0x03, 0xfe, 0xfe, 0xc2,
+ 0x71, 0x03, 0x21, 0xb8, 0x03, 0xc3, 0xa4, 0x04,
+ 0x50, 0x41, 0x53, 0x53, 0x45, 0x44, 0x0d, 0x0a,
+ 0x52, 0x41, 0x4d, 0x20, 0x53, 0x45, 0x51, 0x55,
+ 0x45, 0x4e, 0x43, 0x45, 0x20, 0x54, 0x45, 0x53,
+ 0x54, 0x00, 0x1e, 0x01, 0x7b, 0xe6, 0x07, 0xc2,
+ 0xe0, 0x03, 0x3e, 0x2e, 0xd3, 0x20, 0xd3, 0x01,
+ 0x7b, 0x2f, 0xd3, 0xff, 0x21, 0x00, 0xf0, 0x53,
+ 0x14, 0xc2, 0xed, 0x03, 0x14, 0x72, 0x2c, 0xc2,
+ 0xe8, 0x03, 0x7c, 0x24, 0xfe, 0xff, 0xc2, 0xe8,
+ 0x03, 0x21, 0x00, 0xf0, 0x53, 0x14, 0xc2, 0x02,
+ 0x04, 0x14, 0x7a, 0xbe, 0xc2, 0x26, 0x04, 0x2c,
+ 0xc2, 0xfd, 0x03, 0x7c, 0x24, 0xfe, 0xff, 0xc2,
+ 0xfd, 0x03, 0x1c, 0xc2, 0xd4, 0x03, 0x21, 0x1c,
+ 0x04, 0xc3, 0xa4, 0x04, 0x50, 0x41, 0x53, 0x53,
+ 0x45, 0x44, 0x00, 0xc3, 0xb6, 0x04, 0x54, 0x5d,
+ 0x21, 0x2e, 0x04, 0xc3, 0xa4, 0x04, 0x0d, 0x0a,
+ 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x20, 0x41,
+ 0x54, 0x3a, 0x00, 0x7a, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0xe6, 0x0f, 0xc6, 0x90, 0x27, 0xce, 0x40, 0x27,
+ 0x05, 0xc2, 0x48, 0x04, 0xd3, 0x20, 0xd3, 0x01,
+ 0x7a, 0xe6, 0x0f, 0xc6, 0x90, 0x27, 0xce, 0x40,
+ 0x27, 0x05, 0xc2, 0x59, 0x04, 0xd3, 0x20, 0xd3,
+ 0x01, 0x7b, 0x0f, 0x0f, 0x0f, 0x0f, 0xe6, 0x0f,
+ 0xc6, 0x90, 0x27, 0xce, 0x40, 0x27, 0x05, 0xc2,
+ 0x6e, 0x04, 0xd3, 0x20, 0xd3, 0x01, 0x7b, 0xe6,
+ 0x0f, 0xc6, 0x90, 0x27, 0xce, 0x40, 0x27, 0x05,
+ 0xc2, 0x7f, 0x04, 0xd3, 0x20, 0xd3, 0x01, 0x21,
+ 0x8d, 0x04, 0xc3, 0xa4, 0x04, 0x20, 0x2d, 0x20,
+ 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x20, 0x48,
+ 0x41, 0x4c, 0x54, 0x45, 0x44, 0x0d, 0x0a, 0x00,
+ 0x76, 0xc3, 0xa0, 0x04, 0x7e, 0x23, 0xb7, 0xc2,
+ 0xab, 0x04, 0xe9, 0x05, 0xc2, 0xab, 0x04, 0xd3,
+ 0x20, 0xd3, 0x01, 0xc3, 0xa4, 0x04, 0x31, 0x00,
+ 0xfd, 0xcd, 0x90, 0x07, 0x0d, 0x0a, 0x42, 0x4f,
+ 0x4f, 0x54, 0x20, 0x42, 0x49, 0x4f, 0x53, 0x2e,
+ 0x48, 0x45, 0x58, 0x2c, 0x20, 0x49, 0x4e, 0x49,
+ 0x54, 0x5f, 0x46, 0x41, 0x54, 0x20, 0x00, 0xcd,
+ 0xd8, 0x09, 0xcd, 0x90, 0x07, 0x0d, 0x0a, 0x4c,
+ 0x4f, 0x41, 0x44, 0x49, 0x4e, 0x47, 0x20, 0x46,
+ 0x49, 0x4c, 0x45, 0x20, 0x00, 0x11, 0x01, 0xfd,
+ 0xcd, 0x3d, 0x07, 0x42, 0x49, 0x4f, 0x53, 0x20,
+ 0x20, 0x20, 0x20, 0x48, 0x45, 0x58, 0x00, 0x21,
+ 0x00, 0xfd, 0x36, 0x00, 0x23, 0x11, 0x6d, 0xfd,
+ 0x06, 0x0b, 0xcd, 0x43, 0x0e, 0xcd, 0x21, 0x08,
+ 0xca, 0x1c, 0x01, 0xe5, 0x01, 0x1c, 0x00, 0x09,
+ 0xcd, 0xe5, 0x0d, 0x21, 0x20, 0xfd, 0xcd, 0xed,
+ 0x0d, 0xe1, 0x01, 0x1a, 0x00, 0x09, 0xcd, 0x4c,
+ 0x0e, 0xeb, 0x21, 0x00, 0xfd, 0x36, 0x01, 0x21,
+ 0x0c, 0xfd, 0x73, 0x23, 0x72, 0x23, 0x06, 0x0e,
+ 0x3e, 0xff, 0xcd, 0x51, 0x0e, 0xcd, 0x90, 0x07,
+ 0x0d, 0x0a, 0x46, 0x49, 0x4c, 0x45, 0x20, 0x53,
+ 0x49, 0x5a, 0x45, 0x3d, 0x30, 0x78, 0x00, 0x2a,
+ 0x22, 0xfd, 0xcd, 0x61, 0x07, 0x2a, 0x20, 0xfd,
+ 0xcd, 0x61, 0x07, 0xcd, 0x90, 0x07, 0x0d, 0x0a,
+ 0x00, 0x21, 0x00, 0x00, 0x22, 0x3e, 0xfd, 0x21,
+ 0xff, 0xff, 0x22, 0x25, 0xfd, 0x3e, 0x00, 0x32,
+ 0x34, 0xfd, 0x21, 0xc8, 0x05, 0x22, 0x27, 0xfd,
+ 0x21, 0x20, 0xfd, 0xcd, 0xe5, 0x0d, 0xcd, 0x13,
+ 0x0e, 0xca, 0xba, 0x05, 0xcd, 0x0b, 0x0e, 0x21,
+ 0x20, 0xfd, 0xcd, 0xed, 0x0d, 0x2a, 0x25, 0xfd,
+ 0x23, 0x7c, 0xb5, 0xc2, 0xa3, 0x05, 0xcd, 0x58,
+ 0x08, 0x2a, 0x3e, 0xfd, 0x23, 0x22, 0x3e, 0xfd,
+ 0x21, 0x00, 0xfe, 0x22, 0x25, 0xfd, 0x3a, 0x24,
+ 0xfd, 0xb7, 0xca, 0xb1, 0x05, 0x7e, 0xcd, 0xc3,
+ 0x07, 0x7e, 0x21, 0x78, 0x05, 0xe5, 0x2a, 0x27,
+ 0xfd, 0xe9, 0xcd, 0x90, 0x07, 0x0d, 0x0a, 0x2d,
+ 0x45, 0x4f, 0x46, 0x2d, 0x00, 0xc3, 0xbe, 0x06,
+ 0xfe, 0x3a, 0xc0, 0xaf, 0x32, 0x2d, 0xfd, 0x21,
+ 0x2a, 0x06, 0x22, 0x2a, 0xfd, 0x21, 0xdc, 0x05,
+ 0x22, 0x27, 0xfd, 0xc9, 0xcd, 0x18, 0x07, 0xda,
+ 0x08, 0x06, 0x07, 0x07, 0x07, 0x07, 0x32, 0x2c,
+ 0xfd, 0x21, 0xf0, 0x05, 0x22, 0x27, 0xfd, 0xc9,
+ 0xcd, 0x18, 0x07, 0xda, 0x08, 0x06, 0x67, 0x3a,
+ 0x2c, 0xfd, 0xb4, 0x67, 0x3a, 0x2d, 0xfd, 0x84,
+ 0x32, 0x2d, 0xfd, 0x7c, 0x2a, 0x2a, 0xfd, 0xe9,
+ 0xcd, 0x90, 0x07, 0x0d, 0x0a, 0x21, 0x21, 0x21,
+ 0x20, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x2c, 0x20,
+ 0x4e, 0x4f, 0x54, 0x20, 0x41, 0x20, 0x48, 0x45,
+ 0x58, 0x20, 0x43, 0x48, 0x41, 0x52, 0x00, 0xc3,
+ 0x87, 0x04, 0x32, 0x2e, 0xfd, 0x21, 0x33, 0x06,
+ 0xc3, 0xd2, 0x05, 0x32, 0x30, 0xfd, 0x21, 0x3c,
+ 0x06, 0xc3, 0xd2, 0x05, 0x32, 0x2f, 0xfd, 0x3a,
+ 0x34, 0xfd, 0xb7, 0xc2, 0x50, 0x06, 0x3c, 0x32,
+ 0x34, 0xfd, 0x2a, 0x2f, 0xfd, 0x22, 0x32, 0xfd,
+ 0x21, 0x56, 0x06, 0xc3, 0xd2, 0x05, 0x32, 0x31,
+ 0xfd, 0xfe, 0x02, 0xf2, 0x93, 0x06, 0x3a, 0x2e,
+ 0xfd, 0xb7, 0x21, 0x7d, 0x06, 0xca, 0xd2, 0x05,
+ 0x3d, 0x32, 0x2e, 0xfd, 0x21, 0x72, 0x06, 0xc3,
+ 0xd2, 0x05, 0x2a, 0x2f, 0xfd, 0x77, 0x23, 0x22,
+ 0x2f, 0xfd, 0xc3, 0x5e, 0x06, 0x3a, 0x2d, 0xfd,
+ 0xb7, 0xc2, 0xa3, 0x06, 0x3a, 0x31, 0xfd, 0xfe,
+ 0x01, 0xca, 0xbe, 0x06, 0x21, 0xc8, 0x05, 0x22,
+ 0x27, 0xfd, 0xc9, 0xcd, 0x90, 0x07, 0x2d, 0x49,
+ 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x00,
+ 0xc3, 0x8c, 0x06, 0xcd, 0x90, 0x07, 0x0d, 0x0a,
+ 0x21, 0x21, 0x21, 0x20, 0x43, 0x48, 0x45, 0x43,
+ 0x4b, 0x53, 0x55, 0x4d, 0x20, 0x45, 0x52, 0x52,
+ 0x4f, 0x52, 0x00, 0xc3, 0x87, 0x04, 0x3a, 0x34,
+ 0xfd, 0xb7, 0xc2, 0xe7, 0x06, 0xcd, 0x90, 0x07,
+ 0x0d, 0x0a, 0x21, 0x21, 0x21, 0x20, 0x53, 0x54,
+ 0x41, 0x52, 0x54, 0x20, 0x41, 0x44, 0x44, 0x52,
+ 0x45, 0x53, 0x53, 0x20, 0x4e, 0x4f, 0x54, 0x20,
+ 0x53, 0x45, 0x54, 0x00, 0xc3, 0x87, 0x04, 0xcd,
+ 0x90, 0x07, 0x0d, 0x0a, 0x45, 0x78, 0x65, 0x63,
+ 0x75, 0x74, 0x65, 0x20, 0x61, 0x74, 0x3a, 0x00,
+ 0x2a, 0x15, 0x07, 0x22, 0xfd, 0xff, 0x3a, 0x17,
+ 0x07, 0x32, 0xff, 0xff, 0x2a, 0x32, 0xfd, 0xcd,
+ 0x61, 0x07, 0xcd, 0x90, 0x07, 0x0d, 0x0a, 0x00,
+ 0x3e, 0x01, 0xc3, 0xfd, 0xff, 0xd3, 0x38, 0xe9,
+ 0xfe, 0x30, 0xfa, 0x36, 0x07, 0xfe, 0x3a, 0xfa,
+ 0x3a, 0x07, 0xfe, 0x41, 0xfa, 0x36, 0x07, 0xfe,
+ 0x47, 0xfa, 0x38, 0x07, 0xfe, 0x61, 0xfa, 0x36,
+ 0x07, 0xfe, 0x67, 0xfa, 0x38, 0x07, 0x37, 0xc9,
+ 0xd6, 0x07, 0xe6, 0x0f, 0xc9, 0xe3, 0x7e, 0x23,
+ 0xb7, 0xca, 0x49, 0x07, 0x12, 0x13, 0xc3, 0x3e,
+ 0x07, 0xe3, 0xc9, 0xf5, 0x78, 0xcd, 0x6c, 0x07,
+ 0x79, 0xcd, 0x6c, 0x07, 0xf1, 0xc9, 0xf5, 0x7a,
+ 0xcd, 0x6c, 0x07, 0x7b, 0xcd, 0x6c, 0x07, 0xf1,
+ 0xc9, 0xf5, 0x7c, 0xcd, 0x6c, 0x07, 0x7d, 0xcd,
+ 0x6c, 0x07, 0xf1, 0xc9, 0xf5, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0xcd, 0x7b, 0x07, 0xf1, 0xf5, 0xcd, 0x7b,
+ 0x07, 0xf1, 0xc9, 0xe6, 0x0f, 0xc6, 0x90, 0x27,
+ 0xce, 0x40, 0x27, 0xc3, 0xc3, 0x07, 0x7e, 0x23,
+ 0xb7, 0xc8, 0xcd, 0xc3, 0x07, 0xc3, 0x86, 0x07,
+ 0xe3, 0xf5, 0xcd, 0x86, 0x07, 0xf1, 0xe3, 0xc9,
+ 0x7e, 0xcd, 0xc3, 0x07, 0x23, 0x05, 0xc2, 0x98,
+ 0x07, 0xc9, 0xdb, 0x25, 0xe6, 0x01, 0xca, 0xae,
+ 0x07, 0xdb, 0x20, 0xc3, 0xc0, 0x07, 0xdb, 0x00,
+ 0xe6, 0x02, 0xca, 0xa2, 0x07, 0xdb, 0x01, 0xb7,
+ 0xca, 0xa2, 0x07, 0xfe, 0xff, 0xca, 0xa2, 0x07,
+ 0xfe, 0x20, 0xf8, 0xf5, 0xfe, 0x0d, 0xca, 0xe2,
+ 0x07, 0xfe, 0x20, 0xfa, 0xd5, 0x07, 0x3a, 0x35,
+ 0xfd, 0x3c, 0x32, 0x35, 0xfd, 0xdb, 0x25, 0xe6,
+ 0x20, 0xca, 0xd5, 0x07, 0xf1, 0xd3, 0x20, 0xd3,
+ 0x01, 0xc9, 0xaf, 0x32, 0x35, 0xfd, 0xc3, 0xd5,
+ 0x07, 0x21, 0x65, 0xfd, 0xcd, 0xe5, 0x0d, 0x2a,
+ 0x55, 0xfd, 0x22, 0x7d, 0xfd, 0xb7, 0xcd, 0x98,
+ 0x0b, 0x21, 0x00, 0xfe, 0xaf, 0xbe, 0xc9, 0x01,
+ 0x20, 0x00, 0x09, 0xd2, 0xfc, 0x07, 0xaf, 0x2a,
+ 0x7d, 0xfd, 0x01, 0xf0, 0xff, 0x09, 0x22, 0x7d,
+ 0xfd, 0xd0, 0x7c, 0xb5, 0xc8, 0x21, 0x78, 0xfd,
+ 0xcd, 0xe5, 0x0d, 0xcd, 0x05, 0x0e, 0xc3, 0xf6,
+ 0x07, 0x21, 0x6d, 0xfd, 0xcd, 0xaf, 0x0d, 0xcd,
+ 0x4a, 0x08, 0xc2, 0x3d, 0x08, 0xcd, 0x90, 0x07,
+ 0x20, 0x2d, 0x4e, 0x4f, 0x54, 0x20, 0x46, 0x4f,
+ 0x55, 0x4e, 0x44, 0x00, 0xc9, 0xcd, 0x90, 0x07,
+ 0x20, 0x2d, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53,
+ 0x00, 0xc9, 0xcd, 0xe9, 0x07, 0xc8, 0xcd, 0xab,
+ 0x09, 0xc0, 0xcd, 0xff, 0x07, 0xc3, 0x4d, 0x08,
+ 0x21, 0x00, 0xfd, 0x7e, 0xb7, 0xc2, 0x80, 0x08,
+ 0xcd, 0xff, 0x04, 0x3a, 0x00, 0xfd, 0xb7, 0xc2,
+ 0x80, 0x08, 0xcd, 0x90, 0x07, 0x20, 0x2d, 0x44,
+ 0x69, 0x73, 0x6b, 0x20, 0x4e, 0x6f, 0x74, 0x20,
+ 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x00, 0xc9,
+ 0x21, 0x12, 0xfd, 0x5e, 0x23, 0x56, 0x2a, 0x3e,
+ 0xfd, 0xcd, 0x36, 0x0e, 0xc2, 0x98, 0x08, 0x21,
+ 0x18, 0xfd, 0xcd, 0xe5, 0x0d, 0xc3, 0xa4, 0x09,
+ 0xeb, 0x21, 0x12, 0xfd, 0x73, 0x23, 0x72, 0x2a,
+ 0x36, 0xfd, 0xcd, 0x5e, 0x0e, 0x21, 0x0e, 0xfd,
+ 0xe5, 0xcd, 0x4c, 0x0e, 0x44, 0x4d, 0xe1, 0x7a,
+ 0xb8, 0xc2, 0xb9, 0x08, 0x7b, 0xb9, 0xca, 0x88,
+ 0x09, 0xd2, 0xc4, 0x08, 0x01, 0x00, 0x00, 0x2b,
+ 0x2b, 0xc3, 0xcc, 0x08, 0x7b, 0x91, 0x5f, 0x7a,
+ 0x98, 0x57, 0x23, 0x23, 0xcd, 0x4c, 0x0e, 0x7a,
+ 0xb3, 0xca, 0x37, 0x09, 0x23, 0x7c, 0xb5, 0xc2,
+ 0x06, 0x09, 0xcd, 0x90, 0x07, 0x20, 0x2d, 0x45,
+ 0x52, 0x52, 0x4f, 0x52, 0x2c, 0x20, 0x4e, 0x4f,
+ 0x20, 0x4d, 0x4f, 0x52, 0x45, 0x20, 0x41, 0x4c,
+ 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x45, 0x44, 0x20,
+ 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, 0x53,
+ 0x21, 0x00, 0x76, 0xc3, 0x02, 0x09, 0x2b, 0xc5,
+ 0xd5, 0xe5, 0x5c, 0x2a, 0x61, 0xfd, 0x7d, 0x83,
+ 0x5f, 0x7c, 0xce, 0x00, 0x57, 0x2a, 0x63, 0xfd,
+ 0xd2, 0x1c, 0x09, 0x23, 0x44, 0x4d, 0xcd, 0x98,
+ 0x0b, 0xd1, 0x21, 0x00, 0xfe, 0xb7, 0x7b, 0x17,
+ 0x6f, 0x7c, 0xce, 0x00, 0x67, 0xcd, 0x4c, 0x0e,
+ 0xd1, 0xc1, 0x03, 0x1b, 0xc3, 0xcf, 0x08, 0xeb,
+ 0x21, 0x0e, 0xfd, 0x71, 0x23, 0x70, 0x23, 0x73,
+ 0x23, 0x72, 0xeb, 0x2b, 0x2b, 0x01, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x3e, 0x08, 0x32, 0x3a, 0xfd,
+ 0x3a, 0x51, 0xfd, 0x1f, 0x32, 0x39, 0xfd, 0xd2,
+ 0x60, 0x09, 0xeb, 0x19, 0xeb, 0x79, 0x88, 0x4f,
+ 0x29, 0x78, 0x17, 0x47, 0x3a, 0x3a, 0xfd, 0x3d,
+ 0x32, 0x3a, 0xfd, 0x3a, 0x39, 0xfd, 0xc2, 0x53,
+ 0x09, 0x06, 0x00, 0x2a, 0x69, 0xfd, 0x19, 0xeb,
+ 0x2a, 0x6b, 0xfd, 0xd2, 0x7f, 0x09, 0x03, 0x09,
+ 0xe5, 0xc1, 0x21, 0x14, 0xfd, 0xcd, 0xed, 0x0d,
+ 0x21, 0x12, 0xfd, 0x5e, 0x23, 0x56, 0x2a, 0x3b,
+ 0xfd, 0xcd, 0x5e, 0x0e, 0x21, 0x14, 0xfd, 0x01,
+ 0x00, 0x00, 0x16, 0x00, 0x5f, 0xcd, 0xf5, 0x0d,
+ 0x23, 0xcd, 0xed, 0x0d, 0xcd, 0x98, 0x0b, 0x21,
+ 0x00, 0xfe, 0xc9, 0xe5, 0x06, 0x08, 0x11, 0x6d,
+ 0xfd, 0x1a, 0xbe, 0xc2, 0xd5, 0x09, 0x23, 0x13,
+ 0x05, 0xc2, 0xb1, 0x09, 0xe1, 0xe5, 0x11, 0x08,
+ 0x00, 0x19, 0x06, 0x03, 0x11, 0x75, 0xfd, 0x1a,
+ 0xbe, 0xc2, 0xd5, 0x09, 0x23, 0x13, 0x05, 0xc2,
+ 0xc7, 0x09, 0x04, 0xe1, 0xc9, 0xaf, 0xe1, 0xc9,
+ 0xcd, 0x06, 0x0c, 0xc0, 0xcd, 0x90, 0x07, 0x4d,
+ 0x42, 0x52, 0x00, 0x01, 0x00, 0x00, 0x11, 0x00,
+ 0x00, 0x37, 0xcd, 0x98, 0x0b, 0xcd, 0x83, 0x0b,
+ 0xc0, 0xcd, 0x90, 0x07, 0x20, 0x54, 0x79, 0x70,
+ 0x65, 0x00, 0x3a, 0xc2, 0xff, 0xcd, 0x6c, 0x07,
+ 0x32, 0x46, 0xfd, 0xfe, 0x04, 0xca, 0x12, 0x0a,
+ 0xfe, 0x06, 0xca, 0x12, 0x0a, 0xfe, 0x86, 0xc2,
+ 0x6d, 0x0b, 0x21, 0xc6, 0xff, 0x11, 0x47, 0xfd,
+ 0x06, 0x08, 0xcd, 0x43, 0x0e, 0xcd, 0x90, 0x07,
+ 0x20, 0x50, 0x42, 0x52, 0x00, 0x21, 0x47, 0xfd,
+ 0xcd, 0xe5, 0x0d, 0xcd, 0x98, 0x0b, 0xcd, 0x83,
+ 0x0b, 0xc0, 0x21, 0x0b, 0xfe, 0x11, 0x4f, 0xfd,
+ 0x06, 0x0a, 0xcd, 0x43, 0x0e, 0xeb, 0x2b, 0x2b,
+ 0x7e, 0x23, 0xb6, 0xc2, 0x51, 0x0a, 0x2b, 0xeb,
+ 0x21, 0x20, 0xfe, 0xcd, 0x41, 0x0e, 0xc3, 0x58,
+ 0x0a, 0xaf, 0x23, 0x77, 0x23, 0x77, 0x23, 0xeb,
+ 0x21, 0x1c, 0xfe, 0xcd, 0x41, 0x0e, 0x21, 0x16,
+ 0xfe, 0xcd, 0x3c, 0x0e, 0x2a, 0x52, 0xfd, 0xeb,
+ 0x2a, 0x47, 0xfd, 0x19, 0x22, 0x61, 0xfd, 0x2a,
+ 0x49, 0xfd, 0xd2, 0x76, 0x0a, 0x23, 0x22, 0x63,
+ 0xfd, 0x3a, 0x54, 0xfd, 0x47, 0x2a, 0x5f, 0xfd,
+ 0xeb, 0x21, 0x00, 0x00, 0x19, 0x05, 0xc2, 0x84,
+ 0x0a, 0xeb, 0x2a, 0x61, 0xfd, 0x19, 0x22, 0x65,
+ 0xfd, 0x2a, 0x63, 0xfd, 0xd2, 0x98, 0x0a, 0x23,
+ 0x22, 0x67, 0xfd, 0x06, 0x10, 0x2a, 0x4f, 0xfd,
+ 0xeb, 0x2a, 0x55, 0xfd, 0x7b, 0x1f, 0xda, 0xd3,
+ 0x0a, 0x7d, 0x1f, 0xda, 0xd3, 0x0a, 0x7a, 0x1f,
+ 0x57, 0x7b, 0x1f, 0x5f, 0x7c, 0x1f, 0x67, 0x7d,
+ 0x1f, 0x6f, 0x05, 0xc2, 0xa4, 0x0a, 0xcd, 0x90,
+ 0x07, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20,
+ 0x44, 0x41, 0x54, 0x41, 0x53, 0x54, 0x41, 0x52,
+ 0x54, 0x00, 0xc9, 0x06, 0x05, 0x29, 0xda, 0xbe,
+ 0x0a, 0x05, 0xc2, 0xd5, 0x0a, 0x7b, 0x2f, 0x4f,
+ 0x7a, 0x2f, 0x47, 0x03, 0x11, 0xff, 0xff, 0x09,
+ 0x13, 0xda, 0xe7, 0x0a, 0x2a, 0x65, 0xfd, 0x19,
+ 0x22, 0x69, 0xfd, 0x2a, 0x67, 0xfd, 0xd2, 0xfa,
+ 0x0a, 0x23, 0x22, 0x6b, 0xfd, 0x3a, 0x51, 0xfd,
+ 0x3d, 0x32, 0x3d, 0xfd, 0x3c, 0xca, 0x57, 0x0b,
+ 0x01, 0x00, 0x08, 0x1f, 0xd2, 0x11, 0x0b, 0x50,
+ 0x0c, 0x05, 0xc2, 0x0b, 0x0b, 0x3e, 0x01, 0xb9,
+ 0xc2, 0x2b, 0x0b, 0x7a, 0x2f, 0xc6, 0x0a, 0x32,
+ 0x38, 0xfd, 0x21, 0x7b, 0x0e, 0x11, 0x8b, 0x0e,
+ 0xc3, 0x30, 0x0b, 0x21, 0x5f, 0x0e, 0xe5, 0xd1,
+ 0x22, 0x36, 0xfd, 0xeb, 0x22, 0x3b, 0xfd, 0xcd,
+ 0x90, 0x07, 0x20, 0x56, 0x4f, 0x4c, 0x3d, 0x00,
+ 0x21, 0x2b, 0xfe, 0x06, 0x0b, 0xcd, 0x98, 0x07,
+ 0xcd, 0x90, 0x07, 0x20, 0x53, 0x59, 0x53, 0x3d,
+ 0x00, 0x06, 0x08, 0xcd, 0x98, 0x07, 0xc9, 0xcd,
+ 0x90, 0x07, 0x0d, 0x0a, 0x45, 0x72, 0x72, 0x6f,
+ 0x72, 0x3d, 0x30, 0x20, 0x53, 0x65, 0x63, 0x2f,
+ 0x43, 0x6c, 0x75, 0x73, 0x00, 0xcd, 0x90, 0x07,
+ 0x0d, 0x0a, 0x46, 0x41, 0x54, 0x20, 0x49, 0x6e,
+ 0x69, 0x74, 0x20, 0x46, 0x41, 0x49, 0x4c, 0x45,
+ 0x44, 0x00, 0xc9, 0xcd, 0x90, 0x07, 0x20, 0x53,
+ 0x00, 0x2b, 0x3e, 0xaa, 0xbe, 0xc2, 0x6d, 0x0b,
+ 0x2b, 0x3e, 0x55, 0xbe, 0xc2, 0x6d, 0x0b, 0xc9,
+ 0x21, 0x78, 0xfd, 0xda, 0xa2, 0x0b, 0xcd, 0x1a,
+ 0x0e, 0xc8, 0x21, 0x78, 0xfd, 0xcd, 0xed, 0x0d,
+ 0xcd, 0xeb, 0x0b, 0x06, 0x05, 0x3e, 0x11, 0xcd,
+ 0x0b, 0x0d, 0xca, 0xbe, 0x0b, 0x05, 0xc2, 0xad,
+ 0x0b, 0x05, 0xcd, 0xf3, 0x0c, 0xc9, 0x06, 0x00,
+ 0xcd, 0x51, 0x0d, 0xfe, 0xfe, 0xca, 0xd0, 0x0b,
+ 0x05, 0xc2, 0xc0, 0x0b, 0xcd, 0xf3, 0x0c, 0xc9,
+ 0x01, 0x00, 0x02, 0xcd, 0x51, 0x0d, 0x77, 0x23,
+ 0x0d, 0xc2, 0xd3, 0x0b, 0x05, 0xc2, 0xd3, 0x0b,
+ 0xcd, 0x51, 0x0d, 0xcd, 0x51, 0x0d, 0xcd, 0xf3,
+ 0x0c, 0xaf, 0xc9, 0x3a, 0x40, 0xfd, 0xfe, 0x03,
+ 0xca, 0xfc, 0x0b, 0x79, 0xeb, 0x29, 0x17, 0x47,
+ 0x4c, 0x55, 0x1e, 0x00, 0x21, 0x42, 0xfd, 0xcd,
+ 0xed, 0x0d, 0x21, 0x00, 0xfe, 0xc9, 0xcd, 0xf3,
+ 0x0c, 0x0e, 0x80, 0x3e, 0xff, 0x32, 0x40, 0xfd,
+ 0xd3, 0x30, 0x0d, 0xc2, 0x10, 0x0c, 0xcd, 0xfa,
+ 0x0c, 0xcd, 0x90, 0x07, 0x0d, 0x0a, 0x49, 0x6e,
+ 0x69, 0x74, 0x20, 0x53, 0x44, 0x00, 0xcd, 0x7b,
+ 0x0d, 0x06, 0x00, 0x3e, 0x00, 0xcd, 0x0b, 0x0d,
+ 0xfe, 0x01, 0xca, 0x4a, 0x0c, 0x05, 0xc2, 0x2b,
+ 0x0c, 0xcd, 0x90, 0x07, 0x2d, 0x46, 0x41, 0x49,
+ 0x4c, 0x45, 0x44, 0x00, 0xcd, 0xf3, 0x0c, 0xaf,
+ 0x3d, 0xc9, 0xcd, 0x90, 0x07, 0x20, 0x54, 0x79,
+ 0x70, 0x65, 0x23, 0x00, 0x21, 0xaa, 0x01, 0x22,
+ 0x42, 0xfd, 0x3e, 0x08, 0xcd, 0x0b, 0x0d, 0xe6,
+ 0x04, 0xca, 0x6c, 0x0c, 0x3e, 0x01, 0x32, 0x40,
+ 0xfd, 0xc3, 0x87, 0x0c, 0xcd, 0x51, 0x0d, 0xcd,
+ 0x51, 0x0d, 0xcd, 0x51, 0x0d, 0xcd, 0x51, 0x0d,
+ 0x32, 0x41, 0xfd, 0xfe, 0xaa, 0x3e, 0xaa, 0xc2,
+ 0x39, 0x0c, 0x3e, 0x02, 0x32, 0x40, 0xfd, 0xcd,
+ 0x7b, 0x07, 0xcd, 0x90, 0x07, 0x20, 0x41, 0x43,
+ 0x4d, 0x44, 0x34, 0x31, 0x00, 0xcd, 0x7b, 0x0d,
+ 0x06, 0x00, 0x3e, 0x37, 0xcd, 0x0b, 0x0d, 0x3e,
+ 0x29, 0xcd, 0x0b, 0x0d, 0xfe, 0x00, 0xca, 0xb4,
+ 0x0c, 0xaf, 0xcd, 0x06, 0x0d, 0x05, 0xc2, 0x9a,
+ 0x0c, 0xc3, 0x39, 0x0c, 0xcd, 0x90, 0x07, 0x2b,
+ 0x00, 0x3a, 0x40, 0xfd, 0xfe, 0x02, 0xc2, 0xee,
+ 0x0c, 0x3e, 0x3a, 0xcd, 0x0b, 0x0d, 0xfe, 0x00,
+ 0xc2, 0x39, 0x0c, 0xcd, 0x51, 0x0d, 0xe6, 0xc0,
+ 0xfe, 0xc0, 0xc2, 0xe5, 0x0c, 0x3e, 0x03, 0x32,
+ 0x40, 0xfd, 0xcd, 0x90, 0x07, 0x20, 0x54, 0x79,
+ 0x70, 0x65, 0x23, 0x33, 0x00, 0xcd, 0x51, 0x0d,
+ 0xcd, 0x51, 0x0d, 0xcd, 0x51, 0x0d, 0xcd, 0xf3,
+ 0x0c, 0xaf, 0xc9, 0xf5, 0x3e, 0x01, 0xd3, 0x31,
+ 0xf1, 0xc9, 0xf5, 0x3e, 0x00, 0xd3, 0x31, 0xcd,
+ 0x04, 0x0d, 0xf1, 0xc9, 0x3e, 0x0d, 0x3d, 0xc2,
+ 0x06, 0x0d, 0xc9, 0xc5, 0xcd, 0xfa, 0x0c, 0xcd,
+ 0x59, 0x0d, 0x06, 0xff, 0xfe, 0x00, 0xc2, 0x1b,
+ 0x0d, 0x06, 0x95, 0xfe, 0x08, 0xc2, 0x22, 0x0d,
+ 0x06, 0x87, 0xf6, 0x40, 0xd3, 0x30, 0x3a, 0x45,
+ 0xfd, 0xd3, 0x30, 0x3a, 0x44, 0xfd, 0xd3, 0x30,
+ 0x3a, 0x43, 0xfd, 0xd3, 0x30, 0x3a, 0x42, 0xfd,
+ 0xd3, 0x30, 0x00, 0x78, 0xd3, 0x30, 0x06, 0x00,
+ 0xcd, 0x51, 0x0d, 0x32, 0x41, 0xfd, 0xb7, 0xf2,
+ 0x4f, 0x0d, 0x05, 0xc2, 0x40, 0x0d, 0xb7, 0xc1,
+ 0xc9, 0x3e, 0xff, 0xd3, 0x30, 0x00, 0xdb, 0x30,
+ 0xc9, 0xf5, 0xc5, 0x06, 0x00, 0x0e, 0x01, 0xcd,
+ 0x51, 0x0d, 0x3c, 0xc2, 0x6f, 0x0d, 0x0d, 0xc2,
+ 0x5f, 0x0d, 0xc1, 0xf1, 0x37, 0x3f, 0xc9, 0xaf,
+ 0xcd, 0x06, 0x0d, 0x05, 0xc2, 0x5d, 0x0d, 0xc1,
+ 0xf1, 0x37, 0xc9, 0xaf, 0x32, 0x42, 0xfd, 0x32,
+ 0x43, 0xfd, 0x32, 0x44, 0xfd, 0x32, 0x45, 0xfd,
+ 0xc9, 0xcd, 0xa2, 0x07, 0xfe, 0x1b, 0x37, 0xc8,
+ 0xfe, 0x0d, 0xc8, 0xb9, 0xc8, 0xcd, 0xa6, 0x0d,
+ 0xfe, 0x21, 0xda, 0x89, 0x0d, 0x05, 0x04, 0xc8,
+ 0x77, 0x23, 0x05, 0xc3, 0x89, 0x0d, 0xfe, 0x61,
+ 0xd8, 0xfe, 0x7b, 0xd0, 0xe6, 0x5f, 0xc9, 0xe5,
+ 0x06, 0x08, 0x7e, 0xb7, 0xca, 0xc4, 0x0d, 0xfe,
+ 0x20, 0xca, 0xc4, 0x0d, 0xcd, 0xc3, 0x07, 0x23,
+ 0x05, 0xc2, 0xb2, 0x0d, 0x3e, 0x2e, 0xcd, 0xc3,
+ 0x07, 0xe1, 0xe5, 0x01, 0x08, 0x00, 0x09, 0x06,
+ 0x03, 0x7e, 0xb7, 0xca, 0xe3, 0x0d, 0xfe, 0x20,
+ 0xca, 0xe3, 0x0d, 0xcd, 0xc3, 0x07, 0x23, 0x05,
+ 0xc2, 0xd1, 0x0d, 0xe1, 0xc9, 0x5e, 0x23, 0x56,
+ 0x23, 0x4e, 0x23, 0x46, 0xc9, 0x73, 0x23, 0x72,
+ 0x23, 0x71, 0x23, 0x70, 0xc9, 0x7b, 0x86, 0x5f,
+ 0x23, 0x7a, 0x8e, 0x57, 0x23, 0x79, 0x8e, 0x4f,
+ 0x23, 0x78, 0x8e, 0x47, 0xc9, 0x13, 0x7a, 0xb3,
+ 0xc0, 0x03, 0xc9, 0x7a, 0xb3, 0xc2, 0x11, 0x0e,
+ 0x0b, 0x1b, 0xc9, 0x7a, 0xb3, 0xc0, 0xb1, 0xc0,
+ 0xb0, 0xc9, 0x23, 0x23, 0x23, 0x78, 0xbe, 0xc2,
+ 0x32, 0x0e, 0x2b, 0x79, 0xbe, 0xc2, 0x33, 0x0e,
+ 0x2b, 0x7a, 0xbe, 0xc2, 0x34, 0x0e, 0x2b, 0x7b,
+ 0xbe, 0xc9, 0x2b, 0x2b, 0x2b, 0xc9, 0x7a, 0xbc,
+ 0xc0, 0x7b, 0xbd, 0xc9, 0x06, 0x02, 0xc3, 0x43,
+ 0x0e, 0x06, 0x04, 0x7e, 0x12, 0x23, 0x13, 0x05,
+ 0xc2, 0x43, 0x0e, 0xc9, 0x7e, 0x23, 0x66, 0x6f,
+ 0xc9, 0xf5, 0xc5, 0xe5, 0x77, 0x23, 0x05, 0xc2,
+ 0x54, 0x0e, 0xe1, 0xc1, 0xf1, 0xc9, 0xe9, 0x3a,
+ 0x51, 0xfd, 0xeb, 0x1e, 0x00, 0x47, 0x0e, 0x08,
+ 0x29, 0x7b, 0x07, 0x5f, 0x7c, 0x90, 0xda, 0x73,
+ 0x0e, 0x67, 0x1c, 0x0d, 0xc2, 0x68, 0x0e, 0x7c,
+ 0x16, 0x00, 0xc9, 0x3a, 0x38, 0xfd, 0x47, 0x05,
+ 0xc8, 0xb7, 0x7a, 0x1f, 0x57, 0x7b, 0x1f, 0x5f,
+ 0xc3, 0x7f, 0x0e, 0x3a, 0x3d, 0xfd, 0xa3, 0xc9
+ };
+
+static uint8 jair_ram[JAIR_ROM_SIZE] = {0};
+
+/*********************/
+/* JAIR Definitions */
+/*********************/
+
+/*
+** PORT ASSIGNMENTS
+*/
+#define JAIR_CPU_IO 0x20 /* BASE ADDRESS FOR ONBOARD CPU I/O */
+#define JAIR_UART0 JAIR_CPU_IO /* UART0 OFFSET */
+#define JAIR_UART1 JAIR_CPU_IO + 0x08 /* UART1 OFFSET */
+#define JAIR_SPI JAIR_CPU_IO + 0x10 /* SPI OFFSET */
+#define JAIR_SPI_SS JAIR_CPU_IO + 0x11 /* SPI_SS OFFSET */
+#define JAIR_PPORT JAIR_CPU_IO + 0x18 /* PPORT OFFSET */
+
+#define JAIR_SDATA 0x00 /* 8250 SERIAL DATA */
+#define JAIR_IER 0x01 /* 8250 INTERRUPT ENABLE REGISTER */
+#define JAIR_IIR 0x02 /* 8250 INTERRUPT IDENT REGISTER */
+#define JAIR_LCR 0x03 /* 8250 LINE CONTROL REGISTER */
+#define JAIR_MCR 0x04 /* 8250 MODEM CONTROL REGISTER */
+#define JAIR_LSR 0x05 /* 8250 LINE STATUS REGISTER */
+#define JAIR_MSR 0x06 /* 8250 MODEM STATUS REGISTER */
+#define JAIR_SR 0x07 /* 8250 SCRATCH REGISTER */
+
+/*
+** BIT ASSIGNMENT MASKS
+*/
+#define JAIR_DR 0x01 /* SERIAL DATA READY */
+#define JAIR_THRE 0x20 /* SERIAL TRANSMITTER BUFFER EMPTY */
+#define JAIR_TEMT 0x40 /* SERIAL TRANSMITTER BUFFER EMPTY */
+#define JAIR_DLAB 0x80 /* DIVISOR LATCH ACCESS BIT */
+
+#define JAIR_DCTS 0x01 /* Clear to Send (Delta) */
+#define JAIR_DDSR 0x02 /* Data Set Ready (Delta) */
+#define JAIR_DRNG 0x04 /* Ring Indicate (Delta) */
+#define JAIR_DDCD 0x08 /* Data Carrier Detect (Delta) */
+#define JAIR_CTS 0x10 /* Clear to Send */
+#define JAIR_DSR 0x20 /* Data Set Ready */
+#define JAIR_RNG 0x40 /* Ring Indicate */
+#define JAIR_DCD 0x80 /* Data Carrier Detect */
+#define JAIR_DTR 0x01 /* Data Terminal Ready */
+#define JAIR_RTS 0x02 /* Request to Send */
+
+#define JAIR_STATE_IDLE 0 /* idle */
+#define JAIR_STATE_CMD 1 /* receiving command */
+#define JAIR_STATE_RESP 2 /* sending response */
+#define JAIR_STATE_SBLK 3 /* start block */
+#define JAIR_STATE_WBLK 4 /* write block */
+
+/*
+** SD Commands
+*/
+#define JAIR_CMD0 0
+#define JAIR_CMD8 8 /* send if condition */
+#define JAIR_CMD13 13 /* send status */
+#define JAIR_CMD17 17 /* read single block */
+#define JAIR_CMD24 24 /* write single block */
+#define JAIR_CMD55 55 /* application command */
+#define JAIR_ACMD41 41 + 0x80 /* send op condition */
+
+/****************/
+/* JAIR Device */
+/****************/
+
+#define JAIR_NAME "Josh's Altair / IMASI Replacement CPU & SBC"
+#define JAIR_SNAME "JAIR"
+
+#define JAIR_UNITS 1
+
+#define UNIT_V_JAIR_VERBOSE (UNIT_V_UF + 0) /* VERBOSE / QUIET */
+#define UNIT_JAIR_VERBOSE (1 << UNIT_V_JAIR_VERBOSE)
+#define UNIT_V_JAIR_WPROTECT (UNIT_V_UF + 1) /* WRTENB / WRTPROT */
+#define UNIT_JAIR_WPROTECT (1 << UNIT_V_JAIR_WPROTECT)
+#define UNIT_V_JAIR_ROM (UNIT_V_UF + 2) /* WRTENB / WRTPROT */
+#define UNIT_JAIR_ROM (1 << UNIT_V_JAIR_ROM)
+
+/*
+** JAIR Registers and Interface Controls
+*/
+
+typedef struct {
+ uint32 rom_base; /* Memory Base Address */
+ uint32 rom_size; /* Memory Address space requirement */
+ uint32 io_base; /* I/O Base Address */
+ uint32 io_size; /* I/O Address Space requirement */
+ t_bool sr_ena; /* Shadow ROM enable */
+ t_bool spi_cs; /* SPI *CS (Active Low) */
+ uint8 sd_istate; /* SD Card Input State */
+ uint8 sd_ostate; /* SD Card Output State */
+ uint8 sd_cmd[512+6]; /* SD Card Command */
+ uint16 sd_cmd_len;
+ uint16 sd_cmd_idx;
+ uint8 sd_resp[512+6]; /* SD Card Response */
+ uint16 sd_resp_len;
+ uint16 sd_resp_idx;
+ t_bool sd_appcmd; /* SD app command flag */
+} JAIR_CTX;
+
+static JAIR_CTX jair_ctx = {
+ JAIR_ROM_BASE, JAIR_ROM_SIZE, JAIR_SPI, 2
+};
+
+static UNIT jair_unit[] = {
+ { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE + UNIT_JAIR_ROM, 0) }
+};
+
+static REG jair_reg[] = {
+ { NULL }
+};
+
+static MTAB jair_mod[] = {
+ { MTAB_XTD|MTAB_VDV, 0, "PORT", "PORT",
+ NULL, jair_show_ports, NULL, "I/O port address" },
+ { UNIT_JAIR_ROM, UNIT_JAIR_ROM, "ROM", "ROM", &jair_set_rom,
+ NULL, NULL, "Enable JAIR ROM" },
+ { UNIT_JAIR_ROM, 0, "NOROM", "NOROM", &jair_set_norom,
+ NULL, NULL, "Disable JAIR ROM"},
+ { 0 }
+};
+
+DEVICE jair_dev = {
+ JAIR_SNAME, /* name */
+ jair_unit, /* unit */
+ jair_reg, /* registers */
+ jair_mod, /* modifiers */
+ JAIR_UNITS, /* # units */
+ 10, /* address radix */
+ 31, /* address width */
+ 1, /* addr increment */
+ 8, /* data radix */
+ 8, /* data width */
+ NULL, /* examine routine */
+ NULL, /* deposit routine */
+ &jair_reset, /* reset routine */
+ &jair_boot, /* boot routine */
+ &jair_attach, /* attach routine */
+ &jair_detach, /* detach routine */
+ &jair_ctx, /* context */
+ (DEV_DISABLE | DEV_DIS | DEV_DEBUG), /* flags */
+ ERROR_MSG, /* debug control */
+ jair_dt, /* debug flags */
+ NULL, /* mem size routine */
+ NULL, /* logical name */
+ &jair_help, /* help */
+ NULL, /* attach help */
+ NULL, /* context for help */
+ &jair_description /* description */
+};
+
+/****************/
+/* GENERIC PORT */
+/****************/
+
+typedef struct {
+ PNP_INFO pnp; /* Must be first */
+ int32 conn; /* Connected Status */
+ uint16 baud; /* Baud rate */
+ uint8 status; /* Status Byte */
+ uint8 rdr; /* Receive Data Ready */
+ uint8 rxd; /* Receive Data Buffer */
+ uint8 txd; /* Transmit Data Buffer */
+ t_bool txp; /* Transmit Data Pending */
+ uint8 ier; /* Interrupt Enable Register */
+ uint8 iir; /* Interrupt Ident Register */
+ uint8 lcr; /* Line Control Register */
+ uint8 mcr; /* Modem Control Register */
+ uint8 lsr; /* Line Status Register */
+ uint8 msr; /* Modem Status Register */
+ uint8 sr; /* Scratch Register */
+ uint8 dlls; /* Divisor Latch LS */
+ uint8 dlms; /* Divisor Latch MS */
+ TMLN *tmln; /* TMLN pointer */
+ TMXR *tmxr; /* TMXR pointer */
+} JAIR_PORT_CTX;
+
+/**************************/
+/* JAIRS0 Keyboard Device */
+/**************************/
+
+#define JAIRS0_NAME "JAIR Serial Port 0"
+#define JAIRS0_SNAME "JAIRS0"
+
+static TMLN jairs0_tmln[1] = { /* line descriptors */
+ { 0 }
+};
+
+static TMXR jairs0_tmxr = { /* multiplexer descriptor */
+ 1, /* number of terminal lines */
+ 0, /* listening port (reserved) */
+ 0, /* master socket (reserved) */
+ jairs0_tmln, /* line descriptor array */
+ NULL, /* line connection order */
+ NULL /* multiplexer device (derived internally) */
+};
+
+static JAIR_PORT_CTX jairs0_ctx = {
+ {0, 0, JAIR_UART0, 8}, 0, 9600, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ jairs0_tmln, &jairs0_tmxr
+};
+
+static REG jairs0_reg[] = {
+ { DRDATAD (BAUD0, jairs0_ctx.baud, 16, "Serial port baud register"), },
+ { HRDATAD (TXP0, jairs0_ctx.txp, 1, "Serial port TX data pending"), },
+ { HRDATAD (TXD0, jairs0_ctx.txd, 8, "Serial port TX data register"), },
+ { HRDATAD (RDR0, jairs0_ctx.rdr, 1, "Serial port RX data ready"), },
+ { HRDATAD (RXD0, jairs0_ctx.rxd, 8, "Serial port RX register"), },
+ { HRDATAD (LSR0, jairs0_ctx.lsr, 8, "Serial port line status register"), },
+ { HRDATAD (MSR0, jairs0_ctx.msr, 8, "Serial port modem status register"), },
+ { NULL }
+};
+
+
+static UNIT jairs0_unit[] = {
+ { UDATA (&jair_svc, UNIT_ATTABLE, 0), (int) USECS_PER_SECOND / 1000 }
+};
+
+static MTAB jairs0_mod[] = {
+ { MTAB_XTD|MTAB_VDV, 0, "PORT", "PORT",
+ NULL, jair_show_ports, NULL, "Show serial I/O ports" },
+ { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "BAUD", "BAUD",
+ &jair_set_baud, &jair_show_baud, NULL, "Set baud rate (default=9600)" },
+ { 0 }
+};
+
+DEVICE jairs0_dev = {
+ JAIRS0_SNAME, /* name */
+ jairs0_unit, /* unit */
+ jairs0_reg, /* registers */
+ jairs0_mod, /* modifiers */
+ 1, /* # units */
+ 10, /* address radix */
+ 31, /* address width */
+ 1, /* addr increment */
+ 8, /* data radix */
+ 8, /* data width */
+ NULL, /* examine routine */
+ NULL, /* deposit routine */
+ &jair_port_reset, /* reset routine */
+ NULL, /* boot routine */
+ &jair_attach_mux, /* attach routine */
+ &jair_detach_mux, /* detach routine */
+ &jairs0_ctx, /* context */
+ (DEV_DISABLE | DEV_DIS | DEV_DEBUG | DEV_MUX), /* flags */
+ ERROR_MSG, /* debug control */
+ jair_dt, /* debug flags */
+ NULL, /* mem size routine */
+ NULL, /* logical name */
+ NULL, /* help */
+ NULL, /* attach help */
+ NULL, /* context for help */
+ &jairs0_description /* description */
+};
+
+/************************/
+/* JAIRS1 Serial Device */
+/************************/
+
+#define JAIRS1_NAME "JAIR Serial Port 1"
+#define JAIRS1_SNAME "JAIRS1"
+
+static TMLN jairs1_tmln[1] = { /* line descriptors */
+ { 0 }
+};
+
+static TMXR jairs1_tmxr = { /* multiplexer descriptor */
+ 1, /* number of terminal lines */
+ 0, /* listening port (reserved) */
+ 0, /* master socket (reserved) */
+ jairs1_tmln, /* line descriptor array */
+ NULL, /* line connection order */
+ NULL /* multiplexer device (derived internally) */
+};
+
+static JAIR_PORT_CTX jairs1_ctx = {
+ {0, 0, JAIR_UART1, 8}, 0, 9600, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ jairs1_tmln, &jairs1_tmxr
+};
+
+static REG jairs1_reg[] = {
+ { DRDATAD (BAUD1, jairs1_ctx.baud, 16, "Serial port baud register"), },
+ { HRDATAD (TXP1, jairs1_ctx.txp, 1, "Serial port TX data pending"), },
+ { HRDATAD (TXD1, jairs1_ctx.txd, 8, "Serial port TX data register"), },
+ { HRDATAD (RDR1, jairs1_ctx.rdr, 1, "Serial port RX data ready"), },
+ { HRDATAD (RXD1, jairs1_ctx.rxd, 8, "Serial port RX register"), },
+ { HRDATAD (LSR1, jairs1_ctx.lsr, 8, "Serial port line status register"), },
+ { HRDATAD (MSR1, jairs1_ctx.msr, 8, "Serial port modem status register"), },
+ { NULL }
+};
+
+static UNIT jairs1_unit[] = {
+ { UDATA (&jair_svc, UNIT_ATTABLE, 0), (int) USECS_PER_SECOND / 1000 }
+};
+
+static MTAB jairs1_mod[] = {
+ { MTAB_XTD|MTAB_VDV, 0, "PORT", "PORT",
+ NULL, jair_show_ports, NULL, "Show serial I/O ports" },
+ { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "BAUD", "BAUD",
+ &jair_set_baud, &jair_show_baud, NULL, "Set baud rate (default=9600)" },
+ { 0 }
+};
+
+DEVICE jairs1_dev = {
+ JAIRS1_SNAME, /* name */
+ jairs1_unit, /* unit */
+ jairs1_reg, /* registers */
+ jairs1_mod, /* modifiers */
+ 1, /* # units */
+ 10, /* address radix */
+ 31, /* address width */
+ 1, /* addr increment */
+ 8, /* data radix */
+ 8, /* data width */
+ NULL, /* examine routine */
+ NULL, /* deposit routine */
+ &jair_port_reset, /* reset routine */
+ NULL, /* boot routine */
+ &jair_attach_mux, /* attach routine */
+ &jair_detach_mux, /* detach routine */
+ &jairs1_ctx, /* context */
+ (DEV_DISABLE | DEV_DIS | DEV_DEBUG | DEV_MUX), /* flags */
+ ERROR_MSG, /* debug control */
+ jair_dt, /* debug flags */
+ NULL, /* mem size routine */
+ NULL, /* logical name */
+ NULL, /* help */
+ NULL, /* attach help */
+ NULL, /* context for help */
+ &jairs1_description /* description */
+};
+
+/***********************/
+/* JAIRP Parallel Port */
+/***********************/
+
+#define JAIRP_NAME "JAIR Parallel Port"
+#define JAIRP_SNAME "JAIRP"
+
+static TMLN jairp_tmln[1] = { /* line descriptors */
+ { 0 }
+};
+
+static TMXR jairp_tmxr = { /* multiplexer descriptor */
+ 1, /* number of terminal lines */
+ 0, /* listening port (reserved) */
+ 0, /* master socket (reserved) */
+ jairp_tmln, /* line descriptor array */
+ NULL, /* line connection order */
+ NULL /* multiplexer device (derived internally) */
+};
+
+static JAIR_PORT_CTX jairp_ctx = {
+ {0, 0, JAIR_PPORT, 1}, 0, 9600, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ jairp_tmln, &jairp_tmxr
+};
+
+static REG jairp_reg[] = {
+ { DRDATAD (BAUDP, jairp_ctx.baud, 16, "Serial port baud register"), },
+ { HRDATAD (TXPP, jairp_ctx.txp, 1, "Printer port tx pending"), },
+ { HRDATAD (TXDP, jairp_ctx.txd, 8, "Printer port data register"), },
+ { HRDATAD (RDRP, jairp_ctx.rdr, 1, "Printer port RX data ready"), },
+ { HRDATAD (RXDP, jairp_ctx.rxd, 8, "Printer port RX data register"), },
+ { NULL }
+};
+
+static UNIT jairp_unit[] = {
+ { UDATA (&jair_svc, UNIT_ATTABLE, 0), (int) USECS_PER_SECOND / 1000 }
+};
+
+static MTAB jairp_mod[] = {
+ { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "BAUD", "BAUD",
+ &jair_set_baud, &jair_show_baud, NULL, "Set baud rate (default=9600)" },
+ { 0 }
+};
+
+DEVICE jairp_dev = {
+ JAIRP_SNAME, /* name */
+ jairp_unit, /* unit */
+ jairp_reg, /* registers */
+ jairp_mod, /* modifiers */
+ 1, /* # units */
+ 10, /* address radix */
+ 31, /* address width */
+ 1, /* addr increment */
+ 8, /* data radix */
+ 8, /* data width */
+ NULL, /* examine routine */
+ NULL, /* deposit routine */
+ &jair_port_reset, /* reset routine */
+ NULL, /* boot routine */
+ &jair_attach_mux, /* attach routine */
+ &jair_detach_mux, /* detach routine */
+ &jairp_ctx, /* context */
+ (DEV_DISABLE | DEV_DIS | DEV_DEBUG | DEV_MUX), /* flags */
+ ERROR_MSG, /* debug control */
+ jair_dt, /* debug flags */
+ NULL, /* mem size routine */
+ NULL, /* logical name */
+ NULL, /* help */
+ NULL, /* attach help */
+ NULL, /* context for help */
+ &jairp_description /* description */
+};
+
+static const char* jair_description(DEVICE *dptr) {
+ return JAIR_NAME;
+}
+
+static const char* jairs0_description(DEVICE *dptr) {
+ return JAIRS0_NAME;
+}
+
+static const char* jairs1_description(DEVICE *dptr) {
+ return JAIRS1_NAME;
+}
+
+static const char* jairp_description(DEVICE *dptr) {
+ return JAIRP_NAME;
+}
+
+/*
+ * Reset function for the main JAIR device.
+ *
+ * Enables all other Sol-20 devices
+ */
+static t_stat jair_reset(DEVICE *dptr)
+{
+ static t_bool first = TRUE;
+
+ if (dptr->flags & DEV_DIS) { /* Disconnect Resources */
+ sim_map_resource(jair_ctx.io_base, jair_ctx.io_size, RESOURCE_TYPE_IO, &jairio, "jairio", TRUE);
+ sim_map_resource(jair_ctx.rom_base, jair_ctx.rom_size, RESOURCE_TYPE_MEMORY, &jair_shadow_rom, "jairrom", TRUE);
+ }
+ else {
+ /* Connect I/O Ports at base address */
+ if (sim_map_resource(jair_ctx.io_base, jair_ctx.io_size, RESOURCE_TYPE_IO, &jairio, "jairio", FALSE) != 0) {
+ sim_debug(ERROR_MSG, &jair_dev, "Error mapping I/O resource at 0x%02x\n", jair_ctx.io_base);
+ return SCPE_ARG;
+ }
+ if (sim_map_resource(jair_ctx.rom_base, jair_ctx.rom_size, RESOURCE_TYPE_MEMORY, &jair_shadow_rom, "jairrom", FALSE) != 0) {
+ sim_debug(ERROR_MSG, &jair_dev, "Error mapping ROM resource at 0x%02x\n", jair_ctx.io_base);
+ return SCPE_ARG;
+ }
+
+ if (first) {
+ set_dev_enbdis(&jairs0_dev, NULL, 1, NULL);
+ set_dev_enbdis(&jairs1_dev, NULL, 1, NULL);
+ set_dev_enbdis(&jairp_dev, NULL, 1, NULL);
+
+ first = FALSE;
+ }
+ }
+
+ jair_ctx.sr_ena = TRUE;
+ jair_ctx.spi_cs = TRUE;
+ jair_ctx.sd_appcmd = FALSE;
+ jair_ctx.sd_istate = JAIR_STATE_IDLE;
+ jair_ctx.sd_ostate = JAIR_STATE_IDLE;
+
+ sim_debug(STATUS_MSG, &jair_dev, "reset controller.\n");
+
+ return SCPE_OK;
+}
+
+/*
+ * The BOOT command will enter the ROM at 0x0000
+ */
+static t_stat jair_boot(int32 unitno, DEVICE *dptr)
+{
+ sim_printf("%s: Booting using ROM at 0x%04x\n", JAIR_SNAME, jair_ctx.rom_base);
+
+ *((int32 *) sim_PC->loc) = jair_ctx.rom_base;
+
+ return SCPE_OK;
+}
+
+static t_stat jair_port_reset(DEVICE *dptr) {
+ JAIR_PORT_CTX *port;
+ uint32 u;
+
+ port = (JAIR_PORT_CTX *) dptr->ctxt;
+
+ for (u = 0; u < dptr->numunits; u++) {
+ dptr->units[u].dptr = dptr;
+ }
+
+ if (dptr->flags & DEV_DIS) { /* Disconnect I/O Port(s) */
+ sim_map_resource(port->pnp.io_base, port->pnp.io_size, RESOURCE_TYPE_IO, &jairio, dptr->name, TRUE);
+ for (u = 0; u < dptr->numunits; u++) {
+ sim_cancel(&dptr->units[u]); /* cancel timer */
+ }
+ }
+ else {
+ /* Connect I/O Ports at base address */
+ if (sim_map_resource(port->pnp.io_base, port->pnp.io_size, RESOURCE_TYPE_IO, &jairio, dptr->name, FALSE) != 0) {
+ sim_debug(ERROR_MSG, dptr, "Error mapping I/O resource at 0x%02x\n", port->pnp.io_base);
+ return SCPE_ARG;
+ }
+
+ /* Enable TMXR modem control passthrough */
+ tmxr_set_modem_control_passthru(port->tmxr);
+ tmxr_set_port_speed_control(port->tmxr);
+
+ port->status = 0x00;
+ port->rdr = FALSE;
+ port->txp = FALSE;
+ port->lsr = JAIR_TEMT | JAIR_THRE;
+ port->msr = 0;
+
+ for (u = 0; u < dptr->numunits; u++) {
+ sim_activate_after(&dptr->units[u], dptr->units[u].wait); /* activate timer */
+ }
+ }
+
+ return SCPE_OK;
+}
+
+/*
+ * JAIR service routine
+ *
+ * The JAIR simulator has 3 I/O devices
+ *
+ * JAIRS0 - Keyboard device that supports TMXR
+ * JAIRS1 - Serial device that supports TMXR
+ * JAIRP - Parallel device that supports TMXR
+ */
+static t_stat jair_svc(UNIT *uptr)
+{
+ JAIR_PORT_CTX *port;
+ int32 c = 0;
+ int32 s;
+ t_stat r = SCPE_OK;
+ uint8 msr;
+
+ port = (JAIR_PORT_CTX *) uptr->dptr->ctxt;
+
+ /* Check for new incoming connection */
+ if (uptr->dynflags & UNIT_TM_POLL && !port->conn && uptr->flags & UNIT_ATT) {
+ if (tmxr_poll_conn(port->tmxr) >= 0) { /* poll connection */
+
+ port->conn = 1; /* set connected */
+
+ sim_printf("%s: new connection.\n", uptr->dptr->name);
+ }
+ }
+
+ /* TX byte pending? */
+ if (port->txp == TRUE) {
+ if (uptr->flags & UNIT_ATT) {
+ if (uptr->fileref) {
+ r = (sim_fwrite(&port->txd, 1, 1, uptr->fileref) == 1) ? SCPE_OK : SCPE_IOERR;
+ port->txp = FALSE;
+ port->lsr |= (JAIR_TEMT | JAIR_THRE);
+ } else if (port->conn) {
+ if ((r = tmxr_putc_ln(&port->tmln[0], port->txd)) == SCPE_OK) {
+ tmxr_poll_tx(port->tmxr);
+ port->txp = FALSE;
+ } else if (r == SCPE_LOST) {
+ port->conn = 0; /* Connection was lost */
+ sim_printf("%s: lost connection.\n", uptr->dptr->name);
+ } else {
+ sim_printf("%s: tmxr_putc_ln error %d.\n", uptr->dptr->name, r);
+ }
+ }
+ }
+ else {
+ sim_putchar(port->txd);
+ port->txp = FALSE;
+ port->lsr |= (JAIR_TEMT | JAIR_THRE);
+ }
+ }
+
+ /* Update LSR if no character pending */
+ if (port->txp == FALSE && port->conn && !(port->lsr & (JAIR_TEMT | JAIR_THRE))) {
+ port->lsr |= tmxr_txdone_ln(port->tmln) ? (JAIR_TEMT | JAIR_THRE) : 0;
+ }
+
+ /* Check for Data if RX buffer empty */
+ if (port->rdr == FALSE) {
+ if (uptr->flags & UNIT_ATT) {
+ if (uptr->fileref) {
+ if (sim_fread(&c, 1, 1, uptr->fileref) == 1) {
+ c |= SCPE_KFLAG;
+ }
+ }
+ else if (port->conn) {
+ tmxr_poll_rx(port->tmxr);
+ c = tmxr_getc_ln(&port->tmln[0]);
+ }
+ }
+ else if (uptr == jairs0_unit) {
+ c = sim_poll_kbd();
+ }
+
+ if (c & (TMXR_VALID | SCPE_KFLAG)) {
+ port->rxd = c & 0xff;
+ port->rdr = TRUE;
+ port->lsr |= JAIR_DR;
+ }
+ }
+
+ /* Update Modem Status Register */
+ if (uptr->flags & UNIT_ATT && port->conn) {
+ tmxr_set_get_modem_bits(port->tmln, 0, 0, &s);
+
+ msr = port->msr;
+
+ port->msr &= ~JAIR_CTS;
+ port->msr |= (s & TMXR_MDM_CTS) ? JAIR_CTS : 0;
+
+ /* CTS status changed */
+ if ((msr ^ port->msr) & JAIR_CTS) {
+ port->msr |= JAIR_DCTS;
+ sim_debug(STATUS_MSG, uptr->dptr, "CTS state changed to %s.\n", (port->msr & JAIR_CTS) ? "HIGH" : "LOW");
+ }
+
+ port->msr &= ~JAIR_DSR;
+ port->msr |= (s & TMXR_MDM_DSR) ? JAIR_DSR : 0;
+
+ /* DSR status changed */
+ if ((msr ^ port->msr) & JAIR_DSR) {
+ port->msr |= JAIR_DDSR;
+ sim_debug(STATUS_MSG, uptr->dptr, "DSR state changed to %s.\n", (port->msr & JAIR_DSR) ? "HIGH" : "LOW");
+ }
+
+ port->msr &= ~JAIR_RNG;
+ port->msr |= (s & TMXR_MDM_RNG) ? JAIR_RNG : 0;
+
+ /* RI status changed */
+ if ((msr ^ port->msr) & JAIR_RNG) {
+ port->msr |= (port->msr & JAIR_RNG) ? 0 : JAIR_DRNG; /* trailing edge to low */
+ sim_debug(STATUS_MSG, uptr->dptr, "RNG state changed to %s.\n", (port->msr & JAIR_RNG) ? "HIGH" : "LOW");
+ }
+
+ port->msr &= ~JAIR_DCD;
+ port->msr |= (s & TMXR_MDM_DCD) ? JAIR_DCD : 0;
+
+ /* DCD status changed */
+ if ((msr ^ port->msr) & JAIR_DCD) {
+ port->msr |= JAIR_DDCD;
+ sim_debug(STATUS_MSG, uptr->dptr, "DCD state changed to %s.\n", (port->msr & JAIR_DCD) ? "HIGH" : "LOW");
+ }
+ }
+
+ r = sim_activate_after(uptr, uptr->wait); /* reactivate timer */
+
+ return r;
+}
+
+/* Attach routines */
+static t_stat jair_attach(UNIT *uptr, CONST char *cptr)
+{
+ t_stat r;
+ unsigned int i = 0;
+
+ r = attach_unit(uptr, cptr); /* attach unit */
+ if (r != SCPE_OK) { /* error? */
+ sim_debug(ERROR_MSG, &jair_dev, "ATTACH error=%d\n", r);
+ return r;
+ }
+
+ /* Determine length of this disk */
+ uptr->capac = sim_fsize(uptr->fileref);
+
+ for (i = 0; i < JAIR_UNITS; i++) {
+ if (jair_dev.units[i].fileref == uptr->fileref) {
+ break;
+ }
+ }
+
+ if (i >= JAIR_UNITS) {
+ jair_detach(uptr);
+
+ return SCPE_ARG;
+ }
+
+ /* Default for new file is DSK */
+ uptr->u3 = IMAGE_TYPE_DSK;
+
+ sim_debug(VERBOSE_MSG, uptr->dptr, "unit %d, attached to '%s' size=%d\n",
+ i, cptr, uptr->capac);
+
+ return SCPE_OK;
+}
+
+/* Detach routines */
+static t_stat jair_detach(UNIT *uptr)
+{
+ t_stat r;
+ int8 i;
+
+ for (i = 0; i < JAIR_UNITS; i++) {
+ if (jair_dev.units[i].fileref == uptr->fileref) {
+ break;
+ }
+ }
+
+ if (i >= JAIR_UNITS) {
+ return SCPE_ARG;
+ }
+
+ r = detach_unit(uptr); /* detach unit */
+
+ if (r != SCPE_OK) {
+ return r;
+ }
+
+ jair_dev.units[i].fileref = NULL;
+
+ sim_debug(VERBOSE_MSG, uptr->dptr, "unit %d detached.\n", i);
+
+ return SCPE_OK;
+}
+
+/*
+ * Used to attach (connect) MUX interfaces from the
+ * JAIRS0, JAIRS1, and JAIRP devices
+ */
+static t_stat jair_attach_mux(UNIT *uptr, CONST char *cptr)
+{
+ JAIR_PORT_CTX *xptr;
+ t_stat r;
+
+ xptr = (JAIR_PORT_CTX *) uptr->dptr->ctxt;
+
+ if ((r = tmxr_attach(xptr->tmxr, uptr, cptr)) == SCPE_OK) {
+ xptr->tmln[0].rcve = 1;
+ sim_printf("%s: attached '%s' to interface.\n", uptr->dptr->name, cptr);
+ tmxr_set_get_modem_bits(xptr->tmln, TMXR_MDM_DTR | TMXR_MDM_RTS, 0, NULL);
+ }
+
+ return r;
+}
+
+/*
+ * Used to detach (disconnect) MUX interfaces from the
+ * JAIRS0, JAIRS1, and JAIRP devices
+ */
+static t_stat jair_detach_mux(UNIT *uptr)
+{
+ JAIR_PORT_CTX *xptr;
+ t_stat r;
+
+ xptr = (JAIR_PORT_CTX *) uptr->dptr->ctxt;
+
+ if ((r = tmxr_detach(xptr->tmxr, uptr)) == SCPE_OK) {
+ sim_printf("%s: detached.\n", uptr->dptr->name);
+ }
+
+ return r;
+}
+
+static t_stat jair_show_ports(FILE *st, UNIT *uptr, int32 val, CONST void *desc) {
+ JAIR_PORT_CTX *port;
+
+ port = (JAIR_PORT_CTX *) uptr->dptr->ctxt;
+
+ fprintf(st, "I/O=0x%02X-0x%02X", port->pnp.io_base, port->pnp.io_base + port->pnp.io_size - 1);
+ return SCPE_OK;
+}
+
+static t_stat jair_config_line(DEVICE *dev, TMLN *tmln, int baud)
+{
+ char config[20];
+ const char *fmt;
+ t_stat r = SCPE_IERR;
+
+ if (tmln->serport) {
+ fmt = "8N1";
+
+ sprintf(config, "%d-%s", baud, fmt);
+
+ r = tmxr_set_config_line(tmln, config);
+
+ sim_debug(STATUS_MSG, dev, "port configuration set to '%s'.\n", config);
+ }
+
+ return r;
+}
+
+static int jair_set_mc(TMLN *tmln, uint8 data)
+{
+ int s = 0;
+
+ s |= (data & JAIR_DTR) ? TMXR_MDM_DTR : 0;
+ s |= (data & JAIR_RTS) ? TMXR_MDM_RTS : 0;
+
+ return tmxr_set_get_modem_bits(tmln, s, ~s & (TMXR_MDM_DTR | TMXR_MDM_RTS), NULL);
+}
+
+static int jair_new_baud(UNIT *uptr)
+{
+ JAIR_PORT_CTX *port;
+ int divisor;
+
+ port = (JAIR_PORT_CTX *) uptr->dptr->ctxt;
+
+ divisor = (port->dlms << 8) + port->dlls;
+
+ if (divisor) {
+ port->baud = 115200 / divisor;
+ jair_config_line(uptr->dptr, port->tmln, port->baud);
+ }
+
+ return port->baud;
+}
+
+static t_stat jair_set_baud(UNIT *uptr, int32 value, const char *cptr, void *desc)
+{
+ int32 baud;
+ t_stat r = SCPE_ARG;
+ JAIR_PORT_CTX *port;
+
+ port = (JAIR_PORT_CTX *) uptr->dptr->ctxt;
+
+ if (!(uptr->flags & UNIT_ATT)) {
+ return SCPE_UNATT;
+ }
+
+ if (cptr != NULL) {
+ if (sscanf(cptr, "%d", &baud)) {
+ port->baud = baud;
+ r = jair_config_line(uptr->dptr, port->tmln, port->baud);
+ }
+ }
+
+ return r;
+}
+
+static t_stat jair_show_baud(FILE *st, UNIT *uptr, int32 value, const void *desc)
+{
+ JAIR_PORT_CTX *port;
+
+ port = (JAIR_PORT_CTX *) uptr->dptr->ctxt;
+
+ if (uptr->flags & UNIT_ATT) {
+ fprintf(st, "Baud rate: %d", port->baud);
+ }
+
+ return SCPE_OK;
+}
+
+/*
+ * Handles I/O input and output
+ */
+static int32 jairio(int32 addr, int32 rw, int32 data)
+{
+ if (rw == 0) {
+ return(jair_io_in(addr));
+ }
+ else {
+ return(jair_io_out(addr, data));
+ }
+}
+
+static uint8 jair_io_in(uint32 addr)
+{
+ uint8 data = 0xff;
+
+ switch(addr & 0xff) {
+ case JAIR_UART0 + JAIR_LSR:
+ data = jairs0_ctx.lsr;
+ break;
+
+ case JAIR_UART1 + JAIR_LSR:
+ data = jairs1_ctx.lsr;
+ break;
+
+ case JAIR_UART0 + JAIR_SDATA:
+ data = jairs0_ctx.rxd;
+ jairs0_ctx.rdr = FALSE;
+ jairs0_ctx.lsr &= ~JAIR_DR;
+ break;
+
+ case JAIR_UART1 + JAIR_SDATA:
+ data = jairs1_ctx.rxd;
+ jairs1_ctx.rdr = FALSE;
+ jairs1_ctx.lsr &= ~JAIR_DR;
+ break;
+
+ case JAIR_UART0 + JAIR_MSR:
+ data = jairs0_ctx.msr;
+ jairs0_ctx.msr &= 0xf0; /* Clear deltas */
+ break;
+
+ case JAIR_UART1 + JAIR_MSR:
+ data = jairs1_ctx.msr;
+ jairs1_ctx.msr &= 0xf0; /* Clear deltas */
+ break;
+
+ case JAIR_UART0 + JAIR_SR:
+ data = jairs0_ctx.sr;
+ break;
+
+ case JAIR_UART1 + JAIR_SR:
+ data = jairs1_ctx.sr;
+ break;
+
+ case JAIR_PPORT:
+ data = jairp_ctx.rxd;
+ jairp_ctx.rdr = FALSE;
+ break;
+
+ case JAIR_SPI:
+ if (jair_ctx.spi_cs) { /* Chip is disabled */
+ break;
+ }
+
+ switch (jair_ctx.sd_istate) {
+ case JAIR_STATE_IDLE:
+ data = 0xff;
+ break;
+
+ case JAIR_STATE_RESP:
+ if (jair_ctx.sd_resp_idx < jair_ctx.sd_resp_len) { /* Receive next command byte */
+ data = jair_ctx.sd_resp[jair_ctx.sd_resp_idx++];
+ }
+ else {
+ jair_ctx.sd_istate = JAIR_STATE_IDLE;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case JAIR_SPI_SS:
+ break;
+
+ default:
+ sim_printf("Invalid IO Read %02x\n", addr);
+
+ sim_debug(ERROR_MSG, &jair_dev, "READ Invalid I/O Address %02x (%02x)\n",
+ addr & 0xFF, addr & 0x01);
+ break;
+ }
+
+ return (data);
+}
+
+static uint8 jair_io_out(uint32 addr, int32 data)
+{
+ uint32 sd_addr;
+
+ switch(addr & 0xff) {
+ case JAIR_UART0 + JAIR_SDATA:
+ if (jairs0_ctx.lcr & JAIR_DLAB) {
+ jairs0_ctx.dlls = data;
+ jair_new_baud(jairs0_unit);
+ } else {
+ jairs0_ctx.txd = data;
+ jairs0_ctx.txp = TRUE;
+ jairs0_ctx.lsr &= ~(JAIR_THRE | JAIR_TEMT);
+ }
+ break;
+
+ case JAIR_UART1 + JAIR_SDATA:
+ if (jairs1_ctx.lcr & JAIR_DLAB) {
+ jairs1_ctx.dlls = data;
+ jair_new_baud(jairs1_unit);
+ } else {
+ jairs1_ctx.txd = data;
+ jairs1_ctx.txp = TRUE;
+ jairs1_ctx.lsr &= ~(JAIR_THRE | JAIR_TEMT);
+ }
+ break;
+
+ case JAIR_UART0 + JAIR_IER:
+ if (jairs0_ctx.lcr & JAIR_DLAB) {
+ jairs0_ctx.dlms = data;
+ jair_new_baud(jairs0_unit);
+ } else {
+ jairs0_ctx.ier = data;
+ }
+ break;
+
+ case JAIR_UART1 + JAIR_IER:
+ if (jairs1_ctx.lcr & JAIR_DLAB) {
+ jairs1_ctx.dlms = data;
+ jair_new_baud(jairs1_unit);
+ } else {
+ jairs1_ctx.ier = data;
+ }
+ break;
+
+ case JAIR_UART0 + JAIR_SR:
+ jairs0_ctx.sr = data;
+ break;
+
+ case JAIR_UART1 + JAIR_SR:
+ jairs1_ctx.sr = data;
+ break;
+
+ case JAIR_UART0 + JAIR_LCR:
+ jairs0_ctx.lcr = data;
+ break;
+
+ case JAIR_UART1 + JAIR_LCR:
+ jairs1_ctx.lcr = data;
+ break;
+
+ case JAIR_UART0 + JAIR_MCR:
+ jairs0_ctx.mcr = data;
+ jair_set_mc(jairs0_ctx.tmln, data);
+ break;
+
+ case JAIR_UART1 + JAIR_MCR:
+ jairs1_ctx.mcr = data;
+ jair_set_mc(jairs1_ctx.tmln, data);
+ break;
+
+ case JAIR_PPORT:
+ jairp_ctx.txd = data;
+ jairp_ctx.txp = TRUE;
+
+ jair_ctx.sr_ena = (data & 0x01) ? FALSE : TRUE;
+ break;
+
+ case JAIR_SPI_SS:
+ jair_ctx.spi_cs = data & 0x01;
+
+ if (jair_ctx.spi_cs) { /* If chip is disable, reset */
+ jair_ctx.sd_appcmd = FALSE;
+ jair_ctx.sd_istate = JAIR_STATE_IDLE;
+ jair_ctx.sd_ostate = JAIR_STATE_IDLE;
+ }
+ break;
+
+ case JAIR_SPI:
+ if (jair_ctx.spi_cs) { /* Chip is disabled */
+ break;
+ }
+
+ switch (jair_ctx.sd_ostate) {
+ case JAIR_STATE_IDLE:
+ if ((data & 0xc0) == 0x40) { /* Received start and transmission bits */
+ jair_ctx.sd_cmd[0] = data & 0x3f;
+ jair_ctx.sd_cmd_len = 6;
+ jair_ctx.sd_cmd_idx = 1;
+ jair_ctx.sd_ostate = JAIR_STATE_CMD;
+ }
+ break;
+
+ case JAIR_STATE_CMD:
+ if (jair_ctx.sd_cmd_idx < jair_ctx.sd_cmd_len) { /* Receive next command byte */
+ jair_ctx.sd_cmd[jair_ctx.sd_cmd_idx++] = data;
+ }
+ else {
+ jair_ctx.sd_resp[0] = (jair_ctx.sd_cmd[5] & 0x01) ? 0x00 : 0x04;
+
+ if (jair_ctx.sd_appcmd) {
+ jair_ctx.sd_cmd[0] |= 0x80;
+ jair_ctx.sd_appcmd = FALSE;
+ }
+
+ switch (jair_ctx.sd_cmd[0]) {
+ case JAIR_CMD0:
+ jair_ctx.sd_resp[0] |= 0x01;
+ jair_ctx.sd_resp_idx = 0;
+ jair_ctx.sd_resp_len = 1;
+ jair_ctx.sd_istate = JAIR_STATE_RESP;
+ jair_ctx.sd_ostate = JAIR_STATE_IDLE;
+ break;
+
+ case JAIR_CMD13:
+ jair_ctx.sd_resp[0] = 0x00;
+ jair_ctx.sd_resp[1] = 0x00;
+ jair_ctx.sd_resp_idx = 0;
+ jair_ctx.sd_resp_len = 2;
+ jair_ctx.sd_istate = JAIR_STATE_RESP;
+ jair_ctx.sd_ostate = JAIR_STATE_IDLE;
+ break;
+
+ case JAIR_CMD17:
+ sd_addr = jair_ctx.sd_cmd[1] * 0x1000000;
+ sd_addr |= jair_ctx.sd_cmd[2] * 0x10000;
+ sd_addr |= (uint32) jair_ctx.sd_cmd[3] * 0x100;
+ sd_addr |= (uint32) jair_ctx.sd_cmd[4];
+
+ if (sim_fseek(jair_unit[0].fileref, sd_addr, SEEK_SET) != 0) {
+ jair_ctx.sd_resp[0] |= 0x04;
+ jair_ctx.sd_resp_len = 1;
+ }
+ else if (sim_fread(&jair_ctx.sd_resp[4], 1, 512, jair_unit[0].fileref) != 512) {
+ jair_ctx.sd_resp[0] |= 0x04;
+ jair_ctx.sd_resp_len = 1;
+ } else {
+ jair_ctx.sd_resp[0] |= 0x00;
+ jair_ctx.sd_resp[1] |= 0xff;
+ jair_ctx.sd_resp[2] |= 0xff;
+ jair_ctx.sd_resp[3] |= 0xfe;
+ jair_ctx.sd_resp_len = 4 + 512 + 2;
+ }
+
+ jair_ctx.sd_resp_idx = 0;
+ jair_ctx.sd_istate = JAIR_STATE_RESP;
+ jair_ctx.sd_ostate = JAIR_STATE_IDLE;
+ break;
+
+ case JAIR_CMD24:
+ jair_ctx.sd_resp[0] |= 0x00;
+ jair_ctx.sd_resp_idx = 0;
+ jair_ctx.sd_resp_len = 1;
+ jair_ctx.sd_istate = JAIR_STATE_RESP;
+ jair_ctx.sd_ostate = JAIR_STATE_SBLK;
+ break;
+
+ case JAIR_CMD8:
+ jair_ctx.sd_resp[0] |= 0x04; /* Illegal command **/
+ jair_ctx.sd_resp_idx = 0;
+ jair_ctx.sd_resp_len = 1;
+ jair_ctx.sd_istate = JAIR_STATE_RESP;
+ jair_ctx.sd_ostate = JAIR_STATE_IDLE;
+ break;
+
+ case JAIR_CMD55:
+ jair_ctx.sd_appcmd = TRUE;
+ jair_ctx.sd_resp[0] |= 0x01;
+ jair_ctx.sd_resp_idx = 0;
+ jair_ctx.sd_resp_len = 1;
+ jair_ctx.sd_istate = JAIR_STATE_RESP;
+ jair_ctx.sd_ostate = JAIR_STATE_IDLE;
+ break;
+
+ case JAIR_ACMD41:
+ jair_ctx.sd_resp_idx = 0;
+ jair_ctx.sd_resp_len = 1;
+ jair_ctx.sd_istate = JAIR_STATE_RESP;
+ jair_ctx.sd_ostate = JAIR_STATE_IDLE;
+ break;
+
+ default:
+ jair_ctx.sd_resp[0] |= 0x04; /* Illegal command **/
+ jair_ctx.sd_resp_idx = 0;
+ jair_ctx.sd_resp_len = 1;
+ jair_ctx.sd_istate = JAIR_STATE_RESP;
+ jair_ctx.sd_ostate = JAIR_STATE_IDLE;
+ sim_printf("Command not implemented: %d\n", jair_ctx.sd_cmd[0]);
+ break;
+ }
+ }
+ break;
+
+ case JAIR_STATE_SBLK:
+ if (data == 0xfe) {
+ jair_ctx.sd_ostate = JAIR_STATE_WBLK;
+ jair_ctx.sd_cmd_len = 512;
+ jair_ctx.sd_cmd_idx = 0;
+ }
+ break;
+
+ case JAIR_STATE_WBLK:
+ if (jair_ctx.sd_cmd_idx < jair_ctx.sd_cmd_len) {
+ jair_ctx.sd_cmd[6 + jair_ctx.sd_cmd_idx++] = data; /* store block starting at offset 6 */
+ }
+ else {
+ sd_addr = jair_ctx.sd_cmd[1] * 0x1000000;
+ sd_addr |= jair_ctx.sd_cmd[2] * 0x10000;
+ sd_addr |= (uint32) jair_ctx.sd_cmd[3] * 0x100;
+ sd_addr |= (uint32) jair_ctx.sd_cmd[4];
+
+ if (sim_fseek(jair_unit[0].fileref, sd_addr, SEEK_SET) != 0) {
+ jair_ctx.sd_resp[0] = 0x0b;
+ }
+ else if (sim_fwrite(&jair_ctx.sd_cmd[6], 1, 512, jair_unit[0].fileref) != 512) {
+ jair_ctx.sd_resp[0] = 0x0b;
+ } else {
+ jair_ctx.sd_resp[0] = 0x05;
+ }
+
+ jair_ctx.sd_resp_idx = 0;
+ jair_ctx.sd_resp_len = 1;
+ jair_ctx.sd_istate = JAIR_STATE_RESP;
+ jair_ctx.sd_ostate = JAIR_STATE_IDLE;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ sim_printf("Invalid IO Write %02x\n", addr);
+
+ sim_debug(ERROR_MSG, &jair_dev, "WRITE Invalid I/O Address %02x (%02x)\n",
+ addr & 0xFF, addr & 0x01);
+ break;
+ }
+
+ return(0xff);
+}
+
+static t_stat jair_set_rom(UNIT *uptr, int32 value, CONST char *cptr, void *desc) {
+ jair_ctx.sr_ena = TRUE;
+ return SCPE_OK;
+}
+
+static t_stat jair_set_norom(UNIT *uptr, int32 value, CONST char *cptr, void *desc) {
+ jair_ctx.sr_ena = FALSE;
+ return SCPE_OK;
+}
+
+/*
+** The JAIR overlays the first 8K (minimum) of RAM with a ROM.
+**
+** If the ROM is enabled, writes to 0x0000-0x2000 are written to RAM, reads are
+** read from the ROM.
+**
+** The ROM is enabled/disabled by writing a 0 (enable) or 1 (disable) to the parallel port.
+*/
+static int32 jair_shadow_rom(int32 Addr, int32 rw, int32 data)
+{
+ if (rw == JAIR_ROM_WRITE) {
+ jair_ram[Addr & JAIR_ROM_MASK] = data;
+ } else {
+ if (jair_ctx.sr_ena == TRUE && Addr < JAIR_ROM_SIZE) {
+ return(jair_rom_v25[Addr & JAIR_ROM_MASK]);
+ } else {
+ return(jair_ram[Addr & JAIR_ROM_MASK]);
+ }
+ }
+
+ return 0xff;
+}
+
+/*
+ * Display help
+ */
+static t_stat jair_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
+{
+ return SCPE_OK;
+}
+
diff --git a/Visual Studio Projects/AltairZ80.vcproj b/Visual Studio Projects/AltairZ80.vcproj
index cdd30349..89ff08f4 100644
--- a/Visual Studio Projects/AltairZ80.vcproj
+++ b/Visual Studio Projects/AltairZ80.vcproj
@@ -366,6 +366,10 @@
RelativePath="..\AltairZ80\s100_jadedd.c"
>
+
+
diff --git a/Visual Studio Projects/AltairZ80.vcxproj b/Visual Studio Projects/AltairZ80.vcxproj
index 6c72d749..6635c661 100755
--- a/Visual Studio Projects/AltairZ80.vcxproj
+++ b/Visual Studio Projects/AltairZ80.vcxproj
@@ -281,6 +281,7 @@
+
@@ -349,4 +350,4 @@
-
\ No newline at end of file
+
diff --git a/makefile b/makefile
index 32a3514a..1167f83a 100644
--- a/makefile
+++ b/makefile
@@ -1894,6 +1894,7 @@ ALTAIR_OPT = -I ${ALTAIRD}
ALTAIRZ80D = ${SIMHD}/AltairZ80
ALTAIRZ80 = ${ALTAIRZ80D}/altairz80_cpu.c ${ALTAIRZ80D}/altairz80_cpu_nommu.c \
+ ${ALTAIRZ80D}/s100_jair.c \
${ALTAIRZ80D}/sol20.c \
${ALTAIRZ80D}/s100_vdm1.c \
${ALTAIRZ80D}/mmd.c \