Updated AltairZ80 from Peter Schorn

This commit is contained in:
Mark Pizzolato 2013-04-13 16:47:59 -07:00
parent 400281f3b0
commit ee3d98a125
11 changed files with 745 additions and 494 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/* altairz80_cpu_opt.c: MITS Altair CPU (8080 and Z80)
Copyright (c) 2002-2011, Peter Schorn
Copyright (c) 2002-2013, Peter Schorn
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),

View file

@ -1,6 +1,6 @@
/* altairz80_defs.h: MITS Altair simulator definitions
Copyright (c) 2002-2011, Peter Schorn
Copyright (c) 2002-2013, Peter Schorn
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),

Binary file not shown.

View file

@ -1,6 +1,6 @@
/* altairz80_dsk.c: MITS Altair 88-DISK Simulator
Copyright (c) 2002-2011, Peter Schorn
Copyright (c) 2002-2013, Peter Schorn
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -483,6 +483,7 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
current_disk, PCX);
}
current_track[current_disk]++;
current_flag[current_disk] &= 0xbf; /* mwd 1/29/13: track zero now false */
if (current_track[current_disk] > (tracks[current_disk] - 1))
current_track[current_disk] = (tracks[current_disk] - 1);
if (dirty) /* implies that current_disk < NUM_OF_DSK */

View file

