Diff for /np2/i386c/ia32/cpu_mem.c between versions 1.14 and 1.21

version 1.14, 2004/03/12 13:34:08 version 1.21, 2005/03/12 12:32:54
Line 1 Line 1
 /*      $Id$    */  /*      $Id$    */
   
 /*  /*
  * Copyright (c) 2002-2003 NONAKA Kimihiro   * Copyright (c) 2002-2004 NONAKA Kimihiro
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 12 Line 12
  * 2. Redistributions in binary form must reproduce the above copyright   * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the   *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.   *    documentation and/or other materials provided with the distribution.
  * 3. The name of the author may not be used to endorse or promote products  
  *    derived from this software without specific prior written permission.  
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Line 252  cpu_stack_pop_check(UINT16 s, descriptor Line 250  cpu_stack_pop_check(UINT16 s, descriptor
         }          }
 }  }
   
   
 #if defined(IA32_SUPPORT_PREFETCH_QUEUE)  
 /*  
  * code prefetch  
  */  
 #define CPU_PREFETCHQ_MASK      (CPU_PREFETCH_QUEUE_LENGTH - 1)  
   
 INLINE static MEMCALL void  
 cpu_prefetch(UINT32 address)  
 {  
         UINT offset = address & CPU_PREFETCHQ_MASK;  
         UINT length = CPU_PREFETCH_QUEUE_LENGTH - offset;  
   
         cpu_memory_access_la_region(address, length, CPU_PAGE_READ_CODE, CPU_STAT_USER_MODE, CPU_PREFETCHQ + offset);  
         CPU_PREFETCHQ_REMAIN = (SINT8)length;  
 }  
   
 INLINE static MEMCALL UINT8  
 cpu_prefetchq(UINT32 address)  
 {  
         UINT8 v;  
   
         CPU_PREFETCHQ_REMAIN--;  
         v = CPU_PREFETCHQ[address & CPU_PREFETCHQ_MASK];  
         return v;  
 }  
   
 INLINE static MEMCALL UINT16  
 cpu_prefetchq_w(UINT32 address)  
 {  
         BYTE *p;  
         UINT16 v;  
   
         CPU_PREFETCHQ_REMAIN -= 2;  
         p = CPU_PREFETCHQ + (address & CPU_PREFETCHQ_MASK);  
         v = LOADINTELWORD(p);  
         return v;  
 }  
   
 INLINE static MEMCALL UINT32  
 cpu_prefetchq_3(UINT32 address)  
 {  
         BYTE *p;  
         UINT32 v;  
   
         CPU_PREFETCHQ_REMAIN -= 3;  
         p = CPU_PREFETCHQ + (address & CPU_PREFETCHQ_MASK);  
         v = LOADINTELWORD(p);  
         v += ((UINT32)p[2]) << 16;  
         return v;  
 }  
   
 INLINE static MEMCALL UINT32  
 cpu_prefetchq_d(UINT32 address)  
 {  
         BYTE *p;  
         UINT32 v;  
   
         CPU_PREFETCHQ_REMAIN -= 4;  
         p = CPU_PREFETCHQ + (address & CPU_PREFETCHQ_MASK);  
         v = LOADINTELDWORD(p);  
         return v;  
 }  
 #endif  /* IA32_SUPPORT_PREFETCH_QUEUE */  
   
 #if defined(IA32_SUPPORT_DEBUG_REGISTER)  #if defined(IA32_SUPPORT_DEBUG_REGISTER)
 INLINE static void  INLINE static void
 check_memory_break_point(UINT32 address, UINT length, UINT rw)  check_memory_break_point(UINT32 address, UINT length, UINT rw)
