214 lines
9.5 KiB
C
214 lines
9.5 KiB
C
#ifndef NEFORMAT_H
|
|
#define NEFORMAT_H
|
|
|
|
#include <stdint.h>
|
|
|
|
// ============================================================================
|
|
// MZ (DOS) executable header - precedes the NE header
|
|
// ============================================================================
|
|
|
|
#define MZ_SIGNATURE 0x5A4D // 'MZ'
|
|
|
|
typedef struct __attribute__((packed)) {
|
|
uint16_t signature; // 0x00: 'MZ'
|
|
uint16_t lastPageBytes; // 0x02: bytes on last page
|
|
uint16_t pageCount; // 0x04: pages in file (512 bytes each)
|
|
uint16_t relocationCount; // 0x06: relocation entries
|
|
uint16_t headerParagraphs;// 0x08: header size in paragraphs
|
|
uint16_t minAlloc; // 0x0A: minimum extra paragraphs
|
|
uint16_t maxAlloc; // 0x0C: maximum extra paragraphs
|
|
uint16_t initSS; // 0x0E: initial SS
|
|
uint16_t initSP; // 0x10: initial SP
|
|
uint16_t checksum; // 0x12: checksum
|
|
uint16_t initIP; // 0x14: initial IP
|
|
uint16_t initCS; // 0x16: initial CS
|
|
uint16_t relocationOff; // 0x18: relocation table offset
|
|
uint16_t overlayNum; // 0x1A: overlay number
|
|
uint16_t reserved1[4]; // 0x1C: reserved
|
|
uint16_t oemId; // 0x24: OEM identifier
|
|
uint16_t oemInfo; // 0x26: OEM information
|
|
uint16_t reserved2[10]; // 0x28: reserved
|
|
uint32_t neHeaderOffset; // 0x3C: offset to NE header
|
|
} MzHeaderT;
|
|
|
|
// ============================================================================
|
|
// NE (New Executable) header
|
|
// ============================================================================
|
|
|
|
#define NE_SIGNATURE 0x454E // 'NE'
|
|
|
|
typedef struct __attribute__((packed)) {
|
|
uint16_t signature; // 0x00: 'NE'
|
|
uint8_t linkerMajor; // 0x02: linker version
|
|
uint8_t linkerMinor; // 0x03: linker revision
|
|
uint16_t entryTableOffset; // 0x04: offset to entry table (from NE header)
|
|
uint16_t entryTableSize; // 0x06: size of entry table
|
|
uint32_t fileCrc; // 0x08: file CRC
|
|
uint16_t moduleFlags; // 0x0C: module flags
|
|
uint16_t autoDataSegIndex; // 0x0E: auto data segment index (1-based)
|
|
uint16_t initialHeapSize; // 0x10: initial heap size
|
|
uint16_t initialStackSize; // 0x12: initial stack size
|
|
uint16_t entryPointIP; // 0x14: CS:IP entry point (IP)
|
|
uint16_t entryPointCS; // 0x16: CS:IP entry point (CS segment index)
|
|
uint16_t initialSP; // 0x18: SS:SP initial stack (SP)
|
|
uint16_t initialSS; // 0x1A: SS:SP initial stack (SS segment index)
|
|
uint16_t segmentCount; // 0x1C: number of segment table entries
|
|
uint16_t moduleRefCount; // 0x1E: number of module reference table entries
|
|
uint16_t nonResNameSize; // 0x20: size of non-resident name table
|
|
uint16_t segmentTableOffset; // 0x22: offset to segment table (from NE header)
|
|
uint16_t resourceTableOffset; // 0x24: offset to resource table (from NE header)
|
|
uint16_t resNameTableOffset; // 0x26: offset to resident name table (from NE)
|
|
uint16_t modRefTableOffset; // 0x28: offset to module reference table (from NE)
|
|
uint16_t importNameTableOffset; // 0x2A: offset to imported names table (from NE)
|
|
uint32_t nonResNameTableFileOffset; // 0x2C: file offset of non-resident name table
|
|
uint16_t movableEntryCount; // 0x30: number of movable entry points
|
|
uint16_t sectorAlignShift; // 0x32: sector alignment shift count
|
|
uint16_t resourceSegCount; // 0x34: number of resource segments
|
|
uint8_t targetOS; // 0x36: target operating system
|
|
uint8_t otherFlags; // 0x37: additional flags
|
|
uint16_t gangLoadAreaOffset; // 0x38: offset to gang-load area
|
|
uint16_t gangLoadAreaSize; // 0x3A: size of gang-load area
|
|
uint16_t swapAreaSize; // 0x3C: minimum code swap area size
|
|
uint16_t expectedWinVer; // 0x3E: expected Windows version
|
|
} NeHeaderT;
|
|
|
|
// NE module flags (moduleFlags field)
|
|
#define NE_FFLAGS_SINGLEDATA 0x0001 // Single shared DGROUP
|
|
#define NE_FFLAGS_MULTIPLEDATA 0x0002 // Multiple DGROUP (DLL with per-instance data)
|
|
#define NE_FFLAGS_GLOBALINIT 0x0004 // Global initialization
|
|
#define NE_FFLAGS_PROTMODE 0x0008 // Protected mode only
|
|
#define NE_FFLAGS_8086 0x0010 // 8086 instructions
|
|
#define NE_FFLAGS_80286 0x0020 // 80286 instructions
|
|
#define NE_FFLAGS_80386 0x0040 // 80386 instructions
|
|
#define NE_FFLAGS_80x87 0x0080 // uses 80x87
|
|
#define NE_FFLAGS_FULLSCREEN 0x0100 // full-screen application (not a DLL)
|
|
#define NE_FFLAGS_DLL 0x8000 // DLL or driver (not a task)
|
|
|
|
// NE target OS values
|
|
#define NE_OS_UNKNOWN 0x00
|
|
#define NE_OS_OS2 0x01
|
|
#define NE_OS_WINDOWS 0x02
|
|
#define NE_OS_DOS4 0x03
|
|
#define NE_OS_WIN386 0x04
|
|
|
|
// ============================================================================
|
|
// NE segment table entry
|
|
// ============================================================================
|
|
|
|
typedef struct __attribute__((packed)) {
|
|
uint16_t fileSectorOffset; // Logical sector offset in file (0 = no data)
|
|
uint16_t fileLength; // Length of segment in file (0 = 64K)
|
|
uint16_t flags; // Segment flags
|
|
uint16_t minAllocSize; // Minimum allocation size (0 = 64K)
|
|
} NeSegEntryT;
|
|
|
|
// Segment flags
|
|
#define NE_SEGF_DATA 0x0001 // Data segment (0 = code)
|
|
#define NE_SEGF_ALLOCATED 0x0002 // Loader has allocated memory
|
|
#define NE_SEGF_LOADED 0x0004 // Segment is loaded
|
|
#define NE_SEGF_MOVEABLE 0x0010 // Moveable segment
|
|
#define NE_SEGF_SHAREABLE 0x0020 // Shareable segment
|
|
#define NE_SEGF_PRELOAD 0x0040 // Preload segment
|
|
#define NE_SEGF_READONLY 0x0080 // Read-only (code) or execute-only (data)
|
|
#define NE_SEGF_HASRELOC 0x0100 // Has relocation data
|
|
#define NE_SEGF_DISCARD 0x1000 // Discardable
|
|
|
|
// ============================================================================
|
|
// NE relocation record
|
|
// ============================================================================
|
|
|
|
typedef struct __attribute__((packed)) {
|
|
uint8_t srcType; // Source (fixup) type
|
|
uint8_t flags; // Relocation flags
|
|
uint16_t srcOffset; // Offset within segment of the fixup location
|
|
uint16_t target1; // Module index (1-based) or segment number
|
|
uint16_t target2; // Ordinal/offset or offset within segment
|
|
} NeRelocT;
|
|
|
|
// Relocation source types (srcType field)
|
|
#define NE_RELOC_LOBYTE 0x00 // Low byte fixup
|
|
#define NE_RELOC_SEGMENT 0x02 // 16-bit segment fixup
|
|
#define NE_RELOC_FAR_ADDR 0x03 // 32-bit far pointer (seg:off) fixup
|
|
#define NE_RELOC_OFFSET 0x05 // 16-bit offset fixup
|
|
#define NE_RELOC_FAR48_ADDR 0x0B // 48-bit far pointer fixup
|
|
#define NE_RELOC_OFFSET32 0x0D // 32-bit offset fixup
|
|
|
|
// Relocation target flags (flags field)
|
|
#define NE_RELF_INTERNALREF 0x00 // Internal reference
|
|
#define NE_RELF_IMPORTORD 0x01 // Import by ordinal
|
|
#define NE_RELF_IMPORTNAME 0x02 // Import by name
|
|
#define NE_RELF_OSFIXUP 0x03 // OS fixup
|
|
#define NE_RELF_TARGET_MASK 0x03 // Mask for target type
|
|
#define NE_RELF_ADDITIVE 0x04 // Additive fixup (don't zero target first)
|
|
|
|
// ============================================================================
|
|
// NE entry table structures
|
|
// ============================================================================
|
|
|
|
// Entry table is a series of bundles. Each bundle starts with:
|
|
// BYTE count - number of entries in this bundle (0 = end of table)
|
|
// BYTE indicator - 0x00 = empty, 0xFF = moveable, else fixed segment number
|
|
|
|
// Fixed entry (indicator = segment number 1-254)
|
|
typedef struct __attribute__((packed)) {
|
|
uint8_t flags; // Entry flags
|
|
uint16_t offset; // Offset within segment
|
|
} NeFixedEntryT;
|
|
|
|
// Moveable entry (indicator = 0xFF)
|
|
typedef struct __attribute__((packed)) {
|
|
uint8_t flags; // Entry flags
|
|
uint16_t int3fh; // INT 3Fh instruction (0xCD3F)
|
|
uint8_t segIndex; // Segment number (1-based)
|
|
uint16_t offset; // Offset within segment
|
|
} NeMoveableEntryT;
|
|
|
|
// Entry flags
|
|
#define NE_ENTRY_EXPORTED 0x01 // Entry is exported
|
|
#define NE_ENTRY_SHDATA 0x02 // Entry uses shared data segment
|
|
|
|
// ============================================================================
|
|
// Display driver ordinal numbers (standard DDI exports)
|
|
// ============================================================================
|
|
|
|
#define DDI_ORD_BITBLT 1
|
|
#define DDI_ORD_COLORINFO 2
|
|
#define DDI_ORD_CONTROL 3
|
|
#define DDI_ORD_DISABLE 4
|
|
#define DDI_ORD_ENABLE 5
|
|
#define DDI_ORD_ENUMDFFONTS 6
|
|
#define DDI_ORD_ENUMOBJ 7
|
|
#define DDI_ORD_OUTPUT 8
|
|
#define DDI_ORD_PIXEL 9
|
|
#define DDI_ORD_REALIZEOBJECT 10
|
|
#define DDI_ORD_STRBLT 11
|
|
#define DDI_ORD_SCANLR 12
|
|
#define DDI_ORD_DEVICEMODE 13
|
|
#define DDI_ORD_EXTTEXTOUT 14
|
|
#define DDI_ORD_GETCHARWIDTH 15
|
|
#define DDI_ORD_DEVICEBITMAP 16
|
|
#define DDI_ORD_FASTBORDER 17
|
|
#define DDI_ORD_SETATTRIBUTE 18
|
|
#define DDI_ORD_DIBTODEVICE 19
|
|
#define DDI_ORD_CREATEBITMAP 20
|
|
#define DDI_ORD_DELETEBITMAP 21
|
|
#define DDI_ORD_SELECTBITMAP 22
|
|
#define DDI_ORD_BITMAPBITS 23
|
|
#define DDI_ORD_RECLIP 24
|
|
#define DDI_ORD_GETPALETTE 25
|
|
#define DDI_ORD_SETPALETTE 26
|
|
#define DDI_ORD_SETPALETTETRANS 27
|
|
#define DDI_ORD_UPDATECOLORS 28
|
|
#define DDI_ORD_STRETCHBLT 29
|
|
#define DDI_ORD_STRETCHDIBITS 30
|
|
#define DDI_ORD_SELECTPALETTE 31
|
|
#define DDI_ORD_INQUIRE 101
|
|
#define DDI_ORD_SETCURSOR 102
|
|
#define DDI_ORD_MOVECURSOR 103
|
|
#define DDI_ORD_CHECKCRSR 104
|
|
#define DDI_ORD_GETDRIVERRESID 450
|
|
|
|
// Maximum DDI ordinal we track
|
|
#define DDI_MAX_ORDINAL 500
|
|
|
|
#endif // NEFORMAT_H
|