new 32x renderers, auto fskip change, massive refactoring
[picodrive.git] / platform / gizmondo / giz.c
1 #include <windows.h>
2 #include <stdio.h>
3
4 #include "kgsdk/Framework.h"
5 #include "kgsdk/Framework2D.h"
6 #include "giz.h"
7 #include "version.h"
8
9 #define LOG_FILE "log.log"
10
11 void *giz_screen = NULL;
12 static FILE *logf = NULL;
13
14 #if 0
15 static int  directfb_init(void);
16 static void directfb_fini(void);
17 #endif
18
19 void lprintf(const char *fmt, ...)
20 {
21         va_list vl;
22
23         if (logf == NULL)
24         {
25                 logf = fopen(LOG_FILE, "r+");
26                 //logf = fopen(LOG_FILE, "a");
27                 if (logf == NULL)
28                         return;
29         }
30         fseek(logf, 0, SEEK_END);
31
32         //if (strchr(fmt, '\n'))
33         //      fprintf(logf, "%lu: ", GetTickCount());
34         va_start(vl, fmt);
35         vfprintf(logf, fmt, vl);
36         va_end(vl);
37         fflush(logf);
38 }
39
40 static void giz_log_close(void)
41 {
42         if (logf != NULL)
43         {
44                 fclose(logf);
45                 logf = NULL;
46         }
47 }
48
49 void giz_init(HINSTANCE hInstance, HINSTANCE hPrevInstance)
50 {
51         int ret;
52
53         lprintf("\n\nPicoDrive v" VERSION " (c) notaz, 2006-2008\n");
54         lprintf("%s %s\n\n", __DATE__, __TIME__);
55
56         ret = Framework_Init(hInstance, hPrevInstance);
57         if (!ret)
58         {
59                 lprintf("Framework_Init() failed\n");
60                 exit(1);
61         }
62         ret = Framework2D_Init();
63         if (!ret)
64         {
65                 lprintf("Framework2D_Init() failed\n");
66                 exit(1);
67         }
68 #if 0
69         ret = directfb_init();
70         if (ret != 0)
71         {
72                 lprintf("directfb_init() failed\n");
73         }
74 #endif
75
76         // test screen
77         giz_screen = fb_lock(1);
78         if (giz_screen == NULL)
79         {
80                 lprintf("fb_lock() failed\n");
81                 exit(1);
82         }
83         lprintf("fb_lock() returned %p\n", giz_screen);
84         fb_unlock();
85         giz_screen = NULL;
86 }
87
88 void giz_deinit(void)
89 {
90         Framework2D_Close();
91         Framework_Close();
92 #if 0
93         directfb_fini();
94 #endif
95
96         giz_log_close();
97 }
98
99
100 #define PAGE_SIZE 0x1000
101
102 #define CACHE_SYNC_INSTRUCTIONS 0x002   /* discard all cached instructions */
103 #define CACHE_SYNC_WRITEBACK    0x004   /* write back but don't discard data cache*/
104
105 WINBASEAPI BOOL WINAPI CacheRangeFlush(LPVOID pAddr, DWORD dwLength, DWORD dwFlags);
106 WINBASEAPI BOOL WINAPI VirtualCopy(LPVOID lpvDest, LPVOID lpvSrc, DWORD cbSize, DWORD fdwProtect);
107
108 void cache_flush_d_inval_i(void *start_addr, void *end_addr)
109 {
110         int size = end_addr - start_addr;
111         CacheRangeFlush(start_addr, size, CACHE_SYNC_WRITEBACK);
112         CacheRangeFlush(start_addr, size, CACHE_SYNC_INSTRUCTIONS);
113 }
114
115
116 #if 0
117 static void *mmap_phys(unsigned int addr, int pages)
118 {
119         void *mem;
120         int ret;
121
122         mem = VirtualAlloc(0, pages*PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS);
123         if (mem == NULL)
124         {
125                 lprintf("VirtualAlloc failed\n");
126                 return NULL;
127         }
128
129         ret = VirtualCopy(mem, (void *)addr, pages*PAGE_SIZE, PAGE_READWRITE | PAGE_NOCACHE);
130         if (ret == 0)
131         {
132                 lprintf("VirtualFree failed\n");
133                 VirtualFree(mem, 0, MEM_RELEASE);
134                 return NULL;
135         }
136
137         return mem;
138 }
139
140 static void munmap_phys(void *ptr)
141 {
142         VirtualFree(ptr, 0, MEM_RELEASE);
143 }
144
145 // FB
146 static int   directfb_initialized = 0;
147 static int   directfb_addrs[2] = { 0, 0 };
148 static void *directfb_ptrs[2] = { NULL, NULL };
149 static int   directfb_sel = 0;          // the one currently displayed
150 static volatile unsigned int *memregs = NULL;
151
152 /*static void xdump(void)
153 {
154         int i;
155         for (i = 0; i < 0x1000/4; i += 4)
156         {
157                 lprintf("%04x: %08x %08x %08x %08x\n", i*4, memregs[i],
158                         memregs[i+1], memregs[i+2], memregs[i+3]);
159         }
160 }*/
161
162 static int directfb_init(void)
163 {
164         memregs = mmap_phys(0xac009000, 1);
165         if (memregs == NULL)
166         {
167                 lprintf("can't access hw regs\n");
168                 return -1;
169         }
170
171         // fake lock
172         Framework2D_LockBuffer(1);
173
174         // 0xAC00905C
175         directfb_addrs[0] = memregs[0x5c>>2];
176         lprintf("fb0 is at %08x\n", directfb_addrs[0]);
177
178         Framework2D_UnlockBuffer();
179
180         directfb_ptrs[0] = mmap_phys(directfb_addrs[0], (321*240*2+PAGE_SIZE-1) / PAGE_SIZE);
181         if (directfb_ptrs[0] == NULL)
182         {
183                 lprintf("failed to map fb0\n");
184                 goto fail0;
185         }
186
187         // use directx to discover other buffer
188         xdump();
189         Framework2D_Flip();
190         lprintf("---\n");
191         xdump();
192         exit(1);
193         //Framework2D_LockBuffer(1);
194
195         directfb_addrs[1] = memregs[0x5c>>2] + 0x30000;
196         lprintf("fb1 is at %08x\n", directfb_addrs[1]);
197
198         //Framework2D_UnlockBuffer();
199
200         directfb_ptrs[1] = mmap_phys(directfb_addrs[1], (321*240*2+PAGE_SIZE-1) / PAGE_SIZE);
201         if (directfb_ptrs[1] == NULL)
202         {
203                 lprintf("failed to map fb1\n");
204                 goto fail1;
205         }
206
207         directfb_initialized = 1;
208         directfb_sel = 1;
209         return 0;
210
211 fail1:
212         munmap_phys(directfb_ptrs[0]);
213 fail0:
214         munmap_phys((void *)memregs);
215         return -1;
216 }
217
218 static void directfb_fini(void)
219 {
220         if (!directfb_initialized) return;
221
222         munmap_phys(directfb_ptrs[0]);
223         munmap_phys(directfb_ptrs[1]);
224         munmap_phys((void *)memregs);
225 }
226
227 void *directfb_lock(int is_front)
228 {
229         int which;
230
231         if (!directfb_initialized)
232                 // fall back to directx
233                 return Framework2D_LockBuffer(is_front);
234
235         if (is_front)
236                 which = directfb_sel;
237         else
238                 which = directfb_sel ^ 1; // return backbuffer when possible
239
240         return directfb_ptrs[which];
241 }
242
243 void directfb_unlock(void)
244 {
245         if (!directfb_initialized)
246                 // fall back to directx
247                 Framework2D_UnlockBuffer();
248 }
249
250 void directfb_flip(void)
251 {
252         if (!directfb_initialized) {
253                 Framework2D_Flip();
254                 return;
255         }
256
257         directfb_sel ^= 1;
258         // doesn't work
259         memregs[0x5c>>2] = directfb_addrs[directfb_sel];
260 }
261 #endif