AlphaCPU_vmspal.cpp

Go to the documentation of this file.
00001 /* ES40 emulator.
00002  * Copyright (C) 2007-2008 by the ES40 Emulator Project
00003  *
00004  * WWW    : http://sourceforge.net/projects/es40
00005  * E-mail : camiel@camicom.com
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00020  * 
00021  * Although this is not required, the author would appreciate being notified of, 
00022  * and receiving any modifications you may make to the source code that might serve
00023  * the general public.
00024  */
00025 
00080 #include "StdAfx.h"
00081 #include "AlphaCPU.h"
00082 
00083 #include "Serial.h"
00084 #include "AliM1543C_ide.h"
00085 #include "Disk.h"
00086 
00087 /***********************************************************
00088  *                                                         *
00089  *                      VMS PALcode                        *
00090  *                                                         *
00091  ***********************************************************/
00092 #define p4  state.r[32 + 4]
00093 #define p5  state.r[32 + 5]
00094 #define p6  state.r[32 + 6]
00095 #define p7  state.r[32 + 7]
00096 
00097 #define p20 state.r[32 + 20]
00098 #define p21 state.r[32 + 21]
00099 #define p22 state.r[32 + 22]
00100 #define p23 state.r[32 + 23]
00101 
00102 #define r0  state.r[0]
00103 #define r1  state.r[1]
00104 #define r2  state.r[2]
00105 #define r3  state.r[3]
00106 
00107 //#define r4 state.r[4]
00108 //#define r5 state.r[5]
00109 //#define r6 state.r[6]
00110 //#define r7 state.r[7]
00111 #define r8  state.r[8]
00112 #define r9  state.r[9]
00113 #define r10 state.r[10]
00114 #define r11 state.r[11]
00115 #define r12 state.r[12]
00116 #define r13 state.r[13]
00117 #define r14 state.r[14]
00118 #define r15 state.r[15]
00119 #define r16 state.r[16]
00120 #define r17 state.r[17]
00121 #define r18 state.r[18]
00122 #define r19 state.r[19]
00123 
00124 //#define r20 state.r[20]
00125 //#define r21 state.r[21]
00126 //#define r22 state.r[22]
00127 //#define r23 state.r[23]
00128 #define r24 state.r[24]
00129 
00130 //#define r25 state.r[25]
00131 //#define r26 state.r[26]
00132 #define r27           state.r[27]
00133 #define r28           state.r[28]
00134 #define r29           state.r[29]
00135 #define r30           state.r[30]
00136 #define r31           state.r[31]
00137 
00138 #define hw_stq(a, b)  cSystem->WriteMem(a &~U64(0x7), 64, b, this)
00139 #define hw_stl(a, b)  cSystem->WriteMem(a &~U64(0x3), 32, b, this)
00140 #define stq(a, b)                                        \
00141   if(virt2phys(a, &phys_address, ACCESS_WRITE, NULL, 0)) \
00142     return -1;                                           \
00143   cSystem->WriteMem(phys_address, 64, b, this);
00144 #define ldq(a, b)                                       \
00145   if(virt2phys(a, &phys_address, ACCESS_READ, NULL, 0)) \
00146     return -1;                                          \
00147   b = cSystem->ReadMem(phys_address, 64, this);
00148 #define stl(a, b)                                        \
00149   if(virt2phys(a, &phys_address, ACCESS_WRITE, NULL, 0)) \
00150     return -1;                                           \
00151   cSystem->WriteMem(phys_address, 32, b, this);
00152 #define ldl(a, b)                                       \
00153   if(virt2phys(a, &phys_address, ACCESS_READ, NULL, 0)) \
00154     return -1;                                          \
00155   b = sext_u64_32(cSystem->ReadMem(phys_address, 32, this));
00156 #define ldb(a, b)                                       \
00157   if(virt2phys(a, &phys_address, ACCESS_READ, NULL, 0)) \
00158     return -1;                                          \
00159   b = (char) (cSystem->ReadMem(phys_address, 8, this));
00160 #define hw_ldq(a, b)  b = cSystem->ReadMem(a &~U64(0x7), 64, this)
00161 #define hw_ldl(a, b)  b = sext_u64_32(cSystem->ReadMem(a &~U64(0x3), 32, this));
00162 #define hw_ldbu(a, b) b = cSystem->ReadMem(a, 8, this)
00163 
00172 static int ipl_ier_mask[32][6] =
00173 {
00174 
00175   /* ei, sl, cr, pc,     si, ast */
00176   { 0x3f, 0, 1, 3, 0xfffe, 1 },
00177   { 0x3f, 0, 1, 3, 0xfffc, 1 },
00178   { 0x3f, 0, 1, 3, 0xfff8, 0 },
00179   { 0x3f, 0, 1, 3, 0xfff0, 0 },
00180   { 0x3f, 0, 1, 3, 0xffe0, 0 },
00181   { 0x3f, 0, 1, 3, 0xffc0, 0 },
00182   { 0x3f, 0, 1, 3, 0xff80, 0 },
00183   { 0x3f, 0, 1, 3, 0xff00, 0 },
00184   { 0x3f, 0, 1, 3, 0xfe00, 0 },
00185   { 0x3f, 0, 1, 3, 0xfc00, 0 },
00186   { 0x3f, 0, 1, 3, 0xf800, 0 },
00187   { 0x3f, 0, 1, 3, 0xf000, 0 },
00188   { 0x3f, 0, 1, 3, 0xe000, 0 },
00189   { 0x3f, 0, 1, 3, 0xc000, 0 },
00190   { 0x3f, 0, 1, 3, 0x8000, 0 },
00191   { 0x3f, 0, 1, 3, 0, 0 },
00192   { 0x3f, 0, 1, 3, 0, 0 },
00193   { 0x3f, 0, 1, 3, 0, 0 },
00194   { 0x3f, 0, 1, 3, 0, 0 },
00195   { 0x3f, 0, 1, 3, 0, 0 },
00196   { 0x3f, 0, 1, 3, 0, 0 },
00197   { 0x3d, 0, 1, 3, 0, 0 },
00198   { 0x31, 0, 1, 3, 0, 0 },
00199   { 0x31, 0, 1, 3, 0, 0 },
00200   { 0x31, 0, 1, 3, 0, 0 },
00201   { 0x31, 0, 1, 3, 0, 0 },
00202   { 0x31, 0, 1, 3, 0, 0 },
00203   { 0x31, 0, 1, 3, 0, 0 },
00204   { 0x31, 0, 1, 3, 0, 0 },
00205   { 0x31, 0, 1, 0, 0, 0 },
00206   { 0x31, 0, 1, 3, 0, 0 },
00207   { 0x10, 0, 1, 3, 0, 0 }
00208 };
00209 
00210 /***************************************************************************/
00211 
00217 //\{
00218 
00222 void CAlphaCPU::vmspal_call_cflush()
00223 {
00224 
00225   // don't do anything...
00226 }
00227 
00231 void CAlphaCPU::vmspal_call_draina()
00232 {
00233 
00234   // don't do anything...
00235 }
00236 
00240 void CAlphaCPU::vmspal_call_ldqp()
00241 {
00242   hw_ldq(r16, r0);
00243 }
00244 
00248 void CAlphaCPU::vmspal_call_stqp()
00249 {
00250   hw_stq(r16, r17);
00251 }
00252 
00256 void CAlphaCPU::vmspal_call_swpctx()
00257 {
00258   p23 = state.pc;
00259 
00260   if(r16 & 0x7f)
00261   {
00262 
00263     //context pointer not properly aligned...
00264     p4 = 0x430;
00265     hw_stq(p21 + 0x150, p23);
00266     hw_stq(p21 + 0x158, p4);
00267     vmspal_int_initiate_exception();
00268     return;
00269   }
00270 
00271   hw_ldq(r16 + 0x30, p4);
00272   hw_ldq(r16 + 0x38, p5);
00273   hw_ldq(r16 + 0x28, p6);
00274 
00275   p20 = state.aster | (state.astrr << 4);
00276 
00277   p6 &= 0xff;
00278   state.asn0 = (int) p6;
00279   state.asn1 = (int) p6;
00280   state.asn = (int) p6;
00281   state.aster = (int) p4 & 0xf;
00282   state.astrr = (int) (p4 >> 4) & 0xf;
00283   state.fpen = (int) p5 & 1;
00284   state.ppcen = (int) (p5 >> 0x3e) & 1;
00285   state.check_int = true;
00286 
00287   hw_ldq(r16 + 0x40, p7);
00288   hw_ldq(r16 + 0x20, p6);
00289 
00290   p4 = (state.cc & U64(0xffffffff)) + state.cc_offset;
00291   state.cc_offset = ((u32) p7 & 0xffffffff) - (state.cc & U64(0xffffffff));
00292 
00293   p6 <<= 0x0d;
00294   hw_stq(p21 + 8, p6);
00295   hw_ldq(p21 + 0x10, p5);
00296   hw_ldq(r16, p6);
00297   hw_stl(p5 + 0x40, p4);
00298   hw_stq(p5 + 0x30, p20);
00299   hw_stq(p5, r30);
00300 
00301   r30 = p6;
00302   hw_stq(p21 + 0x10, r16);
00303 }
00304 
00308 void CAlphaCPU::vmspal_call_mfpr_asn()
00309 {
00310   r0 = state.asn;
00311 }
00312 
00316 void CAlphaCPU::vmspal_call_mtpr_asten()
00317 {
00318   r0 = state.aster;
00319   state.aster &= r16;
00320   state.aster |= (r16 >> 4) & 0xf;
00321   state.check_int = true;
00322 }
00323 
00327 void CAlphaCPU::vmspal_call_mtpr_astsr()
00328 {
00329   r0 = state.astrr;
00330   state.astrr &= r16;
00331   state.astrr |= (r16 >> 4) & 0xf;
00332   state.check_int = true;
00333 }
00334 
00338 void CAlphaCPU::vmspal_call_cserve()
00339 {
00340   p23 = state.pc;
00341 
00342   switch(r16)
00343   {
00344   case 0x10:  hw_ldl(r17, r0); break;
00345   case 0x11:  hw_stl(r17, r18); break;
00346   case 0x12:  set_pc(0x12e21); break;
00347   case 0x13:  set_pc(0x12f95); break;
00348   case 0x14:  set_pc(0x13115); break;
00349   case 0x15:  set_pc(0x131c1); break;
00350   case 0x40:  set_pc(0x13249); break;
00351   case 0x41:  hw_ldq(p21 + 0x98, r0); break;
00352   case 0x42:  set_pc(0x13781); break;
00353   case 0x43:  set_pc(0x13261); break;
00354   case 0x44:  set_pc(r17); break;
00355   case 0x45:  set_pc(0x13289); break;
00356   case 0x65:  set_pc(0x132bd); break;
00357   case 0x3e:  set_pc(0x1344d); break;
00358   case 0x66:  set_pc(0x133e9); break;
00359   }
00360 }
00361 
00365 void CAlphaCPU::vmspal_call_mfpr_fen()
00366 {
00367   r0 = state.fpen ? 1 : 0;
00368 }
00369 
00373 void CAlphaCPU::vmspal_call_mtpr_fen()
00374 {
00375   hw_ldq(p21 + 0x10, p4);
00376   state.fpen = (r16 & 1);
00377   hw_stl(p4 + 0x38, r16);
00378 }
00379 
00383 void CAlphaCPU::vmspal_call_mfpr_ipl()
00384 {
00385   r0 = (p22 >> 8) & 0x1f;
00386 }
00387 
00391 void CAlphaCPU::vmspal_call_mtpr_ipl()
00392 {
00393   r0 = (p22 >> 8) & 0xff;
00394   p22 &= ~U64(0xff00);
00395   p22 |= (r16 << 8);
00396   state.eien = ipl_ier_mask[r16][0];
00397   state.slen = ipl_ier_mask[r16][1];
00398   state.cren = ipl_ier_mask[r16][2];
00399   state.pcen = ipl_ier_mask[r16][3];
00400   state.sien = ipl_ier_mask[r16][4];
00401   state.asten = ipl_ier_mask[r16][5];
00402   state.check_int = true;
00403 }
00404 
00408 void CAlphaCPU::vmspal_call_mfpr_mces()
00409 {
00410   r0 = (p22 >> 16) & 0xff;
00411 }
00412 
00416 void CAlphaCPU::vmspal_call_mtpr_mces()
00417 {
00418   p22 = (p22 & U64(0xffffffffff00ffff)) |
00419     (p22 & U64(0x0000000000070000) &~(r16 << 16)) |
00420       ((r16 << 16) & U64(0x0000000000180000));
00421 }
00422 
00426 void CAlphaCPU::vmspal_call_mfpr_pcbb()
00427 {
00428   hw_ldq(p21 + 0x10, r0);
00429 }
00430 
00434 void CAlphaCPU::vmspal_call_mfpr_prbr()
00435 {
00436   hw_ldq(p21 + 0xa8, r0);
00437 }
00438 
00442 void CAlphaCPU::vmspal_call_mtpr_prbr()
00443 {
00444   hw_stq(p21 + 0xa8, r16);
00445 }
00446 
00450 void CAlphaCPU::vmspal_call_mfpr_ptbr()
00451 {
00452   hw_ldq(p21 + 8, r0);
00453   r0 >>= 0x0d;
00454 }
00455 
00459 void CAlphaCPU::vmspal_call_mfpr_scbb()
00460 {
00461   hw_ldq(p21 + 0x170, r0);
00462   r0 >>= 0x0d;
00463 }
00464 
00468 void CAlphaCPU::vmspal_call_mtpr_scbb()
00469 {
00470   hw_stq(p21 + 0x170, (r16 & U64(0xffffffff)) << 0xd);
00471 }
00472 
00476 void CAlphaCPU::vmspal_call_mtpr_sirr()
00477 {
00478   if(r16 > 0 && r16 < 16)
00479   {
00480     state.sir |= 1 << r16;
00481     state.check_int = true;
00482   }
00483 }
00484 
00488 void CAlphaCPU::vmspal_call_mfpr_sisr()
00489 {
00490   r0 = state.sir;
00491 }
00492 
00496 void CAlphaCPU::vmspal_call_mfpr_tbchk()
00497 {
00498   r0 = U64(0x8000000000000000);
00499 }
00500 
00504 void CAlphaCPU::vmspal_call_mtpr_tbia()
00505 {
00506   tbia(ACCESS_READ);
00507   tbia(ACCESS_EXEC);
00508   flush_icache();
00509 }
00510 
00514 void CAlphaCPU::vmspal_call_mtpr_tbiap()
00515 {
00516   tbiap(ACCESS_READ);
00517   tbiap(ACCESS_EXEC);
00518   flush_icache_asm();
00519 }
00520 
00524 void CAlphaCPU::vmspal_call_mtpr_tbis()
00525 {
00526   tbis(r16, ACCESS_READ);
00527   tbis(r16, ACCESS_EXEC);
00528 }
00529 
00533 void CAlphaCPU::vmspal_call_mfpr_esp()
00534 {
00535   u64 t;
00536   hw_ldq(p21 + 0x10, t);
00537   hw_ldq(t + 8, r0);
00538 }
00539 
00543 void CAlphaCPU::vmspal_call_mtpr_esp()
00544 {
00545   u64 t;
00546   hw_ldq(p21 + 0x10, t);
00547   hw_stq(t + 8, r16);
00548 }
00549 
00553 void CAlphaCPU::vmspal_call_mfpr_ssp()
00554 {
00555   u64 t;
00556   hw_ldq(p21 + 0x10, t);
00557   hw_ldq(t + 0x10, r0);
00558 }
00559 
00563 void CAlphaCPU::vmspal_call_mtpr_ssp()
00564 {
00565   u64 t;
00566   hw_ldq(p21 + 0x10, t);
00567   hw_stq(t + 0x10, r16);
00568 }
00569 
00573 void CAlphaCPU::vmspal_call_mfpr_usp()
00574 {
00575   u64 t;
00576   hw_ldq(p21 + 0x10, t);
00577   hw_ldq(t + 0x18, r0);
00578 }
00579 
00583 void CAlphaCPU::vmspal_call_mtpr_usp()
00584 {
00585   u64 t;
00586   hw_ldq(p21 + 0x10, t);
00587   hw_stq(t + 0x18, r16);
00588 }
00589 
00593 void CAlphaCPU::vmspal_call_mtpr_tbisd()
00594 {
00595   tbis(r16, ACCESS_READ);
00596 }
00597 
00601 void CAlphaCPU::vmspal_call_mtpr_tbisi()
00602 {
00603   tbis(r16, ACCESS_EXEC);
00604 }
00605 
00609 void CAlphaCPU::vmspal_call_mfpr_asten()
00610 {
00611   r0 = state.aster;
00612 }
00613 
00617 void CAlphaCPU::vmspal_call_mfpr_astsr()
00618 {
00619   r0 = state.astrr;
00620 }
00621 
00625 void CAlphaCPU::vmspal_call_mfpr_vptb()
00626 {
00627   hw_ldq(p21, r0);
00628 }
00629 
00633 void CAlphaCPU::vmspal_call_mtpr_datfx()
00634 {
00635   u64 t;
00636 
00637   u64 u;
00638   hw_ldq(p21 + 0x10, t);
00639   hw_ldq(t, u);
00640   u |= U64(0x1) << 0x3f;
00641   u &= ~(r16 << 0x3f);
00642   hw_stq(t, u);
00643 }
00644 
00648 void CAlphaCPU::vmspal_call_mfpr_whami()
00649 {
00650   hw_ldq(p21 + 0x98, r0);
00651 }
00652 
00656 void CAlphaCPU::vmspal_call_imb()
00657 {
00658   if(p22 & 0x18)
00659   {
00660     hw_ldq(p21 + 0x10, p20);
00661     hw_ldl(p20 + 0x3c, p5);
00662     p5 |= 1;
00663     hw_stl(p20 + 0x3c, p5);
00664   }
00665 
00666   flush_icache();
00667 }
00668 
00672 void CAlphaCPU::vmspal_call_prober()
00673 {
00674   u64 pa;
00675 
00676   p23 = state.pc;
00677   p4 = r18 & 3; // alt mode
00678   p5 = p22 & 0x18;
00679   p5 >>= 3;     // current mode
00680   p6 = p5 - p4;
00681   if(p5 > p4)
00682     p4 = p5;
00683   state.alt_cm = (int) p4;
00684   hw_stq(p21 + 0x140, state.pc);
00685   hw_stq(p21 + 0x148, p4);
00686 
00687   if(virt2phys(r16, &pa, ACCESS_READ | ALT | PROBE, NULL, 0) < 0)
00688     return;
00689 
00690   if(virt2phys(r16 + r17, &pa, ACCESS_READ | ALT | PROBE, NULL, 0) < 0)
00691     return;
00692 
00693   r0 = 1;
00694   return;
00695 }
00696 
00700 void CAlphaCPU::vmspal_call_probew()
00701 {
00702   u64 pa;
00703 
00704   p23 = state.pc;
00705   p4 = r18 & 3; // alt mode
00706   p5 = p22 & 0x18;
00707   p5 >>= 3;     // current mode
00708   p6 = p5 - p4;
00709   if(p5 > p4)
00710     p4 = p5;
00711   state.alt_cm = (int) p4;
00712   hw_stq(p21 + 0x140, state.pc);
00713   hw_stq(p21 + 0x148, p4);
00714   if(virt2phys(r16, &pa, ACCESS_WRITE | ALT | PROBE | PROBEW, NULL, 0) < 0)
00715     return;
00716 
00717   if(virt2phys(r16 + r17, &pa, ACCESS_WRITE | ALT | PROBE | PROBEW, NULL, 0) < 0)
00718     return;
00719 
00720   r0 = 1;
00721   return;
00722 }
00723 
00727 void CAlphaCPU::vmspal_call_rd_ps()
00728 {
00729   r0 = p22 & U64(0xffff);
00730 }
00731 
00735 int CAlphaCPU::vmspal_call_rei()
00736 {
00737   u64 phys_address;
00738 
00739   p23 = state.pc;
00740 
00741   p7 = p22 & 0x18;    //old cm
00742   hw_stq(p21 + 0x150, p23);
00743   if(r30 & 0x3f)
00744   {
00745 
00746     // stack not aligned
00747     p4 = 0x430;
00748     hw_stq(p21 + 0x158, p4);
00749     return vmspal_int_initiate_exception();
00750   }
00751 
00752   if(p7)
00753   {
00754 
00755     // what to do if the next instruction results in a TNV exception?
00756     ldq(r30 + 0x38, p20);
00757     state.bIntrFlag = false;
00758     ldq(r30 + 0x30, p23);
00759     p4 = p20 & 0x18;  // new cm
00760     if((p4 < p7) || (p20 &~U64(0x3f0000000000001b)))
00761     {
00762       p4 = 0x430;
00763       hw_stq(p21 + 0x158, p4);
00764       vmspal_int_initiate_exception();
00765       return 0;
00766     }
00767 
00768     ldq(r30 + 0x10, state.r[4]);
00769     ldq(r30 + 0x18, state.r[5]);
00770     ldq(r30 + 0x20, state.r[6]);
00771     ldq(r30 + 0x28, state.r[7]);
00772     ldq(r30, r2);
00773     ldq(r30 + 8, r3);
00774     hw_ldq(p21 + 0x10, p6);
00775     p5 = (p20 >> 56) & 0xff;
00776     p7 += p6;
00777     p6 += p4;
00778     p20 &= 0xffff;
00779     p22 &= ~U64(0xffff);
00780     state.cm = (int) (p4 >> 3) & 3;
00781     p22 |= p20;
00782     p23 &= ~U64(0x3);
00783     p20 = r30 + 0x40;
00784     p20 |= p5;
00785     hw_stq(p7, p20);
00786     hw_ldq(p6, r30);
00787     set_pc(p23);
00788     return 0;
00789   }
00790 
00791   ldq(r30 + 0x38, p20);
00792   state.bIntrFlag = false;
00793   p7 = (p20 >> 8) & 0xff;
00794   ldq(r30 + 0x10, state.r[4]);
00795   ldq(r30 + 0x18, state.r[5]);
00796   ldq(r30 + 0x20, state.r[6]);
00797   ldq(r30 + 0x28, state.r[7]);
00798   ldq(r30, r2);
00799   ldq(r30 + 8, r3);
00800   p4 = p20 & 0x18;    // new cm
00801   ldq(r30 + 0x30, p23);
00802 
00803   if(p4)
00804   {
00805     hw_ldq(p21 + 0x10, p7);
00806     p7 += p4;
00807     state.cm = (int) (p4 >> 3) & 3;
00808     p5 = (p20 >> 56) & 0xff;
00809     p20 &= 0xff;
00810     p22 &= ~U64(0xffff);
00811     p22 |= p20;
00812     p23 &= ~U64(0x3);
00813     p20 = r30 + 0x40;
00814     p20 |= p5;
00815     hw_ldq(p7, r30);
00816     hw_stq(p21 + 0x18, p20);
00817     state.eien = ipl_ier_mask[0][0];
00818     state.slen = ipl_ier_mask[0][1];
00819     state.cren = ipl_ier_mask[0][2];
00820     state.pcen = ipl_ier_mask[0][3];
00821     state.sien = ipl_ier_mask[0][4];
00822     state.asten = ipl_ier_mask[0][5];
00823     state.check_int = true;
00824     set_pc(p23);
00825     return 0;
00826   }
00827 
00828   p5 = (p20 >> 56) & 0xff;
00829   p20 &= 0xffff;
00830   p22 &= ~U64(0xffff);
00831   p7 = (p20 >> 8) & 0xff;
00832   p22 |= p20;
00833   p23 &= ~U64(0x3);
00834   p20 = r30 + 0x40;
00835   r30 = p20 | p5;
00836   state.eien = ipl_ier_mask[p7][0];
00837   state.slen = ipl_ier_mask[p7][1];
00838   state.cren = ipl_ier_mask[p7][2];
00839   state.pcen = ipl_ier_mask[p7][3];
00840   state.sien = ipl_ier_mask[p7][4];
00841   state.asten = ipl_ier_mask[p7][5];
00842   state.check_int = true;
00843   set_pc(p23);
00844   return 0;
00845 }
00846 
00850 void CAlphaCPU::vmspal_call_swasten()
00851 {
00852   r0 = (state.aster & (1 << ((p22 >> 3) & 3))) ? 1 : 0;
00853   if(r16 & 1)
00854   {
00855     state.aster |= (1 << ((p22 >> 3) & 3));
00856     state.check_int = true;
00857   }
00858   else
00859     state.aster &= ~(1 << ((p22 >> 3) & 3));
00860 }
00861 
00865 void CAlphaCPU::vmspal_call_wr_ps_sw()
00866 {
00867   p22 &= ~U64(0x3);
00868   p22 |= r16 & U64(0x3);
00869 }
00870 
00874 void CAlphaCPU::vmspal_call_rscc()
00875 {
00876   hw_ldq(p21 + 0xa0, r0);
00877   if((state.cc & U64(0xffffffff)) < (r0 & U64(0x00000000ffffffff)))
00878     r0 += U64(0x1) << 0x20;
00879   r0 &= U64(0xffffffff00000000);
00880   r0 |= (state.cc & U64(0xffffffff));
00881   hw_stq(p21 + 0xa0, r0);
00882 }
00883 
00887 void CAlphaCPU::vmspal_call_read_unq()
00888 {
00889   u64 t;
00890   hw_ldq(p21 + 0x10, t);
00891   hw_ldq(t + 0x48, r0);
00892 }
00893 
00897 void CAlphaCPU::vmspal_call_write_unq()
00898 {
00899   u64 t;
00900   hw_ldq(p21 + 0x10, t);
00901   hw_stq(t + 0x48, r16);
00902 }
00903 
00904 //\}
00905 
00906 /***************************************************************************/
00907 
00913 //\{
00914 
00918 int CAlphaCPU::vmspal_int_initiate_exception()
00919 {
00920   u64 phys_address;
00921 
00922   p4 = p22 & U64(0x18);
00923   hw_ldq(p21 + U64(0x10), p20);
00924   if(p4)
00925   {
00926 
00927     // change mode to kernel
00928     state.cm = 0;
00929 
00930     // switch to kernel stack
00931     p20 += p4;
00932     hw_stq(p20, r30);
00933     hw_ldq(p21 + U64(0x18), r30);
00934   }
00935 
00936   p20 = r30 & U64(0x3f);
00937   r30 &= ~U64(0x3f);
00938   stq(r30 - U64(0x40), r2);
00939   stq(r30 - U64(0x38), r3);
00940   hw_stq(p21 + U64(0xf0), r1);
00941   r3 = p21;
00942   stq(r30 - U64(0x30), state.r[4]);
00943   stq(r30 - U64(0x28), state.r[5]);
00944   stq(r30 - U64(0x20), state.r[6]);
00945   stq(r30 - U64(0x18), state.r[7]);
00946   hw_ldq(state.r[3] + U64(0x160), state.r[4]);
00947   hw_ldq(state.r[3] + U64(0x168), state.r[5]);
00948   hw_ldq(p21 + U64(0xf0), r1);
00949   hw_ldq(p21 + U64(0x170), p4);
00950   hw_ldq(p21 + U64(0x158), p5);
00951   p7 = p22 & U64(0xffff);
00952   p20 <<= 0x38;
00953   p20 |= p7;
00954   p4 += p5;
00955   hw_ldq(p4 + U64(0x00), r2);
00956   hw_ldq(p4 + U64(0x08), r3);
00957   p22 &= ~U64(0x1b);
00958   r30 -= U64(0x40);
00959   hw_ldq(p21 + U64(0x150), p6);
00960   r2 &= ~U64(0x3);
00961   stq(r30 + U64(0x38), p20);
00962   stq(r30 + U64(0x30), p6);
00963 
00964   set_pc(r2);
00965   return -1;
00966 }
00967 
00971 int CAlphaCPU::vmspal_int_initiate_interrupt()
00972 {
00973   u64 phys_address;
00974 
00975   p4 = p22 & U64(0x18);
00976   hw_ldq(p21 + U64(0x10), p20);
00977   if(p4)
00978   {
00979 
00980     // change mode to kernel
00981     state.cm = 0;
00982 
00983     // switch to kernel stack
00984     p20 += p4;
00985     hw_stq(p20, r30);
00986     hw_ldq(p21 + U64(0x18), r30);
00987   }
00988 
00989   p20 = r30 & U64(0x3f);
00990   r30 &= ~U64(0x3f);
00991   stq(r30 - U64(0x40), r2);
00992   stq(r30 - U64(0x38), r3);
00993   hw_stq(p21 + U64(0xf0), r1);
00994   r3 = p21;
00995   stq(r30 - U64(0x30), state.r[4]);
00996   stq(r30 - U64(0x28), state.r[5]);
00997   stq(r30 - U64(0x20), state.r[6]);
00998   stq(r30 - U64(0x18), state.r[7]);
00999   hw_ldq(state.r[3] + U64(0x160), state.r[4]);
01000   hw_ldq(state.r[3] + U64(0x168), state.r[5]);
01001   hw_ldq(p21 + U64(0xf0), r1);
01002   hw_ldq(p21 + U64(0x170), p4);
01003   hw_ldq(p21 + U64(0x158), p5);
01004   p7 = p22 & U64(0xffff);
01005   p20 <<= 0x38;
01006   p20 |= p7;
01007   p4 += p5;
01008   hw_ldq(p4, r2);
01009   hw_ldq(p4 + U64(0x08), r3);
01010   hw_ldq(p21 + U64(0x128), p4);
01011   p22 &= ~U64(0xffff);
01012   p22 |= p4;
01013   r30 -= U64(0x40);
01014   hw_ldq(p21 + U64(0x150), p6);
01015   r2 &= ~U64(0x3);
01016   stq(r30 + U64(0x38), p20);
01017   stq(r30 + U64(0x30), p6);
01018 
01019   set_pc(r2);
01020   return -1;
01021 }
01022 
01023 //\}
01024 
01025 /***************************************************************************/
01026 
01032 //\{
01033 
01037 int CAlphaCPU::vmspal_ent_sw_int(int si)
01038 {
01039   int x;
01040 
01041   state.exc_addr = state.current_pc;
01042   p23 = state.current_pc;
01043   for(x = 15; x >= 0; x--)
01044   {
01045     if(si & (1 << x))
01046       break;
01047   }
01048 
01049   if(x <= 0)
01050     return 0;
01051 
01052   p7 = x;
01053   p4 = (u64) x << 4;
01054   p5 = p4 + 0x500;
01055   hw_stq(p21 + 0x158, p5);
01056   hw_stq(p21 + 0x150, state.current_pc);
01057   state.sir &= ~(1 << x);
01058   state.eien = ipl_ier_mask[x][0];
01059   state.slen = ipl_ier_mask[x][1];
01060   state.cren = ipl_ier_mask[x][2];
01061   state.pcen = ipl_ier_mask[x][3];
01062   state.sien = ipl_ier_mask[x][4];
01063   state.asten = ipl_ier_mask[x][5];
01064   state.check_int = true;
01065   p20 = (u64) x << 8;
01066   p20 |= 4;
01067   hw_stq(p21 + 0x128, p20);
01068   return vmspal_int_initiate_interrupt();
01069 }
01070 
01074 int CAlphaCPU::vmspal_ent_ext_int(int ei)
01075 {
01076   bool  do_11670 = false;
01077 
01078   state.exc_addr = state.current_pc;
01079   p23 = state.current_pc;
01080   p7 = ei;
01081   if(ei & 0x04)
01082   {
01083 
01084     // TIMER interrupt
01085     cSystem->clear_clock_int(state.iProcNum);
01086     p6 = cSystem->get_c_misc();
01087 
01088     p22 += U64(0x0000010000000000);
01089     p22 &= U64(0xffff0fffffffffff);
01090 
01091     hw_ldq(p21 + 0xa0, p20);
01092     p6 = U64(0x1) << 0x20;
01093     p4 = (state.cc & U64(0xffffffff));
01094     p5 = p20 & U64(0xffffffff);
01095     p20 &= U64(0xffffffff00000000);
01096     p7 = p4 - p5;
01097     if(((s64) p7) < 0)
01098       p20 += p6;
01099     p20 |= (state.cc & U64(0xffffffff));
01100     hw_stq(p21 + 0xa0, p20);
01101     hw_stq(p21 + 0x1c8, 0);
01102     p20 = 0x600;
01103     p7 = 0x16;
01104 
01105     do_11670 = true;
01106   }
01107   else if(ei & 0x02)
01108   {
01109     p5 = cSystem->get_c_dir(state.iProcNum);
01110     if(test_bit_64(p5, 0x32))
01111       FAILURE(NotImplemented, "Can't handle IRQ 50");
01112 
01113     p4 = 0x100;
01114     p20 = 8;
01115     while(p20 < 0x30)
01116     {
01117       if(p4 & p5)
01118         break;
01119       p4 *= 2;
01120       p20++;
01121     }
01122 
01123     if(p4 & p5)
01124     {
01125       p20 <<= 4;
01126       p20 += 0x900;
01127       p7 = 0x15;
01128 
01129       do_11670 = true;
01130     }
01131     else if(test_bit_64(p5, 0x37))
01132     {
01133 
01134       // irq 55 - PIC - isa
01135       p5 = U64(0x00000801f8000000);
01136 
01137       // pic_read_vector
01138       hw_ldl(p5, p5);
01139       p4 = p5 & 0xff;
01140       if(p4 == 0x07)
01141         FAILURE(NotImplemented, "Can't handle PIC interrupt 7");
01142 
01143       if(p4 >= 0x10)
01144         return 0;
01145 
01146       p4 <<= 4;
01147       p20 = p4 + 0x800;
01148       hw_ldq(0x148, p5);
01149       if(!p5 || p20 != U64(0x830))
01150       {
01151         p7 = 0x15;
01152         do_11670 = true;
01153       }
01154       else
01155       {
01156         hw_stq(0x150, p20);
01157         p4 = U64(0x00000801a0000000);
01158         p5 = U64(0x2000);
01159         hw_stq(p4 + 0x80, p5);
01160         hw_ldq(p4 + 0x80, p5);
01161         return 0;
01162       }
01163     }
01164     else
01165     {
01166       p6 = p5 & U64(0x0060000000000000);
01167       if(p6)
01168         cSystem->set_c_dim(state.iProcNum,
01169                            cSystem->get_c_dim(state.iProcNum) &~p6);
01170       return 0;
01171     }
01172   }
01173 
01174   if(do_11670)
01175   {
01176     hw_stq(p21 + 0x150, state.current_pc);
01177     hw_stq(p21 + 0x158, p20);
01178     hw_stq(p21 + 0x1d8, p20);
01179     state.eien = ipl_ier_mask[p7][0];
01180     state.slen = ipl_ier_mask[p7][1];
01181     state.cren = ipl_ier_mask[p7][2];
01182     state.pcen = ipl_ier_mask[p7][3];
01183     state.sien = ipl_ier_mask[p7][4];
01184     state.asten = ipl_ier_mask[p7][5];
01185     state.check_int = true;
01186     p20 = p7 << 8;
01187     p20 |= 4;
01188     hw_stq(p21 + 0x128, p20);
01189 
01190     return vmspal_int_initiate_interrupt();
01191   }
01192 
01193   return 0;
01194 }
01195 
01199 int CAlphaCPU::vmspal_ent_ast_int(int ast)
01200 {
01201   int x;
01202 
01203   state.exc_addr = state.current_pc;
01204   p23 = state.current_pc;
01205 
01206   for(x = 0; x < 4; x++)
01207   {
01208     if(ast & (1 << x))
01209       break;
01210   }
01211 
01212   state.asten = 0;
01213   state.sien &= ~7;
01214   p4 = (u64) x << 4;
01215   p5 = 0x240 + p4;
01216   hw_stq(p21 + 0x158, p5);
01217   hw_stq(p21 + 0x150, p23);
01218   state.astrr &= ~(1 << x);
01219   p20 = (p22 & 4) + 0x200;
01220   hw_stq(p21 + 0x128, p20);
01221   return vmspal_int_initiate_interrupt();
01222 }
01223 
01227 int CAlphaCPU::vmspal_ent_dtbm_single(int flags)
01228 {
01229   u64 pte_phys;
01230   u64 t25;
01231   u64 t26;
01232 
01233   p23 = state.exc_addr;
01234   p4 = va_form(state.fault_va, false);
01235   p5 = state.mm_stat;
01236   p7 = state.exc_sum;
01237   p6 = state.fault_va;
01238   p7 &= ~U64(0x1);
01239   if(test_bit_64(p22, 63))
01240   {
01241 
01242     // 1-ON-1 translations
01243     p5 = 0xff01;
01244     p4 = p6 >> 0x0d;
01245     if(!test_bit_64(p6, 43))
01246     {
01247       p4 &= ~U64(0xffffffffbfc00000);
01248       if((p4 >= 0x400a0000 && p4 <= 0x400bffff)
01249        || (p4 >= 0x400c8000 && p4 <= 0x400cffff)
01250        || (p4 >= 0x400e0000 && p4 <= 0x400fbfff)
01251        || (p4 >= 0x400ff800 && p4 <= 0x400fffff)
01252        || (p4 >= 0x40180000 && p4 <= 0x401bffff)
01253        || (p4 >= 0x401c8000 && p4 <= 0x401fbfff)
01254        || (p4 >= 0x401fb000 && p4 <= 0x401fffff)
01255        || (p4 >= 0x40200000 && p4 <= 0x403fffff)) p5 = U64(0x1);
01256     }
01257 
01258     p4 <<= 0x20;
01259     p4 |= p5;
01260     add_tb_d(p6, p4);
01261     return 0;
01262   }
01263 
01264   p4 &= ~U64(0x7);
01265   if(virt2phys(p4, &pte_phys, ACCESS_READ | NO_CHECK | VPTE | (flags & (PROBE | PROBEW)),
01266      NULL, 0))
01267     return -1;
01268   p4 = cSystem->ReadMem(pte_phys, 64, this);
01269 
01270   if(!test_bit_64(p4, 0))
01271   {
01272     if(flags & PROBE)
01273     {
01274       t25 = U64(0x30000);
01275       p4 |= t25;
01276       t26 = p5 & 1; // write or read?
01277       t26 *= 4;
01278       t25 = ((p22 >> 3) & 3) | 8;
01279       t26 += t25;
01280       t25 = p4 >> 0x10;
01281       if(!(t25 & 1))
01282         t26 = 8;
01283       t26 = (t25 << t26) & p4;
01284       p7 = t26 ? 0x90 : 0x80; //page fault or acv
01285       hw_stq(p21 + 0x158, p7);
01286       t26 = p23 &~U64(0x3);
01287       hw_ldq(p21 + 0x148, p7);
01288       if(test_bit_64(p4, (int) (8 + p7 + ((flags & PROBEW) ? 4 : 0))))
01289         return 1;
01290       r0 = 0;
01291       return -1;
01292     }
01293 
01294     if(state.current_pc & 1)
01295     {
01296       t25 = U64(0x30000);
01297       p4 |= t25;
01298       t26 = p5 & 1;           // write or read?
01299       t26 *= 4;
01300       t25 = ((p22 >> 3) & 3) | 8;
01301       t26 += t25;
01302       t25 = p4 >> 0x10;
01303       if(!(t25 & 1))
01304         t26 = 8;
01305       t26 = (t25 << t26) & p4;
01306       p7 = t26 ? 0x90 : 0x80; //page fault or acv
01307       hw_stq(p21 + 0x158, p7);
01308       t26 = p23 &~U64(0x3);
01309 
01310       hw_stq(p21 + 0x118, state.r[25]);
01311       hw_stq(p21 + 0x120, state.r[26]);
01312       state.r[25] = t25;
01313       state.r[26] = t26;
01314       set_pc(0xd981);
01315       return -1;
01316 
01317       //return vmspal_int_dfault_in_palmode();
01318     }
01319 
01320     hw_stq(p21 + U64(0x150), p23);
01321     hw_stq(p21 + U64(0x160), p6);
01322     p20 = ((p22 >> 3) & 3) + 8;
01323     if((test_bit_64(p5, 0) && ((p5 >> 4) & 0x3f) == 0x18)
01324      || (!test_bit_64(p5, 0) && ((p7 >> 8) & 0x1f) == 0x1f))
01325     {
01326 
01327       // write "MISC" or read to R31
01328       set_pc(state.current_pc + 4);
01329       return -1;
01330     }
01331 
01332     p5 &= U64(0x1);
01333     p7 = p5 << 0x3f;
01334     p6 = 4 * p5;
01335     hw_stq(p21 + U64(0x168), p7);
01336     p6 += p20;
01337     p6 = U64(0x1) << p6;
01338     p6 &= p4;
01339     p20 = (p6) ? 0x90 : 0x80;
01340     hw_stq(p21 + U64(0x158), p20);
01341     return vmspal_int_initiate_exception();
01342   }
01343 
01344   add_tb_d(p6, p4);
01345   return 0;
01346 }
01347 
01351 int CAlphaCPU::vmspal_ent_itbm(int flags)
01352 {
01353   u64 pte_phys;
01354 
01355   p4 = va_form(state.exc_addr, true);
01356   p23 = state.exc_addr;
01357   p6 = p23;
01358   if(test_bit_64(p22, 63))
01359   {
01360 
01361     // 1-ON-1 translations enabled
01362     p6 = p23 >> 0x0d;
01363     p5 = 0xf01;
01364     p6 <<= 0x0d;
01365     p6 |= p5;
01366     add_tb_i(p23, p6);
01367     return 0;
01368   }
01369 
01370   p4 &= ~U64(0x7);
01371   if(virt2phys(p4, &pte_phys, ACCESS_READ | NO_CHECK | VPTE, NULL, 0))
01372     return -1;
01373   p4 = cSystem->ReadMem(pte_phys, 64, this);
01374 
01375   p6 = 0xfff;
01376   p5 = p4 & p6;
01377   p6 = p4 >> 0x20;
01378   p6 <<= 0x0d;
01379   if(!(p4 & 1) || (p4 & 8))
01380   {
01381     p20 = (p4 & 1) ? 0xc0 : 0x90;
01382 
01383     p6 = p22 >> 3;
01384     hw_stq(p21 + 0x160, p23);
01385     hw_stq(p21 + 0x150, p23);
01386     p6 &= U64(0x3);
01387     p5 = 1;
01388     p6 += 8;
01389     hw_stq(p21 + 0x168, p5);
01390     p6 = p5 << p6;
01391     p6 &= p4;
01392 
01393     // Access Violation
01394     if(!p6)
01395       p20 = 0x80;
01396     hw_stq(p21 + 0x158, p20);
01397     return vmspal_int_initiate_exception();
01398   }
01399 
01400   p6 |= p5;
01401   add_tb_i(p23, p6);
01402   return 0;
01403 }
01404 
01408 int CAlphaCPU::vmspal_ent_dtbm_double_3(int flags)
01409 {
01410   u64 t25;
01411   u64 t26;
01412 
01413   p7 &= 0xffff;
01414   p5 <<= 16;
01415   p7 |= p5;
01416   p5 = state.exc_addr;
01417   p7 |= 1;
01418   hw_ldq(p21 + 8, t25);       //PTBR
01419   t26 = (p4 << 0x1f) >> 0x33; //L1 index
01420   t25 += t26;
01421   hw_ldq(t25, t25);
01422   t26 = (p4 << 0x29) >> 0x33;
01423   if(t25 & 1)
01424   {
01425     t25 >>= 0x20;
01426     t25 <<= 0x0d;
01427     t25 += t26;
01428     hw_ldq(t25, t25);
01429     if(t25 & 1)
01430     {
01431       add_tb_d(p4, t25);
01432       return 0;
01433     }
01434   }
01435 
01436   // PAGE FAULT...
01437   p4 = p5;          // return address...
01438   p5 = p7 >> 0x10;
01439   t26 = state.pal_base;
01440 
01441   if(flags & PROBE) // in PALmode!!
01442   {
01443     p4 = t25 &~U64(0x30000);
01444     t26 = p5 & 1;   // write or read?
01445     t26 *= 4;
01446     t25 = ((p22 >> 3) & 3) | 8;
01447     t26 += t25;
01448     t25 = p4 >> 16;
01449     if(!(t25 & 1))
01450       t26 = 8;
01451     t26 = (U64(0x1) << t26) & p4;
01452     p7 = t26 ? 0x90 : 0x80; //page fault or acv
01453     hw_stq(p21 + 0x158, p7);
01454 
01455     if(p7 != 0x80)
01456     {
01457       p5 = (flags & PROBEW) ? U64(0x8000000000000000) : 0;
01458       hw_stq(p21 + 0x160, p6);
01459       hw_stq(p21 + 0x168, p5);
01460       hw_stq(p21 + 0x150, state.current_pc);
01461       return vmspal_int_initiate_exception();
01462     }
01463 
01464     r0 = 0;
01465     return -1;
01466   }
01467 
01468   if(p23 & 1)     // in PALmode!!
01469   {
01470     p4 = t25 &~U64(0x30000);
01471     t26 = p5 & 1; // write or read?
01472     t26 *= 4;
01473     t25 = ((p22 >> 3) & 3) | 8;
01474     t26 += t25;
01475     t25 = p4 >> 16;
01476     if(!(t25 & 1))
01477       t26 = 8;
01478     t26 = (U64(0x1) << t26) & p4;
01479     p7 = t26 ? 0x90 : 0x80; //page fault or acv
01480     hw_stq(p21 + 0x158, p7);
01481     t26 = p23 &~U64(0x3);
01482 
01483     hw_stq(p21 + 0x118, state.r[25]);
01484     hw_stq(p21 + 0x120, state.r[26]);
01485     state.r[25] = t25;
01486     state.r[26] = t26;
01487     set_pc(0xd981);
01488     return -1;
01489   }
01490 
01491   p20 = p4 &~U64(0x3);
01492   p4 = t25 & 0x100;
01493   hw_stq(p21 + 0x150, p23);
01494   p20 = t26 - p20;
01495   t26 = p20 + 0x590;
01496   if(!t26)
01497   {
01498     p5 = 1;
01499     hw_stq(p21 + 0x160, p23);
01500     p20 = p4 ? 0x90 : 0x80;
01501     hw_stq(p21 + 0x168, p5);
01502     hw_stq(p21 + 0x158, p20);
01503     return vmspal_int_initiate_exception();
01504   }
01505 
01506   if((test_bit_64(p5, 0) && ((p5 >> 4) & 0x3f) == 0x18)
01507    || (!test_bit_64(p5, 0) && ((p7 >> 8) & 0x1f) == 0x1f))
01508   {
01509     set_pc(p23 + 4);
01510     return -1;
01511   }
01512 
01513   p5 <<= 0x3f;
01514   p20 = p4 ? 0x90 : 0x80;
01515   hw_stq(p21 + 0x168, p5);
01516   hw_stq(p21 + 0x160, p6);
01517   hw_stq(p21 + 0x158, p20);
01518   return vmspal_int_initiate_exception();
01519 }
01520 
01524 int CAlphaCPU::vmspal_ent_iacv(int flags)
01525 {
01526   p6 = state.current_pc;
01527   p4 = 1;
01528   p5 = 0x80;
01529   hw_stq(p21 + 0x168, p4);
01530   hw_stq(p21 + 0x158, p5);
01531   if(state.current_pc & 1)
01532   {
01533     p7 = state.current_pc;
01534     p20 = 5;
01535     hw_stq(p21 + 0xc8, p20);
01536     p23 = state.current_pc;
01537     set_pc(0xde01);
01538     return -1;
01539   }
01540 
01541   hw_stq(p21 + 0x160, state.current_pc);
01542   hw_stq(p21 + 0x150, state.current_pc);
01543   return vmspal_int_initiate_exception();
01544 }
01545 
01549 int CAlphaCPU::vmspal_ent_dfault(int flags)
01550 {
01551   u64 t25;
01552 
01553   u64 t26;
01554   p6 = state.current_pc;
01555   p7 = state.exc_sum;
01556   p5 = state.mm_stat;
01557   if(flags & PROBE)
01558   {
01559     hw_stq(p21 + 0xd0, p23);
01560     p23 = p6;
01561     t26 = p6 &~U64(0x3);
01562     p6 = state.fault_va;
01563     t25 = p5 & 2;
01564     p7 = 0x80;
01565     if(!t25)
01566     {
01567       t25 = p5 & 8;
01568       p7 = t25 ? 0xb0 : 0xa0;
01569       tbis(p6, ACCESS_READ);
01570     }
01571 
01572     hw_stq(p21 + 0x158, p7);
01573     p4 = 1;
01574     hw_ldq(p21 + 0x158, p7);
01575     if(p7 == 0xa0 || p7 == 0xb0)
01576     {
01577       return 1;
01578     }
01579 
01580     r0 = 0;
01581     return -1;
01582   }
01583 
01584   if(state.current_pc & 1)
01585   {
01586     hw_stq(p21 + 0xd0, p23);
01587     p23 = p6;
01588     t26 = p6 &~U64(0x3);
01589     p6 = state.fault_va;
01590     t25 = p5 & 2;
01591     p7 = 0x80;
01592     if(!t25)
01593     {
01594       t25 = p5 & 8;
01595       p7 = t25 ? 0xb0 : 0xa0;
01596       tbis(p6, ACCESS_READ);
01597     }
01598 
01599     hw_stq(p21 + 0x158, p7);
01600     p4 = 1;
01601     hw_stq(p21 + 0x118, state.r[25]);
01602     hw_stq(p21 + 0x120, state.r[26]);
01603     state.r[25] = t25;
01604     state.r[26] = t26;
01605     set_pc(0xd981);
01606     return -1;
01607   }
01608 
01609   p20 = state.fault_va;
01610   if(((state.mm_stat & 1) && (((state.mm_stat >> 4) & 0x3f) == 0x18))
01611    || (!(state.mm_stat & 1) && (((state.exc_sum >> 8) & 0x1f) == 0x1f)))
01612   {
01613     set_pc(state.current_pc + 4);
01614     return -1;
01615   }
01616 
01617   p7 = 0x80;
01618   if(!(state.mm_stat & 2))
01619   {
01620     p7 = (state.mm_stat & 4) ? 0xa0 : 0xb0;
01621     tbis(p20, ACCESS_READ);
01622   }
01623 
01624   hw_stq(p21 + 0x158, p7);
01625   hw_stq(p21 + 0x160, p20);
01626   p5 <<= 0x3f;
01627   hw_stq(p21 + 0x168, p5);
01628   hw_stq(p21 + 0x150, p6);
01629   return vmspal_int_initiate_exception();
01630 }
01631 
01632 //\}

SourceForge.net Logo
Project space on SourceForge.net