Index: /trunk/src/VBox/Devices/PC/DevRTC.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevRTC.cpp	(revision 27459)
+++ /trunk/src/VBox/Devices/PC/DevRTC.cpp	(revision 27460)
@@ -1,5 +1,5 @@
 /* $Id$ */
 /** @file
- * Motorola MC146818 RTC/CMOS Device.
+ * Motorola MC146818 RTC/CMOS Device with PIIX4 extensions.
  */
 
@@ -117,7 +117,10 @@
 
 /** The saved state version. */
-#define RTC_SAVED_STATE_VERSION             3
+#define RTC_SAVED_STATE_VERSION             4
+/** The saved state version used by VirtualBox pre-3.2.
+ * This does not include the second 128-byte bank. */
+#define RTC_SAVED_STATE_VERSION_VBOX_32PRE  3
 /** The saved state version used by VirtualBox 3.1 and earlier.
- * This does not include disabled by HPET state.  */
+ * This does not include disabled by HPET state. */
 #define RTC_SAVED_STATE_VERSION_VBOX_31     2
 /** The saved state version used by VirtualBox 3.0 and earlier.
@@ -144,7 +147,7 @@
 
 struct RTCState {
-    uint8_t cmos_data[128];
-    uint8_t cmos_index;
-    uint8_t Alignment0[7];
+    uint8_t cmos_data[256];
+    uint8_t cmos_index[2];
+    uint8_t Alignment0[6];
     struct my_tm current_tm;
     /** The configured IRQ. */
