mirror of
https://github.com/rcornwell/sims.git
synced 2026-04-17 00:35:52 +00:00
IBM360: Major update. MVT now can be built.
CDR: Clean up to return correct status on EOF and empty deck. CHAN: Fixed problems with storage key support. CHAN: Proper handling of error on initial connect to device. CPU: Fixed errors in handling of storage key protection. CPU: Added aligned data access. CPU: Floating point code starting to work. Still some errors. DASD: Corrected sense data for 2311 and 2314 drives for CP/67. MT: Cleaned up proper handling of unattached units. SYS: Fixed bug in deposit.
This commit is contained in:
@@ -3,24 +3,20 @@ Current status:
|
||||
Operating Systems:
|
||||
TOS/360: Will IPL, and read IPL deck. Will run some jobs.
|
||||
|
||||
DOS/360: Will initialize disk.
|
||||
Will restore disk.
|
||||
Will run basic commands.
|
||||
Assembly aborts with invalid instruction.
|
||||
DOS/360: Will restore and run supervisor gen job on 2314.
|
||||
|
||||
OS/360: Will initialize disk.
|
||||
Will restore disk.
|
||||
Can run some jobs.
|
||||
OS/360: MVT can be generated. Fortran, Algol working.
|
||||
|
||||
ibm360_cpu.c:
|
||||
Need to complete floating point and decimal instructions.
|
||||
Floating point starting to work.
|
||||
Decimal instructions need test.
|
||||
Complete /67 support.
|
||||
|
||||
ibm360_chan.c
|
||||
More debugging required.
|
||||
Mostly working.
|
||||
|
||||
ibm360_cdp.c:
|
||||
Add support for binary mode.
|
||||
Fix translation table.
|
||||
|
||||
ibm360_cdr.c:
|
||||
Add support for binary mode.
|
||||
@@ -32,15 +28,15 @@ ibm360_con.c:
|
||||
Appears to be working.
|
||||
|
||||
ibm360_dasd.c:
|
||||
Possibly working.
|
||||
Mostly working.
|
||||
|
||||
ibm360_lpr.c:
|
||||
Need to add in support for line skip and skip control.
|
||||
|
||||
ibm360_mt.c:
|
||||
Possibly working.
|
||||
Mostly working.
|
||||
|
||||
ibm360_sys.c:
|
||||
Need to add in deposit function.
|
||||
Working.
|
||||
|
||||
|
||||
|
||||
@@ -119,6 +119,16 @@ uint8 cdr_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
}
|
||||
|
||||
sim_debug(DEBUG_CMD, dptr, "CMD unit=%d %x\n", unit, cmd);
|
||||
if (cmd != 4 && sim_card_eof(uptr) == 1) {
|
||||
uint16 *image = (uint16 *)(uptr->up7);
|
||||
uptr->u5 = SNS_INTVENT;
|
||||
sim_read_card(uptr, image); /* Read in the EOF */
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
}
|
||||
if (cmd != 4 && (uptr->flags & UNIT_ATT) == 0) {
|
||||
uptr->u5 = SNS_INTVENT;
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
}
|
||||
switch (cmd & 0x7) {
|
||||
case 2: /* Read command */
|
||||
if ((cmd & 0xc0) != 0xc0)
|
||||
@@ -171,6 +181,8 @@ cdr_srv(UNIT *uptr) {
|
||||
|
||||
if ((uptr->u3 & CDR_CMDMSK) == CHN_SNS) {
|
||||
uint8 ch = uptr->u5;
|
||||
if (ch == 0 && (uptr->flags & UNIT_ATT) == 0)
|
||||
ch = SNS_INTVENT;
|
||||
chan_write_byte(addr, &ch);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
uptr->u3 &= ~(CDR_CMDMSK);
|
||||
@@ -180,16 +192,16 @@ cdr_srv(UNIT *uptr) {
|
||||
/* Check if new card requested. */
|
||||
if ((uptr->u3 & CDR_CARD) == 0) {
|
||||
switch(sim_read_card(uptr, image)) {
|
||||
case CDSE_EOF:
|
||||
case CDSE_EMPTY:
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
uptr->u5 = SNS_INTVENT;
|
||||
case CDSE_EOF:
|
||||
uptr->u3 &= ~CDR_CMDMSK;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
return SCPE_OK;
|
||||
case CDSE_ERROR:
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
|
||||
uptr->u5 = SNS_INTVENT;
|
||||
uptr->u3 &= ~CDR_CMDMSK;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
|
||||
return SCPE_OK;
|
||||
case CDSE_OK:
|
||||
uptr->u3 |= CDR_CARD;
|
||||
|
||||
@@ -150,22 +150,26 @@ readfull(int chan, uint32 addr, uint32 *word) {
|
||||
int sk, k;
|
||||
if ((addr & AMASK) > MEMSIZE) {
|
||||
chan_status[chan] |= STATUS_PCHK;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
sk = (addr >> 24) & 0xff;
|
||||
sk = (addr >> 24) & 0xf0;
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
if (sk != 0) {
|
||||
if ((cpu_dev.flags & PROTECT) == 0) {
|
||||
if ((cpu_unit.flags & FEAT_PROT) == 0) {
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
k = key[(addr & 0xfffc00) >> 10];
|
||||
k = key[addr >> 9];
|
||||
if ((k & 0x8) != 0 && (k & 0xf0) != sk) {
|
||||
//fprintf(stderr, "Prot %08x %x %x\n\r", addr << 2, k, sk);
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
*word = M[addr];
|
||||
return 0;
|
||||
}
|
||||
@@ -184,24 +188,25 @@ readbuff(int chan) {
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
sk = (addr >> 24) & 0xff;
|
||||
sk = (addr >> 24) & 0xf0;
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
if (sk != 0) {
|
||||
if ((cpu_dev.flags & PROTECT) == 0) {
|
||||
if ((cpu_unit.flags & FEAT_PROT) == 0) {
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
k = key[(addr & 0xfffc00) >> 10];
|
||||
k = key[addr >> 9];
|
||||
if ((k & 0x8) != 0 && (k & 0xf0) != sk) {
|
||||
//fprintf(stderr, "Prot %08x %x %x\n\r", addr << 2, k, sk);
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
chan_buf[chan] = M[addr];
|
||||
if ((ccw_cmd[chan] & CMD_TYPE) == CMD_WRITE) {
|
||||
sim_debug(DEBUG_CDATA, &cpu_dev, "Channel write %02x %06x %08x %08x '",
|
||||
@@ -233,23 +238,24 @@ writebuff(int chan) {
|
||||
return 1;
|
||||
}
|
||||
sk = (addr >> 24) & 0xff;
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
if (sk != 0) {
|
||||
if ((cpu_dev.flags & PROTECT) == 0) {
|
||||
if ((cpu_unit.flags & FEAT_PROT) == 0) {
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
k = key[(addr & 0xfffc00) >> 10];
|
||||
if ((k & 0x8) != 0 && (k & 0xf0) != sk) {
|
||||
k = key[addr >> 9];
|
||||
if ((k & 0xf0) != sk) {
|
||||
//fprintf(stderr, "Prot %08x %x %x\n\r", addr << 2, k, sk);
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
M[addr] = chan_buf[chan];
|
||||
sim_debug(DEBUG_CDATA, &cpu_dev, "Channel readf %02x %06x %08x %08x '",
|
||||
chan, ccw_addr[chan] & 0xFFFFFC, chan_buf[chan], ccw_count[chan]);
|
||||
@@ -575,8 +581,6 @@ int startio(uint16 addr) {
|
||||
uptr = find_chan_dev(addr);
|
||||
if (uptr == 0)
|
||||
return 3;
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return 3;
|
||||
if (ccw_cmd[chan] != 0 || (ccw_flags[chan] & (FLAG_CD|FLAG_CC)) != 0 || chan_status[chan] != 0)
|
||||
return 2;
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x %x %x\n", addr, chan,
|
||||
@@ -595,13 +599,24 @@ int startio(uint16 addr) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (load_ccw(chan, 0) || (chan_status[chan] & (STATUS_PCI))) {
|
||||
M[0x44 >> 2] = ((uint32)chan_status[chan]<<16) | M[0x44 >> 2] & 0xffff;
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "Channel store csw %02x %08x\n",
|
||||
chan, M[0x44 >> 2]);
|
||||
chan_status[chan] &= ~STATUS_PCI;
|
||||
dev_status[addr] = 0;
|
||||
return 1;
|
||||
if (load_ccw(chan, 0)) {
|
||||
if (chan_status[chan] & (STATUS_ATTN|STATUS_CHECK|STATUS_PROT|STATUS_PCHK|STATUS_EXPT)) {
|
||||
M[0x44 >> 2] = ((uint32)chan_status[chan]<<16) | M[0x44 >> 2] & 0xffff;
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x %x %x cc=2\n", addr, chan,
|
||||
ccw_cmd[chan], ccw_flags[chan]);
|
||||
chan_status[chan] = 0;
|
||||
dev_status[addr] = 0;
|
||||
ccw_cmd[chan] = 0;
|
||||
return 1;
|
||||
}
|
||||
if (chan_status[chan] & (STATUS_PCI)) {
|
||||
M[0x44 >> 2] = ((uint32)chan_status[chan]<<16) | M[0x44 >> 2] & 0xffff;
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "Channel store csw %02x %08x\n",
|
||||
chan, M[0x44 >> 2]);
|
||||
chan_status[chan] &= ~STATUS_PCI;
|
||||
dev_status[addr] = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (chan_status[chan] & STATUS_BUSY) {
|
||||
M[0x40 >> 2] = 0;
|
||||
@@ -628,34 +643,32 @@ int testio(uint16 addr) {
|
||||
uptr = find_chan_dev(addr);
|
||||
if (uptr == 0)
|
||||
return 3;
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return 3;
|
||||
if (chan_status[chan] & (STATUS_PCI|STATUS_ATTN|STATUS_CHECK|\
|
||||
STATUS_PROT|STATUS_PCHK|STATUS_EXPT)) {
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1\n", addr, chan,
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1\n", addr, chan,
|
||||
ccw_cmd[chan], ccw_flags[chan]);
|
||||
store_csw(chan);
|
||||
return 1;
|
||||
}
|
||||
if (ccw_cmd[chan] != 0 || (ccw_flags[chan] & (FLAG_CD|FLAG_CC)) != 0) {
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=2\n", addr, chan,
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=2\n", addr, chan,
|
||||
ccw_cmd[chan], ccw_flags[chan]);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
if (chan_dev[chan] != 0 && chan_dev[chan] != addr) {
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=2a\n", addr, chan,
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=2a\n", addr, chan,
|
||||
ccw_cmd[chan], ccw_flags[chan]);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
if (ccw_cmd[chan] == 0 && chan_status[chan] != 0) {
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1a\n", addr, chan,
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1a\n", addr, chan,
|
||||
ccw_cmd[chan], ccw_flags[chan]);
|
||||
store_csw(chan);
|
||||
chan_dev[chan] = 0;
|
||||
return 1;
|
||||
}
|
||||
if (dev_status[addr] != 0) {
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1b\n", addr, chan,
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1b\n", addr, chan,
|
||||
ccw_cmd[chan], ccw_flags[chan]);
|
||||
M[0x40 >> 2] = 0;
|
||||
M[0x44 >> 2] = ((uint32)dev_status[addr]) << 24;
|
||||
@@ -663,18 +676,21 @@ int testio(uint16 addr) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
chan_status[chan] = dibp->start_cmd(uptr, chan, 0) << 8;
|
||||
if (chan_status[chan] & (STATUS_ATTN|STATUS_CHECK|STATUS_EXPT)) {
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1c\n", addr, chan,
|
||||
status = dibp->start_cmd(uptr, chan, 0) << 8;
|
||||
if (status == 0 && (uptr->flags & UNIT_ATT) == 0) {
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1c\n", addr, chan,
|
||||
ccw_cmd[chan], ccw_flags[chan]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (status & (STATUS_ATTN|STATUS_CHECK|STATUS_EXPT)) {
|
||||
M[0x44 >> 2] = ((uint32)status<<24) | M[0x44 >> 2] & 0xffff;
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1d\n", addr, chan,
|
||||
ccw_cmd[chan], ccw_flags[chan]);
|
||||
M[0x44 >> 2] = ((uint32)chan_status[chan]<<16) | M[0x44 >> 2] & 0xffff;
|
||||
chan_status[chan] = 0;
|
||||
dev_status[addr] = 0;
|
||||
return 1;
|
||||
}
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=0\n", addr, chan,
|
||||
ccw_cmd[chan], ccw_flags[chan]);
|
||||
chan_status[chan] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -386,7 +386,7 @@ uint8 dasd_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
sim_debug(DEBUG_CMD, dptr, "CMD unit=%d %02x\n", unit, cmd);
|
||||
if ((uptr->flags & UNIT_ATT) == 0) {
|
||||
if (cmd == 0x4) { /* Sense */
|
||||
sim_debug(DEBUG_CMD, dptr, "CMD sense\n");
|
||||
sim_debug(DEBUG_CMD, dptr, "CMD sense\n");
|
||||
ch = uptr->u5 & 0xff;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 1 %x\n", unit, ch);
|
||||
chan_write_byte(addr, &ch) ;
|
||||
@@ -406,9 +406,9 @@ uint8 dasd_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
}
|
||||
if (cmd == 0x0)
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
return 0;
|
||||
|
||||
uptr->u5 = 0x48; /*SNS_INTVENT|SNS_CMDREJ; */
|
||||
uptr->u5 = SNS_INTVENT|SNS_CMDREJ;
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
}
|
||||
|
||||
@@ -734,7 +734,7 @@ index:
|
||||
if (chan_write_byte(addr, &ch))
|
||||
goto sense_end;
|
||||
if (disk_type[type].sen_cnt > 6) {
|
||||
ch = 0;
|
||||
ch = (unit & 07) | ((~unit & 07) << 3);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 4 %x\n", unit, ch);
|
||||
if (chan_write_byte(addr, &ch))
|
||||
goto sense_end;
|
||||
@@ -756,11 +756,20 @@ index:
|
||||
goto sense_end;
|
||||
i = 8;
|
||||
} else {
|
||||
ch = unit;
|
||||
if (disk_type[type].dev_type == 0x11)
|
||||
ch = 0xc8;
|
||||
else
|
||||
ch = 0x40;
|
||||
if ((uptr->u4 >> 8) & SNS_ENDCYL)
|
||||
ch |= 4;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 4 %x\n", unit, ch);
|
||||
if (chan_write_byte(addr, &ch))
|
||||
goto sense_end;
|
||||
i = 4;
|
||||
ch = unit;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 5 %x\n", unit, ch);
|
||||
if (chan_write_byte(addr, &ch))
|
||||
goto sense_end;
|
||||
i = 5;
|
||||
}
|
||||
ch = 0;
|
||||
for (; i < disk_type[type].sen_cnt; i++) {
|
||||
|
||||
@@ -76,17 +76,15 @@ typedef struct dib {
|
||||
#define GET_UADDR(x) ((UNIT_ADDR_MASK & x) >> UNIT_V_ADDR)
|
||||
#define UNIT_ADDR(x) ((x) << UNIT_V_ADDR)
|
||||
|
||||
#define PROTECT_V UNIT_V_UF+12
|
||||
#define PROTECT (1 << PROTECT_V)
|
||||
|
||||
/* Arithmetic */
|
||||
|
||||
/* Instruction format */
|
||||
|
||||
/* Globally visible flags */
|
||||
|
||||
/* I/O routine functions */
|
||||
|
||||
/* CPU options, needed by channel */
|
||||
#define FEAT_PROT (1 << (UNIT_V_UF + 8)) /* Storage protection feature */
|
||||
#define FEAT_DEC (1 << (UNIT_V_UF + 9)) /* Decimal instruction set */
|
||||
#define FEAT_FLOAT (1 << (UNIT_V_UF + 10)) /* Floating point instruction set */
|
||||
#define FEAT_UNIV (3 << (UNIT_V_UF + 9)) /* All instructions */
|
||||
#define FEAT_STOR (1 << (UNIT_V_UF + 11)) /* No alignment restrictions */
|
||||
#define FEAT_TIMER (1 << (UNIT_V_UF + 12)) /* Interval timer */
|
||||
#define FEAT_DAT (1 << (UNIT_V_UF + 13)) /* Dynamic address translation */
|
||||
#define EXT_IRQ (1 << (UNIT_V_UF_31)) /* External interrupt */
|
||||
|
||||
/* low addresses */
|
||||
#define IPSW 0x00 /* IPSW */
|
||||
|
||||
@@ -268,6 +268,10 @@ uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
|
||||
case 0x3: /* Control */
|
||||
case 0xb: /* Control */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) {
|
||||
uptr->u5 |= SNS_INTVENT;
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
}
|
||||
if ((uptr->flags & MTUF_9TR) == 0) {
|
||||
uptr->u5 |= (SNS_7TRACK << 8);
|
||||
if ((cmd & 0xc0) == 0xc0) {
|
||||
@@ -375,8 +379,12 @@ t_stat mt_srv(UNIT * uptr)
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) {
|
||||
uptr->u5 |= SNS_INTVENT;
|
||||
if (cmd != MT_SENSE)
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
if (cmd != MT_SENSE) {
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
@@ -918,7 +918,7 @@ if (sw & SWMASK ('M')) {
|
||||
}
|
||||
num = get_uint(cptr, rdx, max[l], &r);
|
||||
for (i = 0; i < l && i < 4; i++)
|
||||
val[i] = (num >> (i * 8)) & 0xff;
|
||||
val[i] = (num >> (((l - 1) - i) * 8)) & 0xff;
|
||||
return -(l-1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user