rev |
line source |
pascal@19515
|
1 // This file is distributed under GPL
|
pascal@19515
|
2 //
|
pascal@19515
|
3 // High mem handling routines
|
pascal@19515
|
4 // C++ part of VCPI madness is here
|
pascal@19515
|
5
|
pascal@19515
|
6 #include "crtl.h"
|
pascal@19515
|
7 #include "common.h"
|
pascal@19515
|
8
|
pascal@19515
|
9 // Returns physical addr of allocated himem chunk
|
pascal@19515
|
10 // Never fails (will use fallback if not enough mem/no xmm)
|
pascal@19515
|
11 // TODO: with proper cleanup it is possible to exit to DOS
|
pascal@19515
|
12 // even after XMM alloc - do dealloc, then exit...
|
pascal@19515
|
13 // don't forget to clean up the mess then, especially
|
pascal@19515
|
14 // XMM handle which is lost inside xmm_alloc()...
|
pascal@19515
|
15 // (don't drop fallback: use it if no XMM driver detected)
|
pascal@19515
|
16 static void read2mem(struct image_himem *m) {
|
pascal@19515
|
17 u32 buf=m->buf;
|
pascal@19515
|
18 while(1) {
|
pascal@19515
|
19 u8 xfer_buf[PAGE_SIZE];
|
pascal@19515
|
20 u16 size = read_image(m, xfer_buf, sizeof(xfer_buf));
|
pascal@19515
|
21 if(s16(size) <= 0) break;
|
pascal@19515
|
22 memcpy32(0, buf, seg(xfer_buf), ofs(xfer_buf), size);
|
pascal@19515
|
23 buf += size;
|
pascal@19515
|
24 m->remaining -= size;
|
pascal@19515
|
25 }
|
pascal@19515
|
26 }
|
pascal@19515
|
27
|
pascal@19515
|
28 extern "C" void sort(u32* v, int size);
|
pascal@19515
|
29
|
pascal@19515
|
30 // Returns ptr to mallocated zero-terminated list of physical page addrs
|
pascal@19515
|
31 // Never fails (will die if not enough mem)
|
pascal@19515
|
32 // Addresses are sorted in ascending order
|
pascal@19515
|
33 // static void malloc_vcpi(struct image_himem *m) {
|
pascal@19515
|
34 static void read2vcpi(struct image_himem *m) {
|
pascal@19515
|
35 u16 cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
|
pascal@19515
|
36 u32* bufv = (u32*)malloc_or_die((cnt+1)*sizeof(u32));
|
pascal@19515
|
37 // our malloc zeroes allocated mem: buf[cnt]=0;
|
pascal@19515
|
38 // Allocate pages, storing addrs in addrbuf
|
pascal@19515
|
39 {for(int i=0;i<cnt;i++) {
|
pascal@19515
|
40 u32 v;
|
pascal@19515
|
41 asm {
|
pascal@19515
|
42 db 66h
|
pascal@19515
|
43 xor dx,dx
|
pascal@19515
|
44 mov ax,0DE04h
|
pascal@19515
|
45 int 67h
|
pascal@19515
|
46 db 66h
|
pascal@19515
|
47 mov [word ptr v],dx
|
pascal@19515
|
48 }
|
pascal@19515
|
49 extern const char vcpi_alloc_err[];
|
pascal@19515
|
50 if(!v) die(vcpi_alloc_err);
|
pascal@19515
|
51 bufv[i] = v;
|
pascal@19515
|
52 }}
|
pascal@19515
|
53 // Sanitize addresses: ascending sort
|
pascal@19515
|
54 sort(bufv,cnt);
|
pascal@19515
|
55 m->bufv = bufv;
|
pascal@19515
|
56 //}
|
pascal@19515
|
57
|
pascal@19515
|
58 // Reads opened fd data into malloc_vcpi'ed memory
|
pascal@19515
|
59 // Dies if file isn't exactly 'size' bytes long
|
pascal@19515
|
60 // Needs intermediate buffer of exactly Nx4k bytes
|
pascal@19515
|
61 // static void read2vcpi(struct image_himem *m) {
|
pascal@19515
|
62 while(1) {
|
pascal@19515
|
63 u8 xfer_buf[PAGE_SIZE];
|
pascal@19515
|
64 u16 size = read_image(m, xfer_buf, PAGE_SIZE);
|
pascal@19515
|
65 if(s16(size) <= 0 || !*bufv) break;
|
pascal@19515
|
66 m->remaining -= size;
|
pascal@19515
|
67 memcpy_vcpi(*bufv++, seg(xfer_buf), ofs(xfer_buf));
|
pascal@19515
|
68 }
|
pascal@19515
|
69 }
|
pascal@19515
|
70
|
pascal@19515
|
71 void init_vcpi() {
|
pascal@19515
|
72 heap_top = prepare_vcpi(malloc_or_die(8*1024+4));
|
pascal@19515
|
73 get_vcpi_interface() || die("VCPI: low 640k: need 1:1 mapping");
|
pascal@19515
|
74 }
|
pascal@19515
|
75
|
pascal@19515
|
76 int skip_xmmalloc;
|
pascal@19515
|
77 void load_image(struct image_himem *m) {
|
pascal@19515
|
78 no_exit++; // die() won't return to DOS
|
pascal@19515
|
79 m->remaining = m->size;
|
pascal@19515
|
80 m->buf = m->fallback;
|
pascal@19515
|
81 if(m->fallback < _1m) {
|
pascal@19515
|
82 read2mem(m);
|
pascal@19515
|
83 } else if(vcpi==0) {
|
pascal@19515
|
84 if (!skip_xmmalloc) {
|
pascal@19515
|
85 u32 v = xmm_alloc(m->size);
|
pascal@19515
|
86 if(v) m->buf = v;
|
pascal@19515
|
87 }
|
pascal@19515
|
88 read2mem(m);
|
pascal@19515
|
89 } else {
|
pascal@19515
|
90 //malloc_vcpi(m);
|
pascal@19515
|
91 read2vcpi(m);
|
pascal@19515
|
92 }
|
pascal@19515
|
93 if(m->remaining) die("Read error");
|
pascal@19515
|
94 //break iso case close(m->fd);
|
pascal@19515
|
95 }
|
pascal@19515
|
96
|