Index: boot/freeldr/freeldr/arch/i386/pcrtc.c =================================================================== --- boot/freeldr/freeldr/arch/i386/pcrtc.c (revision 48129) +++ boot/freeldr/freeldr/arch/i386/pcrtc.c (working copy) @@ -27,56 +27,66 @@ static TIMEINFO TimeInfo; REGS Regs; - /* Some BIOSes, such as the 1998/07/25 system ROM - * in the Compaq Deskpro EP/SB, leave CF unchanged - * if successful, so CF should be cleared before - * calling this function. */ - __writeeflags(__readeflags() & ~EFLAGS_CF); + for (;;) + { + /* Some BIOSes, such as the 1998/07/25 system ROM + * in the Compaq Deskpro EP/SB, leave CF unchanged + * if successful, so CF should be cleared before + * calling this function. */ + Regs.x.eflags = 0; +// __writeeflags(__readeflags() & ~EFLAGS_CF); - /* Int 1Ah AH=04h - * TIME - GET REAL-TIME CLOCK DATE (AT,XT286,PS) - * - * AH = 04h - * CF clear to avoid bug - * Return: - * CF clear if successful - * CH = century (BCD) - * CL = year (BCD) - * DH = month (BCD) - * DL = day (BCD) - * CF set on error - */ - Regs.b.ah = 0x04; - Int386(0x1A, &Regs, &Regs); + /* Int 1Ah AH=04h + * TIME - GET REAL-TIME CLOCK DATE (AT,XT286,PS) + * + * AH = 04h + * CF clear to avoid bug + * Return: + * CF clear if successful + * CH = century (BCD) + * CL = year (BCD) + * DH = month (BCD) + * DL = day (BCD) + * CF set on error + */ + Regs.b.ah = 0x04; + Int386(0x1A, &Regs, &Regs); - TimeInfo.Year = 100 * BCD_INT(Regs.b.ch) + BCD_INT(Regs.b.cl); - TimeInfo.Month = BCD_INT(Regs.b.dh); - TimeInfo.Day = BCD_INT(Regs.b.dl); + if (!INT386_SUCCESS(Regs)) continue; - /* Some BIOSes leave CF unchanged if successful, - * so CF should be cleared before calling this function. */ - __writeeflags(__readeflags() & ~EFLAGS_CF); + TimeInfo.Year = 100 * BCD_INT(Regs.b.ch) + BCD_INT(Regs.b.cl); + TimeInfo.Month = BCD_INT(Regs.b.dh); + TimeInfo.Day = BCD_INT(Regs.b.dl); - /* Int 1Ah AH=02h - * TIME - GET REAL-TIME CLOCK TIME (AT,XT286,PS) - * - * AH = 02h - * CF clear to avoid bug - * Return: - * CF clear if successful - * CH = hour (BCD) - * CL = minutes (BCD) - * DH = seconds (BCD) - * DL = daylight savings flag (00h standard time, 01h daylight time) - * CF set on error (i.e. clock not running or in middle of update) - */ - Regs.b.ah = 0x02; - Int386(0x1A, &Regs, &Regs); + /* Some BIOSes leave CF unchanged if successful, + * so CF should be cleared before calling this function. */ + Regs.x.eflags = 0; +// __writeeflags(__readeflags() & ~EFLAGS_CF); - TimeInfo.Hour = BCD_INT(Regs.b.ch); - TimeInfo.Minute = BCD_INT(Regs.b.cl); - TimeInfo.Second = BCD_INT(Regs.b.dh); + /* Int 1Ah AH=02h + * TIME - GET REAL-TIME CLOCK TIME (AT,XT286,PS) + * + * AH = 02h + * CF clear to avoid bug + * Return: + * CF clear if successful + * CH = hour (BCD) + * CL = minutes (BCD) + * DH = seconds (BCD) + * DL = daylight savings flag (00h standard time, 01h daylight time) + * CF set on error (i.e. clock not running or in middle of update) + */ + Regs.b.ah = 0x02; + Int386(0x1A, &Regs, &Regs); + if (!INT386_SUCCESS(Regs)) continue; + + TimeInfo.Hour = BCD_INT(Regs.b.ch); + TimeInfo.Minute = BCD_INT(Regs.b.cl); + TimeInfo.Second = BCD_INT(Regs.b.dh); + + break; + } return &TimeInfo; } Index: boot/freeldr/freeldr/arch/i386/int386.S =================================================================== --- boot/freeldr/freeldr/arch/i386/int386.S (revision 48129) +++ boot/freeldr/freeldr/arch/i386/int386.S (working copy) @@ -23,6 +23,10 @@ #define ASM #include +/* Only these flags are propagated into Int386() */ +#define FLAGS_PROP (I386FLAG_CF | \ + I386FLAG_ZF | \ + I386FLAG_SF) Int386_REGS: @@ -85,6 +89,7 @@ movl $Int386_REGS,%edi movl Int386_regsin,%esi movl $0x24,%ecx + cld rep movsb @@ -101,6 +106,16 @@ movw %cs:Int386_gs,%ax movw %ax,%gs /* GS register */ + /* Prepare EFLAGS for recover */ + pushf + movw %cs:Int386_eflags, %ax + popw %cx + andw $FLAGS_PROP, %ax + andw $~FLAGS_PROP, %cx + orw %cx, %ax + pushw %ax + + /* Recover general purpose registers */ movl %cs:Int386_eax,%eax /* EAX register */ movl %cs:Int386_ebx,%ebx /* EBX register */ movl %cs:Int386_ecx,%ecx /* ECX register */ @@ -109,6 +124,9 @@ movl %cs:Int386_esi,%esi /* ESI register */ movl %cs:Int386_edi,%edi /* EDI register */ + /* Recover previously prepared flags */ + popf + /* Do not set the flags register */ /* only return its value in regsout */ //pushl Int386_eflags @@ -149,6 +167,7 @@ movl $Int386_REGS,%esi movl Int386_regsout,%edi movl $0x24,%ecx + cld rep movsb Index: boot/freeldr/freeldr/include/arch.h =================================================================== --- boot/freeldr/freeldr/include/arch.h (revision 48129) +++ boot/freeldr/freeldr/include/arch.h (working copy) @@ -58,6 +58,19 @@ #define EXTERN(x) .global x; x: +// Flag Masks +#define I386FLAG_CF 0x0001 // Carry Flag +#define I386FLAG_RESV1 0x0002 // Reserved - Must be 1 +#define I386FLAG_PF 0x0004 // Parity Flag +#define I386FLAG_RESV2 0x0008 // Reserved - Must be 0 +#define I386FLAG_AF 0x0010 // Auxiliary Flag +#define I386FLAG_RESV3 0x0020 // Reserved - Must be 0 +#define I386FLAG_ZF 0x0040 // Zero Flag +#define I386FLAG_SF 0x0080 // Sign Flag +#define I386FLAG_TF 0x0100 // Trap Flag (Single Step) +#define I386FLAG_IF 0x0200 // Interrupt Flag +#define I386FLAG_DF 0x0400 // Direction Flag +#define I386FLAG_OF 0x0800 // Overflow Flag #ifndef ASM @@ -148,20 +161,6 @@ // specifically handles linear addresses. int Int386(int ivec, REGS* in, REGS* out); -// Flag Masks -#define I386FLAG_CF 0x0001 // Carry Flag -#define I386FLAG_RESV1 0x0002 // Reserved - Must be 1 -#define I386FLAG_PF 0x0004 // Parity Flag -#define I386FLAG_RESV2 0x0008 // Reserved - Must be 0 -#define I386FLAG_AF 0x0010 // Auxiliary Flag -#define I386FLAG_RESV3 0x0020 // Reserved - Must be 0 -#define I386FLAG_ZF 0x0040 // Zero Flag -#define I386FLAG_SF 0x0080 // Sign Flag -#define I386FLAG_TF 0x0100 // Trap Flag (Single Step) -#define I386FLAG_IF 0x0200 // Interrupt Flag -#define I386FLAG_DF 0x0400 // Direction Flag -#define I386FLAG_OF 0x0800 // Overflow Flag - // This macro tests the Carry Flag // If CF is set then the call failed (usually) #define INT386_SUCCESS(regs) ((regs.x.eflags & I386FLAG_CF) == 0)