dpvm/mzload.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
};
}