64 lines
1.2 KiB
C
64 lines
1.2 KiB
C
|
#include <stdint.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
/* x86 memory map
|
||
|
0x00000 - 0x003FF IVT 0x400
|
||
|
0x00400 - 0x9FFFF FREE 0x9FC00
|
||
|
0xA0000 - 0xBFFFF VGA 0x20000
|
||
|
0xC0000 - 0xFFFFF FREE 0x40000
|
||
|
|
||
|
total freemem - 0xDFC00 - 916480 bytes/895.0K
|
||
|
*/
|
||
|
|
||
|
typedef struct { // pointer into program data into which load segment is added
|
||
|
uint16_t offset,
|
||
|
segment;
|
||
|
} __attribute__((packed)) reloc;
|
||
|
|
||
|
typedef struct { // no endian checks - this will only work on x86+vm anyway
|
||
|
uint16_t mz,
|
||
|
bytes,
|
||
|
pages,
|
||
|
relsz,
|
||
|
len,
|
||
|
minalloc, // can easily ignore - we have 895k free
|
||
|
maxalloc,
|
||
|
ss,
|
||
|
sp,
|
||
|
sum,
|
||
|
ip,
|
||
|
cs,
|
||
|
rel, // pointer to
|
||
|
overlay; // zero if main binary
|
||
|
reloc r[];
|
||
|
} __attribute__((packed)) mz;
|
||
|
|
||
|
typedef struct {
|
||
|
uint16_t ss, sp, ip, cs;
|
||
|
} mz_start;
|
||
|
|
||
|
#define m8 ((uint8_t*)m) // access mz by byte
|
||
|
uint32_t loadmz(mz* m, uint8_t* mem, uint32_t seg, mz_start* m) {
|
||
|
|
||
|
uint32_t sz = (((uint32_t)m->pages) << 9) + m->bytes;
|
||
|
memcpy( // copy mz to memory
|
||
|
mem + (seg << 4),
|
||
|
m8 + (m->len << 4),
|
||
|
sz
|
||
|
);
|
||
|
|
||
|
for(int i = 0; i < m->relsz; i++) *(uint16_t*)(
|
||
|
m8 +
|
||
|
(seg << 4) +
|
||
|
((uint32_t)m->r[i].segment << 4) +
|
||
|
(uint32_t)m->r[i].offset
|
||
|
) += seg;
|
||
|
|
||
|
*m = (mz_start) {
|
||
|
m->ss+seg,
|
||
|
m->sp,
|
||
|
m->ip,
|
||
|
m->cs+seg
|
||
|
};
|
||
|
}
|