@ -1,6 +1,6 @@
/* altairz80_hdsk.c: simulated hard disk device to increase capacity
Copyright (c) 2002-2011, Peter Schorn
Copyright (c) 2002-2013, Peter Schorn
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -28,6 +28,7 @@
#include "altairz80_defs.h"
#include <assert.h>
#include "sim_imd.h"
/* Debug flags */
#define READ_MSG (1 << 0)
@ -43,6 +44,9 @@ static t_stat show_format(FILE *st, UNIT *uptr, int32 val, void *desc);
static t_stat hdsk_reset(DEVICE *dptr);
static t_stat hdsk_attach(UNIT *uptr, char *cptr);
static t_stat hdsk_detach(UNIT *uptr);
static uint32 is_imd(const UNIT *uptr);
static void assignFormat(UNIT *uptr);
static void verifyDiskInfo(const DISK_INFO info, const char unitChar);
#define UNIT_V_HDSK_WLK (UNIT_V_UF + 0) /* write locked */
#define UNIT_HDSK_WLK (1 << UNIT_V_HDSK_WLK)
@ -118,6 +122,7 @@ typedef struct {
#define SPT16 16
#define SPT32 32
#define SPT26 26
#define SPT52 52
static HDSK_INFO hdsk_info_data = { { 0x0000, 0, 0xFD, 1 } };
@ -126,18 +131,18 @@ static int32 standard8[SPT26] = { 0, 6, 12, 18, 24, 4, 10, 16,
19, 25, 5, 11, 17, 23, 3, 9,
15, 21 };
static int32 appple_ii_DOS[SPT16] = { 0, 6, 12, 3, 9, 15, 14, 5,
static int32 apple_ii_DOS[SPT16] = { 0, 6, 12, 3, 9, 15, 14, 5,
11, 2, 8, 7, 13, 4, 10, 1 };
static int32 appple_ii_DOS2[SPT32] = { 0, 1, 12, 13, 24, 25, 6, 7,
static int32 apple_ii_DOS2[SPT32] = { 0, 1, 12, 13, 24, 25, 6, 7,
18, 19, 30, 31, 28, 29, 10, 11,
22, 23, 4, 5, 16, 17, 14, 15,
26, 27, 8, 9, 20, 21, 2, 3 };
static int32 appple_ii_PRODOS[SPT16] = { 0, 9, 3, 12, 6, 15, 1, 10,
static int32 apple_ii_PRODOS[SPT16] = { 0, 9, 3, 12, 6, 15, 1, 10,
4, 13, 7, 8, 2, 11, 5, 14 };
static int32 appple_ii_PRODOS2[SPT32] = { 0, 1, 18, 19, 6, 7, 24, 25,
static int32 apple_ii_PRODOS2[SPT32] = { 0, 1, 18, 19, 6, 7, 24, 25,
12, 13, 30, 31, 2, 3, 20, 21,
8, 9, 26, 27, 14, 15, 16, 17,
4, 5, 22, 23, 10, 11, 28, 29 };
@ -197,17 +202,44 @@ static DPB dpb[] = {
{ "SSSD8S", 256256, SPT26, 0x03, 0x07, 0x00, 242, 0x003F,
0xC0, 0x00, 0x0000, 0x0002, 0x00, 0x00, 0, 0, standard8 }, /* Standard 8" SS SD with skew */
{ "SSDD8", 512512, SPT52, 0x04, 0x0F, 0x01, 242, 0x007F,
0xC0, 0x00, 0x0000, 0x0002, 0x01, 0x01, 0, 0, NULL }, /* Standard 8" SS DD */
{ "SSDD8S", 512512, SPT52, 0x04, 0x0F, 0x01, 242, 0x007F,
0xC0, 0x00, 0x0000, 0x0002, 0x01, 0x01, 0, 0, standard8 }, /* Standard 8" SS DD with skew */
{ "DSDD8", 1025024, SPT52, 0x04, 0x0F, 0x00, 493, 0x007F,
0xC0, 0x00, 0x0000, 0x0002, 0x01, 0x01, 0, 0, NULL }, /* Standard 8" DS DD */
{ "DSDD8S", 1025024, SPT52, 0x04, 0x0F, 0x00, 493, 0x007F,
0xC0, 0x00, 0x0000, 0x0002, 0x01, 0x01, 0, 0, NULL }, /* Standard 8" DS DD with skew */
{"512SSDD8",591360, 60, 0x04, 0x0F, 0x00, 280, 0x007F,
0xC0, 0x00, 0x0000, 0x0002, 0x02, 0x03, 0, 0, NULL }, /* Standard 8" SS DD with 512 byte sectors */
{"512DSDD8",1182720, 60, 0x04, 0x0F, 0x00, 569, 0x007F,
0xC0, 0x00, 0x0000, 0x0002, 0x02, 0x03, 0, 0, NULL }, /* Standard 8" DS DD with 512 byte sectors */
#if 0
/* CP/M 3 BIOS currently does not support physical sector size 1024 */
{"1024SSDD8",630784, 64, 0x04, 0x0F, 0x00, 299, 0x007F,
0xC0, 0x00, 0x0000, 0x0002, 0x03, 0x07, 0, 0, NULL }, /* Standard 8" SS DD with 1024 byte sectors */
{"1024DSDD8",1261568, 64, 0x04, 0x0F, 0x00, 607, 0x007F,
0xC0, 0x00, 0x0000, 0x0002, 0x03, 0x07, 0, 0, NULL }, /* Standard 8" DS DD with 1024 byte sectors */
#endif
{ "APPLE-DO",143360, SPT32, 0x03, 0x07, 0x00, 127, 0x003F,
0xC0, 0x00, 0x0000, 0x0003, 0x01, 0x01, 0, 0, appple_ii_DOS }, /* Apple II DOS 3.3 */
0xC0, 0x00, 0x0000, 0x0003, 0x01, 0x01, 0, 0, apple_ii_DOS }, /* Apple II DOS 3.3 */
{ "APPLE-PO",143360, SPT32, 0x03, 0x07, 0x00, 127, 0x003F,
0xC0, 0x00, 0x0000, 0x0003, 0x01, 0x01, 0, 0, appple_ii_PRODOS }, /* Apple II PRODOS */
0xC0, 0x00, 0x0000, 0x0003, 0x01, 0x01, 0, 0, apple_ii_PRODOS }, /* Apple II PRODOS */
{ "APPLE-D2",143360, SPT32, 0x03, 0x07, 0x00, 127, 0x003F,
0xC0, 0x00, 0x0000, 0x0003, 0x00, 0x00, 0, 0, appple_ii_DOS2 }, /* Apple II DOS 3.3, deblocked */
0xC0, 0x00, 0x0000, 0x0003, 0x00, 0x00, 0, 0, apple_ii_DOS2 }, /* Apple II DOS 3.3, deblocked */
{ "APPLE-P2",143360, SPT32, 0x03, 0x07, 0x00, 127, 0x003F,
0xC0, 0x00, 0x0000, 0x0003, 0x00, 0x00, 0, 0, appple_ii_PRODOS2 }, /* Apple II PRODOS, deblocked */
0xC0, 0x00, 0x0000, 0x0003, 0x00, 0x00, 0, 0, apple_ii_PRODOS2 }, /* Apple II PRODOS, deblocked */
{ "MITS", 337568, SPT32, 0x03, 0x07, 0x00, 254, 0x00FF,
0xFF, 0x00, 0x0000, 0x0006, 0x00, 0x00, 137, 3, mits }, /* MITS Altair original */
@ -215,6 +247,20 @@ static DPB dpb[] = {
{ "MITS2", 1113536, SPT32, 0x04, 0x0F, 0x00, 0x1EF, 0x00FF,
0xF0, 0x00, 0x0000, 0x0006, 0x00, 0x00, 137, 3, mits }, /* MITS Altair original, extra */
/*
dw 40 ;#128 byte records/track
db 4,0fh ;block shift mask (2K)
db 1 ;extent mask
dw 194 ;maximun block number
dw 127 ;max number of dir entry - 1
db 0C0H,00h ;alloc vector for directory
dw 0020h ;checksum size
dw 2 ;offset for sys tracks
db 2,3 ;physical sector shift (512 sector)
*/
{ "V1050", 409600, 40, 0x04, 0x0F, 0x01, 194, 0x007F,
0xC0, 0x00, 0x0000, 0x0002, 0x02, 0x03, 0, 0, NULL }, /* Visual Technology Visual 1050, http://www.metabarn.com/v1050/index.html */
{ "", 0 }
};
@ -228,6 +274,7 @@ static UNIT hdsk_unit[] = {
{ UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) },
{ UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) }
};
static DISK_INFO* hdsk_imd[HDSK_NUMBER];
static REG hdsk_reg[] = {
{ DRDATA (HDCMD, hdskLastCommand, 32), REG_RO },
@ -267,41 +314,30 @@ DEVICE hdsk_dev = {
/* Reset routine */
static t_stat hdsk_reset(DEVICE *dptr) {
PNP_INFO *pnp = (PNP_INFO *)dptr->ctxt;
if (dptr->flags & DEV_DIS) {
sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &hdsk_io, TRUE);
PNP_INFO *pnp = (PNP_INFO *)dptr -> ctxt;
if (dptr -> flags & DEV_DIS) {
sim_map_resource(pnp -> io_base, pnp -> io_size, RESOURCE_TYPE_IO, &hdsk_io, TRUE);
} else {
/* Connect HDSK at base address */
if (sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &hdsk_io, FALSE) != 0) {
printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, pnp->mem_base);
dptr->flags |= DEV_DIS;
if (sim_map_resource(pnp -> io_base, pnp -> io_size, RESOURCE_TYPE_IO, &hdsk_io, FALSE) != 0) {
printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, pnp -> mem_base);
dptr -> flags |= DEV_DIS;
return SCPE_ARG;
}
}
return SCPE_OK;
}
/* Attach routine */
static t_stat hdsk_attach(UNIT *uptr, char *cptr) {
t_stat r;
#ifdef _WIN32
#define strcasecmp _stricmp
#endif
static uint32 is_imd(const UNIT *uptr) {
return ((uptr != NULL) && (uptr -> filename != NULL) && (strlen(uptr -> filename) > 3) &&
(strcasecmp(".IMD", uptr -> filename + strlen(uptr -> filename) - 4) == 0));
}
static void assignFormat(UNIT *uptr) {
uint32 i;
char unitChar;
r = attach_unit(uptr, cptr); /* attach unit */
if ( r != SCPE_OK) /* error? */
return r;
/* Step 1: Determine capacity of this disk */
uptr -> capac = sim_fsize(uptr -> fileref); /* the file length is a good indication */
if (uptr -> capac == 0) { /* file does not exist or has length 0 */
uptr -> capac = uptr -> HDSK_NUMBER_OF_TRACKS *
uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE;
if (uptr -> capac == 0)
uptr -> capac = HDSK_CAPACITY;
} /* post condition: uptr -> capac > 0 */
assert(uptr -> capac);
/* Step 2: Determine format based on disk capacity */
uptr -> HDSK_FORMAT_TYPE = -1; /* default to unknown format type */
for (i = 0; dpb[i].capac != 0; i++) { /* find disk parameter block */
if (dpb[i].capac == uptr -> capac) { /* found if correct capacity */
@ -309,13 +345,89 @@ static t_stat hdsk_attach(UNIT *uptr, char *cptr) {
break;
}
}
}
static void verifyDiskInfo(const DISK_INFO info, const char unitChar) {
uint32 track, head;
if (info.ntracks < 1)
printf("HDSK%c (IMD): WARNING: Number of tracks is 0.\n", unitChar);
if (info.nsides < 1) {
printf("HDSK%c (IMD): WARNING: Number of sides is 0.\n", unitChar);
return;
}
for (track = 0; track < info.ntracks / info.nsides; track++)
for (head = 0; head < info.nsides; head++) {
if (info.track[track][head].nsects != info.track[1][0].nsects)
printf("HDSK%c (IMD): WARNING: For track %i and head %i expected number of sectors "
"%i but got %i.\n", unitChar, track, head,
info.track[1][0].nsects, info.track[track][head].nsects);
if (info.track[track][head].sectsize != info.track[1][0].sectsize)
printf("HDSK%c (IMD): WARNING: For track %i and head %i expected sector size "
"%i but got %i.\n", unitChar, track, head,
info.track[1][0].sectsize, info.track[track][head].sectsize);
if (info.track[track][head].start_sector != info.track[1][0].start_sector)
printf("HDSK%c (IMD): WARNING: For track %i and head %i expected start sector "
"%i but got %i.\n", unitChar, track, head,
info.track[1][0].start_sector, info.track[track][head].start_sector);
}
}
/* Attach routine */
static t_stat hdsk_attach(UNIT *uptr, char *cptr) {
int32 thisUnitIndex;
char unitChar;
const t_stat r = attach_unit(uptr, cptr); /* attach unit */
if (r != SCPE_OK) /* error? */
return r;
assert(uptr != NULL);
thisUnitIndex = find_unit_index(uptr);
unitChar = '0' + thisUnitIndex;
assert((0 <= thisUnitIndex) && (thisUnitIndex < HDSK_NUMBER));
if (is_imd(uptr)) {
if ((sim_fsize(uptr -> fileref) == 0) &&
(diskCreate(uptr -> fileref, "$Id: SIMH hdsk.c $") != SCPE_OK)) {
printf("HDSK%c (IMD): Failed to create IMD disk.\n", unitChar);
detach_unit(uptr);
return SCPE_OPENERR;
}
hdsk_imd[thisUnitIndex] = diskOpen(uptr -> fileref, sim_deb && (hdsk_dev.dctrl & VERBOSE_MSG));
if (hdsk_imd[thisUnitIndex] == NULL)
return SCPE_IOERR;
verifyDiskInfo(*hdsk_imd[thisUnitIndex], '0' + thisUnitIndex);
uptr -> HDSK_NUMBER_OF_TRACKS = hdsk_imd[thisUnitIndex] -> ntracks;
uptr -> HDSK_SECTORS_PER_TRACK = hdsk_imd[thisUnitIndex] -> track[1][0].nsects;
uptr -> HDSK_SECTOR_SIZE = hdsk_imd[thisUnitIndex] -> track[1][0].sectsize;
uptr -> capac = ((uptr -> HDSK_NUMBER_OF_TRACKS) *
(uptr -> HDSK_SECTORS_PER_TRACK) *
(uptr -> HDSK_SECTOR_SIZE));
assignFormat(uptr);
if (uptr -> HDSK_FORMAT_TYPE == -1) { /* Case 1: no disk parameter block found*/
uptr -> HDSK_FORMAT_TYPE = 0;
printf("HDSK%c (IMD): WARNING: Unsupported disk capacity, assuming HDSK type "
"with capacity %iKB.\n", unitChar, uptr -> capac / 1000);
uptr -> flags |= UNIT_HDSK_WLK;
printf("HDSK%c (IMD): WARNING: Forcing WRTLCK.\n", unitChar);
}
return SCPE_OK;
}
/* Step 1: Determine capacity of this disk */
uptr -> capac = sim_fsize(uptr -> fileref); /* the file length is a good indication */
if (uptr -> capac == 0) { /* file does not exist or has length 0 */
uptr -> capac = (uptr -> HDSK_NUMBER_OF_TRACKS *
uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE);
if (uptr -> capac == 0)
uptr -> capac = HDSK_CAPACITY;
} /* post condition: uptr -> capac > 0 */
assert(uptr -> capac);
/* Step 2: Determine format based on disk capacity */
assignFormat(uptr);
/* Step 3: Set number of sectors per track and sector size */
if (uptr -> HDSK_FORMAT_TYPE == -1) { /* Case 1: no disk parameter block found*/
for (i = 0; i < hdsk_dev.numunits; i++) /* find affected unit number */
if (&hdsk_unit[i] == uptr)
break; /* found */
unitChar = '0' + i;
if (uptr -> HDSK_FORMAT_TYPE == -1) { /* Case 1: no disk parameter block found */
uptr -> HDSK_FORMAT_TYPE = 0;
printf("HDSK%c: WARNING: Unsupported disk capacity, assuming HDSK type with capacity %iKB.\n",
unitChar, uptr -> capac / 1000);
@ -350,8 +462,16 @@ static t_stat hdsk_attach(UNIT *uptr, char *cptr) {
static t_stat hdsk_detach(UNIT *uptr) {
t_stat result;
int32 unitIndex;
if (uptr == NULL)
return SCPE_IERR;
if (is_imd(uptr)) {
unitIndex = find_unit_index(uptr);
if (unitIndex == -1)
return SCPE_IERR;
assert((0 <= unitIndex) && (unitIndex < HDSK_NUMBER));
diskClose(&hdsk_imd[unitIndex]);
}
result = detach_unit(uptr);
uptr -> capac = HDSK_CAPACITY;
uptr -> HDSK_FORMAT_TYPE = 0;
@ -490,7 +610,7 @@ static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
install_ALTAIRbootROM(); /* install modified ROM */
}
assert(install_bootrom(bootrom_hdsk, BOOTROM_SIZE_HDSK, HDSK_BOOT_ADDRESS, FALSE) == SCPE_OK);
*((int32 *) sim_PC->loc) = HDSK_BOOT_ADDRESS;
*((int32 *) sim_PC -> loc) = HDSK_BOOT_ADDRESS;
return SCPE_OK;
}
@ -603,12 +723,46 @@ static int32 doSeek(void) {
return CPM_OK;
}
uint8 hdskbuf[HDSK_MAX_SECTOR_SIZE] = { 0 }; /* data buffer */
static uint8 hdskbuf[HDSK_MAX_SECTOR_SIZE] = { 0 }; /* data buffer */
/* pre-condition: checkParameters has been executed to repair any faulty parameters */
static int32 doRead(void) {
int32 i;
t_stat result;
DISK_INFO *thisDisk;
int32 hostSector;
int32 sectorSize;
uint32 flags;
uint32 readlen;
uint32 cylinder;
uint32 head;
UNIT *uptr = &hdsk_dev.units[selectedDisk];
if (is_imd(uptr)) {
thisDisk = hdsk_imd[selectedDisk];
hostSector = ((dpb[uptr -> HDSK_FORMAT_TYPE].skew == NULL) ?
selectedSector : dpb[uptr -> HDSK_FORMAT_TYPE].skew[selectedSector]) + thisDisk -> track[1][0].start_sector;
sectorSize = ((dpb[uptr -> HDSK_FORMAT_TYPE].physicalSectorSize == 0) ?
uptr -> HDSK_SECTOR_SIZE :
dpb[uptr -> HDSK_FORMAT_TYPE].physicalSectorSize);
flags = 0;
readlen = 0;
cylinder = selectedTrack;
head = 0;
if (cylinder >= thisDisk -> ntracks / thisDisk -> nsides) {
head = 1;
cylinder -= thisDisk -> ntracks / thisDisk -> nsides;
}
result = sectRead(thisDisk, cylinder, head, hostSector, hdskbuf, sectorSize,
&flags, &readlen);
if (result != SCPE_OK) {
for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++)
hdskbuf[i] = CPM_EMPTY;
sim_debug(VERBOSE_MSG, &hdsk_dev, "HDSK%d (IMD): " ADDRESS_FORMAT
" . Could not read Sector=%02d Track=%04d.\n",
selectedDisk, PCX, selectedSector, selectedTrack);
return CPM_ERROR;
}
} else {
if (doSeek())
return CPM_ERROR;
@ -620,6 +774,7 @@ static int32 doRead(void) {
selectedDisk, PCX, selectedSector, selectedTrack);
return CPM_OK; /* allows the creation of empty hard disks */
}
}
for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++)
PutBYTEWrapper(selectedDMA + i, hdskbuf[i]);
return CPM_OK;
@ -628,9 +783,43 @@ static int32 doRead(void) {
/* pre-condition: checkParameters has been executed to repair any faulty parameters */
static int32 doWrite(void) {
int32 i;
t_stat result;
DISK_INFO *thisDisk;
int32 hostSector;
int32 sectorSize;
uint32 flags;
uint32 writelen;
uint32 cylinder;
uint32 head;
size_t rtn;
UNIT *uptr = &hdsk_dev.units[selectedDisk];
if (((uptr -> flags) & UNIT_HDSK_WLK) == 0) { /* write enabled */
if (is_imd(uptr)) {
for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++)
hdskbuf[i] = GetBYTEWrapper(selectedDMA + i);
thisDisk = hdsk_imd[selectedDisk];
hostSector = ((dpb[uptr -> HDSK_FORMAT_TYPE].skew == NULL) ?
selectedSector : dpb[uptr -> HDSK_FORMAT_TYPE].skew[selectedSector]) + thisDisk -> track[1][0].start_sector;
sectorSize = ((dpb[uptr -> HDSK_FORMAT_TYPE].physicalSectorSize == 0) ?
uptr -> HDSK_SECTOR_SIZE :
dpb[uptr -> HDSK_FORMAT_TYPE].physicalSectorSize);
flags = 0;
writelen = 0;
cylinder = selectedTrack;
head = 0;
if (cylinder >= thisDisk -> ntracks / thisDisk -> nsides) {
head = 1;
cylinder -= thisDisk -> ntracks / thisDisk -> nsides;
}
result = sectWrite(thisDisk, cylinder, head, hostSector, hdskbuf,
sectorSize, &flags, &writelen);
if (result != SCPE_OK) {
sim_debug(VERBOSE_MSG, &hdsk_dev, "HDSK%d (IMD): " ADDRESS_FORMAT
" . Could not write Sector=%02d Track=%04d.\n",
selectedDisk, PCX, selectedSector, selectedTrack);
return CPM_ERROR;
}
} else {
if (doSeek())
return CPM_ERROR;
for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++)
@ -643,6 +832,7 @@ static int32 doWrite(void) {
return CPM_ERROR;
}
}
}
else {
sim_debug(VERBOSE_MSG, &hdsk_dev, "HDSK%d: " ADDRESS_FORMAT
" Could not write to locked disk Sector=%02d Track=%04d.\n",

View file

@ -1,6 +1,6 @@
/* altairz80_net.c: networking capability
Copyright (c) 2002-2011, Peter Schorn
Copyright (c) 2002-2013, Peter Schorn
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -77,16 +77,14 @@ static struct {
static UNIT net_unit = {
UDATA (&net_svc, UNIT_ATTABLE, 0),
0, /* wait, set in attach */
0, /* u3 = Port */
0, /* u4 = IP of host */
0, /* u3, unused */
0, /* u4, unused */
0, /* u5, unused */
0, /* u6, unused */
};
static REG net_reg[] = {
{ DRDATA (POLL, net_unit.wait, 32) },
{ HRDATA (IPHOST, net_unit.u4, 32), REG_RO },
{ DRDATA (PORT, net_unit.u3, 32), REG_RO },
{ NULL }
};

View file

@ -1,6 +1,6 @@
/* altairz80_sio.c: MITS Altair serial I/O card
Copyright (c) 2002-2011, Peter Schorn
Copyright (c) 2002-2013, Peter Schorn
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -72,7 +72,7 @@ uint8 *URLContents(const char *URL, uint32 *length) {
char *result;
strncat(str, URL, RESULT_BUFFER_LENGTH - strlen(RESULT_LEAD_IN) - strlen(RESULT_LEAD_OUT) - 1);
strcat(str, RESULT_LEAD_OUT);
result = malloc(strlen(str));
result = (char*)malloc(strlen(str));
strcpy(result, str);
*length = strlen(str);
return (uint8*)result;
@ -733,8 +733,10 @@ static int32 sio0dCore(const int32 port, const int32 io, const int32 data) {
ch = sio_unit.flags & UNIT_SIO_ANSI ? data & 0x7f : data; /* clear highest bit in ANSI mode */
if ((ch != CONTROLG_CHAR) || !(sio_unit.flags & UNIT_SIO_BELL)) {
voidSleep();
if ((sio_unit.flags & UNIT_ATT) && (!sio_unit.u4)) /* attached to a port and not to a file */
if ((sio_unit.flags & UNIT_ATT) && (!sio_unit.u4)) { /* attached to a port and not to a file */
tmxr_putc_ln(&TerminalLines[spi.terminalLine], ch); /* status ignored */
tmxr_poll_tx(&altairTMXR); /* poll xmt */
}
else
sim_putchar(ch);
}

View file

@ -1,6 +1,6 @@
/* altairz80_sys.c: MITS Altair system interface
Copyright (c) 2002-2011, Peter Schorn
Copyright (c) 2002-2013, Peter Schorn
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -138,13 +138,13 @@ const char *sim_stop_messages[] = {
static char *const Mnemonics8080[] = {
/* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
"NOP", "LXI B,#h", "STAX B", "INX B", "INR B", "DCR B", "MVI B,*h", "RLC", /* 00-07 */
"DB 09h", "DAD B", "LDAX B", "DCX B", "INR C", "DCR C", "MVI C,*h", "RRC", /* 08-0f */
"DB 10h", "LXI D,#h", "STAX D", "INX D", "INR D", "DCR D", "MVI D,*h", "RAL", /* 10-17 */
"DB 18h", "DAD D", "LDAX D", "DCX D", "INR E", "DCR E", "MVI E,*h", "RAR", /* 18-1f */
"DB 20h", "LXI H,#h", "SHLD #h", "INX H", "INR H", "DCR H", "MVI H,*h", "DAA", /* 20-27 */
"DB 28h", "DAD H", "LHLD #h", "DCX H", "INR L", "DCR L", "MVI L,*h", "CMA", /* 28-2f */
"DB 30h", "LXI SP,#h", "STA #h", "INX SP", "INR M", "DCR M", "MVI M,*h", "STC", /* 30-37 */
"DB 38h", "DAD SP", "LDA #h", "DCX SP", "INR A", "DCR A", "MVI A,*h", "CMC", /* 38-3f */
"_NOP", "DAD B", "LDAX B", "DCX B", "INR C", "DCR C", "MVI C,*h", "RRC", /* 08-0f */
"_NOP", "LXI D,#h", "STAX D", "INX D", "INR D", "DCR D", "MVI D,*h", "RAL", /* 10-17 */
"_NOP", "DAD D", "LDAX D", "DCX D", "INR E", "DCR E", "MVI E,*h", "RAR", /* 18-1f */
"_NOP", "LXI H,#h", "SHLD #h", "INX H", "INR H", "DCR H", "MVI H,*h", "DAA", /* 20-27 */
"_NOP", "DAD H", "LHLD #h", "DCX H", "INR L", "DCR L", "MVI L,*h", "CMA", /* 28-2f */
"_NOP", "LXI SP,#h", "STA #h", "INX SP", "INR M", "DCR M", "MVI M,*h", "STC", /* 30-37 */
"_NOP", "DAD SP", "LDA #h", "DCX SP", "INR A", "DCR A", "MVI A,*h", "CMC", /* 38-3f */
"MOV B,B", "MOV B,C", "MOV B,D", "MOV B,E", "MOV B,H", "MOV B,L", "MOV B,M", "MOV B,A", /* 40-47 */
"MOV C,B", "MOV C,C", "MOV C,D", "MOV C,E", "MOV C,H", "MOV C,L", "MOV C,M", "MOV C,A", /* 48-4f */
"MOV D,B", "MOV D,C", "MOV D,D", "MOV D,E", "MOV D,H", "MOV D,L", "MOV D,M", "MOV D,A", /* 50-57 */
@ -162,13 +162,13 @@ static char *const Mnemonics8080[] = {
"ORA B", "ORA C", "ORA D", "ORA E", "ORA H", "ORA L", "ORA M", "ORA A", /* b0-b7 */
"CMP B", "CMP C", "CMP D", "CMP E", "CMP H", "CMP L", "CMP M", "CMP A", /* b8-bf */
"RNZ", "POP B", "JNZ #h", "JMP #h", "CNZ #h", "PUSH B", "ADI *h", "RST 0", /* c0-c7 */
"RZ", "RET", "JZ #h", "DB CBh", "CZ #h", "CALL #h", "ACI *h", "RST 1", /* c8-cf */
"RZ", "RET", "JZ #h", "_JMP #h", "CZ #h", "CALL #h", "ACI *h", "RST 1", /* c8-cf */
"RNC", "POP D", "JNC #h", "OUT *h", "CNC #h", "PUSH D", "SUI *h", "RST 2", /* d0-d7 */
"RC", "DB D9h", "JC #h", "IN *h", "CC #h", "DB DDh", "SBI *h", "RST 3", /* d8-df */
"RC", "_RET", "JC #h", "IN *h", "CC #h", "_CALL #h", "SBI *h", "RST 3", /* d8-df */
"RPO", "POP H", "JPO #h", "XTHL", "CPO #h", "PUSH H", "ANI *h", "RST 4", /* e0-e7 */
"RPE", "PCHL", "JPE #h", "XCHG", "CPE #h", "DB EDh", "XRI *h", "RST 5", /* e8-ef */
"RPE", "PCHL", "JPE #h", "XCHG", "CPE #h", "_CALL #h", "XRI *h", "RST 5", /* e8-ef */
"RP", "POP PSW", "JP #h", "DI", "CP #h", "PUSH PSW", "ORI *h", "RST 6", /* f0-f7 */
"RM", "SPHL", "JM #h", "EI", "CM #h", "DB FDh", "CPI *h", "RST 7" /* f8-ff */
"RM", "SPHL", "JM #h", "EI", "CM #h", "_CALL #h", "CPI *h", "RST 7" /* f8-ff */
};
static char *const MnemonicsZ80[256] = {

View file

@ -2,7 +2,7 @@
IMSAI FIF Disk Controller by Ernie Price
Based on altairz80_dsk.c, Copyright (c) 2002-2011, Peter Schorn
Based on altairz80_dsk.c, Copyright (c) 2002-2013, Peter Schorn
Plug-n-Play added by Howard M. Harte

View file

@ -759,7 +759,7 @@ t_stat trackWrite(DISK_INFO *myDisk,
* sector record type as the first byte, and fill the sector
* data with the fillbyte.
*/
dataLen = (128 << sectorLen)+1;
dataLen = sectorLen + 1;
sectorData = malloc(dataLen);
memset(sectorData, fillbyte, dataLen);
sectorData[0] = SECT_RECORD_NORM;