Diff for /np2/i386c/ia32/cpu_mem.mcr between versions 1.3 and 1.9

version 1.3, 2004/03/25 15:08:32 version 1.9, 2012/01/08 19:09:40
Line 1 Line 1
 /*      $Id$    */  
   
 /*  /*
  * Copyright (c) 2004 NONAKA Kimihiro   * Copyright (c) 2004 NONAKA Kimihiro
  * All rights reserved.   * All rights reserved.
Line 12 Line 10
  * 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 27 Line 23
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */   */
   
 #define VIRTUAL_ADDRESS_MEMORY_ACCESS_FUNCTION(width, valtype, length) \  #define DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(width, valtype, length) \
 valtype MEMCALL \  valtype MEMCALL \
 cpu_vmemoryread_##width(int idx, UINT32 offset) \  cpu_vmemoryread_##width(int idx, UINT32 offset) \
 { \  { \
         descriptor_t *sd; \          descriptor_t *sdp; \
         UINT32 addr; \          UINT32 addr; \
         int exc; \          int exc; \
 \  \
         __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \          __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \
 \  \
         sd = &CPU_STAT_SREG(idx); \          sdp = &CPU_STAT_SREG(idx); \
         if (!sd->valid) { \          addr = sdp->u.seg.segbase + offset; \
                 exc = GP_EXCEPTION; \  
                 goto err; \  
         } \  
 \  \
         if (!(sd->flag & CPU_DESC_FLAG_READABLE)) { \          if (!CPU_STAT_PM) \
                 cpu_memoryread_check(sd, offset, (length), \  
                     (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); \  
         } else { \  
                 switch (sd->type) { \  
                 case 4: case 5: case 6: case 7: \  
                         if (offset - ((length) - 1) <= sd->u.seg.limit) \  
                                 goto range_failure; \  
                         break; \  
 \  
                 default: \  
                         if (offset > sd->u.seg.limit - ((length) - 1)) \  
                                 goto range_failure; \  
                         break; \  
                 } \  
         }  \  
         addr = sd->u.seg.segbase + offset; \  
         check_memory_break_point(addr, (length), CPU_DR7_RW_RO); \  
         if (!CPU_STAT_PAGING) \  
                 return cpu_memoryread_##width(addr); \                  return cpu_memoryread_##width(addr); \
         return cpu_linear_memory_read_##width(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); \  
 \  \
 range_failure: \          if (!SEG_IS_VALID(sdp)) { \
         if (idx == CPU_SS_INDEX) { \  
                 exc = SS_EXCEPTION; \  
         } else { \  
                 exc = GP_EXCEPTION; \                  exc = GP_EXCEPTION; \
                   goto err; \
           } \
           if (!(sdp->flag & CPU_DESC_FLAG_READABLE)) { \
                   cpu_memoryread_check(sdp, offset, (length), \
                       CHOOSE_EXCEPTION(idx)); \
           } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { \
                   if (!check_limit_upstairs(sdp, offset, (length))) \
                           goto range_failure; \
         } \          } \
         VERBOSE(("cpu_vmemoryread: type = %d, offset = %08x, length = %d, limit = %08x", sd->type, offset, length, sd->u.seg.limit)); \          return cpu_lmemoryread_##width(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); \
   \
   range_failure: \
           VERBOSE(("cpu_vmemoryread_" #width ": type = %d, offset = %08x, length = %d, limit = %08x", sdp->type, offset, length, sdp->u.seg.limit)); \
           exc = CHOOSE_EXCEPTION(idx); \
 err: \  err: \
         EXCEPTION(exc, 0); \          EXCEPTION(exc, 0); \
         return 0;       /* compiler happy */ \          return 0;       /* compiler happy */ \
Line 80  err: \ Line 63  err: \
 void MEMCALL \  void MEMCALL \
 cpu_vmemorywrite_##width(int idx, UINT32 offset, valtype value) \  cpu_vmemorywrite_##width(int idx, UINT32 offset, valtype value) \
 { \  { \
         descriptor_t *sd; \          descriptor_t *sdp; \
         UINT32 addr; \          UINT32 addr; \
         int exc; \          int exc; \
 \  \
         __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \          __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \
 \  \
         sd = &CPU_STAT_SREG(idx); \          sdp = &CPU_STAT_SREG(idx); \
         if (!sd->valid) { \          addr = sdp->u.seg.segbase + offset; \
   \
           if (!CPU_STAT_PM) { \
                   cpu_memorywrite_##width(addr, value); \
                   return; \
           } \
   \
           if (!SEG_IS_VALID(sdp)) { \
                 exc = GP_EXCEPTION; \                  exc = GP_EXCEPTION; \
                 goto err; \                  goto err; \
         } \          } \
 \          if (!(sdp->flag & CPU_DESC_FLAG_WRITABLE)) { \
         if (!(sd->flag & CPU_DESC_FLAG_WRITABLE)) { \                  cpu_memorywrite_check(sdp, offset, (length), \
                 cpu_memorywrite_check(sd, offset, (length), \                      CHOOSE_EXCEPTION(idx)); \
                     (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); \          } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { \
         } else { \                  if (!check_limit_upstairs(sdp, offset, (length))) \
                 switch (sd->type) { \                          goto range_failure; \
                 case 6: case 7: \  
                         if (offset - ((length) - 1) <= sd->u.seg.limit) \  
                                 goto range_failure; \  
                         break; \  
 \  
                 default: \  
                         if (offset > sd->u.seg.limit - ((length) - 1)) \  
                                 goto range_failure; \  
                         break; \  
                 } \  
         } \  
         addr = sd->u.seg.segbase + offset; \  
         check_memory_break_point(addr, (length), CPU_DR7_RW_RW); \  
         if (!CPU_STAT_PAGING) { \  
                 cpu_memorywrite_##width(addr, value); \  
         } else { \  
                 cpu_linear_memory_write_##width(addr, value, CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE); \  
         } \          } \
           cpu_lmemorywrite_##width(addr, value, CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE); \
         return; \          return; \
 \  \
 range_failure: \  range_failure: \
         if (idx == CPU_SS_INDEX) { \          VERBOSE(("cpu_vmemorywrite_" #width ": type = %d, offset = %08x, length = %d, limit = %08x", sdp->type, offset, length, sdp->u.seg.limit)); \
                 exc = SS_EXCEPTION; \          exc = CHOOSE_EXCEPTION(idx); \
         } else { \  
                 exc = GP_EXCEPTION; \  
         } \  
         VERBOSE(("cpu_vmemorywrite: type = %d, offset = %08x, length = %d, limit = %08x", sd->type, offset, length, sd->u.seg.limit)); \  
 err: \  err: \
         EXCEPTION(exc, 0); \          EXCEPTION(exc, 0); \
 } \  }
 \  
   #define DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(width, valtype, length) \
 UINT32 MEMCALL \  UINT32 MEMCALL \
 cpu_memory_access_va_RMW_##width(int idx, UINT32 offset, UINT32 (*func)(UINT32, void *), void *arg) \  cpu_vmemory_RMW_##width(int idx, UINT32 offset, UINT32 (CPUCALL *func)(UINT32, void *), void *arg) \
 { \  { \
         descriptor_t *sd; \          descriptor_t *sdp; \
         UINT32 addr; \          UINT32 addr; \
         UINT32 res, dst; \          UINT32 result; \
           valtype value; \
         int exc; \          int exc; \
 \  \
         __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \          __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \
 \  \
         sd = &CPU_STAT_SREG(idx); \          sdp = &CPU_STAT_SREG(idx); \
         if (!sd->valid) { \          addr = sdp->u.seg.segbase + offset; \
   \
           if (!CPU_STAT_PM) { \
                   value = cpu_memoryread_##width(addr); \
                   result = (*func)(value, arg); \
                   cpu_memorywrite_##width(addr, result); \
                   return value; \
           } \
   \
           if (!SEG_IS_VALID(sdp)) { \
                 exc = GP_EXCEPTION; \                  exc = GP_EXCEPTION; \
                 goto err; \                  goto err; \
         } \          } \
 \          if (!(sdp->flag & CPU_DESC_FLAG_WRITABLE)) { \
         if (!(sd->flag & CPU_DESC_FLAG_WRITABLE)) { \                  cpu_memorywrite_check(sdp, offset, (length), \
                 cpu_memorywrite_check(sd, offset, (length), \                      CHOOSE_EXCEPTION(idx)); \
                     (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); \          } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { \
         } else { \                  if (!check_limit_upstairs(sdp, offset, (length))) \
                 switch (sd->type) { \                          goto range_failure; \
                 case 6: case 7: \  
                         if (offset - ((length) - 1) <= sd->u.seg.limit) \  
                                 goto range_failure; \  
                         break; \  
 \  
                 default: \  
                         if (offset > sd->u.seg.limit - ((length) - 1)) \  
                                 goto range_failure; \  
                         break; \  
                 } \  
         } \  
         addr = sd->u.seg.segbase + offset; \  
         check_memory_break_point(addr, (length), CPU_DR7_RW_RW); \  
         if (!CPU_STAT_PAGING) { \  
                 dst = cpu_memoryread_##width(addr); \  
                 res = (*func)(dst, arg); \  
                 cpu_memorywrite_##width(addr, res); \  
         } else { \  
                 dst = cpu_memory_access_la_RMW_##width(addr, func, arg); \  
         } \          } \
         return dst; \          return cpu_lmemory_RMW_##width(addr, func, arg); \
 \  \
 range_failure: \  range_failure: \
         if (idx == CPU_SS_INDEX) { \          VERBOSE(("cpu_vmemory_RMW_" #width ": type = %d, offset = %08x, length = %d, limit = %08x", sdp->type, offset, length, sdp->u.seg.limit)); \
                 exc = SS_EXCEPTION; \          exc = CHOOSE_EXCEPTION(idx); \
         } else { \  
                 exc = GP_EXCEPTION; \  
         } \  
         VERBOSE(("cpu_memory_access_va_RMW: type = %d, offset = %08x, length = %d, limit = %08x", sd->type, offset, length, sd->u.seg.limit)); \  
 err: \  err: \
         EXCEPTION(exc, 0); \          EXCEPTION(exc, 0); \
         return 0;       /* compiler happy */ \          return 0;       /* compiler happy */ \

Removed from v.1.3  
changed lines
  Added in v.1.9


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