/* -*- Mode:C; Tab-width:4 -*- */
/*                                                                       */
/*                                                                       */
/*                      RESTRICTED RIGHTS LEGEND                         */
/*                                                                       */
/* Use, duplication, or disclosure by the Government is subject to       */
/* restrictions as set forth in subdivision (c)(1)(ii) of the Rights in  */
/* Technical Data and Computer Software clause at 252.227-7013.          */
/*                                                                       */
/*                    TEXAS INSTRUMENTS INCORPORATED.                    */
/*                            P.O. BOX 149149                            */
/*                         AUSTIN, TEXAS 78714-9149                      */
/*                              MS 2151                                  */
/*                                                                       */
/*  Copyright (C)   1987,1988,1989,1990 Texas Instruments Incorporated.  */
/*  All rights reserved.                                                 */
/*                                                                       */

/*  2-24-89     BJ  Added virtual<>physical translations to queueing.    */

#ifndef __UTILITY__
#define __UTILITY__ 1

#include <types.h>
/*  included quickdraw and windows because WindowPtr is referred to within desk.h  clm 8/22/89 */
#ifndef _QUICKDRAW_
#include <quickdraw.h>
#endif
#ifndef _WINDOWS_
#include <windows.h>
#endif
#include <desk.h>

/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */

typedef struct S_BE_Info
 {	unsigned long	BE_Sys_Trap;
	unsigned long	BE_PC;
	unsigned long	BE_Adr;
	unsigned long	BE_Count;
	unsigned short	BE_Flag;
 } BE_Data, *BE_DataP;
 
/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */


/************************************************************/
/*                                                          */
/* General GLOBALS                                          */
/*                                                          */
/************************************************************/

#define TRUE 1
#define FALSE 0
#define NULL 0

/************************************************************/
/*                                                          */
/* MMU Support                                              */
/*                                                          */
/************************************************************/

extern char *ptr24to32();
extern char *ptr32to24();

#define MMU24 0		/* 24 bit addressing mode */
#define MMU32 1		/* 32 bit addressing mode */

extern unsigned int swap_mmu_mode();
extern unsigned int mmu_mode;			/* This is in AddinComm.c */

/* A macro to make the transition to 32 bit mode a little easier.					 */
/* I am not sure on how many compilers this will work but it seems to work on MPW c. */

#define with_32_bit_mode(block)														\
		{																			\
			int swap = FALSE;														\
			if(mmu_mode != MMU32)													\
				{																	\
					swap = TRUE;													\
					mmu_mode = MMU32;                                               \
					DebugStr("\pswap1");                                            \
					swap_mmu_mode(mmu_mode);										\
				}																	\
			block;																	\
			if(swap == TRUE)														\
				{																	\
					mmu_mode = MMU24;												\
					swap_mmu_mode(mmu_mode);										\
				}																	\
		}																			\

#define with_24_bit_mode(block)														\
		{																			\
			int swap = FALSE;														\
			if(mmu_mode != MMU24)													\
				{																	\
					swap = TRUE;													\
					mmu_mode = MMU24;												\
					swap_mmu_mode(mmu_mode);										\
				}																	\
			block;																	\
			if(swap == TRUE)														\
				{																	\
					mmu_mode = MMU32;												\
					swap_mmu_mode(mmu_mode);										\
				}																	\
		}																			\


/*
For example:

main()
	{
		int x,y;
		with_32_bit_mode(
							x=1;
							y=2;
							x=y;);
	}
	
*/
/************************************************************/
/*                                                          */
/* AUX virtual memory support                               */
/*                                                          */
/************************************************************/

pascal Ptr
physical_to_virtual(address)
	Ptr address;
	 extern;

pascal Ptr
virtual_to_physical(address)
	Ptr address;
	 extern;

pascal Ptr
make_pointer(slot, offset)
	 unsigned char slot;
	 unsigned long offset;
	 extern;

/************************************************************/
/*                                                          */
/* Queueing                                                 */
/*                                                          */
/************************************************************/