@@ -258,14 +261,17 @@
 {
     RTCState *s = (RTCState*)opaque;
-
+    uint32_t bank;
+
+    bank = (addr >> 1) & 1;
     if ((addr & 1) == 0) {
-        s->cmos_index = data & 0x7f;
+        s->cmos_index[bank] = (data & 0x7f) + (bank * 128);
     } else {
-        Log(("CMOS: Write idx %#04x: %#04x (old %#04x)\n", s->cmos_index, data, s->cmos_data[s->cmos_index]));
-        switch(s->cmos_index) {
+        Log(("CMOS: Write bank %d idx %#04x: %#04x (old %#04x)\n", bank, 
+             s->cmos_index[bank], data, s->cmos_data[s->cmos_index[bank]]));
+        switch(s->cmos_index[bank]) {
         case RTC_SECONDS_ALARM:
         case RTC_MINUTES_ALARM:
         case RTC_HOURS_ALARM:
-            s->cmos_data[s->cmos_index] = data;
+            s->cmos_data[s->cmos_index[0]] = data;
             break;
         case RTC_SECONDS:
@@ -276,5 +282,5 @@
         case RTC_MONTH:
         case RTC_YEAR:
-            s->cmos_data[s->cmos_index] = data;
+            s->cmos_data[s->cmos_index[0]] = data;
             /* if in set mode, do not update the time */
             if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
@@ -309,5 +315,5 @@
             break;
         default:
-            s->cmos_data[s->cmos_index] = data;
+            s->cmos_data[s->cmos_index[bank]] = data;
             break;
         }
@@ -488,8 +494,11 @@
     RTCState *s = (RTCState*)opaque;
     int ret;
+    unsigned bank;
+
+    bank = (addr >> 1) & 1;
     if ((addr & 1) == 0) {
         return 0xff;
     } else {
-        switch(s->cmos_index) {
+        switch(s->cmos_index[bank]) {
         case RTC_SECONDS:
         case RTC_MINUTES:
@@ -499,19 +508,19 @@
         case RTC_MONTH:
         case RTC_YEAR:
-            ret = s->cmos_data[s->cmos_index];
+            ret = s->cmos_data[s->cmos_index[0]];
             break;
         case RTC_REG_A:
-            ret = s->cmos_data[s->cmos_index];
+            ret = s->cmos_data[s->cmos_index[0]];
             break;
         case RTC_REG_C:
-            ret = s->cmos_data[s->cmos_index];
+            ret = s->cmos_data[s->cmos_index[0]];
             rtc_raise_irq(s, 0);
             s->cmos_data[RTC_REG_C] = 0x00;
             break;
         default:
-            ret = s->cmos_data[s->cmos_index];
+            ret = s->cmos_data[s->cmos_index[bank]];
             break;
         }
-        Log(("CMOS: Read idx %#04x: %#04x\n", s->cmos_index, ret));
+        Log(("CMOS: Read bank %d idx %#04x: %#04x\n", bank, s->cmos_index[bank], ret));
         return ret;
     }
@@ -645,5 +654,5 @@
     /* The state. */
     SSMR3PutMem(pSSM, pThis->cmos_data, 128);
-    SSMR3PutU8(pSSM, pThis->cmos_index);
+    SSMR3PutU8(pSSM, pThis->cmos_index[0]);
 
     SSMR3PutS32(pSSM, pThis->current_tm.tm_sec);
@@ -663,5 +672,8 @@
     TMR3TimerSave(pThis->CTX_SUFF(pSecondTimer2), pSSM);
 
-    return SSMR3PutBool(pSSM, pThis->fDisabledByHpet);
+    SSMR3PutBool(pSSM, pThis->fDisabledByHpet);
+
+    SSMR3PutMem(pSSM, &pThis->cmos_data[128], 128);
+    return SSMR3PutU8(pSSM, pThis->cmos_index[1]);
 }
 
@@ -676,4 +688,5 @@
 
     if (    uVersion != RTC_SAVED_STATE_VERSION
+        &&  uVersion != RTC_SAVED_STATE_VERSION_VBOX_32PRE
         &&  uVersion != RTC_SAVED_STATE_VERSION_VBOX_31
         &&  uVersion != RTC_SAVED_STATE_VERSION_VBOX_30)
@@ -704,5 +717,5 @@
     /* The state. */
     SSMR3GetMem(pSSM, pThis->cmos_data, 128);
-    SSMR3GetU8(pSSM, &pThis->cmos_index);
+    SSMR3GetU8(pSSM, &pThis->cmos_index[0]);
 
     SSMR3GetS32(pSSM, &pThis->current_tm.tm_sec);
@@ -724,4 +737,11 @@
     if (uVersion > RTC_SAVED_STATE_VERSION_VBOX_31)
          SSMR3GetBool(pSSM, &pThis->fDisabledByHpet);
+
+    if (uVersion > RTC_SAVED_STATE_VERSION_VBOX_32PRE)
+    {
+        /* Second CMOS bank. */
+        SSMR3GetMem(pSSM, &pThis->cmos_data[128], 128);
+        SSMR3GetU8(pSSM, &pThis->cmos_index[1]);
+    }
 
     int period_code = pThis->cmos_data[RTC_REG_A] & 0x0f;
@@ -767,5 +787,5 @@
  * @returns VBox status code.
  * @param   pDevIns     Device instance of the RTC.
- * @param   iReg        The CMOS register index.
+ * @param   iReg        The CMOS register index; bit 8 determines bank.
  * @param   u8Value     The CMOS register value.
  */
@@ -794,5 +814,5 @@
  * @returns VBox status code.
  * @param   pDevIns     Device instance of the RTC.
- * @param   iReg        The CMOS register index.
+ * @param   iReg        The CMOS register index; bit 8 determines bank.
  * @param   pu8Value    Where to store the CMOS register value.
  */
@@ -851,5 +871,6 @@
     rtcCalcCRC(pThis);
 
-    Log(("CMOS: \n%16.128Rhxd\n", pThis->cmos_data));
+    Log(("CMOS bank 0: \n%16.128Rhxd\n", &pThis->cmos_data[0]));
+    Log(("CMOS bank 1: \n%16.128Rhxd\n", &pThis->cmos_data[128]));
     return VINF_SUCCESS;
 }
@@ -1000,5 +1021,5 @@
         return rc;
 
-    rc = PDMDevHlpIOPortRegister(pDevIns, pThis->IOPortBase, 2, NULL,
+    rc = PDMDevHlpIOPortRegister(pDevIns, pThis->IOPortBase, 4, NULL,
                                  rtcIOPortWrite, rtcIOPortRead, NULL, NULL, "MC146818 RTC/CMOS");
     if (RT_FAILURE(rc))
@@ -1006,5 +1027,5 @@
     if (fGCEnabled)
     {
-        rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->IOPortBase, 2, 0,
+        rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->IOPortBase, 4, 0,
                                        "rtcIOPortWrite", "rtcIOPortRead", NULL, NULL, "MC146818 RTC/CMOS");
         if (RT_FAILURE(rc))
@@ -1013,5 +1034,5 @@
     if (fR0Enabled)
     {
-        rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->IOPortBase, 2, 0,
+        rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->IOPortBase, 4, 0,
                                        "rtcIOPortWrite", "rtcIOPortRead", NULL, NULL, "MC146818 RTC/CMOS");
         if (RT_FAILURE(rc))
