-
Notifications
You must be signed in to change notification settings - Fork 0
/
memory.c
executable file
·1837 lines (1625 loc) · 45.1 KB
/
memory.c
1
#include <types.h>#include <quickdraw.h>#include <memory.h>#include <resources.h>#include <StdLib.h>#define MEMORY_C#include "exception.h"#include "mmemory.h"#include "vax.h"#include "defines.h"#include "func.h"#include "docmds.h"#include "window.h"#include "aprintf.h"#include "sysw.h"#include "symbol_tab.h"#pragma segment VaxMemstatic vax_mem_type vax_mem;static address real_free_mem_bitmap;static address sys_globs;quad quad_zero = {0,0}; /*so we can assigne zero to a quad*/oct oct_zero = {0,0,0,0}; /*so we can assigne zero to an oct*/reg_type vax_regs[48]; /*16 usual regs and 32 temp regs*/address opaddr[ MAXARGS ];psl_type psl;long nf_temp_reg = 0x10;reg_type ipr[NUM_IPRS];long saw_watch_point = 0;unsigned int memory_csr[3]; /*Memory controller control and status registers*/unsigned char *boot_roms; /*Boot ROMS*/umap_register *unibus_map; /*UniBus MAP registers*/#define vax_fetchbR(a) (*VAX2MAC_address(a))#define vax_putbR(b, a) (*VAX2MAC_address(a) = b)typedef union{ unsigned char aword_by_byte[2]; unsigned short aword;} swap;void init_vax_memory( /*Allocates memory for VAX physical memory*/ /*Allocates watch map for VAX debugging*/ /*Sets up default display modes for IPR's*/ void){long i;Handle vax_real_memory_H;Handle vax_watchmap_H; /*allocate space for VAX real memory + watchpoints*/ IPR(MVMEM) = REAL_MEM_SIZE; vax_real_memory_H = NewHandle ( (Size) IPR(MVMEM) ); vax_watchmap_H = NewHandle ( (Size) (IPR(MVMEM) >> 3) & 0x1FFFFFFF); if(vax_real_memory_H == (Handle)0 || vax_watchmap_H == (Handle)0 ) { aprintf("MAC_OUT_OF_MEMORY\nWanted %u bytes",VAX_MEM_SIZE ); exit(1); } HLock(vax_real_memory_H); HLock(vax_watchmap_H); vax_mem.real_memory = (unsigned char *) *vax_real_memory_H; vax_mem.watchmap = (unsigned char *) *vax_watchmap_H; memory_csr[2] = (1 << ( IPR(MVMEM) / 128 )) - 1; for(i = 0; i < NUM_IPRS; i++) ipr[i].dis_mode = HEX_FORMAT;}unsigned char *mac_address( /*returns the Macintosh address of the Vax Address a*/ register address a){ a &= Physical_Address_Mask; /*The top word of a physical address is ignored*/ if(a >= IPR(MVMEM)) { if(stop == 0) aprintf("Invalid Real address 0x%x (%d)",a,a); stop = 1; return (unsigned char *) ERROR; } return (VAX2MAC_address(a));}void freeallmem( /*Clears all VAX memory including registers and IPR's*/ /*Marks Console register transmit status register as ready*/ /*Zero's the line counters for the dispaly of each region of memory*/ long And_watch_points){long i;unsigned char *p; /*Blat all of vax real memory and watch points*/ for(p = vax_mem.real_memory, i = 0; i < IPR(MVMEM); i++) *p++ = 0; if(And_watch_points) { for(p = vax_mem.watchmap, i = 0; i < (IPR(MVMEM) >> 3); i++) *p++ = 0; } /*Clear R0 - R15*/ for(i = 0; i < 16; i++) vax_regs[i].contents.as_ulong = 0; /*Clear IPR's*/ for(i = 0; i < NUM_IPRS; i++) IPR(i) = 0; IPR(MVMEM) = REAL_MEM_SIZE; /*restore the available memory register*/ IPR(TXCS) = 0x80; /*mark console transmitter as ready*/ IPR(ASTR) = 0x4; /*Mark AST level as non pending*/ IPR(ISP) = IPR(MVMEM) > 1; /*Half way through physical memory*/ PSL = 0x041F0000; /*Using Interrupt stack, IPL = 1F, CMD = Kernel, PMD = kernel*/ IPR(CSTS) = 0x80; /*Tu58 Transmit ready bit*/ cdlines(); /*Fix memory windows scroll bars*/ sklines(); syslines(); set_maxscroll_sysw(); }void display_memory_usage( /*Displays the memory usage of the current processes VAX memory*/ void){address p0 = IPR(P0BR);address p1 = IPR(P1BR) + (IPR(P1LR) << 2);address s = IPR(SBR);long p0_pages = IPR(P0LR);long p1_pages = TOTAL_P1_PAGES;long s_pages = IPR(SLR);long num_p0_pages = 0;long num_p1_pages = 0;long num_s_pages = 0;real_page_entry pte;long num_p0_used;long num_p1_used;long num_s_used;long num_used; if(IPR(MME) == 1) { while(p0_pages-- > 0) { pte = vax_fetchpt(p0,0); p0 += sizeof(real_page_entry); if(pte.protection != NA) num_p0_pages++; } while(p1_pages-- > IPR(P1LR)) { pte = vax_fetchpt(p1,0); p1 += sizeof(real_page_entry); if(pte.protection != NA) num_p1_pages++; } while(s_pages-- > 0) { vax_fetchptR(s,0,(&pte)); s += sizeof(real_page_entry); if(pte.protection != NA) num_s_pages++; } num_p0_used = num_p0_pages * PAGE_SIZE; num_p1_used = num_p1_pages * PAGE_SIZE; num_s_used = num_s_pages * PAGE_SIZE; num_used = num_p0_used + num_p1_used + num_s_used; if(current_process) { aprintf("Used: 0x%X Free: 0x%X Total: 0x%X \nP0: 0x%X Code 0x%X Data 0x%X UData 0x%X\nP1: 0x%X \nS : 0x%X", num_used, IPR(MVMEM) - num_used, IPR(MVMEM), num_p0_used, current_process->txtsiz, current_process->datsiz, current_process->bsssiz, num_p1_used, num_s_used); } else { aprintf("Used: 0x%X Free: 0x%X Total: 0x%X \nP0: 0x%X\nP1: 0x%X \nS : 0x%X", num_used, IPR(MVMEM) - num_used, IPR(MVMEM), num_p0_used, num_p1_used, num_s_used); } } else aprintf("Virtual memory off\n\nAvailable Physical memory: 0x%x (%d)",IPR(MVMEM),IPR(MVMEM));} /*MAINTAIN FREE PAGES BITMAP*/unsigned long next_free_pf( /* returns the page number of the first free physical page */ void){unsigned long i; /* Byte index */unsigned long j; /* Bit index */unsigned char k;/*Bit mask */ for(i = 0; i < (NUM_PAGE_FRAMES >> 3); i++) { for(j = 0, k = 0x01; j < 8; j++, k <<= 1) if((*VAX2MAC_address(real_free_mem_bitmap + i) & k) == 0) { *VAX2MAC_address(real_free_mem_bitmap+i) |= k; return ( i << 3 ) + j; } } return ERROR;}long mark_as_free_pf( /*Mark as Free an allocated Physical page*/ unsigned long pfn){unsigned char bit_mask = ~(0x01 << (pfn & 0x7));unsigned long index = pfn >> 3; if(pfn >= NUM_PAGE_FRAMES) return -1; *VAX2MAC_address(real_free_mem_bitmap + index) &= bit_mask; return 0;}/*DUMMY CODE FOR INTERLOCKS*/void get_interlock(void){ /*Currently nothing can access memory while an interlocked*/ /*instruction is executing. Should this change the this */ /*function should provide the locking */ /*if(interlock) sleep(interlock);*/ /*interlock = 1*/}void free_interlock(void){ /*Currently nothing can access memory while an interlocked*/ /*instruction is executing. Should this change the this */ /*function should provide the locking */ /*interlock = 0*/ /*wake(interlock);*/}/*CODE TO LOAD BOOT ROMS INTO PHYSICAL MEMORY*/int copy_boot_roms( address base /*base address of 64K mem seg for booting in*/){Handle vrom_H;long vrom_H_size; base += 0xFA00; vrom_H = GetResource ('VROM',(short)128); if(vrom_H == (Handle) 0) { if(stop == 0) aprintf("MAC_OUT_OF_MEMORY\nUnable to load VAX Boot ROMS"); stop = 1; return -1; } vrom_H_size = SizeResource(vrom_H); if(base + vrom_H_size <= IPR(MVMEM)) /*can we fit the ROMS in*/ { HLock(vrom_H); boot_roms = (unsigned char *) *vrom_H; while(vrom_H_size--) vax_putbR(*boot_roms++, base++); HUnlock(vrom_H); ReleaseResource (vrom_H); return 0; } else { ReleaseResource (vrom_H); return -1; }}/*MAINTAIN PAGE TABLES FOR DUMMY SYSTEM*/address add_p0_pte( /* creates a P0 page table entry */ /*returns the pages virtual address*/ unsigned long modified, unsigned long pfn, unsigned long protection){union{ real_page_entry pte; long pte_as_long;} u;address a = IPR(P0BR) + (IPR(P0LR) << 2);unsigned long hold = CMD;address virtual_address; u.pte.valid = 1; u.pte.modified = modified; u.pte.pfn = pfn; u.pte.mbz = 0; u.pte.own = 0; u.pte.s = 0; u.pte.protection = protection; CMD = KSP; vax_putl(u.pte_as_long, a); CMD = hold; virtual_address = (IPR(P0LR)++ << 9); cdlines(); set_maxscroll_sysw(); return virtual_address;}address add_p1_pte( /* creates a P1 page table entry */ /*returns the pages virtual address*/ unsigned long modified, unsigned long pfn, unsigned long protection) {union{ real_page_entry pte; long pte_as_long;} u;address a = IPR(P1BR) + (--IPR(P1LR) << 2);unsigned long hold = CMD; u.pte.valid = 1; u.pte.modified = modified; u.pte.pfn = pfn; u.pte.mbz = 0; u.pte.own = 0; u.pte.s = 0; u.pte.protection = protection; CMD = KSP; vax_putl(u.pte_as_long, a); CMD = hold; sklines(); set_maxscroll_sysw(); return (unsigned long) P1_SPACE + PAGE_SIZE + (IPR(P1LR) << 9);}address add_sys_pte( /* creates a system page table entry */ /* returns the pages virtual address */ unsigned long modified, unsigned long pfn, unsigned long protection){union{ real_page_entry pte; long pte_as_long;} u;address a = IPR(SBR) + (IPR(SLR) << 2); /*vax real address of the pte*/address virtual_address; u.pte.valid = 1; u.pte.modified = modified; u.pte.pfn = pfn; u.pte.mbz = 0; u.pte.own = 0; u.pte.s = 0; u.pte.protection = protection; vax_putliR(u.pte_as_long, a); virtual_address = (unsigned int)S_SPACE + (IPR(SLR)++ << 9); syslines(); set_maxscroll_sysw(); return virtual_address;}address alloc_cd( /*Allocates a block of VAX memory in P0 space */ /*Returns the Virual address of the Block or ERROR if the call fails */ long size, short protection){long wanted;long i;address start;long error = 0;long pfn; start = IPR(P0LR) << 9; /*note first available pages index*/ wanted = (size + PAGE_SIZE - 1)/ PAGE_SIZE; /*round up to exact number of pages*/ for(i = 0; i < wanted; i++) { if((pfn = next_free_pf()) == ERROR) { aprintf("P0 alloc: No free pages left\nTried to get %d pages",wanted); for(i--;i >= 0; i--) free_p0_page(); return (address) ERROR; } add_p0_pte(0,pfn,protection); } return(start) ; /*returns virtual address of block allocated*/}void free_p0_page( /*Clears the last allocated P0 page*/ void){ /*be carefull of this*/real_page_entry pte; if(IPR(P0LR)) { pte = vax_fetchpt(IPR(P0BR) + (--IPR(P0LR) << 2),0); mark_as_free_pf(pte.pfn); cdlines(); set_maxscroll_sysw(); }}void alloc_p1_space( /* Allocates stacks */ /*generates a PCCB */ void){ add_p1_pte(0,IPR(PCBB) = next_free_pf(),URKW) - PAGE_SIZE; /*Per process data*/ IPR(PCBB) = IPR(PCBB) << 9; /*allocate the stack pages*/ add_p1_pte(0,0,NA); /*Bound stack with inaccessable page*/ IPR(KSP) = add_p1_pte(0,next_free_pf(),URKW); /*Kernel Stack*/ (void) add_p1_pte(0,next_free_pf(),URKW); add_p1_pte(0,0,NA); /*Bound stack with inaccessable page*/ IPR(ESP) = add_p1_pte(0,next_free_pf(),UREW); /*Exec Stack*/ (void) add_p1_pte(0,next_free_pf(),UREW); add_p1_pte(0,0,NA); /*Bound stack with inaccessable page*/ IPR(SSP) = add_p1_pte(0,next_free_pf(),URSW); /*Supervisor Stack*/ (void) add_p1_pte(0,next_free_pf(),URSW); add_p1_pte(0,0,NA); /*Bound stack with inaccessable page*/ IPR(USP) = add_p1_pte(0,next_free_pf(),UW); /*USER STACK*/ (void) add_p1_pte(0,next_free_pf(),UW); }void alloc_sys_space( /*Sets up system space page tables*/ /*Turns on Virtual memory */ void){unsigned long pfn = 0;long i; IPR(MME) = 1; /*turn on memory management*/ IPR(SCBB) = 0; /*maps to 0x80000000*/ IPR(SBR) = PAGE_SIZE; /*maps to 0x80000A00*/ IPR(SLR) = 0; add_sys_pte(0,pfn++,UW); /*SCBB*/ pfn++; /*want to skip real page 1 so we can stick the S PTE's there*/ add_sys_pte(0,0,NA); /*NA page after interrupt stack*/ add_sys_pte(0,pfn++,URKW); /*interrupt stack*/ IPR(ISP) = add_sys_pte(0,pfn++,URKW) + PAGE_SIZE; add_sys_pte(0,0,NA); /*NA page before interrupt stack*/ add_sys_pte(1,1,UR); /*SBR*/ add_sys_pte(1,real_free_mem_bitmap = pfn++,URKW); /*Bitmap of allocated pages*/ real_free_mem_bitmap = real_free_mem_bitmap << 9; sys_globs = add_sys_pte(0,pfn++,URKW); /*Misc system globals*/ IPR(P0BR) = add_sys_pte(0,pfn++,URKW); /*P0BR*/ add_sys_pte(0,0,NA); /**/ add_sys_pte(0,0,NA); /**/ IPR(P0LR) = 0; add_sys_pte(0,0,NA); /*P1BR*/ IPR(P1BR) = add_sys_pte(0,pfn++,URKW) + PAGE_SIZE - MAX_PAGE_TABLE_SIZE; IPR(P1LR) = TOTAL_P1_PAGES; /*2**30 / PAGE_SIZE. Number of pages free in P1 space*/ for(i = 0; i < pfn; i++) (void) next_free_pf(); /*set bits in mem bitmap for sys space*/}/*WATCH POINT CODE*/ void toggle_watch_bit( /*Toggle the bit associated with the address VAX virtual addr*/ address addr){address rvaxaddress;unsigned char byte_mask;unsigned long index; if((rvaxaddress = check_reference(addr,KSP,RD,0)) == ERROR) { aprintf("Unable to Set/Clear watch point at address %x",addr); return ; } index = rvaxaddress >> 3; byte_mask = 1 << (rvaxaddress & 0x7); vax_mem.watchmap[index] ^= byte_mask;}void clear_range_watch_points(address addr, long length)/*Clear range of watch points*/{long i;address rvaxaddress;unsigned char byte_mask;unsigned long index; for(i = 0; i < length; i++) { if((rvaxaddress = check_reference(addr,KSP,RD,0)) == ERROR) { aprintf("Unable to Clear watch point at address %x",addr); return; } index = rvaxaddress >> 3; byte_mask = 1 << (rvaxaddress & 0x7); vax_mem.watchmap[index] &= ~byte_mask; } }void set_range_watch_points(address addr, long length)/*Set range of watch points*/{long i;address rvaxaddress;unsigned char byte_mask;unsigned long index; for(i = 0; i < length; i++) { if((rvaxaddress = check_reference(addr,KSP,RD,0)) == ERROR) { aprintf("Unable to Set watch point at address %x",addr); return; } index = rvaxaddress >> 3; byte_mask = 1 << (rvaxaddress & 0x7); vax_mem.watchmap[index] |= byte_mask; }}void clear_all_watch_points(void)/*Clear ALL set watch points*/{long i;unsigned char *p; for(p = vax_mem.watchmap, i = 0; i < (IPR(MVMEM) >> 3); i++) *p++ = 0;}/*PHYSICAL TO VIRTUAL MEMORY MAPPING*/ address virtual( /*returns the virtual address given the physical address*/ /*returns ERROR if address not found*/ address physical){address page_number;address offset;real_page_entry the_pte;unsigned long i;address page_table_address;address p1;long p1_pages ; physical &= Physical_Address_Mask; /*The top word of a physical address is ignored*/ if(physical >= IPR(MVMEM)) /*verify we have a semi-sensible address*/ { return ERROR; } if(IPR(MME) == 0) /*if virtual memory off*/ { return physical; } page_number = (physical & PAGE_NUMBER_MASK) >> 9; offset = physical & OFFSET_MASK; /*First check in System Space*/ page_table_address = IPR(SBR); vax_fetchptR( page_table_address, 0,(&the_pte)) ; for( i = 0; i < IPR(SLR); i++) { if( the_pte.valid == 1 && the_pte.pfn == page_number) { return (S_SPACE + (i << 9) + offset); } else { page_table_address += sizeof(real_page_entry); vax_fetchptR(page_table_address, 0,(&the_pte)) ; } } /*Next check the P1 space*/ p1 = IPR(P1BR) + MAX_PAGE_TABLE_SIZE - sizeof(real_page_entry); p1_pages = TOTAL_P1_PAGES; while(p1_pages-- > IPR(P1LR)) { the_pte = vax_fetchpt(p1,0); if( the_pte.valid == 1 && the_pte.pfn == page_number ) { return (P1_SPACE + (p1_pages << 9) + offset) ; } p1 -= sizeof(real_page_entry); } /*Last check P0 Space*/ page_table_address = IPR(P0BR); the_pte = vax_fetchpt( page_table_address, 0) ; for( i = 0; i < IPR(P0LR); i++) { if( the_pte.valid == 1 && the_pte.pfn == page_number) { return (PO_SPACE + (i << 9) + offset); } else { page_table_address += sizeof(real_page_entry); the_pte = vax_fetchpt(page_table_address, 0 ) ; } } return ERROR;}/*VIRTUAL TO PHYSICAL MAPPING CODE*/void vax_fetchptR( /*fetch a page table entry given its physcial (VAX) address */ /*Returns the result in pte */ /*Generates a memory fault for an invalid address setting *pte to 0 */ register address a, register long modify, register real_page_entry *pte){ union{ real_page_entry w; unsigned long x; unsigned char y[4];} z;register unsigned char *p ;register unsigned char *q ; a &= Physical_Address_Mask; /*The top word of a physical address is ignored*/ if( a >= IPR(MVMEM) ) { IPR(MCESR) |= BUS_ERROR; IPR(MCSR) |= NON_EXIST_MEM; exception(FAULT,V_MCV,"Physical address error",2,a,1); z.x = 0; } else { p = (unsigned char *) VAX2MAC_address(a); q = (unsigned char *) &z.y[3]; *q = *p++; *--q = *p++; *--q = *p++; *--q = *p; if(modify) { *p |= 0x04; } } *pte = z.w;}real_page_entry vax_fetchpt( /* fetch a page table entry given its virtual address */ /* Usually bypassed for speed */ /* Returns the pte. */ /* Generates a memory fault for an invalid address setting *pte to 0 */ address a, long modify ){ union virtual_address v;register unsigned long space;register unsigned long page_number;register unsigned long byte_in_page;union{ real_page_entry pte; long x;}y;real_page_entry the_pte; /*extract parts of address*/ v.v_address = a; space = v.decoded_addr.space; page_number = v.decoded_addr.page; byte_in_page = v.decoded_addr.offset; if( space == S0) { if( page_number >= IPR(SLR) ) { memory_fault(V_ACV,"Access Control Violation",a,(modify << 2) | 3 ); y.x = 0; return( y.pte ); } vax_fetchptR((IPR(SBR) + (page_number << 2)),0,(&the_pte)); page_number = the_pte.pfn; vax_fetchptR(((page_number << 9) | byte_in_page),modify,(&the_pte)); return the_pte; } else { if(stop == 0) aprintf("Page table entry not in system space"); stop = 1; y.x = 0; return( y.pte ); }}address check_reference( /*Returns the vax Physical address of the given virtual address*/ register address addr, /* virtual address */ long mode, /* processor mode to check referce with */ long protection, /* want to read(1) or write(2) */ long modify /* Want to mark page as modified */){ register unsigned long page_number;real_page_entry the_pte;register unsigned long tmp; if(IPR(MME) == 0) { /*Real memory addressing*/ addr &= Physical_Address_Mask; if(addr >= IPR(MVMEM)) { return( (address) ERROR ); } else { return( addr ); } } /*extract parts of address*/ page_number = (addr & PAGE_NUMBER_MASK) >> 9; switch(addr & SPACE_MASK) { case PO_SPACE_C: if( page_number >= IPR(P0LR) ) { /*aprintf("P0 Length error %x",addr);*/ memory_fault(V_ACV,"Access Control Violation",addr,(modify << 2) | 1 ); return( (address) ERROR ); } tmp = IPR(P0BR) + (page_number << 2); page_number = tmp & PAGE_NUMBER_MASK; vax_fetchptR((IPR(SBR) + (page_number >> 7)),0,(&the_pte)); page_number = the_pte.pfn; vax_fetchptR(((page_number << 9) | (tmp & OFFSET_MASK)),modify,(&the_pte)); break; case P1_SPACE_C: if( page_number < IPR(P1LR) ) { /*aprintf("P1 Length error %x",addr);*/ memory_fault(V_ACV,"Access Control Violation",addr,(modify << 2) | 1 ); return( (address) ERROR ); } tmp = IPR(P1BR) + (page_number << 2); page_number = tmp & PAGE_NUMBER_MASK; vax_fetchptR((IPR(SBR) + (page_number >> 7)),0,(&the_pte)); page_number = the_pte.pfn; vax_fetchptR(((page_number << 9) | (tmp & OFFSET_MASK)),modify,(&the_pte)); break; case S_SPACE_C: if( page_number >= IPR(SLR) ) { /*aprintf("S Length error %x",addr);*/ memory_fault(V_ACV,"Access Control Violation",addr,(modify << 2) | 1 ); return( (address) ERROR ); } vax_fetchptR((IPR(SBR) + (page_number << 2)),modify,(&the_pte)); break; default: /*if (space == R)*/ /*aprintf("R %x",addr);*/ memory_fault(V_ACV,"Access Control Violation",addr,(modify << 2) | 1 ); return( (address) ERROR ); } if( TEST_PERM(mode,the_pte.protection,protection) || displaymode == 1) { page_number = the_pte.pfn; if(the_pte.valid != 1) { /*aprintf("Invalid page Table entry",addr);*/ memory_fault(V_TNV,"Translation Not Valid",addr,(modify << 2) ); return (address) ERROR; } if((tmp = ((page_number << 9) | (addr & OFFSET_MASK))) >= IPR(MVMEM)) { /*aprintf("Maps to invalid real address %x, %x",addr, tmp);*/ IPR(MCESR) |= BUS_ERROR; IPR(MCSR) |= NON_EXIST_MEM; exception(FAULT,V_MCV,"Physical address error",2,addr,1); return (address) ERROR; } return tmp; } else { #ifdef DEBUG aprintf("Don't have access priv %x\nmode %x:the_pte.protection %x: protection %x",addr,mode,the_pte.protection,protection);#endif memory_fault(V_ACV,"Access Control Violation",addr,(modify << 2) | 2); return( (address) ERROR ); } }/*PHYSICAL ADDRESS FETCH AND PUT INSTRUCTIONS*/unsigned char fvax_fetchbR( /*return byte at VAX Physical address a */ /* Returns 0 on error and sets stop */ /* Will set saw_watch_point if it did */ address a){ a &= Physical_Address_Mask; /*The top word of a physical address is ignored*/ if(a >= IPR(MVMEM)) { stop = 1; return 0; } if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[a >> 3] & (1 << (a & 0x7));#ifdef WANT_WATCHES_HERE if(r_watch_and_breaks_on && saw_watch_point && exceptions_on) { exceptions_on = 0; aprintf(hexmode ? "WatchPoint\nRead byte at physical address 0x%x":"WatchPoint\nRead byte at physical address %u" , a); stop = 1; saw_watch_point = 0; }#endif return vax_fetchbR(a);}long fvax_putbR( /*Writes byte b at VAX physical address a*/ /* Returns -1 on error and sets stop */ /* Will set saw_watch_point if it did */ unsigned char b, address a){ a &= Physical_Address_Mask; /*The top word of a physical address is ignored*/ if(a >= IPR(MVMEM)) { stop = 1; return -1; } vax_putbR(b, a); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[a >> 3] & (1 << (a & 0x7));#ifdef WANT_WATCHES_HERE if(w_watch_and_breaks_on && saw_watch_point && exceptions_on) { exceptions_on = 0; aprintf(hexmode ? "WatchPoint\nModified byte at physical address 0x%x":"WatchPoint\nModified byte at physical address %u" , a); stop = 1; saw_watch_point = 0; }#endif return 0;}unsigned long vax_fetchliR( /* Return a long from the aligned VAX Physical address a */ /* Returns 0 on error and sets stop */ register address a){unsigned long x;register unsigned char *p;register unsigned char *q = ((unsigned char *) &x) + 3;swap amask;unsigned long index; a &= Physical_Address_Mask; /*The top word of a physical address is ignored*/ p = VAX2MAC_address(a); if((a & 0x3) || a >= IPR(MVMEM)) { if(stop == 0) { IPR(MCESR) |= BUS_ERROR; IPR(MCSR) |= NON_EXIST_MEM; exception(FAULT,V_MCV,"Physical address error",2,a,1); } stop = 1; return 0; } *q = *p++;*--q = *p++;*--q = *p++;*--q = *p; /*check for watch points*/ amask.aword = 0x0F << (a & 0x7); index = a >> 3; if(saw_watch_point == 0) saw_watch_point = (vax_mem.watchmap[index] & amask.aword_by_byte[1] ) || (vax_mem.watchmap[index+1] & amask.aword_by_byte[0] ); if(saw_watch_point && r_watch_and_breaks_on && exceptions_on) { exceptions_on = 0; aprintf(hexmode ? "WatchPoint\nRead long at physical address 0x%x":"WatchPoint\nRead long at physical address %u" , a); stop = 1; saw_watch_point = 0; } return x;} int vax_putliR( /* Put a long at the aligned VAX Physical address a */ /* Returns -1 on error and sets stop */ unsigned long l, register address a){register unsigned char *p;register unsigned char *q = ((unsigned char *) &l) + 3;swap amask;unsigned long index; a &= Physical_Address_Mask; /*The top word of a physical address is ignored*/ p = VAX2MAC_address(a); if((a & 0x3) || a >= IPR(MVMEM)) { if( stop == 0 ) { IPR(MCESR) |= BUS_ERROR; IPR(MCSR) |= NON_EXIST_MEM; exception(FAULT,V_MCV,"Physical address error",2,a,1); } stop = 1; return -1; } *p++ = *q;*p++ = *--q;*p++ = *--q;*p = *--q; /*check for watch points*/ amask.aword = 0x0F << (a & 0x7); index = a >> 3; if(saw_watch_point == 0) saw_watch_point = (vax_mem.watchmap[index] & amask.aword_by_byte[1] ) || (vax_mem.watchmap[index+1] & amask.aword_by_byte[0] ); if(saw_watch_point && w_watch_and_breaks_on && exceptions_on) { exceptions_on = 0; aprintf(hexmode ? "WatchPoint\nModified long at physical address 0x%x":"WatchPoint\nModified long at physical address %u" , a); stop = 1; saw_watch_point = 0; } return 0;}/*VIRTUAL ADDRESS FETCH AND PUT INSTRUCTIONS*/byte vax_fetchb( /*fetch a byte given the virtual address*/ address addr){address abyte; if((addr & ~REG_MASK) == REGBASE) return( vax_regs[addr & REG_MASK].contents.as_byte ); if((abyte = check_reference( addr,CMD,RD,0)) == ERROR ) return( (unsigned char) 0 ); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); if(r_watch_and_breaks_on && saw_watch_point && exceptions_on) { exceptions_on = 0; aprintf(hexmode ? "WatchPoint\nReading Byte at 0x%x":"WatchPoint\nReading Byte at %u" , addr); stop = 1; saw_watch_point = 0; } return( vax_fetchbR(abyte) ) ;} word vax_fetchw( /*return the word at the given virtual address*/ address addr){union{ unsigned char word_by_byte[ 2 ]; word mac_word;} t;address abyte;swap amask;unsigned long index; if((addr & ~REG_MASK) == REGBASE) return( vax_regs[addr & REG_MASK].contents.as_word ); if((addr & 0x1FF) == 0x1FF) /*We are going to cross a page boundary*/ { if( (abyte = check_reference( addr++,CMD ,RD,0)) == ERROR ) return( (word) 0); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); t.word_by_byte[ 1 ] = vax_fetchbR(abyte); if( (abyte = check_reference( addr--,CMD ,RD,0)) == ERROR ) return( (word) 0); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); t.word_by_byte[ 0 ] = vax_fetchbR(abyte); } else { if( (abyte = check_reference( addr,CMD ,RD,0)) == ERROR ) return( (word) 0); /*check for watch points*/ amask.aword = 0x03 << (abyte & 0x7); index = abyte >> 3; if(saw_watch_point == 0) { saw_watch_point = ( vax_mem.watchmap[index] & amask.aword_by_byte[1]) || ( vax_mem.watchmap[index+1] & amask.aword_by_byte[0] ); } t.word_by_byte[ 1 ] = vax_fetchbR(abyte++); t.word_by_byte[ 0 ] = vax_fetchbR(abyte); } if(saw_watch_point && r_watch_and_breaks_on && exceptions_on) { exceptions_on = 0; aprintf(hexmode ? "WatchPoint\nReading word at 0x%x":"WatchPoint\nReading word at %u" , addr); stop = 1; saw_watch_point = 0; } return( t.mac_word );} long vax_fetchl( /*fetch a long word given the VAX virtual address*/ address addr){union{ unsigned char long_by_byte[ 4 ]; long mac_Long;} t;address abyte;swap amask;unsigned long index; if((addr & ~REG_MASK) == REGBASE) return( ( long ) vax_regs[addr & REG_MASK].contents.as_long ); if((addr & 0x1FC) == 0x1FC && (addr & 3)) /*We are going to cross a page boundary*/ { if( (abyte = check_reference( addr++,CMD ,RD, 0)) == ERROR ) return( ( long ) 0); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); t.long_by_byte[ 3 ] = vax_fetchbR(abyte); if( (abyte = check_reference( addr++,CMD ,RD, 0)) == ERROR ) return( ( long ) 0); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; t.long_by_byte[ 2 ] = vax_fetchbR(abyte); if( (abyte = check_reference( addr++,CMD ,RD, 0)) == ERROR ) return( ( long ) 0); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); t.long_by_byte[ 1 ] = vax_fetchbR(abyte); if( (abyte = check_reference( addr,CMD ,RD, 0)) == ERROR ) return( ( long ) 0); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); t.long_by_byte[ 0 ] = vax_fetchbR(abyte); addr -= 3; } else { if( (abyte = check_reference( addr,CMD ,RD, 0)) == ERROR ) return( ( long ) 0); /*check for watch points*/ amask.aword = 0x0F << (abyte & 0x7); index = abyte >> 3; if(saw_watch_point == 0) saw_watch_point = (vax_mem.watchmap[index] & amask.aword_by_byte[1] ) || (vax_mem.watchmap[index+1] & amask.aword_by_byte[0] ); t.long_by_byte[ 3 ] = vax_fetchbR(abyte++); t.long_by_byte[ 2 ] = vax_fetchbR(abyte++); t.long_by_byte[ 1 ] = vax_fetchbR(abyte++); t.long_by_byte[ 0 ] = vax_fetchbR(abyte); } if(saw_watch_point && r_watch_and_breaks_on && exceptions_on) { exceptions_on = 0; aprintf(hexmode ? "WatchPoint\nReading Long at 0x%x":"WatchPoint\nReading Long at %u" , addr); stop = 1; saw_watch_point = 0; } return( t.mac_Long );} quad vax_fetchq( /*fetch a quad word given the VAX virtual address*/ address addr){union{ unsigned char quad_by_byte[8]; quad mac_quad;} t;address abyte;swap amask;unsigned long index; if((addr & ~REG_MASK) == REGBASE) { addr &= REG_MASK; t.mac_quad.long0 = vax_regs[addr].contents.as_ulong; if(addr == 0xF) addr = 0; else addr++; t.mac_quad.long1 = vax_regs[addr].contents.as_long; return t.mac_quad; } if((addr & 0x1F8) == 0x1F8 && ( addr & 0x7 )) { if( (abyte = check_reference( addr++,CMD ,RD,0)) == ERROR ) return( quad_zero ); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); t.quad_by_byte[7] = vax_fetchbR(abyte); if( (abyte = check_reference( addr++,CMD ,RD,0)) == ERROR ) return( quad_zero ); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); t.quad_by_byte[6] = vax_fetchbR(abyte); if( (abyte = check_reference( addr++,CMD ,RD,0)) == ERROR ) return( quad_zero ); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; t.quad_by_byte[5] = vax_fetchbR(abyte); if( (abyte = check_reference( addr++,CMD ,RD,0)) == ERROR ) return( quad_zero ); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; t.quad_by_byte[4] = vax_fetchbR(abyte); if( (abyte = check_reference( addr++,CMD ,RD,0)) == ERROR ) return( quad_zero ); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; t.quad_by_byte[3] = vax_fetchbR(abyte); if( (abyte = check_reference( addr++,CMD ,RD,0)) == ERROR ) return( quad_zero ); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; t.quad_by_byte[2] = vax_fetchbR(abyte); if( (abyte = check_reference( addr++,CMD ,RD,0)) == ERROR ) return( quad_zero ); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); t.quad_by_byte[1] = vax_fetchbR(abyte); if( (abyte = check_reference( addr,CMD ,RD,0)) == ERROR ) return( quad_zero ); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; t.quad_by_byte[0] = vax_fetchbR(abyte); addr -= 7; } else { if( (abyte = check_reference( addr,CMD ,RD,0)) == ERROR ) return( quad_zero ); /*check for watch points*/ amask.aword = 0xFF << (abyte & 0x7); index = abyte >> 3; if(saw_watch_point == 0) saw_watch_point = (vax_mem.watchmap[index] & amask.aword_by_byte[1] ) || (vax_mem.watchmap[index+1] & amask.aword_by_byte[0] ); t.quad_by_byte[7] = vax_fetchbR(abyte++); t.quad_by_byte[6] = vax_fetchbR(abyte++); t.quad_by_byte[5] = vax_fetchbR(abyte++); t.quad_by_byte[4] = vax_fetchbR(abyte++); t.quad_by_byte[3] = vax_fetchbR(abyte++); t.quad_by_byte[2] = vax_fetchbR(abyte++); t.quad_by_byte[1] = vax_fetchbR(abyte++); t.quad_by_byte[0] = vax_fetchbR(abyte); } if(saw_watch_point && r_watch_and_breaks_on && exceptions_on) { exceptions_on = 0; aprintf(hexmode ? "WatchPoint\nReading quad atn 0x%x":"WatchPoint\nReading quad at %u" , addr); stop = 1; } return( t.mac_quad );}oct vax_fetcho( /*fetch a oct word given the VAX virtual address*/ address addr){oct mac_oct; if((addr & ~REG_MASK) == REGBASE) { /*Octs stored in registers in reverse long order*/ addr &= REG_MASK; mac_oct.long0 = vax_regs[addr].contents.as_ulong; if(addr == 0xF) addr = 0; else addr++; mac_oct.long1 = vax_regs[addr].contents.as_ulong; if(addr == 0xF) addr = 0; else addr++; mac_oct.long2 = vax_regs[addr].contents.as_ulong; if(addr == 0xF) addr = 0; else addr++; mac_oct.long3 = vax_regs[addr].contents.as_long; return mac_oct; } mac_oct.long0 = (unsigned long)vax_fetchl(addr); addr += 4; mac_oct.long1 = (unsigned long)vax_fetchl(addr); addr += 4; mac_oct.long2 = (unsigned long)vax_fetchl(addr); addr += 4; mac_oct.long3 = (long)vax_fetchl(addr); if(stop_writes == 1) /*We had a memory fault?*/ return(oct_zero); return(mac_oct);}long vax_fetchv( /*Fetch a size bits from VAX memory*/ address base, long position, unsigned char size){union{ quad t; byte ttt[8];} result;long shift;long nbytes;long i; if(size == 0) return 0; /* nothing to extract */ if(size > 32) { exception(FAULT,V_RO,"Reseverd Operand Fault",0,0); return 0; /* size too large */ } if((base & ~REG_MASK) == REGBASE) { if(position > 31 || position < 0) { exception(FAULT,V_RO,"Reseverd Operand Fault",0,0); return 0; } if(position + size > 32) { /* have to fetch from the reg specified + next one */ result.t = vax_fetchq(base); result.t.long0 = ((((result.t.long0 >> position) & ((1 << (32 - position)) - 1)) | (result.t.long1 << (32 - position))) & ((1 << size ) - 1)) ; } else { result.t.long0 = (vax_fetchl(base) >> position) & ((1 << size ) - 1) ; } } else { shift = position & 7; /* get bit in byte of start position*/ base += position >> 3; /*calculate start byte*/ nbytes = (size+7)/8; if(size + shift > (nbytes * 8)) nbytes++; result.t = quad_zero; i = 7; do { result.ttt[i--] = vax_fetchb(base++); } while(--nbytes > 0); result.t.long0 = ( ( ( (result.t.long0 >> shift) & ( ( 1 << (32 - shift) ) - 1) ) | (result.t.long1 << (32 - shift)) ) & ( (1 << size ) - 1) ) ; } return(result.t.long0);}v_float vax_fetchf( /*fetch a float given the VAX virtual address*/ address a){v_float v; v.f = vax_fetchl(a); return v;} long vax_putb( /*Write "value" to VAX address "addr" */ /*Return -1 on error */ /*If the external long stop_writes is set an error will be returned */ unsigned char value, address addr){address abyte; if(stop_writes) return -1; if((addr & ~REG_MASK) == REGBASE) { vax_regs[addr & REG_MASK].contents.as_byte = (value & BYTE_MASK); return 0; /*ok*/ } if((abyte = check_reference( addr,CMD,WR,1)) == ERROR ) return -1; /*failed*/ vax_putbR(value, abyte); if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); if(saw_watch_point && w_watch_and_breaks_on && exceptions_on) { exceptions_on = 0; aprintf(hexmode ? "WatchPoint\nWriting Byte at 0x%x":"WatchPoint\nWriting Byte at %u" , addr); stop = 1; saw_watch_point = 0; } return 0; /*ok*/} long vax_putw( /*Write "value" to VAX address "addr" */ /*Return -1 on error */ /*If the external long stop_writes is set an error will be returned */ word value, address addr){union{ unsigned char word_by_byte[ 2 ]; word mac_word;} t;address abyte;swap amask;unsigned long index; if(stop_writes) return -1; if((addr & ~REG_MASK) == REGBASE) { vax_regs[addr & REG_MASK].contents.as_word = (value & WORD_MASK) ; return 0; /*ok*/ } t.mac_word = value; if((addr & 0x1FF) == 0x1FF) /*We are going to cross a page boundary*/ { if( (abyte = check_reference( addr++,CMD ,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); vax_putbR(t.word_by_byte[ 1 ],abyte); if( (abyte = check_reference( addr--,CMD ,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); vax_putbR(t.word_by_byte[ 0 ],abyte); } else { if( (abyte = check_reference( addr,CMD ,WR,1)) == ERROR ) return -1; /*failed*/ /*check for watch points*/ amask.aword = 0x03 << (abyte & 0x7); index = abyte >> 3; if(saw_watch_point == 0) saw_watch_point = (vax_mem.watchmap[index] & amask.aword_by_byte[1] ) || (vax_mem.watchmap[index+1] & amask.aword_by_byte[0] ); vax_putbR(t.word_by_byte[ 1 ],abyte++); vax_putbR(t.word_by_byte[ 0 ],abyte); } if(saw_watch_point && w_watch_and_breaks_on && exceptions_on) { exceptions_on = 0; aprintf(hexmode ? "WatchPoint\nWriting Word at 0x%x":"WatchPoint\nWriting Word at %u" , addr); stop = 1; saw_watch_point = 0; } return 0; /*ok*/}long vax_putl( /*Write "value" to VAX address "addr" */ /*Return -1 on error */ /*If the external long stop_writes is set an error will be returned */ long value, address addr){union{ byte long_by_byte[ 4 ]; unsigned long mac_Long;} t;address abyte;swap amask;unsigned long index; if(stop_writes) return -1; if((addr & ~REG_MASK) == REGBASE) { vax_regs[addr & REG_MASK].contents.as_long = value; return 0; /*ok*/ } t.mac_Long = value; if((addr & 0x1FC) == 0x1FC && (addr & 3)) /*We are going to cross a page boundary*/ { if((abyte = check_reference( addr++ ,CMD,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); vax_putbR(t.long_by_byte[ 3 ],abyte); if((abyte = check_reference( addr++ ,CMD,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; vax_putbR(t.long_by_byte[ 2 ],abyte); if((abyte = check_reference( addr++ ,CMD,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; vax_putbR(t.long_by_byte[ 1 ],abyte); if((abyte = check_reference( addr ,CMD,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; vax_putbR(t.long_by_byte[ 0 ],abyte); addr -= 3; } else { if((abyte = check_reference( addr ,CMD,WR,1)) == ERROR ) return -1; /*failed*/ /*check for watch points*/ amask.aword = 0x0F << (abyte & 0x7); index = abyte >> 3; if(saw_watch_point == 0) saw_watch_point = (vax_mem.watchmap[index] & amask.aword_by_byte[1] ) || (vax_mem.watchmap[index+1] & amask.aword_by_byte[0] ); vax_putbR(t.long_by_byte[ 3 ],abyte++); vax_putbR(t.long_by_byte[ 2 ],abyte++); vax_putbR(t.long_by_byte[ 1 ],abyte++); vax_putbR(t.long_by_byte[ 0 ],abyte); } if(saw_watch_point && w_watch_and_breaks_on && exceptions_on) { exceptions_on = 0; aprintf(hexmode ? "WatchPoint\nWriting Long at 0x%x":"WatchPoint\nWriting Long at %u" , addr); stop = 1; saw_watch_point = 0; } return 0; /*ok*/} int vax_putq( /*Write "value" to VAX address "addr" */ /*Return -1 on error */ /*If the external long stop_writes is set an error will be returned */ quad value, address addr){union{ byte quad_by_byte[8]; quad mac_quad;} t;address abyte;swap amask;unsigned long index; if(stop_writes) return -1; if((addr & ~REG_MASK) == REGBASE) { addr &= REG_MASK; vax_regs[addr].contents.as_ulong = value.long0; if(addr == 0xF) addr = 0; else addr++; vax_regs[addr].contents.as_long = value.long1; return 0; /*ok*/ } t.mac_quad = value; if((addr & 0x1F8) == 0x1F8 && ( addr & 0x7 )) { if((abyte = check_reference( addr++,CMD ,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); vax_putbR(t.quad_by_byte[7],abyte); if((abyte = check_reference( addr++,CMD ,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; vax_putbR(t.quad_by_byte[6],abyte); if((abyte = check_reference( addr++,CMD ,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; vax_putbR(t.quad_by_byte[5],abyte); if((abyte = check_reference( addr++,CMD ,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; vax_putbR(t.quad_by_byte[4],abyte); if((abyte = check_reference( addr++,CMD ,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); vax_putbR(t.quad_by_byte[3],abyte); if((abyte = check_reference( addr++,CMD ,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)) ; vax_putbR(t.quad_by_byte[2],abyte); if((abyte = check_reference( addr++,CMD ,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); vax_putbR(t.quad_by_byte[1],abyte); if((abyte = check_reference( addr,CMD ,WR,1)) == ERROR ) return -1; /*failed*/ if(saw_watch_point == 0) saw_watch_point = vax_mem.watchmap[abyte >> 3] & (1 << (abyte & 0x7)); vax_putbR(t.quad_by_byte[0],abyte); addr -= 7; } else { if((abyte = check_reference( addr,CMD ,WR,1)) == ERROR ) return -1; /*failed*/ /*check for watch points*/ amask.aword = 0xFF << (abyte & 0x7); index = abyte >> 3; if(saw_watch_point == 0) saw_watch_point = (vax_mem.watchmap[index] & amask.aword_by_byte[1] ) || (vax_mem.watchmap[index+1] & amask.aword_by_byte[0] ); vax_putbR(t.quad_by_byte[7],abyte++); vax_putbR(t.quad_by_byte[6],abyte++); vax_putbR(t.quad_by_byte[5],abyte++); vax_putbR(t.quad_by_byte[4],abyte++); vax_putbR(t.quad_by_byte[3],abyte++); vax_putbR(t.quad_by_byte[2],abyte++); vax_putbR(t.quad_by_byte[1],abyte++); vax_putbR(t.quad_by_byte[0],abyte); } if(saw_watch_point && w_watch_and_breaks_on && exceptions_on) { exceptions_on = 0; aprintf(hexmode ? "WatchPoint\nWriting Quad at 0x%x":"WatchPoint\nWriting Quad at %u" , addr); stop = 1; saw_watch_point = 0; } return 0; /*ok*/} int vax_puto( /*Write "value" to VAX address "addr" */ /*Return -1 on error */ /*If the external long stop_writes is set an error will be returned */ oct value, address addr){ if(stop_writes) return -1; if((addr & ~REG_MASK) == REGBASE) { addr &= REG_MASK; vax_regs[addr].contents.as_ulong = value.long0; if(addr == 0xF) addr = 0; else addr++; vax_regs[addr].contents.as_ulong = value.long1; if(addr == 0xF) addr = 0; else addr++; vax_regs[addr].contents.as_ulong = value.long2; if(addr == 0xF) addr = 0; else addr++; vax_regs[addr].contents.as_long = value.long3; return 0; /*ok*/ } else { /*low long to hi long*/ if(vax_putl((long)value.long0,addr) == ERROR) return ERROR; addr += 4; if(vax_putl((long)value.long1,addr) == ERROR) return ERROR; addr += 4; if(vax_putl((long)value.long2,addr) == ERROR) return ERROR; addr += 4; if(vax_putl(value.long3,addr) == ERROR) return ERROR; } return 0; /*ok*/} int vax_putv( /*Write "value" to VAX address bitfield specified by base,size,position */ /*Return -1 on error */ /*If the external long stop_writes is set an error will be returned */ long value, address base, long position, unsigned char size){union{ quad t; unsigned char ttt[8];} result;long bmask;long tmask;long shift;long nbytes;long i;long j; if(stop_writes) return -1; if(size == 0) return 0 ; /* nothing to add */ if(size > 32) { exception(FAULT,V_RO,"Reseverd Operand Fault",0,0); return -1; /* size too large */ } if((base & ~REG_MASK) == REGBASE) { if(position > 31 || position < 0) { exception(FAULT,V_RO,"Reseverd Operand Fault",0,0); return -1; } if(position + size > 32) { /* have to put into the reg specified + next one */ result.t = vax_fetchq(base); bmask = ((1 << size ) - 1) << position; tmask = (unsigned long)((1 << size ) - 1) >> (32 - position); result.t.long0 = (result.t.long0 & ~bmask) | ( (value << position) & bmask ); result.t.long1 = (result.t.long1 & ~tmask) | ( (value >> (32 - position)) & tmask ); vax_putq(result.t,base); return 0; } else { bmask = (((1 << size ) - 1) << position); result.t.long0 = (vax_fetchl(base) & ~bmask) | ( (value << position) & bmask ); vax_putl(result.t.long0,base); return 0; } } else { shift = position & 7; /* get bit in byte of start position*/ base += (position >> 3); /*calculate start byte*/ nbytes = (size+7)/8 ; if(size + shift > (nbytes * 8)) nbytes++; result.t = quad_zero; i = 7; j = base; do { result.ttt[i--] = vax_fetchb(j++); } while(--nbytes > 0); bmask = ((1 << size ) - 1) << shift; tmask = (unsigned long)((1 << size ) - 1) >> (32 - shift); result.t.long0 = (result.t.long0 & ~bmask) | ( (value << shift) & bmask ); result.t.long1 = (result.t.long1 & ~tmask) | ( (value >> (32 - shift)) & tmask ); nbytes = (size+7)/8 ; if(size + shift > (nbytes * 8)) nbytes++; i = 7; j = base; do { vax_putb(result.ttt[i--],j++); } while(--nbytes > 0); return 0; }}long vax_putf( /*write a float to a given VAX virtual address*/ /*Return -1 on error */ /*If the external long stop_writes is set an error will be returned */ v_float v, address a){ return vax_putl(v.f,a);}