I'm trying to set the handler of Interrupt 28h to my own routine, restore all the registers and flags involved, and restore the original Interrupt handler. I'm using NASM Assembler, under DOSBox and MS-DOS 6.22 in VirtualBox.
I've thought about debugging, but doing so on a TSR program sounds impossible. I've tried pushing the Data Segment onto the Code Segment, and saving the original Data Segment for restoring later, but it seems to hang the machine even after restoring the Data Segment.
section .text ;Code Section
org 100h ;DOS Executable Start
mov ah,35h ;Get Interrupt Vector
mov al,28h ;Of Interrupt 28h
int 21h ;Call DOS Kernel
push cs ;Push Code Segment
pop ds ;Onto Data Segment
mov [oldseg],es ;Save Old Interrupt Vector Segment
mov [oldoff],bx ;Save Old Interrupt Vector Offset
mov ah,25h ;Set Interrupt Vector
mov dx,resstart ;To Resstart
int 21h ;Call DOS Kernel
mov dx,resend ;Set Data Offset to Resend
sub dx,resstart ;Subtract Resstart
shr dx,4h ;Shift Right 4 Bits for Paragraph
inc dx ;One Extra Paragraph for PSP
mov ah,31h ;Terminate and Stay Resident
xor al,al ;Return Code
int 21h ;Call DOS Kernel
resstart: ;Resident Code Start
push ax ;Save AX
push es ;Save ES
push di ;Save DI
push cx ;Save CX
push ds ;Save DS
push dx ;Save DX
mov ah,00h ;Set Video Mode
mov al,13h ;To Mode 13h
int 10h ;Call BIOS Video
mov ax,0A000h ;VGA Segment
mov es,ax ;Stored in ES
xor di,di ;VGA Offset in DI
mov cx,0FA00h ;Fill Entire Screen
mov al,09h ;With Light Blue Color
rep stosb ;Repeat Store AL at ES:DI
mov ah,25h ;Set Interrupt Vector
mov al,28h ;Of Interrupt 28h
mov ds,[oldseg] ;Restore Old Interrupt Vector Segment
mov dx,[oldoff] ;Restore Old Interrupt Vector Offset
int 21h ;Call DOS Kernel
pop dx ;Restore DX
pop ds ;Restore DS
pop cx ;Restore CX
pop di ;Restore DI
pop es ;Restore ES
pop ax ;Restore AX
iret ;Return and Restore Flags
resend: ;Resident Code End
section .data
oldseg dw 0 ;Old Interrupt Vector Segment
oldoff dw 0 ;Old Interrupt Vector Offset
After returning the original interrupt vector address, and setting the new interrupt vector address to "resstart", the program should terminate and stay resident. After this, Interrupt 28h would be triggered automatically since DOS has nothing else to do, which would in turn run my Interrupt handler.
The Interrupt handler sets the video mode to 13h, tries to fill the entire screen with a light blue color, restores the original Interrupt 28h handler, restores all registers and flags involved, and returns to DOS. Executing this program yields no results, the system doesn't even hang. While running the part of setting video mode 13h and filling the entire screen with blue on its own separately, it works perfectly fine.
org 100h
that you are iun fact creating a program with a.COM
extension? – Alsworth