ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/video_vosf.h
(Generate patch)

Comparing BasiliskII/src/Unix/video_vosf.h (file contents):
Revision 1.18 by cebix, 2001-06-27T19:03:37Z vs.
Revision 1.19 by cebix, 2001-06-28T21:20:00Z

# Line 24 | Line 24
24   // Note: this file is #include'd in video_x.cpp
25   #ifdef ENABLE_VOSF
26  
27 + #include <fcntl.h>
28 + #include <sys/mman.h>
29 + #include "sigsegv.h"
30 + #include "vm_alloc.h"
31 +
32 + #ifdef ENABLE_MON
33 + # include "mon.h"
34 + #endif
35 +
36 + // Variables for Video on SEGV support
37 + static uint8 *the_host_buffer;                                          // Host frame buffer in VOSF mode
38 + static uint32 the_buffer_size;                                          // Size of allocated the_buffer
39 +
40 + struct ScreenPageInfo {
41 +    int top, bottom;                    // Mapping between this virtual page and Mac scanlines
42 + };
43 +
44 + struct ScreenInfo {
45 +    uintptr memBase;                    // Real start address
46 +    uintptr memStart;                   // Start address aligned to page boundary
47 +    uintptr memEnd;                             // Address of one-past-the-end of the screen
48 +    uint32 memLength;                   // Length of the memory addressed by the screen pages
49 +    
50 +    uint32 pageSize;                    // Size of a page
51 +    int pageBits;                               // Shift count to get the page number
52 +    uint32 pageCount;                   // Number of pages allocated to the screen
53 +    
54 +        bool dirty;                                     // Flag: set if the frame buffer was touched
55 +    char * dirtyPages;                  // Table of flags set if page was altered
56 +    ScreenPageInfo * pageInfo;  // Table of mappings page -> Mac scanlines
57 + };
58 +
59 + static ScreenInfo mainBuffer;
60 +
61 + #define PFLAG_SET_VALUE                 0x00
62 + #define PFLAG_CLEAR_VALUE               0x01
63 + #define PFLAG_SET_VALUE_4               0x00000000
64 + #define PFLAG_CLEAR_VALUE_4             0x01010101
65 + #define PFLAG_SET(page)                 mainBuffer.dirtyPages[page] = PFLAG_SET_VALUE
66 + #define PFLAG_CLEAR(page)               mainBuffer.dirtyPages[page] = PFLAG_CLEAR_VALUE
67 + #define PFLAG_ISSET(page)               (mainBuffer.dirtyPages[page] == PFLAG_SET_VALUE)
68 + #define PFLAG_ISCLEAR(page)             (mainBuffer.dirtyPages[page] != PFLAG_SET_VALUE)
69 +
70 + #ifdef UNALIGNED_PROFITABLE
71 + # define PFLAG_ISSET_4(page)    (*((uint32 *)(mainBuffer.dirtyPages + (page))) == PFLAG_SET_VALUE_4)
72 + # define PFLAG_ISCLEAR_4(page)  (*((uint32 *)(mainBuffer.dirtyPages + (page))) == PFLAG_CLEAR_VALUE_4)
73 + #else
74 + # define PFLAG_ISSET_4(page) \
75 +                PFLAG_ISSET(page  ) && PFLAG_ISSET(page+1) \
76 +        &&      PFLAG_ISSET(page+2) && PFLAG_ISSET(page+3)
77 + # define PFLAG_ISCLEAR_4(page) \
78 +                PFLAG_ISCLEAR(page  ) && PFLAG_ISCLEAR(page+1) \
79 +        &&      PFLAG_ISCLEAR(page+2) && PFLAG_ISCLEAR(page+3)
80 + #endif
81 +
82 + // Set the selected page range [ first_page, last_page [ into the SET state
83 + #define PFLAG_SET_RANGE(first_page, last_page) \
84 +        memset(mainBuffer.dirtyPages + (first_page), PFLAG_SET_VALUE, \
85 +                (last_page) - (first_page))
86 +
87 + // Set the selected page range [ first_page, last_page [ into the CLEAR state
88 + #define PFLAG_CLEAR_RANGE(first_page, last_page) \
89 +        memset(mainBuffer.dirtyPages + (first_page), PFLAG_CLEAR_VALUE, \
90 +                (last_page) - (first_page))
91 +
92 + #define PFLAG_SET_ALL do { \
93 +        PFLAG_SET_RANGE(0, mainBuffer.pageCount); \
94 +        mainBuffer.dirty = true; \
95 + } while (0)
96 +
97 + #define PFLAG_CLEAR_ALL do { \
98 +        PFLAG_CLEAR_RANGE(0, mainBuffer.pageCount); \
99 +        mainBuffer.dirty = false; \
100 + } while (0)
101 +
102 + // Set the following macro definition to 1 if your system
103 + // provides a really fast strchr() implementation
104 + //#define HAVE_FAST_STRCHR 0
105 +
106 + static inline int find_next_page_set(int page)
107 + {
108 + #if HAVE_FAST_STRCHR
109 +        char *match = strchr(mainBuffer.dirtyPages + page, PFLAG_SET_VALUE);
110 +        return match ? match - mainBuffer.dirtyPages : mainBuffer.pageCount;
111 + #else
112 +        while (PFLAG_ISCLEAR_4(page))
113 +                page += 4;
114 +        while (PFLAG_ISCLEAR(page))
115 +                page++;
116 +        return page;
117 + #endif
118 + }
119 +
120 + static inline int find_next_page_clear(int page)
121 + {
122 + #if HAVE_FAST_STRCHR
123 +        char *match = strchr(mainBuffer.dirtyPages + page, PFLAG_CLEAR_VALUE);
124 +        return match ? match - mainBuffer.dirtyPages : mainBuffer.pageCount;
125 + #else
126 +        while (PFLAG_ISSET_4(page))
127 +                page += 4;
128 +        while (PFLAG_ISSET(page))
129 +                page++;
130 +        return page;
131 + #endif
132 + }
133 +
134 + static int zero_fd = -1;
135 +
136 + #ifdef HAVE_PTHREADS
137 + static pthread_mutex_t vosf_lock = PTHREAD_MUTEX_INITIALIZER;   // Mutex to protect frame buffer (dirtyPages in fact)
138 + #define LOCK_VOSF pthread_mutex_lock(&vosf_lock);
139 + #define UNLOCK_VOSF pthread_mutex_unlock(&vosf_lock);
140 + #else
141 + #define LOCK_VOSF
142 + #define UNLOCK_VOSF
143 + #endif
144 +
145 + static int log_base_2(uint32 x)
146 + {
147 +        uint32 mask = 0x80000000;
148 +        int l = 31;
149 +        while (l >= 0 && (x & mask) == 0) {
150 +                mask >>= 1;
151 +                l--;
152 +        }
153 +        return l;
154 + }
155 +
156 +
157 + /*
158 + *  Initialize mainBuffer structure
159 + */
160 +
161 + static bool video_init_buffer(void)
162 + {
163 +        if (use_vosf) {
164 +                const uint32 page_size  = getpagesize();
165 +                const uint32 page_mask  = page_size - 1;
166 +                
167 +                mainBuffer.memBase      = (uintptr) the_buffer;
168 +                // Align the frame buffer on page boundary
169 +                mainBuffer.memStart             = (uintptr)((((unsigned long) the_buffer) + page_mask) & ~page_mask);
170 +                mainBuffer.memLength    = the_buffer_size;
171 +                mainBuffer.memEnd       = mainBuffer.memStart + mainBuffer.memLength;
172 +
173 +                mainBuffer.pageSize     = page_size;
174 +                mainBuffer.pageCount    = (mainBuffer.memLength + page_mask)/mainBuffer.pageSize;
175 +                mainBuffer.pageBits     = log_base_2(mainBuffer.pageSize);
176 +
177 +                if (mainBuffer.dirtyPages) {
178 +                        free(mainBuffer.dirtyPages);
179 +                        mainBuffer.dirtyPages = NULL;
180 +                }
181 +
182 +                mainBuffer.dirtyPages = (char *) malloc(mainBuffer.pageCount + 2);
183 +
184 +                if (mainBuffer.pageInfo) {
185 +                        free(mainBuffer.pageInfo);
186 +                        mainBuffer.pageInfo = NULL;
187 +                }
188 +
189 +                mainBuffer.pageInfo = (ScreenPageInfo *) malloc(mainBuffer.pageCount * sizeof(ScreenPageInfo));
190 +
191 +                if ((mainBuffer.dirtyPages == 0) || (mainBuffer.pageInfo == 0))
192 +                        return false;
193 +                
194 +                mainBuffer.dirty = false;
195 +
196 +                PFLAG_CLEAR_ALL;
197 +                // Safety net to insure the loops in the update routines will terminate
198 +                // See a discussion in <video_vosf.h> for further details
199 +                PFLAG_CLEAR(mainBuffer.pageCount);
200 +                PFLAG_SET(mainBuffer.pageCount+1);
201 +
202 +                uint32 a = 0;
203 +                for (int i = 0; i < mainBuffer.pageCount; i++) {
204 +                        int y1 = a / VideoMonitor.mode.bytes_per_row;
205 +                        if (y1 >= VideoMonitor.mode.y)
206 +                                y1 = VideoMonitor.mode.y - 1;
207 +
208 +                        int y2 = (a + mainBuffer.pageSize) / VideoMonitor.mode.bytes_per_row;
209 +                        if (y2 >= VideoMonitor.mode.y)
210 +                                y2 = VideoMonitor.mode.y - 1;
211 +
212 +                        mainBuffer.pageInfo[i].top = y1;
213 +                        mainBuffer.pageInfo[i].bottom = y2;
214 +
215 +                        a += mainBuffer.pageSize;
216 +                        if (a > mainBuffer.memLength)
217 +                                a = mainBuffer.memLength;
218 +                }
219 +                
220 +                // We can now write-protect the frame buffer
221 +                if (vm_protect((char *)mainBuffer.memStart, mainBuffer.memLength, VM_PAGE_READ) != 0)
222 +                        return false;
223 +        }
224 +        return true;
225 + }
226 +
227 +
228   /*
229   *  Page-aligned memory allocation
230   */
# Line 62 | Line 263 | static bool screen_fault_handler(sigsegv
263          if (fault_instruction != SIGSEGV_INVALID_PC)
264                  fprintf(stderr, " [IP=0x%08X]", fault_instruction);
265          fprintf(stderr, "\n");
266 + #if EMULATED_68K
267 +        uaecptr nextpc;
268 +        extern void m68k_dumpstate(uaecptr *nextpc);
269 +        m68k_dumpstate(&nextpc);
270 + #endif
271 + #ifdef ENABLE_MON
272 +        char *arg[4] = {"mon", "-m", "-r", NULL};
273 +        mon(3, arg);
274 +        QuitEmulator();
275 + #endif
276          return false;
277   }
278  
# Line 131 | Line 342 | static inline void update_display_window
342                  const int bytes_per_pixel = VideoMonitor.mode.bytes_per_row / VideoMonitor.mode.x;
343                  int i = y1 * bytes_per_row, j;
344                  
345 <                if (depth == 1) {
345 >                if (VideoMonitor.mode.depth == VDEPTH_1BIT) {
346  
347                          // Update the_host_buffer and copy of the_buffer
348                          for (j = y1; j <= y2; j++) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines