A Real PC XT Core Perhaps?

For topics which do not fit in other specific forums.
User avatar
Newsdee
Top Contributor
Posts: 830
Joined: Mon May 25, 2020 1:07 am
Has thanked: 98 times
Been thanked: 209 times

Re: A Real PC XT Core Perhaps?

Unread post by Newsdee »

jordi wrote: Tue Dec 28, 2021 9:11 am This core would be a must in Mister, as a preservation project! I vote for porting it.
Definitely has a niche for early games that run on composite colors, if it could simulate the artifacting as is done with the Apple II core.
This page lists 57 games that support that mode: https://www.mobygames.com/attribute/she ... Id,29/p,4/
breiztiger
Top Contributor
Posts: 427
Joined: Sun May 24, 2020 7:17 pm
Has thanked: 23 times
Been thanked: 93 times

Re: A Real PC XT Core Perhaps?

Unread post by breiztiger »

not only for video but for real xt speed also
CPC-Power Staff
jordi
Posts: 225
Joined: Thu Jun 11, 2020 10:11 am
Has thanked: 87 times
Been thanked: 71 times

Re: A Real PC XT Core Perhaps?

Unread post by jordi »

Newsdee wrote: Tue Dec 28, 2021 1:34 pm
jordi wrote: Tue Dec 28, 2021 9:11 am This core would be a must in Mister, as a preservation project! I vote for porting it.
Definitely has a niche for early games that run on composite colors, if it could simulate the artifacting as is done with the Apple II core.
This page lists 57 games that support that mode: https://www.mobygames.com/attribute/she ... Id,29/p,4/
and it's missing some games, isn't it? like maniac mansion.
jordi
Posts: 225
Joined: Thu Jun 11, 2020 10:11 am
Has thanked: 87 times
Been thanked: 71 times

Re: A Real PC XT Core Perhaps?

Unread post by jordi »

breiztiger wrote: Tue Dec 28, 2021 1:42 pm not only for video but for real xt speed also
yep, like test drive. I never feel it's running at right speed :lol:
User avatar
Newsdee
Top Contributor
Posts: 830
Joined: Mon May 25, 2020 1:07 am
Has thanked: 98 times
Been thanked: 209 times

Re: A Real PC XT Core Perhaps?

Unread post by Newsdee »

Magiduck looks fun to play (CGA composite modern game):
https://sparcie.wordpress.com/2018/02/2 ... k-for-dos/
Mills
Posts: 83
Joined: Mon Jun 08, 2020 2:52 pm
Has thanked: 15 times
Been thanked: 29 times

Re: A Real PC XT Core Perhaps?

Unread post by Mills »

This is a great!.

I tried to synthesize next186 (mist port) to test on my mister. It showed no errors, but I don't know how to connect the core to mister's sys functions... So there is no graphics, input or sound :) .

I wanted to help by making CPU instructions cycle accurate (8088, then an 8086 and 186 could also be created), next186 cpu sources are very easy to read and I wanted to give it a try.
Hope more people find this interesting because any improvements can be shared to create cores on any fpga.
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

First of all, happy new year! Let's see if this year is better than 2021.

I have made an analysis of a game that does not work in this core , the Tapper. In this case, we get to the menu screen and it is possible to modify the options, but when starting it, it hangs at this point:

IMG_20211231_173919.jpg
IMG_20211231_173919.jpg (39.05 KiB) Viewed 15388 times

If we debug it, we have that the point where it hangs is in the following instruction JNZ:

tapper_1.jpg
tapper_1.jpg (105.47 KiB) Viewed 15388 times

As can be seen, the variable located at 0x44c3 is checked and as long as it is not 0 it remains in a loop. Higher up in the code, you can also see that it has been set to 1 but apparently no change is observed between the two points. However, adding a trace at that point, at the time it hangs, it is not worth 1, but I have been able to verify that it is worth 0FEh. This is what puzzles me, where and how is this value being modified?. If we want to prevent it from getting hung up, it is as simple as patching the game in the following way, for example:

IMG_20211231_174429.jpg
IMG_20211231_174429.jpg (72.95 KiB) Viewed 15388 times

Now we are over this screen and we could play:

IMG_20211231_175112.jpg
IMG_20211231_175112.jpg (280.93 KiB) Viewed 15388 times

