~ubuntu-branches/ubuntu/raring/simh/raring

« back to all changes in this revision

Viewing changes to PDP18B/pdp18b_cpu.c

  • Committer: Bazaar Package Importer
  • Author(s): Vince Mulhollon
  • Date: 2007-04-13 20:16:15 UTC
  • mfrom: (1.1.7 upstream) (2.1.3 lenny)
  • Revision ID: james.westby@ubuntu.com-20070413201615-jiar46bgkrs0dw2h
Tags: 3.7.0-1
* New upstream released 03-Feb-2007
* i7094 added which emulates the IBM 7090/7094
* Upstream has converted almost entirely to pdf format for docs
* All manpages updated
* All docs are registered with the doc-base system

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
   cpu          PDP-4/7/9/15 central processor
27
27
 
 
28
   26-Dec-06    RMS     Fixed boundary test in KT15/XVM (reported by Andrew Warkentin)
 
29
   30-Oct-06    RMS     Added idle and infinite loop detection
 
30
   08-Oct-06    RMS     Added RDCLK instruction
 
31
                        Fixed bug, PC off by one on fetch mem mmgt error
 
32
                        PDP-15 sets API 3 on mem mmgt trap (like PI)
 
33
                        PDP-15 sets API 4 on CAL only if 0-3 inactive
 
34
                        CAF clears memory management mode register
28
35
   27-Jun-06    RMS     Reset clears AC, L, and MQ
29
36
   22-Sep-05    RMS     Fixed declarations (from Sterling Garwood)
30
37
   16-Aug-05    RMS     Fixed C++ declaration and cast problems
285
292
#define UNIT_RELOC      (1 << UNIT_V_RELOC)
286
293
#define UNIT_XVM        (1 << UNIT_V_XVM)
287
294
#define UNIT_MSIZE      (1 << UNIT_V_MSIZE)
 
295
#define OP_KSF          0700301
288
296
 
289
297
#define HIST_API        0x40000000
290
298
#define HIST_PI         0x20000000
373
381
extern int32 sim_int_char;
374
382
extern int32 sim_interval;
375
383
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
 
384
extern t_bool sim_idle_enab;
376
385
extern DEVICE *sim_devices[];
377
386
extern FILE *sim_log;
378
387
 
383
392
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
384
393
t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc);
385
394
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc);
 
395
void cpu_caf (void);
386
396
void cpu_inst_hist (int32 addr, int32 inst);
387
397
void cpu_intr_hist (int32 flag, int32 lvl);
388
398
int32 upd_iors (void);
398
408
int32 Reloc15 (int32 ma, int32 acc);
399
409
int32 RelocXVM (int32 ma, int32 acc);
400
410
extern t_stat fp15 (int32 ir);
 
411
extern int32 clk_task_upd (t_bool clr);
401
412
#else
402
413
#define INDEX(i,x)
403
414
#endif
530
541
    { UNIT_PROT+UNIT_RELOC+UNIT_XVM, UNIT_PROT+UNIT_RELOC+UNIT_XVM,
531
542
      "XVM", "XVM", NULL },
532
543
#endif
 
544
    { MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE", &sim_set_idle, &sim_show_idle },
 
545
    { MTAB_XTD|MTAB_VDV, 0, NULL, "NOIDLE", &sim_clr_idle, NULL },
533
546
#if defined (PDP4)
534
547
    { UNIT_MSIZE, 4096, NULL, "4K", &cpu_set_size },
535
548
#endif
566
579
{
567
580
int32 api_int, api_usmd, skp;
568
581
int32 iot_data, device, pulse;
 
582
int32 last_IR;
569
583
t_stat reason;
570
584
extern UNIT clk_unit;
571
585
 
574
588
LAC = LAC & LACMASK;
575
589
MQ = MQ & DMASK;
576
590
reason = 0;
 
591
last_IR = -1;
577
592
sim_rtc_init (clk_unit.wait);                           /* init calibration */
578
593
if (cpu_unit.flags & UNIT_NOAPI) api_enb = api_req = api_act = 0;
579
594
api_int = api_eval (&int_pend);                         /* eval API */
642
657
    if (trap_pending) {                                 /* trap pending? */
643
658
        PCQ_ENTRY;                                      /* save old PC */
644
659
        MB = Jms_word (1);                              /* save state */
645
 
        MA = ion? 0: 020;                               /* save in 0/20 */
646
 
        ion = 0;                                        /* interrupts off */
 
660
        if (ion) {                                      /* int on? */
 
661
            ion = 0;                                    /* interrupts off */
 
662
            MA = 0;                                     /* treat like PI */
 
663
#if defined (PDP15)
 
664
            ion_defer = 2;                              /* free instruction */
 
665
            if (!(cpu_unit.flags & UNIT_NOAPI)) {       /* API? */
 
666
                api_act = api_act | API_ML3;            /* set lev 3 active */
 
667
                api_int = api_eval (&int_pend);         /* re-evaluate */
 
668
                }
 
669
#endif
 
670
            }
 
671
        else MA = 020;                                  /* sortof like CAL */
647
672
        emir_pending = rest_pending = trap_pending = 0; /* emir,rest,trap off */
648
673
        usmd = usmd_buf = 0;                            /* user mode off */
649
674
        Write (MA, MB, WR);                             /* physical write */
676
701
        usmd = usmd_buf = 0;                            /* user mode off */
677
702
        emir_pending = rest_pending = 0;                /* emir, restore off */
678
703
        xct_count = 0;
 
704
        Read (MA, &IR, FE);                             /* fetch instruction */
679
705
        goto xct_instr;
680
706
        }
681
707
 
685
711
        if (hst_lnt) cpu_intr_hist (HIST_PI, 0);        /* record */
686
712
        MB = Jms_word (usmd);                           /* save state */
687
713
        ion = 0;                                        /* interrupts off */
 
714
        ion_defer = 2;                                  /* free instruction */
688
715
#if defined (PDP9)                                      /* PDP-9, */
689
716
        memm = 0;                                       /* extend off */
690
717
#else                                                   /* PDP-15 */
691
 
        ion_defer = 2;                                  /* free instruction */
692
718
        if (!(cpu_unit.flags & UNIT_NOAPI)) {           /* API? */
693
719
            api_act = api_act | API_ML3;                /* set lev 3 active */
694
720
            api_int = api_eval (&int_pend);             /* re-evaluate */
713
739
 
714
740
    xct_count = 0;                                      /* track nested XCT's */
715
741
    MA = PC;                                            /* fetch at PC */
 
742
    if (Read (MA, &IR, FE)) continue;                   /* fetch instruction */
716
743
    PC = Incr_addr (PC);                                /* increment PC */
717
744
 
718
 
    xct_instr:                                          /* label for XCT */
719
 
    if (Read (MA, &IR, FE)) continue;                   /* fetch instruction */
 
745
    xct_instr:                                          /* label for API, XCT */
720
746
    if (hst_lnt) cpu_inst_hist (MA, IR);                /* history? */
721
747
    if (ion_defer) ion_defer = ion_defer - 1;           /* count down defer */
722
748
    if (sim_interval) sim_interval = sim_interval - 1;
846
872
#if defined (PDP9)
847
873
        ion_defer = 1;                                  /* defer intr */
848
874
#endif
 
875
        if (Read (MA, &IR, FE)) break;                  /* fetch inst, mm err? */
849
876
        goto xct_instr;                                 /* go execute */
850
877
 
851
878
/* CAL: opcode 00 - api_usmd records whether usmd = 1 at start of API cycle
867
894
#if defined (PDP9) || defined (PDP15)
868
895
        usmd = usmd_buf = 0;                            /* clear user mode */
869
896
        if ((cpu_unit.flags & UNIT_NOAPI) == 0) {       /* if API, act lvl 4 */
870
 
            api_act = api_act | 010;
 
897
#if defined (PDP15)                                     /* PDP15: if 0-3 inactive */
 
898
          if ((api_act & (API_ML0|API_ML1|API_ML2|API_ML3)) == 0)
 
899
#endif
 
900
            api_act = api_act | API_ML4;
871
901
            api_int = api_eval (&int_pend);
872
902
            }
873
903
#endif
899
929
 
900
930
    case 031:                                           /* JMP, indir */
901
931
        if (Ia (MA, &MA, 1)) break;
 
932
        INDEX (IR, MA);
 
933
        PCQ_ENTRY;                                      /* save old PC */
 
934
        PC = MA & AMASK;
 
935
        break;
 
936
 
 
937
/* JMP direct - check for idle */
 
938
 
902
939
    case 030:                                           /* JMP, dir */
903
940
        INDEX (IR, MA);
904
941
        PCQ_ENTRY;                                      /* save old PC */
 
942
        if (sim_idle_enab) {                            /* idling enabled? */
 
943
            t_bool iof = (ion_inh != 0) ||              /* IOF if inhibited */
 
944
                ((ion == 0) && (api_enb == 0));         /* or PI and api off */
 
945
            if (((MA ^ (PC - 2)) & AMASK) == 0) {       /* 1) JMP *-1? */
 
946
                if (iof && (last_IR == OP_KSF) &&       /*    iof, prv KSF, */
 
947
                    !TST_INT (TTI))                     /*    no TTI flag? */
 
948
                    sim_idle (0, FALSE);                /* we're idle */
 
949
                }
 
950
            else if (((MA ^ (PC - 1)) & AMASK) == 0) {  /* 2) JMP *? */
 
951
                if (iof) reason = STOP_LOOP;            /*    iof? inf loop */
 
952
                else sim_idle (0, FALSE);               /*    ion? idle */                
 
953
                }
 
954
            }                                           /* end idle */
905
955
        PC = MA & AMASK;
906
956
        break;
907
957
 
1369
1419
 
1370
1420
        case 017:                                       /* mem protection */
1371
1421
            if (PROT) {                                 /* enabled? */
1372
 
                if ((pulse == 001) && prvn) PC = Incr_addr (PC);
1373
 
                else if ((pulse == 041) && nexm) PC = Incr_addr (PC);
1374
 
                else if (pulse == 002) prvn = 0;
1375
 
                else if (pulse == 042) usmd_buf = 1;
1376
 
                else if (pulse == 004) BR = LAC & BRMASK;
1377
 
                else if (pulse == 044) nexm = 0;
 
1422
                if ((pulse == 001) && prvn)             /* MPSK */
 
1423
                    PC = Incr_addr (PC);
 
1424
                else if ((pulse == 041) && nexm)        /* MPSNE */
 
1425
                    PC = Incr_addr (PC);
 
1426
                else if (pulse == 002) prvn = 0;        /* MPCV */
 
1427
                else if (pulse == 042) usmd_buf = 1;    /* MPEU */
 
1428
                else if (pulse == 004)                  /* MPLD */
 
1429
                    BR = LAC & BRMASK;
 
1430
                else if (pulse == 044) nexm = 0;        /* MPCNE */
1378
1431
                }
1379
1432
            else reason = stop_inst;
1380
1433
            break;
1388
1441
            if ((pulse == 001) || (pulse == 041)) PC = Incr_addr (PC);
1389
1442
            else if (pulse == 002) {                    /* CAF */
1390
1443
                reset_all (1);                          /* reset all exc CPU */
1391
 
                api_enb = api_req = api_act = 0;        /* reset API system */
 
1444
                cpu_caf ();                             /* CAF to CPU */
1392
1445
                }
1393
1446
            else if (pulse == 044) rest_pending = 1;    /* DBR */
1394
1447
            if (((cpu_unit.flags & UNIT_NOAPI) == 0) && (pulse & 004)) {
1444
1497
        case 017:                                       /* mem protection */
1445
1498
            if (PROT) {                                 /* enabled? */
1446
1499
                t = XVM? BRMASK_XVM: BRMASK;
1447
 
                if ((pulse == 001) && prvn) PC = Incr_addr (PC);
1448
 
                else if ((pulse == 041) && nexm) PC = Incr_addr (PC);
1449
 
                else if (pulse == 002) prvn = 0;
1450
 
                else if (pulse == 042) usmd_buf = 1;
1451
 
                else if (pulse == 004) BR = LAC & t;
1452
 
                else if (RELOC && (pulse == 024)) RR = LAC & t;
1453
 
                else if (pulse == 044) nexm = 0;
 
1500
                if ((pulse == 001) && prvn)             /* MPSK */
 
1501
                    PC = Incr_addr (PC);
 
1502
                else if ((pulse == 041) && nexm)        /* MPSNE */
 
1503
                    PC = Incr_addr (PC);
 
1504
                else if (pulse == 002) prvn = 0;        /* MPCV */
 
1505
                else if (pulse == 042)                  /* MPEU */
 
1506
                     usmd_buf = 1;
 
1507
                else if (XVM && (pulse == 062))         /* RDCLK */
 
1508
                    iot_data = clk_task_upd (TRUE);
 
1509
                else if (pulse == 004) BR = LAC & t;    /* MPLD */
 
1510
                else if (RELOC && (pulse == 024))       /* MPLR */
 
1511
                    RR = LAC & t;
 
1512
                else if (pulse == 044) nexm = 0;        /* MPCNE */
1454
1513
                }
1455
1514
            else reason = stop_inst;
1456
1515
            break;
1464
1523
            if ((pulse == 001) || (pulse == 041)) PC = Incr_addr (PC);
1465
1524
            else if (pulse == 002) {                    /* CAF */
1466
1525
                reset_all (2);                          /* reset all exc CPU, FP15 */
1467
 
                api_enb = api_req = api_act = 0;        /* reset API system */
 
1526
                cpu_caf ();                             /* CAF to CPU */
1468
1527
                }
1469
1528
            else if (pulse == 044) rest_pending = 1;    /* DBR */
1470
1529
            if (((cpu_unit.flags & UNIT_NOAPI) == 0) && (pulse & 004)) {
1519
1578
        }                                               /* end switch opcode */
1520
1579
 
1521
1580
    api_usmd = 0;                                       /* API cycle over */
 
1581
    last_IR = IR;                                       /* save IR for next */
1522
1582
    }                                                   /* end while */
1523
1583
 
1524
1584
/* Simulation halted */
1835
1895
int32 pa;
1836
1896
 
1837
1897
ma = ma & AMASK;                                        /* 17b addressing */
1838
 
if (ma >= (BR | 0377)) {                                /* boundary viol? */
 
1898
if (ma > (BR | 0377)) {                                 /* boundary viol? */
1839
1899
    if (rc != REL_C) prvn = trap_pending = 1;           /* set flag, trap */
1840
1900
    return -1;
1841
1901
    }
1871
1931
        else pa = RR + (ma & 0377);                                                     /* no, ISAS reloc */
1872
1932
        }
1873
1933
else {
1874
 
    if (ma >= (BR | 0377)) {                            /* normal reloc, viol? */
 
1934
    if (ma > (BR | 0377)) {                             /* normal reloc, viol? */
1875
1935
        if (rc != REL_C) prvn = trap_pending = 1;       /* set flag, trap */
1876
1936
        return -1;
1877
1937
        }
1911
1971
return SCPE_OK;
1912
1972
}
1913
1973
 
 
1974
/* CAF routine (CPU reset isn't called by CAF) */
 
1975
 
 
1976
void cpu_caf (void)
 
1977
{
 
1978
api_enb = api_req = api_act = 0;                    /* reset API system */
 
1979
nexm = prvn = trap_pending = 0;                     /* reset MM system */
 
1980
usmd = usmd_buf = usmd_defer = 0;
 
1981
MMR = 0;
 
1982
return;
 
1983
}
 
1984
 
1914
1985
/* Memory examine */
1915
1986
 
1916
1987
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)