1 /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
2 
3 #define IN_REG68K_C
4 
5 #include "generator.h"
6 #include "registers.h"
7 
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11 
12 // not recommended for wxWidgets linkage
13 #ifdef USE_SETJMP
14 #include <setjmp.h>
15 #endif
16 
17 #include "reg68k.h"
18 #include "cpu68k.h"
19 #include "ui.h"
20 #include "vars.h"
21 
22 // __CYGWIN__ wrapper added by Ray Arachelian for LisaEm to prevent crashes in reg68k_ext exec
23 #ifdef __CYGWIN__
24  uint32 reg68k_pc;
25  uint32 *reg68k_regs;
26  t_sr reg68k_sr;
27 #else
28 #if (!(defined(PROCESSOR_ARM) || defined(PROCESSOR_SPARC) || defined(PROCESSOR_INTEL) ))
29 uint32 reg68k_pc;
30 uint32 *reg68k_regs;
31 t_sr reg68k_sr;
32 #endif
33 #endif
34 
35 #define LISA_REBOOTED(x)   { ALERT_LOG(0,"rebooting? reg68k_pc:%08x,pc24:%08x %16llx",reg68k_pc,pc24,cpu68k_clocks); return x;}
36 #define LISA_POWEREDOFF(x) { save_pram(); profile_unmount(); lisa_powered_off();  return x;}
37 
38 
39 static int dbx=0;
40 
41 
42 static int insetjmpland=0;
43 
44 
45 static uint32 last_cpu68k_clocks=0;
46 
47 static uint32 last_bus_error_pc=0;
48 
49 static int    nmi_error_trap=0;
50 static uint32 last_nmi_error_pc=0;
51 
52 static uint32 nmi_pc=0, nmi_addr_err=0, nmi_clk=0, nmi_stop=0;
53 
54 
55 uint16 InstructionRegister;
56 uint8  CPU_function_code;     // cpu function code state output bits (FC2/Fc1/FC0).  // fc2= supervisor mode, fc1/0=program/data access
57                               //
58                               // should set to CPU_function_code=(reg68k_sr.sr_struct.s<<2) | 1; for normal access
59                               //               CPU_function_code=(reg68k_sr.sr_struct.s<<2) | 2; for execution/program access.
60                               //
61 
62 #define SET_CPU_FNC_DATA() {CPU_function_code=(reg68k_sr.sr_struct.s? 4:0) | 1;}
63 #define SET_CPU_FNC_CODE() {CPU_function_code=(reg68k_sr.sr_struct.s? 4:0) | 2;}
64 
65 
66 uint8  CPU_READ_MODE;         // 1=read, 0=write (for addr/bus error exceptions)
67 
68 uint32 pc24=0, lastpc24=0, page;
69 static int loopy_vector=0;                  // prevent fetch from calling this again.
70 
71 
72 
73 
74 /*** forward references ***/
75 #ifdef DEBUG
76 void dumpmmu(uint8 c, FILE *out);
77 void validate_mmu_segments(char *from);
78 void printregs(FILE *buglog,char *tag);
79 void extprintregs(FILE *buglog,char *tag);
80 
81 #endif
82 
83 extern char *slrname(uint16 slr);       // from memory.c
84 
85 // Make sure that the bitfield unions work correctly - if they're in the wrong order, they won't.  This double checks
86 // that ./configure got the right order.
87 //
88 
89 
reg68k_sanity_check_bitorder(void)90 void reg68k_sanity_check_bitorder(void)
91 {
92   int bad=0; uint16 x;
93   int64 i64;
94   int32 i32;
95   union
96   {
97     uint32 l;
98     uint8  c[4];
99   } e;
100 
101 
102   union {
103   struct {
104   uint8 h:4;
105   uint8 i0:1;
106   uint8 i1:1;
107   uint8 i2:1;
108   uint8 i3:1;
109   } hi;
110   uint8 i;
111   }bf;
112 
113   x=reg68k_sr.sr_int;
114 
115   reg68k_sr.sr_int=0x2700;
116   #define IMSK (reg68k_sr.sr_struct.i0 | (reg68k_sr.sr_struct.i1<<1) | (reg68k_sr.sr_struct.i2<<2) )
117 
118    if (sizeof(reg68k_sr)!=2) {bad=1;
119                               DEBUG_LOG(0,"expected reg68k_sr to be two bytes! it is %d instead!",sizeof(reg68k_sr));
120                               messagebox("Sanity Check Failed! reg68k_sr is not 2 bytes!", "Compilation Failure!");
121                              }
122 
123   if (sizeof(uint8)  !=1 ) {bad=1; DEBUG_LOG(0,"Size of uint8  is not 1"); messagebox("Sanity check failed sizeof(uint8)!=1","Sanity check failed");}
124   if (sizeof(uint16) !=2 ) {bad=1; DEBUG_LOG(0,"Size of uint16 is not 2"); messagebox("Sanity check failed sizeof(uint16)!=2","Sanity check failed");}
125   if (sizeof(uint32) !=4 ) {bad=1; DEBUG_LOG(0,"Size of uint32 is not 4"); messagebox("Sanity check failed sizeof(uint32)!=4","Sanity check failed");}
126 #ifdef uint64
127   if (sizeof(uint64) !=8 ) {bad=1; DEBUG_LOG(0,"Size of uint64 is not 8"); messagebox("Sanity check failed sizeof(uint64)!=8","Sanity check failed");}
128 #endif
129 
130   if (sizeof(int8)  !=1 ) {bad=1; DEBUG_LOG(0,"Size of int8  is not 1"); messagebox("Sanity check failed sizeof(int8)!=1","Sanity check failed");}
131   if (sizeof(int16) !=2 ) {bad=1; DEBUG_LOG(0,"Size of int16 is not 2"); messagebox("Sanity check failed sizeof(int16)!=2","Sanity check failed");}
132   if (sizeof(int32) !=4 ) {bad=1; DEBUG_LOG(0,"Size of int32 is not 4"); messagebox("Sanity check failed sizeof(int32)!=4","Sanity check failed");}
133 #ifdef int64
134   if (sizeof(int64) !=8 ) {bad=1; DEBUG_LOG(0,"Size of int64 is not 8"); messagebox("Sanity check failed sizeof(int64)!=8","Sanity check failed");}
135 #endif
136 
137   e.l=0xdeadbeef;
138   #ifdef  WORDS_BIGENDIAN
139     if (e.c[0]!=0xde && e.c[1]!=0xad && e.c[2]!=0xbe && e.c[3]!=0xef )
140        {bad=1; DEBUG_LOG(0,"Endian Mismatch - BIGENDIAN defined, but fails test"); messagebox("Sanity check failed: BIGENDIAN defined, but fails test","Sanity check failed");}
141   #else
142     if (e.c[0]!=0xef && e.c[1]!=0xbe && e.c[2]!=0xad && e.c[3]!=0xde )
143        {bad=1; DEBUG_LOG(0,"Endian Mismatch - LITTLE ENDIAN defined, but fails test"); messagebox("Sanity check failed: LITTLE ENDIAN defined, but fails test","Sanity check failed");}
144 
145   #endif
146 
147   i64=-1;
148   i32=-1;
149 
150   i64=(i64>>1);
151   i32=(i32>>1);
152 
153   if (i64!=-1) {bad=1; DEBUG_LOG(0,"64 bit signed right shift of -1 !=-1"); messagebox("Sanity check failed: 64 bit signed right shift of -1 !=-1","Sanity check failed");}
154   if (i32!=-1) {bad=1; DEBUG_LOG(0,"32 bit signed right shift of -1 !=-1"); messagebox("Sanity check failed: 32 bit signed right shift of -1 !=-1","Sanity check failed");}
155 
156   bf.i=0xf3;
157 
158   if (sizeof(bf)!=1) {bad=1; DEBUG_LOG(0,"sizeof(uint8) bitfield!=1!"); messagebox("Sanity check failed: sizeof(uint8) bitfield!=1!","Sanity Check Failure!");}
159 
160   #ifdef BYTES_HIGHFIRST
161   //  bf.i=f3 bf.hi.h=f bf.hi.i0,1,2,3=0 0 1 1
162    if (bf.hi.h  !=15) {bad=1; DEBUG_LOG(0,"bitfield/BYTES_HIGHFIRST hi.h!=f");  messagebox("Sanity check failed: bitfield/BYTES_HIGHFIRST hi.h!=f ","Sanity Check Failure");}
163    if (bf.hi.i0 !=0 ) {bad=1; DEBUG_LOG(0,"bitfield/BYTES_HIGHFIRST hi.i0!=0"); messagebox("Sanity check failed: bitfield/BYTES_HIGHFIRST hi.i0!=0","Sanity Check Failure");}
164    if (bf.hi.i1 !=0 ) {bad=1; DEBUG_LOG(0,"bitfield/BYTES_HIGHFIRST hi.i1!=0"); messagebox("Sanity check failed: bitfield/BYTES_HIGHFIRST hi.i1!=0","Sanity Check Failure");}
165    if (bf.hi.i2 !=1 ) {bad=1; DEBUG_LOG(0,"bitfield/BYTES_HIGHFIRST hi.i2!=1"); messagebox("Sanity check failed: bitfield/BYTES_HIGHFIRST hi.i2!=1","Sanity Check Failure");}
166    if (bf.hi.i3 !=1 ) {bad=1; DEBUG_LOG(0,"bitfield/BYTES_HIGHFIRST hi.i3!=1"); messagebox("Sanity check failed: bitfield/BYTES_HIGHFIRST hi.i3!=1","Sanity Check Failure");}
167 
168 
169   #else
170    // bf.i=f3 bf.hi.h=3 bf.hi.i0,1,2,3=1 1 1 1
171    if (bf.hi.h  !=3 ) {bad=1; DEBUG_LOG(0,"bitfield/!BYTES_HIGHFIRST hi.h!=3");  messagebox("Sanity check failed: bitfield/!BYTES_HIGHFIRST hi.h!=3","Sanity Check Failure");}
172    if (bf.hi.i0 !=1 ) {bad=1; DEBUG_LOG(0,"bitfield/!BYTES_HIGHFIRST hi.i0!=1"); messagebox("Sanity check failed: bitfield/!BYTES_HIGHFIRST hi.i0!=1","Sanity Check Failure");}
173    if (bf.hi.i1 !=1 ) {bad=1; DEBUG_LOG(0,"bitfield/!BYTES_HIGHFIRST hi.i1!=1"); messagebox("Sanity check failed: bitfield/!BYTES_HIGHFIRST hi.i1!=1","Sanity Check Failure");}
174    if (bf.hi.i2 !=1 ) {bad=1; DEBUG_LOG(0,"bitfield/!BYTES_HIGHFIRST hi.i2!=1"); messagebox("Sanity check failed: bitfield/!BYTES_HIGHFIRST hi.i2!=1","Sanity Check Failure");}
175    if (bf.hi.i3 !=1 ) {bad=1; DEBUG_LOG(0,"bitfield/!BYTES_HIGHFIRST hi.i3!=1"); messagebox("Sanity check failed: bitfield/!BYTES_HIGHFIRST hi.i3!=1","Sanity Check Failure");}
176   #endif
177 
178 
179   reg68k_sr.sr_int=0x2700; if (IMSK!=7)  {DEBUG_LOG(0,"BIT ORDER IS WRONG! Expect 7 got %d %c%c%c%c%c%c%c imsk:%d ",IMSK,(reg68k_sr.sr_struct.t ? 't':'.'),(reg68k_sr.sr_struct.s ? 'S':'.'),(reg68k_sr.sr_struct.z ? 'z':'.'),(reg68k_sr.sr_struct.x ? 'x':'.'),(reg68k_sr.sr_struct.n ? 'n':'.'),(reg68k_sr.sr_struct.v ? 'v':'.'),        (reg68k_sr.sr_struct.c ? 'c':'.'),((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 ))); bad=1;}
180   reg68k_sr.sr_int=0x2600; if (IMSK!=6)  {DEBUG_LOG(0,"BIT ORDER IS WRONG! Expect 6 got %d %c%c%c%c%c%c%c imsk:%d ",IMSK,(reg68k_sr.sr_struct.t ? 't':'.'),(reg68k_sr.sr_struct.s ? 'S':'.'),(reg68k_sr.sr_struct.z ? 'z':'.'),(reg68k_sr.sr_struct.x ? 'x':'.'),(reg68k_sr.sr_struct.n ? 'n':'.'),(reg68k_sr.sr_struct.v ? 'v':'.'),        (reg68k_sr.sr_struct.c ? 'c':'.'),((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 ))); bad=1;}
181   reg68k_sr.sr_int=0x2500; if (IMSK!=5)  {DEBUG_LOG(0,"BIT ORDER IS WRONG! Expect 5 got %d %c%c%c%c%c%c%c imsk:%d ",IMSK,(reg68k_sr.sr_struct.t ? 't':'.'),(reg68k_sr.sr_struct.s ? 'S':'.'),(reg68k_sr.sr_struct.z ? 'z':'.'),(reg68k_sr.sr_struct.x ? 'x':'.'),(reg68k_sr.sr_struct.n ? 'n':'.'),(reg68k_sr.sr_struct.v ? 'v':'.'),        (reg68k_sr.sr_struct.c ? 'c':'.'),((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 ))); bad=1;}
182   reg68k_sr.sr_int=0x2400; if (IMSK!=4)  {DEBUG_LOG(0,"BIT ORDER IS WRONG! Expect 4 got %d %c%c%c%c%c%c%c imsk:%d ",IMSK,(reg68k_sr.sr_struct.t ? 't':'.'),(reg68k_sr.sr_struct.s ? 'S':'.'),(reg68k_sr.sr_struct.z ? 'z':'.'),(reg68k_sr.sr_struct.x ? 'x':'.'),(reg68k_sr.sr_struct.n ? 'n':'.'),(reg68k_sr.sr_struct.v ? 'v':'.'),        (reg68k_sr.sr_struct.c ? 'c':'.'),((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 ))); bad=1;}
183   reg68k_sr.sr_int=0x2300; if (IMSK!=3)  {DEBUG_LOG(0,"BIT ORDER IS WRONG! Expect 3 got %d %c%c%c%c%c%c%c imsk:%d ",IMSK,(reg68k_sr.sr_struct.t ? 't':'.'),(reg68k_sr.sr_struct.s ? 'S':'.'),(reg68k_sr.sr_struct.z ? 'z':'.'),(reg68k_sr.sr_struct.x ? 'x':'.'),(reg68k_sr.sr_struct.n ? 'n':'.'),(reg68k_sr.sr_struct.v ? 'v':'.'),        (reg68k_sr.sr_struct.c ? 'c':'.'),((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 ))); bad=1;}
184   reg68k_sr.sr_int=0x2200; if (IMSK!=2)  {DEBUG_LOG(0,"BIT ORDER IS WRONG! Expect 2 got %d %c%c%c%c%c%c%c imsk:%d ",IMSK,(reg68k_sr.sr_struct.t ? 't':'.'),(reg68k_sr.sr_struct.s ? 'S':'.'),(reg68k_sr.sr_struct.z ? 'z':'.'),(reg68k_sr.sr_struct.x ? 'x':'.'),(reg68k_sr.sr_struct.n ? 'n':'.'),(reg68k_sr.sr_struct.v ? 'v':'.'),        (reg68k_sr.sr_struct.c ? 'c':'.'),((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 ))); bad=1;}
185   reg68k_sr.sr_int=0x2100; if (IMSK!=1)  {DEBUG_LOG(0,"BIT ORDER IS WRONG! Expect 1 got %d %c%c%c%c%c%c%c imsk:%d ",IMSK,(reg68k_sr.sr_struct.t ? 't':'.'),(reg68k_sr.sr_struct.s ? 'S':'.'),(reg68k_sr.sr_struct.z ? 'z':'.'),(reg68k_sr.sr_struct.x ? 'x':'.'),(reg68k_sr.sr_struct.n ? 'n':'.'),(reg68k_sr.sr_struct.v ? 'v':'.'),        (reg68k_sr.sr_struct.c ? 'c':'.'),((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 ))); bad=1;}
186   reg68k_sr.sr_int=0x2000; if (IMSK!=0)  {DEBUG_LOG(0,"BIT ORDER IS WRONG! Expect 0 got %d %c%c%c%c%c%c%c imsk:%d ",IMSK,(reg68k_sr.sr_struct.t ? 't':'.'),(reg68k_sr.sr_struct.s ? 'S':'.'),(reg68k_sr.sr_struct.z ? 'z':'.'),(reg68k_sr.sr_struct.x ? 'x':'.'),(reg68k_sr.sr_struct.n ? 'n':'.'),(reg68k_sr.sr_struct.v ? 'v':'.'),        (reg68k_sr.sr_struct.c ? 'c':'.'),((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 ))); bad=1;}
187 
188   reg68k_sr.sr_int=0x2000; if (!reg68k_sr.sr_struct.s)  {DEBUG_LOG(0,"BIT ORDER IS WRONG! Expected Supervisor Bit on  %c%c%c%c%c%c%c imsk:%d ",(reg68k_sr.sr_struct.t ? 't':'.'),(reg68k_sr.sr_struct.s ? 'S':'.'),(reg68k_sr.sr_struct.z ? 'z':'.'),(reg68k_sr.sr_struct.x ? 'x':'.'),(reg68k_sr.sr_struct.n ? 'n':'.'),(reg68k_sr.sr_struct.v ? 'v':'.'),        (reg68k_sr.sr_struct.c ? 'c':'.'),((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 )));  bad=1;}
189   reg68k_sr.sr_int=0x0000; if ( reg68k_sr.sr_struct.s)  {DEBUG_LOG(0,"BIT ORDER IS WRONG! Expected Supervisor Bit off %c%c%c%c%c%c%c imsk:%d ",(reg68k_sr.sr_struct.t ? 't':'.'),(reg68k_sr.sr_struct.s ? 'S':'.'),(reg68k_sr.sr_struct.z ? 'z':'.'),(reg68k_sr.sr_struct.x ? 'x':'.'),(reg68k_sr.sr_struct.n ? 'n':'.'),(reg68k_sr.sr_struct.v ? 'v':'.'),        (reg68k_sr.sr_struct.c ? 'c':'.'),((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 ))); bad=1;}
190   reg68k_sr.sr_int=0x2700; if (!reg68k_sr.sr_struct.s)  {DEBUG_LOG(0,"BIT ORDER IS WRONG! Expected Supervisor Bit on  %c%c%c%c%c%c%c imsk:%d ",(reg68k_sr.sr_struct.t ? 't':'.'),(reg68k_sr.sr_struct.s ? 'S':'.'),(reg68k_sr.sr_struct.z ? 'z':'.'),(reg68k_sr.sr_struct.x ? 'x':'.'),(reg68k_sr.sr_struct.n ? 'n':'.'),(reg68k_sr.sr_struct.v ? 'v':'.'),        (reg68k_sr.sr_struct.c ? 'c':'.'),((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 )));  bad=1;}
191   reg68k_sr.sr_int=0x0700; if ( reg68k_sr.sr_struct.s)  {DEBUG_LOG(0,"BIT ORDER IS WRONG! Expected Supervisor Bit off %c%c%c%c%c%c%c imsk:%d ",(reg68k_sr.sr_struct.t ? 't':'.'),(reg68k_sr.sr_struct.s ? 'S':'.'),(reg68k_sr.sr_struct.z ? 'z':'.'),(reg68k_sr.sr_struct.x ? 'x':'.'),(reg68k_sr.sr_struct.n ? 'n':'.'),(reg68k_sr.sr_struct.v ? 'v':'.'),        (reg68k_sr.sr_struct.c ? 'c':'.'),((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 ))); bad=1;}
192 
193   reg68k_sr.sr_int=x;
194 
195 
196   if (bad) {
197              EXIT(1938,0,"Sanity Check Failed! reg68k_sr int does not match bitfields!", "Compilation Failure!");
198            }
199 }
200 
201 
niceascii(char c)202 char niceascii(char c)
203 { c &=127;
204  if (c<31) c|=32;
205  if (c==127) c='.';
206  return c;
207 }
208 
209 
210 void lisa_addrerror(uint32 addr);
211 
212 char *getvector(int v);
213 static int atexitset=0;
214 
215 // MMU Test Patterns.  1 assumes X flag is preset before. 2 assumes X=0
216 //                       0         1     2     3        4      5     6      7      8     9      10     11     12     13     14     15    16
217 uint16 mmupattern1[17]={0xa55a,0x4ab5,0x956b,0x2ad6,0x55ad,0xab5a,0x56b4,0xad69,0x5ad2,0xb5a5,0x6b4a,0xd695,0xad2a,0x5a55,0xb4ab,0x6956,0xd2ad};
218 uint16 mmupattern2[17]={0xa55a,0x4ab4,0x9569,0x2ad2,0x55a5,0xab4a,0x5694,0xad29,0x5a52,0xb4a5,0x694a,0xd295,0xa52a,0x4a55,0x94ab,0x2956,0x52ad};
219 
220 static uint8 pending_vector_bitmap=0;
221 
222 #ifdef DEBUG
223 extern void append_floppy_log(char *s);
224 #endif
225 
226 // only two are available: empty or dual parallel
get_nmi_pending_irq(void)227 int get_nmi_pending_irq(void) {return 0;}
228 
get_exs2_pending_irq_empty(void)229 int get_exs2_pending_irq_empty(void) {return 0;}
get_exs1_pending_irq_empty(void)230 int get_exs1_pending_irq_empty(void) {return 0;}
get_exs0_pending_irq_empty(void)231 int get_exs0_pending_irq_empty(void) {return 0;}
232 
233 
get_exs0_pending_irq_2xpar(void)234 int get_exs0_pending_irq_2xpar(void) { return (via[3].via[IFR]&via[3].via[IER])||((via[4].via[IFR]&via[4].via[IER]));}
get_exs1_pending_irq_2xpar(void)235 int get_exs1_pending_irq_2xpar(void) { return (via[5].via[IFR]&via[5].via[IER])||((via[6].via[IFR]&via[6].via[IER]));}
get_exs2_pending_irq_2xpar(void)236 int get_exs2_pending_irq_2xpar(void) { return (via[7].via[IFR]&via[7].via[IER])||((via[8].via[IFR]&via[8].via[IER]));}
237 
238 
239 
240 // These is here in this file because they are shared IRQs, it belongs more in the via6522.c file but there is a
241 // videoirq and floppy component too, so it should be in a shared place.  Might as well be static inline for speed.
242 
get_irq1_pending_irq(void)243 int get_irq1_pending_irq(void )
244 {
245             // this is just a fixup for the COPS VIA, doesn't affect the rest of this.
246             if (via[1].via[IER] & via[1].via[IFR] & 0x7f) via[1].via[IFR] |=0x80; else  via[1].via[IFR] &=0x7f;
247 
248             // IRQ1 is the only shared IRQ - Vertical Retrace, Floppy FDIR, and VIA2 (Parallel Port) all use it.
249             // fix via IFR bit 0x80's so bit 7 is properly reflecting enabled IRQ's.  Correct these bits before checking.
250             if (via[2].via[IER] & via[2].via[IFR] & 0x7f) via[2].via[IFR] |=0x80; else  via[2].via[IFR] &=0x7f;
251 
252             DEBUG_LOG(0,"IRQ1: vertical:%d fdir:%d VIA2-IFR bits:%s%s%s%s%s%s%s%s returning:%d",
253                (verticallatch && (videoirq & 1)), floppy_FDIR ,
254                (via[2].via[IFR] &  VIA_IRQ_BIT_CA2         ? "0:CA2 ": " "   ),
255                (via[2].via[IFR] &  VIA_IRQ_BIT_CA1         ? "1:CA1 ": " "   ),
256                (via[2].via[IFR] &  VIA_IRQ_BIT_SR          ? "2:SR  ": " "   ),
257                (via[2].via[IFR] &  VIA_IRQ_BIT_CB2         ? "3:CB2 ": " "   ),
258                (via[2].via[IFR] &  VIA_IRQ_BIT_CB1         ? "4:CB1 ": " "   ),
259                (via[2].via[IFR] &  VIA_IRQ_BIT_T2          ? "5:T2  ": " "   ),
260                (via[2].via[IFR] &  VIA_IRQ_BIT_T1          ? "6:T1  ": " "   ),
261                (via[2].via[IFR] &  VIA_IRQ_BIT_SET_CLR_ANY ? "7:ANY ": "None"),
262 
263                ((verticallatch && (videoirq & 1)) || floppy_FDIR || (via[2].via[IFR] & 0x80)));
264 
265 
266 
267             return ((verticallatch && (videoirq & 1)) || floppy_FDIR || (via[2].via[IFR] & 0x80)); //was vertical, not verticallatch
268 }
269 
270 
271 #ifdef PARANOID
272 #define HIGHEST(x) (highest=((x)>highest ? (x):highest))
273 #else
274 #define HIGHEST(x) (highest=(x))
275 #endif
276 // re/calculates the pending_vector_bitmap and returns the highest IRQ to be serviced.
277 
278 // this is mirrored from cops.c
get_cops_pending_irq(void)279 static inline int get_cops_pending_irq(void )
280 {
281      // bit 7 of IFR indicates whether any VIA1 IRQ's have been fired, so check to see if any of them have, then set bit 7
282      if (via[1].via[IER] & via[1].via[IFR] & 0x7f)
283      {
284        via[1].via[IFR] |=0x80;
285        return 0x80;
286      }
287 
288      via[1].via[IFR] &=0x7f;
289      return 0;
290 }
291 
292 
293 
294 
295 
get_pending_vector(void)296 static inline uint8 get_pending_vector(void)
297 {
298   int highest=0;
299 
300 
301   //---- recalculated pending vector bitmap, and find the highest IRQ to be serviced  ------------
302 
303 
304   #ifdef DEBUG
305   pending_vector_bitmap=                                         // no such thing as IRQ0 on 68000
306    (get_irq1_pending_irq() ? BIT1:0) |                           // VTIR/FDIR/VIA2   IRQ1
307    (get_cops_pending_irq() ? BIT2:0) |                           // COPS/VIA1        IRQ2
308    (get_exs2_pending_irq() ? BIT3:0) |                           // Expansion slot 2 IRQ3
309    (get_exs1_pending_irq() ? BIT4:0) |                           // Expansion slot 1 IRQ4
310    (get_exs0_pending_irq() ? BIT5:0) |                           // Expansion slot 0 IRQ5
311    (get_scc_pending_irq()  ? BIT6:0) |                           // SCC              IRQ6
312    (get_nmi_pending_irq()  ? BIT7:0) ;                           // NMI              IRQ7
313 
314     highest=highest_bit_num(pending_vector_bitmap);
315     if (highest==0xff) highest=0;
316 
317    DEBUG_LOG(0,"IRQ1:: vertical retrace:%d floppy_FDIR:%d via2_IFR:%02x  IRQ2:via1_IFR:%02x",
318            (vertical && (videoirq & 1)),
319            floppy_FDIR,
320            via[2].via[IFR],
321            via[1].via[IFR]);
322 
323    if (highest==1 && floppy_FDIR && (!((regs.sr.sr_int>>8)&7))) append_floppy_log("get_pending_vector:Floppy FDIR IRQ1 is about to be taken if called\n");
324 
325    DEBUG_LOG(0,"Next pending vector is:%d, map is:%s%s%s%s%s%s%s",highest,
326         ((pending_vector_bitmap & BIT1)  ? "v1":"."),
327         ((pending_vector_bitmap & BIT2)  ? "v2":"."),
328         ((pending_vector_bitmap & BIT3)  ? "v3":"."),
329         ((pending_vector_bitmap & BIT4)  ? "v4":"."),
330         ((pending_vector_bitmap & BIT5)  ? "v5":"."),
331         ((pending_vector_bitmap & BIT6)  ? "v6":"."),
332         ((pending_vector_bitmap & BIT7)  ? "v7":".") );
333 
334 
335   #else
336 
337   if       (get_nmi_pending_irq()  ) {highest=7;pending_vector_bitmap=BIT7;}
338   else if  (get_scc_pending_irq()  ) {highest=6;pending_vector_bitmap=BIT6;}
339   else if  (get_exs0_pending_irq() ) {highest=5;pending_vector_bitmap=BIT5;}
340   else if  (get_exs1_pending_irq() ) {highest=4;pending_vector_bitmap=BIT4;}
341   else if  (get_exs2_pending_irq() ) {highest=3;pending_vector_bitmap=BIT3;}
342   else if  (get_cops_pending_irq() ) {highest=2;pending_vector_bitmap=BIT2;}
343   else if  (get_irq1_pending_irq() ) {highest=1;pending_vector_bitmap=BIT1;}
344 
345   #endif
346 
347 
348 
349   return highest;
350 }
351 
352 
353 #ifdef DEBUG
354 static char templine[1024];
355 #endif
356 
357 #define IS_VECTOR_AVAILABLE_INT(avno) (  ((reg68k_sr.sr_int >> 8) & 7)<(avno)  || (avno)==7)
358 #define IS_VECTOR_AVAILABLE_EXT(avno) (  ((regs.sr.sr_int   >> 8) & 7)<(avno)  || (avno)==7)
359 
is_vector_available(int avno)360 int is_vector_available(int avno)
361 {
362    if (insetjmpland) return (IS_VECTOR_AVAILABLE_INT(avno));
363    return IS_VECTOR_AVAILABLE_EXT(avno);
364 }
365 
366 
367 
368 
fire_pending_external_autovector(void)369 static inline void fire_pending_external_autovector(void)
370 {
371  uint8 i=get_pending_vector();
372  DEBUG_LOG(0,"Firing pending IRQ:%d if it meets the mask",i);
373 
374 
375  if (IS_VECTOR_AVAILABLE_EXT(i))
376     {
377     #ifdef DEBUG
378     snprintf(templine,1024,"fire_pending_ext_av:Firing IRQ1 while floppy_FDIR is set. mask:%d",((regs.sr.sr_int>>8) & 7) );
379     if (i==1 && floppy_FDIR) append_floppy_log(templine);
380     #endif
381 
382     reg68k_external_autovector(i);
383 
384     }
385 }
386 
fire_pending_internal_autovector(void)387 static inline void fire_pending_internal_autovector(void)
388 {
389  uint8 i=get_pending_vector();
390  DEBUG_LOG(0,"Firing pending IRQ:%d if it meets the mask",i);
391  if (IS_VECTOR_AVAILABLE_INT(i))
392      {
393        #ifdef DEBUG
394        snprintf(templine,1024,"fire_pending_int_av:Firing IRQ1 while floppy_FDIR is set. mask:%d",((reg68k_sr.sr_int>>8) & 7) );
395        if (i==1 && floppy_FDIR) append_floppy_log("fire_pending_int_av:Firing IRQ1 while floppy_FDIR is set");
396        #endif
397        reg68k_internal_autovector(i);
398      }
399  #ifdef DEBUG
400  else
401     {
402      DEBUG_LOG(0,"Could not fire IRQ:%d because it did not meet the mask.",i);
403     }
404  #endif
405 
406 }
407 
408 #ifdef DEBUG
409 
410 
check_mmu_pattern(uint32 x)411 void check_mmu_pattern(uint32 x)
412 {
413  int i,found=0;
414 
415  for (i=0; i<17; i++)
416    {
417     if (x==mmupattern1[i])
418             {found=1; fprintf(buglog,"MMUPATTERN: %4x found at %2d in 1 con:%d @pc=%08x a0=%08x reg#:%d\n",mmupattern1[i],i,1+(segment1|segment2),pc24,reg68k_regs[8],reg68k_regs[8]>>17); break;}
419     if (x==mmupattern2[i]) {found=2; fprintf(buglog,"MMUPATTERN: %4x found at %2d in 2 con:%d @pc=%08x a0=%08x reg#:%d\n",mmupattern2[i],i,1+(segment1|segment2),pc24,reg68k_regs[8],reg68k_regs[8]>>17); break;}
420    }
421    if ( !found) fprintf(buglog,"MMUPATTERN: %4x not found        con:%d @pc=%08x a0=%08x reg#:%d\n",x,1+(segment1|segment2),pc24,reg68k_regs[8],reg68k_regs[8]>>17);
422 }
423 
dumpmmupage(uint8 c,uint8 i,FILE * out)424 void dumpmmupage(uint8 c, uint8 i, FILE *out)
425 {
426     char s[1024];
427 
428     int16 pagestart, pageend;
429     lisa_mem_t rfn, wfn;
430     uint32 mymaxlisaram=maxlisaram;
431 
432     if (maxlisaram==1024*1024) mymaxlisaram+=0x80000;
433 
434     get_slr_page_range(c,i,&pagestart,&pageend,&rfn,&wfn);
435     fprintf(out,"mmu[%d][%d].slr:%04x in->(%08x-%08x)  base:%08x->sor:%04x %s ch:%d pgrange:%d-%d arange: out-> %08x-%08x  r/wfn:%d:%d\n",
436         c,i,
437              mmu_all[c][i].slr,
438              i<<17,
439              (i<<17) | 0x1FFFF,
440 
441         mmu_all[c][i].sor<<9,mmu_all[c][i].sor,
442         printslr(s,1024,mmu_all[c][i].slr),
443         mmu_all[c][i].changed,pagestart,pageend,
444 
445         ((((mmu_all[c][i].sor & 0xfff)+pagestart)<<9)),
446         (((((mmu_all[c][i].sor & 0xfff)+pageend)<<9)+511)),rfn,wfn    );
447 
448     if ((unsigned)(((mmu_all[c][i].sor & 0xfff)+pagestart)<<9)>mymaxlisaram)
449             {fprintf(out,"**** START RANGE OVER MAXLISARAM (%08x)!!!!!! chopped to 2mb it's:%08x, unchopped:%08x****\n\n",mymaxlisaram,
450             (((((mmu_all[c][i].sor & 0xfff)+pagestart)<<9)) & TWOMEGMLIM),
451             (((mmu_all[c][i].sor & 0xfff)+pagestart)<<9)    );}
452 
453     if ((unsigned)((((mmu_all[c][i].sor & 0xfff)+pageend)<<9)+511)>mymaxlisaram)
454             {fprintf(out,"**** END RANGE OVER MAXLISARAM (%08x)!!!!!! chopped to 2mb it's:%08x, unchopped:%08x****\n\n",mymaxlisaram,
455             (((((mmu_all[c][i].sor & 0xfff)+pageend)<<9)+511) & TWOMEGMLIM),
456             (((((mmu_all[c][i].sor & 0xfff)+pageend)<<9)+511))  );}
457 
458 
459 }
460 
dumpmmu(uint8 c,FILE * out)461 void dumpmmu(uint8 c, FILE *out)
462 {
463     //char s[1024];
464     int i,f;
465 
466     //int16 pagestart, pageend;
467     //lisa_mem_t rfn, wfn;
468 
469     fprintf(out,"\nmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm dump_mmu mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm\n\n");
470 
471 	for (i=0; i<128; i++)
472 	{
473         dumpmmupage(c,i,out);
474         // keep,might want to re-enable this later
475         /*
476         get_slr_page_range(c,i,&pagestart,&pageend,&rfn,&wfn);
477         fprintf(out,"mmu[%d][%d].slr:%04x in->(%08x-%08x)  base:%08x->sor:%04x %s ch:%d pgrange:%d-%d arange: out-> %08x-%08x  r/wfn:%d:%d\n",
478             c,i,
479                  mmu_all[c][i].slr,
480                  i<<17,
481                  (i<<17) | 0x1FFFF,
482 
483             mmu_all[c][i].sor<<9,mmu_all[c][i].sor,
484             printslr(s,1024,mmu_all[c][i].slr),
485             mmu_all[c][i].changed,pagestart,pageend,
486 
487             ((((mmu_all[c][i].sor & 0xfff)+pagestart)<<9)),
488             (((((mmu_all[c][i].sor & 0xfff)+pageend)<<9)+511)),rfn,wfn    );
489 
490         // is this +i before  + pagestart i.e i+pagestart) and i+pageend) needed/allowed here?
491         if ((unsigned)(((mmu_all[c][i].sor & 0xfff)+pagestart)<<9)>maxlisaram)
492                 {fprintf(out,"**** START RANGE OVER MAXLISARAM (%08x)!!!!!! chopped to 2mb it's:%08x, unchopped:%08x****\n\n",maxlisaram,
493                 (((((mmu_all[c][i].sor & 0xfff)+pagestart)<<9)) & TWOMEGMLIM),
494                 (((mmu_all[c][i].sor & 0xfff)+pagestart)<<9)    );}
495 
496         if ((unsigned)((((mmu_all[c][i].sor & 0xfff)+pageend)<<9)+511)>maxlisaram)
497                 {fprintf(out,"**** END RANGE OVER MAXLISARAM (%08x)!!!!!! chopped to 2mb it's:%08x, unchopped:%08x****\n\n",maxlisaram,
498                 (((((mmu_all[c][i].sor & 0xfff)+pageend)<<9)+511) & TWOMEGMLIM),
499                 (((((mmu_all[c][i].sor & 0xfff)+pageend)<<9)+511))  );}
500         */
501 	}
502 
503     fflush(out);
504     fprintf(out,"\n\n");
505     for ( i=0; i<32768; i++)
506     {
507        fprintf(out,"%08x-%08x mmu[%d] mmu_t[%d][%04x].addr=%08x rfn=%s wfn=%s ipct:%s out:%08x-%08x",
508             (i*512),(i*512)+511,(i*512)>>17,
509             c,i,
510             mmu_trans_all[c][i].address,
511             mspace(mmu_trans_all[c][i].readfn),
512             mspace(mmu_trans_all[c][i].writefn),
513             (mmu_trans_all[c][i].table ? "yes":"no"),
514             ((i*512)+mmu_trans_all[c][i].address),((i*512)+511+mmu_trans_all[c][i].address)
515             );
516 
517             // 1000000000000000
518             // 5432109876543210
519             if (mmu_trans_all[c][i].readfn==sio_mmu)
520             {
521                 f=rmmuslr2fn(mmu_all[c][i>>8].slr,i);
522                 fprintf(out,"mmu_sio: (%d) %s",f,mspace(f));
523             }
524        fprintf(out,"\n");
525     }
526     fflush(out);
527 }
528 
529 
dumpallmmu(void)530 void dumpallmmu(void)
531 {
532     //long i;
533     FILE *out;
534     static char filename[128];
535     static int instance;
536 
537     debug_log_enabled=1;
538     #ifdef DEBUG
539     debug_on("mmu-dump");
540     #endif
541 
542     instance++;
543     snprintf(filename,128,"/log/lisaem-output-mmu-%08x-%d.txt",pc24,instance);
544     DEBUG_LOG(0,filename);
545     out=fopen(filename,"wt");
546 
547     //fprintf(out,"SRC::init_7E70SLR is set to: r/w %04x/%04x\n",mmu_trans_all[0][0x7e70].readfn,mmu_trans_all[0][0x7e70].writefn);
548 
549     //dump_scc();
550     #ifdef DEBUG
551     if (insetjmpland) printregs(out,"");
552     #endif
553     dumpmmu(0,out); dumpmmu(1,out); dumpmmu(2,out); dumpmmu(3,out); dumpmmu(4,out);
554 
555     //if (insetjmpland) printregs(buglog,"");
556 
557     fclose(out);
558 }
559 
560 
561 #endif
562 
563 
564 
reg68k_external_step(void)565 unsigned int reg68k_external_step(void)
566 {
567 	static t_ipc ipc;
568 	static t_iib *piib;
569     static unsigned long clks;
570 
571   /* !!! entering global register usage area !!! */
572     #ifdef USE_SETJMP
573 	jmp_buf jb;
574 
575 
576     if (!setjmp(jb))
577     #endif
578     {
579     /* move PC and register block into global processor register variables */
580 		reg68k_pc = regs.pc;
581 		reg68k_regs = regs.regs;
582         reg68k_sr.sr_int = regs.sr.sr_int;
583 
584         regs.pending = get_pending_vector();
585 		if (regs.pending && ((reg68k_sr.sr_int >> 8) & 7) < regs.pending)
586 			reg68k_internal_autovector(regs.pending);
587 
588 		if (!(piib = cpu68k_iibtable[fetchword(reg68k_pc)]))
589             DEBUG_LOG(1,"Invalid instruction @ %08X\n", reg68k_pc); // RA
590 
591        #if DEBUG
592        if (!piib) DEBUG_LOG(0,"about to pass NULL IIB");
593        #endif
594 
595         cpu68k_ipc(reg68k_pc, piib,&ipc);
596         if (!abort_opcode)
597            cpu68k_functable[fetchword(reg68k_pc) * 2 + 1] (&ipc);
598     /* restore global registers back to permanent storage */
599         regs.pc = reg68k_pc; regs.sr = reg68k_sr;
600         #ifdef USE_SETJMP
601 		longjmp(jb, 1);
602         #endif
603 	}
604     cpu68k_clocks += ipc.clks;
605     DEBUG_LOG(0,"cpu68k_clocks:%016llx this opcode:%d",cpu68k_clocks,ipc.clks);
606     return clks;                  /* number of clocks done */
607 }
608 
getreg(uint8 regnum)609 uint32 getreg(uint8 regnum)  //16=pc, 17=sp 0=7Dregs 8-15Aregs
610 {
611     if (!insetjmpland)
612             {
613                 if (regnum==16) return regs.pc;
614                 if (regnum==17) return regs.sp;
615                 if (regnum<16 ) return regs.regs[regnum];
616 
617             }
618 
619     else   {
620                 if (regnum==16) return reg68k_pc;
621                 if (regnum==17) return regs.sp;
622                 if (regnum<16 ) return reg68k_regs[regnum];
623            }
624     return 0xdeadbeef;
625 
626 }
627 
628 
629 #ifdef DEBUG
printregs(FILE * buglog,char * tag)630 void printregs(FILE *buglog,char *tag)
631 {
632 
633 
634     if (!debug_log_enabled) return;
635     if (!insetjmpland) {extprintregs(buglog,tag); return;}
636 
637     fprintf(buglog,"%sD 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x %c%c%c%c%c%c%c imsk:%d pnd:%s%s%s%s%s%s%s (%d/%d/%s cx:%d)SRC:\n",tag,
638 		reg68k_regs[0], reg68k_regs[1], reg68k_regs[2], reg68k_regs[3], reg68k_regs[4],
639 		reg68k_regs[5], reg68k_regs[6], reg68k_regs[7],
640 		(reg68k_sr.sr_struct.t ? 't':'.'),
641         (reg68k_sr.sr_struct.s ? 'S':'.'),
642         (reg68k_sr.sr_struct.z ? 'z':'.'),
643         (reg68k_sr.sr_struct.x ? 'x':'.'),
644 		(reg68k_sr.sr_struct.n ? 'n':'.'),
645 		(reg68k_sr.sr_struct.v ? 'v':'.'),
646         (reg68k_sr.sr_struct.c ? 'c':'.'),
647         ((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 )),
648 
649         (pending_vector_bitmap & 1) ? "1":"",
650         (pending_vector_bitmap & 2) ? "2":"",
651         (pending_vector_bitmap & 4) ? "3":"",
652         (pending_vector_bitmap & 8) ? "4":"",
653         (pending_vector_bitmap & 16) ? "5":"",
654         (pending_vector_bitmap & 32) ? "6":"",
655         (pending_vector_bitmap & 64) ? "7":"",
656 
657         segment1,segment2,start ? "START":"normal",context );
658 
659     fprintf(buglog,"%sA 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x SP:%08x PC:%08x SRC:\n\n",tag,
660 		reg68k_regs[8], reg68k_regs[9], reg68k_regs[10],reg68k_regs[11],reg68k_regs[12],
661         reg68k_regs[13],reg68k_regs[14],reg68k_regs[15],regs.sp,reg68k_pc);
662     fflush(buglog);
663 }
664 
665 /*
666 		reg68k_pc = regs.pc;
667 		reg68k_regs = regs.regs;
668 		reg68k_sr = regs.sr;
669  */
extprintregs(FILE * buglog,char * tag)670 void extprintregs(FILE *buglog,char *tag)
671 {
672 
673 
674     if (!debug_log_enabled) return;
675     if (insetjmpland) {printregs(buglog,tag); return;}
676 
677 
678                     // the SRC: at the end is so I can grep the output and see both registers and source code. :)
679     fprintf(buglog,"%sD 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x %c%c%c%c%c%c%c irqmsk:%d  %d/%d/%d context:%d SRC:\n",tag,
680         regs.regs[0], regs.regs[1], regs.regs[2], regs.regs[3], regs.regs[4],
681         regs.regs[5], regs.regs[6], regs.regs[7],
682         (regs.sr.sr_struct.t ? 't':'.'),
683         (regs.sr.sr_struct.s ? 'S':'.'),
684         (regs.sr.sr_struct.z ? 'z':'.'),
685         (regs.sr.sr_struct.x ? 'x':'.'),
686         (regs.sr.sr_struct.n ? 'n':'.'),
687         (regs.sr.sr_struct.v ? 'v':'.'),
688         (regs.sr.sr_struct.c ? 'c':'.'),
689         ((regs.sr.sr_struct.i2 ? 4:0 )+(regs.sr.sr_struct.i1 ? 2:0 )+(regs.sr.sr_struct.i0 ? 1:0 )),
690         segment1,segment2,start,context );
691 
692     fprintf(buglog,"%sA 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x SP:%08x PC:%08x SRC:\n\n",tag,
693         regs.regs[8], regs.regs[9], regs.regs[10],regs.regs[11],regs.regs[12],
694         regs.regs[13],regs.regs[14],regs.regs[15],regs.sp,regs.pc);
695     fflush(buglog);
696 }
697 #endif
698 
699 
dumpram(char * reason)700 void dumpram(char *reason)
701 {
702  FILE *ramdump;
703  char filename[256];
704  uint32 i,j; //,k;
705  uint16 slr, sor; //, mfn;
706  //uint32 a9 =((pc24) & 0x00ffffff)>>9;
707  //uint32 a17=((pc24) & 0x00ffffff)>>17;
708  uint32 mad; //filter; mtd;
709  //lisa_mem_t fn;
710 
711  snprintf(filename,256,"/log/lisaem-output-ramdump-%s-%08x.%016llx",reason,pc24,cpu68k_clocks);
712  ramdump=fopen(filename,"wt");
713 
714  fprintf(ramdump,"context:%d segment1:%d, segment2:%d, start:%d pc24:%08x\n\n",context,segment1,segment2,start,pc24);
715 
716 
717  fprintf(ramdump,"ramsize:%08x, lastcx:%d, cx:%d seg1:%d, seg2:%d, start:%d, mmudirty:%08x,%08x,%08x,%08x,%08x\n",
718         maxlisaram,
719         lastcontext, context,
720         segment1, segment2, start,
721         mmudirty_all[0],mmudirty_all[1],mmudirty_all[2],mmudirty_all[3],mmudirty_all[4]);
722 
723  fprintf(ramdump,"diag1:%d, diag2:%d, soft:%d, hard:%d, vert:%d, vidlatch:%02x, lastvidlatch:%02x, vidlatchaddr:%08x, lastvidlatchadr:%08x",
724         diag1, diag2,
725         softmem,
726         hardmem,
727         vertical,
728         videolatch, lastvideolatch,  videolatchaddress, lastvideolatchaddress);
729 
730         //videoramdirty,
731         //videoximgdirty,
732 
733  fprintf(ramdump,"regs D 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x SR:%02x %c%c%c%c%c%c%c irqmsk:%d  %d/%d/%d context:%d\n",
734 		reg68k_regs[0], reg68k_regs[1], reg68k_regs[2], reg68k_regs[3], reg68k_regs[4],
735         reg68k_regs[5], reg68k_regs[6], reg68k_regs[7], reg68k_sr.sr_int,
736 		(reg68k_sr.sr_struct.t ? 't':'.'),
737         (reg68k_sr.sr_struct.s ? 'S':'.'),
738         (reg68k_sr.sr_struct.z ? 'z':'.'),
739         (reg68k_sr.sr_struct.x ? 'x':'.'),
740 		(reg68k_sr.sr_struct.n ? 'n':'.'),
741 		(reg68k_sr.sr_struct.v ? 'v':'.'),
742         (reg68k_sr.sr_struct.c ? 'c':'.'),
743         ((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 )),
744         segment1,segment2,start,context );
745 
746  fprintf(ramdump,"regs A 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x SP:%08x PC:%08x\n\n\n",
747 		reg68k_regs[8], reg68k_regs[9], reg68k_regs[10],reg68k_regs[11],reg68k_regs[12],
748         reg68k_regs[13],reg68k_regs[14],reg68k_regs[15],regs.sp,reg68k_pc);
749 
750 
751  for (i=0; i<5; i++)
752   for ( j=0; j<128; j++)
753   {
754     slr=mmu_all[i][j].slr;
755     sor=mmu_all[i][j].sor;
756 
757     mad=((sor & 0x0fff)<<9) & TWOMEGMLIM;
758 
759   fprintf(ramdump,"mmu[%d][%3d].slr:%04x,sor:%04x  %08x-%08x::-->(%08x)  type::%s\n",
760         i,j,slr,sor,((uint32)j<<17),((uint32)j<<17)+((1<<17)-1),mad,
761         slrname(slr)
762         );
763  }
764  fflush(ramdump);
765 
766 
767 
768  for ( i=0; i<maxlisaram; i+=16)
769   {
770    if (lisaram[i+0]|lisaram[i+1]|lisaram[i+2]| lisaram[i+3]| lisaram[i+4]| lisaram[i+5]| lisaram[i+6]| lisaram[i+7]|
771         lisaram[i+8]|lisaram[i+9]|lisaram[i+10]|lisaram[i+11]|lisaram[i+12]|lisaram[i+13]|lisaram[i+14]|lisaram[i+15])
772    fprintf(ramdump,"RAM %06x: %02x %02x %02x %02x %02x %02x %02x %02x:%02x %02x %02x %02x %02x %02x %02x %02x |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
773         i,
774         lisaram[i+0],lisaram[i+1],lisaram[i+2], lisaram[i+3], lisaram[i+4], lisaram[i+5], lisaram[i+6], lisaram[i+7],
775         lisaram[i+8],lisaram[i+9],lisaram[i+10],lisaram[i+11],lisaram[i+12],lisaram[i+13],lisaram[i+14],lisaram[i+15],
776         ((lisaram[i+0 ]>' ' && lisaram[i+0 ]<127) ? lisaram[i+0 ]:'.'),
777         ((lisaram[i+1 ]>' ' && lisaram[i+1 ]<127) ? lisaram[i+1 ]:'.'),
778         ((lisaram[i+2 ]>' ' && lisaram[i+2 ]<127) ? lisaram[i+2 ]:'.'),
779         ((lisaram[i+3 ]>' ' && lisaram[i+3 ]<127) ? lisaram[i+3 ]:'.'),
780         ((lisaram[i+4 ]>' ' && lisaram[i+4 ]<127) ? lisaram[i+4 ]:'.'),
781         ((lisaram[i+5 ]>' ' && lisaram[i+5 ]<127) ? lisaram[i+5 ]:'.'),
782         ((lisaram[i+6 ]>' ' && lisaram[i+6 ]<127) ? lisaram[i+6 ]:'.'),
783         ((lisaram[i+7 ]>' ' && lisaram[i+7 ]<127) ? lisaram[i+7 ]:'.'),
784         ((lisaram[i+8 ]>' ' && lisaram[i+8 ]<127) ? lisaram[i+8 ]:'.'),
785         ((lisaram[i+9 ]>' ' && lisaram[i+9 ]<127) ? lisaram[i+9 ]:'.'),
786         ((lisaram[i+10]>' ' && lisaram[i+10]<127) ? lisaram[i+10]:'.'),
787         ((lisaram[i+11]>' ' && lisaram[i+11]<127) ? lisaram[i+11]:'.'),
788         ((lisaram[i+12]>' ' && lisaram[i+12]<127) ? lisaram[i+12]:'.'),
789         ((lisaram[i+13]>' ' && lisaram[i+13]<127) ? lisaram[i+13]:'.'),
790         ((lisaram[i+14]>' ' && lisaram[i+14]<127) ? lisaram[i+14]:'.'),
791         ((lisaram[i+15]>' ' && lisaram[i+15]<127) ? lisaram[i+15]:'.')  );
792   }
793 
794 
795  fflush(ramdump);
796  fclose(ramdump);
797 }
798 
799 
800 
801 extern void xxxcheckcontext(uint8 c, char *text);
802 
xdumpram(void)803 void xdumpram(void) {dumpram("atexit");}
804 
805 
806 #ifdef DEBUG
807 
808 extern char *gettimername(uint8 t);
809 #ifdef LOOKAHEAD
810         static int been_here_before=0;
811 #endif
812 
813    #ifdef PROCNAME_DEBUG
is_valid_procname(uint8 c)814    int is_valid_procname(uint8 c)
815    {
816     c &=0x7f;
817     if (c>='A' && c<='Z') return 1;
818     if (c=='_' || c==' ') return 1;
819     if (c>='0' && c<='9') return 1;
820     return 0;
821    }
822 
is_valid_procname_w(uint16 w)823    int is_valid_procname_w(uint16 w)
824    {
825      return (is_valid_procname(w>>8) && is_valid_procname(w & 0x7f) );
826    }
827    #endif
828 #endif
829 
830 
get_address_mmu_rfn_type(uint32 addr)831 int get_address_mmu_rfn_type(uint32 addr)
832 {
833  addr=addr & 0x00ffffff;
834  return mmu_trans[(addr>>9) & 32767].readfn;
835 }
836 
837 extern long get_wx_millis(void);
838 
839 
reg68k_external_execute(int32 clocks)840 int32 reg68k_external_execute(int32 clocks)
841 {
842  XTIMER entry=cpu68k_clocks;
843  XTIMER entry_stop=cpu68k_clocks+clocks;
844  XTIMER clks_stop=cpu68k_clocks+clocks;
845 
846  // remove these.
847  XTIMER entrystop=cpu68k_clocks_stop;
848  // remove these.
849 
850 
851 
852 #ifdef DEBUG
853 
854         static char text[1024];
855 
856         #ifdef SUPPRESS_LOOP_DISASM
857                 int32 suppress_printregs=0;
858                 int32 last_regs_idx=0;
859                 t_regs last_regs[MAX_LOOP_REGS];               // last opcode register values
860         #endif
861 
862 #endif
863 
864 
865 
866 #define MAX_INSTR_PER_CALL 1000
867 
868     static t_ipc *ipc;
869     static mmu_trans_t *mt;
870     static uint32 last_pc;
871 
872 #ifdef USE_SETJMP
873     jmp_buf jb;
874 #endif
875 
876 //#ifdef DEBUG
877 //    if ( !atexitset)
878 //    {
879 //    atexit(dump_scc);
880 //    atexit(dumpallmmu);
881 //    atexit(xdumpram);
882 //    atexit(dumpvia);
883 //    atexitset=1;
884 //    }
885 
886 //   if (insetjmpland)
887 //       {fprintf(buglog,"*** DANGER Entering %s:%s:%d from %s setjmpland*****\n",__FILE__,__FUNCTION__,__LINE__,(insetjmpland ? "inside" : "outside")); fflush(buglog); EXIT(1);}
888 //
889 //#endif
890 
891   #ifdef USE_SETJMP
892   if (!setjmp(jb))
893   #endif
894     {
895 
896     /* move PC and register block into global variables */
897         reg68k_pc   = regs.pc;//20060129// & 0x00ffffff;
898 		reg68k_regs = regs.regs;
899         reg68k_sr.sr_int   = regs.sr.sr_int;
900         insetjmpland=1;
901 //		ALERT_LOG(0,"entry reg68k_pc:%08x,pc24:%08x mmutrans:%08x clock:%16llx",reg68k_pc,pc24,cpu68k_clocks,CHK_MMU_TRANS(pc24));
902 
903         last_bus_error_pc=0;
904 
905 
906         // this sets cpu68k_clocks_stop
907 
908 
909         if ( (reg68k_pc) & 1  || (regs.pc &1)  )  LISA_REBOOTED(0);
910 
911 
912         get_next_timer_event();
913 
914 
915 
916         #ifdef DISASM_SKIPPED_OPCODES
917         if (debug_log_enabled && pc24>lastpc24 && lastpc24>0)
918          if ( (pc24-lastpc24)<128)
919          {
920           uint32 cursor=lastpc24;
921           char text[1024];
922           static t_ipc myipc;
923           static t_iib *mypiib;
924 
925           DEBUG_LOG(0,"disassembling skipped opcodes between %08x-%08x",cursor,pc24);
926 
927           pc24 = reg68k_pc & 0x00ffffff;
928 
929 
930           while (cursor<pc24)
931             {
932               abort_opcode=2;
933               if (!(mypiib = cpu68k_iibtable[fetchword(cursor)]))
934                    {DEBUG_LOG(1,"Invalid instruction @ %08X\n", cursor); cursor=pc24;
935                     break;
936                    }
937                if (abort_opcode==1) cursor=pc24;
938                abort_opcode=2;
939                #ifdef DEBUG
940                  if (!mypiib) DEBUG_LOG(0,"About to send null IPC!");
941                #endif
942                cpu68k_ipc(cursor, mypiib,&myipc); if (abort_opcode==1) cursor=pc24;
943 
944                abort_opcode=2;  diss68k_gettext(&myipc, text); if (abort_opcode==1) cursor=pc24;
945 
946                fprintf(buglog,"\nx:%08x (skipped) opcode=%04x %s             +%d clks   SRC:\n",cursor,myipc.opcode,text,myipc.clks);
947 
948                cursor +=myipc.wordlen*2;        if (!myipc.wordlen) {EXIT(14,0,"*** Doh! ipc.wordlen=0 **");}
949             }
950            if (abort_opcode==1) DEBUG_LOG(0,"**DANGER*** GOT abort_opcode!******\n");
951            debug_log_enabled=1;
952          }
953         #endif
954         ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
955 
956         lastpc24=pc24;
957         clks_stop=MIN(clks_stop,cpu68k_clocks_stop);
958 
959         DEBUG_LOG(0,"\n\ncpu68k_clocks is:%016llx before entering do-while loop\nwill expire at %016llx",cpu68k_clocks,
960                 clks_stop);
961 
962         do {
963             abort_opcode=0;
964             SET_CPU_FNC_CODE();
965 
966 
967             pc24 = reg68k_pc & 0x00ffffff;
968             if (reg68k_pc & 1)  LISA_REBOOTED(0);
969 
970 
971 	/* C ROM */ if (lisarom[0x3ffc]==0x02 && lisarom[0x3ffd]==0x11 && pc24==0xfe0270) ALERT_LOG(0,"C ROM 0x275:%02x",lisarom[0x0275]);
972 
973 
974 
975 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
976 // disassemble skipped code (within reason)
977 // 1/0000d42e (lisacx 0 0/0/0) opcode=303c MOVE.W
978 // 2005.04.15 hack to get at the LisaTest Video test routines.
979 
980 // Screenshot
981 //if (pc24==0xd5ec) ascii_screendump();
982 
983 
984 #ifdef LOOKAHEAD
985     if (pc24==LOOKSTARTADDR && been_here_before==0)
986       {
987         uint32 cursor=pc24;
988         char text[1024];
989         static t_ipc myipc;
990         static t_iib *mypiib;
991 
992         been_here_before=1;
993         debug_off();
994         debug_on("lookahead"); debug_log_enabled=1;
995 
996         DEBUG_LOG(0,"lookahead disassembling skipped opcodes between %08x-%08x",cursor,pc24);
997 
998         pc24 = reg68k_pc & 0x00ffffff;
999 
1000 
1001         while (cursor<LOOKENDADDR)
1002           {
1003             abort_opcode=2;
1004             if (!(mypiib = cpu68k_iibtable[fetchword(cursor)]))
1005                  {DEBUG_LOG(1,"Invalid instruction @ %08X\n", cursor); cursor=pc24;
1006                   break;
1007                  }
1008              if (abort_opcode==1) cursor=LOOKENDADDR;
1009              abort_opcode=2;
1010              #ifdef DEBUG
1011                if (!mypiib) DEBUG_LOG(0,"About to send null IPC!");
1012                #endif
1013              cpu68k_ipc(cursor, mypiib,&myipc); if (abort_opcode==1) cursor=LOOKENDADDR;
1014 
1015              abort_opcode=2;  diss68k_gettext(&myipc, text); if (abort_opcode==1) cursor=LOOKENDADDR;
1016 
1017              if (mypiib->clocks!=myipc.clks) DEBUG_LOG(0,"ERROR:iib clocks:%d != ipc clocks:%d !", mypiib->clocks , myipc.clks);
1018              fprintf(buglog,"\nL:%08x  opcode=%04x   %-70s  +%d clks",cursor,myipc.opcode,text,myipc.clks);
1019 
1020              cursor +=myipc.wordlen*2;        if (!myipc.wordlen) {EXIT(14,0,"*** Doh! ipc.wordlen=0 **");}
1021           }
1022          if (abort_opcode==1) DEBUG_LOG(0,"**DANGER*** GOT abort_opcode!******\n");
1023          debug_log_enabled=0; debug_off();
1024        }
1025 #endif
1026 
1027 
1028 
1029 
1030           ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1031 
1032 
1033             mt=&mmu_trans[(pc24>>9) & 32767];
1034             if (mt->readfn==bad_page)
1035                 {
1036                  DEBUG_LOG(0,"\n\nCurrent opcode lives inside a bad_page, throwing lisa_mmu_exception @ %d/%08x. Previous IR=%04x",
1037                       context,pc24,InstructionRegister);
1038                  DEBUG_LOG(0,"mmu_trans[%04x] segment #%d\n\n",(pc24>>9) & 32767,(pc24>>17));
1039                  //fflush(buglog);dumpmmupage(context, (pc24>>17), buglog); fflush(buglog);
1040                  lisa_mmu_exception(pc24);
1041                  break;           // this break here causes the "fucked timing" danger warning - it can be ignored
1042                 }
1043 
1044 
1045 
1046             lastsflag=reg68k_sr.sr_struct.s;
1047 
1048             #ifdef DEBUG
1049 
1050                #ifdef SUPPRESS_LOOP_DISASM
1051 
1052                   if (!suppress_printregs)
1053                   {
1054                      if (debug_log_enabled)  {printregs(buglog,"");}
1055                   }
1056                   else
1057                   {
1058                    int32 i;  int32 j=(suppress_printregs & 32767); int flag=0;
1059                    char line[1024], buf[1024];
1060 
1061                    snprintf(line,1024,"loop:: %08x: ",pc24);
1062 
1063                 // might want to change j to be the previous instruction - but doesn't matter very much I suppose
1064                    for (i=0; i<8;  i++)  if (last_regs[j].regs[i]!=reg68k_regs[i]) {snprintf(buf,1024,"D%d:%08x ",i,reg68k_regs[i]); strncat(line,buf,1024);flag=1;}
1065                    for (i=8; i<16; i++)  if (last_regs[j].regs[i]!=reg68k_regs[i]) {snprintf(buf,1024,"A%d:%08x ",i-8,reg68k_regs[i]); strncat(line,buf,1024);flag=1;}
1066                    if (last_regs[j].sr.sr_int!=reg68k_sr.sr_int)
1067                    {flag=1;
1068                         snprintf(buf,1024,"%c%c%c%c%c%c%c imsk:%d ",
1069                         (reg68k_sr.sr_struct.t ? 't':'.'),
1070                         (reg68k_sr.sr_struct.s ? 'S':'.'),
1071                         (reg68k_sr.sr_struct.z ? 'z':'.'),
1072                         (reg68k_sr.sr_struct.x ? 'x':'.'),
1073                         (reg68k_sr.sr_struct.n ? 'n':'.'),
1074                         (reg68k_sr.sr_struct.v ? 'v':'.'),
1075                         (reg68k_sr.sr_struct.c ? 'c':'.'),
1076                         ((reg68k_sr.sr_struct.i2 ? 4:0 )+(reg68k_sr.sr_struct.i1 ? 2:0 )+(reg68k_sr.sr_struct.i0 ? 1:0 )) );
1077                         strncat(line,buf,1024);
1078                    }
1079                    if (flag) fprintf(buglog,"%s\n",line);
1080                   }
1081                #else
1082                 if (debug_log_enabled)  {printregs(buglog,"");} // printlisatime(buglog);}
1083                #endif
1084             #endif
1085 
1086 			// get the page and the mmu_translation table entry for this pc24
1087             page=pc24>>9;     mt=&mmu_trans[page];
1088 
1089 
1090 
1091             // Is this page table allocated?  If not allocate it as needed.
1092 			if (mt!=NULL && mt->table!=NULL)
1093 			{
1094                ipc=&(mt->table->ipc[(pc24 & 0x1ff)>>1]);
1095 
1096                // we have an IPC, now check it to see that it matches what's in there
1097                // this is a sanity check against moved pages, but not against self
1098                // modifying code which only changes operands - that would be too slow
1099                // to check.
1100 
1101      #ifdef DEBUG
1102         dbx=debug_log_enabled; //20070723//debug_log_enabled=0;
1103      #endif
1104 
1105                abort_opcode=2;
1106                #ifndef EVALUATE_EACH_IPC
1107                if (ipc->opcode != (fetchword(pc24)))
1108                #endif
1109                 {
1110                     if (abort_opcode==1) break;
1111 
1112 
1113                     if (!mt->table) mt->table=get_ipct();  //we can skip fre_ipct
1114 
1115                     cpu68k_makeipclist(pc24); if (abort_opcode==1) break;
1116                     ipc=&(mt->table->ipc[(pc24 & 0x1ff)>>1]);
1117 				}
1118                 abort_opcode=0;
1119 
1120 
1121      #ifdef DEBUG
1122         {
1123             #ifdef ICACHE_DEBUG
1124             if (dbx && pc24>16)
1125             {
1126               int i;  uint8 c,nice[1024], hex[1024], tmp[1024];
1127 
1128               nice[0]=0; hex[0]=0;
1129 
1130               for (i=0; i<32; i++)
1131                   {
1132                      abort_opcode=2;
1133                      c=lisa_ram_safe_getbyte(context,(pc24-16+i));
1134                      if (i & 1) snprintf(tmp,1024,"%02x ",c);
1135                      else       snprintf(tmp,1024,"%02x",c);
1136 
1137                      strncat(hex,tmp,1024);
1138                      nice[i]=niceascii(c);
1139                   }
1140 
1141               debug_log_enabled|=dbx;     // re-enable debug log only after icache fetches to prevent verbosity
1142 
1143               fprintf(buglog,"%08x:%s|%s clk:%016llx\n",pc24-16,hex,nice,cpu68k_clocks);
1144               //DEBUG_LOG(0,"icache:%04x:%04x:%04x:%04x:%04x  clk:%08x",ipc->opcode,icache2,icache4, icache6, icache8,cpu68k_clocks);
1145               abort_opcode=0;
1146             }
1147             else debug_log_enabled=dbx;
1148             #else
1149                  debug_log_enabled|=dbx;
1150             #endif
1151         }
1152      #endif
1153 
1154             } // end of if (mt!=NULL && mt->table!=NULL)
1155             else // need to make this IPC table
1156             {
1157                 //if ( !mt)  { fprintf(buglog,"Doh! mt is null! bye!"); EXIT(4);  }
1158                 abort_opcode=2; mt->table=get_ipct();  if (abort_opcode==1) break;
1159                 abort_opcode=0;
1160 
1161                 abort_opcode=2;
1162                 cpu68k_makeipclist(pc24);
1163                 if (abort_opcode==1) break;
1164 
1165                 #ifdef DEBUG
1166                        if ( !mt->table)  {DEBUG_LOG(-1,"reg68k_extern_exec: got a null mt->table from makeipclist!");}
1167                 #endif
1168 
1169                 ipc=&(mt->table->ipc[(pc24 & 0x1ff)>>1]);
1170            }
1171 
1172 			// If the page isn't RAM or ROM, then we can't execute it.
1173 			// I can get rid of this check to speed things up... but...
1174 
1175 #ifdef DEBUG
1176             if (mt->readfn!=ram && mt->readfn!=sio_rom && mt->readfn!=sio_mmu)
1177 			{
1178                 EXIT(397,0,"Woot! Trying to execute from non-ram/rom! Living dangerously!"
1179                            "Bye Bye! PC24= %08x  ipc# %d mt->readfn=%d %s\n",pc24,(pc24 & 0x1ff)>>1,mt->readfn,mspace(mt->readfn));
1180 			}
1181 			else
1182 #endif
1183 			{
1184 
1185 
1186 // keep this can use for debugger later
1187 #ifdef xxxHALT_AT
1188 if ( (pc24==0xfe06f2 || pc24==0xfe14F2 || pc24==0xfe144a pc==0xfe) && mt->readfn==sio_rom)
1189     {
1190     EXIT(398,0,"compiled in halt.");
1191     }
1192 #endif
1193 
1194 
1195 
1196 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1197 #ifdef DEBUG
1198 
1199 
1200 
1201                 if (debug_log_enabled)
1202                 {
1203                      if (mt->readfn==sio_mmu && rom_source_file && dtc_rom_fseeks && ((pc24 & 0xffff)<0x3fff))
1204                      {   char buff[1024];
1205                          fseek(rom_source_file,dtc_rom_fseeks[pc24 & 0x3fff],SEEK_SET);
1206                          fgets(buff,1024,rom_source_file); if (strlen(buff)>5) fprintf(buglog,"%08x: SRC: %s\n",pc24,buff);
1207                      }
1208 
1209                     #ifdef SUPPRESS_LOOP_DISASM
1210                     {
1211                      int i,j,k=0;
1212 
1213                      suppress_printregs=0;
1214 
1215                      j=last_regs_idx;
1216                      do   {j--; if (j<0) j=MAX_LOOP_REGS-1;
1217                            if (pc24==last_regs[j].pc) k=1;
1218                      }     while (j!=last_regs_idx && !k);
1219 
1220                      // copy to current register
1221                      j=last_regs_idx+1;  if (j>=MAX_LOOP_REGS) j=0;
1222 
1223                      last_regs[j].pc=pc24;
1224                      last_regs[j].sp=regs.sp;
1225                      last_regs[j].sr.sr_int=reg68k_sr.sr_int;
1226                      for (i=0; i<16; i++)  last_regs[j].regs[i]=reg68k_regs[i];
1227                      last_regs_idx=j;
1228 
1229 
1230                      if ((ipc->opcode & 0xf000)==0xa000)
1231                       {
1232                         char temp[256];
1233                         snprintf(temp,256,"::%08x ",fetchlong(pc24+2));
1234                         strncat(text,temp,256);
1235                       }
1236                      #endif
1237 
1238             #ifdef PROCNAME_DEBUG
1239             {  uint16 w,w1,w2,w3;
1240 
1241                w=lisa_ram_safe_getword(context,(pc24-2));
1242                //DEBUG_LOG(0,"entering procedure: got 5th word:%04x",w);
1243                if (w<0x00f0)
1244                {
1245                        w3=lisa_ram_safe_getword(context,(pc24-10));
1246                  //      DEBUG_LOG(0,"entering procedure got word in 0th spot:%04x is valid & 0x8000:%d is valid:%d",w3,(w3 & 0x8000),
1247                  //           is_valid_procname_w(w3 & 0x7f7f));
1248                  if ( (w3 & 0x8000) && is_valid_procname_w(w3 & 0x7f7f) )
1249                     {
1250                        w2=lisa_ram_safe_getword(context,(pc24-8));
1251                        w1=lisa_ram_safe_getword(context,(pc24-6));
1252                        w =lisa_ram_safe_getword(context,(pc24-4));
1253 
1254                    //    DEBUG_LOG(0,"entering procedure Got words:%04x %04x %04x %04x",w3,w2,w1,w);
1255 
1256                        if (is_valid_procname_w(w) && is_valid_procname_w(w1) && is_valid_procname_w(w2) )
1257                                fprintf(buglog,"\n\n****** Entering Procedure: %c%c%c%c%c%c%c%c *********\n\n",
1258                                        ((w3>>8) & 0x7f),(w3 & 0x7f),
1259                                        ((w2>>8) & 0x7f),(w2 & 0x7f),
1260                                        ((w1>>8) & 0x7f),(w1 & 0x7f),
1261                                        ((w >>8) & 0x7f),(w  & 0x7f)     );
1262 
1263                     }
1264                }
1265             }
1266             #endif       // end of PROCNAME_DEBUG
1267 
1268 
1269                      if (!k)
1270                       {if (ipc->opcode!=0xe350)
1271                        abort_opcode=2;  diss68k_gettext(ipc, text);
1272                        fprintf(buglog,"%d/%08x (lisacx %d %d/%d/%d) opcode=%04x %s    SRC:clk:%016llx +%ld clks\n",context,pc24,
1273                        (segment1|segment2),segment1,segment2,start,ipc->opcode,text,cpu68k_clocks, ipc->clks);
1274                       }
1275                       else suppress_printregs=32768|j;
1276                     }
1277            }
1278            last_cpu68k_clocks=cpu68k_clocks;
1279 #endif
1280 
1281 // Cheat to skip over big wait loop in NMI code
1282 #ifdef SKIP_BIGWAIT_NMI_CODE
1283 if (lisa_os_boot_mouse_x_ptr==0xfec)
1284 {/////////////////////////////////////////////////////////////////////////////////////////
1285 
1286 if ( ipc->opcode==0x5381)
1287 {
1288  // hack to speed up lisatest?
1289  if (pc24==0xd36e && reg68k_regs[1]==0x3d090) reg68k_regs[1]=1;
1290  if (pc24==0xdd52 && reg68k_regs[1]>1 ) {reg68k_regs[1]=1;}
1291 }
1292 else                                    // 2005.04.05 06:22am - Turn Debugging on LisaTest CPU ErrorLevel
1293     if (pc24==0x0000d2c8 && ipc->opcode==0xb3cb && reg68k_regs[6]==0x00000018 && reg68k_regs[8]<0x001ff000)
1294     {
1295       debug_on("LisaTest-cpu-errorlogic"); debug_log_enabled=1; debug_log_enabled=1; last_dbe=1;
1296       reg68k_regs[8]=0x001fff00; reg68k_regs[9]=0x001fff00;
1297       memerror=0xFFF8;
1298       DEBUG_LOG(0,"LisaTest CPU Error Logic - enabling debug 2005.04.05");
1299     }
1300 
1301 
1302 }///////////////////////////////////////////////////////////////////////////////////////////
1303 #endif
1304 
1305 
1306 
1307 
1308 
1309 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1310 
1311                 if (abort_opcode==1) {EXITR(476,0,"MMU/BUS/Address exception occured on opcode fetch!\n");}
1312                 abort_opcode=0;          // clear any addr/bus errors/traps/etc that may have occured.
1313 
1314                 InstructionRegister=ipc->opcode;
1315 
1316 
1317 
1318 #ifdef CPU_CORE_TESTER
1319 {
1320  char texttext[1024];
1321 
1322  abort_opcode=2;  diss68k_gettext(ipc, text);
1323  snprintf(texttext,1024,"opcode:%s (%04x) @%d/%08x icache:%02x%02x %02x%02x  %02x%02x %02x%02x  %02x%02x %02x%02x  %02x%02x %02x%02x\n",
1324              text,ipc->opcode,context,reg68k_pc,
1325   		     lisa_ram_safe_getbyte(context,pc24+0),
1326   		     lisa_ram_safe_getbyte(context,pc24+1),
1327   		     lisa_ram_safe_getbyte(context,pc24+2),
1328   		     lisa_ram_safe_getbyte(context,pc24+3),
1329 
1330   		     lisa_ram_safe_getbyte(context,pc24+4),
1331   		     lisa_ram_safe_getbyte(context,pc24+5),
1332   		     lisa_ram_safe_getbyte(context,pc24+6),
1333   		     lisa_ram_safe_getbyte(context,pc24+7),
1334 
1335   		     lisa_ram_safe_getbyte(context,pc24+8),
1336   		     lisa_ram_safe_getbyte(context,pc24+9),
1337   		     lisa_ram_safe_getbyte(context,pc24+10),
1338   		     lisa_ram_safe_getbyte(context,pc24+11),
1339 
1340   		     lisa_ram_safe_getbyte(context,pc24+12),
1341   		     lisa_ram_safe_getbyte(context,pc24+13),
1342   		     lisa_ram_safe_getbyte(context,pc24+14),
1343   		     lisa_ram_safe_getbyte(context,pc24+15) );
1344 
1345 			 corecpu_start_opcode(texttext, context);
1346 
1347 }
1348 #endif
1349 
1350 //			   ALERT_LOG(0,"pc:%08x opcode:%04x mmu trans:%08x opcode mem:%02x%02x",reg68k_pc,ipc->opcode,
1351 //			             CHK_MMU_TRANS(reg68k_pc),lisaram[CHK_MMU_TRANS(reg68k_pc)],lisaram[CHK_MMU_TRANS(reg68k_pc+1)]);
1352 
1353 //	           {
1354 //			   char text[1024];
1355 //   		       diss68k_gettext(ipc, text);
1356 //
1357 //			    ALERT_LOG(0,"%08x %s",reg68k_pc,text);
1358 // 		       }
1359      #ifdef DEBUG
1360         dbx=debug_log_enabled; //20070723//debug_log_enabled=0;
1361      #endif
1362 
1363 
1364                 if (ipc->function)                               // if the IPC is valid, and loaded
1365                      {SET_CPU_FNC_DATA(); ipc->function(ipc);}   // execute the function, else rebuild the IPC
1366                 else {
1367                         static t_iib *piib;
1368 
1369                         if (!(piib = cpu68k_iibtable[fetchword(reg68k_pc)]))
1370                             ALERT_LOG(1,"Invalid instruction @ %08X\n", reg68k_pc); // RA
1371 
1372 
1373                         SET_CPU_FNC_CODE();
1374                         #ifdef DEBUG
1375                           if (!ipc)  DEBUG_LOG(0,"About to send null IPC!");
1376                           if (!piib) DEBUG_LOG(0,"About to send null IPC!");
1377                         #endif
1378 
1379                         cpu68k_ipc(reg68k_pc,piib,ipc);
1380 
1381                         if (piib->clocks!=ipc->clks)
1382                             DEBUG_LOG(0,"ERROR:iib clocks:%d != ipc clocks:%d !", piib->clocks , ipc->clks);
1383 
1384                         DEBUG_LOG(0,"Got an IPC without a function at %08x, opcode is:%04x doing it manually - like it's just 0000 OR ",reg68k_pc,ipc->opcode);
1385 
1386                         if (abort_opcode==1) break;
1387 
1388 
1389                         ipc->function=cpu68k_functable[fetchword(reg68k_pc) * 2 + 1];
1390 
1391 
1392                         //cpu68k_functable[fetchword(reg68k_pc) * 2 + 1] (&ipc); (&ipc);
1393 
1394                         SET_CPU_FNC_DATA();
1395                         if (abort_opcode==1) {DEBUG_LOG(0,"MMU/BUS/Address exception occured on opcode fetch!\n"); fflush(buglog); break;}
1396                         else {
1397                                 InstructionRegister=ipc->opcode;
1398                                 abort_opcode=0;
1399                                 if (ipc->function) ipc->function(ipc);
1400                                 else {   EXITR(277,0,"No ipc function at %d/%08x, even after attempting to get one!\n",context,pc24);}
1401                              }
1402                     }  // if we have it, execute, else loop is done. :)
1403 
1404      #ifdef DEBUG
1405         debug_log_enabled|=dbx;
1406      #endif
1407 
1408 
1409 #ifdef CPU_CORE_TESTER
1410 	   corecpu_complete_opcode(context);
1411 #endif
1412 
1413 
1414 
1415 
1416 #ifdef XXXDEBUG
1417 
1418 
1419 /*
1420                if ((pc24 & 0x00ff0000)!=0x00fe0000 && (reg68k_pc & 0x00ff0000)==0x00fe0000)
1421 				  ALERT_LOG(0,"Entering ROM from operating system at %08x from %08x %s\n"
1422 	                          "D 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x\n"
1423 	                          "A 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x\n",
1424 	                           reg68k_pc,pc24,get_rom_label(reg68k_pc),
1425 							   reg68k_regs[0], reg68k_regs[1], reg68k_regs[2], reg68k_regs[3], reg68k_regs[4], reg68k_regs[5], reg68k_regs[6], reg68k_regs[7],
1426 							   reg68k_regs[8], reg68k_regs[9], reg68k_regs[10],reg68k_regs[11],reg68k_regs[12],reg68k_regs[13],reg68k_regs[14],reg68k_regs[15]
1427 	                      );
1428 */
1429 				if (reg68k_pc==0x00fe0090 || pc24==0x00fe0090)
1430 				{
1431    				  ALERT_LOG(0,"ENT Entering ROM profile read.  ROMLESS")
1432 				  int i;
1433 				  uint8 b;
1434 
1435 				  b=fetchbyte(0x1b3);
1436 
1437 				  ALERT_LOG(0,"ENT Booting up reg68k_pc:%08x from pc24:%08x %s. reg68k_sr.sr_int=%04x regs.sp=%08x 1b3:%02x   ROMLESS\n"
1438 				              "ENT D 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x ROMLESS\n"
1439 				              "ENT A 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x ROMLESS\n",
1440 				               reg68k_pc,pc24,get_rom_label(reg68k_pc),reg68k_sr.sr_int,regs.sp,b,
1441 				    		   reg68k_regs[0], reg68k_regs[1], reg68k_regs[2], reg68k_regs[3], reg68k_regs[4], reg68k_regs[5], reg68k_regs[6], reg68k_regs[7],
1442 				    		   reg68k_regs[8], reg68k_regs[9], reg68k_regs[10],reg68k_regs[11],reg68k_regs[12],reg68k_regs[13],reg68k_regs[14],reg68k_regs[15]
1443 				          );
1444 
1445 				}
1446 
1447 
1448 //				  if (reg68k_pc==0x00fe1fee)
1449 //				  {
1450 //
1451 //				    ALERT_LOG(0,"RET Return from ROM profile read.  ROMLESS")
1452 //					int i;
1453 //					uint8 b;
1454 //
1455 //					b=fetchbyte(0x1b3);
1456  //
1457 //					ALERT_LOG(0,"RET Booting up reg68k_pc:%08x from pc24:%08x %s. reg68k_sr.sr_int=%04x regs.sp=%08x 1b3:%02x ROMLESS\n"
1458 //					            "RET D 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x ROMLESS\n"
1459 //					            "RET A 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x ROMLESS\n",
1460 //					             reg68k_pc,pc24,get_rom_label(reg68k_pc),reg68k_sr.sr_int,regs.sp,b,
1461 //					  		   reg68k_regs[0], reg68k_regs[1], reg68k_regs[2], reg68k_regs[3], reg68k_regs[4], reg68k_regs[5], reg68k_regs[6], reg68k_regs[7],
1462 //					  		   reg68k_regs[8], reg68k_regs[9], reg68k_regs[10],reg68k_regs[11],reg68k_regs[12],reg68k_regs[13],reg68k_regs[14],reg68k_regs[15]
1463 //					        );
1464  //
1465 //				  }
1466 
1467 				  if (reg68k_pc==0x00020000)
1468                   {
1469 	                  int i;
1470 					  uint8 b;
1471 
1472 					  b=fetchbyte(0x1b3);
1473 
1474 					  ALERT_LOG(0,"INT Booting up reg68k_pc:%08x from pc24:%08x %s. reg68k_sr.sr_int=%04x regs.sp=%08x 1b3:%02x  ROMLESS\n"
1475 		                          "INT D 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x  ROMLESS\n"
1476 		                          "INT A 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x 6:%08x 7:%08x  ROMLESS\n",
1477 		                           reg68k_pc,pc24,get_rom_label(reg68k_pc),reg68k_sr.sr_int,regs.sp,b,
1478 								   reg68k_regs[0], reg68k_regs[1], reg68k_regs[2], reg68k_regs[3], reg68k_regs[4], reg68k_regs[5], reg68k_regs[6], reg68k_regs[7],
1479 								   reg68k_regs[8], reg68k_regs[9], reg68k_regs[10],reg68k_regs[11],reg68k_regs[12],reg68k_regs[13],reg68k_regs[14],reg68k_regs[15]
1480 		                      );
1481 
1482 
1483                    }
1484 #endif
1485 
1486 
1487                 pc24 = reg68k_pc; //20060321// & 0x00ffffff;
1488 
1489                 abort_opcode=0;
1490 
1491                 #ifdef DEBUG
1492                 if (ipc->clks >160) {DEBUG_LOG(0,"***INSANELY FUCKED UP IPC STRUCT TIMING! ***BUG**** ipc->clks==%d",ipc->clks);cpu68k_printipc(ipc);}
1493                 #endif
1494                 //else DEBUG_LOG(0,"ipc->clks this cycle:%ld",ipc->clks);
1495 
1496                 cpu68k_clocks+=ipc->clks;
1497         } // if execute from ram/rom else statement
1498 
1499 #ifdef DEBUG
1500     if (0==reg68k_pc)
1501        {
1502         DEBUG_LOG(0,"pc=0 LastPC24=%08x pc24=%08x abort_opcode:%d",lastpc24,pc24,abort_opcode);
1503        }
1504 #endif
1505     clks_stop=MIN(clks_stop,cpu68k_clocks_stop);
1506 
1507    } while (clks_stop>cpu68k_clocks && !regs.stop);
1508 
1509 
1510 #ifdef DEBUG
1511     DEBUG_LOG(0,"pc=%08x cpu68k_clocks is:%016llx stop is :%016llx diff:%016llx  regs.stop is %d event:%d %s after exiting do-while loop",
1512             reg68k_pc, cpu68k_clocks,cpu68k_clocks_stop,
1513             cpu68k_clocks_stop-cpu68k_clocks, regs.stop,
1514             next_timer_id(),gettimername(next_timer_id() ) );
1515 
1516     printregs(buglog,"");
1517 #endif
1518 
1519    last_pc=reg68k_pc;
1520    regs.pc = reg68k_pc;  regs.sr.sr_int = reg68k_sr.sr_int;
1521 
1522 
1523    // handle NMI - NMI unlike Bus Error occurs AFTER the current opcode completes. ////////////////////////////////////////////
1524    if (nmi_clk && nmi_pc)
1525    {  // regs.stop=nmi_stop;                                    // NMI can only occur on memory access resulting in soft parity error, not while cpu is stopped
1526          regs.stop=0;
1527          reg68k_internal_vector(0x1f, reg68k_pc,nmi_addr_err);  // 7 is wrong for vector, right for autovector.
1528          nmi_addr_err=0;  nmi_clk=0; nmi_pc=0; nmi_stop=0;      // clear flags
1529          regs.stop=0;
1530    }
1531    else  // NMI did not occur, instead, see if there's a pending IRQ, or we're very close to one.
1532    {
1533                               // check for the next pending IRQ's.
1534           if (cpu68k_clocks+10>=cpu68k_clocks_stop)
1535           {
1536             //long x=get_wx_millis();
1537             fire_pending_internal_autovector();
1538             //long y=get_wx_millis();
1539             check_current_timer_irq();
1540             //long z=get_wx_millis();
1541 
1542             //ALERT_LOG(0,"irq timings: fire_pending_int_auto:%ldms, check_current_timer_irq:%ldms, total:%ldms",y-x,z-y,z-x);
1543           }
1544    }
1545 
1546    if (regs.stop)  cpu68k_clocks=cpu68k_clocks_stop;
1547 
1548    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1549   insetjmpland=0;
1550   #ifdef USE_SETJMP
1551   longjmp(jb, 1);
1552   #endif
1553  }
1554 
1555  return entry_stop-cpu68k_clocks;           // how many cycles left over if positive, negative if did too many.
1556 }
1557 
1558 
1559 
1560 
reg68k_external_autovector(int avno)1561 void reg68k_external_autovector(int avno)
1562 {
1563 #ifdef USE_SETJMP
1564       jmp_buf jb;
1565 #endif
1566 
1567 
1568       if (insetjmpland)
1569        {DEBUG_LOG(0,"*** DANGER Entering %s:%s:%d from %s setjmpland***** vector:%d\n",__FILE__,__FUNCTION__,__LINE__,(insetjmpland ? "inside" : "outside"),avno); fflush(buglog);
1570         reg68k_internal_autovector(avno);
1571         return;
1572        }
1573     #ifdef USE_SETJMP
1574     if (!setjmp(jb))
1575     #endif
1576       {
1577     /* move PC and register block into global processor register variables */
1578 		reg68k_pc = regs.pc;
1579 		reg68k_regs = regs.regs;
1580         reg68k_sr.sr_int = regs.sr.sr_int;
1581         DEBUG_LOG(0,"Inside setjmp land, about to call internal_autovector:%d reg68k_pc:%08x reg68k_sr:%08x",avno,reg68k_pc,reg68k_sr.sr_int);
1582         insetjmpland=1;
1583 
1584         reg68k_internal_autovector(avno);
1585 
1586         DEBUG_LOG(0,"Autovector:%d reg68k_pc:%08x reg68k_sr:%08x regs.pc:%08x regs.sr:%08x, exiting setjmp land",avno,reg68k_pc,reg68k_sr.sr_int,regs.pc,regs.sr.sr_int);
1587     /* restore global registers back to permanent storage */
1588 		regs.pc = reg68k_pc;
1589         regs.sr.sr_int = reg68k_sr.sr_int;
1590 
1591         insetjmpland=0;
1592         #ifdef USE_SETJMP
1593         longjmp(jb, 1);
1594         #endif
1595 	}
1596 }
1597 
1598 
reg68k_external_vector(int vector,uint32 oldpc,uint32 addr_error)1599 void reg68k_external_vector(int vector, uint32 oldpc,uint32 addr_error)
1600 {
1601 #ifdef USE_SETJMP
1602     jmp_buf jb;
1603 #endif
1604 
1605     DEBUG_LOG(0,"VECTOR: %d, OLDPC:%08x memerr@:%08x",vector,oldpc,addr_error);
1606        if (insetjmpland)
1607        {fprintf(buglog,"*** DANGER Entering %s:%s:%d from %s setjmpland*****\n",__FILE__,__FUNCTION__,__LINE__,(insetjmpland ? "inside" : "outside")); fflush(buglog);
1608         reg68k_internal_vector(vector,oldpc,addr_error);
1609         return;
1610        }
1611 
1612     #ifdef USE_SETJMP
1613     if (!setjmp(jb))
1614     #endif
1615      {
1616     /* move PC and register block into global processor register variables */
1617 
1618         DEBUG_LOG(0,"In setjmp land vector:%d oldpc:%08x regs.pc:%08x regs.sr:%x",vector,oldpc,regs.pc,regs.sr.sr_int);
1619 
1620         reg68k_pc = regs.pc;
1621 		reg68k_regs = regs.regs;
1622         reg68k_sr.sr_int = regs.sr.sr_int;
1623         insetjmpland=1;
1624 
1625         DEBUG_LOG(0,"Calling internal_vector from external reg68k_pc:%08x reg68k_sr:%x",reg68k_pc,reg68k_sr.sr_int);
1626         reg68k_internal_vector(vector,oldpc,addr_error);
1627         DEBUG_LOG(0,"Done with internal_vector vector:%d reg68k_pc:%08x reg68k_sr:%08x regs.pc:%08x regs.sr:%08x, exiting setjmp land",
1628                 vector,
1629                 reg68k_pc,
1630                 reg68k_sr.sr_int,regs.pc,regs.sr.sr_int);
1631 
1632 
1633     /* restore global registers back to permanent storage */
1634 		regs.pc = reg68k_pc;
1635         regs.sr.sr_int = reg68k_sr.sr_int;
1636 
1637         insetjmpland=0;
1638         #ifdef USE_SETJMP
1639         longjmp(jb, 1);
1640         #endif
1641 	}
1642 }
1643 
1644 
1645 
1646 
1647 
1648 
1649 
1650 
1651 // called by mmuflush to make sure that the correct context is set!
reg68k_update_supervisor_internal(void)1652 void reg68k_update_supervisor_internal(void)  {lastsflag=reg68k_sr.sr_struct.s;}
reg68k_update_supervisor_external(void)1653 void reg68k_update_supervisor_external(void)  {lastsflag=regs.sr.sr_struct.s;}
1654 
1655 // Macros for 68000 Vector operations - these are turned into macro's to make the source code more readable and still faster than fn's
1656 
1657 #define A7PUSH_BYTE(x)    {abort_opcode=2; reg68k_regs[15] -= 1;    storebyte(reg68k_regs[15], (x));}
1658 #define A7PUSH_WORD(x)    {abort_opcode=2; reg68k_regs[15] -= 2;    storeword(reg68k_regs[15], (x));}
1659 #define A7PUSH_LONG(x)    {abort_opcode=2; reg68k_regs[15] -= 4;    storelong(reg68k_regs[15], (x));}
1660 #define GETVECTOR(x)      (fetchlong((x)*4))
1661 #define SWAPA7withSSP()   {reg68k_regs[15] ^= regs.sp; regs.sp ^= reg68k_regs[15]; reg68k_regs[15] ^= regs.sp;}
1662 #define SETSUPERVISOR(x)  {reg68k_sr.sr_struct.s = (x);}
1663 #define GETSUPERVISOR()   (reg68k_sr.sr_struct.s)
1664 
1665 /* reg68k_internal_autovector - go to autovector - this call assumes global
1666      registers are already setup
1667 interrupts must not occur during cpu68k_frozen, as this flag indicates
1668 that we are catching up events due to a dma transfer.  Since the dma
1669 transfer is triggered by a memory write at which stage the current value
1670 of the PC is not written anywhere (due to being in the middle of a 68k
1671 	block and it's in a local register), we MUST NOT use regs.pc - this
1672 routine uses reg68k_pc but this is loaded by reg68k_external_autovector,
1673 which is called by event_nextevent() and therefore will be a *WRONG*
1674 	reg68k_pc!
1675 */
1676 
1677 
1678 
reg68k_internal_autovector(int avno)1679 void reg68k_internal_autovector(int avno)
1680 {
1681 
1682     reg68k_internal_vector(V_AUTO + avno - 1,reg68k_pc,0);  //-1
1683 
1684 
1685     #ifdef DISABLED_2005_02_02
1686     int curlevel = (reg68k_sr.sr_int >> 8) & 7;
1687 	uint32 tmpaddr;
1688     uint16 saved_sr=reg68k_sr.sr_int;
1689 
1690        if (!insetjmpland)
1691        {fprintf(buglog,"*** DANGER Entering %s:%s:%d from %s setjmpland*****\n",__FILE__,__FUNCTION__,__LINE__,(insetjmpland ? "inside" : "outside")); fflush(buglog);
1692        reg68k_external_autovector(avno);
1693        return;
1694        }
1695 
1696     DEBUG_LOG(0,"curlevel:%d avno:%d cpufrozen: %ld",curlevel,avno,cpu68k_frozen);
1697     fflush(buglog); fflush(stdout);
1698 
1699     if ((curlevel < avno || avno == 7) && !cpu68k_frozen)
1700     {
1701       #ifdef DEBUG
1702        if (avno==1 && floppy_FDIR) append_floppy_log("reg68k_int_av_ ***Firing IRQ1 because FDIR is set***\n");
1703       #endif
1704 
1705        if (regs.stop && nmi_clk && nmi_pc) {regs.stop=0; nmi_addr_err=0;  nmi_clk=0; nmi_pc=0; nmi_stop=0;}      // clear flags
1706        else  if (regs.stop)
1707         {
1708             DEBUG_LOG(0,"exiting from STOP opcode @%08x - will continue at %08x after ISR handles IRQ:%d.",reg68k_pc,reg68k_pc+4,vno);
1709             reg68k_pc += 4;  /* autovector whilst in a STOP instruction */
1710 			regs.stop = 0;
1711             regs.pc = reg68k_pc; regs.sr = reg68k_sr;
1712 		}
1713 
1714 
1715         if (!GETSUPERVISOR()) {
1716             SWAPA7withSSP();
1717             SETSUPERVISOR(1);
1718 
1719             DEBUG_LOG(0,"S mode change SP:%08x/A7:%08x swapped.",reg68k_regs[15],regs.sp);
1720 
1721            // if (segment1|segment2)
1722               {
1723                //lastsflag=reg68k_sr.sr_struct.s;
1724                regs.pc = reg68k_pc; regs.sr = reg68k_sr;
1725                SET_MMU_DIRTY(0xdec0de);
1726                mmuflush(0x3000);
1727                fprintf(buglog,"post mmuflush context=%d s1/s2=%d/%d start=%d\n",context,segment1,segment2,start);
1728               }
1729            // Supervisor flag set causes context change
1730 		}
1731         lastsflag=reg68k_sr.sr_struct.s;
1732 
1733         A7PUSH_LONG(reg68k_pc); if (abort_opcode==1) {EXIT(779,0,"Doh! got abort_opcode=%d on storeword of SR!\n",abort_opcode); }
1734         A7PUSH_WORD(saved_sr);  if (abort_opcode==1) {EXIT(780,0,"Doh! got abort_opcode=1 on storeword of SR!\n");}
1735 
1736         // insert format/vector here    // RA for 68010+ disable for 68000/68008.
1737         //   FV=0x1000 | ((V_AUTO + avno - 1) * 4);
1738         //or FV=0x0000 | ((V_AUTO + avno - 1) * 4);
1739         //reg68k_regs[15] -= 2;
1740         //storeword(reg68k_regs[15], FV);
1741         ////////////////////////////////
1742 
1743 		reg68k_sr.sr_struct.t = 0;
1744 		reg68k_sr.sr_int &= ~0x0700;
1745 		reg68k_sr.sr_int |= avno << 8;
1746 		tmpaddr = reg68k_pc;
1747 
1748         DEBUG_LOG(0,"autovector#%d V_AUTO:%08x Vector address: %d * 4 = %08x",avno,V_AUTO,(V_AUTO + avno - 1),((V_AUTO + avno - 1)*4));
1749 
1750         abort_opcode=0;
1751         reg68k_pc = fetchlong((V_AUTO + avno - 1) * 4);
1752         if (abort_opcode==1) {EXIT(781,0,"Doh! got abort_opcode=1 while fetching vector for IRQ!\n"); }
1753 
1754         DEBUG_LOG(0,"INTERNAL AUTOVECTOR %d: oldpc %x -> newpc is %x\n", avno, tmpaddr, reg68k_pc);
1755 
1756       //  if (avno<7 && avno) pending_vector_bitmap &= ~(1<<(avno-1));
1757 
1758       //  regs.pending = get_pending_vector();
1759         // restore regs to extern
1760         regs.pc = reg68k_pc;
1761         regs.sr.sr_int = reg68k_sr.sr_int;
1762 
1763     }
1764     else
1765     {
1766 
1767 //      if (avno<7 && avno) pending_vector_bitmap |= (1<<(avno-1));
1768 //      regs.pending = get_pending_vector();
1769 //     if (!regs.pending || regs.pending < avno)
1770 //     {
1771 //        printregs(buglog,"");
1772 //        DEBUG_LOG(0,"INTERNAL AUTOVECTOR %d: was not taken because IRQ level:%d filtered it. set pending to it...SR:%04x:%04x %s\n\n",avno,curlevel,regs.sr.sr_int,reg68k_sr.sr_int,
1773 //                ((regs.sr.sr_int!=reg68k_sr.sr_int) ? "DANGER":"ok"));
1774 //
1775 //        regs.pending = avno;
1776 //      }
1777 //        //regs.pending = 0;
1778 
1779 	}
1780     #endif
1781 }
1782 
1783 
reg68k_internal_vector(int vno,uint32 oldpc,uint32 addr_error)1784 void reg68k_internal_vector(int vno, uint32 oldpc, uint32 addr_error)
1785 {
1786    static uint32 lastoldpc;
1787    static int32  lastclk;
1788    static int lastvno;
1789    uint16 saved_sr=reg68k_sr.sr_int;
1790 
1791    int avno=(vno-V_AUTO+1);
1792    int curlevel = (reg68k_sr.sr_int >> 8) & 7;
1793    //unused//static uint32 tmpaddr;
1794    uint16 busfunctioncode;
1795    uint8 old_supervisor=reg68k_sr.sr_struct.s;
1796 
1797 	  if (vno==V_LINE15 && romless && (reg68k_pc & 0x00ff0000)==0x00fe0000)
1798       {
1799 	   if (romless_entry()) return;
1800 	  }
1801 
1802 
1803     /*-----------------12/8/2003 9:56PM-----------------
1804      * needs to do this: RA
1805      *
1806      * SSP-2 ->SSP                      // push FV -- 680010+ only
1807      * Format/Vector Offset -> (SSP)
1808      * SSP-4->4->SSP                    // push PC
1809      * PC->(SSP)
1810      * SSP-2 ->SSP                      // push SR
1811      * SR->(SSP)
1812      * Vector Address->PC               // PC=Vector
1813      *
1814      * --------------------------------------------------*/
1815 
1816 
1817    // #ifdef DEBUG
1818    //     validate_mmu_segments("reg68k internal_vector");
1819    //  #endif
1820 
1821    // avoid bus/addr error repeats on multi-operand opcodes...
1822    if (lastclk==cpu68k_clocks && lastvno==vno)
1823       {
1824         DEBUG_LOG(0,"Suppressing internal_vector - VECTOR:%d, oldpc:%08x clk:%016llx",vno,oldpc,cpu68k_clocks);
1825         return;
1826       }
1827 
1828    lastclk =cpu68k_clocks;   lastvno =vno;   lastoldpc =oldpc;
1829 
1830 
1831    if (!insetjmpland)
1832        {fprintf(buglog,"*** DANGER Entering %s:%s:%d from %s setjmpland - unclean sloppy code*****\n",__FILE__,__FUNCTION__,__LINE__,(insetjmpland ? "inside" : "outside")); fflush(buglog);
1833         reg68k_external_vector(vno,oldpc,addr_error);
1834         return;
1835        }
1836 
1837    #ifdef DEBUG
1838 
1839     DEBUG_LOG(0,"Entering: internal_vector - VECTOR:%d, addr_err:%08x oldpc:%08x, pc24:%08x, reg68k_pc:%08x",
1840                  vno,addr_error,oldpc,pc24,reg68k_pc);
1841 
1842     if (oldpc!=reg68k_pc && vno<32)
1843     DEBUG_LOG(0,"DANGER DANGER DANGER oldpc:%08x is not reg68k_pc:%08x, pc24:%08x oldpc24:%08x vector:%d",oldpc, reg68k_pc,pc24,lastpc24,vno);
1844 
1845     if (vno==37) lisaos_trap5();        // log LisaOS trap #5 calls by name
1846     printregs(buglog,"irqdone");
1847 
1848 
1849    #endif
1850 
1851    if (avno>0 && avno<8)                // If it's an autovector, check the IRQ mask before allowing it to occur.
1852       {
1853         DEBUG_LOG(0,"PC:%08x AutoVector is:%d vector:%d curlevel is %d cpu stop status is:%d",reg68k_pc,avno,vno,curlevel,regs.stop);
1854         if (! (IS_VECTOR_AVAILABLE_INT(avno))) {DEBUG_LOG(0,"Vector requested is not available (INTMASK too low)");return;}
1855       }
1856    else avno=0;                         // clear avno since it wasn't an autovector - this saves time later on the avno check.
1857 
1858 
1859    if (!GETSUPERVISOR()) {
1860 
1861        SWAPA7withSSP();
1862        SETSUPERVISOR(1);
1863      // 2005.02.01 - removed if statement to force flush here on switch from user to supervisor mode
1864      //if (segment1|segment2)                 // if we're not in supervisor space already, flush the mmu
1865        {DEBUG_LOG(0,"Turning Supervisor flag on while in internal_vector flushing mmu context=%d s1/s2=%d/%d start=%d\n",context,segment1,segment2,start);
1866         SET_MMU_DIRTY(0xdec0de);  mmuflush(0x3000);
1867         DEBUG_LOG(0,"post mmuflush context=%d s1/s2=%d/%d start=%d\n",context,segment1,segment2,start);
1868        }
1869 
1870        DEBUG_LOG(5,"S mode change SP:%08x/A7:%08x swapped.",reg68k_regs[15],regs.sp);
1871        lastsflag=reg68k_sr.sr_struct.s;  regs.pc = reg68k_pc; regs.sr.sr_int = reg68k_sr.sr_int;
1872     }
1873 
1874    // might be a retake of the same addr/bus error on same opcode.  doh!  ie: when btst is done (read, write) two bus errors can occur
1875    // this is here because the previous run would have set Supervisor, and if it was already set before that, that's fine too
1876    // the problem is the following fetchlong can't be done until mmu context is set, and mmu is flushed, else gremlins
1877 
1878 
1879    {
1880     abort_opcode=2;
1881     uint32 x=GETVECTOR(vno);
1882 
1883     if (x==0xaf) {
1884                    ALERT_LOG(0,"Got bus error whilst trying to fetch vector:%d - PC:%d/%08x",vno,context,oldpc);
1885                    SET_MMU_DIRTY(0xdec0de);  mmuflush(0x3000);
1886                    x=GETVECTOR(vno);
1887                    if (x==0xaf) ALERT_LOG(0,"Failed again after trying to flush mmu! Something is very wrong!");
1888                    ALERT_LOG(0,"Attempting the old fetchlong method, if you don't see the result, we're recursive");
1889                    abort_opcode=2;
1890                    x=fetchlong(vno*4);
1891                    ALERT_LOG(0,"Got back from fetchlong:%08x",x);
1892                  }
1893 
1894     if (x==0xaf || x==oldpc)  {loopy_vector--; abort_opcode=0;//DEBUG_LOG(0,"retake of same vector");
1895                                 return;}
1896    }
1897    if (abort_opcode==1)        {EXIT(782,0,"Doh! got abort_opcode=1 on vector fetch in %s!\n",__FUNCTION__); }
1898    abort_opcode=0;
1899 
1900    if (regs.stop && nmi_clk && nmi_pc) {regs.stop=0; nmi_addr_err=0;  nmi_clk=0; nmi_pc=0; nmi_stop=0;}      // clear flags
1901    else if (regs.stop)
1902    {
1903        DEBUG_LOG(0,"exiting from STOP opcode @%08x - will continue at %08x after ISR handles IRQ:%d.",reg68k_pc,reg68k_pc+4,vno);
1904        oldpc+=4;
1905        regs.stop = 0;
1906        reg68k_pc=oldpc;
1907        pc24=oldpc;
1908        regs.pc = oldpc; regs.sr = reg68k_sr;
1909    }
1910 
1911          if (vno==2 || vno==3)
1912          {
1913             if        ((InstructionRegister & 0xff00)==0x4a00) {oldpc+=2;}
1914             else if   ((InstructionRegister & 0xff00)==0x4e00)
1915             {
1916               if      ((InstructionRegister & 0x00f0)==0x00d0) {oldpc+=2;}
1917               else if ((InstructionRegister & 0x00ff)==0x0075) {oldpc+=2; regs.sp+=4;}
1918               else if ((InstructionRegister & 0x00ff)==0x0073) {oldpc+=0;}
1919               else if ((InstructionRegister & 0x00ff)==0x00f9) {oldpc+=2;}
1920               else if ((InstructionRegister & 0x00ff)==0x00b9) {oldpc+=6;}
1921               else if ((InstructionRegister & 0x00ff)==0x00a8) {oldpc+=4;}
1922               else if ((InstructionRegister & 0x00ff)==0x0090) {oldpc+=2;}
1923               else    {
1924                         ALERT_LOG(0,"\n\n\7*** DANGER *** Unhandled opcode in buserror:%04x\n\n\7",InstructionRegister);
1925                         oldpc+=(cpu68k_iibtable[InstructionRegister]->wordlen<<1);
1926                       }
1927             }
1928          }
1929 
1930          DEBUG_LOG(0,"PUSH PC %08x context:%d",oldpc,context);
1931          A7PUSH_LONG(oldpc); //   ? (oldpc+(cpu68k_iibtable[InstructionRegister]->wordlen<<1)) : oldpc);
1932          if (abort_opcode==1) {EXIT(783,0,"Doh! got abort_opcode=1 on push pc %s!\n",__FUNCTION__); }
1933          DEBUG_LOG(0,"PUSH SR %04x context:%d",saved_sr,context);
1934          A7PUSH_WORD(saved_sr);
1935          if (abort_opcode==1) {EXIT(784,0,"Doh! got abort_opcode=1 on push sr in %s!\n",__FUNCTION__); }
1936     // "Short format 0 only four words are to be removed from the top of the stack. SR and PC are loaded from the stack frame."
1937     abort_opcode=0;
1938 
1939    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1940    if (vno==2 || vno==3)               // PUSH IS IN THIS ORDER: ---> PC,SR,IR,ADDR,BUSFN
1941    {  // memerror=(uint16)(( CHK_MMU_TRANS(addr_error) )>>5);
1942 
1943        memerror=(uint16)((               addr_error  )>>5);
1944 
1945        busfunctioncode=CPU_function_code | (CPU_READ_MODE<<4) |1;
1946 
1947        cpu68k_clocks+=(116*2); // Addr/Bus  // *2 2005.04.13.18:43
1948 
1949        DEBUG_LOG(0,"BUS_OR_ADDR: ADDR error:%d at PC:%08x pc24:%08x addr:%08x clk:%016llx - pushing extended exception frame for 68000",
1950             vno,oldpc,pc24,addr_error,cpu68k_clocks);
1951 
1952        DEBUG_LOG(0,"PUSH IR:%04x context:%d",InstructionRegister,context); A7PUSH_WORD(InstructionRegister);  if (abort_opcode==1) {EXIT(784,0,"Doh! got abort_opcode=1 on push IR    in %s!\n",__FUNCTION__); }
1953        DEBUG_LOG(0,"PUSH AE:%08x context:%d",addr_error,context);          A7PUSH_LONG(addr_error);           if (abort_opcode==1) {EXIT(784,0,"Doh! got abort_opcode=1 on push ADDRC in %s!\n",__FUNCTION__); }
1954        DEBUG_LOG(0,"PUSH BF:%04x context:%d",busfunctioncode,context);     A7PUSH_WORD(busfunctioncode);      if (abort_opcode==1) {EXIT(784,0,"Doh! got abort_opcode=1 on push BUSFN in %s!\n",__FUNCTION__); }
1955 
1956        // prevent autovectors from interrupting BUS/ADDR exception ISR's.
1957        //DEBUG_LOG(0,"Set Mask to 7 for BUS/ADDR Exception");
1958 
1959        // this might not be such a good idea
1960        // reg68k_sr.sr_int |=(7 << 8);      // no need for &= since we turn on all 3 bits.
1961        regs.pc = reg68k_pc;  regs.sr.sr_int = reg68k_sr.sr_int;
1962    }
1963    else // is this an autovector? if so handle that.
1964    {    if (avno)                                   //2005.02.02 - code refactoring/consolidation
1965         {
1966          #ifdef DEBUG
1967           if (avno==1 && floppy_FDIR) append_floppy_log("reg68k_int_av_ ***Firing IRQ1 because FDIR is set***\n");
1968          #endif
1969 
1970         //reg68k_sr.sr_struct.t = 0;                // disable trace bit - no need for it - it's handled below
1971           reg68k_sr.sr_int &= ~0x0700;              // clear IRQ Mask
1972           reg68k_sr.sr_int |= (avno<<8);            // set IRQ mask to avno
1973         //tmpaddr = reg68k_pc;                      // not used
1974 
1975           DEBUG_LOG(0,"autovector#%d V_AUTO:%08x Vector address: %d * 4 = %08x",vno-V_AUTO+1,V_AUTO,vno,(vno*4));
1976 
1977         //abort_opcode=2;reg68k_pc = GETVECTOR(vno);  if (abort_opcode==1) {fprintf(buglog,"Doh! got abort_opcode=1 while fetching vector for IRQ!\n"); EXIT(781);}
1978         }
1979 
1980        cpu68k_clocks+=87;  // IRQ1-7
1981 
1982    }
1983 
1984 
1985    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1986 
1987     abort_opcode=2;  reg68k_pc=GETVECTOR(vno);    // should turn this into vector 15 - spurious IRQ
1988     if (abort_opcode==1) {EXIT(58,0,"Doh got abort_opcode=1 on vector fetch in %s - BYE BYE\n",__FUNCTION__); }
1989     abort_opcode=0;
1990 
1991     DEBUG_LOG(0,"SRC: VECTOR IRQ: %s oldpc:%08x -> newpc:%08x A7=%08x SP=%08x Mode pre-IRQ:%s\n",
1992             getvector(vno), oldpc, reg68k_pc,reg68k_regs[15],regs.sp, (old_supervisor ? "Supervisor":"User"));
1993 
1994     regs.pending = get_pending_vector();                                           // not sure that I need this any longer - RA
1995 
1996     if (0==reg68k_pc) {debug_on("reg68k_pc=0"); EXIT(59,0,"reg68k_pc got nullified. bye");  }
1997     if (reg68k_pc& 1)   LISA_REBOOTED();
1998 
1999     reg68k_sr.sr_struct.t=0;                                                       // turn off trace on trap.
2000     regs.pc = reg68k_pc; regs.sr.sr_int = reg68k_sr.sr_int;                        // flush to external copy of regs
2001     DEBUG_LOG(0,"Done with vector fn. regs.pc=%08x reg68k_pc:%08x",regs.pc,reg68k_pc);
2002 
2003     abort_opcode=0;
2004     return;
2005 }
2006 
2007 
2008 #ifdef DEBUG
print_pc_and_regs(char * text)2009 void print_pc_and_regs(char *text)
2010 {
2011   fprintf(buglog,"\n\n%s PC%08x\n",text, reg68k_pc);  fflush(buglog);
2012   printregs(buglog,""); fflush(buglog);
2013 }
2014 #endif
2015 
lisa_buserror(uint32 addr_error)2016 void lisa_buserror(uint32 addr_error)
2017 {
2018     reg68k_internal_vector(2 ,reg68k_pc, addr_error);
2019     abort_opcode=1;
2020 }
2021 
2022 #define LINE(x) DEBUG_LOG(0,"%s:%s:%d %s LINE LOG"       ,__FILE__,__FUNCTION__,__LINE__,x); fflush(buglog);
2023 
lisa_mmu_exception(uint32 addr_error)2024 void lisa_mmu_exception(uint32 addr_error)
2025 {
2026    char temp[1024];
2027 
2028    //20060105 memerror=(uint16)(( CHK_MMU_TRANS(addr_error)+(maxlisaram!=RAM1024K ? 0:RAM512K) )>>5);
2029    memerror=(uint16)(( CHK_MMU_TRANS(addr_error) )>>5);
2030 /*
2031    ALERT_LOG(0,"MMU BUSERROR: IR:%04x @ %d/@%08x :: buserr@addr:%08x -> phys-addr:%08x SOR:%04x SLR:%04x %s",
2032          InstructionRegister,context,reg68k_pc,
2033          addr_error,
2034          CHK_MMU_REGST(addr_error),
2035          mmu[(addr_error & MMUSEGFILT)>>17].sor,
2036          mmu[(addr_error & MMUSEGFILT)>>17].slr,
2037          printslr(temp,1024, mmu[(addr_error & MMUSEGFILT)>>17].slr)
2038          );
2039 */
2040    reg68k_internal_vector(2,reg68k_pc,addr_error);
2041    abort_opcode=1;
2042 }
2043 
2044 
lisa_addrerror(uint32 addr_error)2045 void lisa_addrerror(uint32 addr_error)
2046 {
2047     ALERT_LOG(0,"Odd Address Exception @%08x PC=%08x clk:%016llx ",addr_error,reg68k_pc,cpu68k_clocks);
2048 
2049     DEBUG_LOG(0,"ADDRESS EXCEPTION @%08x PC=%08x",addr_error,reg68k_pc);
2050     reg68k_internal_vector(3,reg68k_pc,addr_error);
2051     abort_opcode=1;
2052 }
2053 
2054 
2055 // this may only be called from internal land!
lisa_nmi_vector(uint32 addr_error)2056 void lisa_nmi_vector(uint32 addr_error)
2057 {
2058    //unused//uint32 pc_before_nmi=reg68k_pc;
2059 
2060    //20060105memerror=(uint16)(( CHK_MMU_TRANS(addr_error)+(maxlisaram!=RAM1024K ? 0:RAM512K) )>>5);
2061     memerror=(uint16)(( CHK_MMU_TRANS(addr_error) )>>5);
2062 
2063 //   ALERT_LOG(0,"NMI @%08x PC=%08x clk:%016llx memerr latch:%04x - resucitated memlatch:%08x",addr_error,reg68k_pc,cpu68k_clocks,memerror,(uint32)(memerror<<5));
2064    DEBUG_LOG(0,"NMI Exception @%08x (phys:%08x) PC=%08x clk:%016llx ",
2065                 addr_error,
2066                 (CHK_MMU_TRANS(addr_error)),
2067                 reg68k_pc,
2068                 cpu68k_clocks);
2069 
2070    DEBUG_LOG(0,"NMI ERROR: current state: context:%d seg1:%d seg2:%d start:%d",context,segment1,segment2,start);
2071 
2072 
2073 
2074 
2075    nmi_pc      = reg68k_pc;
2076    nmi_addr_err= addr_error;
2077    nmi_clk     = cpu68k_clocks;
2078    nmi_stop    = regs.stop;
2079 
2080    regs.stop=1;
2081    return;
2082 
2083   ///////////// old dead code////////////////// CODEKARMA CODE KARMA CLEANUP CLEAN UP
2084    return;
2085 
2086 
2087 
2088    #ifdef disabled_2005_02_01
2089    DEBUG_LOG(0,"NMI @%08x pc24==%08x reg68k_pc:%08",addr_error,pc24,reg68k_pc);
2090 
2091    if (abort_opcode || last_nmi_error_pc==reg68k_pc) {fprintf(buglog,"suppressing NMI - abort_opcode=1\n"); return;}
2092 
2093     //#ifdef DEBUG
2094       if (nmi_error_trap>3 || last_nmi_error_pc==pc24) {EXIT(786,0,"NMI on top of NMI!\n"); };
2095       last_nmi_error_pc=reg68k_pc;
2096       nmi_error_trap++;
2097     //#endif
2098 
2099     DEBUG_LOG(0,"*** SRC: Lisa NMI - likely for parity test @ %08x pc=%08x ***",addr_error,reg68k_pc);
2100 
2101     // Be sure to change from regs68k.pc to reg68k_pc if changing this to internal!
2102 
2103     DEBUG_LOG(0,"int VECTOR 1F (autovector 6 NMI.  mem addr:%08x, reg68k_pc:%08x pc24:%08x lastpc24:%08x",addr_error,reg68k_pc,pc24, lastpc24);
2104 
2105    // reg68k_external_autovector(7);         // using 7 now    ???
2106 
2107        if (!insetjmpland)
2108        {EXIT(1,0,"*** DANGER Entering %s:%s:%d from %s setjmpland*****\n",__FILE__,__FUNCTION__,__LINE__,(insetjmpland ? "inside" : "outside"));}
2109 
2110     reg68k_internal_vector(0x1f, reg68k_pc,addr_error);  // 7 is wrong for vector, right for autovector.
2111     abort_opcode=1; // not tru                     // NMI is an IRQ - DOES not abort an opcode.  Just signals after completion of opcode
2112 
2113     DEBUG_LOG(0,"Done with external_vector call. reg68k_pc is now %08x, it originally was %08x",reg68k_pc,pc_before_nmi);
2114     if (pc24 & 1) fprintf(buglog,"%s:%s:%d PC24 is now odd!!!!%08x\n",__FILE__,__FUNCTION__,__LINE__,pc24);
2115     //#ifdef DEBUG
2116       nmi_error_trap--;
2117     //#endif
2118    #endif
2119 }
2120 
lisa_external_nmi_vector(uint32 addr_error)2121 void lisa_external_nmi_vector(uint32 addr_error)
2122 {
2123    uint32 pc_before_nmi=reg68k_pc;
2124 
2125    DEBUG_LOG(0,"External NMI vector @%08x PC=%08x clk:%016llx ",addr_error,reg68k_pc,cpu68k_clocks);
2126 
2127    DEBUG_LOG(0,"\n** NMI @%08x pc24==%08x\n",addr_error,pc24);
2128    DEBUG_LOG(0,"NMI extern ");
2129 
2130    if (abort_opcode || last_nmi_error_pc==reg68k_pc) {fprintf(buglog,"suppressing NMI - abort_opcode=1\n"); return;}
2131 
2132     //#ifdef DEBUG
2133       if (nmi_error_trap>3 || last_nmi_error_pc==pc24) {EXIT(786,0,"NMI on top of NMI!\n"); };
2134       last_nmi_error_pc=reg68k_pc;
2135       nmi_error_trap++;
2136     //#endif
2137 
2138     DEBUG_LOG(0,"*** SRC: Lisa NMI - likely for parity test @ %08x pc=%08x ***",addr_error,reg68k_pc);
2139 
2140     // Be sure to change from regs68k.pc to reg68k_pc if changing this to internal!
2141 
2142     DEBUG_LOG(0,"int VECTOR 1F (autovector 6 NMI.  mem addr:%08x, reg68k_pc:%08x pc24:%08x lastpc24:%08x",addr_error,reg68k_pc,pc24, lastpc24);
2143 
2144    if (!insetjmpland)
2145 	{EXIT(1,0,"*** DANGER Entering %s:%s:%d from %s setjmpland*****\n",__FILE__,__FUNCTION__,__LINE__,(insetjmpland ? "inside" : "outside"));}
2146 
2147    // reg68k_external_autovector(7);         // using 7 now    ???
2148     memerror=(uint16)(( CHK_MMU_TRANS(addr_error) )>>5);
2149     reg68k_external_vector(0x1f, reg68k_pc,addr_error);  // 7 is wrong for vector, right for autovector.  // DANGER DANGER was pc24
2150     abort_opcode=1;                                      /// VERY STRANGE THAT THIS NEEDS TO BE SO!!! Something odd about this???
2151 
2152     DEBUG_LOG(0,"Done with external_vector call. reg68k_pc is now %08x, it originally was %08x",reg68k_pc,pc_before_nmi);
2153     if (reg68k_pc & 1) fprintf(buglog,"%s:%s:%d reg68k_pc is now odd!!!!%08x\n",__FILE__,__FUNCTION__,__LINE__,pc24);
2154     //#ifdef DEBUG
2155       nmi_error_trap--;
2156     //#endif
2157 }
2158 
2159 
2160