Although partially, since the music of the game does not work and when the game ends, this time it hangs on the initial screen
of welcoming:

IMG_20211231_175024.jpg
IMG_20211231_175024.jpg (162 KiB) Viewed 15388 times

Which leads me to think that this wait method applies at various points. In fact, in a real PCXT or in the PCEM, before continuing at these points after a short time.

Therefore, we analyze the points where it is referred to:

tapper_3.jpg
tapper_3.jpg (56.39 KiB) Viewed 15388 times

And we see that there are several points where this value changes and there is a loop. I would say that some background timer is changing it because there are more areas of the code where the initial value and the loop was obtained in a row:

tapper_2.jpg
tapper_2.jpg (29.32 KiB) Viewed 15388 times

Looking for references to calls to the timer 8259 of a PCXT, we found a couple of them, one of them here:

tapper_4.jpg
tapper_4.jpg (149.02 KiB) Viewed 15388 times

and another at a very close point and similar in appearance. I've also seen a routine related to DMA get called a couple of times:

tapper_5.jpg
tapper_5.jpg (116.48 KiB) Viewed 15388 times

And if we now look at the shortcomings of Next186:

Next186.jpg
Next186.jpg (83.79 KiB) Viewed 15388 times

Everything starts to make more sense. Looping music and screen-to-screen timeouts will most likely not work due to these issues. But the difficult thing in this case is not the identification of the problem, but how to establish the correct solution that does not go through patching the game, since I am sure that these may be affecting other games and programs with various associated effects that make them not compatible with the core.
User avatar
kathleen
Top Contributor
Posts: 409
Joined: Fri Jun 26, 2020 4:23 am
Location: Belgium
Has thanked: 224 times
Been thanked: 131 times

Re: A Real PC XT Core Perhaps?

Unread post by kathleen »

spark2k06 wrote: Sat Jan 01, 2022 6:38 am First of all, happy new year! Let's see if this year is better than 2021.
Happy new year to you as well ! Cross my fingers for having a better year than 2021, I'm confident it will be.

