VOGONS

Common searches


First post, by Peter Swinkels

User metadata
Rank Oldbie
Rank
Oldbie

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.
Show last 32 lines
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 ;
Show last 25 lines
   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

Attachments

  • Filename
    PlDmpTSR.zip
    File size
    1.97 KiB
    Downloads
    51 downloads
    File license
    Public domain

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

Reply 2 of 7, by BloodyCactus

User metadata
Rank Oldbie
Rank
Oldbie

line 27, your not closing the file you think your closing!

moving stuff into DI, you need ES, you only setup DS. DI uses ES by default.

also you could just

mov cx,0x300
l1:
insb
stosb
loop .l1

also dont call the redirected interrupt via an INT call, just jump to its address.

--/\-[ Stu : Bloody Cactus :: [ https://bloodycactus.com :: http://kråketær.com ]-/\--

Reply 3 of 7, by Peter Swinkels

User metadata
Rank Oldbie
Rank
Oldbie

@vstrakh: I would have to check to be sure. If I remember correctly the file already has to exist for INT 0x21, 0x3D to work.

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

Reply 4 of 7, by Peter Swinkels

User metadata
Rank Oldbie
Rank
Oldbie

@BloodyCactus:
It seems the only mistake I made was messing up the code to close the file handle. I fixed it and the program works as expected now. Thank you!

Also, I looked it up and I believe you're confusing the behavior for DI with how it is used by byte string based instructions. (movs, insb, outs, stosb, etc.) Why don't I use insb and stosb? Don't I need to specify the color index at 0x3c8 for each palette entry?

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

Reply 5 of 7, by BloodyCactus

User metadata
Rank Oldbie
Rank
Oldbie
Peter Swinkels wrote on 2022-05-28, 13:54:

Also, I looked it up and I believe you're confusing the behavior for DI with how it is used by byte string based instructions. (movs, insb, outs, stosb, etc.) Why don't I use insb and stosb? Don't I need to specify the color index at 0x3c8 for each palette entry?

its been a while. maybe I was getting cnofused winth BP, which always uses SS unless overriden.

--/\-[ Stu : Bloody Cactus :: [ https://bloodycactus.com :: http://kråketær.com ]-/\--

Reply 7 of 7, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author
Peter Swinkels wrote on 2022-05-28, 13:54:

Don't I need to specify the color index at 0x3c8 for each palette entry?

1) The index auto-increments after three data bytes are read or written. (So, yes, you can REP INSB to read a block of palette data to memory at ES:DI)
2) There are separate read and write indexes. Since you're reading the DAC, you should be setting the read index with port 0x3c7. You will not read the DAC values in the expected order by setting the write index with port 0x3c8.
https://wiki.osdev.org/VGA_Hardware#Port_0x3C8