625{
628 FAST486_SYSTEM_DESCRIPTOR NewTssDescriptor;
629 FAST486_TSS OldTss;
630 PFAST486_LEGACY_TSS OldLegacyTss = (PFAST486_LEGACY_TSS)&OldTss;
631 FAST486_TSS NewTss;
632 PFAST486_LEGACY_TSS NewLegacyTss = (PFAST486_LEGACY_TSS)&NewTss;
633 USHORT NewLdtr, NewEs, NewCs, NewSs, NewDs;
634
635 if ((
State->TaskReg.Modern &&
State->TaskReg.Limit < (
sizeof(FAST486_TSS) - 1))
636 || (!
State->TaskReg.Modern &&
State->TaskReg.Limit < (
sizeof(FAST486_LEGACY_TSS) - 1)))
637 {
638
641 }
642
643
644 if (!Fast486ReadLinearMemory(
State,
646 &OldTss,
647 State->TaskReg.Modern
648 ? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
650 {
651
653 }
654
655
656
658 {
659 if (
State->TaskReg.Modern) Selector =
LOWORD(OldTss.Link);
660 else Selector = OldLegacyTss->Link;
661 }
662
663
667 {
670 }
671
672
673 if (!Fast486ReadLinearMemory(
State,
675 &NewTssDescriptor,
676 sizeof(NewTssDescriptor),
678 {
679
681 }
682
683 if (!NewTssDescriptor.Present)
684 {
685
688 }
689
690
691 NewTssAddress = NewTssDescriptor.Base;
692 NewTssAddress |= NewTssDescriptor.BaseMid << 16;
693 NewTssAddress |= NewTssDescriptor.BaseHigh << 24;
694
695
696 NewTssLimit = NewTssDescriptor.Limit | (NewTssDescriptor.LimitHigh << 16);
697
698 if (NewTssDescriptor.Granularity)
699 {
700 NewTssLimit <<= 12;
701 NewTssLimit |= 0x00000FFF;
702 }
703
704 if (NewTssLimit < (sizeof(FAST486_TSS) - 1)
705 && NewTssLimit != (sizeof(FAST486_LEGACY_TSS) - 1))
706 {
707
710 }
711
712
713
714
715
722 {
725 }
726
727
728 if (!Fast486ReadLinearMemory(
State,
729 NewTssAddress,
730 &NewTss,
733 ? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
735 {
736
738 }
739
741 {
742
743 FAST486_SYSTEM_DESCRIPTOR OldTssDescriptor;
744
745 if (!Fast486ReadLinearMemory(
State,
748 &OldTssDescriptor,
749 sizeof(OldTssDescriptor),
751 {
752
754 }
755
757
758 if (!Fast486WriteLinearMemory(
State,
761 &OldTssDescriptor,
762 sizeof(OldTssDescriptor),
764 {
765
767 }
768 }
769 else
770 {
771
774 {
775 NewTss.Link =
State->TaskReg.Selector;
776
777
778 if (!Fast486WriteLinearMemory(
State,
779 NewTssAddress,
780 &NewTss.Link,
781 sizeof(NewTss.Link),
783 {
784
786 }
787 }
788 else
789 {
790 NewLegacyTss->Link =
State->TaskReg.Selector;
791
792
793 if (!Fast486WriteLinearMemory(
State,
794 NewTssAddress,
795 &NewLegacyTss->Link,
796 sizeof(NewLegacyTss->Link),
798 {
799
801 }
802 }
803 }
804
805
806 if (
State->TaskReg.Modern)
807 {
808 OldTss.Cr3 =
State->ControlRegisters[FAST486_REG_CR3];
809 OldTss.Eip =
State->InstPtr.Long;
810 OldTss.Eflags =
State->Flags.Long;
811 OldTss.Eax =
State->GeneralRegs[FAST486_REG_EAX].Long;
812 OldTss.Ecx =
State->GeneralRegs[FAST486_REG_ECX].Long;
813 OldTss.Edx =
State->GeneralRegs[FAST486_REG_EDX].Long;
814 OldTss.Ebx =
State->GeneralRegs[FAST486_REG_EBX].Long;
815 OldTss.Esp =
State->GeneralRegs[FAST486_REG_ESP].Long;
816 OldTss.Ebp =
State->GeneralRegs[FAST486_REG_EBP].Long;
817 OldTss.Esi =
State->GeneralRegs[FAST486_REG_ESI].Long;
818 OldTss.Edi =
State->GeneralRegs[FAST486_REG_EDI].Long;
819 OldTss.Es =
State->SegmentRegs[FAST486_REG_ES].Selector;
820 OldTss.Cs =
State->SegmentRegs[FAST486_REG_CS].Selector;
821 OldTss.Ss =
State->SegmentRegs[FAST486_REG_SS].Selector;
822 OldTss.Ds =
State->SegmentRegs[FAST486_REG_DS].Selector;
823 OldTss.Fs =
State->SegmentRegs[FAST486_REG_FS].Selector;
824 OldTss.Gs =
State->SegmentRegs[FAST486_REG_GS].Selector;
825 OldTss.Ldtr =
State->Ldtr.Selector;
826 }
827 else
828 {
829 OldLegacyTss->Ip =
State->InstPtr.LowWord;
830 OldLegacyTss->Flags =
State->Flags.LowWord;
831 OldLegacyTss->Ax =
State->GeneralRegs[FAST486_REG_EAX].LowWord;
832 OldLegacyTss->Cx =
State->GeneralRegs[FAST486_REG_ECX].LowWord;
833 OldLegacyTss->Dx =
State->GeneralRegs[FAST486_REG_EDX].LowWord;
834 OldLegacyTss->Bx =
State->GeneralRegs[FAST486_REG_EBX].LowWord;
835 OldLegacyTss->Sp =
State->GeneralRegs[FAST486_REG_ESP].LowWord;
836 OldLegacyTss->Bp =
State->GeneralRegs[FAST486_REG_EBP].LowWord;
837 OldLegacyTss->Si =
State->GeneralRegs[FAST486_REG_ESI].LowWord;
838 OldLegacyTss->Di =
State->GeneralRegs[FAST486_REG_EDI].LowWord;
839 OldLegacyTss->Es =
State->SegmentRegs[FAST486_REG_ES].Selector;
840 OldLegacyTss->Cs =
State->SegmentRegs[FAST486_REG_CS].Selector;
841 OldLegacyTss->Ss =
State->SegmentRegs[FAST486_REG_SS].Selector;
842 OldLegacyTss->Ds =
State->SegmentRegs[FAST486_REG_DS].Selector;
843 OldLegacyTss->Ldtr =
State->Ldtr.Selector;
844 }
845
846
847 if (!Fast486WriteLinearMemory(
State,
849 &OldTss,
850 State->TaskReg.Modern
851 ? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
853 {
854
856 }
857
858
861 {
862
864 }
865 else
866 {
867
869 }
870
871
872 if (!Fast486WriteLinearMemory(
State,
874 &NewTssDescriptor,
875 sizeof(NewTssDescriptor),
877 {
878
880 }
881
882
884
885
886 State->TaskReg.Selector = Selector;
887 State->TaskReg.Base = NewTssAddress;
888 State->TaskReg.Limit = NewTssLimit;
890
892 {
893
894 State->ControlRegisters[FAST486_REG_CR3] = NewTss.Cr3;
895 }
896
897
898 Fast486FlushTlb(
State);
899
900
902 {
904 }
905 else
906 {
908 }
909
910#ifndef FAST486_NO_PREFETCH
911
913#endif
914
915
917 {
918 State->InstPtr.Long =
State->SavedInstPtr.Long = NewTss.Eip;
919 State->Flags.Long = NewTss.Eflags;
920 State->GeneralRegs[FAST486_REG_EAX].Long = NewTss.Eax;
921 State->GeneralRegs[FAST486_REG_ECX].Long = NewTss.Ecx;
922 State->GeneralRegs[FAST486_REG_EDX].Long = NewTss.Edx;
923 State->GeneralRegs[FAST486_REG_EBX].Long = NewTss.Ebx;
924 State->GeneralRegs[FAST486_REG_EBP].Long = NewTss.Ebp;
925 State->GeneralRegs[FAST486_REG_ESI].Long = NewTss.Esi;
926 State->GeneralRegs[FAST486_REG_EDI].Long = NewTss.Edi;
927 NewEs = NewTss.Es;
928 NewCs = NewTss.Cs;
929 NewDs = NewTss.Ds;
930 NewLdtr = NewTss.Ldtr;
931
933 {
935 {
936 case 0:
937 {
938 State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp0;
939 NewSs = NewTss.Ss0;
940 break;
941 }
942
943 case 1:
944 {
945 State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp1;
946 NewSs = NewTss.Ss1;
947 break;
948 }
949
950 case 2:
951 {
952 State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp2;
953 NewSs = NewTss.Ss2;
954 break;
955 }
956 }
957 }
958 else
959 {
960 State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp;
961 NewSs = NewTss.Ss;
962 }
963 }
964 else
965 {
966 State->InstPtr.LowWord =
State->SavedInstPtr.LowWord = NewLegacyTss->Ip;
967 State->Flags.LowWord = NewLegacyTss->Flags;
968 State->GeneralRegs[FAST486_REG_EAX].LowWord = NewLegacyTss->Ax;
969 State->GeneralRegs[FAST486_REG_ECX].LowWord = NewLegacyTss->Cx;
970 State->GeneralRegs[FAST486_REG_EDX].LowWord = NewLegacyTss->Dx;
971 State->GeneralRegs[FAST486_REG_EBX].LowWord = NewLegacyTss->Bx;
972 State->GeneralRegs[FAST486_REG_EBP].LowWord = NewLegacyTss->Bp;
973 State->GeneralRegs[FAST486_REG_ESI].LowWord = NewLegacyTss->Si;
974 State->GeneralRegs[FAST486_REG_EDI].LowWord = NewLegacyTss->Di;
975 NewEs = NewLegacyTss->Es;
976 NewCs = NewLegacyTss->Cs;
977 NewDs = NewLegacyTss->Ds;
978 NewLdtr = NewLegacyTss->Ldtr;
979
981 {
983 {
984 case 0:
985 {
986 State->GeneralRegs[FAST486_REG_ESP].Long = NewLegacyTss->Sp0;
987 NewSs = NewLegacyTss->Ss0;
988 break;
989 }
990
991 case 1:
992 {
993 State->GeneralRegs[FAST486_REG_ESP].Long = NewLegacyTss->Sp1;
994 NewSs = NewLegacyTss->Ss1;
995 break;
996 }
997
998 case 2:
999 {
1000 State->GeneralRegs[FAST486_REG_ESP].Long = NewLegacyTss->Sp2;
1001 NewSs = NewLegacyTss->Ss2;
1002 break;
1003 }
1004 }
1005 }
1006 else
1007 {
1008 State->GeneralRegs[FAST486_REG_ESP].Long = NewLegacyTss->Sp;
1009 NewSs = NewLegacyTss->Ss;
1010 }
1011 }
1012
1013
1015
1017 {
1019 FAST486_SYSTEM_DESCRIPTOR GdtEntry;
1020
1022 {
1023
1026 }
1027
1028 if (!Fast486ReadDescriptorEntry(
State, NewLdtr, &Valid, (PFAST486_GDT_ENTRY)&GdtEntry))
1029 {
1030
1032 }
1033
1034 if (!Valid)
1035 {
1036
1039 }
1040
1042 {
1043
1046 }
1047
1048 if (!GdtEntry.Present)
1049 {
1052 }
1053
1054
1055 State->Ldtr.Selector = NewLdtr;
1056 State->Ldtr.Base = GdtEntry.Base | (GdtEntry.BaseMid << 16) | (GdtEntry.BaseHigh << 24);
1057 State->Ldtr.Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
1058
1059 if (GdtEntry.Granularity)
1060 {
1061 State->Ldtr.Limit <<= 12;
1062 State->Ldtr.Limit |= 0x00000FFF;
1063 }
1064 }
1065 else
1066 {
1067
1069 }
1070
1071
1072 if (!Fast486LoadSegmentInternal(
State, FAST486_REG_CS, NewCs, FAST486_EXCEPTION_TS))
1073 {
1075 }
1076
1077 if (!Fast486LoadSegmentInternal(
State, FAST486_REG_SS, NewSs, FAST486_EXCEPTION_TS))
1078 {
1080 }
1081
1082 if (!Fast486LoadSegmentInternal(
State, FAST486_REG_ES, NewEs, FAST486_EXCEPTION_TS))
1083 {
1085 }
1086
1087 if (!Fast486LoadSegmentInternal(
State, FAST486_REG_DS, NewDs, FAST486_EXCEPTION_TS))
1088 {
1090 }
1091
1093 {
1094 if (!Fast486LoadSegmentInternal(
State,
1095 FAST486_REG_FS,
1096 NewTss.Fs,
1097 FAST486_EXCEPTION_TS))
1098 {
1100 }
1101
1102 if (!Fast486LoadSegmentInternal(
State,
1103 FAST486_REG_GS,
1104 NewTss.Gs,
1105 FAST486_EXCEPTION_TS))
1106 {
1108 }
1109 }
1110
1112}
#define FAST486_BUSY_TSS_16_SIGNATURE
#define FAST486_TSS_SIGNATURE
#define FAST486_TSS_16_SIGNATURE
#define FAST486_LDT_SIGNATURE
#define FAST486_BUSY_TSS_SIGNATURE
#define GET_SEGMENT_RPL(s)
#define GET_SEGMENT_INDEX(s)
#define SEGMENT_TABLE_INDICATOR
#define RtlZeroMemory(Destination, Length)