For the rest, I cannot help :-( But this is already a good step that you identified the root cause. Hope that somebody with the right skill will be willing to help you to solve this issue.

かすりん

User avatar
pgimeno
Top Contributor
Posts: 669
Joined: Thu Jun 11, 2020 9:44 am
Has thanked: 246 times
Been thanked: 208 times

Re: A Real PC XT Core Perhaps?

Unread post by pgimeno »

spark2k06 wrote: Sat Jan 01, 2022 6:38 am I have made an analysis of a game that does not work in this core , the Tapper. In this case, we get to the menu screen and it is possible to modify the options, but when starting it, it hangs at this point:

[...]
There's something weird in your analysis. Position 44C3h gets modified by the INT 1Ch (Timer Tick) handler, which is located at 3758h. That interrupt handler is somewhat long; in particular this fragment is the one that should modify the byte at 44C3h:

Code: Select all

L37C1:
        dec     byte ptr cs:[44C2]
        jne     L37DB
        mov     byte ptr cs:[44C2],3C
        cmp     byte ptr cs:[44C3],0
        je      L37DB
        dec     byte ptr cs:[44C3]
L37DB:
From that, I don't see how can that byte possibly become FEh, because it's a countdown that should stop at 0 and never wrap around. The other counter, 44C2h, seems to be constantly counting from 60 (3Ch) to 0 as a divisor of the tick frequency. Finding what writes an FEh to 44C3h would be important for diagnosis, because that should never happen, and it suggests a bug in the CPU module.

For some reason, that routine is not listed in your list of references to 44C3h.
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

pgimeno wrote: Sat Jan 01, 2022 1:04 pm
spark2k06 wrote: Sat Jan 01, 2022 6:38 am I have made an analysis of a game that does not work in this core , the Tapper. In this case, we get to the menu screen and it is possible to modify the options, but when starting it, it hangs at this point:

[...]
There's something weird in your analysis. Position 44C3h gets modified by the INT 1Ch (Timer Tick) handler, which is located at 3758h. That interrupt handler is somewhat long; in particular this fragment is the one that should modify the byte at 44C3h:

Code: Select all

L37C1:
        dec     byte ptr cs:[44C2]
        jne     L37DB
        mov     byte ptr cs:[44C2],3C
        cmp     byte ptr cs:[44C3],0
        je      L37DB
        dec     byte ptr cs:[44C3]
L37DB:
From that, I don't see how can that byte possibly become FEh, because it's a countdown that should stop at 0 and never wrap around. The other counter, 44C2h, seems to be constantly counting from 60 (3Ch) to 0 as a divisor of the tick frequency. Finding what writes an FEh to 44C3h would be important for diagnosis, because that should never happen, and it suggests a bug in the CPU module.

For some reason, that routine is not listed in your list of references to 44C3h.
Very well seen! I have not detected where the change of address is made in the 1Ch interrupt, but it is clear that at the point you comment is where the change of value of the content of that address takes place, I will check the CPU module, it would not surprise me that again due to problems with the code cache.

The IDA has not automatically detected the code of that int, I should have identified it myself manually so that later the IDA finds all the references, it is good to know for the next

I will keep you informed
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

I had incorrectly fetched the content of CS: [44C3], actually I was getting it from the DS segment, other than CS. Now I get it fine, and it contains 1, as it should be ... I keep investigating the decrement of CS: [44C2]. It may have something to do with the timer timings.
User avatar
pgimeno
Top Contributor
Posts: 669
Joined: Thu Jun 11, 2020 9:44 am
Has thanked: 246 times
Been thanked: 208 times

Re: A Real PC XT Core Perhaps?

Unread post by pgimeno »

INT 1Ch should be called by the BIOS INT 08h handler. Is it possible that that isn't happening with the BIOS you're using?

If the timer is to blame and not the BIOS, it's possible that it works, but the speed is much slower than the creators anticipated. Have you waited for a while just in case?
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

pgimeno wrote: Sat Jan 01, 2022 7:11 pm INT 1Ch should be called by the BIOS INT 08h handler. Is it possible that that isn't happening with the BIOS you're using?

If the timer is to blame and not the BIOS, it's possible that it works, but the speed is much slower than the creators anticipated. Have you waited for a while just in case?
I have verified that 3C is decremented until reaching the loop, but, it seems that once there the int 8 is never launched. I've patched that loop to jump to another code where I force int 8 to run ... and that's how it works:

20220102-141243-045.jpg
20220102-141243-045.jpg (43.39 KiB) Viewed 14802 times

Therefore, there must be a bug in the Next186 CPU module that disable this int (and others maybe?), it will be the next thing to analyze.
User avatar
pgimeno
Top Contributor
Posts: 669
Joined: Thu Jun 11, 2020 9:44 am
Has thanked: 246 times
Been thanked: 208 times

Re: A Real PC XT Core Perhaps?

Unread post by pgimeno »

spark2k06 wrote: Sun Jan 02, 2022 2:20 pmI have verified that 3C is decremented until reaching the loop, but, it seems that once there the int 8 is never launched. I've patched that loop to jump to another code where I force int 8 to run ... and that's how it works:

[...]

Therefore, there must be a bug in the Next186 CPU module that disable this int (and others maybe?), it will be the next thing to analyze.
By 3C do you mean 44C3?

There are many possible hypotheses, it's hard to put the finger on one. The interrupt flag may be a possible culprit, for example, especially if you say that the timer interrupt works in other circumstances. A wrong implementation of the 8259 PIC may be another one.

Do you have Quaid Analyzer? I think it's much more suitable for this task than debug, because it gives you control and step-by-step trace even when the keyboard interrupt is trapped by the application. It also tries to preserve the graphical screen and switch to text mode for debugging (the graphical screen is not correctly preserved in most cases, but at least you can see what you're doing). It also allows you to trace whether interrupts are executed, and even to redefine the breakpoint interrupt in case INT 3 is blocked by the application (but you have to be careful because then it becomes a length 2 instruction). It's quirky and not very comfortable to work with, but these features make it reach places that debug can't.
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

pgimeno wrote:
By 3C do you mean 44C3?
Sorry for not being more specific. By 3C, I mean the divisor you were commenting on at address 44C2...
It is seen that until the loop is reached, it is correctly decremented.
pgimeno wrote:
There are many possible hypotheses, it's hard to put the finger on one. The interrupt flag may be a possible culprit, for example, especially if you say that the timer interrupt works in other circumstances. A wrong implementation of the 8259 PIC may be another one.
I have already found the exact reason for this behavior. It turns out that before reaching this loop, between functions, a call is made to INT 13h, and what happens is that its output always clears the interrupt flag... and I also see that it does so after its return in IRET. So there are two options:

