예제 #1
0
파일: RTC.cs 프로젝트: derplayer/x8086Sharp
        private Scheduler.Task task;// = new TaskSC(this);

        public RTC(X8086 cpu, InterruptRequest irq)
        {
            task     = new TaskSC(this);
            this.irq = irq;

            for (int i = 0x70; i <= 0x71; i++)
            {
                ValidPortAddress.Add((uint)i);
            }

            for (int i = 0x240; i <= 0x24F; i++)
            {
                ValidPortAddress.Add((uint)i);
            }

            // FIXME: Although this works, when pausing the emulation causes the internal timers to get out of sync:
            // The contents at 46C no longer reflect what's returned by INT 1A, 02
            // So the x8086.Resume method should perform a re-sync setting the new tick values into 46C.
            // It also appears that the x8086.Resume method should also advance the time...

            cpu.TryAttachHook((byte)(0x8), new X8086.IntHandler(() =>
            {
                uint ticks = (uint)((DateTime.Now - new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0)).Ticks / 10000000 * 18.206);
                //cpu.RAM16[0x40, 0x6E] = (ticks >> 16) & 0xFFFF;
                //cpu.RAM16[0x40, 0x6C] = ticks & 0xFFFF;
                //cpu.RAM8[0x40, 0x70] = 0;
                cpu.set_RAM16(0x40, 0x6E, 0x0, false, (ushort)((long)(ticks >> 16) & 0xFFFF));
                cpu.set_RAM16(0x40, 0x6C, 0x0, false, (ushort)((long)(ticks) & 0xFFFF));
                cpu.set_RAM8(0x40, 0x70, 0x0, false, 0x00);

                cpu.TryDetachHook(0x8);
                return(false);
            }));

            cpu.TryAttachHook((byte)(0x1A), new X8086.IntHandler(() =>
            {
                switch (cpu.Registers.AH)
                {
                case 0x2:    // Read real time clock time
                    cpu.Registers.CH = (byte)ToBCD((ushort)DateTime.Now.Hour);
                    cpu.Registers.CL = (byte)ToBCD((ushort)DateTime.Now.Minute);
                    cpu.Registers.DH = (byte)ToBCD((ushort)DateTime.Now.Second);
                    cpu.Registers.DL = 0;
                    cpu.Flags.CF     = 0;
                    return(true);

                case 0x4:    // Read real time clock date
                    cpu.Registers.CH = (byte)ToBCD((ushort)(DateTime.Now.Year / 100));
                    cpu.Registers.CL = (byte)ToBCD((ushort)DateTime.Now.Year);
                    cpu.Registers.DH = (byte)ToBCD((ushort)DateTime.Now.Month);
                    cpu.Registers.DL = (byte)ToBCD((ushort)DateTime.Now.Day);
                    cpu.Flags.CF     = 0;
                    return(true);

                default:
                    return(false);
                }
            }));
        }