@@ -446,6 +446,8 @@ void CAliM1543C::init() {
446446 state.toy_stored_data [0x17 ] = 0 ;
447447 }
448448
449+ state.toy_pi_last_fire = 0 ;
450+
449451 ResetPCI ();
450452
451453 // PIT Setup
@@ -760,7 +762,6 @@ void CAliM1543C::toy_write(u32 address, u8 data) {
760762 // periodic interrupt rate divisor of 32 = interrupt every 976.562 ms
761763 // (1024Hz clock)
762764 if (state.toy_stored_data [0x0a ] & 0x80 ) {
763-
764765 // Once the UIP line goes high, we have to stay high for 2228us.
765766 hold_count--;
766767 if (hold_count == 0 ) {
@@ -782,67 +783,9 @@ void CAliM1543C::toy_write(u32 address, u8 data) {
782783 (2228 / (IPus * 3 )) + 1 ; // .876 @ 847IPus, so we add one.
783784 }
784785 }
785-
786- // # /****************************************************/
787- // # #define RTC_CONTROL RTC_REG_B
788- // # # define RTC_SET 0x80 /* disable updates for clock setting */
789- // # # define RTC_PIE 0x40 /* periodic interrupt enable */
790- // # # define RTC_AIE 0x20 /* alarm interrupt enable */
791- // # # define RTC_UIE 0x10 /* update-finished interrupt enable */
792- // # # define RTC_SQWE 0x08 /* enable square-wave output */
793- // # # define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear
794- // */ # # define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm
795- // */ # # define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */
796- // #
797- // this is set (by the srm?) to 0x0e = SQWE | DM_BINARY | 24H
798- // linux sets the PIE bit later.
799- // # /***********************************************************/
800- // # #define RTC_INTR_FLAGS RTC_REG_C
801- // # /* caution - cleared by read */
802- // # # define RTC_IRQF 0x80 /* any of the following 3 is active */
803- // # # define RTC_PF 0x40
804- // # # define RTC_AF 0x20
805- // # # define RTC_UF 0x10
806- // #
807786 }
808787
809- {
810- /*
811- See sys/dev/ic/mc146818reg.h and sys/arch/alpha/alpha/mcclock.c
812- */
813- static clock_t last_fire = 0 ;
814- clock_t now = clock ();
815- double timedelta = (now - last_fire) / (double )CLOCKS_PER_SEC;
816- int rate_pow = state.toy_stored_data [0x0a ] & 0x0f ;
817- double period = (1 << rate_pow)/65536.0 ;
818- #define MC_BASE_32_KHz 0x20
819- #define RTC_PF 0x40
820-
821- if (state.toy_stored_data [0x0a ] & MC_BASE_32_KHz)
822- {
823- if (rate_pow == 0x1 )
824- {
825- period = 1 /256.0 ;
826- }
827- else if (rate_pow == 0x2 )
828- {
829- period = 1 /128.0 ;
830- }
831- }
832-
833- if (rate_pow && (timedelta >= period))
834- {
835- state.toy_stored_data [0x0c ] |= RTC_PF;
836- last_fire = now;
837- }
838- }
839-
840- state.toy_access_ports [1 ] = state.toy_stored_data [data & 0x7f ];
841-
842- // register C is cleared after a read, and we don't care if its a write
843- if (data == 0x0c )
844- state.toy_stored_data [data & 0x7f ] = 0 ;
845- break ;
788+ toy_handle_periodic_interrupt (data);
846789
847790 case 1 :
848791 if (state.toy_access_ports [0 ] == 0x0b &&
@@ -862,6 +805,39 @@ void CAliM1543C::toy_write(u32 address, u8 data) {
862805 }
863806}
864807
808+ /* *
809+ * Handle RTC periodic interrupt.
810+ **/
811+ void CAliM1543C::toy_handle_periodic_interrupt (u8 data) {
812+ /*
813+ See sys/dev/ic/mc146818reg.h and sys/arch/alpha/alpha/mcclock.c in NetBSD and
814+ the RTC datasheet: https://www.nxp.com/docs/en/data-sheet/MC146818.pdf.
815+ */
816+ clock_t now = clock ();
817+ double timedelta = (now - state.toy_pi_last_fire ) / (double )CLOCKS_PER_SEC;
818+ int rate_pow = state.toy_stored_data [0x0a ] & 0x0f ;
819+ double period = (1 << rate_pow) / 65536.0 ;
820+
821+ if (state.toy_stored_data [0x0a ] & MC_BASE_32_KHz) {
822+ if (rate_pow == 0x1 ) {
823+ period = 1 / 256.0 ;
824+ } else if (rate_pow == 0x2 ) {
825+ period = 1 / 128.0 ;
826+ }
827+ }
828+
829+ if (rate_pow && (timedelta >= period)) {
830+ state.toy_stored_data [0x0c ] |= RTC_PF;
831+ state.toy_pi_last_fire = now;
832+ }
833+
834+ state.toy_access_ports [1 ] = state.toy_stored_data [data & 0x7f ];
835+
836+ // register C is cleared after a read, and we don't care if it's a write
837+ if (data == 0x0c )
838+ state.toy_stored_data [data & 0x7f ] = 0 ;
839+ }
840+
865841/* *
866842 * Read from the programmable interrupt timer ports (40h-43h)
867843 *
@@ -960,7 +936,6 @@ void CAliM1543C::pit_write(u32 address, u8 data) {
960936void CAliM1543C::pit_clock () {
961937 int i;
962938 for (i = 0 ; i < 3 ; i++) {
963-
964939 // decrement the counter.
965940 if (state.pit_status [i] & 0x40 )
966941 continue ;
0 commit comments