1. Bug in Next186 IP module.

2. Bug in the BIOS routine used in the Next186 project:

https://github.com/spark2k06/next186lit ... ext186.ASM

Code: Select all

; --------------------- INT 13h - Disk services ----------------
HDLastError       equ     <ds:[74h]>
HDOpStarted       equ     <ds:[92h]>    ; bit 3: in INT13h (all other bits must be 0)
HDSize            equ     <ds:[94h]>

int13   proc near
        push    ds
        push    bp
        push    40h
        pop     ds
        xor     byte ptr HDOpStarted, 8
        jz      short inINT13
        sti                     
        cld
        cmp     ah, 1ah
        jbe     short Disk1
        sub     ah, 41h-1bh     ; extensions
        cmp     ah, 22h
        jbe     short Disk1
        mov     ah, 1           ; bad command error
        jmp     short exit33
inINT13:        
        mov     ah, 0aah        ; drive not ready
        jmp     short exit2
Disk1:
        mov     bp, ax
        shr     bp, 7
        and     bp, 1feh
        push    ds
        call    cs:disktbl[bp]
        pop     ds
exit33:        
        mov     HDLastError, ah
exit2:
        xor     byte ptr HDOpStarted, 8
        neg     ah              ; CF <- (AH != 0)
exit77:
        mov     bp, sp
        rcr     byte ptr [bp+8], 1
        rol     byte ptr [bp+8], 1  ; insert error CF on stack
        neg     ah
        pop     bp
        pop     ds
        iret
I'm thinking about where the real problem may be. Now it is easy to debug it, because a simple call to INT 13h from the debugger allows us to see how after the IRET, it clears the interrupt flag ... when from PCEM or in a real PCXT machine this does not happen. It is therefore very likely that the bug is in the Next186 module.
pgimeno wrote: Do you have Quaid Analyzer? I think it's much more suitable for this task than debug, because it gives you control and step-by-step trace even when the keyboard interrupt is trapped by the application. It also tries to preserve the graphical screen and switch to text mode for debugging (the graphical screen is not correctly preserved in most cases, but at least you can see what you're doing). It also allows you to trace whether interrupts are executed, and even to redefine the breakpoint interrupt in case INT 3 is blocked by the application (but you have to be careful because then it becomes a length 2 instruction). It's quirky and not very comfortable to work with, but these features make it reach places that debug can't.
I did not know Quaid Analyzer, thank you very much for the suggestion, I will keep it in mind for future debugging ;-)
User avatar
pgimeno
Top Contributor
Posts: 669
Joined: Thu Jun 11, 2020 9:44 am
Has thanked: 246 times
Been thanked: 208 times

Re: A Real PC XT Core Perhaps?

Unread post by pgimeno »

spark2k06 wrote: Mon Jan 03, 2022 12:20 pm I'm thinking about where the real problem may be. Now it is easy to debug it, because a simple call to INT 13h from the debugger allows us to see how after the IRET, it clears the interrupt flag ... when from PCEM or in a real PCXT machine this does not happen. It is therefore very likely that the bug is in the Next186 module.
Good finding. IRET should definitely restore interrupts to the state stored in the stack. If they were disabled before executing INT 13h, they should be disabled after IRET. If they were enabled, they should be enabled after IRET. If that's not the case, then the implementation of IRET is buggy. Of course it's possible to fiddle with the stack inside the interrupt routine, and disable the copy of the flags stored there, to enable/disable interrupts on return, but it doesn't seem to me that the INT 13h handler does this, from what you've posted.

EDIT: Come to think about it, the bug might be in these read-modify-write instructions:

Code: Select all

        rcr     byte ptr [bp+8], 1
        rol     byte ptr [bp+8], 1  ; insert error CF on stack
It should not be accessing the second byte of the flags, where the interrupt flag is stored, because it's a byte access. Worth taking a look though.
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

