I was having problems with the JAIR device keeping up with received data at 57.6K. This PR makes the following changes to the JAIR devices: - Refactors the service routines into STAT, TX and RX units - Adds a 128-byte input ring buffer - Corrects a null pointer exception - Adds overrun status bit implementation - Removes a tab with spaces
1925 lines
76 KiB
C
1925 lines
76 KiB
C
/*** 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_rx_svc(UNIT *uptr);
|
|
static t_stat jair_tx_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_get_modem_status(UNIT *uptr);
|
|
static void jair_get_rxdata(UNIT *uptr);
|
|
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_OE 0x02 /* SERIAL OVERRUN ERROR */
|
|
#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 */
|
|
|
|
#define JAIR_STAT_WAIT 10000 /* Status wait interval */
|
|
#define JAIR_IO_WAIT 250 /* IO wait interval */
|
|
|
|
/*
|
|
** 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)
|
|
#define UNIT_V_JAIR_CONSOLE (UNIT_V_UF + 3) /* Port checks console for input */
|
|
#define UNIT_JAIR_CONSOLE (1 << UNIT_V_JAIR_CONSOLE)
|
|
|
|
/*
|
|
** 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 */
|
|
/****************/
|
|
|
|
#define JAIR_IOBUF_SIZE (128)
|
|
#define JAIR_IOBUF_MASK (JAIR_IOBUF_SIZE-1)
|
|
|
|
#define JAIR_PORT_UNITS 3
|
|
|
|
#define JAIR_UNIT_STAT 0
|
|
#define JAIR_UNIT_RX 1
|
|
#define JAIR_UNIT_TX 2
|
|
|
|
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 */
|
|
int32 iobuf[JAIR_IOBUF_SIZE];
|
|
uint32 iobufin;
|
|
uint32 iobufout;
|
|
} 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 (BUFIN0, jairs0_ctx.iobufin, 16, "Serial port buffer in ptr"), },
|
|
{ HRDATAD (BUFOUT0, jairs0_ctx.iobufout, 16, "Serial port buffer out ptr"), },
|
|
{ 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[JAIR_PORT_UNITS] = {
|
|
{ UDATA (&jair_svc, UNIT_ATTABLE | UNIT_JAIR_CONSOLE, 0), JAIR_STAT_WAIT },
|
|
{ UDATA (&jair_rx_svc, UNIT_DIS | UNIT_JAIR_CONSOLE, 0), JAIR_IO_WAIT },
|
|
{ UDATA (&jair_tx_svc, UNIT_DIS | UNIT_JAIR_CONSOLE, 0), JAIR_IO_WAIT }
|
|
};
|
|
|
|
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 */
|
|
JAIR_PORT_UNITS, /* # 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 */
|
|
&jairs0_tmxr, /* 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 (BUFIN1, jairs1_ctx.iobufin, 16, "Serial port buffer in ptr"), },
|
|
{ HRDATAD (BUFOUT1, jairs1_ctx.iobufout, 16, "Serial port buffer out ptr"), },
|
|
{ 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[JAIR_PORT_UNITS] = {
|
|
{ UDATA (&jair_svc, UNIT_ATTABLE, 0), JAIR_STAT_WAIT },
|
|
{ UDATA (&jair_rx_svc, UNIT_DIS, 0), JAIR_IO_WAIT },
|
|
{ UDATA (&jair_tx_svc, UNIT_DIS, 0), JAIR_IO_WAIT }
|
|
};
|
|
|
|
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 */
|
|
JAIR_PORT_UNITS, /* # 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 */
|
|
&jairs1_tmxr, /* 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[JAIR_PORT_UNITS] = {
|
|
{ UDATA (&jair_svc, UNIT_ATTABLE, 0), JAIR_STAT_WAIT },
|
|
{ UDATA (&jair_rx_svc, UNIT_DIS, 0), JAIR_IO_WAIT },
|
|
{ UDATA (&jair_tx_svc, UNIT_DIS, 0), JAIR_IO_WAIT }
|
|
};
|
|
|
|
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 */
|
|
JAIR_PORT_UNITS, /* # 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 */
|
|
&jairp_tmxr, /* 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;
|
|
}
|
|
|
|
static t_stat jair_port_reset(DEVICE *dptr) {
|
|
JAIR_PORT_CTX *port;
|
|
char uname[12];
|
|
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);
|
|
tmxr_set_line_unit(port->tmxr, 0, &dptr->units[JAIR_UNIT_RX]);
|
|
tmxr_set_line_output_unit(port->tmxr, 0, &dptr->units[JAIR_UNIT_TX]);
|
|
|
|
sprintf(uname, "%.6sRX", sim_uname(&dptr->units[JAIR_UNIT_RX]));
|
|
sim_set_uname(&dptr->units[JAIR_UNIT_RX], uname);
|
|
sprintf(uname, "%.6sTX", sim_uname(&dptr->units[JAIR_UNIT_TX]));
|
|
sim_set_uname(&dptr->units[JAIR_UNIT_TX], uname);
|
|
|
|
port->status = 0x00;
|
|
port->rdr = FALSE;
|
|
port->txp = FALSE;
|
|
port->lsr = JAIR_TEMT | JAIR_THRE;
|
|
port->msr = 0;
|
|
port->iobufin = 0;
|
|
port->iobufout = 0;
|
|
|
|
for (u = 0; u < dptr->numunits; u++) {
|
|
sim_activate_abs(&dptr->units[u], dptr->units[u].wait); /* activate timer */
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
/*
|
|
* JAIR service routines
|
|
*
|
|
* 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;
|
|
t_stat r = SCPE_OK;
|
|
|
|
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_debug(VERBOSE_MSG, &jair_dev, "new connection.\n");
|
|
}
|
|
}
|
|
|
|
/* Update modem status register */
|
|
if ((uptr->flags & UNIT_ATT) && port->conn) {
|
|
jair_get_modem_status(uptr);
|
|
}
|
|
|
|
sim_activate_abs(uptr, uptr->wait); /* reactivate timer */
|
|
|
|
return r;
|
|
}
|
|
|
|
static t_stat jair_rx_svc(UNIT *uptr)
|
|
{
|
|
UNIT *rxunit = uptr;
|
|
JAIR_PORT_CTX *port;
|
|
int32 c = 0;
|
|
t_stat r = SCPE_OK;
|
|
|
|
port = (JAIR_PORT_CTX *) uptr->dptr->ctxt;
|
|
|
|
/* switch to unit 0 */
|
|
uptr = uptr->dptr->units;
|
|
|
|
/* Buffer any received data */
|
|
if ((uptr->flags & UNIT_ATT) && port->conn) {
|
|
tmxr_poll_rx(port->tmxr);
|
|
|
|
while ((c = tmxr_getc_ln(&port->tmln[0])) & TMXR_VALID) {
|
|
port->iobuf[port->iobufin++] = c;
|
|
port->iobufin &= JAIR_IOBUF_MASK;
|
|
if (port->iobufin == port->iobufout) {
|
|
port->iobufin--;
|
|
port->iobufin &= JAIR_IOBUF_MASK;
|
|
port->lsr |= JAIR_OE; /* Overrun Error */
|
|
}
|
|
}
|
|
}
|
|
|
|
sim_activate_abs(rxunit, rxunit->wait); /* reactivate timer */
|
|
|
|
return r;
|
|
}
|
|
|
|
static t_stat jair_tx_svc(UNIT *uptr)
|
|
{
|
|
UNIT *txunit = uptr;
|
|
JAIR_PORT_CTX *port;
|
|
t_stat r = SCPE_OK;
|
|
|
|
port = (JAIR_PORT_CTX *) uptr->dptr->ctxt;
|
|
|
|
/* switch to unit 0 */
|
|
uptr = uptr->dptr->units;
|
|
|
|
/* 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;
|
|
}
|
|
|
|
sim_activate_abs(txunit, txunit->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_debug(VERBOSE_MSG, uptr->dptr, "attached '%s' to interface.\n", 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;
|
|
|
|
r = tmxr_detach(xptr->tmxr, uptr);
|
|
|
|
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];
|
|
t_stat r = SCPE_IERR;
|
|
|
|
sprintf(config, "%d-8N1", baud);
|
|
|
|
if (tmln->serport) {
|
|
r = tmxr_set_config_line(tmln, config);
|
|
}
|
|
|
|
sim_debug(STATUS_MSG, dev, "port configuration set to '%s'.\n", config);
|
|
|
|
return r;
|
|
}
|
|
|
|
static void jair_get_rxdata(UNIT *uptr)
|
|
{
|
|
JAIR_PORT_CTX *port;
|
|
int32 c = 0xff;
|
|
|
|
port = (JAIR_PORT_CTX *) uptr->dptr->ctxt;
|
|
|
|
if (uptr->flags & UNIT_ATT) {
|
|
if (uptr->fileref) {
|
|
if (sim_fread(&c, 1, 1, uptr->fileref) == 1) {
|
|
c |= SCPE_KFLAG;
|
|
}
|
|
}
|
|
else if (port->conn) {
|
|
if (port->iobufin != port->iobufout) {
|
|
c = port->iobuf[port->iobufout++];
|
|
port->iobufout &= JAIR_IOBUF_MASK;
|
|
}
|
|
}
|
|
}
|
|
else if (uptr->flags & UNIT_JAIR_CONSOLE) {
|
|
c = sim_poll_kbd();
|
|
}
|
|
|
|
if (c & (TMXR_VALID | SCPE_KFLAG)) {
|
|
port->rxd = c & 0xff;
|
|
port->rdr = TRUE;
|
|
port->lsr |= JAIR_DR;
|
|
}
|
|
}
|
|
|
|
static int jair_get_modem_status(UNIT *uptr)
|
|
{
|
|
JAIR_PORT_CTX *port;
|
|
uint8 msr;
|
|
int32 s;
|
|
t_stat r;
|
|
|
|
port = (JAIR_PORT_CTX *) uptr->dptr->ctxt;
|
|
|
|
r = 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");
|
|
}
|
|
|
|
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:
|
|
if (!(jairs0_ctx.lsr & JAIR_DR)) {
|
|
jair_get_rxdata(jairs0_unit);
|
|
}
|
|
data = jairs0_ctx.lsr;
|
|
break;
|
|
|
|
case JAIR_UART1 + JAIR_LSR:
|
|
if (!(jairs1_ctx.lsr & JAIR_DR)) {
|
|
jair_get_rxdata(jairs1_unit);
|
|
}
|
|
data = jairs1_ctx.lsr;
|
|
break;
|
|
|
|
case JAIR_UART0 + JAIR_SDATA:
|
|
data = jairs0_ctx.rxd;
|
|
jairs0_ctx.rdr = FALSE;
|
|
jairs0_ctx.lsr &= ~(JAIR_DR | JAIR_OE);
|
|
break;
|
|
|
|
case JAIR_UART1 + JAIR_SDATA:
|
|
data = jairs1_ctx.rxd;
|
|
jairs1_ctx.rdr = FALSE;
|
|
jairs1_ctx.lsr &= ~(JAIR_DR | JAIR_OE);
|
|
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_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 (!(jair_unit[0].flags & UNIT_ATT)) {
|
|
jair_ctx.sd_resp[0] |= 0x04;
|
|
jair_ctx.sd_resp_len = 1;
|
|
}
|
|
else 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_debug(ERROR_MSG, &jair_dev, "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 (!(jair_unit[0].flags & UNIT_ATT)) {
|
|
jair_ctx.sd_resp[0] = 0x0b;
|
|
}
|
|
else 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_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;
|
|
}
|
|
|