First post, by Peter Swinkels
Okay,
Wanting to know the color palette used by a game I modified a TSR I wrote earlier so that it can extract the VGA palette and save it to a file. It works as expected except for the fact that DOSBox freezes after calling (by pressing F12) the TSR while at the prompt. Strangely enough calling the TSR causes no issues when calling it from inside another program. Could someone have a look at the code (I use NASM to assemble it) below and see if I made any mistakes?
Main.asm
; VGA Palette Dumping TSR for MS-DOS - By: Peter Swinkels, ***2022***
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.
REDIRECTED_FROM EQU 0x08 ; Defines the interrupt to be redirected.
REDIRECTED_TO EQU 0xFF ; Defines the redirected interrupt's new vector.
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 "PalDump.asm" ; Includes the TSR module.
POP ES ; Restores the registers.
POP DS ;
POPA ;
INT REDIRECTED_TO ; Calls the redirected interrupt.
IRET ; Returns.
EndTSR:
Main:
MOV AH, 0x09 ; Displays the TSR "start" message.
MOV DX, TSR_Start_Msg ;
INT 0x21 ;
MOV AH, 0x35 ; Checks whether this TSR is already active by checking for a redirected interrupt.
MOV AL, REDIRECTED_TO ;
INT 0x21 ;
MOV AX, ES ;
CMP AX, 0x0000 ;
JNE IsActive ;
CMP BX, 0x0000 ;
JNE IsActive ;
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, REDIRECTED_FROM ;
INT 0x21 ;
MOV DX, BX ; Places the retrieved vector at another interrupt.
PUSH ES ;
POP DS ;
MOV AH, 0x25 ;
MOV AL, REDIRECTED_TO ;
INT 0x21 ;
PUSH CS ; Sets this TSR's interrupt vector.
POP DS ;
MOV DX, TSR ;
MOV AH, 0x25 ;
MOV AL, REDIRECTED_FROM ;
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 ;
TSR_Activate_Msg DB "Already active!", 0x0D, 0x0A, "$"
TSR_Activated_Msg DB "Activated.", 0x0D, 0x0A, "$"
TSR_Start_Msg DB "VGA Palette Dumping TSR for MS-DOS v1.00 - by: Peter Swinkels, ***2022***"
DB 0x0D, 0x0A
DB "F12 = Dump the VGA palette."
DB 0x0D, 0x0A
DB "$"
PalDump.asm
; VGA Palette Dumping module for TSR.
MOV WORD BX, [CEInDOS_Offset] ; Skips palette dumping if either the critical error or InDOS flag are set.
MOV WORD ES, [CEInDOS_Segment] ;
ES ;
CMP BYTE [BX - 0x01], 0x00 ;
JNE Done ;
ES ;
CMP BYTE [BX], 0x00 ;
JNE Done ;
IN AL, 0x60 ; Skips palette dumping unless the F12 key is being pressed.
CMP AL, 0x58 ;
JNE Done ;
CMP BYTE [Busy], 0x00 ; Checks whether a dump is already in progress.
JNE Done ;
MOV BYTE [Busy], 0x01 ; Sets the flag indicating a dump is in progress.
MOV AH, 0x3C ; Creates the output file.
MOV CX, 0x00 ;
LEA DX, OutputFile ;
INT 0x21 ;
JC Done ;
MOV AX, BX ; Closes the newly created output file.
MOV AH, 0x3E ;
INT 21h ;
JC Done ;
MOV AH, 0x3D ; Opens the output file for writing.
MOV AL, 0x01 ;
LEA DX, OutputFile ;
INT 0x21 ;
JC Done ;
MOV BX, AX ; Retrieves the filehandle.
XOR AL, AL ; Resets the color index.
MOV [Color], AL ;
MOV DI, Palette ; Sets the target to the palette buffer.
Dump:
MOV AL, [Color] ; Sets the color's index.
MOV DX, 0x3C8 ;
OUT DX, AL ;
MOV CX, 0x03 ; Retrieves the RGB values.
GetRGB: ;
MOV DX, 0x3C9 ;
IN AL, DX ;
MOV [DI], AL ;
INC DI ;
LOOP GetRGB ;
MOV AL, [Color] ; Moves to the next color index or stops dumping when the last one has been reached.
CMP AL, 0xFF ;
JE DumpFinished ;
INC AL ;
MOV [Color], AL ;
JMP Dump ;
DumpFinished:
MOV AH, 0x40 ; Saves the retrieved palette.
MOV CX, 0x300 ;
MOV DX, Palette ;
INT 0x21 ;
JC Done ;
MOV AH, 0x3E ; Closes the output file.
INT 21h ;
JMP NEAR Done ;
Busy DB 0x00
CEInDOS_Offset DW 0x0000
CEInDOS_Segment DW 0x0000
Color DB 0x00
MemorySegment DW 0x0000
OutputFile DB "PalDump.dat", 0x00
Palette Times 0x300 DB 0x00
Done:
MOV BYTE [Busy], 0x00 ; Clears the flag indicating a dump is progress.
Here is an earlier TSR this one is based off:
https://github.com/PeterSwinkels/Memory-Dumpi … -TSR-for-MS-DOS
Do not read if you don't like attention seeking self-advertisements!
Did you read it anyway? Well, you can find all sorts of stuff I made using various programming languages over here:
https://github.com/peterswinkels