pgimeno wrote: Mon Jan 03, 2022 1:12 pm Good finding. IRET should definitely restore interrupts to the state stored in the stack. If they were disabled before executing INT 13h, they should be disabled after IRET. If they were enabled, they should be enabled after IRET. If that's not the case, then the implementation of IRET is buggy. Of course it's possible to fiddle with the stack and disable the copy of the flags stored there, to enable/disable interrupts on return, but it doesn't seem to me that the INT 13h handler does this, from what you've posted.
Yes, but curiously, the INT 13h does not behave like this in the PCEM for example ... within the INT 13h routine there is an STI, and apparently, in this case the correct behavior is for the function to return the enabled interrupts, although prior to the INT 13h call they are disabled:

INT13h.jpg
INT13h.jpg (24.68 KiB) Viewed 14803 times

So the original PCEM BIOS routine does seem to fiddle with the stack, or so I think.
User avatar
pgimeno
Top Contributor
Posts: 669
Joined: Thu Jun 11, 2020 9:44 am
Has thanked: 246 times
Been thanked: 208 times

Re: A Real PC XT Core Perhaps?

Unread post by pgimeno »

Oops, I edited while you were typing. Please take a look at my edit above.
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

pgimeno wrote: Mon Jan 03, 2022 1:12 pm
EDIT: Come to think about it, the bug might be in these read-modify-write instructions:

Code: Select all

        rcr     byte ptr [bp+8], 1
        rol     byte ptr [bp+8], 1  ; insert error CF on stack
It should not be accessing the second byte of the flags, where the interrupt flag is stored, because it's a byte access. Worth taking a look though.
Very well seen too! I will take a look :-)
User avatar
pgimeno
Top Contributor
Posts: 669
Joined: Thu Jun 11, 2020 9:44 am
Has thanked: 246 times
Been thanked: 208 times

Re: A Real PC XT Core Perhaps?

Unread post by pgimeno »

spark2k06 wrote: Mon Jan 03, 2022 1:24 pm Yes, but curiously, the INT 13h does not behave like this in the PCEM for example ... within the INT 13h routine there is an STI, and apparently, in this case the correct behavior is for the function to return the enabled interrupts, although prior to the INT 13h call they are disabled:
A different BIOS may not use IRET for returning. It's fairly usual to use RETF 0002h to return without restoring the flags. The BIOS you posted does use IRET though, therefore the interrupt flag should be preserved.

Edit: From my recollection, this inconsistency in handling the interrupt flag (some forcing it set, some restoring it) was endemic in interrupt handlers (except those for IRQs of course). Most handlers forced it set and returned with RETF 0002h instead of IRET. It's usual to have to disable ints after an interrupt call if you want them off, even if they were off before the call.
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

pgimeno wrote: Mon Jan 03, 2022 1:32 pm Edit: From my recollection, this inconsistency in handling the interrupt flag (some forcing it set, some restoring it) was endemic in interrupt handlers (except those for IRQs of course). Most handlers forced it set and returned with RETF 0002h instead of IRET. It's usual to have to disable ints after an interrupt call if you want them off, even if they were off before the call.
Yes,

Code: Select all

exit77:
        mov     bp, sp
        rcr     byte ptr [bp+8], 1
        rol     byte ptr [bp+8], 1  ; insert error CF on stack
	or      byte ptr [bp+9], 2  ; sti
        neg     ah
        pop     bp
        pop     ds
        iret
Yes, for now I solved it by setting the bit directly on the stack. So the bug is finally in the BIOS, but I am very afraid that this BIOS is full of mines, the music still does not work ... and there are other apps that hang, who knows why, such as the Turbo Debbuger. .. is proving to be a daunting task.

However, thank you very much for your help, your knowledge has been very valuable to me ;)
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

Better I stay with your advice to use ref 0002, the game also works:

Code: Select all

exit77:
        mov     bp, sp
        rcr     byte ptr [bp+8], 1
        rol     byte ptr [bp+8], 1  ; insert error CF on stack        
        neg     ah
        pop     bp
        pop     ds
        retf    0002
... although the music of it and Turbo Debugger still do not work, they are other bugs, perhaps it also has something to do with interruptions ... I will review the same and I will use in all retf 0002

Edit: Wait, here they are using CF, maybe in this particular interrupt it is better to use the other solution of forcing STI in BP+9
User avatar
pgimeno
Top Contributor
Posts: 669
Joined: Thu Jun 11, 2020 9:44 am
Has thanked: 246 times
Been thanked: 208 times

Re: A Real PC XT Core Perhaps?

Unread post by pgimeno »

