1 /**************************************************************************************\
2 *                                                                                      *
3 *              The Lisa Emulator Project  V1.2.6      DEV 2007.12.04                   *
4 *                             http://lisaem.sunder.net                                 *
5 *                                                                                      *
6 *                  Copyright (C) 1998, 2007 Ray A. Arachelian                          *
7 *                                All Rights Reserved                                   *
8 *                                                                                      *
9 *           This program is free software; you can redistribute it and/or              *
10 *           modify it under the terms of the GNU General Public License                *
11 *           as published by the Free Software Foundation; either version 2             *
12 *           of the License, or (at your option) any later version.                     *
13 *                                                                                      *
14 *           This program is distributed in the hope that it will be useful,            *
15 *           but WITHOUT ANY WARRANTY; without even the implied warranty of             *
16 *           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
17 *           GNU General Public License for more details.                               *
18 *                                                                                      *
19 *           You should have received a copy of the GNU General Public License          *
20 *           along with this program;  if not, write to the Free Software               *
21 *           Foundation, Inc., 59 Temple Place #330, Boston, MA 02111-1307, USA.        *
22 *                                                                                      *
23 *                   or visit: http://www.gnu.org/licenses/gpl.html                     *
24 *                                                                                      *
25 *                                                                                      *
26 *                                                                                      *
27 *      Global externed variables, macros, macro constants, and function prototypes.    *
28 *                                                                                      *
29 *   ---------------------------------------------------------------------------------  *
30 *                                                                                      *
31 *   Yes, this is ugly, yes, it's not quite standard practice, but there is madness to  *
32 *   method.  ;-)    (For the irony impaired, yes, that IS backwards)                   *
33 *                                                                                      *
34 *   1. Include all the needed include files.                                           *
35 *   2. Define macro fn's and constants used elsewhere                                  *
36 *   3. define type definitions                                                         *
37 *   4. define externed global variables                                                *
38 *   5. define fn extern or local prototypes (self checking)                            *
39 *                                                                                      *
40 \**************************************************************************************/
41 
42 // This should always be on, but we can cheat for a slight speedup to turn it off?
43 #define CHECKODDPOINTERS 1
44 #define DEBUGLEVEL 100
45 
46 // If tracelog is enabled, also enable DEBUG code so that tracing can be done.
47 #ifdef TRACE
48 #ifndef DEBUG
49 #define DEBUG
50 #endif
51 #endif
52 
53 //Enable to build a Lisa1 emulator instead of a Lisa2 emulator - not yet implemented - place holder.
54 //#define LISA1
55 
56 // enables MMU cache vs mmu registers testing - this is VERY VERY SLOW, and no longer valid
57 //#define MMUVALIDATE 1
58 
59 
60 // If this is disabled the Generator CORE will calculate the status flags on every opcode
61 // hack for LisaEm to see if there are flag calculation issues.
62 #define NORMAL_GENERATOR_FLAGS 1
63 
64 // This forces each executed opcode to have it's IPC re-created - used to see if IPC cache
65 // isn't working properly, or if we're hitting self-modifying code  -- very slow, do not use
66 //#define EVALUATE_EACH_IPC 1
67 
68 //enable a read after write to ensure we get back the same data we wrote - no longer supported
69 //#define VERIFY_WRITES 1
70 // If this is enabled, it's a little slower because extra checks are required.
71 
72 //do not use this ever//#define ALLOW_1536K_RAM 1 -- no longer
73 
74 
75 // Enable this if you want all of the Lisa Status register bits to be set. - slower, but more acurate.
76 #define FULL_STATREG 1
77 
78 // Enable this to disassemble skipped opcodes to the log that weren't executed - might be buggy!
79 //#define DISASM_SKIPPED_OPCODES 1
80 
81 // Same as above, but specific to a single block of code instead of every chunk of code.
82 // //0xd27a-0xddff for LisaTest  *REMOVE*
83 //#define LOOKAHEAD 1
84 //#define LOOKSTARTADDR    0x00b848d0
85 //#define LOOKENDADDR      0x00b849cc
86 
87 // If enabled, what screenhash value to turn debugging on
88 //#define DEBUG_ON_SCREENHASH  {0,0,0,0,0,0,0,0,       0x7f,0x19,0xcc,0x88,0x87,0x5f,0xca,0x64,0xff,0xfc,0xff,0x5c,0x00,0x00}
89 //#define DEBUG_OFF_SCREENHASH {0,0,0,0,0,0,0,0,       0xff,0xff,0x9b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xdf}
90 
91 //{0x7f,0xcb,0xe7,0xbd,0xe0,0xf3,0x2b,0xcd,0x7f,0xf3,0xff,0x5d,0x00,0x00}
92 
93 // If this is turned on, the VIA timers will no longer be tied to the CPU speed, rather,
94 // they'll be adjusted to match the throttle. So if the throttle is 10Mhz, these will take
95 // 2x CPU cycles they normally do.  This is in the hopes of slowing down the blinking
96 // text cursor to a reasonable value so it doesn't flicker.  It might not work with all
97 // OS's - will certainly cause LisaTest to complain if its run at throttle >5.0Mhz
98 //#define TIE_VIA_TIMER_TO_HOST 1
99 // above does not work and instead throws error 93 on the dual parallel slot's power on self test.
100 
101 
102 
103 // How close do we need to be in order to declare a matching the screen hash?
104 #define SCREENHASH_LIMIT    16
105 
106 // Do read-only memory violations cause bus errors?
107 #define ROMEMCAUSESBUSERROR 1
108 
109 // Do physical memory over/underflows cause MMU exceptions?
110 //#define PHYS_UNDER_BUSERR 1
111 //#ifdef PHYS_OVERFLOW_BUSERR 1
112 
113 // Enable this to avoid C compiler assumptions (noteably in the get_pending_vector() fn)
114 // it's safer to enable this if not using GCC, or you can't guarantee expression evaluation order is left to right
115 #define PARANOID 1
116 
117 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
118 // The following options are only for DEBUG enabled compiles
119 #ifdef DEBUG
120 
121 // If this is enabled, and debug log is enabled, it will attempt to suppress loop disassembly
122 // by keeping track of the last MAX_LOOP_REGS and will only output the changed registers.
123 #define SUPPRESS_LOOP_DISASM 1
124 #define MAX_LOOP_REGS 10
125 
126 // switches to fn's that log memory calls, if undefined, these are macros, so they're much faster.
127 // only turn this on if you need it.
128 #define DEBUGMEMCALLS 1
129 
130 // this enables the cpucoretester.c which is runs multiple cores in parallel and tests them
131 //#define CPU_CORE_TESTER 1
132 
133 // If this is enabled, it will force the Instruction Parameter Cache to be invalidated on
134 // for that address on each write to memory.  This is to correct problems with self-modifying code
135 // I'm not sure whether or not there are any such problems, but it is provided as a compile itme option.
136 //#define FORCE_MEMWRITE_TO_INVALIDATE_IPC 1
137 
138 // If debugging is turned on, this option can be turned on to provide a dump of the
139 // instruction cache and also the current cpu clock value when debugging is enabled.
140 // useful for extra long opcodes, and the debuggng of the 68K core.
141 #define ICACHE_DEBUG 1
142 
143 // Detect procedure entry into LisaOS
144 #define PROCNAME_DEBUG 1
145 
146 #endif
147 // The above options are only for DEBUG enabled compiles
148 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
149 
150 //-----------------------------------------------------------------------------------------------------------------------------
151 
152 #ifndef IN_VARS_H
153 #define IN_VARS_H 1
154 
155 #define BIT0  1
156 #define BIT1  2
157 #define BIT2  4
158 #define BIT3  8
159 #define BIT4  16
160 #define BIT5  32
161 #define BIT6  64
162 #define BIT7  128
163 #define BIT8  256
164 #define BIT9  512
165 #define BIT10 1024
166 #define BIT11 2048
167 #define BIT12 4096
168 #define BIT13 8192
169 #define BIT14 16384
170 #define BIT15 32768
171 
172 
173 // Allow C to call C++
174 
175 #ifdef __cplusplus
176 #define CPP2C "C"
177 #else
178 #define CPP2C
179 #endif
180 
181 
182 // Magic Macros - allows me to get around one of C's more annoying limits
183 // global variables are generally a big no-no, but in emulators, you want
184 // to get as much performance out of things as you can, so you bend the rules.
185 //
186 // Globals accessed by other .c files need extern declarations, which is
187 // fine and great.  But externs stupidly don't ignore assignments, so you
188 // can't just use a global variable file, so you wind up with a .c and a .h
189 // if these get out of sync, all sorts of evil things can happen.  i.e. you
190 // delcare a variable as a uint8 in one file and a uint16 in another.  When
191 // you compile, the compiler has no knowledge that one .c file expencts a
192 // byte and the other expects a word - because the two .c files have a different
193 // view of things - one has the actual variable, the other has an extern
194 // delcaration - hence, very bad things happen.
195 //
196 // Solution: we fix this by putting all the global variables in a single file
197 // this one, but use C MACRO's to allow it to turn on extern in the case of
198 // the include, and assign in the value in the case of the globals vars.c file.
199 //
200 // Neat, no?
201 //
202 // The one caveat is that C Macro's can't handle missing parameters, so we need
203 // two versions - one for when we don't assign a value (DECLARE) and one for when
204 // we do (GLOBAL).  Also, we can't do this: int a,b,c - need one GLOBAL per var now.
205 //- - - - - - - - - -
206 
207 ///////////////////////////////////////////////////////////////////////////////////
208 // Are we assigning a value to the variable? (and alternate default value version)
209 
210 
211 //#define    ASSIGN(TYPE, VAR, val...)        TYPE VAR= ## val  // ## causes gcc 3.x preprocessor to warn
212 #define    ASSIGN(TYPE, VAR, val...)        TYPE VAR = val
213 #define   CASSIGN(MYTYPE, MYVAR, val...)    const MYTYPE MYVAR = val
214 #define  NOASSIGN(TYPE, VAR)                TYPE VAR
215 
216 // Are we defining an extern reference to the variable?
217 #define  REFERENCE(TYPE, VAR, val...)  extern TYPE VAR
218 #define CREFERENCE(TYPE, VAR, val...)  extern const TYPE VAR
219 
220 // Doesn't matter, we can use a single macro for both, but decide which one here.
221 #ifdef IN_VARS_C
222 
223   #define GLOBAL(TYPE, VAR, val...)           TYPE VAR = val
224   #define DECLARE(TYPE, VAR)                  TYPE VAR
225   #define AGLOBAL(MYTYPE, MYVAR, val...)     const MYTYPE MYVAR = val
226   #define ACGLOBAL(TYPE, VAR, val...)        const TYPE VAR = val
227 
228 #else
229   #define AGLOBAL  REFERENCE
230   #define ACGLOBAL REFERENCE
231   #define GLOBAL   REFERENCE
232   #define DECLARE  REFERENCE
233 #endif
234 
235 
236 /////////////////////////////////////////////////////////////////////////////////
237 
238 
239 // include all the includes we'll (might) need (and want)
240 #include <stdio.h>
241 #include <stdlib.h>
242 #include <string.h>
243 #include <sys/types.h>
244 #include <unistd.h>
245 #include <errno.h>
246 #include <time.h>
247 
248 #ifndef __MSVCRT__
249 #include <sys/mman.h>
250 #endif
251 
252 
253 #include "built_by.h"
254 #include "generator.h"
255 #include "registers.h"
256 
257 
258 // disable this - dangerous to little-endian transforms??
259 #ifdef ALIGNLONGS
260 #undef ALIGNLONGS
261 #endif
262 
263 
264 
265 #include "z8530_structs.h"
266 #include "libdc42.h"
267 
268 
269 // If the Host OS has this, use it.
270 #ifndef FILENAME_MAX
271  #define FILENAME_MAX 256
272 #endif
273 
274 
275 /*-------------------- 2003.07.08 17:23 ------------------------
276  * hack to fix endianness under CygWin.  Might not be an
277  * actuall issue with cygwin, but rather with the configure
278  * scripts that I use...  *NOTE* Modifications to these must
279  * also be reflected in registers.h and generator.h!
280  * ----------------------------------------------------------*/
281 
282 #ifdef PROCESSOR_INTEL
283   #undef WORDS_BIGENDIAN
284   #undef BIG_ENDIAN
285   #ifndef LITTLE_ENDIAN
286     #define LITTLE_ENDIAN 1
287   #endif
288   #undef BYTESHIGHFIRST
289 #endif
290 
291 #ifdef  PROCESSOR_SPARC
292   #define WORDS_BIGENDIAN 1
293   #ifndef BIG_ENDIAN
294     #define BIG_ENDIAN 1
295   #endif
296   #undef  LITTLE_ENDIAN
297   #define BYTESHIGHFIRST 1
298 #endif
299 
300 #ifdef  __POWERPC__
301 #define BYTES_HIGHFIRST  1
302 #define WORDS_BIGENDIAN  1
303 #endif
304 #ifdef __sparc__
305 #define BYTES_HIGHFIRST  1
306 #define WORDS_BIGENDIAN
307 #endif
308 #ifdef sparc
309 #define BYTES_HIGHFIRST  1
310 #define WORDS_BIGENDIAN  1
311 #endif
312 
313 
314 
315 #ifdef __CYGWIN__
316   #undef WORDS_BIGENDIAN
317   #undef BIG_ENDIAN
318   #ifndef LITTLE_ENDIAN
319     #define LITTLE_ENDIAN 1
320   #endif
321   #undef BYTESHIGHFIRST
322 #endif
323 
324 
325 
326 #ifndef MIN
327   #define MIN(x,y) ( (x)<(y) ? (x):(y) )
328 #endif
329 
330 #ifndef MAX
331   #define MAX(x,y) ( (x)>(y) ? (x):(y) )
332 #endif
333 
334 
335 #ifdef CPU_CORE_TESTER
336 extern 				void corecpu_get_start_masterregs(void);
337 extern              void corecpu_complete_opcode(int endmmucx);
338 #endif
339 
340 
341 // Utility tables
342 //
343 // These are here to make certain transformation operations faster, and easier.
344 //
345 // Doesn't look like I'm using most of these, but it may be worth having them around
346 //
347 //
348 //////////////////////////////////////////////////////////////////////////////////
349 
350 // given a byte, find the bit# with the highest value.  return ff for 0 since
351 // no bit is set (bit0=1, bit1=2, bit2=4, bit3=8, etc.)
highest_bit_num(uint8 v)352 static inline int highest_bit_num(uint8 v)
353 {
354     unsigned int s, r = 0;
355     if (v == 0) return 0xff;
356     s = ((v & 0xf0)!=0) << 2; v >>= s; r |= s;
357     s = ((v & 0x0c)!=0) << 1; v >>= s; r |= s;
358     s = ((v & 0x02)!=0) << 0; v >>= s; r |= s;
359     return r;
360 }
361 
362 // same as above but instead, return the value of the highest bit, not it's #
363 ACGLOBAL(uint8,highest_bit_val[],
364 { 0x00,0x01,0x02,0x02,0x04,0x04,0x04,0x04,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
365   0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
366   0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
367   0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
368   0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
369   0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
370   0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
371   0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
372   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
373   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
374   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
375   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
376   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
377   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
378   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
379   0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
380 });
381 
382 // same as above but invert the result (to save an ^0xff operation on masks)
383 ACGLOBAL(uint8,highest_bit_val_inv[],
384 { 0xff,0xfe,0xfd,0xfd,0xfb,0xfb,0xfb,0xfb,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,
385   0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,
386   0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,
387   0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,
388   0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,
389   0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,
390   0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,
391   0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,
392   0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
393   0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
394   0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
395   0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
396   0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
397   0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
398   0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
399   0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f
400 });
401 
402 
403 
404 
405 
406 /////////////////////////////////////  Macro Constants ////////////////////////////////////////////////////////////////////////
407 
408 
409 
410 //////
411 // Used to decode MMU SLR
412 //                                8    4    2   1
413 #define FILTR           0xf00 //(2048+1024+512+256)
414 #define SLR_MASK        0xf00 //(2048+1024+512+256)  // f
415 #define SLR_RO_STK      0x400 //(     1024        )  // 4
416 #define SLR_RO_MEM      0x500 //(     1024+    256)  // 5
417 #define SLR_RW_STK      0x600 //(     1024+512    )  // 6
418 #define SLR_RW_MEM      0x700 //(     1024+512+256)  // 7
419 #define SLR_IO_SPACE    0x900 //(2048+         256)  // 8
420 #define SLR_UNUSED_PAGE 0xc00 //(2048+1024)          // c   1100= IO+RO (Read Only + IO)
421 #define SLR_SIO_SPACE   0xf00 //(2048+1024+512+256)  // f
422 
423 #define SERIAL_PORT_A_DATA    0xFCD247
424 #define SERIAL_PORT_A_CONTROL 0xFCD243
425 #define SERIAL_PORT_B_DATA    0xFCD245
426 #define SERIAL_PORT_B_CONTROL 0xFCD241
427 #define IRQ_FLOPPY     1			// run of the mill floppy IRQ's.
428 #define IRQ_VIDEO      1            // not sure if this is correct
429 #define IRQ_FDIR_ON    40           // special cases.  These are for floppy fdir=1, fdir=0
430 #define IRQ_FDIR_OFF   41
431 #define IRQ_GOBYTE_0   42           // zero gobyte after some time
432 
433 #define IRQ_SCC        6            // Serial port
434 #define IRQ_VIA1       2			// Keyboard/Mouse/Clock (COPS controller)
435 #define IRQ_COPS       2            // Keyboard/Mouse/Clock (COPS controller)
436 #define IRQ_VIA2       1 			// Parallel Port VIA
437 #define IRQ_SLOT0      5			// Expasion Slot IRQ's
438 #define IRQ_SLOT1      4
439 #define IRQ_SLOT2      3
440 
441 
442 
443 
444 /*
445 *   7   NMI - Highest Priority                                                         *
446 *   6   RS-232 Ports                                                                   *
447 *   5   Expansion Slot 0                                                               *
448 *   4   Expansion Slot 1                                                               *
449 *   3   Expansion Slot 2                                                               *
450 *   2   Keyboard                                                                       *
451 *   1   All other internal interrupts -- lowest priority                               *
452 *                                                                                      *
453 *   Reset: Initial SSP               $000000           0                               *
454 *   Reset: Initial PC                $000004           1                               *
455 *   Bus Error:                       $000008           2                               *
456 *   Address Error:                   $00000C           3                               *
457 *   Illegal Instruction:             $000010           4                               *
458 *   Zero Divide:                     $000014           5                               *
459 *   CHK Instruction:                 $000018           6                               *
460 *   TRAPV Instruction:               $00001C                                           *
461 *   Privilidge Violation:            $000020                                           *
462 *   Trace:                           $000024                                           *
463 *   Unimplemented Instruction 1010   $000028                                           *
464 *   Unimplemented Instruction 1111   $00002C                                           *
465 *   Reserved/Unassigned:             $000030 - $00005F                                 *
466 *   Spurious Interrupt:              $000060           24                              *
467 *   Other Internal Interrupt:        $000064                                           *
468 *   Keyboard Interrupt:              $000068           1a/26                           *
469 *   Slot 2 Autovector:               $00006C           1b/27                           *
470 *   Slot 1 Autovector:               $000070           1c/28                           *
471 *   Slot 0 Autovector:               $000074           1d/29                           *
472 *   RS-232 Interrupt                 $000078           1e/30                           *
473 *   Non-Maskable Interrupt:          $00007C           1f/31                           *
474 *   Trap Instruction Vectors:        $000080 - $000BF                                  *
475 *   Reserved, Unassigned:            $0000C0 - $000Cf                                  *
476 *   User Interrupt Vectors:          $000100 - $003FF                                  *
477 
478 */
479 
480 // this must be a power of 2 under 65536 and huge!  This is the size of the Interrupt Queue Ring buffer.
481 // since the lisa can shut off interrupts,  we need this to be huge.
482 //////////////////////////////////////////////////////////////////////////////////////////////////////////
483 #define MAXIRQQUEUE 64
484 
485 
486 // *** WARNING Make sure you copy the above to vars.c as
487 // it does not include vars.h
488 #define PROFILE_IMG_HEADER_SIZE 2048
489 
490 /* Defines for the Via 6522 code -- MMU needs these to decypher the register accessed. */
491 // Expansion Port Slots.  PARPORTVER is the ROM version number.
492 #define PARPORTVER  {0x00,01,00,07}
493 #define V0HVIA1BASE 0xFC2000
494 #define V0LVIA1BASE 0xFC2800
495 #define V1HVIA1BASE 0xFC4000
496 #define V1LVIA1BASE 0xFC4800
497 #define V2HVIA1BASE 0xFC8000
498 #define V2LVIA1BASE 0xFC8800
499 
500 /* Definitions for VIA 1   -- COPS                                      */
501 #define VIA1BASE 0xFCDD80             /* Base address of VIA 1          */
502 
503 // VIA1 registers are on the odd addresses in increments of 2.
504 #define ORB1   ((0*2)+1)    /* Port B output Register         */
505 #define IRB1   ((0*2)+1)
506 #define ORA1   ((1*2)+1)    /* Port A output Register         */
507 #define IRA1   ((1*2)+1)
508 #define DDRB1  ((2*2)+1)    /* Port B Data Direction Register */
509 #define DDRA1  ((3*2)+1)    /* Port A Data Direction Register */
510 #define T1CL1  ((4*2)+1)
511 #define T1CH1  ((5*2)+1)
512 #define T1LL1  ((6*2)+1)    /* Low Order T1 Latch             */
513 #define T1LH1  ((7*2)+1)    /* High Order T1 Latch            */
514 #define T2CL1  ((8*2)+1)    /* Low Order T2 Counter           */
515 #define T2CH1  ((9*2)+1)    /* Low Order T2 Counter           */
516 #define SR1    ((10*2)+1)
517 #define ACR1   ((11*2)+1)
518 #define PCR1   ((12*2)+1)
519 #define IFR1   ((13*2)+1)
520 #define IER1   ((14*2)+1)
521 #define ORANH1 ((15*2)+1)
522 #define IRANH1 ((15*2)+1)
523 
524 
525 #define VVIA2BASE 0xFCD900             /* Base address of VIA 2          */
526 
527 /* Definitions for VIA 2   -- Parallel Port  */
528 // VIA2 registers are on the odd addresses in increments of 8.
529 #define ORB2   ((0*8)+1)
530 #define IRB2   ((0*8)+1)
531 #define ORA2   ((1*8)+1)
532 #define IRA2   ((1*8)+1)
533 #define DDRB2  ((2*8)+1)
534 #define DDRA2  ((3*8)+1)
535 #define T1CL2  ((4*8)+1)
536 #define T1CH2  ((5*8)+1)
537 #define T1LL2  ((6*8)+1)
538 #define T1LH2  ((7*8)+1)
539 #define T2CL2  ((8*8)+1)
540 #define T2CH2  ((9*8)+1)
541 #define SR2    ((10*8)+1)
542 #define ACR2   ((11*8)+1)
543 #define PCR2   ((12*8)+1)
544 #define IFR2   ((13*8)+1)
545 #define IER2   ((14*8)+1)
546 #define ORANH2 ((15*8)+1)
547 #define IRANH2 ((15*8)+1)
548 
549 
550 #define ORB    0
551 #define IRB    0
552 #define ORA    1
553 #define IRA    1
554 #define DDRB   2
555 #define DDRA   3
556 #define T1CL   4
557 #define T1CH   5
558 #define T1LL   6
559 #define T1LH   7
560 #define T2CL   8
561 #define T2CH   9
562 #define SHIFTREG    10
563 #define ACR   11
564 #define PCR   12
565 #define IFR   13
566 #define IER   14
567 #define ORANH 15
568 #define IRANH 15
569 
570 // Shadow of T2
571 #define T2LL   16
572 #define T2LH   17
573 
574 // Shadows of I/O regs
575 #define IRAA  18
576 #define ORAA  19
577 #define IRBB  20
578 #define ORBB  21
579 
580 
581 // Paralell port VIA PORT B bit definitions
582 #define OCDLine_BIT    1
583 #define BSYLine_BIT    2
584 #define DENLine_BIT    4
585 #define RRWLine_BIT    8
586 #define CMDLine_BIT   16
587 #define PARITY_BIT    32
588 #define DSK_DIAG_BIT  64
589 #define CTRL_RES_BIT 128
590 
591 // if all are cleared, clear bit 7 else set it
592 //if (via[2].via[IER] & via[2].via[IFR] & 0x7f) via[2].via[IFR] |=0x80; // if any actively on, bit 7 is on.
593 
594 #define FIX_VIA_IFR(vianum)  {                                                               \
595                                if ( via[vianum].via[IFR] & 127) via[vianum].via[IFR]|=128;   \
596                                else via[vianum].via[IFR]=0;                                  \
597 	                         }
598 
599 #define FIX_VIAP_IFR()       {                                                               \
600                                if ( V->via[IFR] & 127) V->via[IFR]|=128;                     \
601                                else V->via[IFR]=0;                                           \
602  	                         }
603 
604 #define IS_PARALLEL_PORT_ENABLED(vianum) (profile_power & (1<<(vianum-2)) )
605 
606 
607 #define  VIA_IRQ_BIT_CA2          1  // cleared by read/write of reg1 (ora) unless CA2/CB2 in PCR set as independent irq - only writing to ifr will then clear it
608 #define  VIA_IRQ_BIT_CA1          2  // cleared by read or write reg 1
609 #define  VIA_IRQ_BIT_SR           4  // cleared by read/write of shift register
610 #define  VIA_IRQ_BIT_CB2          8  // cleared by read or write orb - except if PCR sets it as independent IRQ like ca2
611 #define  VIA_IRQ_BIT_CB1         16  // cleared by read/write orb
612 #define  VIA_IRQ_BIT_T2          32  // read t2 low or write t2 high clears it
613 #define  VIA_IRQ_BIT_T1          64  // read t1 low or wite t1 high clears it
614 #define  VIA_IRQ_BIT_SET_CLR_ANY 128 // only cleared when all other IRQ's are cleared.
615 
616 /* Timer ID's  */
617 #define CYCLE_TIMER_VIAn_T1_TIMER(x)  ((x)    )
618 #define CYCLE_TIMER_VIAn_T2_TIMER(x)  ((x)+128)
619 #define CYCLE_TIMER_VIAn_SHIFTREG(x)  ((x)+64 )
620 
621 
622 #define CYCLE_TIMER_VIA1_T1_TIMER           (1    )
623 #define CYCLE_TIMER_VIA1_T2_TIMER           (1+128)
624 #define CYCLE_TIMER_VIA1_SHIFTREG           (1+64 )
625 
626 #define CYCLE_TIMER_VIA2_T1_TIMER           (2    )
627 #define CYCLE_TIMER_VIA2_T2_TIMER           (2+128)
628 #define CYCLE_TIMER_VIA2_SHIFTREG           (2+64 )
629 
630 #define CYCLE_TIMER_VIA3_T1_TIMER           (3    )
631 #define CYCLE_TIMER_VIA3_T2_TIMER           (3+128)
632 #define CYCLE_TIMER_VIA3_SHIFTREG           (3+64 )
633 
634 #define CYCLE_TIMER_VIA4_T1_TIMER           (4    )
635 #define CYCLE_TIMER_VIA4_T2_TIMER           (4+128)
636 #define CYCLE_TIMER_VIA4_SHIFTREG           (4+64 )
637 
638 #define CYCLE_TIMER_VIA5_T1_TIMER           (5    )
639 #define CYCLE_TIMER_VIA5_T2_TIMER           (5+128)
640 #define CYCLE_TIMER_VIA5_SHIFTREG           (5+64 )
641 
642 #define CYCLE_TIMER_VIA6_T1_TIMER           (6    )
643 #define CYCLE_TIMER_VIA6_T2_TIMER           (6+128)
644 #define CYCLE_TIMER_VIA6_SHIFTREG           (6+64 )
645 
646 #define CYCLE_TIMER_VIA7_T1_TIMER           (7    )
647 #define CYCLE_TIMER_VIA7_T2_TIMER           (7+128)
648 #define CYCLE_TIMER_VIA7_SHIFTREG           (7+64 )
649 
650 #define CYCLE_TIMER_VIA8_T1_TIMER           (8    )
651 #define CYCLE_TIMER_VIA8_T2_TIMER           (8+128)
652 #define CYCLE_TIMER_VIA8_SHIFTREG           (8+64 )
653 
654 #define CYCLE_TIMER_VERTICAL_RETRACE        (11   )
655 #define CYCLE_TIMER_COPS_MOUSE_IRQ          (12   )
656 #define CYCLE_TIMER_COPS_CLOCK_DSEC         (13   )
657 #define CYCLE_TIMER_FDIR                    (14   )
658 
659 #define CYCLE_TIMER_Z8530                   (15   )
660 
661 #define CYCLE_TIMER_SCC_B_XMT_BUF_EMPTY     (16+0 )     // Z8530 Channel B Transmit Buffer Empty
662 #define CYCLE_TIMER_SCC_B_EXT_STAT_CHG      (16+1 )     // Z8530 Channel B External/Status Change
663 #define CYCLE_TIMER_SCC_B_RCVD_CHAR         (16+2 )     // Z8530 Channel B Receive Character Avail
664 #define CYCLE_TIMER_SCC_B_SPECIAL           (16+3 )     // Z8530 Channel B Special Receive Condition
665 
666 #define CYCLE_TIMER_SCC_A_XMT_BUF_EMPTY     (20+0 )     // Z8530 Channel A Transmit Buffer Empty
667 #define CYCLE_TIMER_SCC_A_EXT_STAT_CHG      (20+1 )     // Z8530 Channel A External/Status Change
668 #define CYCLE_TIMER_SCC_A_RCVD_CHAR         (20+2 )     // Z8530 Channel A Receive Character Avail
669 #define CYCLE_TIMER_SCC_A_SPECIAL           (20+3 )     // Z8530 Channel A Special Receive Condition
670 
671 
672 
673 
674 
675 
676 
677 
678 
679 
680 
681 
682 
683 
684 
685 
686 ///////////////////////////////////////////////// Type definitions /////////////////////////////////////////////////
687 //
688 // 64 bit values might not be available on all host systems.  They seem to be define on modern ones, although I've
689 // noticed buggy/limited support for them when using shift operations.  However, as long as addition/substraction
690 // and multiplication works, and they're built in to your CPU, they can be used to gain an advantage with the timer
691 // code.  int32's can also be used by the timer code, however they will cause a slowdown every 5 minutes of guest
692 // runtime, and at every event as the timers are checked for overflow.
693 //
694 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
695 #ifndef int64
696   #define int64 int64_t
697   #define USE64BITTIMER 1
698 #endif
699 #define USE64BITTIMER 1
700 
701 
702 // HALF_CLK needs to be the highest bit we can go before the value becomes negative. i.e. for 32 bit values, bit 30.
703 // for 64 bit values, bit 62 (since the msb is the sign bit)
704 //
705 //------------------------------------------------------------------------------------------------------------------------
706 //
707 // I'd love to change these to int64's and HALF_CLK to (1<<62), however, it seems 64 bit shifts are a bit buggy at the moment
708 // on Linux IA32 with debian gcc 4.0.3-1
709 
710 //#ifdef XXBROKENXX
711 #ifdef USE64BITTIMER
712                   //  0123456789012345 - careful, want to use 1<<62 however, found bugs in shifting with gcc 4!
713   #define HALF_CLK (0x4000000000000000)
714   #define XTIMER int64
715  // #define prevent_clk_overflow_now(x) {1}
716  // #define prevent_clk_overflow(x) {1}
717   #define USING64BITTIMER 1
718 
719 #else
720 
721   #define HALF_CLK (1<<30)
722   #define XTIMER int32
723   #define CLKDIV2(x) ((x)>>=1)
724   //#define CLKDIV2(x) ((x)/=2)
725 extern void  prevent_clk_overflow_now(void);
726 
727 #endif
728 
729 extern void  init_ipct_allocator(void);
730 
731 GLOBAL(uint8,*lisaram,NULL);                 // pointer to Lisa RAM
732 
733 
734 
735 // this enables a hack that tricks the lisa into skipping the full ram test, thus speeding up
736 // the boot process - this sets a PRAM variable saying RAM test is done.
737 GLOBAL(int,cheat_ram_test,1);
738 GLOBAL(int,romless,0);
739 
740 // othe globally saved defaults
741 GLOBAL(int,sound_effects_on,1);
742 GLOBAL(int,profile_power,127);
743 DECLARE(int,hide_host_mouse);
744 DECLARE(int,skins_on);
745 DECLARE(int,skins_on_next_run);
746 DECLARE(int,lisa_ui_video_mode);
747 DECLARE(uint32,refresh_rate);
748 DECLARE(uint32,refresh_rate_used);
749 
750 
751 typedef uint8 lisa_mem_t;         /* type indicator for the above #defines for use with fn's           */
752 
753 typedef struct
754 {
755   uint32 size;
756   uint8 *buffer;
757   uint32 start;
758   uint32 end;
759 } FLIFLO_QUEUE_t;
760 
761 typedef struct
762       {
763        int16 x;
764        int16 y;
765        int8  button;                    // 0=no click change, 1=down, -1=up.
766       } mousequeue_t;
767 
768 
769 
770 
771 typedef struct
772 {
773     int8   Command;                      // what command is the profile doing:
774                                          // -1=disabled, -2=idle, 1=read, 2=write, 3=write verify
775                                          //
776     uint8   StateMachineStep;            // what step of Command is the state machine of this profile in?
777 
778     uint8   DataBlock[4+8+532+8+2];      // 4 status bytes, command block, data block, 2 for good luck ;)
779 
780     uint16  indexread;                   // indeces into the buffer for the Lisa to Read or Write
781 	uint16  indexwrite;
782     uint32  blocktowrite;                // used by the write command to store the block number to write
783 
784   //uint32  numblocks;                   // (24 bit value!) size of this profile in blocks.
785                                          //   (9728=5mb, 532 bytes/sector)
786                                          // We shouldn't make this more than 10Mb until we've tried it.
787 
788                                          // Control Lines from 6522 (except OCDLine which is Command=-1)
789     uint8   CMDLine;                     // set by Lisa
790     uint8   BSYLine;                     // set by ProFile
791     uint8   DENLine;                     // set by Lisa (drive enabled)
792     uint8   RRWLine;                     // set by Lisa (read or write)
793 
794     uint8   VIA_PA;                      // data to from VIA PortA (copied to/from V->via[0])
795     uint8   last_a_accs;
796     int32   last_reset_cpuclk;           // last reset occured at what cpu clock?
797 
798     DC42ImageType DC42;                  // actual storage container
799 
800     // DC42 contains the ProFilename and file handler
801     //char  ProFileFileName[FILENAME_MAX]; // the file name for this Profile disk image to open;
802 
803     XTIMER   clock_e;                     // used for timeouts - this is in relation to cpu68k_clocks
804     XTIMER   alarm_len_e;                 // used for timeouts - how long was the delay set for in clock_e event expiration
805 
806 
807 	int      vianum;
808 	int      last_cmd;
809 }  ProFileType;
810 
811 
812 
813 
814 typedef struct
815 {
816 	uint8 active;           		// is this VIA active? (except via1 and via2 s/b always active)
817                                  	// make sure that the initialization code sets these anyway!!!
818 
819     uint8 vianum;                   // Which VIA is this?
820 
821     uint8 via[22];                  // standard via registers + timer 2 shadows and actual IRA/ORA/IRB/IRA shadows, etc.
822 
823     int last_a_accs;                // was the last access to port A a read or a write? (for DDRA flips from 00 to ff)
824                                     // I've seen some code that writes to port A, then sets DDRA to FF, only at that point
825                                     // is the data put on the port.  I've seen other code that does the opposite, so I need
826                                     // some way to distinguish what the value in PORT A is from in order to output properly
827 
828     int orapending;                 // there are many ways to output data.  some OS's set DDRA=0, then write to ORA, then
829                                     // set DDRA=FF to output.  Others set DDRA=FF 1st, then write to ORA.  When DDRA=0 and
830                                     // a write is made to ora, the data cannot be placed on PA, but as soon as DDRA=FF, the
831                                     // PA gets data out and CA2 is set.  So to avoid a bug where an extra ORA is made when
832                                     // DDRA=FF, ORA is written, DDRA=0, then DDRA=FF, this keeps track of the pending.
833 
834     XTIMER t1_e;                    // e_clock trigger - at what point will the via clock expire vs cpu68k_clocks
835     XTIMER t1_fired;
836     XTIMER t2_e;
837     XTIMER t2_fired;
838     XTIMER sr_e;
839     XTIMER sr_fired;
840 
841 	XTIMER last_pa_write;           // used to find the end of print jobs
842 
843     //#ifdef DEBUG
844     XTIMER t1_set_cpuclk;
845     XTIMER t2_set_cpuclk;
846     XTIMER t1_fired_cpuclk;
847     XTIMER t2_fired_cpuclk;
848     //#endif
849 
850     ProFileType *ProFile;           // If there's a ProFile attached, this structure deals with it.
851     int ADMP;                       // If there's an Apple Dot Matrix Printer (same as IW, but parallel)
852 
853 	uint8 irqnum;           		// Interrupt number for this VIA
854 	uint8 srcount;
855     uint8 ca1, ca2, cb1, cb2;       // port A,B control lines
856 
857 	uint8 (*irb)(uint8 vianum, uint8 reg);		    // Function Pointers to the Handlers for what's connected to the VIA's.
858 	void  (*orb)(uint8 vianum,uint8 data, uint8 reg);
859 	uint8 (*ira)(uint8 vianum, uint8 reg);
860 	void  (*ora)(uint8 vianum,uint8 data, uint8 reg);
861 }   viatype;
862 
863 // What can I say, I'm a lazy fuck, I don't like to worry about the case of these.
864 #define ViaType viatype
865 #define VIAType viatype
866 #define VIAtype viatype
867 
868 GLOBAL(int32,video_scan,0);
869 
870 GLOBAL(int,lisa_vid_size_x,720);
871 GLOBAL(int,lisa_vid_size_y,364);
872 GLOBAL(int,lisa_vid_size_xbytes,90);
873 GLOBAL(int,has_lisa_xl_screenmod,0);
874 
875 // used by mouse routines to detect mouse acceleration undo strategy
876 #define LISA_ROM_RUNNING      0
877 #define LISA_OFFICE_RUNNING   1
878 #define LISA_TEST_RUNNING     2
879 #define LISA_MACWORKS_RUNNING 3
880 #define LISA_MONITOR_RUNNING  4
881 #define LISA_XENIX_RUNNING    5
882 #define UNKNOWN_OS_RUNNING    100
883 
884 GLOBAL(int,running_lisa_os,LISA_ROM_RUNNING);
885 int check_running_lisa_os(void);
886 GLOBAL(int,mouse_x_tolerance,0);
887 GLOBAL(int,mouse_y_tolerance,0);
888 
889 GLOBAL(int,mouse_x_halfing_tolerance,1);
890 GLOBAL(int,mouse_y_halfing_tolerance,1);
891 
892 // can turn these into a pointer and several arrays for various OS's.
893 GLOBAL(int,anti_jitter_sample_dec1[],{64,32,16,8,4,2,0,0,0});
894 GLOBAL(int,anti_jitter_sample_dec2[],{1,2,4,16,32,64,0,0,0});
895 
896 GLOBAL(int,anti_jitter_decellerate_xt[],{8,32,64,0});
897 GLOBAL(int,anti_jitter_decellerate_xn[],{1,2,4,0});
898 GLOBAL(int,anti_jitter_decellerate_yt[],{8,32,64,0});
899 GLOBAL(int,anti_jitter_decellerate_yn[],{1,2,3,0});
900 
901 //GLOBAL(int,via_port_idx_bits[],{0, 2,1, 4,3, 6,5});
902                               //2, 4,3, 6,5, 8,7
903 GLOBAL(uint32,lisa_os_mouse_x_ptr,0x486);
904 GLOBAL(uint32,lisa_os_mouse_y_ptr,0x488);
905 GLOBAL(uint32,lisa_os_boot_mouse_x_ptr,0x486);
906 GLOBAL(uint32,lisa_os_boot_mouse_y_ptr,0x488);
907 GLOBAL(int8,floppy_picked,1);                         //2006.06.11 - if 1 enable profile access immediately
908 
909 typedef struct _lisa_clock
910 {
911  uint8 year;
912  uint8 days_h;
913  uint8 days_l;  uint8 hours_h;
914  uint8 hours_l; uint8 mins_h;
915  uint8 mins_l;  uint8 secs_h;
916  uint8 secs_l;  uint8 tenths;
917 } t_lisa_clock;
918 
919 DECLARE(t_lisa_clock,lisa_clock);
920 
921 GLOBAL(int32,lisa_alarm,0);
922 GLOBAL(uint8,lisa_clock_set_idx,0);
923 GLOBAL(uint8,lisa_alarm_power,0);
924 GLOBAL(uint8,lisa_clock_on,1);
925 DECLARE(uint8,eparity[256]);
926 DECLARE(uint8,lisa_clock_set[8]);
927 
928 // Instruction Parameter Cache
929 typedef struct _t_ipc {
930     void (*function)(struct _t_ipc *ipc);  //8/4    // pointer to the function that executes this opcode
931     uint8 used;                            //1      // bitmap of XNZVC flags inspected
932     uint8 set;                             //1      // bitmap of XNZVC flags altered
933     uint16 opcode;                         //2      // absolutely necessary - the opcode itself i.e. 0x4e75=RTS
934 
935     uint16 wordlen;                        //2      // might be able to delete this if we also add nextpc, but diss68k will need work as will
936                                                     // lots of mods of cpu68.k  To get it call iib->wordlen  but the illegal instruction in
937                                                     // there needs checking.
938 
939     unsigned int :0;                       //3      // what's this here for?  alignment I suspect?
940     uint32 src;                            //4
941     uint32 dst;                            //4
942 
943     // //  // // // // // // // // // // // // // these are extensions to the normal generator code in order to refine it, etc.
944 
945     uint16 reg;                            //2      // for cpu68k-inline idx_val macros/inlines replacing the bug that causes the
946                                                     // high octet in PC (bits 31-24) to be filled, then causes negative PC on sign ext.
947     uint8  clks;                           //1      // might be able to remove this if I can get this from iib without too much of a slowdown - maybe
948 
949     struct _t_ipc *next;                   //8/4    // next ipc in chain. we could get rid of this, but then things would run slower
950                                                     // and we'd need to do a whole lot of more work to get things to work.
951                                                     // Need to get rid of this, but have to redo stuff in cpu68k.c to do it.
952     // //  // // // // // // // // // // // // // /////////////////////////////////////////////////////////////////////////////
953 } t_ipc;
954 
955 
956 typedef struct _t_ipc_table
957 {
958 	// Pointers to all the IPC's in this page.  Since the min 68k opcode is 2 bytes in size
959 	// the most you can have are 256 instructions per page.  We thus no longer need a hash table
960 	// nor any linked list of IPC's as this is a direct pointer to the IPC.  Ain't life grand?
961 
962     t_ipc ipc[256];                            // only need this, the rest I think is junk
963 
964 	// These are merged together so that on machines with 32 bit architectures we can
965 	// save four bytes.  It will still save 2 bytes on 64 bit machines.
966     union t
967     {   uint32 clocks;                  // can I get rid of this one? - it's used in cpu68k.c - but can be gotten rid of
968 
969                                         // we still use the *next pointer to keep track of IPC's.
970         struct _t_ipc_table *next;      // try to get rid of these as they're not really needed, only used for free list!
971     } t;
972 
973 
974 #ifdef PROCESSOR_ARM
975 	void (*compiled)(struct _t_ipc *ipc);
976 	//uint8 norepeat;	// what's this do? this only gets written to, but not read.  Maybe Arm needs it?
977 #endif
978 } t_ipc_table;
979 
980 //////////////////////////////////////////////////////////
981 //
982 // MMU Translation Table for page.  This provides function pointers to read/write handlers as well as address translation
983 // via the address offset (signed) integer which gets added to the address.
984 //
985 // The table is an array of 256's ipc's -- if NULL it hasn't been allocated for this page.  The table is a pointer to
986 // an element of a linked list of IPC tables.
987 //
988 // For a 2MB (fully loaded non-XL 4MB hacked up Lisa) you have upto: 2097152 bytes of RAM + 16384ROM -> that's
989 // upto 2113536 bytes maximum of executable code (most of it won't be executable.)
990 //
991 // In terms of 512 byte MMU pages, this is: 4128 pages.  Each ipc structure takes about 32 bytes * 256/page = 8K * 4128 pages
992 // we have a maximum of 32MB (it's much smaller than this since not all of the Lisa's memory will be IPC's.)
993 // Yup, this is one memory hungry emulator....  So we need decent memory management on the MMU+ipct's.
994 //
995 // Why 256 ipc's/page? Simple: smallest 68k opcode is 2 bytes, there are 512/page, so at most there are 256 ipc's/page.
996 // But because management of these is not trivial, we allocate 256 of them per page if they're used.
997 //
998 // Note that the IPC's point to the virtual, not physical pages.
999 
1000 typedef struct _mmu_trans_t
1001 {	int32 address;	     /* quick ea translation. Just add to lower bits  - needs to be signed 	*/
1002     //uint32 sor9;
1003 	lisa_mem_t readfn;   /* index to read and write fn's for that segment, that way I			*/
1004 	lisa_mem_t writefn;  /* can have read only segments without doing special checking.		*/
1005 	t_ipc_table *table;  /* Pointer to a table of IPC's or NULL if one hasn't been assigned.	*/
1006 } mmu_trans_t;
1007 
1008 
1009 // Lisa's MMU table.  This get's converted to mmu_trans table above on a per/page basis.
1010 typedef struct
1011 {
1012     uint16 sor, slr;          // real sor, slr
1013     //uint16 newsor, newslr;    // used when updating - won't change to this until both are written to.
1014 	uint8  changed;   		  // this is a flag to let us know that an mmu segment has changed.
1015 		                  	  // come back later to correct it. bit 0=newslr set, bit 1=newsor set.
1016 } mmu_t;
1017 
1018 
1019 
1020 
1021 
1022 
1023 GLOBAL(uint8,lastsflag,0);
1024 
1025 GLOBAL(uint8,floppy_FDIR,0);
1026 GLOBAL(uint8,floppy_6504_wait,1);
1027 GLOBAL(uint8,floppy_irq_top,1);
1028 GLOBAL(uint8,floppy_irq_bottom,1);  // interrupt settings (are floppies allowd to interrupt)
1029 DECLARE(uint8,floppy_ram[2048]);
1030 
1031 GLOBAL(uint32,mmudirty,0);
1032 DECLARE(uint32,mmudirty_all[5]);
1033 
1034 
1035 DECLARE(uint8,lisarom[0x4000]);              // space for the MC68000 ROM
1036 DECLARE(uint8,dualparallelrom[2048]);           // rom space for the dual parallel card
1037 
1038 DECLARE(uint8,dirtyvidram[32768]);
1039 
1040 GLOBAL(uint32,segment1,0);                   // MMU related bits
1041 GLOBAL(uint32,segment2,0);
1042 GLOBAL(uint32,context,0);
1043 GLOBAL(uint32,lastcontext,0);
1044 
1045 GLOBAL(uint32,address32,0);                  // not sure that this is needed anymore
1046 GLOBAL(uint32,address,0);
1047 GLOBAL(uint32,mmuseg,0);
1048 GLOBAL(uint32,mmucontext,0);
1049 GLOBAL(uint32,transaddress,0);
1050 
1051 // special memory latches toggled by i/o space addresses in the lisa.
1052 GLOBAL(uint32,diag1,0);
1053 GLOBAL(uint32,diag2,0);
1054 GLOBAL(uint32,start,1);
1055 GLOBAL(uint32,softmem,0);
1056 GLOBAL(uint32,vertical,0);
1057 GLOBAL(uint32,verticallatch,0);
1058 GLOBAL(uint32,hardmem,0);
1059 GLOBAL(uint32,videolatch,0x2f);
1060 GLOBAL(uint32,lastvideolatch,0x2f);
1061 GLOBAL(uint32,videolatchaddress,(0x2f*32768));
1062 GLOBAL(uint32,lastvideolatchaddress,0x2f*32768);
1063 GLOBAL(uint32,statusregister,0);
1064 GLOBAL(uint32,videoramdirty,0);
1065 GLOBAL(uint32,videoximgdirty,0);
1066 GLOBAL(uint16,memerror,0);
1067 
1068 // hack for intermediate RC2 version - stolen from LisaCanvas.cpp as an ugly quick and dirty hack
1069 GLOBAL(int,dirty_x_min,720);
1070 GLOBAL(int,dirty_x_max,0);
1071 GLOBAL(int,dirty_y_min,364);
1072 GLOBAL(int,dirty_y_max,0);
1073 
1074 GLOBAL(int,e_dirty_x_min,720);
1075 GLOBAL(int,e_dirty_x_max,0);
1076 GLOBAL(int,e_dirty_y_min,500);
1077 GLOBAL(int,e_dirty_y_max,0);
1078 
1079 // hack for intermediate RC2 version - stolen from LisaCanvas.cpp as an ugly quick and dirty hack
1080 
1081 
1082 
1083 GLOBAL(uint8,contrast,0xff); // 0xff=black 0x80=visible 0x00=all white
1084 GLOBAL(uint8,volume,4); // 0x0e is the mask for this.
1085 GLOBAL(long,*dtc_rom_fseeks,NULL);
1086 GLOBAL(FILE,*rom_source_file,NULL);
1087 
1088 GLOBAL(int,debug_log_enabled,0);
1089 GLOBAL(FILE,*buglog,NULL);
1090 
1091 #ifdef DEBUG
1092 #ifdef DEBUG_ON_SCREENHASH
1093 GLOBAL(uint8,debug_hash[],DEBUG_ON_SCREENHASH);
1094 #endif
1095 #ifdef DEBUG_OFF_SCREENHASH
1096 GLOBAL(uint8,debug_hash_off[],DEBUG_OFF_SCREENHASH);
1097 #endif
1098 #endif
1099 
1100 
1101 
1102 
1103 // hexadecimal conversion table table.
1104 ACGLOBAL(char,*hex,"0123456789abcdef");
1105 
1106 
1107 
1108 /****************** COPS.C definitions/vars visible to outside world... ************************************/
1109 
1110 #define MAXCOPSQUEUE 512
1111 #define MAXMOUSEQUEUE 16
1112 
1113 GLOBAL(int16,copsqueuelen,0);
1114 DECLARE(uint8,copsqueue[MAXCOPSQUEUE]);
1115 GLOBAL(uint8, NMIKEY,0);
1116 GLOBAL(uint8, cops_powerset,0);
1117 GLOBAL(uint8, cops_clocksetmode,0);
1118 GLOBAL(uint8, cops_timermode,0);
1119 GLOBAL( int8, mouse_pending,0);
1120 GLOBAL( int8, mouse_pending_x,0);
1121 GLOBAL( int8, mouse_pending_y,0);
1122 GLOBAL(int16, last_mouse_x,0);
1123 GLOBAL(int16, last_mouse_y,0);
1124 GLOBAL(int16, last_mouse_button,0);
1125 GLOBAL(int16, mousequeuelen,0);
1126 DECLARE(mousequeue_t,mousequeue[MAXMOUSEQUEUE]);
1127 
1128 
1129 // How many percent of the current IPCT's should we allocate. ** MUST MATCH WHAT'S IN vars.c!!!!!!! ***
1130 #define IPCT_ALLOC_PERCENT 20
1131 
1132 // What's the maximum time's we'll call malloc?
1133 #define MAX_IPCT_MALLOCS 8
1134 
1135 // we should never need to even do more than the initial malloc if initial_ipcts=4128.
1136 DECLARE(t_ipc_table,*ipct_mallocs[MAX_IPCT_MALLOCS]);
1137 
1138 // size of each of the above mallocs - not really needed, but could be useful for debugging.
1139 DECLARE(uint32,sipct_mallocs[MAX_IPCT_MALLOCS]);
1140 
1141 DECLARE(t_ipc_table,*ipct_mallocs[MAX_IPCT_MALLOCS]);
1142 DECLARE(uint32,sipct_mallocs[MAX_IPCT_MALLOCS]);
1143 GLOBAL(uint32,iipct_mallocs ,0);
1144 GLOBAL(uint32,ipcts_allocated,0);
1145 GLOBAL(uint32,ipcts_used,0);
1146 GLOBAL(uint32,ipcts_free,0);
1147 GLOBAL(t_ipc_table,*ipct_free_head,NULL);
1148 GLOBAL(t_ipc_table, *ipct_free_tail,NULL);
1149 
1150 /* (2MB RAM max+ 16KROM)=2113536 bytes of potentially executable code divided by 512(bytes/mmu page) = 4128
1151 *  ipc's page = maximum= 8256 ipct's is maximum - should not have to go above this ever.
1152 *  this value is only for testing, until we test the LisaEM under heavy load to find the actual used number of ipct's
1153 *  and lessen it to free things up.  remember, each ipct holds 256 ipcs plus extra info.  */
1154 GLOBAL(uint32,initial_ipcts,4128);
1155 
1156                                         // 212,179 ->missing 18 lines! 18 lines is the entire retrace cycle!
1157 
1158 #define CYCLES_PER_LINE           (212) //was212               //213       /* (720+176)/(20.375Mhz/5Mhz) .. =219.87 was 224*/
1159 #define VISIBLE_LINE_CYCLES       (179) //180
1160 #define FULL_FRAME_CYCLES         (CYCLES_PER_LINE*364)                    //-4330)   /* 364 lines visible  -17 added 2005.04.14 10:51am */
1161 #define HALF_FRAME_CYCLES         (FULL_FRAME_CYCLES/2)
1162 #define QUARTER_FRAME_CYCLES      (FULL_FRAME_CYCLES/4)
1163 //#define VERT_RETRACE_ON           (450)                 //450   //-VERT_RETRACE_ON-250
1164 #define VERT_RETRACE_CYCLES_X     ((CYCLES_PER_LINE*(380-364))) //-VERT_RETRACE_ON)  //-VERT_RETRACE_ON)   //2005.05.04 - change it to 16  was 15  /* 15 retrace lines  */
1165 #define VERT_RETRACE_ON           (VERT_RETRACE_CYCLES_X/2)
1166 #define VERT_RETRACE_CYCLES       (VERT_RETRACE_CYCLES_X/2)
1167 
1168 #define ONE_SECOND              5000000
1169 //#define ONE_SECOND                5093750
1170 
1171 #define COPS_IRQ_TIMER_FACTOR     20375                    // was 20000
1172 #define THIRTY_SECONDS           (ONE_SECOND*30)
1173 #define TWENTY_SECONDS           (ONE_SECOND*20)
1174 #define FIFTEEN_SECONDS          (ONE_SECOND*15)
1175 #define TEN_SECONDS              (ONE_SECOND*10)
1176 #define FIVE_SECONDS             (ONE_SECOND*5)
1177 #define MILLIONTH_OF_A_SECOND    (ONE_SECOND/1000000)
1178 #define HUN_THOUSANDTH_OF_A_SEC  (ONE_SECOND/100000)
1179 #define TEN_THOUSANDTH_OF_A_SEC  (ONE_SECOND/10000)
1180 #define THOUSANDTH_OF_A_SECOND   (ONE_SECOND/1000)
1181 #define HUNDREDTH_OF_A_SECOND    (ONE_SECOND/100)
1182 #define TENTH_OF_A_SECOND        (ONE_SECOND/10)
1183 
1184 #define HALF_OF_A_SECOND         (ONE_SECOND/2)
1185 #define THIRD_OF_A_SECOND        (ONE_SECOND/3)
1186 #define QUARTER_OF_A_SECOND      (ONE_SECOND/4)
1187 #define FIFTH_OF_A_SECOND        (ONE_SECOND/5)
1188 #define EIGHTH_OF_A_SECOND       (ONE_SECOND/8)
1189 
1190 #define REFRESHRATE (ONE_SECOND/60)
1191 
1192 // old versions of above - likely wrong
1193 //#define FULL_FRAME_CYCLES    65520
1194 //#define HALF_FRAME_CYCLES    32760
1195 //#define QUARTER_FRAME_CYCLES 16380
1196 //#define VERT_RETRACE_CYCLES   2700
1197 //#define COPS_IRQ_TIMER_FACTOR     20000
1198 //#define HUNDRETH_OF_A_SECOND      50000
1199 //#define TENTH_OF_A_SECOND        500000
1200 //#define ONE_SECOND              5000000
1201 
1202 // number of CPU cycles between transmitting a character of the SCC and the count zero interrupt.
1203 #define Z8530_XMIT_DELAY        1000
1204 
1205 GLOBAL(XTIMER,lastrefresh,0);
1206 GLOBAL(XTIMER,virq_start,FULL_FRAME_CYCLES);
1207 GLOBAL(XTIMER,fdir_timer,-1);
1208 GLOBAL(XTIMER,cpu68k_clocks_stop,ONE_SECOND);
1209 GLOBAL(XTIMER,cpu68k_clocks,0);
1210 GLOBAL(XTIMER,lasttenth,0);
1211 GLOBAL(XTIMER,clktest,0);
1212 GLOBAL(XTIMER,cops_event,-1);
1213 GLOBAL(XTIMER,tenth_sec_cycles,TENTH_OF_A_SECOND);      // 10th of a second cycles.  5,000,000 cycles/sec so 500000 10ths/sec
1214 GLOBAL(XTIMER,z8530_event,-1);
1215 GLOBAL(XTIMER,cops_mouse,(COPS_IRQ_TIMER_FACTOR*4));
1216 
1217 
1218 
1219 #define KBCOPSCYCLES 6350
1220                               // if mouse is enabled, next clock event is cops_mouse.
1221                               // if copsqueuelen - that means we have data, and either cops event is off, or it's further
1222                               // away, then set it closer.
1223 
1224 
1225 #define SET_COPS_NEXT_EVENT(x) { cops_event=(cops_mouse ? (cpu68k_clocks+cops_mouse):-1);                             \
1226                                  if (copsqueuelen>0 && ((cops_event>(cpu68k_clocks+KBCOPSCYCLES)) || cops_event<0))   \
1227                                         cops_event=cpu68k_clocks+KBCOPSCYCLES;                                        \
1228                                  DEBUG_LOG(0,"SET_COPS_NEXT:copsqueuelen:%d cops_mouse:%ld cops_event:%016llx cpu68k_clk:%016llx \n", \
1229                                              copsqueuelen,cops_mouse, cops_event, cpu68k_clocks);                     \
1230                                 }
1231 
1232 
1233                                //         ***** still need logic for when cops_event=-1 but there's now data to deal with
1234                                //                 i.e. need to make sure timer is turned on.  likely can change the send macro to check
1235                                //
1236                                //if (cops_event<0) SET_COPS_NEXT_EVENT(0);
1237 
1238 
1239 GLOBAL(uint32,via_clock_diff,2);       // 2
1240 
1241 // These should be external as they belong to generator
1242 #ifndef IN_CPU68K_C
1243 extern unsigned long cpu68k_frames;
1244 extern unsigned long cpu68k_frozen;
1245 extern int abort_opcode;
1246   #ifdef DEBUG
1247    extern int do_iib_check;
1248 
1249   #endif
1250 #endif
1251 
1252 // recheck these for correctness!
1253 
1254 // 0x3100=12544
1255 // X  =  100000/12544 [7.97193877551]
1256 // Hmmm, seems it's better to use 8 as a timing factor
1257 GLOBAL(float,via_throttle_factor,1.0);
1258 
1259 // something is broken with the VIA timing, no matter what I do with it, the clock is still skewed.
1260 #ifdef TIE_VIA_TIMER_TO_HOST
1261 
1262 #define LISA2ECLKFACTOR  (XTIMER)((float)10*(via_throttle_factor)) // 10 //( 7.750950) //8.117647058825 //.11764705882=5,5  83=5,7 //.1176470588=5,5  .1176470589=5,7  .117647058[7|5]=5,5 585=5,5  57=5,5 9=5,7 //.117647055=5,5  .11764706[5|3|1]=5,7 .11764706=5,7  .11764707=5,7  .11764705=5,5 .1176471=5,7 72=5,7  .1176470=5,5 .117647[3|5]=5,7  //.117648=5,7  //.117647=5,5 //.117649=5,7  //117645=5,5 //1176[3/4]=5,5 //1165=5,7// 1176=5,5 //.1178/7=5,7 // 1175=5,5 //118=5,7 //117=5,5 //.119=5,7 // 8.113/114/115=5,5 // 8.11=5,5 // 8.12=5,7 // 8.16,14=5,7// 8.18=5,7 // 8.20=5,7 // 8.1=5,5 //8.0=5,5 // 8.3 5,7 // 8.25=5,7 //  8.2=5,7 // 8.1=7,5  // 9 5,7 //7.9=5,5  //8=5.5  //7.8=5.5  //8             // 10  // 8
1263 #define LISA1ECLKFACTOR  (XTIMER)((float)4 *(via_throttle_factor))  //( 3.263358)
1264 
1265 #else
1266 
1267 #define LISA2ECLKFACTOR  10 // 10 //( 7.750950) //8.117647058825 //.11764705882=5,5  83=5,7 //.1176470588=5,5  .1176470589=5,7  .117647058[7|5]=5,5 585=5,5  57=5,5 9=5,7 //.117647055=5,5  .11764706[5|3|1]=5,7 .11764706=5,7  .11764707=5,7  .11764705=5,5 .1176471=5,7 72=5,7  .1176470=5,5 .117647[3|5]=5,7  //.117648=5,7  //.117647=5,5 //.117649=5,7  //117645=5,5 //1176[3/4]=5,5 //1165=5,7// 1176=5,5 //.1178/7=5,7 // 1175=5,5 //118=5,7 //117=5,5 //.119=5,7 // 8.113/114/115=5,5 // 8.11=5,5 // 8.12=5,7 // 8.16,14=5,7// 8.18=5,7 // 8.20=5,7 // 8.1=5,5 //8.0=5,5 // 8.3 5,7 // 8.25=5,7 //  8.2=5,7 // 8.1=7,5  // 9 5,7 //7.9=5,5  //8=5.5  //7.8=5.5  //8             // 10  // 8
1268 #define LISA1ECLKFACTOR  4   //( 3.263358)
1269 
1270 #endif
1271 //#define LISA1ECLKFACTOR (24.117647058825) //24.117647058825 //.11764705882=5,5  83=5,7 //.1176470588=5,5  .1176470589=5,7  .117647058[7|5]=5,5 585=5,5  57=5,5 9=5,7 //.117647055=5,5  .11764706[5|3|1]=5,7 .11764706=5,7  .11764707=5,7  .11764705=5,5 .1176471=5,7 72=5,7  .1176470=5,5 .117647[3|5]=5,7  //.117648=5,7  //.117647=5,5 //.117649=5,7  //117645=5,5 //1176[3/4]=5,5 1165=5,7// 1176=5,5 //.1178/6=5,7 // 1175=5,5 //118=5,7 //117=5,5 //         //24.113/114/115=5,5//24.11=,5   //24.12=5,7 //24.16,14=5,7 //24.18=5.7//24.20=5,7 //24.1=5,5 //24.0=5,5  24.3 5,7 //24.25=5,7 // 24.2=5,7 //24.1=7,5  //25 5,7 //23.9=5,5 //24=5.5 //23.8=5.5 //23.3=err 5 //23            // 25  // 20    needs to be 22.5 or 7.5
1272 // above might need to be fractional?
1273 
1274 
1275 // 5Mhz / 10 = 500Khz    every 10 cpu cycles
1276 // 5Mhz /4   = 1.25Mhz   every  4 cpu cycles
1277 //
1278 #define VIACLK_TO_CPUCLK(X) ( ((floppy_ram[0x18]&96)==32) ? ((X)*(XTIMER)(LISA2ECLKFACTOR)) :((X)*(XTIMER)(LISA1ECLKFACTOR)))
1279 #define CPUCLK_TO_VIACLK(X) ( ((floppy_ram[0x18]&96)==32) ? ((X)/(XTIMER)(LISA2ECLKFACTOR)) :((X)/(XTIMER)(LISA1ECLKFACTOR)))
1280 
1281 
1282 // How many microseconds should lisaem sleep between emulation cycles.  This allows us to slow down the emulator
1283 // so that we can either get an acurate 5MHz clock, or be nice to the host OS.  This is implemented using poll with
1284 // a null handle as per poll's man page.  The value of microsleep_tix is global so that it may be adjusted elsewhere
1285 // in the code on the fly, as needed, perhaps it can be raised during I/O and idle mouse times.
1286 #ifdef DEBUG
1287 GLOBAL(int,microsleep_tix,0);
1288 #else
1289 GLOBAL(int,microsleep_tix,0);
1290 #endif
1291 
1292 // Scotty: Captain, we din' can reference it!
1293 // Kirk:   Analysis, Mr. Spock?
1294 // Spock:  Captain, it doesn't appear in the symbol table.
1295 // Kirk:   Then it's of external origin?
1296 // Spock:  Affirmative.
1297 // Kirk:   Mr. Sulu, go to pass two.
1298 // Sulu:   Aye aye, sir, going to pass two.
1299 
1300 
1301 
1302 /*
1303  * But wait, there is mad to my method and reason!  Read on gentle hacker.  Here's the explanation.
1304  *
1305  * For sooth, thou shalt learneth...
1306  *
1307  * You see, C depends on variable and prototype declarations to know whether they be externed, to know the proper number and
1308  * types of parameters and return type of said functions.  If it does not know the proper types, it will warn, however, if the
1309  * prototype for a given function is incorrect, you can expect a maladjusted stack, and bad things will certainly happen.
1310  *
1311  * Having header files solves this - except it introduces another snag.  Should your header file delcare parameters differently
1312  * (aka incorrectly) than your .c file, you can expect warnings neither from gcc, nor from ld, which cannot know that this has
1313  * occured.
1314  *
1315  * One way to test for this is to include your header file into your C file, *BUT* this will not work from extern'ed functions.
1316  * gcc will complain about "conflicting types for...." and "previous declaration..." indicating a bug.  But you cannot use this
1317  * to self check your headers... so what to do? what to do?
1318  *
1319  * Another way is to use a program that automatically builds header files, but, meh - why would you want to have all your fn's
1320  * in a header file?
1321  *
1322  * Well, if you like Macro's, (and what good C programmer doesn't?) then the answer is clear.  Define a Macro to resolve as
1323  * extern when it should, and null when it shouldn't.  Easy as pie.
1324  *
1325  * I ran across this issue when I added several parameters to a function that I forgot was used externally in other code.
1326  * The program compiled just fine, and crashed beautifully.  gdb was able to solve the issue, but I thought I'd kill it for
1327  * good.  Always, always, always, program defensively.
1328  *
1329  *
1330  *
1331  */
1332 
1333 #ifdef EXTERNX
1334 #undef EXTERNX
1335 #endif
1336 #ifndef IN_FLIFLO_QUEUE_C
1337  #define EXTERNX extern
1338 #else
1339  #define EXTERNX ;
1340 #endif
1341 EXTERNX int fliflo_buff_is_full(FLIFLO_QUEUE_t *b);
1342 EXTERNX int fliflo_buff_has_data(FLIFLO_QUEUE_t *b);
1343 EXTERNX int fliflo_buff_is_empty(FLIFLO_QUEUE_t *b);
1344 EXTERNX uint32 fliflo_buff_size(FLIFLO_QUEUE_t *b);
1345 EXTERNX uint32 fliflo_buff_percent_full(FLIFLO_QUEUE_t *b);
1346 EXTERNX int fliflo_buff_add(FLIFLO_QUEUE_t *b,uint8 data);
1347 EXTERNX uint8 fliflo_buff_pop(FLIFLO_QUEUE_t *b);
1348 EXTERNX uint8 fliflo_buff_get(FLIFLO_QUEUE_t *b);
1349 EXTERNX uint8 fliflo_buff_peek(FLIFLO_QUEUE_t *b);
1350 EXTERNX uint8 fliflo_buff_peek_end(FLIFLO_QUEUE_t *b);
1351 EXTERNX int fliflo_buff_create(FLIFLO_QUEUE_t *b, uint32 size);
1352 EXTERNX void fliflo_buff_destroy(FLIFLO_QUEUE_t *b);
1353 
1354 //extern void alertlog(char *alert);
1355 
1356 //#endif
1357 
1358 #define UI_LOG( level, fmt, args... ) {fprintf(buglog,"%s:%s:%d: ",__FILE__,__FUNCTION__,__LINE__); fprintf(buglog,  fmt , ## args); fprintf(buglog,"\n");fflush(buglog);}
1359 
1360 DECLARE(char,_msg_alert[1024]);
1361 DECLARE(char,_msg_alert2[1024]);
1362 
1363 
1364 #ifdef DEBUG
1365 
1366    extern void dumpmmu(uint8 c, FILE *out);
1367    extern void dumpmmupage(uint8 c, uint8 i, FILE *out);
1368 
1369 
1370 
1371 
1372   /*define check_iib() {my_check_iib(__FILE__,__FUNCTION__,__LINE__);}
1373      ifndef IN_CPU68K_C
1374      extern void my_check_iib(char *filename, char *function, long line);
1375      endif
1376   */
1377    #define check_iib() {;}
1378 
1379 
1380 // do full iib sanity check
1381 //#define DEBUG_LOG( level, fmt, args... ) { if ( level <= DEBUGLEVEL ) {fprintf(buglog,"%s:%s:%d: ",__FILE__,__FUNCTION__,__LINE__); fprintf(buglog,  fmt , ## args); fprintf(buglog,"\n"); fflush(buglog);if (do_iib_check) my_check_iib(__FILE__,__FUNCTION__,__LINE__);} }
1382 // don't do iib sanity check - speed things up
1383 
1384    #define DEBUG_LOG( level, fmt, args... ) { if ( (level <= DEBUGLEVEL) && debug_log_enabled)                        \
1385    {fprintf(buglog,"%s:%s:%d:",__FILE__,__FUNCTION__,__LINE__); fprintf(buglog,  fmt , ## args);                      \
1386     fprintf(buglog,"\n"); fflush(buglog); fflush(stdout);}                                                            }
1387 
1388 /*
1389      if (mmu_trans!=mmu_trans_all[context] || mmu!=mmu_all[context] || (start && context))
1390         { fprintf(buglog,"\n\n\nBUGCHK: context:%d start:%d seg1/2:%d/%d\n",context,start,segment1,segment2);
1391           fprintf(buglog,"BUGCHK: mmu_trans=%p [0]=%p [1]=%p [2]=%p [3]=%p [4]=%p\n", mmu_trans,mmu_trans_all[0],mmu_trans_all[1],mmu_trans_all[2],mmu_trans_all[3],mmu_trans_all[4]);
1392           fprintf(buglog,"BUGCHK: mmu=%p mmu_all[0]=%p [1]=%p [2]=%p [3]=%p [4]=%p\n\n\n",mmu,mmu_all[0],mmu_all[1],mmu_all[2],mmu_all[3],mmu_all[4]);
1393           _EXIT(1); }
1394      }
1395 
1396 fprintf(buglog,"context:%d videoram @ %08x\n",context,videolatchaddress); fflush(buglog);
1397 */
1398 #else
1399   #define DEBUG_LOG( level, fmt, args... )  {}
1400   #define check_iib() {}
1401 #endif
1402 
1403 // this is needed because gdb doesn't tell you where your program quit from, just gives you the octal version of the exit
1404 // parameter which is chopped to 9 bits for some oddball reason.
1405 #define EXIT(x,cmd,fmt,args...) { char msg[1024], msg2[1024];                                                                              \
1406                     snprintf(msg2,1024, fmt, ## args);                                                                                     \
1407 	                snprintf(msg,1024,"We've encountered a problem!\n%s\nStopped at %s:%s:%d with code :%d",                               \
1408 	                       msg2,                                                                                                           \
1409 	                       __FILE__,__FUNCTION__,__LINE__,x);                                                                              \
1410 				    if (!cmd) strncat(msg,"\nLisaEM will now quit.",1024);                                                                 \
1411                     fprintf(buglog,"%s:%s:%d: exit with code :%d\n%s\n",__FILE__,__FUNCTION__,__LINE__,x,msg2);                            \
1412 					messagebox(msg,"Emulation aborted!");                                                                                  \
1413 					fflush(buglog); if (!cmd) exit(x); else return;                                                                        \
1414                     }
1415 
1416 #define EXITR(x,cmd,fmt,args...) { char msg[1024], msg2[1024];                                                                             \
1417                     snprintf(msg2, 1024, fmt, ## args);                                                                                    \
1418 	                snprintf(msg,1024,"I'm sorry, the emulation has aborted due to a fatal error\n%s\nStopped at %s:%s:%d with code :%d",  \
1419 	                       msg2,                                                                                                           \
1420 	                       __FILE__,__FUNCTION__,__LINE__,x);                                                                              \
1421 				    if (!cmd) strncat(msg,"\nLisaEM will now quit.",1024);                                                                 \
1422                     fprintf(buglog,"%s:%s:%d: exit with code :%d\n%s\n",__FILE__,__FUNCTION__,__LINE__,x,msg2);                            \
1423 					messagebox(msg,"Emulation aborted!");                                                                                  \
1424 					fflush(buglog); if (!cmd) exit(x); else return cmd-1;                                                                  \
1425                     }
1426 
1427 
1428 
1429 
1430 
1431    #define ALERT_LOG( level, fmt, args... ) { if ( (level <= DEBUGLEVEL) )                                            \
1432    {                                                                                                                  \
1433     fprintf(stderr,"%s:%s:%d:",__FILE__,__FUNCTION__,__LINE__); fprintf(stderr,  fmt , ## args);                      \
1434     fprintf(stderr,"\n"); fflush(stderr);                                                                             \
1435     if (buglog && buglog!=stderr)  {                                                                                  \
1436     fprintf(buglog,"%s:%s:%d:",__FILE__,__FUNCTION__,__LINE__); fprintf(buglog,  fmt , ## args);                      \
1437     fprintf(buglog,"\n"); fflush(buglog);  }                                                                          \
1438    }                                        }
1439 
1440 
1441 ///////// Memory access macros//////////////////////////////////////////////////////////////////////////////////////////////////
1442 
1443 
1444 
1445 
1446 /******* Memory/MMU related defines, protos and vars *******/
1447 
1448 
1449 // Context Selectors
1450 #define CXASEL   (1+( segment1|segment2)                 )
1451 #define CXSEL    (1+((segment1|segment2)&(lastsflag?0:3)))
1452 #define CXSASEL ((1+((segment1|segment2)&(lastsflag?0:3))) & (start?0:7) )
1453 
1454 
1455 // mmu cache coherency
1456 #define SET_MMU_DIRTY(x)  {mmudirty=(x); mmudirty_all[CXASEL]=mmudirty;}
1457 #define GET_MMU_DIRTY(x)  {mmudirty=     mmudirty_all[CXASEL];}
1458 #define GET_MMUS_DIRTY(x) {mmudirty=     mmudirty_all[CXSASEL];}
1459 
1460 // are we trying to access a changed MMU block?  If so rebuild it!
1461 #define CHECK_DIRTY_MMU(addr)  {if (context && (mmu[((addr) & 0x00fe0000)>>17].changed)) {SET_MMU_DIRTY(0xdec0de); mmuflush(0);}}
1462 
1463 // filter out segment # - i.e. keep page+offset
1464 #define   MMUXXFILT 0x0001ffff
1465 
1466 //#define SEGCHOP 1  /// bad - causes POST to get stuck
1467 
1468 #ifdef SEGCHOP
1469 #define MMU_X_FIL 0x0001ffff
1470 #else
1471 #define MMU_X_FIL 0x00ffffff
1472 #endif
1473 
1474 #define MMUSEGFILT 0x00fe0000
1475 #define MMUEPAGEFL 0x00fffe00
1476 //#define TWOMEGMLIM 0x001fffff
1477 
1478 GLOBAL(uint32,TWOMEGMLIM,0x001fffff);
1479 
1480 
1481 
1482 
1483 
1484 
1485 
1486 
1487 #ifndef IN_REG68K_C  /////////////////////////////////////////////////////////////////////////////////////////////////////////
1488 // __CYGWIN__ wrapper added by Ray Arachelian for LisaEm to prevent crashes in reg68k_ext exec
1489 #ifdef __CYGWIN__
1490  uint32 reg68k_pc;
1491  uint32 *reg68k_regs;
1492  t_sr reg68k_sr;
1493 #else
1494 //#if (!(defined(PROCESSOR_ARM) || defined(PROCESSOR_SPARC) || defined(PROCESSOR_INTEL) ))
1495 #if (!(defined(PROCESSOR_ARM) || defined(PROCESSOR_SPARC)  ))      //20051125
1496 uint32 reg68k_pc;
1497 uint32 *reg68k_regs;
1498 t_sr reg68k_sr;
1499 #endif
1500 #endif
1501 
1502 #else
1503 
1504 
1505 #ifdef __CYGWIN__
1506  extern uint32 reg68k_pc;
1507  extern uint32 *reg68k_regs;
1508  extern t_sr reg68k_sr;
1509 #else
1510 #if (!(defined(PROCESSOR_ARM) || defined(PROCESSOR_SPARC) || defined(PROCESSOR_INTEL) ))
1511  extern uint32 reg68k_pc;
1512  extern uint32 *reg68k_regs;
1513  extern t_sr reg68k_sr;
1514 #endif
1515 #endif
1516 
1517 
1518 #endif
1519 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1520 
1521 
1522 
1523 DECLARE(viatype,via[9]);
1524 GLOBAL(uint8,via_running,0); // If any VIA has a runing timer/SHIFTREG, then this is set (using bitmap of vianumber)
1525 
1526 extern uint32 pc24;
1527 // Used for Exception processing in Address/BUS errors
1528 extern uint16 InstructionRegister;
1529 extern uint8  CPU_function_code;
1530 extern uint8  CPU_READ_MODE;
1531 
1532 
1533 extern void contrastchange(void);
1534 
1535 extern uint8 get_next_timer_id(void);
1536 
1537 extern void cops_reset(void);
1538 extern void disable_vidram(void);
1539 extern void enable_vidram(void);
1540 extern uint8 via1_ira(uint8 regnum);
1541 extern void via1_ora(uint8 data,uint8 regnum);
1542 extern void print_pc_and_regs(char *text);
1543 
1544 extern uint8 viaX_ira(viatype *V,uint8 regnum);
1545 extern uint8 viaX_irb(viatype *V);
1546 extern void  viaX_ora(viatype *V, uint8 data, uint8 regnum);
1547 extern void  viaX_orb(viatype *V, uint8 data);
1548 
1549 extern void reset_via(int i);
1550 
1551 extern void set_crdy_line(void);
1552 extern void clr_crdy_line(void);
1553 extern int  is_crdy_line(void);
1554 extern void set_kb_data_ready(void) ;
1555 extern int is_vector_available(int avno);
1556 extern void lisa_external_nmi_vector(uint32 addr);
1557 extern void reg68k_internal_autovector(int avno);
1558 extern int get_address_mmu_rfn_type(uint32 addr);
1559 extern void reg68k_sanity_check_bitorder(void);
1560 
1561 extern char *mspace(lisa_mem_t fn);
1562 extern int  floppy_insert(char *Image);
1563 extern void apple_1(void);
1564 extern void apple_2(void);
1565 extern void apple_3(void);
1566 extern void apple_dot(void);
1567 extern void apple_dot_down(void);
1568 extern void apple_dot_up(void);
1569 extern void send_nmi_key(void);
1570 extern void presspowerswitch(void);
1571 
1572 
1573 extern void shift_option_0(void);
1574 extern void shift_option_4(void);
1575 extern void shift_option_7(void);
1576 
1577 extern void add_mouse_event(int16 x, int16 y, int8 button);
1578 
1579 extern void mmuflush(uint16 opts);
1580 extern lisa_mem_t rmmuslr2fn(uint16 slr, uint32 a9);
1581 extern t_ipc_table *get_ipct(void);
1582 extern void checkcontext(uint8 c, char *text);
1583 extern void cpu68k_printipc(t_ipc * ipc);
1584 #ifdef DEBUG
1585   extern void dump_scc(void);
1586 #endif
1587 extern char *printslr(char *x, long size, uint16 slr);
1588 extern lisa_mem_t rmmuslr2fn(uint16 slr, uint32 a9);
1589 extern void get_slr_page_range(int cx,int seg, int16 *pagestart, int16 *pageend, lisa_mem_t *rfn, lisa_mem_t *wfn);
1590 extern lisa_mem_t rmmuslr2fn(uint16 slr, uint32 a9);
1591 
1592 
1593 
1594 extern void dumpram(char *reason);
1595 extern void    dumpvia(void);
1596 extern void fdumpvia1(FILE *out);
1597 extern void fdumpvia2(FILE *out);
1598 extern void fliflo_dump(FLIFLO_QUEUE_t *b,char *s);
1599 
1600 
1601 #ifdef DEBUG
1602 extern char *slrname(uint16 slr);
1603 #endif
1604 
1605 #ifdef DEBUG
1606 extern void validate_mmu_segments(char *from);
1607 #endif
1608 
1609 
1610 
1611 #ifdef EXTERNX
1612 #undef EXTERNX
1613 #endif
1614 #ifndef IN_ROM_C
1615  #define EXTERNX extern
1616 #else
1617  #define EXTERNX ;
1618 #endif
1619 EXTERNX int has_xl_screenmod(void);
1620 EXTERNX int16 read_dtc_rom(  char *filename, uint8 *ROM);
1621 EXTERNX int16 read_split_rom(char *filename, uint8 *ROMMX);
1622 EXTERNX int16 read_rom(      char *filename, uint8 *ROMMX);
1623 EXTERNX uint8 *decode_lisa_icon(uint8 *icon);
1624 EXTERNX int read_parallel_card_rom(char *filename);
1625 
1626 
1627 
1628 
1629 // not likely that these are needed, but could be useful elsewhere:
1630 EXTERNX uint8 ishex(char c);
1631 EXTERNX uint8 gethex(char c);
1632 EXTERNX uint8 brol(uint8 outdata, uint8 loop);
1633 EXTERNX uint16 wrol(uint16 outdata, uint8 loop);
1634 EXTERNX uint32 lrol(uint32 outdata, uint8 loop);
1635 
1636 
1637 
1638 #ifdef EXTERNX
1639 #undef EXTERNX
1640 #endif
1641 #ifndef IN_MMU_C
1642  #define EXTERNX extern
1643 #else
1644  #define EXTERNX ;
1645 #endif
1646 EXTERNX void init_lisa_mmu(void);
1647 EXTERNX void checkcontext(uint8 c, char *text);
1648 
1649 #ifdef EXTERNX
1650 #undef EXTERNX
1651 #endif
1652 #ifndef IN_UI_LOG_C
1653  #define EXTERNX extern
1654 #else
1655  #define EXTERNX ;
1656 #endif
1657 EXTERNX void ui_err(const char *text, ...);
1658 EXTERNX void ui_error(const char *text, ...);
1659 EXTERNX void ui_log(unsigned int loglevel, const char *text, ...);
1660 EXTERNX void ui_log_verbose(const char *text, ...);
1661 EXTERNX void ui_log_request(const char *text, ...);
1662 EXTERNX void ui_log_critical(const char *text, ...);
1663 EXTERNX void ui_log_debug3(const char *text, ...);
1664 EXTERNX void ui_log_debug2(const char *text, ...);
1665 EXTERNX void ui_log_debug1(const char *text, ...);
1666 EXTERNX void ui_log_user(const char *text, ...);
1667 EXTERNX void ui_log_normal(const char *text, ...);
1668 
1669 
1670 #ifdef EXTERNX
1671 #undef EXTERNX
1672 #endif
1673 #ifndef  IN_VIA6522_C
1674  #define EXTERNX extern
1675 #else
1676  #define EXTERNX ;
1677 #endif
1678 EXTERNX void all_vias_run(void);
1679 EXTERNX void init_vias(void);
1680 EXTERNX void get_next_timer_event(void);
1681 EXTERNX void check_current_timer_irq(void);
1682 EXTERNX uint8 next_timer_id(void);
1683 EXTERNX void VIAProfileLoop(int vianum, ProFileType *P, int event);
1684 
1685 
1686 
1687 
1688 
1689 
1690 #ifndef IN_IRQ_C
1691 extern int8 IRQRingBufferAdd(uint8 irql, uint32 address);
1692 extern uint8 IRQRingGet(void);
1693 extern void init_IRQ(void);
1694 #endif
1695 
1696 
1697 
1698 
1699 
1700 
1701 
1702 #ifndef IN_COPS_C
1703 extern void cops_keyboard_id(void);
1704 extern void set_keyboard_id(int32);
1705 extern void init_cops(void);
1706 #endif
1707 
1708 #ifndef IN_FLOPPY_C
1709 extern void floppy_go6504(void);
1710 #endif
1711 
1712 #ifndef IN_PROFILE_C
1713 extern void ProfileLoop(ProFileType *P, int event);
1714 extern void ProfileReset(ProFileType *P);
1715 extern void ProfileResetOff(ProFileType *P);
1716 extern void get_profile_spare_table(ProFileType *P);
1717 
1718 #endif
1719 
1720 #define PROLOOP_EV_IRB 0                   // event=0 <- Read from IRB
1721 #define PROLOOP_EV_IRA 1                   // event=1 <- Read from IRA
1722 #define PROLOOP_EV_ORA 2                   // event=2 <- write to ORA
1723 #define PROLOOP_EV_ORB 3                   // event=3 <- write to ORB
1724 #define PROLOOP_EV_NUL 4                   // event=4 <- null event - called occasionally by event handling to allow timeouts
1725 
1726 
1727 
1728 /****** Video ***********/
1729 
1730 GLOBAL(uint8,bitdepth,0);
1731 
1732 GLOBAL(uint8,softmemerror,0);
1733 GLOBAL(uint8,harderror,0);
1734 GLOBAL(uint8,videoirq,0);
1735 GLOBAL(uint8,bustimeout,0);
1736 GLOBAL(uint8,videobit,0);
1737 GLOBAL(uint8,serialnumshiftcount,0);
1738 GLOBAL(uint8,serialnumshift,0);
1739 DECLARE(uint8,serialnum[8]);
1740 DECLARE(uint8,serialnum240[32]);
1741 
1742 #define MAXSOUNDS 10
1743 
1744 GLOBAL(int,SoundLastOne,5);
1745 DECLARE(char,*SoundBuffer[MAXSOUNDS]);
1746 DECLARE(uint32,SoundBufSize[MAXSOUNDS]);
1747 
1748 GLOBAL(int,z8530_last_irq_status_bits,0);
1749 DECLARE(char,*scc_a_port);  DECLARE(char,scc_a_OPTIONS[1024]);
1750 DECLARE(char,*scc_b_port);  DECLARE(char,scc_b_OPTIONS[1024]);
1751 DECLARE(int,scc_a_telnet_port);
1752 DECLARE(int,scc_b_telnet_port);
1753 
1754 
1755 GLOBAL(int,scc_a_IW,-1);
1756 GLOBAL(int,scc_b_IW,-1);
1757 
1758 GLOBAL(uint8,serial_a,SCC_NOTHING);
1759 GLOBAL(uint8,serial_b,SCC_NOTHING);
1760 
1761 GLOBAL(FILE,*scc_a_port_F,NULL);
1762 GLOBAL(FILE,*scc_b_port_F,NULL);
1763 
1764 // USed by memory diag tests
1765 GLOBAL(uint8,*mem_parity_bits1,NULL);
1766 GLOBAL(uint8,*mem_parity_bits2,NULL);
1767 GLOBAL(uint32,last_bad_parity_adr,0);
1768 
1769 GLOBAL(int,scc_running,0);
1770 
1771 
1772 
1773 extern void sound_fork(void);
1774 extern void sound_play(uint16 freq);
1775 extern void sound_off(void);
1776 
1777 //DECLARE(scc_func_t, scc_fn[2] );
1778 
1779 //  5 sets of mmu registers, each of 128 segments.
1780 //  (4 are real lisa mmu contexts, added an extra for easier START mode translation)
1781 DECLARE(mmu_t,mmu_all[5][128]);
1782 
1783 // *mmu is in current context. i.e. mmu = mmu_all[4] sets context[4] (START mode).  I do this so that I
1784 
1785 // don't have to dereference the array every single memory access as that would add an unnecessary expense.
1786 // i.e. mmu_all[SEGMENT1+SEGMENT2|SETUP][(address>>17)&0x7f] is very expensive, but
1787 // mmu[(address>>17)&0x7f] is far less expensive.
1788 GLOBAL(mmu_t,*mmu,NULL);
1789 
1790 DECLARE(mmu_trans_t,mmu_trans_all[5][32768]);
1791 
1792 /* sadly if I used enums for lisa_mem_t.readfn/.writefn gcc would allocate 4 bytes for each so the total
1793    or this would be 12 bytes x 32768 pages/context x 5 = 1.85MB of ram for this table.  Instead I used
1794    defines and uint8's for lisa_mem_t, so this should be 1.25M depending on how they're packed    */
1795 
1796 GLOBAL(mmu_trans_t,*mmu_trans,mmu_trans_all[0]); // ptr to current context, so I don't have to do expensive double array deref.
1797 // i.e. mmu_trans=mmu_trans_all[0] is context 0.
1798 
1799 // Refs for Generator's mem68k.c
1800 // These are initialized by init_lisa_mmu.
1801 
1802 // temp vars to play with, don't include these in vars.c
1803 DECLARE(mmu_t,m); // temp variable to play with
1804 DECLARE(mmu_trans_t,mt); // mmu translation - temporary var
1805 DECLARE(mmu_trans_t,*lastvideo_mt);
1806 
1807 // result of mmu logical->physical translation
1808 GLOBAL(int32,physaddr,0);
1809 
1810 // Lisa I/O Space types and other types of accesses.
1811 
1812 // These used to be enums, but enums in gcc are 32 bits long, and unless you want to pass
1813 // the -fshort-enums which may break other things, I'd rather just set them up as #DEFINEs and
1814 // be done with it.  Could have left them as enums, but that would bloat the mmu structures I use
1815 // as mmu_trans_all would grow huge.  consts can't be used to set arrays, so #DEFINES they'll have
1816 // to be.
1817 
1818 
1819 // Note, these are the letters Ox not zero x, so they're perfectly legal symbol names
1820 // It makes for easier reading of addresses when reading the source. :)
1821 
1822 // Regular (non-special) I/O address space.  Subject to MMU mapping.
1823 
1824 #define OxERROR           0     /* This should never be used - it indicates a bug in our code */
1825 #define OxUnused	 	  1     /* unused I/O space address (only used in I/O space map) */
1826 #define Ox0000_slot1	  2
1827 #define Ox2000_slot1	  3
1828 #define Ox4000_slot2	  4
1829 #define Ox6000_slot2	  5
1830 #define Ox8000_slot3	  6
1831 #define Oxa000_slot3	  7
1832 #define Oxc000_flopmem	  8
1833 #define Oxd000_ff_space   9
1834 #define Oxd200_sccz8530	 10
1835 #define Oxd800_par_via2	 11
1836 #define Oxdc00_cops_via1 12
1837 #define Oxe000_latches	 13
1838 #define Oxe800_videlatch 14
1839 #define Oxf000_memerror  15
1840 #define Oxf800_statreg	 16
1841 
1842 // Real Lisa memory
1843 #define ram		         17     /* Plain old RAM, or stack access.                                   */
1844 #define vidram           18     /* same as ram, but flag on write that screen needs refreshing       */
1845 #define ro_violn         19     /* Read only violation - what trap should I call? See schematic      */
1846 #define bad_page         20     /* Bad page or unallocated segment - what trap here?                 */
1847 
1848 // Special I/O space
1849 #define sio_rom          21     /* access to ROM via sio mode                                        */
1850 #define sio_mrg          22     /* mmu register being accessed.  Which depends on bit 3 of addr      */
1851 
1852 #define sio_mmu          23     /* access ram or other spaces via the mmu (bit14=1 in address)       */
1853 
1854 
1855 // Disparcher to I/O space (dispatcher to the Ox????_ fn's list above)
1856 #define io               24     /* This is a dispatcher for I/O space when we don't know the address */
1857 
1858 #define Oxd400_amd9512   25
1859 
1860 #define OxVoid           26     /* Reserved mem fn's that do nothing, and return junk                */
1861 
1862 // 27-31 unused.
1863 
1864 #define MAX_LISA_MFN     27     /* The last Lisa Memory function type we have                        */
1865 
1866 
1867 #define DEBUG_MFN_TRACE  32     // trap/trace fn's.
1868 
1869 
1870 // I/O Address Maps.  These are used to initialize the fn pointers on the OUTPUT side of the mmu.
1871 GLOBAL(char,*memspaces[],
1872 {
1873 	"00-OxERROR",
1874 	"01-OxUnused",
1875 	"02-Ox0000_slot1",
1876 	"03-Ox2000_slot1",
1877 	"04-Ox4000_slot2",
1878 	"05-Ox6000_slot2",
1879 	"06-Ox8000_slot3",
1880 	"07-Oxa000_slot3",
1881 	"08-Oxc000_flopmem",
1882     "09-0xd000_ff_space",
1883 	"10-Oxd200_sccz8530",
1884 	"11-Oxd800_par_via2",
1885 	"12-Oxdc00_cops_via1",
1886 	"13-Oxe000_latches",
1887 	"14-Oxe800_videlatch",
1888 	"15-Oxf000_memerror",
1889 	"16-Oxf800_statreg",
1890 	"17-ram",
1891 	"18-vidram",
1892 	"19-ro_violn",
1893 	"20-bad_page",
1894 	"21-sio_rom",
1895 	"22-sio_mrg",
1896 	"23-sio_mmu",
1897     "24-io",
1898     "25-Oxd400_amd9512",
1899     "26-OxVoid"
1900 });
1901 
1902 
1903 ACGLOBAL(lisa_mem_t,io_map[],
1904 {                  // +0             // +1              // +2              //+3
1905 /*                 +000              +200                +400              +600 */
1906 /* 0xfc0000 : */   Ox0000_slot1,    Ox0000_slot1,    Ox0000_slot1,    Ox0000_slot1,     //   0
1907 /* 0xfc0800 : */   Ox0000_slot1,    Ox0000_slot1,    Ox0000_slot1,    Ox0000_slot1,     //   4
1908 /* 0xfc1000 : */   Ox0000_slot1,    Ox0000_slot1,    Ox0000_slot1,    Ox0000_slot1,     //   8
1909 /* 0xfc1800 : */   Ox0000_slot1,    Ox0000_slot1,    Ox0000_slot1,    Ox0000_slot1,     //  12
1910 /* 0xfc2000 : */   Ox2000_slot1,    Ox2000_slot1,    Ox2000_slot1,    Ox2000_slot1,     //  16
1911 
1912 /* 0xfc2800 : */   Ox2000_slot1,    Ox2000_slot1,    Ox2000_slot1,    Ox2000_slot1,     //  20
1913 /* 0xfc3000 : */   Ox2000_slot1,    Ox2000_slot1,    Ox2000_slot1,    Ox2000_slot1,     //  24
1914 /* 0xfc3800 : */   Ox2000_slot1,    Ox2000_slot1,    Ox2000_slot1,    Ox2000_slot1,     //  28
1915 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1916 /* 0xfc4000 : */   Ox4000_slot2,    Ox4000_slot2,    Ox4000_slot2,    Ox4000_slot2,     //  32
1917 /* 0xfc4800 : */   Ox4000_slot2,    Ox4000_slot2,    Ox4000_slot2,    Ox4000_slot2,     //  36
1918 
1919 /* 0xfc5000 : */   Ox4000_slot2,    Ox4000_slot2,    Ox4000_slot2,    Ox4000_slot2,     //  40
1920 /* 0xfc5800 : */   Ox4000_slot2,    Ox4000_slot2,    Ox4000_slot2,    Ox4000_slot2,     //  44
1921 /* 0xfc6000 : */   Ox6000_slot2,    Ox6000_slot2,    Ox6000_slot2,    Ox6000_slot2,     //  48
1922 /* 0xfc6800 : */   Ox6000_slot2,    Ox6000_slot2,    Ox6000_slot2,    Ox6000_slot2,     //  52
1923 /* 0xfc7000 : */   Ox6000_slot2,    Ox6000_slot2,    Ox6000_slot2,    Ox6000_slot2,     //  56
1924 
1925 /* 0xfc7800 : */   Ox6000_slot2,    Ox6000_slot2,    Ox6000_slot2,    Ox6000_slot2,     //  60
1926 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1927 /* 0xfc8000 : */   Ox8000_slot3,    Ox8000_slot3,    Ox8000_slot3,    Ox8000_slot3,     //  74
1928 /* 0xfc8800 : */   Ox8000_slot3,    Ox8000_slot3,    Ox8000_slot3,    Ox8000_slot3,     //  78
1929 /* 0xfc9000 : */   Ox8000_slot3,    Ox8000_slot3,    Ox8000_slot3,    Ox8000_slot3,     //  82
1930 /* 0xfc9800 : */   Ox8000_slot3,    Ox8000_slot3,    Ox8000_slot3,    Ox8000_slot3,     //  86
1931 
1932 /* 0xfca000 : */   Oxa000_slot3,    Oxa000_slot3,    Oxa000_slot3,    Oxa000_slot3,     //  90
1933 /* 0xfca800 : */   Oxa000_slot3,    Oxa000_slot3,    Oxa000_slot3,    Oxa000_slot3,     //  94
1934 /* 0xfcb000 : */   Oxa000_slot3,    Oxa000_slot3,    Oxa000_slot3,    Oxa000_slot3,     //  98
1935 /* 0xfcb800 : */   Oxa000_slot3,    Oxa000_slot3,    Oxa000_slot3,    Oxa000_slot3,     // 102
1936 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1937 
1938 /* 0xfcc000 : */   Oxc000_flopmem,   Oxc000_flopmem,   Oxc000_flopmem,   Oxc000_flopmem,    // 106
1939 
1940 /* 0xfcc800 : */   Oxc000_flopmem,   Oxc000_flopmem,   Oxc000_flopmem,   Oxc000_flopmem,    // 110
1941 
1942 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1943 /* 0xfcd000 : */   Oxd000_ff_space,  Oxd200_sccz8530,  Oxd400_amd9512,   Oxd400_amd9512,    // 114
1944 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1945 /* 0xfcd800 : */   Oxd800_par_via2,  Oxd800_par_via2,  Oxdc00_cops_via1, Oxdc00_cops_via1,  // 118
1946 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1947 /* 0xfce000 : */   Oxe000_latches,   OxUnused,         OxUnused,         OxUnused,          // 122
1948 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1949 /* 0xfce800 : */   Oxe800_videlatch, Oxe800_videlatch, Oxe800_videlatch, Oxe800_videlatch,  // 126
1950 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1951 /* 0xfcf000 : */   Oxf000_memerror,  Oxf000_memerror,  Oxf000_memerror,  Oxf000_memerror,   // 130
1952 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1953 /* 0xfcf800 : */   Oxf800_statreg,   Oxf800_statreg,   Oxf800_statreg,   Oxf800_statreg     // 134
1954 /*                 +000              +200                +400              +600 */
1955 });
1956 
1957 
1958 
1959 ACGLOBAL(lisa_mem_t,sio_map[], // danger! this is for use on pre-MMU addresses - lop off the top 17 bits of the address
1960                       // as well as the low 9 bits ( address & 01fe00)
1961 {
1962 /*               000       200       400       600       800       a00        c00       e00 */
1963 /*000000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, // 8/line
1964 /*001000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1965 /*002000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1966 /*003000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1967 /*004000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1968 /*005000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1969 /*006000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1970 /*007000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1971 /*008000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1972 /*009000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1973 /*00a000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1974 /*00b000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1975 /*00c000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1976 /*00d000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1977 /*00e000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1978 /*00f000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1979 /*010000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1980 /*011000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1981 /*012000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1982 /*013000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1983 /*014000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1984 /*015000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1985 /*016000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1986 /*017000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1987 /*018000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1988 /*019000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1989 /*01a000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1990 /*01b000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1991 /*01c000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1992 /*01d000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1993 /*01e000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1994 /*01f000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu
1995 });
1996 
1997 
1998 GLOBAL(int,dispmemready,0);
1999 
2000 // Status register in memory.c
2001 //------------------------------------------------------------------------------
2002 #define STATREG_SOFTMEM_ERR 1           /* lisa doesn't use this bit */
2003 #define STATREG_HARDMEM_ERR 2           /* Parity error bit 1=not set, 0=set */
2004 #define STATREG_VERTICALRTC 4
2005 #define STATREG_BUSTIMEOUT  8
2006 #define STATREG_VIDEOBIT   16
2007 #define STATREG_CSYNC      32
2008 #define STATREG_HORIZONTAL 32
2009 #define STATREG_INVBIT     64           /* lisa doesn't use this bit normally */
2010 #define STATREG_UNUSEDBIT 128           /* lisa doesn't use this bit */
2011 
2012 
2013 
2014 
2015 
2016 
2017 #ifndef IN_CPU68K_C
2018 extern void free_ipct(t_ipc_table *ipct);
2019 #endif
2020 
2021 extern int diss68k_gettext(t_ipc * ipc, char *text);
2022 
2023 // memory function definitions.
2024 uint8 *(*mem68k_memptr[MAX_LISA_MFN]) (uint32 addr);
2025 uint8 (*mem68k_fetch_byte[MAX_LISA_MFN]) (uint32 addr);
2026 uint16 (*mem68k_fetch_word[MAX_LISA_MFN]) (uint32 addr);
2027 uint32 (*mem68k_fetch_long[MAX_LISA_MFN]) (uint32 addr);
2028 void (*mem68k_store_byte[MAX_LISA_MFN]) (uint32 addr, uint8 data);
2029 void (*mem68k_store_word[MAX_LISA_MFN]) (uint32 addr, uint16 data);
2030 void (*mem68k_store_long[MAX_LISA_MFN]) (uint32 addr, uint32 data);
2031 
2032 extern int get_exs2_pending_irq_empty(void);
2033 extern int get_exs1_pending_irq_empty(void);
2034 extern int get_exs0_pending_irq_empty(void);
2035 
2036 extern int get_exs0_pending_irq_2xpar(void);
2037 extern int get_exs1_pending_irq_2xpar(void);
2038 extern int get_exs2_pending_irq_2xpar(void);
2039 
2040 GLOBAL(int,(*get_exs0_pending_irq)(void),&get_exs0_pending_irq_empty);
2041 GLOBAL(int,(*get_exs1_pending_irq)(void),&get_exs1_pending_irq_empty);
2042 GLOBAL(int,(*get_exs2_pending_irq)(void),&get_exs2_pending_irq_empty);
2043 
2044 
2045 /* These macro "functions" are used by generator.  I use the above macro's in here just to avoid
2046    macro soup insanity.  Yeah, so they're probably not super duper optimized, but there's time
2047    for that once the emulator is debugged and working. -- RA */
2048 //define fetchaddr(addr) mem68k_memptr[RFN_MMU_TRANS](addr)
2049 //define fetchbyte(addr) mem68k_fetch_byte[RFN_MMU_TRANS](addr)
2050 //define fetchword(addr) mem68k_fetch_word[RFN_MMU_TRANS](addr)
2051 //define fetchlong(addr) mem68k_fetch_long[RFN_MMU_TRANS](addr)
2052 //define storebyte(addr,data) mem68k_store_byte[WFN_MMU_TRANS ](addr,data)
2053 //define storeword(addr,data) mem68k_store_word[WFN_MMU_TRANS ](addr,data)
2054 //define storelong(addr,data) mem68k_store_long[WFN_MMU_TRANS ](addr,data)
2055 
2056 extern void   lisa_ram_safe_setbyte(uint8 context, uint32 address,uint8 data);
2057 extern uint8  lisa_ram_safe_getbyte(uint8 context, uint32 address);
2058 extern uint16 lisa_ram_safe_getword(uint8 context, uint32 address);
2059 extern uint32 lisa_ram_safe_getlong(uint8 context, uint32 address);
2060 
2061 #ifndef INMEMORYDOTC
2062   extern void  *dmem68k_memptr(    char *file, char *function, int line,uint32 a);
2063   extern uint8  dmem68k_fetch_byte(char *file, char *function, int line,uint32 a );
2064   extern uint16 dmem68k_fetch_word(char *file, char *function, int line,uint32 a );
2065   extern uint32 dmem68k_fetch_long(char *file, char *function, int line,uint32 a );
2066   extern void   dmem68k_store_byte(char *file, char *function, int line,uint32 a, uint8  d);
2067   extern void   dmem68k_store_word(char *file, char *function, int line,uint32 a, uint16 d);
2068   extern void   dmem68k_store_long(char *file, char *function, int line,uint32 a, uint32 d);
2069 #endif
2070 
2071 
2072 #ifdef DEBUGMEMCALLS
2073 
2074   #define fetchaddr(a)   dmem68k_memptr(    (char *)__FILE__,(char *)__FUNCTION__,__LINE__,a)
2075   #define fetchbyte(a)   dmem68k_fetch_byte((char *)__FILE__,(char *)__FUNCTION__,__LINE__,(uint32)(a))
2076   #define fetchword(a)   dmem68k_fetch_word((char *)__FILE__,(char *)__FUNCTION__,__LINE__,(uint32)(a))
2077   #define fetchlong(a)   dmem68k_fetch_long((char *)__FILE__,(char *)__FUNCTION__,__LINE__,(uint32)(a))
2078   #define storebyte(a,d) dmem68k_store_byte((char *)__FILE__,(char *)__FUNCTION__,__LINE__,(uint32)(a),( uint8)(d))
2079   #define storeword(a,d) dmem68k_store_word((char *)__FILE__,(char *)__FUNCTION__,__LINE__,(uint32)(a),(uint16)(d))
2080   #define storelong(a,d) dmem68k_store_long((char *)__FILE__,(char *)__FUNCTION__,__LINE__,(uint32)(a),(uint32)(d))
2081 #else
2082 
2083   #define fetchaddr(a)   mem68k_memptr[    (mmu_trans[((a) & 0x00fffe00)>>9].readfn)](a)
2084   #define fetchbyte(a)   mem68k_fetch_byte[(mmu_trans[((a) & 0x00fffe00)>>9].readfn)](a)
2085   #define fetchword(a)   mem68k_fetch_word[(mmu_trans[((a) & 0x00fffe00)>>9].readfn)](a)
2086   #define fetchlong(a)   mem68k_fetch_long[(mmu_trans[((a) & 0x00fffe00)>>9].readfn)](a)
2087   #define storebyte(a,d) mem68k_store_byte[(mmu_trans[((a) & 0x00fffe00)>>9].writefn)]((a),( uint8)(d))
2088   #define storeword(a,d) mem68k_store_word[(mmu_trans[((a) & 0x00fffe00)>>9].writefn)]((a),(uint16)(d))
2089   #define storelong(a,d) mem68k_store_long[(mmu_trans[((a) & 0x00fffe00)>>9].writefn)]((a),(uint32)(d))
2090 #endif
2091 
2092 
2093 
2094 
2095 // As these are defined in memory.c, we cannot define them here as externs.  like duh!
2096 #ifndef INMEMORYDOTC
2097 // fn protos
2098 extern uint8  *lisa_mptr_OxERROR(uint32 addr);
2099 extern uint8  lisa_rb_OxERROR(uint32 addr);
2100 extern uint16 lisa_rw_OxERROR(uint32 addr);
2101 extern uint32 lisa_rl_OxERROR(uint32 addr);
2102 extern void   lisa_wb_OxERROR(uint32 addr, uint8 data);
2103 extern void   lisa_ww_OxERROR(uint32 addr, uint16 data);
2104 extern void   lisa_wl_OxERROR(uint32 addr, uint32 data);
2105 
2106 extern uint8  *lisa_mptr_OxUnused(uint32 addr);
2107 extern uint8  lisa_rb_OxUnused(uint32 addr);
2108 extern uint16 lisa_rw_OxUnused(uint32 addr);
2109 extern uint32 lisa_rl_OxUnused(uint32 addr);
2110 extern void   lisa_wb_OxUnused(uint32 addr, uint8 data);
2111 extern void   lisa_ww_OxUnused(uint32 addr, uint16 data);
2112 extern void   lisa_wl_OxUnused(uint32 addr, uint32 data);
2113 
2114 extern uint8  *lisa_mptr_Ox0000_slot1(uint32 addr);
2115 extern uint8  lisa_rb_Ox0000_slot1(uint32 addr);
2116 extern uint16 lisa_rw_Ox0000_slot1(uint32 addr);
2117 extern uint32 lisa_rl_Ox0000_slot1(uint32 addr);
2118 extern void   lisa_wb_Ox0000_slot1(uint32 addr, uint8 data);
2119 extern void   lisa_ww_Ox0000_slot1(uint32 addr, uint16 data);
2120 extern void   lisa_wl_Ox0000_slot1(uint32 addr, uint32 data);
2121 
2122 extern uint8  *lisa_mptr_Ox2000_slot1(uint32 addr);
2123 extern uint8  lisa_rb_Ox2000_slot1(uint32 addr);
2124 extern uint16 lisa_rw_Ox2000_slot1(uint32 addr);
2125 extern uint32 lisa_rl_Ox2000_slot1(uint32 addr);
2126 extern void   lisa_wb_Ox2000_slot1(uint32 addr, uint8 data);
2127 extern void   lisa_ww_Ox2000_slot1(uint32 addr, uint16 data);
2128 extern void   lisa_wl_Ox2000_slot1(uint32 addr, uint32 data);
2129 
2130 extern uint8  *lisa_mptr_Ox4000_slot2(uint32 addr);
2131 extern uint8  lisa_rb_Ox4000_slot2(uint32 addr);
2132 extern uint16 lisa_rw_Ox4000_slot2(uint32 addr);
2133 extern uint32 lisa_rl_Ox4000_slot2(uint32 addr);
2134 extern void   lisa_wb_Ox4000_slot2(uint32 addr, uint8 data);
2135 extern void   lisa_ww_Ox4000_slot2(uint32 addr, uint16 data);
2136 extern void   lisa_wl_Ox4000_slot2(uint32 addr, uint32 data);
2137 
2138 extern uint8  *lisa_mptr_Ox6000_slot2(uint32 addr);
2139 extern uint8  lisa_rb_Ox6000_slot2(uint32 addr);
2140 extern uint16 lisa_rw_Ox6000_slot2(uint32 addr);
2141 extern uint32 lisa_rl_Ox6000_slot2(uint32 addr);
2142 extern void   lisa_wb_Ox6000_slot2(uint32 addr, uint8 data);
2143 extern void   lisa_ww_Ox6000_slot2(uint32 addr, uint16 data);
2144 extern void   lisa_wl_Ox6000_slot2(uint32 addr, uint32 data);
2145 
2146 extern uint8  *lisa_mptr_Ox8000_slot3(uint32 addr);
2147 extern uint8  lisa_rb_Ox8000_slot3(uint32 addr);
2148 extern uint16 lisa_rw_Ox8000_slot3(uint32 addr);
2149 extern uint32 lisa_rl_Ox8000_slot3(uint32 addr);
2150 extern void   lisa_wb_Ox8000_slot3(uint32 addr, uint8 data);
2151 extern void   lisa_ww_Ox8000_slot3(uint32 addr, uint16 data);
2152 extern void   lisa_wl_Ox8000_slot3(uint32 addr, uint32 data);
2153 
2154 extern uint8  *lisa_mptr_Oxa000_slot3(uint32 addr);
2155 extern uint8  lisa_rb_Oxa000_slot3(uint32 addr);
2156 extern uint16 lisa_rw_Oxa000_slot3(uint32 addr);
2157 extern uint32 lisa_rl_Oxa000_slot3(uint32 addr);
2158 extern void   lisa_wb_Oxa000_slot3(uint32 addr, uint8 data);
2159 extern void   lisa_ww_Oxa000_slot3(uint32 addr, uint16 data);
2160 extern void   lisa_wl_Oxa000_slot3(uint32 addr, uint32 data);
2161 
2162 
2163 extern uint8 lisa_rb_ext_2par_via(viatype *V,uint32 addr);
2164 extern void  lisa_wb_ext_2par_via(viatype *V,uint32 addr, uint8 xvalue);
2165 
2166 extern uint8  *lisa_mptr_2x_parallel_l(uint32 addr);
2167 extern uint8  lisa_rb_2x_parallel_l(uint32 addr);
2168 extern uint16 lisa_rw_2x_parallel_l(uint32 addr);
2169 extern uint32 lisa_rl_2x_parallel_l(uint32 addr);
2170 extern void   lisa_wb_2x_parallel_l(uint32 addr, uint8 data);
2171 extern void   lisa_ww_2x_parallel_l(uint32 addr, uint16 data);
2172 extern void   lisa_wl_2x_parallel_l(uint32 addr, uint32 data);
2173 
2174 
2175 extern uint8  *lisa_mptr_2x_parallel_h(uint32 addr);
2176 extern uint8  lisa_rb_2x_parallel_h(uint32 addr);
2177 extern uint16 lisa_rw_2x_parallel_h(uint32 addr);
2178 extern uint32 lisa_rl_2x_parallel_h(uint32 addr);
2179 extern void   lisa_wb_2x_parallel_h(uint32 addr, uint8 data);
2180 extern void   lisa_ww_2x_parallel_h(uint32 addr, uint16 data);
2181 extern void   lisa_wl_2x_parallel_h(uint32 addr, uint32 data);
2182 
2183 
2184 extern uint8  *lisa_mptr_Oxc000_flopmem(uint32 addr);
2185 extern uint8  lisa_rb_Oxc000_flopmem(uint32 addr);
2186 extern uint16 lisa_rw_Oxc000_flopmem(uint32 addr);
2187 extern uint32 lisa_rl_Oxc000_flopmem(uint32 addr);
2188 extern void   lisa_wb_Oxc000_flopmem(uint32 addr, uint8 data);
2189 extern void   lisa_ww_Oxc000_flopmem(uint32 addr, uint16 data);
2190 extern void   lisa_wl_Oxc000_flopmem(uint32 addr, uint32 data);
2191 
2192 extern uint8  *lisa_mptr_Oxd200_sccz8530(uint32 addr);
2193 extern uint8  lisa_rb_Oxd200_sccz8530(uint32 addr);
2194 extern uint16 lisa_rw_Oxd200_sccz8530(uint32 addr);
2195 extern uint32 lisa_rl_Oxd200_sccz8530(uint32 addr);
2196 extern void   lisa_wb_Oxd200_sccz8530(uint32 addr, uint8 data);
2197 extern void   lisa_ww_Oxd200_sccz8530(uint32 addr, uint16 data);
2198 extern void   lisa_wl_Oxd200_sccz8530(uint32 addr, uint32 data);
2199 
2200 extern uint8  *lisa_mptr_Oxd800_par_via2(uint32 addr);
2201 extern uint8  lisa_rb_Oxd800_par_via2(uint32 addr);
2202 extern uint16 lisa_rw_Oxd800_par_via2(uint32 addr);
2203 extern uint32 lisa_rl_Oxd800_par_via2(uint32 addr);
2204 extern void   lisa_wb_Oxd800_par_via2(uint32 addr, uint8 data);
2205 extern void   lisa_ww_Oxd800_par_via2(uint32 addr, uint16 data);
2206 extern void   lisa_wl_Oxd800_par_via2(uint32 addr, uint32 data);
2207 
2208 extern uint8  *lisa_mptr_Oxdc00_cops_via1(uint32 addr);
2209 extern uint8  lisa_rb_Oxdc00_cops_via1(uint32 addr);
2210 extern uint16 lisa_rw_Oxdc00_cops_via1(uint32 addr);
2211 extern uint32 lisa_rl_Oxdc00_cops_via1(uint32 addr);
2212 extern void   lisa_wb_Oxdc00_cops_via1(uint32 addr, uint8 data);
2213 extern void   lisa_ww_Oxdc00_cops_via1(uint32 addr, uint16 data);
2214 extern void   lisa_wl_Oxdc00_cops_via1(uint32 addr, uint32 data);
2215 
2216 extern uint8  *lisa_mptr_Oxe000_latches(uint32 addr);
2217 extern uint8  lisa_rb_Oxe000_latches(uint32 addr);
2218 
2219 extern uint16 lisa_rw_Oxe000_latches(uint32 addr);
2220 extern uint32 lisa_rl_Oxe000_latches(uint32 addr);
2221 extern void   lisa_wb_Oxe000_latches(uint32 addr, uint8 data);
2222 extern void   lisa_ww_Oxe000_latches(uint32 addr, uint16 data);
2223 extern void   lisa_wl_Oxe000_latches(uint32 addr, uint32 data);
2224 
2225 extern uint8  *lisa_mptr_Oxe800_videlatch(uint32 addr);
2226 extern uint8  lisa_rb_Oxe800_videlatch(uint32 addr);
2227 extern uint16 lisa_rw_Oxe800_videlatch(uint32 addr);
2228 extern uint32 lisa_rl_Oxe800_videlatch(uint32 addr);
2229 extern void   lisa_wb_Oxe800_videlatch(uint32 addr, uint8 data);
2230 extern void   lisa_ww_Oxe800_videlatch(uint32 addr, uint16 data);
2231 extern void   lisa_wl_Oxe800_videlatch(uint32 addr, uint32 data);
2232 
2233 extern uint8  *lisa_mptr_Oxf000_memerror(uint32 addr);
2234 extern uint8  lisa_rb_Oxf000_memerror(uint32 addr);
2235 extern uint16 lisa_rw_Oxf000_memerror(uint32 addr);
2236 extern uint32 lisa_rl_Oxf000_memerror(uint32 addr);
2237 extern void   lisa_wb_Oxf000_memerror(uint32 addr, uint8 data);
2238 extern void   lisa_ww_Oxf000_memerror(uint32 addr, uint16 data);
2239 extern void   lisa_wl_Oxf000_memerror(uint32 addr, uint32 data);
2240 
2241 extern uint8  *lisa_mptr_Oxf800_statreg(uint32 addr);
2242 extern uint8  lisa_rb_Oxf800_statreg(uint32 addr);
2243 extern uint16 lisa_rw_Oxf800_statreg(uint32 addr);
2244 extern uint32 lisa_rl_Oxf800_statreg(uint32 addr);
2245 extern void   lisa_wb_Oxf800_statreg(uint32 addr, uint8 data);
2246 extern void   lisa_ww_Oxf800_statreg(uint32 addr, uint16 data);
2247 extern void   lisa_wl_Oxf800_statreg(uint32 addr, uint32 data);
2248 
2249 extern uint8  *lisa_mptr_ram(uint32 addr);
2250 extern uint8  lisa_rb_ram(uint32 addr);
2251 extern uint16 lisa_rw_ram(uint32 addr);
2252 extern uint32 lisa_rl_ram(uint32 addr);
2253 extern void   lisa_wb_ram(uint32 addr, uint8 data);
2254 extern void   lisa_ww_ram(uint32 addr, uint16 data);
2255 extern void   lisa_wl_ram(uint32 addr, uint32 data);
2256 
2257 extern uint8  *lisa_mptr_ro_violn(uint32 addr);
2258 extern uint8  lisa_rb_ro_violn(uint32 addr);
2259 extern uint16 lisa_rw_ro_violn(uint32 addr);
2260 extern uint32 lisa_rl_ro_violn(uint32 addr);
2261 extern void   lisa_wb_ro_violn(uint32 addr, uint8 data);
2262 extern void   lisa_ww_ro_violn(uint32 addr, uint16 data);
2263 extern void   lisa_wl_ro_violn(uint32 addr, uint32 data);
2264 
2265 extern uint8  *lisa_mptr_bad_page(uint32 addr);
2266 extern uint8  lisa_rb_bad_page(uint32 addr);
2267 extern uint16 lisa_rw_bad_page(uint32 addr);
2268 extern uint32 lisa_rl_bad_page(uint32 addr);
2269 extern void   lisa_wb_bad_page(uint32 addr, uint8 data);
2270 extern void   lisa_ww_bad_page(uint32 addr, uint16 data);
2271 extern void   lisa_wl_bad_page(uint32 addr, uint32 data);
2272 
2273 extern uint8  *lisa_mptr_sio_rom(uint32 addr);
2274 extern uint8  lisa_rb_sio_rom(uint32 addr);
2275 extern uint16 lisa_rw_sio_rom(uint32 addr);
2276 extern uint32 lisa_rl_sio_rom(uint32 addr);
2277 extern void   lisa_wb_sio_rom(uint32 addr, uint8 data);
2278 extern void   lisa_ww_sio_rom(uint32 addr, uint16 data);
2279 extern void   lisa_wl_sio_rom(uint32 addr, uint32 data);
2280 
2281 extern uint8  *lisa_mptr_sio_mrg(uint32 addr);
2282 extern uint8  lisa_rb_sio_mrg(uint32 addr);
2283 extern uint16 lisa_rw_sio_mrg(uint32 addr);
2284 extern uint32 lisa_rl_sio_mrg(uint32 addr);
2285 extern void   lisa_wb_sio_mrg(uint32 addr, uint8 data);
2286 extern void   lisa_ww_sio_mrg(uint32 addr, uint16 data);
2287 extern void   lisa_wl_sio_mrg(uint32 addr, uint32 data);
2288 
2289 extern uint8  *lisa_mptr_sio_mmu(uint32 addr);
2290 extern uint8  lisa_rb_sio_mmu(uint32 addr);
2291 extern uint16 lisa_rw_sio_mmu(uint32 addr);
2292 extern uint32 lisa_rl_sio_mmu(uint32 addr);
2293 extern void   lisa_wb_sio_mmu(uint32 addr, uint8 data);
2294 extern void   lisa_ww_sio_mmu(uint32 addr, uint16 data);
2295 extern void   lisa_wl_sio_mmu(uint32 addr, uint32 data);
2296 
2297 extern uint8  *lisa_mptr_vidram(uint32 addr);
2298 extern uint8  lisa_rb_vidram(uint32 addr);
2299 extern uint16 lisa_rw_vidram(uint32 addr);
2300 extern uint32 lisa_rl_vidram(uint32 addr);
2301 extern void   lisa_wb_vidram(uint32 addr, uint8 data);
2302 extern void   lisa_ww_vidram(uint32 addr, uint16 data);
2303 extern void   lisa_wl_vidram(uint32 addr, uint32 data);
2304 
2305 extern void   lisa_wb_xlvidram_parity(uint32 addr, uint8  data);
2306 extern void   lisa_ww_xlvidram_parity(uint32 addr, uint16 data);
2307 extern void   lisa_wl_xlvidram_parity(uint32 addr, uint32 data);
2308 extern void   lisa_wb_xlvidram(uint32 addr, uint8  data);
2309 extern void   lisa_ww_xlvidram(uint32 addr, uint16 data);
2310 extern void   lisa_wl_xlvidram(uint32 addr, uint32 data);
2311 
2312 
2313 
2314 extern uint8  *lisa_mptr_io(uint32 addr);
2315 extern uint8  lisa_rb_io(uint32 addr);
2316 extern uint16 lisa_rw_io(uint32 addr);
2317 extern uint32 lisa_rl_io(uint32 addr);
2318 extern void   lisa_wb_io(uint32 addr, uint8 data);
2319 extern void   lisa_ww_io(uint32 addr, uint16 data);
2320 extern void   lisa_wl_io(uint32 addr, uint32 data);
2321 
2322 extern uint8  lisa_rb_ram_parity(uint32 addr);
2323 extern uint16 lisa_rw_ram_parity(uint32 addr);
2324 extern uint32 lisa_rl_ram_parity(uint32 addr);
2325 extern void   lisa_wb_ram_parity(uint32 addr, uint8  data);
2326 extern void   lisa_ww_ram_parity(uint32 addr, uint16 data);
2327 extern void   lisa_wl_ram_parity(uint32 addr, uint32 data);
2328 
2329 extern uint8  lisa_rb_vidram_parity(uint32 addr);
2330 extern uint16 lisa_rw_vidram_parity(uint32 addr);
2331 extern uint32 lisa_rl_vidram_parity(uint32 addr);
2332 extern void   lisa_wb_vidram_parity(uint32 addr, uint8  data);
2333 extern void   lisa_ww_vidram_parity(uint32 addr, uint16 data);
2334 extern void   lisa_wl_vidram_parity(uint32 addr, uint32 data);
2335 
2336 extern uint8  *lisa_mptr_Oxd000_ff_space(uint32 addr);
2337 extern uint8   lisa_rb_Oxd000_ff_space(uint32 addr);
2338 extern uint16  lisa_rw_Oxd000_ff_space(uint32 addr);
2339 extern uint32  lisa_rl_Oxd000_ff_space(uint32 addr);
2340 extern void    lisa_wb_Oxd000_ff_space(uint32 addr, uint8  data);
2341 extern void    lisa_ww_Oxd000_ff_space(uint32 addr, uint16 data);
2342 extern void    lisa_wl_Oxd000_ff_space(uint32 addr, uint32 data);
2343 
2344 
2345 // not implemented - for future AMD9512 FPU's
2346 extern uint8  *lisa_mptr_Oxd400_amd9512(uint32 addr);
2347 extern uint8   lisa_rb_Oxd400_amd9512(uint32 addr);
2348 extern uint16  lisa_rw_Oxd400_amd9512(uint32 addr);
2349 extern uint32  lisa_rl_Oxd400_amd9512(uint32 addr);
2350 extern void    lisa_wb_Oxd400_amd9512(uint32 addr, uint8  data);
2351 extern void    lisa_ww_Oxd400_amd9512(uint32 addr, uint16 data);
2352 extern void    lisa_wl_Oxd400_amd9512(uint32 addr, uint32 data);
2353 
2354 // reserved memory access for mmu pages out of scope that should not cause mmu_exception
2355 extern uint8  *lisa_mptr_OxVoid(uint32 addr);
2356 extern uint8   lisa_rb_OxVoid(uint32 addr);
2357 extern uint16  lisa_rw_OxVoid(uint32 addr);
2358 extern uint32  lisa_rl_OxVoid(uint32 addr);
2359 extern void    lisa_wb_OxVoid(uint32 addr, uint8  data);
2360 extern void    lisa_ww_OxVoid(uint32 addr, uint16 data);
2361 extern void    lisa_wl_OxVoid(uint32 addr, uint32 data);
2362 
2363 
2364 #endif
2365 
2366 
2367 extern void keystroke_cops(unsigned char c);
2368 extern void send_cops_keycode(int k);
2369 
2370 extern void apple_1(void);
2371 extern void apple_2(void);
2372 extern void apple_3(void);
2373 extern void apple_enternum(void);
2374 extern void apple_S(void);              // for lisatest
2375 extern void apple_enter(void);
2376 extern void apple_renter(void);
2377 
2378 extern void vidfixromchk(uint8 *s);
2379 extern void keystroke_cops(unsigned char c);
2380 extern void init_IRQ(void);
2381 extern void init_Profiles(void);
2382 
2383 extern void profile_unmount(void);
2384 
2385 extern void init_sounds(void);
2386 extern void initialize_scc(void);
2387 extern void init_telnet_serial_port(int portnum);
2388 extern uint16 crc16(uint16 crc, uint8 data);
2389 extern void seek_mouse_event(void);
2390 extern void init_floppy(long iorom);
2391 
2392 
2393 extern void lisa_addrerror(uint32 addr);
2394 extern void lisa_busrerror(uint32 addr);
2395 extern void lisa_mmu_exception(uint32 addr);
2396 extern void lisa_nmi_vector(uint32 addr);
2397 
2398 
2399 extern CPP2C void lisa_powered_off(void);
2400 extern CPP2C void lisa_rebooted(void);
2401 extern CPP2C void messagebox(char *s, char *t);
2402 extern CPP2C int yesnomessagebox(char *s, char *t);
2403 extern CPP2C void floppy_motor_sounds(int track);
2404 extern CPP2C void eject_floppy_animation(void);
2405 extern CPP2C void save_pram(void);
2406 extern CPP2C int pickprofilesize(char *filename);
2407 
2408 //extern CPP2C char *getDocumentsDir(void);
2409 //extern CPP2C char *getResourcesDir(void);
2410 //extern CPP2C char *getExecutablePath(void);
2411 
2412 extern CPP2C int ImageWriter_LisaEm_Init(int iwnum);
2413 extern CPP2C void iw_formfeed(int iw);
2414 extern CPP2C void ImageWriterLoop(int iw,uint8 c);
2415 extern CPP2C void gen_clock_diff_sleep(long diff);
2416 
2417 
2418 
2419 
2420 
2421 void set_loram_clk(void);
2422 
2423 extern void lisa_diag2_on_mem(void);
2424 extern void lisa_diag2_off_mem(void);
2425 
2426 extern void  lisa_buserror(uint32 addr);
2427 extern void  mc68k_reset(void);
2428 extern uint8 lisa_rb_Oxd200_sccz8530(uint32 addr);
2429 extern uint8 lisa_rb_Oxd800_par_via2(uint32 addr);
2430 extern void  lisa_wb_Oxd800_par_via2(uint32 addr, uint8 data);
2431 extern uint8 lisa_rb_Oxdc00_cops_via1(uint32 addr);
2432 extern void  lisa_wb_Oxdc00_cops_via1(uint32 addr, uint8 data);
2433 extern void  fixromchk(void);
2434 extern int   checkromchksum(void);
2435 
2436 #ifndef IN_ROMLESS_C
2437 extern void romless_vfychksum(void);
2438 extern void romless_proread(void);
2439 extern void romless_twgread(void);
2440 extern int romless_boot(int profileboot);
2441 extern int romless_entry(void);
2442 #endif
2443 extern void my_dump_cops(FILE *buglog);
2444 //extern char *dis_movem(char *out, uint16, opcode, uint16 msk);
2445 
2446 
2447 extern void get_next_timer_event(void);
2448 extern void FloppyIRQ_time_up(void);
2449 
2450 extern void debug_on(char *reason);
2451 extern void debug_off(void);
2452 extern char *chk_mtmmu(uint32 a, uint8 write);
2453 extern void print_via_profile_state(char *s, uint8 data, viatype *V);
2454 extern int profile_mount(char *filename, ProFileType *P);
2455 extern void reg68k_external_autovector(int avno);
2456 
2457 extern CPP2C void LisaScreenRefresh(void);
2458 
2459 
2460 extern uint8 is_lisa_mouse_on(void);
2461 extern void cops_timer_alarm(void);
2462 extern void flag_vert_retrace_irq(void);
2463 
2464 extern int get_nmi_pending_irq(void);
2465 extern int get_scc_pending_irq(void);
2466 //extern int get_exs0_pending_irq(void);
2467 //extern int get_exs1_pending_irq(void);
2468 //extern int get_exs2_pending_irq(void);
2469 //extern int get_cops_pending_irq(void);  made static inline and placed in reg68k.c for speedup
2470 extern int get_irq1_pending_irq(void);
2471 extern void reset_video_timing(void);
2472 
2473 #ifdef DEBUG
2474 extern char *get_rom_label(uint32 pc24);
2475 extern char *getvector(int v);
2476 extern void lisaos_trap5(void);
2477 extern char *mac_aline_traps(uint16 opcode);
2478 #endif
2479 
2480 extern uint32 getreg(uint8 regnum);
2481 
2482 extern void printlisatime(FILE *out);
2483 extern void normalize_lisa_clock(void);
2484 extern void normalize_lisa_set_clock(void);
2485 extern void decisecond_clk_tick(void);
2486 extern void ascii_screendump(void);
2487 uint8 cmp_screen_hash(uint8 *hashtable1, uint8 *hashtable2);
2488 
2489 
2490 
2491 #define GETSEG(a)   (((a & MMUSEGFILT)>>17) & 0x7f)
2492 #define GETEPAGE(a) (((a & MMUEPAGEFL)>>9)  & 0x7fff)
2493 
2494 /* these are a bit too conservative perhaps, but they will prevent address overflows.              0x00fe0000*/
2495 //** DANGER ** REMOVE & TWOMEGLIM!!! ***
2496 #define CHK_MMU_REGST(addr)     (        (((       mmu[(addr & MMUSEGFILT)>>17].sor<<9) +  (addr & MMUXXFILT))              ))
2497 //#define RAM_MMU_REGST(addr)     (lisaram+(((       mmu[(addr & MMUSEGFILT)>>17].sor<<9) +  (addr & MMUXXFILT))  & TWOMEGMLIM))
2498 #define CHK_MMU_A_REGST(c,addr) (        (((mmu_all[c][(addr & MMUSEGFILT)>>17].sor<<9) +  (addr & MMUXXFILT))              ))
2499 #define RAM_MMU_A_REGST(c,addr) (lisaram+(((mmu_all[c][(addr & MMUSEGFILT)>>17].sor<<9) +  (addr & MMUXXFILT))              ))
2500 
2501 #define VALIDATE_MMU(addr)       (        (((       mmu[(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT))  & TWOMEGMLIM))
2502 
2503 // cheato
2504 //#define XCHK_MMU_TRANS(addr)     (        (((       mmu[(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT))  & TWOMEGMLIM))
2505 //#define XRAM_MMU_TRANS(addr)     (lisaram+(((       mmu[(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT))  & TWOMEGMLIM))
2506 //#define XCHK_MMU_A_TRANS(c,addr) (        (((mmu_all[c][(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT))  & TWOMEGMLIM))
2507 //#define XRAM_MMU_A_TRANS(c,addr) (lisaram+(((mmu_all[c][(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT))  & TWOMEGMLIM))
2508 
2509 
2510 // half way cheato
2511 //#define XXCHK_MMU_TRANS(addr)     ((        (((addr & 0xffffff)+mmu_trans[       (addr & MMUEPAGEFL)>>9].sor9) + (addr & MMUXXFILT)  & TWOMEGMLIM)))
2512 //#define XXRAM_MMU_TRANS(addr)     ((lisaram+(((addr & 0xffffff)+mmu_trans[       (addr & MMUEPAGEFL)>>9].sor9) + (addr & MMUXXFILT)  & TWOMEGMLIM)))
2513 //#define XXCHK_MMU_A_TRANS(c,addr) ((        (((addr & 0xffffff)+mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].sor9) + (addr & MMUXXFILT)  & TWOMEGMLIM)))
2514 //#define XXRAM_MMU_A_TRANS(c,addr) ((lisaram+(((addr & 0xffffff)+mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].sor9) + (addr & MMUXXFILT)  & TWOMEGMLIM)))
2515 
2516 // needs to be above fn def below
2517 GLOBAL(uint32,maxlisaram,2*1024*1024);
2518 GLOBAL(uint32,minlisaram,0);
2519 
2520 
2521 #define RAM512K  ( 512*1024)
2522 #define RAM1024K (1024*1024)
2523 #define RAM1536K (1536*1024)
2524 #define RAM2048K (2048*1024)
2525 
2526 #ifdef BULLSHYTE_ALLOW_1536K_RAM
RAMWARP(uint32 a,uint32 b,int c)2527    inline static uint32 RAMWARP(uint32 a, uint32 b, int c)
2528    {
2529 
2530 
2531     #ifdef OFFOFFOFFF20051205DEBUG
2532     uint32 sgn, usgn, xadd1, xadd2, slrchk;
2533 
2534     sgn=  ((int32)( (int32)(b & 0x00ffffff)+(int32)(mmu_trans_all[c][(b & MMUEPAGEFL)>>9].address))    & 0x1fffff);
2535     usgn= ((uint32)(        (b & 0x00ffffff)+       (mmu_trans_all[c][(b & MMUEPAGEFL)>>9].address)))  & 0x1FFFFF;
2536     xadd1=CHK_MMU_A_REGST(c,b);
2537     xadd2= 0x1FFFFF & (((mmu_all[c][b>>17].sor<<9) + (b & 0x1fe00))|(b &511));
2538     slrchk=0x1FFFFF & (((mmu_all[c][b>>17].slr & 0xff)<<9) + (b & 0x1fe00));
2539 
2540     if (sgn!=usgn)   ALERT_LOG(0,"DANGER - Signed MMU addition not the same as unsigned %d/%08x!=%08x(unsigned)",c,sgn,usgn);
2541     if (xadd1!=usgn) ALERT_LOG(0,"DANGER - Unsigned MMU addition not the same as CHK_MMU_A_REGST%d/%08x!=%08x(unsigned)",c,xadd1,usgn);
2542     if (xadd2!=usgn) ALERT_LOG(0,"DANGER - Unsigned MMU addition not the same HWG83 p 36 pdf %d/%08x!=%08x(unsigned)",c,xadd2,usgn);
2543     if (slrchk>0x1FFFFF) DEBUG_LOG(0,"SLR>1FFFFF");
2544 
2545     //if (maxlisaram==RAM2048K) return a;                                    // fast exit
2546 
2547 
2548     DEBUG_LOG(0," Current context=%d, context passed to me:%d slrchk:%08x >1FFFFF:%d",context,c,slrchk, (slrchk>0x1FFFFF));
2549     DEBUG_LOG(0," a=%08x inputaddr:%08x 2mblim s/b 001fffff:%08x mmu-delta:%d signed addition:%08x, normal addition:%08x via mmureg:%08x seg:%d sor:%04x slr:%04x",
2550     a,b,TWOMEGMLIM ,
2551     mmu_trans_all[c][(b & MMUEPAGEFL)>>9].address,
2552     ( (int32)(b & 0x00ffffff)+(int32)(mmu_trans_all[c][(b & MMUEPAGEFL)>>9].address)),
2553     (        (b & 0x00ffffff)+       (mmu_trans_all[c][(b & MMUEPAGEFL)>>9].address)),
2554 
2555     CHK_MMU_A_REGST(c,b),
2556     ((b & MMUSEGFILT)>>17 ),
2557     mmu_all[c][(b & MMUSEGFILT)>>17].sor,
2558     mmu_all[c][(b & MMUSEGFILT)>>17].slr
2559                                                );
2560     #endif
2561 
2562     #ifdef BULLSHYTE
2563     switch (maxlisaram)
2564     {
2565         case (RAM512K ):   // single 1/2MB board
2566                          if (a<RAM512K ) return a;                         // inside 512K
2567                          //20051109 if (a<RAM1024K) return (a & (RAM512K-1)); // warp
2568                          memset(&lisaram[maxlisaram],0xff,128);
2569                          return maxlisaram;                   // above 1MB is junk - return highest and hope for best
2570 
2571         case (RAM1024K):   // two 1/2 MB boards //
2572                         if (a<=RAM1024K) return a;
2573                         else return maxlisaram;
2574                         //20060106
2575                         // if (a<RAM512K)    {
2576                         //                       DEBUG_LOG(0,"<512KB");
2577                         //                       memset(&lisaram[maxlisaram],0xff,16); return maxlisaram;} //20051109
2578                         // if (a>=RAM1536K)  {
2579                         //                       DEBUG_LOG(0,">1536KB");
2580                         //                       memset(&lisaram[maxlisaram],0xff,16); return maxlisaram;} //20051109
2581                         //
2582                         // return a-RAM512K;                                                // 1st board 1MB
2583                          //20051109 return a-RAM1024K;                                    // 2nd warp
2584 
2585         case (RAM1536K):  // one 1MB board and one 1/2mb board
2586                          if (a<RAM1536K) return a;                                       // first board 1.5M
2587                          {memset(&lisaram[maxlisaram],0xff,128); return maxlisaram;}                  // 2nd board junk
2588 
2589 
2590         default:          return (a & 0x00ffffff);
2591     }
2592     #endif
2593    return a;
2594    }
2595                                                             //12345678
2596  #define RAM_MMU_TRANS(addr)     ((lisaram+RAMWARP((((addr) & 0x00ffffff) +mmu_trans[       (addr & MMUEPAGEFL)>>9].address),addr,context))               )
2597  #define RAM_MMU_A_TRANS(c,addr) ((lisaram+RAMWARP((((addr) & 0x00ffffff) +mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].address),addr,c ))               )
2598  #define CHK_MMU_TRANS(addr)     ((        RAMWARP((((addr) & 0x00ffffff) +mmu_trans[       (addr & MMUEPAGEFL)>>9].address),addr,context)) & (TWOMEGMLIM))
2599  #define CHK_MMU_A_TRANS(c,addr) ((        RAMWARP((((addr) & 0x00ffffff) +mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].address),addr,c )) & (TWOMEGMLIM))
2600 
2601 #else
2602 
2603   // these first two are very dangerous! - need to deprecate their use!
2604                                                             //12345678
2605   #define RAM_MMU_TRANS(addr)            (lisaram+(((addr & 0x00ffffff) +mmu_trans[       (addr & MMUEPAGEFL)>>9].address)  ))
2606   #define RAM_MMU_A_TRANS(c,addr)        (lisaram+(((addr & 0x00ffffff) +mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].address)  ))
2607   #define CHK_MMU_TRANS(addr)            (        (((addr & 0x00ffffff) +mmu_trans[       (addr & MMUEPAGEFL)>>9].address)  ))
2608   #define CHK_MMU_A_TRANS(c,addr)        (        (((addr & 0x00ffffff) +mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].address)  ))
2609 
2610 #endif
2611 
2612 
2613 #define RFN_MMU_TRANS(addr)     (mmu_trans[                                    (addr & MMUEPAGEFL)>>9].readfn )
2614 #define WFN_MMU_TRANS(addr)     (mmu_trans[                                    (addr & MMUEPAGEFL)>>9].writefn)
2615 #define RFN_MMU_A_TRANS(c,addr) (mmu_trans_all[c][                             (addr & MMUEPAGEFL)>>9].readfn )
2616 #define WFN_MMU_A_TRANS(c,addr) (mmu_trans_all[c][                             (addr & MMUEPAGEFL)>>9].writefn)
2617 
2618 
2619 // Memory checking macros
2620 // CHK- check only - no bus error
2621 // RCHK-Read check - call bus error
2622 // WCHK-Write check - call bus error
2623 // QCHK_RAM_LIMITS - check and quit emulator
2624 
2625 // can call CHK_RAM_LIMITS, then check for -1, else do lisaram[physaddr] for a pointer
2626 #define CHK_RAM_LIMITS(addr)                                                                                                 \
2627 {       physaddr=(        (((addr & 0x00ffffff)+mmu_trans[       (addr & MMUEPAGEFL)>>9].address) ));                        \
2628         if (physaddr<(signed)minlisaram) physaddr=-2;  else if (physaddr>(signed)maxlisaram) physaddr=-1;                    \
2629 }
2630 
2631 #define CHK_RAM_A_LIMITS(c,addr)                                                                                             \
2632 {       physaddr=(        (((addr & 0x00ffffff)+mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].address) ));                        \
2633         if (physaddr<(signed)minlisaram) physaddr=-2;  else if (physaddr>(signed)maxlisaram) physaddr=-1;                    \
2634 }
2635 
2636 
2637 // check, and quit if error
2638 #define QCHK_RAM_LIMITS(addr)                                                                                                \
2639 {       physaddr=(        (((addr & 0x00ffffff)+mmu_trans[       (addr & MMUEPAGEFL)>>9].address) ));                        \
2640         if (physaddr<0||physaddr>(signed)maxlisaram)                                                                         \
2641            {fprintf(buglog,"*** %s:%s:%d:: mem out of range! @ %d/%08x :: @mmu=%08x\n\n",                                    \
2642                            __FILE__,__FUNCTION__,__LINE__,context,addr,physaddr); EXIT(2); }                                 \
2643 }
2644 
2645 // check and abort on read, or write
2646 // if (TWOMEGMLIM==0x001fffff && (physaddr<minlisaram||((uint32)(physaddr))>maxlisaram))
2647 //
2648 // if ((physaddr<minlisaram||((uint32)(physaddr))>maxlisaram))
2649 
2650 #define RCHK_RAM_LIMITS(addr)                                                                                                \
2651 {          physaddr=(        ((addr+mmu_trans[       (addr & MMUEPAGEFL)>>9].address) ));                                    \
2652            if (physaddr<minlisaram) return 0x75;  else if (physaddr>(signed)maxlisaram) physaddr=-1;                         \
2653            if ((((uint32)(physaddr))>=maxlisaram))                                                                           \
2654            {fprintf(buglog,"*** %s:%s:%d:: mem out of range! @ %d/%08x :: @mmu=%08x\n\n",                                    \
2655             __FILE__,__FUNCTION__,__LINE__,context,addr,physaddr); CPU_READ_MODE=1; lisa_mmu_exception(addr); return 0x93;}  \
2656 }                                                                     //lisa_mmu_exception(addr);
2657 
2658 
2659 #define WCHK_RAM_LIMITS(addr)                                                                                                \
2660 {          physaddr=(        ((addr+mmu_trans[       (addr & MMUEPAGEFL)>>9].address) ));                                    \
2661            if (physaddr<minlisaram) return;       else if (physaddr>(signed)maxlisaram) physaddr=-1;                         \
2662            if ((((uint32)(physaddr))>=maxlisaram))                                                                           \
2663            {fprintf(buglog,"*** %s:%s:%d:: mem out of range! @ %d/%08x :: @mmu=%08x\n\n",                                    \
2664            __FILE__,__FUNCTION__,__LINE__,context,addr,physaddr);  CPU_READ_MODE=0; lisa_mmu_exception(addr); return;}       \
2665 }                                                                     //lisa_mmu_exception(addr);
2666 
2667 
2668 #define XRCHK_RAM_LIMITS(addr) {}
2669 #define XWCHK_RAM_LIMITS(addr) {}
2670 
2671 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2672 
2673 
2674 #endif
2675