[RESOLVED] Simulating an interrupt call using CALL FAR and PUSHF
Someone suggested I should simulate an interrupt call using a vector saved in a "variable" instead of assigning the redirected interrupt another number regarding a TSR I wrote. The original program (https://github.com/PeterSwinkels/Mem...TSR-for-MS-DOS) reassigns interrupt 0x8 to 0xFF and uses the INT opcode to call interrupt 0xFF. The modified program attempts to store interrupt 0x8's vector in a "variable" and use CALL FAR [...] in combination with PUSHF to call it.
The relevant code: (the full program is attached to this thread)
Code:
; Memory Dumping TSR for MS-DOS - By: Peter Swinkels, ***2021***
ALIGN 0x01, DB 0x90 ; Defines alignment.
BITS 16 ; Defines the segment size used by this program.
ORG 0x0100 ; Indicates that all relative pointers to data are moved forward by 0x0100 bytes.
TSR_VECTOR EQU 0x08 ; Defines the interrupt to be redirected.
JMP NEAR Main ; Jumps to the main entry point.
TSR:
PUSHA ; Saves the registers.
PUSH DS ;
PUSH ES ;
PUSH CS ; Restores the data segment register.
POP DS ;
%INCLUDE "Memdump.asm" ; Includes the TSR's code file.
POP ES ; Restores the registers.
POP DS ;
POPA ;
PUSHF ; Calls the redirected interrupt.
CALL FAR [Redirected] ;
IRET ; Returns.
EndTSR:
Main:
MOV AH, 0x09 ; Displays the TSR "start" message.
MOV DX, TSR_Start_Msg ;
INT 0x21 ;
MOV AL, [IsActiveFlag] ; Checks whether this TSR is already active.
CMP AL, 0x00 ;
JNE IsActive ;
MOV BYTE [IsActiveFlag], 0x01 ; Sets this TSR as being active.
MOV AH, 0x34 ; Retrieves the address of the critical error and InDOS flags.
INT 0x21 ;
MOV [CEInDOS_Offset], BX ;
MOV [CEInDOS_Segment], ES ;
MOV AH, 0x35 ; Retrieves vector the vector for the interrupt to be redirected.
MOV AL, TSR_VECTOR ;
INT 0x21 ;
MOV [Redirected_Segment], ES ;
MOV [Redirected_Offset], BX ;
PUSH CS ; Sets this TSR's interrupt vector.
POP DS ;
MOV DX, TSR ;
MOV AH, 0x25 ;
MOV AL, TSR_VECTOR ;
INT 0x21 ;
MOV AH, 0x09 ; Displays the TSR "activated" message.
MOV DX, TSR_Activated_Msg ;
INT 0x21 ;
MOV AX, 0x3100 ; Terminates and stays resident.
MOV DX, EndTSR ;
ADD DX, 0x0F ;
SHR DX, 0x04 ;
INT 0x21 ;
IsActive: ;
MOV AH, 0x09 ; Displays the TSR "already active" message.
MOV DX, TSR_Activate_Msg ;
INT 0x21 ;
MOV AH, 0x4C ; Quits if the TSR is already active.
INT 0x21 ;
IsActiveFlag DB 0x00
Redirected:
Redirected_Offset DW 0x0000
Redirected_Segment DW 0x0000
TSR_Activate_Msg DB "Already active!", 0x0D, 0x0A, "$"
TSR_Activated_Msg DB "Activated.", 0x0D, 0x0A, "$"
TSR_Start_Msg DB "Memory Dumping TSR for MS-DOS v1.08 - by: Peter Swinkels, ***2021***"
DB 0x0D, 0x0A
DB "F12 = Dump conventional memory."
DB 0x0D, 0x0A
DB "$"
The program appears to load and return to the DOS prompt correct but immediately freezes the system. I suspect there is a bug in the code that should call int 0x8 but can't find any mistakes. Does anyone else see any obvious mistakes?
Re: Simulating an interrupt call using CALL FAR and PUSHF
Thank you, that partially solved the problem. I modified the code as follows:
Code:
TSR:
PUSHA ; Saves the registers.
PUSH DS ;
PUSH ES ;
PUSH CS ; Restores the data segment register.
POP DS ;
%INCLUDE "Memdump.asm" ; Includes the TSR's code file.
PUSHF ; Calls the redirected interrupt.
CALL FAR [Redirected] ;
POP ES ; Restores the registers.
POP DS ;
POPA ;
I had to move the POPA instruction as well. (because of the order in which things get pushed onto the stack). The program now doesn't freeze after starting, however after instructing it to perform a memory dump it does so and then freezes! What gives?
EDIT:
Never mind, adding a CS segment override before the far call appears to have fixed the issue.
Re: [RESOLVED] Simulating an interrupt call using CALL FAR and PUSHF
Okay, it looks I was too quick to assume the problem was solved. The modified TSR seemingly works but I have noticed two major bugs:
1. The program doesn't detect that it has already been activated despite the fact I can't find any obvious flaw in the code that handles the detection. And freezes the system when you start it a second time.
2. It appears to interfere with other programs now. I have no idea why.
Re: [RESOLVED] Simulating an interrupt call using CALL FAR and PUSHF
1. This must have been an issue with the original impl too. You’ll need second “communications channel” i.e. interrupt handler to negotiate between two instances of the TSR. For instance hook INT 60 and impl function AH=7F with lower AL accepting 1, 2, 3, etc. for subfunctions like “are you installed already?”, “print state”, “dump debug output” and so on but this will complicate the program a bit.
2. Try the CS:[Redirected] addressing and keep push/pop as in the original.
Re: [RESOLVED] Simulating an interrupt call using CALL FAR and PUSHF
1. No I checked, the original program works exactly as expected. It uses another method of detecting. Download it and see for yourself.
2. Okay! EDIT: Moving the POP/POPA instructions helps but it still messes up other programs.