The question is what is clearing the bit in [BP+9]. That's what shouldn't be happening in the first place, at least if INT 13h is called with interrupts enabled. Is it? Where's the INT 13h call that is disabling the interrupts? EDIT: If it's the one at 08B7 then yes, it's called with interrupts enabled and therefore nothing should be clearing it in the stack. Whatever clears it is not working properly. That's the byte at address 03FD if I'm not mistaken. I'd first check if either of the RCR/ROL instructions I've pointed at is the culprit. EDIT2: Another hypothesis is that the INT nn instruction is saving the flags with that bit cleared, which would be obviously wrong.

Anyway, a simple BIOS-side fix is:

Code: Select all

exit77:
        pushf           ; preserve carry
        neg      ah
        popf            ; restore carry
        pop     bp
        pop     ds
        retf    0002h
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

pgimeno wrote: Mon Jan 03, 2022 8:45 pm The question is what is clearing the bit in [BP+9]. That's what shouldn't be happening in the first place, at least if INT 13h is called with interrupts enabled. Is it? Where's the INT 13h call that is disabling the interrupts? EDIT: If it's the one at 08B7 then yes, it's called with interrupts enabled and therefore nothing should be clearing it in the stack. Whatever clears it is not working properly. That's the byte at address 03FD if I'm not mistaken. I'd first check if either of the RCR/ROL instructions I've pointed at is the culprit. EDIT2: Another hypothesis is that the INT nn instruction is saving the flags with that bit cleared, which would be obviously wrong.

Anyway, a simple BIOS-side fix is:

Code: Select all

exit77:
        pushf           ; preserve carry
        neg      ah
        popf            ; restore carry
        pop     bp
        pop     ds
        retf    0002h
I checked that the ror and rcl instructions were working correctly, the bp + 9 contained 00 at the time, because interrupts are disabled at the time of IRET, I will try to find out why it is 00.

Thanks!
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

pgimeno wrote: The question is what is clearing the bit in [BP+9]. That's what shouldn't be happening in the first place, at least if INT 13h is called with interrupts enabled. Is it? Where's the INT 13h call that is disabling the interrupts? EDIT: If it's the one at 08B7 then yes, it's called with interrupts enabled and therefore nothing should be clearing it in the stack. Whatever clears it is not working properly. That's the byte at address 03FD if I'm not mistaken. I'd first check if either of the RCR/ROL instructions I've pointed at is the culprit. EDIT2: Another hypothesis is that the INT nn instruction is saving the flags with that bit cleared, which would be obviously wrong.
The answer to this question has to do with how this interruption is reached. Both in this BIOS and in the original PCXT, INT 13h is reached through intermediate calls where PUSHF has previously been executed, as this instruction comes from the call to INT 13h, it causes interruptions to have been previously disabled, this it is the only reason then, and in any case, on all intermediate calls functions are exited via RETF 0002, just as the last BIOS routine should also do.
pgimeno wrote: Anyway, a simple BIOS-side fix is:

Code: Select all

exit77:
        pushf           ; preserve carry
        neg      ah
        popf            ; restore carry
        pop     bp
        pop     ds
        retf    0002h

Therefore, and definitely, I'll stick with your solution. It is the most elegant way to preserve CF and keep interrupts enabled without resorting to the contents of the stack and IRET. Now it's time to find out why the music in the game doesn't work and why Turbo Debugger hangs:

turbo_d.jpg
turbo_d.jpg (19.96 KiB) Viewed 15362 times

Because I have reviewed the IRET and RETF 0002 used in the rest of the BIOS interrupts and in advance they seem to be used properly.
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

Turbo Debugger does not work because there comes a point where it tries to execute an unimplemented 286+ instruction:

next186.jpg
next186.jpg (56.61 KiB) Viewed 10112 times

If we change that instruction to mov byte ptr [41c68+5], FFh, it already works and is recognized as 286:

IMG_20220104_183416.jpg
IMG_20220104_183416.jpg (312.09 KiB) Viewed 10112 times

If instead we fill it with NOPs, the content of that address is 00h, and then Turbo Debugger detects it as 386.

This leads me to the conclusion that, as what I intend with this core is to be as faithful as possible to a PCXT (maximum 186), I will try to remove any reference to 286 opcodes from the Next186 module to avoid it being detected as such, and then don't crash because you try to use unimplemented instructions.