typedef struct q_elem
{
  struct q_elem *q_elem_link;
} q_elem;

extern void q_element();
extern q_elem *deq_element();

typedef struct queue_struct
{
  unsigned char lock;
  unsigned char unused[3];
  long lock_collisions;
  Ptr head;
  Ptr tail;
  long length;
  long spare_word;
} queue_struct;

#define initialize_q(q)              \
    (q)->head = NULL;                  \
    (q)->tail = NULL;                  \
    (q)->lock_collisions = 0;          \
    (q)->lock = NULL;                  \
    (q)->length = 0;

#define q_length(q)                    \
    swap_32b((q)->length)

#define set_q_length(q, value)         \
    (q)->length = swap_32b(value)

/* clm 8/24/89 - physical_to_virtual takes as its arg a
     Ptr, but swap_32b returns an unsigned int value;
     coerced the value returned by swap_32b */
#define q_head(q)                     \
    (Ptr)physical_to_virtual((Ptr)swap_32b((q)->head))

#define set_q_head(q, val)             \
    (q)->head = (Ptr)swap_32b(virtual_to_physical(val))

/* clm 8/24/89 - same change as for q_head */
#define q_tail(q)                     \
    (Ptr)physical_to_virtual((Ptr)swap_32b((q)->tail))

#define set_q_tail(q, val)             \
    (q)->tail = (Ptr)swap_32b(virtual_to_physical(val))

/* clm 8/24/89 - same changes as for q_head and q_tail */
#define q_link(el)                                      \
    (Ptr)physical_to_virtual((Ptr)swap_32b(el->q_elem_link))

/* clm 8/23/89 - changed the cast type-name from Ptr to
     (q_elem *) for the proper type casting . */
#define set_q_link(el, val)                             \
    el->q_elem_link = (q_elem *)swap_32b(virtual_to_physical(val))
	
#define q_lock_collisions(q)                     \
    swap_32b((q)->lock_collisions)

#define set_q_lock_collisions(q, val)             \
    (q)->lock_collisions = swap_32b(val)

extern Boolean test_and_set();

#define q_unlock(queue)					\
  (queue)->lock = NULL


/************************************************************/
/*                                                          */
/* ENDIAN SWAPPING                                          */
/*                                                          */
/************************************************************/

extern void block_swap_16b();		/* Block move and byte swap a 16 bit data block. 	*/
extern void block_swap_32b();		/* Block move and byte swap a 32 bit data block. 	*/
extern unsigned int swap_32b(val);	/* Byte swap a 32 bit quantity. 					*/
extern unsigned short swap_16b(val);			/* Byte swaps a 16 bit quantity. 					*/

/************************************************************/
/*                                                          */
/* DEBUG Support                                            */
/*                                                          */
/************************************************************/

/* #include <wlw.h> */

/* Wait for a key to be pressed. Assumes there is a function named                       */
/*  event_handler(event_mask, sleep_time) for waiting.                                   */ 
#include <events.h>
extern event_handler();              
#define wait_key()                                                                        \
{                                                                                         \
 /* EventRecord event;             12/01/89 sbw */                                                         \
  SysBeep(5);                                                                             \
  printf("Press Any Key To Continue ---\n");                                              \
  while (event_handler(-1, 0) != keyDown);                                        \
}

pascal void debugger()
	 extern 0xa9ff;

PrtWarnMsg();


/************************************************************/
/*                                                          */
/* NuBus Read/Write                                         */
/*                                                          */
/************************************************************/
void nubus_write();
unsigned long nubus_read();
void nubus_write_byte();
unsigned short nubus_read_byte();


/************************************************************/
/*                                                          */
/* MISC                                                     */
/*                                                          */
/************************************************************/

extern short r_ioctl();

#include <devices.h>
#define CurrentA5 ((Ptr) *((Ptr *) 0x904))
#define uTableBase ((DCtlEntry ***) 0x11c)
#define MIN(a, b)     ((a < b) ? a : b)
#define MAX(a, b)     ((a > b) ? a : b)

extern DCtlEntry **get_dce();
extern void set_dce();

#endif