Line 339  check_memory_break_point(UINT32 address, Line 272  check_memory_break_point(UINT32 address,
 #define check_memory_break_point(address, length, rw)  #define check_memory_break_point(address, length, rw)
 #endif  #endif
   
   
 /*  /*
  * code fetch   * code fetch
  */   */
   #define ucrw    (CPU_PAGE_READ_CODE | CPU_STAT_USER_MODE)
   
 UINT8 MEMCALL  UINT8 MEMCALL
 cpu_codefetch(UINT32 offset)  cpu_codefetch(UINT32 offset)
 {  {
         descriptor_t *sd;          descriptor_t *sd;
         UINT32 addr;          UINT32 addr;
   #if defined(IA32_SUPPORT_TLB)
           TLB_ENTRY_T *ep;
   #endif
   
         sd = &CPU_STAT_SREG(CPU_CS_INDEX);          sd = &CPU_STAT_SREG(CPU_CS_INDEX);
         if (offset <= sd->u.seg.limit) {          if (offset <= sd->u.seg.limit) {
                 addr = sd->u.seg.segbase + offset;                  addr = sd->u.seg.segbase + offset;
 #if defined(IA32_SUPPORT_PREFETCH_QUEUE)                  if (!CPU_STAT_PAGING)
                 if (CPU_PREFETCHQ_REMAIN <= 0) {  
                         cpu_prefetch(addr);  
                 }  
                 return cpu_prefetchq(addr);  
 #else   /* !IA32_SUPPORT_PREFETCH_QUEUE */  
                 if (!CPU_STAT_PM)  
                         return cpu_memoryread(addr);                          return cpu_memoryread(addr);
                 return cpu_lcmemoryread(addr);  #if defined(IA32_SUPPORT_TLB)
 #endif  /* IA32_SUPPORT_PREFETCH_QUEUE */                  ep = tlb_lookup(addr, ucrw);
                   if (ep != NULL && ep->memp != NULL) {
                           return ep->memp[addr & 0xfff];
                   }
   #endif
                   return cpu_linear_memory_read_b(addr, ucrw);
         }          }
         EXCEPTION(GP_EXCEPTION, 0);          EXCEPTION(GP_EXCEPTION, 0);
         return 0;       /* compiler happy */          return 0;       /* compiler happy */
Line 371  cpu_codefetch_w(UINT32 offset) Line 309  cpu_codefetch_w(UINT32 offset)
 {  {
         descriptor_t *sd;          descriptor_t *sd;
         UINT32 addr;          UINT32 addr;
 #if defined(IA32_SUPPORT_PREFETCH_QUEUE)  #if defined(IA32_SUPPORT_TLB)
         UINT16 v;          TLB_ENTRY_T *ep;
           UINT16 value;
 #endif  #endif
   
         sd = &CPU_STAT_SREG(CPU_CS_INDEX);          sd = &CPU_STAT_SREG(CPU_CS_INDEX);
         if (offset <= sd->u.seg.limit - 1) {          if (offset <= sd->u.seg.limit - 1) {
                 addr = sd->u.seg.segbase + offset;                  addr = sd->u.seg.segbase + offset;
 #if defined(IA32_SUPPORT_PREFETCH_QUEUE)                  if (!CPU_STAT_PAGING)
                 if (CPU_PREFETCHQ_REMAIN <= 0) {  
                         cpu_prefetch(addr);  
                 }  
                 if (CPU_PREFETCHQ_REMAIN >= 2) {  
                         return cpu_prefetchq_w(addr);  
                 }  
   
                 v = cpu_prefetchq(addr);  
                 addr++;  
                 cpu_prefetch(addr);  
                 v += (UINT16)cpu_prefetchq(addr) << 8;  
                 return v;  
 #else   /* !IA32_SUPPORT_PREFETCH_QUEUE */  
                 if (!CPU_STAT_PM)  
                         return cpu_memoryread_w(addr);                          return cpu_memoryread_w(addr);
                 return cpu_lcmemoryread_w(addr);  #if defined(IA32_SUPPORT_TLB)
 #endif  /* IA32_SUPPORT_PREFETCH_QUEUE */                  ep = tlb_lookup(addr, ucrw);
                   if (ep != NULL && ep->memp != NULL) {
                           if ((addr + 1) & 0x00000fff) {
                                   return LOADINTELWORD(ep->memp + (addr & 0xfff));
                           }
                           value = ep->memp[0xfff];
                           ep = tlb_lookup(addr + 1, ucrw);
                           if (ep != NULL && ep->memp != NULL) {
                                   value += (UINT16)ep->memp[0] << 8;
                                   return value;
                           }
                   }
   #endif
                   return cpu_linear_memory_read_w(addr, ucrw);
         }          }
         EXCEPTION(GP_EXCEPTION, 0);          EXCEPTION(GP_EXCEPTION, 0);
         return 0;       /* compiler happy */          return 0;       /* compiler happy */
Line 406  cpu_codefetch_d(UINT32 offset) Line 344  cpu_codefetch_d(UINT32 offset)
 {  {
         descriptor_t *sd;          descriptor_t *sd;
         UINT32 addr;          UINT32 addr;
 #if defined(IA32_SUPPORT_PREFETCH_QUEUE)  #if defined(IA32_SUPPORT_TLB)
         UINT32 v;          TLB_ENTRY_T *ep[2];
           UINT32 value;
           UINT remain;
 #endif  #endif
   
         sd = &CPU_STAT_SREG(CPU_CS_INDEX);          sd = &CPU_STAT_SREG(CPU_CS_INDEX);
         if (offset <= sd->u.seg.limit - 3) {          if (offset <= sd->u.seg.limit - 3) {
                 addr = sd->u.seg.segbase + offset;                  addr = sd->u.seg.segbase + offset;
 #if defined(IA32_SUPPORT_PREFETCH_QUEUE)                  if (!CPU_STAT_PAGING)
                 if (CPU_PREFETCHQ_REMAIN <= 0) {                          return cpu_memoryread_d(addr);
                         cpu_prefetch(addr);  #if defined(IA32_SUPPORT_TLB)
                 }                  ep[0] = tlb_lookup(addr, ucrw);
                 if (CPU_PREFETCHQ_REMAIN >= 4) {                  if (ep[0] != NULL && ep[0]->memp != NULL) {
                         return cpu_prefetchq_d(addr);                          remain = 0x1000 - (addr & 0xfff);
                 } else {                          if (remain >= 4) {
                         switch (CPU_PREFETCHQ_REMAIN) {                                  return LOADINTELDWORD(ep[0]->memp + (addr & 0xfff));
                         case 1:                          }
                                 v = cpu_prefetchq(addr);                          ep[1] = tlb_lookup(addr + remain, ucrw);
                                 addr++;                          if (ep[1] != NULL && ep[1]->memp != NULL) {
                                 cpu_prefetch(addr);                                  switch (remain) {
                                 v += (UINT32)cpu_prefetchq_3(addr) << 8;                                  case 3:
                                 break;                                          value = ep[0]->memp[0xffd];
                                           value += (UINT32)LOADINTELWORD(ep[0]->memp + 0xffe) << 8;
                         case 2:                                          value += (UINT32)ep[1]->memp[0] << 24;
                                 v = cpu_prefetchq_w(addr);                                          break;
                                 addr += 2;  
                                 cpu_prefetch(addr);                                  case 2:
                                 v += (UINT32)cpu_prefetchq_w(addr) << 16;                                          value = LOADINTELWORD(ep[0]->memp + 0xffe);
                                 break;                                          value += (UINT32)LOADINTELWORD(ep[1]->memp + 0) << 16;
                                           break;
                         case 3:  
                                 v = cpu_prefetchq_3(addr);                                  case 1:
                                 addr += 3;                                          value = ep[0]->memp[0xfff];
                                 cpu_prefetch(addr);                                          value += (UINT32)LOADINTELWORD(ep[1]->memp + 0) << 8;
                                 v += (UINT32)cpu_prefetchq(addr) << 24;                                          value += (UINT32)ep[1]->memp[2] << 24;
                                 break;                                          break;
   
                                   default:
                                           ia32_panic("cpu_codefetch_d(): out of range. (remain = %d)\n", remain);
                                           return (UINT32)-1;
                                   }
                                   return value;
                         }                          }
                         return v;  
                 }                  }
 #else   /* !IA32_SUPPORT_PREFETCH_QUEUE */  #endif
                 if (!CPU_STAT_PM)                  return cpu_linear_memory_read_d(addr, ucrw);
                         return cpu_memoryread_d(addr);  
                 return cpu_lcmemoryread_d(addr);  
 #endif  /* IA32_SUPPORT_PREFETCH_QUEUE */  
         }          }
         EXCEPTION(GP_EXCEPTION, 0);          EXCEPTION(GP_EXCEPTION, 0);
         return 0;       /* compiler happy */          return 0;       /* compiler happy */
 }  }
   
   
 /*  /*
  * virtual address -> linear address   * additional physical address memory access functions
  */   */
 UINT8 MEMCALL  UINT64 MEMCALL
 cpu_vmemoryread(int idx, UINT32 offset)  cpu_memoryread_q(UINT32 address)
 {  {
         descriptor_t *sd;          UINT64 value;
         UINT32 addr;  
         int exc;  
   
         __ASSERT((unsigned int)idx < CPU_SEGREG_NUM);          value = cpu_memoryread_d(address);
           value += (UINT64)cpu_memoryread_d(address + 4) << 32;
   
         sd = &CPU_STAT_SREG(idx);          return value;
         if (!sd->valid) {  }
                 exc = GP_EXCEPTION;  
                 goto err;  
         }  
   
         if (!(sd->flag & CPU_DESC_FLAG_READABLE)) {  
                 cpu_memoryread_check(sd, offset, 1,  
                     (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION);  
         } else {  
                 switch (sd->type) {  
                 case 4: case 5: case 6: case 7:  
                         if (offset <= sd->u.seg.limit)  
                                 goto range_failure;  
                         break;  
   
                 default:  REG80 MEMCALL
                         if (offset > sd->u.seg.limit)  cpu_memoryread_f(UINT32 address)
                                 goto range_failure;  {
                         break;          REG80 value;
                 }          UINT i;
         }  
         addr = sd->u.seg.segbase + offset;  
         check_memory_break_point(addr, 1, CPU_DR7_RW_RO);  
         if (!CPU_STAT_PM)  
                 return cpu_memoryread(addr);  
         return cpu_lmemoryread(addr, CPU_STAT_USER_MODE);  
   
 range_failure:          for (i = 0; i < sizeof(REG80); ++i) {
         if (idx == CPU_SS_INDEX) {                  value.b[i] = cpu_memoryread(address + i);
                 exc = SS_EXCEPTION;  
         } else {  
                 exc = GP_EXCEPTION;  
         }          }
         VERBOSE(("cpu_vmemoryread: type = %d, offset = %08x, limit = %08x", sd->type, offset, sd->u.seg.limit));          return value;
 err:  
         EXCEPTION(exc, 0);  
         return 0;       /* compiler happy */  
 }  }
   
 UINT16 MEMCALL  void MEMCALL
 cpu_vmemoryread_w(int idx, UINT32 offset)  cpu_memorywrite_q(UINT32 address, UINT64 value)
 {  {
         descriptor_t *sd;  
         UINT32 addr;  
         int exc;  
   
         __ASSERT((unsigned int)idx < CPU_SEGREG_NUM);          cpu_memorywrite_d(address, (UINT32)value);
           cpu_memorywrite_d(address + 4, (UINT32)(value >> 32));
         sd = &CPU_STAT_SREG(idx);  }
         if (!sd->valid) {  
                 exc = GP_EXCEPTION;  
                 goto err;  
         }  
   
         if (!(sd->flag & CPU_DESC_FLAG_READABLE)) {  
                 cpu_memoryread_check(sd, offset, 2,  
                     (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION);  
         } else {  
                 switch (sd->type) {  
                 case 4: case 5: case 6: case 7:  
                         if (offset - 1 <= sd->u.seg.limit)  
                                 goto range_failure;  
                         break;  
   
                 default:  void MEMCALL
                         if (offset > sd->u.seg.limit - 1)  cpu_memorywrite_f(UINT32 address, const REG80 *value)
                                 goto range_failure;  {
                         break;          UINT i;
                 }  
         }   
         addr = sd->u.seg.segbase + offset;  
         check_memory_break_point(addr, 2, CPU_DR7_RW_RO);  
         if (!CPU_STAT_PM)  
                 return cpu_memoryread_w(addr);  
         return cpu_lmemoryread_w(addr, CPU_STAT_USER_MODE);  
   
 range_failure:          for (i = 0; i < sizeof(REG80); ++i) {
         if (idx == CPU_SS_INDEX) {                  cpu_memorywrite(address + i, value->b[i]);
                 exc = SS_EXCEPTION;  
         } else {  
                 exc = GP_EXCEPTION;  
         }          }
         VERBOSE(("cpu_vmemoryread_w: type = %d, offset = %08x, limit = %08x", sd->type, offset, sd->u.seg.limit));  
 err:  
         EXCEPTION(exc, 0);  
         return 0;       /* compiler happy */  
 }  }
   
 UINT32 MEMCALL  /*
 cpu_vmemoryread_d(int idx, UINT32 offset)   * virtual address memory access functions
    */
   #include "cpu_mem.mcr"
   
   VIRTUAL_ADDRESS_MEMORY_ACCESS_FUNCTION(b, UINT8, 1)
   VIRTUAL_ADDRESS_MEMORY_ACCESS_FUNCTION(w, UINT16, 2)
   VIRTUAL_ADDRESS_MEMORY_ACCESS_FUNCTION(d, UINT32, 4)
   
   UINT64 MEMCALL
   cpu_vmemoryread_q(int idx, UINT32 offset)
 {  {
         descriptor_t *sd;          descriptor_t *sd;
         UINT32 addr;          UINT32 addr;
Line 572  cpu_vmemoryread_d(int idx, UINT32 offset Line 465  cpu_vmemoryread_d(int idx, UINT32 offset
         }          }
   
         if (!(sd->flag & CPU_DESC_FLAG_READABLE)) {          if (!(sd->flag & CPU_DESC_FLAG_READABLE)) {
                 cpu_memoryread_check(sd, offset, 4,                  cpu_memoryread_check(sd, offset, 8,
                     (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION);                      (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION);
         } else {          } else {
                 switch (sd->type) {                  switch (sd->type) {
                 case 4: case 5: case 6: case 7:                  case 4: case 5: case 6: case 7:
                         if (offset - 3 <= sd->u.seg.limit)                          if (offset - (8 - 1) <= sd->u.seg.limit)
                                 goto range_failure;                                  goto range_failure;
                         break;                          break;
   
                 default:                  default:
                         if (offset > sd->u.seg.limit - 3)                          if (offset > sd->u.seg.limit - (8 - 1))
                                 goto range_failure;                                  goto range_failure;
                         break;                          break;
                 }                  }
         }          } 
         addr = sd->u.seg.segbase + offset;          addr = sd->u.seg.segbase + offset;
         check_memory_break_point(addr, 4, CPU_DR7_RW_RO);          check_memory_break_point(addr, 8, CPU_DR7_RW_RO);
         if (!CPU_STAT_PM)          if (!CPU_STAT_PAGING)
                 return cpu_memoryread_d(addr);                  return cpu_memoryread_q(addr);
         return cpu_lmemoryread_d(addr, CPU_STAT_USER_MODE);          return cpu_linear_memory_read_q(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE);
   
 range_failure:  range_failure:
         if (idx == CPU_SS_INDEX) {          if (idx == CPU_SS_INDEX) {
Line 599  range_failure: Line 492  range_failure:
         } else {          } else {
                 exc = GP_EXCEPTION;                  exc = GP_EXCEPTION;
         }          }
         VERBOSE(("cpu_vmemoryread_d: type = %d, offset = %08x, limit = %08x", sd->type, offset, sd->u.seg.limit));          VERBOSE(("cpu_vmemoryread_q: type = %d, offset = %08x, limit = %08x", sd->type, offset, sd->u.seg.limit));
 err:  err:
         EXCEPTION(exc, 0);          EXCEPTION(exc, 0);
         return 0;       /* compiler happy */          return 0;       /* compiler happy */
 }  }
   
 /* vaddr memory write */  
 void MEMCALL  void MEMCALL
 cpu_vmemorywrite(int idx, UINT32 offset, UINT8 val)  cpu_vmemorywrite_q(int idx, UINT32 offset, UINT64 value)
 {  {
         descriptor_t *sd;          descriptor_t *sd;
         UINT32 addr;          UINT32 addr;
Line 622  cpu_vmemorywrite(int idx, UINT32 offset, Line 514  cpu_vmemorywrite(int idx, UINT32 offset,
         }          }
   
         if (!(sd->flag & CPU_DESC_FLAG_WRITABLE)) {          if (!(sd->flag & CPU_DESC_FLAG_WRITABLE)) {
                 cpu_memorywrite_check(sd, offset, 1,                  cpu_memorywrite_check(sd, offset, 8,
                     (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION);                      (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION);
         } else {          } else {
                 switch (sd->type) {                  switch (sd->type) {
                 case 6: case 7:                  case 6: case 7:
                         if (offset <= sd->u.seg.limit)                          if (offset - (8 - 1) <= sd->u.seg.limit)
                                 goto range_failure;                                  goto range_failure;
                         break;                          break;
   
                 default:                  default:
                         if (offset > sd->u.seg.limit)                          if (offset > sd->u.seg.limit - (8 - 1))
                                 goto range_failure;                                  goto range_failure;
                         break;                          break;
                 }                  }
         }          }
         addr = sd->u.seg.segbase + offset;          addr = sd->u.seg.segbase + offset;
         check_memory_break_point(addr, 1, CPU_DR7_RW_RW);          check_memory_break_point(addr, 8, CPU_DR7_RW_RW);
         if (!CPU_STAT_PM) {          if (!CPU_STAT_PAGING) {
                 /* real mode */                  cpu_memorywrite_q(addr, value);
                 cpu_memorywrite(addr, val);  
         } else {          } else {
                 /* protected mode */                  cpu_linear_memory_write_q(addr, value, CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE);
                 cpu_lmemorywrite(addr, val, CPU_STAT_USER_MODE);  
         }          }
         return;          return;
   
Line 654  range_failure: Line 544  range_failure:
         } else {          } else {
                 exc = GP_EXCEPTION;                  exc = GP_EXCEPTION;
         }          }
         VERBOSE(("cpu_vmemorywrite: type = %d, offset = %08x, limit = %08x", sd->type, offset, sd->u.seg.limit));          VERBOSE(("cpu_vmemorywrite_q: type = %d, offset = %08x, limit = %08x", sd->type, offset, sd->u.seg.limit));
 err:  err:
         EXCEPTION(exc, 0);          EXCEPTION(exc, 0);
 }  }
   
 void MEMCALL  REG80 MEMCALL
 cpu_vmemorywrite_w(int idx, UINT32 offset, UINT16 val)  cpu_vmemoryread_f(int idx, UINT32 offset)
 {  {
         descriptor_t *sd;          descriptor_t *sd;
         UINT32 addr;          UINT32 addr;
Line 674  cpu_vmemorywrite_w(int idx, UINT32 offse Line 564  cpu_vmemorywrite_w(int idx, UINT32 offse
                 goto err;                  goto err;
         }          }
   
         if (!(sd->flag & CPU_DESC_FLAG_WRITABLE)) {          if (!(sd->flag & CPU_DESC_FLAG_READABLE)) {
                 cpu_memorywrite_check(sd, offset, 2,                  cpu_memoryread_check(sd, offset, 10,
                     (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION);                      (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION);
         } else {          } else {
                 switch (sd->type) {                  switch (sd->type) {
                 case 6: case 7:                  case 4: case 5: case 6: case 7:
                         if (offset - 1 <= sd->u.seg.limit)                          if (offset - (10 - 1) <= sd->u.seg.limit)
                                 goto range_failure;                                  goto range_failure;
                         break;                          break;
   
                 default:                  default:
                         if (offset > sd->u.seg.limit - 1)                          if (offset > sd->u.seg.limit - (10 - 1))
                                 goto range_failure;                                  goto range_failure;
                         break;                          break;
                 }                  }
         }          } 
         addr = sd->u.seg.segbase + offset;          addr = sd->u.seg.segbase + offset;
         check_memory_break_point(addr, 2, CPU_DR7_RW_RW);          check_memory_break_point(addr, 10, CPU_DR7_RW_RO);
         if (!CPU_STAT_PM) {          if (!CPU_STAT_PAGING)
                 /* real mode */                  return cpu_memoryread_f(addr);
                 cpu_memorywrite_w(addr, val);          return cpu_linear_memory_read_f(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE);
         } else {  
                 /* protected mode */  
                 cpu_lmemorywrite_w(addr, val, CPU_STAT_USER_MODE);  
         }  
         return;  
   
 range_failure:  range_failure:
         if (idx == CPU_SS_INDEX) {          if (idx == CPU_SS_INDEX) {
Line 707  range_failure: Line 592  range_failure:
         } else {          } else {
                 exc = GP_EXCEPTION;                  exc = GP_EXCEPTION;
         }          }
         VERBOSE(("cpu_vmemorywrite_w: type = %d, offset = %08x, limit = %08x", sd->type, offset, sd->u.seg.limit));          VERBOSE(("cpu_vmemoryread_f: type = %d, offset = %08x, limit = %08x", sd->type, offset, sd->u.seg.limit));
 err:  err:
         EXCEPTION(exc, 0);          EXCEPTION(exc, 0);
           {
                   REG80 dummy;
                   memset(&dummy, 0, sizeof(dummy));
                   return dummy;   /* compiler happy */
           }
 }  }
   
 void MEMCALL  void MEMCALL
 cpu_vmemorywrite_d(int idx, UINT32 offset, UINT32 val)  cpu_vmemorywrite_f(int idx, UINT32 offset, const REG80 *value)
 {  {
         descriptor_t *sd;          descriptor_t *sd;
         UINT32 addr;          UINT32 addr;
Line 728  cpu_vmemorywrite_d(int idx, UINT32 offse Line 618  cpu_vmemorywrite_d(int idx, UINT32 offse
         }          }
   
         if (!(sd->flag & CPU_DESC_FLAG_WRITABLE)) {          if (!(sd->flag & CPU_DESC_FLAG_WRITABLE)) {
                 cpu_memorywrite_check(sd, offset, 4,                  cpu_memorywrite_check(sd, offset, 10,
                     (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION);                      (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION);
         } else {          } else {
                 switch (sd->type) {                  switch (sd->type) {
                 case 6: case 7:                  case 6: case 7:
                         if (offset - 3 <= sd->u.seg.limit)                          if (offset - (10 - 1) <= sd->u.seg.limit)
                                 goto range_failure;                                  goto range_failure;
                         break;                          break;
   
                 default:                  default:
                         if (offset > sd->u.seg.limit - 3)                          if (offset > sd->u.seg.limit - (10 - 1))
                                 goto range_failure;                                  goto range_failure;
                         break;                          break;
                 }                  }
         }          }
         addr = sd->u.seg.segbase + offset;          addr = sd->u.seg.segbase + offset;
         check_memory_break_point(addr, 4, CPU_DR7_RW_RW);          check_memory_break_point(addr, 10, CPU_DR7_RW_RW);
         if (!CPU_STAT_PM) {          if (!CPU_STAT_PAGING) {
                 /* real mode */                  cpu_memorywrite_f(addr, value);
                 cpu_memorywrite_d(addr, val);  
         } else {          } else {
                 /* protected mode */                  cpu_linear_memory_write_f(addr, value, CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE);
                 cpu_lmemorywrite_d(addr, val, CPU_STAT_USER_MODE);  
         }          }
         return;          return;
   
Line 760  range_failure: Line 648  range_failure:
         } else {          } else {
                 exc = GP_EXCEPTION;                  exc = GP_EXCEPTION;
         }          }
         VERBOSE(("cpu_vmemorywrite_d: type = %d, offset = %08x, limit = %08x", sd->type, offset, sd->u.seg.limit));          VERBOSE(("cpu_vmemorywrite_f: type = %d, offset = %08x, limit = %08x", sd->type, offset, sd->u.seg.limit));
 err:  err:
         EXCEPTION(exc, 0);          EXCEPTION(exc, 0);
 }  }

Removed from v.1.14  
changed lines
  Added in v.1.21


RetroPC.NET-CVS <cvs@retropc.net>