Announcement

Collapse

Forum Rules and Etiquette

Our mission ...

This forum is part of our mission to promote the preservation of vintage computers through education and outreach. (In real life we also run events and have a museum.) We encourage you to join us, participate, share your knowledge, and enjoy.

This forum has been around in this format for over 15 years. These rules and guidelines help us maintain a healthy and active community, and we moderate the forum to keep things on track. Please familiarize yourself with these rules and guidelines.


Rule 1: Remain civil and respectful

There are several hundred people who actively participate here. People come from all different backgrounds and will have different ways of seeing things. You will not agree with everything you read here. Back-and-forth discussions are fine but do not cross the line into rude or disrespectful behavior.

Conduct yourself as you would at any other place where people come together in person to discuss their hobby. If you wouldn't say something to somebody in person, then you probably should not be writing it here.

This should be obvious but, just in case: profanity, threats, slurs against any group (sexual, racial, gender, etc.) will not be tolerated.


Rule 2: Stay close to the original topic being discussed
  • If you are starting a new thread choose a reasonable sub-forum to start your thread. (If you choose incorrectly don't worry, we can fix that.)
  • If you are responding to a thread, stay on topic - the original poster was trying to achieve something. You can always start a new thread instead of potentially "hijacking" an existing thread.



Rule 3: Contribute something meaningful

To put things in engineering terms, we value a high signal to noise ratio. Coming here should not be a waste of time.
  • This is not a chat room. If you are taking less than 30 seconds to make a post then you are probably doing something wrong. A post should be on topic, clear, and contribute something meaningful to the discussion. If people read your posts and feel that their time as been wasted, they will stop reading your posts. Worse yet, they will stop visiting and we'll lose their experience and contributions.
  • Do not bump threads.
  • Do not "necro-post" unless you are following up to a specific person on a specific thread. And even then, that person may have moved on. Just start a new thread for your related topic.
  • Use the Private Message system for posts that are targeted at a specific person.


Rule 4: "PM Sent!" messages (or, how to use the Private Message system)

This forum has a private message feature that we want people to use for messages that are not of general interest to other members.

In short, if you are going to reply to a thread and that reply is targeted to a specific individual and not of interest to anybody else (either now or in the future) then send a private message instead.

Here are some obvious examples of when you should not reply to a thread and use the PM system instead:
  • "PM Sent!": Do not tell the rest of us that you sent a PM ... the forum software will tell the other person that they have a PM waiting.
  • "How much is shipping to ....": This is a very specific and directed question that is not of interest to anybody else.


Why do we have this policy? Sending a "PM Sent!" type message basically wastes everybody else's time by making them having to scroll past a post in a thread that looks to be updated, when the update is not meaningful. And the person you are sending the PM to will be notified by the forum software that they have a message waiting for them. Look up at the top near the right edge where it says 'Notifications' ... if you have a PM waiting, it will tell you there.

Rule 5: Copyright and other legal issues

We are here to discuss vintage computing, so discussing software, books, and other intellectual property that is on-topic is fine. We don't want people using these forums to discuss or enable copyright violations or other things that are against the law; whether you agree with the law or not is irrelevant. Do not use our resources for something that is legally or morally questionable.

Our discussions here generally fall under "fair use." Telling people how to pirate a software title is an example of something that is not allowable here.


Reporting problematic posts

If you see spam, a wildly off-topic post, or something abusive or illegal please report the thread by clicking on the "Report Post" icon. (It looks like an exclamation point in a triangle and it is available under every post.) This send a notification to all of the moderators, so somebody will see it and deal with it.

If you are unsure you may consider sending a private message to a moderator instead.


New user moderation

New users are directly moderated so that we can weed spammers out early. This means that for your first 10 posts you will have some delay before they are seen. We understand this can be disruptive to the flow of conversation and we try to keep up with our new user moderation duties to avoid undue inconvenience. Please do not make duplicate posts, extra posts to bump your post count, or ask the moderators to expedite this process; 10 moderated posts will go by quickly.

New users also have a smaller personal message inbox limit and are rate limited when sending PMs to other users.


Other suggestions
  • Use Google, books, or other definitive sources. There is a lot of information out there.
  • Don't make people guess at what you are trying to say; we are not mind readers. Be clear and concise.
  • Spelling and grammar are not rated, but they do make a post easier to read.
See more
See less

I found the SAVEALL opcode

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    I found the SAVEALL opcode

    Everyone who is interested in this sort of thing already knows about the LOADALL instruction. But what Intel didn't include in this no-longer-secret document is that there is an instruction that does the reverse, and it can be used on a regular 286 chip without extra pins.

    There is one hint in Intel's attempts at misdirection:

    The opcode 0D6H is a proprietary single byte instruction. No restrictions apply to its execution. It can be emulated as a NOP.

    The 0F1H opcode is a prefix which performs no function. It counts like any other prefix towards the maximum instruction length. No restrictions apply to its execution.
    D6 does do something of course, and I suspected F1 might as well. Note it says that it is a prefix!

    Executing 0F 04 will lock up the CPU without doing anything. With the F1 prefix, it appears at first to do the same, but the internal state is actually written to memory at 000800H! All we need is a short timeout before resetting the CPU, and the keyboard controller is slow enough to work for that.

    This might be helpful to investigate some internal details, the 10 extra words ignored by LOADALL are written too. Maybe also for a debugger (if only there was a way to interrupt without changing any descriptor caches!)
    Attached Files

    #2
    Is this 80286 only or does it also apply to later CPUs? Is it uniformly implemented in the second source 80286 and 80C286 CPUs?
    Reach me: vcfblackhole _at_ protonmail dot com.

    Comment


      #3
      Originally posted by Chuck(G) View Post
      Is this 80286 only or does it also apply to later CPUs? Is it uniformly implemented in the second source 80286 and 80C286 CPUs?
      I assume it works on every 286, but not on any later generation, since they don't have the 286 version of LOADALL. Maybe there is something similar on 386s, I don't have any to test this with.

      Comment


        #4
        N80C286-12
        ET 037E6KX
        (M) AMD
        (C) INTEL 1982

        Results:
        Code:
        (clean boot, no HIMEM.SYS)
        ???? ???? ????  MSW stk? ???? ???? ???? ???? ???? ????
        0018 9310 00AD FFF0 03AE 0000 00E6 0000 0000 03B0 0002
        
        (with HIMEM.SYS)
        0000 9315 00AD ...
        My other 286:
        Harris
        CS80C286-16
        F3360 (delta) 8929
        (C) INTEL '82

        Hangs, which shouldn't happen - likely a problem with the mainboard, BIOS or my reset code. I'll try the chip in the first machine later.

        Comment


          #5
          Tested the Harris chip and another AMD in the same machine, they all work. There are some differences in both unitialized descriptors and the unknown registers, as seen after a clean boot:

          Code:
          N80C286-12
          ET 037E6KX
          (M) AMD
          (C) INTEL 1982
          
          ???? ???? ????  MSW stk? ???? ???? ???? ???? ???? ????
          0018 9310 0164 FFF0 03BE 0000 00E6 0000 0000 03C0 0060 
          
          TASK FLAG   IP  LDT   DS   SS   CS   ES
          0000 0046 016B 0000 0F9A 0F9A 0F7E 0F9A 
          
            DI   SI   BP   SP   BX   DX   CX   AX
          04C0 0900 091C 03C0 0000 0171 0F7E 00FE 
          
          ESbase ar  lim CSbase ar  lim SSbase ar  lim DSbase ar  lim
          00F9A0 82 FFFF 00F7E0 82 FFFF 00F9A0 82 FFFF 00F9A0 82 FFFF 
          
          GDTbas ar  lim LDTbas ar  lim IDTbas ar  lim TSSbas ar  lim
          08F866 FF FFFF 000000 7F 0000 000000 FF FFFF 000000 FF 0000 
          ------
          
          HARRIS
          CS80C286-16
          F3360 Δ 8929
          (C) INTEL '82
          
          ???? ???? ????  MSW stk? ???? ???? ???? ???? ???? ????
          0018 9310 0164 FFF0 03BE 5EEC 00E6 CD8D 8BFC 03C0 0060
          
          TASK FLAG   IP  LDT   DS   SS   CS   ES
          0000 0046 016B 0000 0F9A 0F9A 0F7E 0F9A
          
            DI   SI   BP   SP   BX   DX   CX   AX
          04C0 0900 091C 03C0 0000 0171 0F7E 00FE
          
          ESbase ar  lim CSbase ar  lim SSbase ar  lim DSbase ar  lim
          00F9A0 82 FFFF 00F7E0 82 FFFF 00F9A0 82 FFFF 00F9A0 82 FFFF
          
          GDTbas ar  lim LDTbas ar  lim IDTbas ar  lim TSSbas ar  lim
          08F866 FF FFFF FFFFFF FF FFFF 000000 FF FFFF FFFFFF FF FFFF
          
          ------
          
          AMD
          N80L286-10/S
          003D42S
          (M) (C) INTEL 1982
          
          ???? ???? ????  MSW stk? ???? ???? ???? ???? ???? ????
          0018 9310 0164 FFF0 03BE FFFF 00E6 FFFF FFFF 03C0 0060
          
          TASK FLAG   IP  LDT   DS   SS   CS   ES
          0000 0046 016B 0000 0F9A 0F9A 0F7E 0F9A
          
            DI   SI   BP   SP   BX   DX   CX   AX
          04C0 0900 091C 03C0 0000 0171 0F7E 00FE
          
          ESbase ar  lim CSbase ar  lim SSbase ar  lim DSbase ar  lim
          00F9A0 82 FFFF 00F7E0 82 FFFF 00F9A0 82 FFFF 00F9A0 82 FFFF
          
          GDTbas ar  lim LDTbas ar  lim IDTbas ar  lim TSSbas ar  lim
          08F866 FF FFFF FFFFFF FF FFFF 000000 FF FFFF FFFFFF FF FFFF
          I also did a quick check of which registers can be changed using LOADALL (on the 80C286-12):

          0800 writable
          0802 only some bits, CPL/access rights?
          0804 no change
          0808 no change, copy of SP before last push/pop?
          080A writable
          080C writable
          080E writable
          0810 writable
          0812 no change
          0814 no change

          Comment


            #6
            That's awesome

            Comment


              #7
              dreNorteR,

              This is very interesting. A couple of questions:
              What happens if you run the following in DEBUG under DOS 3.3 or 4.0/4.01 (those versions of DOS reserve 102 bytes at 0:800h for LOADALL use by HIMEM.SYS):

              e 100 f1 0f 04 cc 90
              g
              d 0:800

              Theoretically since DOS 3.3 and 4.0/4.01 reserve 102 bytes in the IBMBIO/IO.SYS data area this should not hang DOS since no system data will be overwritten.

              Also what happens if you use F0 instead of F1 as the first byte ? If F0 works the same as F1 then this would show that F1 is an alias for F0 (LOCK) on the 286.

              Comment


                #8
                I made a program that lets you interactively change the registers. A "Load+Save" function sets everything up to immediately start the reset and save operation:

                Code:
                ;come here by LOADALL, DX=0064, AL=FE
                out dx,al
                db 0f1h,0fh,04h
                ;can resume here with another LOADALL
                jmp hello_world
                All registers except for X1 and maybe X8 are writable, some just don't keep their value for much more than these minimal instructions. Changing them doesn't have any observable effect so far. Would be kind of disappointing if there isn't some secret debug mode to be enabled...

                800 'X0' ???
                802 'X1' ??? (read-only? high byte always 93 or 83)
                804 'X2' IP after last CALL or near RET
                808 'X3' Value of SP before last stack access
                80A 'X4' ???
                80C 'X5' ???
                80E 'X6' ???
                810 'X7' ???
                812 'X8' (loses written value) SP after last RET
                814 'X9' IP after last RETF or IRET

                X4 (but not X5), X6 and X7 persist after Ctrl-Alt-Del on my machine.
                X5 (but not X4), X6 and X7 after CPU reset.
                X8 seems to have another temporary use that makes it change immediately. Maybe I/O instructions?

                Can anyone try if this works at all on their machine?

                edit: very quick & dirty user interface, doesn't support mono video card
                Attached Files

                Comment


                  #9
                  Made a few improvements, like monochrome support and more reliable reset code. I didn't enable A20 before, since it worked for me without that, but many machines apparently require this. Also disabling the keyboard so it can't interfere during reset, which seems to have fixed some random hangs for me.

                  Still only works on one of my two machines, so I really want someone else to try it!
                  (Reset and LOADALL work on both, only SAVEALL hangs)

                  F1: Set up defaults for LOADALL (also done at start)
                  F2: Test CPU reset
                  F3: Test SAVEALL on its own
                  F4: Test LOADALL on its own
                  F5: LOADALL -> reset+SAVEALL immediately afterwards
                  F6: Same, but starts reset even before LOADALL

                  Starting the reset command before LOADALL seems to be just as reliable. And X8 is used by the LOADALL microcode itself, which is why it is set to 0864 - the address of the last word loaded.

                  -----

                  So what is the F1 prefix really? I don't think Intel added this just to be extra sneaky, there must be a technical reason. Some research / speculation:

                  The original purpose of LOADALL was to return from ICE mode (similar to SMM on newer CPUs), loading all the internal registers is just a necessary part of that. When LOADALL is executed in ICE mode, the state would be loaded from its own special address space that uses extra pins, which are likely not connected on a normal 80286 chip.

                  0F 04 must then be the opcode to enter ICE mode, and the CPU switches immediately to this separate address space, waiting forever for a ready signal on the non-connected pins. But there must be a way for ICE mode to access the memory of the program being debugged. The 80386 has the UMOV instruction for this.

                  So it is likely that this is the function performed by the F1 prefix on the 286 (which is different from the 386's ICEBP opcode): it modifies an instruction to access memory using the normal bus pins. Outside of ICE mode, it has no effect, as Intel documented. The one exception is 0F 04, because when executing the state save it has already switched modes.

                  Unfortunately, the mode switch seems to clear the prefetch queue, so we can't get it to execute an instruction in ICE mode (like F1 0F 05 to resume normal execution, although there is another reason this couldn't work - can you see why?).

                  I also couldn't get a triple fault by setting the IDT limit to zero and enabling the trap flag just before switching. Either these registers are reset, or the CPU gets stuck before a trap can occur.
                  Attached Files
                  Last edited by dreNorteR; June 24, 2019, 12:39 AM.

                  Comment


                    #10
                    Well, you can see why the F1 instruction went undocumented--on the 80386 and higher, it serves a different function--so called "ICEBP" INT 01 instruction. I wonder if other F1 xx opcodes on the 80286 tie in with the bond-out 80286 used in ICE.

                    The instruction clutter got so bad with later CPUs that Intel eventually had to have two "official" undocumented opcodes for the software emulators (UD1 and UD2).
                    Reach me: vcfblackhole _at_ protonmail dot com.

                    Comment


                      #11
                      Originally posted by Chuck(G) View Post
                      Well, you can see why the F1 instruction went undocumented--on the 80386 and higher, it serves a different function--so called "ICEBP" INT 01 instruction. I wonder if other F1 xx opcodes on the 80286 tie in with the bond-out 80286 used in ICE.
                      Yes, F1h on the 286 is a prefix, and different from ICEBP which is a single byte opcode for 386+

                      Its likely function is to access user memory from ICE mode, which explains how it interacts with 0F 04. But of course we can't know for sure, unless someone who actually worked at Intel on the 286 design confirms this.

                      Comment


                        #12
                        Originally posted by dreNorteR View Post
                        Yes, F1h on the 286 is a prefix, and different from ICEBP which is a single byte opcode for 386+

                        Its likely function is to access user memory from ICE mode, which explains how it interacts with 0F 04. But of course we can't know for sure, unless someone who actually worked at Intel on the 286 design confirms this.
                        Try replacing F1h with F0h and executing F0h 0Fh 04h and see what happens (see my earlier post in this thread).

                        Comment


                          #13
                          Originally posted by pcdosretro View Post
                          Try replacing F1h with F0h and executing F0h 0Fh 04h and see what happens (see my earlier post in this thread).
                          Sorry, didn't see your post!

                          F1 is not an alias for F0, nothing will get written to memory if you use the F0 prefix. Also, whether you use the correct prefix or not, the CPU will hang and has to be reset to regain control. Using the keyboard controller (output FEh to port 64h) works because there is a delay long enough that the instruction can execute first.

                          My test program saves the data at 0800, so it will run under DOS 6.22.

                          Comment


                            #14
                            Apparently Intel referred to this instruction as STOREALL - https://www.pcjs.org/pubs/pc/referen...80386/loadall/

                            Comment


                              #15
                              Having tested some more, it seems that all the extra registers are simply temporary values used by certain instructions. X1 must be involved in privilege checking and FPU emulation; for some reason, LOADALL will leave a copy of the word containing access rights of the ES (not CS or SS) descriptor there. Floating point opcodes load it with MSW.

                              X0 and X4-X7 are all used in protected mode, as can be seen after starting and exiting Windows 3.0.

                              So, no hidden features to unlock, and apart from the descriptor caches it seems rather useless for debugging too. I wonder if Intel actually had a need to save this particular information, or if it is just a side effect of how the state saving works?

                              I think there is not much more to discover about this, except for the actual code used by Intel in their I²ICE system. From reading the documentation archived on bitsavers, the code for the probe module is not in ROM but loaded by the host software, from a file called I2ICE.286. A disassembly of that could confirm the actual intended use of the F1 prefix.

                              edit:
                              Originally posted by pcdosretro View Post
                              Apparently Intel referred to this instruction as STOREALL - https://www.pcjs.org/pubs/pc/referen...80386/loadall/
                              Thanks for the link (now I can see your post for some reason, must be the "new user" filter), wouldn't have expected this page to have information on the 286. This seems to confirm what I found out with my experiments:

                              The 286 also loads a number of temp registers, but the values in these registers are “dead” when the next instruction (other than STOREALL) begins execution. Consequently, the values loaded into the temp registers can have no effecton 286 program execution, so these can be ignored. As long as the 386 temps are also “dead” when the next instruction begins (except for STOREALL), there will be no problems with 386-specific temp registers.
                              Last edited by dreNorteR; June 26, 2019, 06:38 AM.

                              Comment

                              Working...
                              X