@@ -37,6 +37,7 @@ import (
37
37
mem "github.com/rcornwell/S370/emu/memory"
38
38
op "github.com/rcornwell/S370/emu/opcodemap"
39
39
ch "github.com/rcornwell/S370/emu/sys_channel"
40
+ "github.com/rcornwell/S370/util/debug"
40
41
)
41
42
42
43
/*
@@ -179,6 +180,16 @@ func Shutdown() {
179
180
ch .Shutdown ()
180
181
}
181
182
183
+ // Enable debug options.
184
+ func Debug (opt string ) error {
185
+ flag , ok := debugOption [opt ]
186
+ if ! ok {
187
+ return errors .New ("CPU debug option invalid: " + opt )
188
+ }
189
+ debugMsk |= flag
190
+ return nil
191
+ }
192
+
182
193
// Return CPU PC.
183
194
func PC () uint32 {
184
195
return sysCPU .PC
@@ -320,10 +331,10 @@ func (cpu *cpuState) fetch() (int, bool) {
320
331
step .R1 = (step .reg >> 4 ) & 0xf
321
332
step .R2 = step .reg & 0xf
322
333
323
- // brop := (step.opcode == op.OpBC || step.opcode == op.OpBCR)
324
- // if cpu.iPC == cpu.PC && brop && (step.reg&0xf0) == 0xf0 {
325
- // return memCycle, false
326
- // }
334
+ //brop := (step.opcode == op.OpBC || step.opcode == op.OpBCR)
335
+ //if cpu.iPC == cpu.PC && brop && (step.reg&0xf0) == 0xf0 {
336
+ // return memCycle, false
337
+ //}
327
338
cpu .perRegMod = 0
328
339
cpu .perCode = 0
329
340
cpu .perAddr = cpu .PC
@@ -349,22 +360,13 @@ func (cpu *cpuState) fetch() (int, bool) {
349
360
return memCycle , true
350
361
}
351
362
step .address1 = (word >> 16 )
352
- inst [2 ] = byte ((word >> 24 ) & 0xff )
353
- inst [3 ] = byte ((word >> 16 ) & 0xff )
354
363
} else {
355
364
step .address1 = word
356
- inst [2 ] = byte (word >> 8 )
357
- inst [3 ] = byte (word & 0xff )
358
365
}
359
- // if cpu.iPC != 0x0002026 {
360
- // fmt.Printf("%02x%02x ", inst[2], inst[3])
361
- // }
362
366
step .address1 &= 0xffff
367
+ inst [2 ] = byte (step .address1 >> 8 )
368
+ inst [3 ] = byte (step .address1 & 0xff )
363
369
cpu .PC += 2
364
- // } else {
365
- // if cpu.iPC != 0x0002026 {
366
- // fmt.Printf(" ")
367
- // }
368
370
}
369
371
370
372
// If SS
@@ -378,29 +380,33 @@ func (cpu *cpuState) fetch() (int, bool) {
378
380
return memCycle , true
379
381
}
380
382
step .address2 = (word >> 16 )
381
- inst [4 ] = byte (word >> 8 )
382
- inst [5 ] = byte (word & 0xff )
383
383
} else {
384
384
step .address2 = word
385
- inst [4 ] = byte (word >> 8 )
386
- inst [5 ] = byte (word & 0xff )
387
385
}
388
- // if cpu.iPC != 0x0002026 {
389
- // fmt.Printf("%02x%02x ", inst[4], inst[5])
390
- // }
391
386
step .address2 &= 0xffff
387
+ inst [4 ] = byte (step .address2 >> 8 )
388
+ inst [5 ] = byte (step .address2 & 0xff )
392
389
cpu .PC += 2
393
- // } else {
394
- // if cpu.iPC != 0x0002026 {
395
- // fmt.Printf(" ")
396
- // }
397
390
}
398
391
399
392
// if cpu.iPC != 0x0002026 {
400
- symbolic , _ := dis .Disasemble (inst )
401
- symbolic += " "
402
- // fmt.Printf(" %s\n", symbolic)
403
- //}
393
+ if (debugMsk & debugInst ) != 0 {
394
+ str := fmt .Sprintf ("%08x %02x %02x " , cpu .iPC , uint32 (step .opcode ), uint32 (step .reg ))
395
+ if cpu .ilc > 1 {
396
+ str += fmt .Sprintf ("%02x%02x " , inst [2 ], inst [3 ])
397
+ } else {
398
+ str += " "
399
+ }
400
+ if cpu .ilc > 2 {
401
+ str += fmt .Sprintf ("%02x%02x " , inst [4 ], inst [5 ])
402
+ } else {
403
+ str += " "
404
+ }
405
+ symbolic , _ := dis .Disasemble (inst )
406
+ str += symbolic
407
+ debug .Debugf ("CPU" , debugMsk , debugInst , str )
408
+ }
409
+
404
410
err = cpu .execute (& step )
405
411
if err != 0 {
406
412
cpu .suppress (oPPSW , err )
@@ -624,7 +630,7 @@ func (cpu *cpuState) lpsw(src1, src2 uint32) {
624
630
cpu .stKey = uint8 ((src1 >> 16 ) & 0xf0 )
625
631
cpu .flags = uint8 ((src1 >> 16 ) & 0x7 )
626
632
cpu .PC = src2 & AMASK
627
- // fmt.Printf(" LPSW %08x: %08x %08x\n ", cpu.iPC, src1, src2)
633
+ debug . Debugf ( "CPU" , debugMsk , debugDetail , " LPSW %08x: %08x %08x" , cpu .iPC , src1 , src2 )
628
634
// sim_debug(DEBUG_INST, &cpu_dev, "PSW=%08x %08x ", src1, src2)
629
635
if cpu .ecMode && ((src1 & 0xb800c0ff ) != 0 || (src2 & 0xff000000 ) != 0 ) {
630
636
cpu .suppress (oPPSW , ircSpec )
@@ -698,7 +704,7 @@ func (cpu *cpuState) storePSW(vector uint32, irqcode uint16) (irqaddr uint32) {
698
704
word1 |= uint32 (extEnable ) << 24
699
705
}
700
706
701
- //fmt.Printf(" Store PSW: %08x %04x %08x %08x\n ", vector, irqcode, word1, word2)
707
+ debug . Debugf ( "CPU" , debugMsk , debugDetail , " Store PSW: %08x %04x %08x %08x" , vector , irqcode , word1 , word2 )
702
708
memCycle ++
703
709
mem .SetMemory (vector , word1 )
704
710
memCycle ++
@@ -1166,7 +1172,7 @@ func (cpu *cpuState) writeHalf(virtAddr, data uint32) uint16 {
1166
1172
1167
1173
offset := virtAddr & 3
1168
1174
1169
- // Validate address cy = dec_divstep(l int, s1 int, s2 int, v1 *[32]uint8, v2 *[32]uint8) uint8
1175
+ // Validate address
1170
1176
physAddr , pageErr := cpu .transAddr (virtAddr )
1171
1177
if pageErr != 0 {
1172
1178
return pageErr
@@ -1320,110 +1326,3 @@ func setIPLDev(devNum uint16, _ string, _ []config.Option) error {
1320
1326
IPLDev = devNum
1321
1327
return nil
1322
1328
}
1323
-
1324
- //
1325
- // /* Reset */
1326
-
1327
- // t_stat
1328
- // cpu_reset (DEVICE *dptr)
1329
- // {
1330
- // int i;
1331
-
1332
- // /* Make sure devices are mapped correctly */
1333
- // chan_set_devs();
1334
- // sim_vm_fprint_stopped = &cpu_fprint_stopped;
1335
- // /* Create memory array if it does not exist. */%s\n
1336
- // if (M == NULL) { /* first time init? */
1337
- // sim_brk_types = sim_brk_dflt = SWMASK ('E');
1338
- // M = (uint32 *) calloc (((uint32) MEMSIZE) >> 2, sizeof (uint32));
1339
- // if (M == NULL)
1340
- // return SCPE_MEM;
1341
- // }
1342
- // /* Set up channels */
1343
- // chan_set_devs();
1344
-
1345
- // sysmsk = irqcode = irqaddr = loading = 0;
1346
- // st_key = cc = pmsk = ec_mode = interval_irq = flags = 0;
1347
- // page_en = irq_en = ext_en = per_en = 0;
1348
- // clk_state = CLOCK_UNSET;
1349
- // for (i = 0; i < 256; i++)
1350
- // tlb[i] = 0;
1351
- // for (i = 0; i < 4096; i++)
1352
- // key[i] = 0;
1353
- // for (i = 0; i < 16; i++)
1354
- // cregs[i] = 0;
1355
- // clk_cmp[0] = clk_cmp[1] = 0xffffffff;
1356
- // if (Q370) {
1357
- // if (clk_state == CLOCK_UNSET) {
1358
- // /* Set TOD to current time */
1359
- // time_t seconds = sim_get_time(NULL);
1360
- // t_uint64 lsec = (t_uint64)seconds;
1361
- // /* IBM measures time from 1900, Unix starts at 1970 */
1362
- // /* Add in number of years from 1900 to 1970 + 17 leap days */
1363
- // lsec += ((70 * 365) + 17) * 86400ULL;
1364
- // lsec *= 1000000ULL;
1365
- // lsec <<= 12;
1366
- // tod_clock[0] = (uint32)(lsec >> 32);
1367
- // tod_clock[1] = (uint32)(lsec & FMASK);
1368
- // clk_state = CLOCK_SET;
1369
- // }
1370
- // cregs[0] = 0x000000e0;
1371
- // cregs[2] = 0xffffffff;
1372
- // cregs[14] = 0xc2000000;
1373
- // cregs[15] = 512;
1374
- // }
1375
-
1376
- // if (cpu_unit[0].flags & (FEAT_370|FEAT_TIMER)) {
1377
- // sim_rtcn_init_unit (&cpu_unit[0], 1000, TMR_RTC);
1378
- // sim_activate(&cpu_unit[0], 100);
1379
- // }
1380
- // idle_stop_tm0 = 0;
1381
- // return SCPE_OK;
1382
- // }
1383
-
1384
- // /* RSV: Set CPU IDLESTOP=<val>
1385
- // * <val>=number of seconds.
1386
- // *
1387
- // * Sets max time in secounds CPU is IDLE but waiting for interrupt
1388
- // * from device. if <val> not zero, simulated CPU will wait for this wallclock
1389
- // * number of seconds, then stop. This allows to script a BOOT command and the
1390
- // * continue automatically when IPL has finished. Set to zero to disable.
1391
- // */
1392
-
1393
- // t_stat cpu_set_idle_stop (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
1394
- // {
1395
- // int32 n;
1396
- // t_stat r;
1397
-
1398
- // if (cptr == NULL) {
1399
- // return SCPE_ARG;
1400
- // }
1401
- // n = (int32) get_uint(cptr, 10, 60, &r);
1402
- // if (r != SCPE_OK) return SCPE_ARG;
1403
- // idle_stop_msec = n * 1000;
1404
- // idle_stop_tm0 = 0;
1405
- // return SCPE_OK;
1406
- // }
1407
-
1408
- // t_bool
1409
- // cpu_fprint_stopped (FILE *st, t_stat v)
1410
- // {
1411
- // if (ec_mode) {
1412
- // if (Q370)
1413
- // fprintf(st, " PSW=%08x %08x\n",
1414
- // (((uint32)page_en) << 26) | ((per_en) ? 1<<30:0) | ((irq_en) ? 1<<25:0) |
1415
- // ((ext_en) ? 1<<24:0) | 0x80000 | (((uint32)st_key) << 16) |
1416
- // (((uint32)flags) << 16) | (((uint32)cc) << 12) | (((uint32)pmsk) << 8), PC);
1417
- // else
1418
- // fprintf(st, " PSW=%08x %08x\n",
1419
- // (((uint32)page_en) << 26) | ((irq_en) ? 1<<25:0) | ((ext_en) ? 1<<24:0) |
1420
- // (((uint32)st_key) << 16) | (((uint32)flags) << 16) |
1421
- // (((uint32)ilc) << 14) | (((uint32)cc) << 12) | (((uint32)pmsk) << 8), PC);
1422
- // } else {
1423
- // fprintf(st, " PSW=%08x %08x\n",
1424
- // ((uint32)(ext_en) << 24) | (((uint32)sysmsk & 0xfe00) << 16) |
1425
- // (((uint32)st_key) << 16) | (((uint32)flags) << 16) | ((uint32)irqcode),
1426
- // (((uint32)ilc) << 30) | (((uint32)cc) << 28) | (((uint32)pmsk) << 24) | PC);
1427
- // }
1428
- // return FALSE;
1429
- // } */
0 commit comments