I wonder which assembler you're using, because many DOS-era assemblers recognize the NNh form of hexadecimal, but not the 0xNN form.
Some general points: your use of CLI/STI in the interrupt handler is unnecessary because interrupts are always disabled when the handler is entered and IRET will restore the interrupt flag to its former state along with the other CPU flags. PUSHA/POPA are excessive, you only need push/pop AX and BX in addition to DS because they are the only registers your handler modifies. For your apparent intention to disable numlock, you need to mask off bit 5 of 40h:17h, but you're also masking 40h:18h entirely (which may indeed cause the keyboard to not work properly) by using a word pointer instead of a byte pointer, so I guess you want:
AND AL,0DFh ; mask off bit 5 (numlock mode)
Lastly, there are debugger builds of DOSBox you can use to analyze what your assembled program is actually doing: DOSBox debugger
The cli at handler entry and the sti at exit don’t do anything useful, and I don’t get the cli at the very beginning. At least do an sti before exiting. Maybe one of the invoked int functions does this implicitly. I don’t remember and did not bother looking it up, but at least it looks strange.
You should pay attention to which type of program binary your assembler of choice is producing (COM or EXE), and if additional things (e.g. ORG 0x100 for COM, stack location for EXE, etc.) are needed for the type produced.
Okay, I made a few changes and decided to try to have my TSR display a character instead of modifying the Num Lock status. Code:
1; A TSR for MS-DOS - By: Peter Swinkels, ***2021*** 2ORG 0x0100 3 4; Retrieves interrupt 0x08's vector. 5CLI 6MOV AH, 0x35 7MOV AL, 0x08 8INT 0x21 9 10; Places the retrieved vector at another interrupt. 11MOV DX, BX 12PUSH ES 13POP DS 14MOV AH, 0x25 15MOV AL, 0xC8 16INT 0x21 17 18; Places this TSR at interrupt 0x08. 19PUSH CS 20POP DS 21MOV DX, TSR 22MOV AH, 0x25 23MOV AL, 0x08 24INT 0x21 25 26; Terminates and stays resident. 27MOV AH, 0x31 28MOV AL, 0x00 29MOV DX, 0x00FF 30INT 0x21 31 32TSR: 33; Disables hardware interrupts. 34CLI 35 36; Saves the registers. 37PUSHA 38PUSH DS 39 40; Displays a character. 41MOV DL, 0x21 42MOV AH, 0x02 43INT 0x21 44 45; Restores the registers. 46POP DS 47POPA 48 49; Calls the redirected interrupt. 50INT 0xC8 51 52; Sends an End-Of Interrupt signal to the 8259 interrupt controller. 53PUSH AX 54MOV AL, 0x20 55OUT 0x20, AL 56POP AX 57 58; Returns. 59STI 60IRET
It appears to work now. When I get around to it I am going to see if I can integrate some code I wrote that dumps all conventional memory to a file. That's why I wanted to create a TSR to begin with. Thank you all for your input!
Last edited by Peter Swinkels on 2021-06-19, 21:21. Edited 1 time in total.
IMO, TSRs that react to a key press should hook the keyboard IRQ 1 handler (INT 9) because the interrupt only occurs when there is a key press or release. Using the timer IRQ 0 (INT 8) as you have is inefficient and adds unnecessary processing to the system.
Since you're posting in the DOSBox section of the forum, why not just use the DOSBox debugger to dump memory?
I don't like the DOSBox debugger, a lot of steps. Writing my own software may be more work at first, but being able to press a single key to dump all conventional memory is worth it. Yeah, there is room for improvement in what I wrote. When I get around to it I will investigate using other methods.
OTOH using the timer interrupt may be more reliable because most games intercept the keyboard interrupt and never call the original handler, whereas I assume they continue calling the timer interrupt, even if they install their own handler.
Nevermind my earlier question. I figured it out and made the appropriate changes. Thank you for pointing that flaw out. Your earlier comment implied there were several things wrong, which other things need to be fixed as well according to you?