On at 2023-04-30 17:19 -0500, rehsd.i...@gmail.com wrote:
Not sure if it’s bad etiquette to reply to your own post, but… I may
just need to change out my “iret” with “ret 2”. I’m doing some testing…
Rich
In NASM you can indeed use this as an alternative, but you need *far*
return, that is "retf 2". However, I do not recommend this choice.
Instead, you can use a lahf or rcr \ rol trick to pass back either all
arithmetic status flags (excepting the Overflow Flag) or only the Carry
Flag. The core of your problem is that you were trying to set the
current flags *in the interrupt handler*. But once you run an iret
instruction, it pops the flags off the interrupt return stack frame. So
to return flags to your caller, you either have to go with retf 2 (with
all its problems) or modify the flags image in the stack frame before
you run iret.
I recently commented on similar problems in [1] and [2]. I also gave an
example from my SEEKEXT tool [3]:
.iret_CF:
push bp
mov bp, sp
rcr byte [bp + 6], 1 ; flip
rol byte [bp + 6], 1 ; flop
pop bp
iret
One of the reports [2] also contains an lahf example:
push bp
mov bp, sp
push ax
lahf
; bp + 0 = saved bp
; bp + 2 = ip
; bp + 4 = cs
; bp + 6 = fl
mov byte [bp + 6], ah
pop ax
pop bp
iret
[1]: https://github.com/640-KB/GLaBIOS/issues/20
[2]: https://github.com/MobyGamer/softhddi/issues/1
[3]: https://hg.pushbx.org/ecm/seekext/file/bbfcfa0d1c0b/resident.asm#l254
Regards,
ecm
*From:* rehsd.i...@gmail.com <rehsd.i...@gmail.com>
*Sent:* Sunday, April 30, 2023 4:53 PM
*To:* freedos-devel@lists.sourceforge.net
*Subject:* CPU flags register not updating on interrupt calls
Hi, everyone. I’m new here. This is my first post. 😊
I am currently working on getting FreeDOS running on my homebrew 286
system. I am running into an issue where interrupt calls from FreeDOS to
my BIOS are not showing updated values for the CPU flags register after
the call. This happens with built-in interrupt calls in FreeDOS or
custom calls I am making. Here’s a simple test function that I added to
FreeDOS’s main.c (I call it just before signon()):
*void test_interrupt()*
*{*
* iregs regs;*
* regs.a.x = 0x1122;*
* regs.b.x = 0x0033;*
**
* regs.c.x = 0x4455;*
* regs.d.x = 0x6677;*
* regs.di = 0x8899;*
* regs.si = 0xaabb;*
**
*init_call_intr(0x15, ®s);*
**
* printf("\nInt test: ");*
* printf("ax=%04X bx=%04X cx=%04X dx=%04X di=%04X si=%04X
flags=%04X\n",regs.a.x,regs.b.x,regs.c.x,regs.d.x,regs.di,regs.si,regs.flags);*
*}*
In the assembly code for the BIOS interrupt service routine (I’m just
using interrupt 0x15 for testing), I update the flags register. When I
try to read the updated flags register back in FreeDOS, I am not getting
the values that I expect. For example, if I use something like the
following in my interrupt service routine, when I read regs.flags in
test_interupt() above, the carry flag may or may not be set properly
(same with the zero flag).
* mov ah, 0b01000001 ;SF, ZF, AF, PF, and
CF flags (bits 7, 6, 4, 2, haveand 0, respectively) – other flags are left
unchanged by CPU*
* sahf*
*iret*
In, kernel/pcb.h <https://github.com/FDOS/kernel/blob/master/hdr/pcb.h>,
I see some notes about “offsets must match the assembly process” and a
couple of different layouts for the offsets. Could this be related to
the issue I am having? I am using NASM 2.16.01 and Watcom 1.9.
Suggestions or things I could look into?
I have posted additional details here
<https://www.rehsdonline.com/post/troubleshooting-cpu-flags-register-between-bios-and-freedos>,
including a video walk-through of what I am seeing.
Thank you!
Rich
_______________________________________________
Freedos-devel mailing list
Freedos-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freedos-devel
_______________________________________________
Freedos-devel mailing list
Freedos-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freedos-devel