I also have to analyze all the possible ways to identify a 286, to somehow disable them from the Next186 IP core, we will start here:

https://reverseengineering.stackexchang ... -code-work
https://en.wikipedia.org/wiki/X86_instr ... with_80286
User avatar
pgimeno
Top Contributor
Posts: 669
Joined: Thu Jun 11, 2020 9:44 am
Has thanked: 246 times
Been thanked: 208 times

Re: A Real PC XT Core Perhaps?

Unread post by pgimeno »

Don't miss that PUSH SP may have changed behaviour between models. I bet it's the instruction that comes right before the POP AX that appears in the first line of the snippet you've shown.

Most likely, in 8088/8086, PUSH SP pushes the value of SP *after* decrementing, that is, except for flags, it is equivalent to:

Code: Select all

  SUB SP,2
  MOV [SP],SP
In later models, the behaviour is:

Code: Select all

  MOV [SP-2],SP
  SUB SP,2
In the former case, after PUSH SP / POP AX, you have AX != SP, but in the latter case, AX == SP.
User avatar
spark2k06
Core Developer
Posts: 865
Joined: Sat Jun 06, 2020 9:05 am
Has thanked: 409 times
Been thanked: 961 times

Re: A Real PC XT Core Perhaps?

Unread post by spark2k06 »

pgimeno wrote: In the former case, after PUSH SP / POP AX, you have AX != SP, but in the latter case, AX == SP.
Correct! It is as you comment. If we jump from that point now it is detected as 186, as it should be:

186_detect.jpg
186_detect.jpg (57.35 KiB) Viewed 10112 times

On the other hand, here we can see how EMS memory, in addition to being detected, is used by Turbo Debugger without problems :)

IMG_20220104_193756.jpg
IMG_20220104_193756.jpg (350.38 KiB) Viewed 10112 times

The next step will be to modify the IP core module of the Next186 so that the PUSH SP instruction has the behavior we want, in order to be detected as 186. I have reviewed the rest of the instructions, and it does not seem that any other of 286 is used , so the goal is the one mentioned, to delete any indication that it is a 286, when we know that it does not behave as such... so let's start with pgimeno's suggestion.

In addition, I have seen that gyurco's fork has many improvements in its VGA version compared to Nicolae's original Next186, both at the IP core level and the other modules:

https://github.com/gyurco/Next186

So I'm going to take advantage to merge the changes and thus see how compatibility improves in games CGA for this version based on the Graphics Gremlin board.
Mills
Posts: 83
Joined: Mon Jun 08, 2020 2:52 pm
Has thanked: 15 times
Been thanked: 29 times

Re: A Real PC XT Core Perhaps?

Unread post by Mills »

pgimeno wrote: Wed Jan 05, 2022 2:45 am Don't miss that PUSH SP may have changed behaviour between models. I bet it's the instruction that comes right before the POP AX that appears in the first line of the snippet you've shown.

Most likely, in 8088/8086, PUSH SP pushes the value of SP *after* decrementing, that is, except for flags, it is equivalent to:

Code: Select all

  SUB SP,2
  MOV [SP],SP
In later models, the behaviour is:

Code: Select all

  MOV [SP-2],SP
  SUB SP,2
In the former case, after PUSH SP / POP AX, you have AX != SP, but in the latter case, AX == SP.
Do you know any good source to read about how instructions work for 8088/86 (286 would also be cool). That way we could make the instructions work like on the real machine. I only found pdf's explaining how many cycles every instruction takes, we could make the cpu cycle accurate but it would still be different.
User avatar
pgimeno
Top Contributor
Posts: 669
Joined: Thu Jun 11, 2020 9:44 am
Has thanked: 246 times
Been thanked: 208 times

Re: A Real PC XT Core Perhaps?

Unread post by pgimeno »

Mills wrote: Wed Jan 05, 2022 12:09 pm Do you know any good source to read about how instructions work for 8088/86 (286 would also be cool). That way we could make the instructions work like on the real machine.
No, I know that from my own experience. I've done a lot of disassembly on x86 in my DOS times :) I've seen PUSH SP used to detect the CPU type in more cases.
Mills wrote: Wed Jan 05, 2022 12:09 pm I only found pdf's explaining how many cycles every instruction takes, we could make the cpu cycle accurate but it would still be different.
Maybe something like a list of CPU bugs could have these kinds of specifics.
Post Reply