|
|
1.1 root 1: /*
2: Hatari - videl.c
3:
1.1.1.9 root 4: This file is distributed under the GNU General Public License, version 2
5: or at your option any later version. Read the file gpl.txt for details.
1.1 root 6:
7: Falcon Videl emulation. The Videl is the graphics shifter chip of the Falcon.
8: It supports free programmable resolutions with 1, 2, 4, 8 or 16 bits per
9: pixel.
10:
11: This file originally came from the Aranym project and has been heavily
12: modified to work for Hatari (but the kudos for the great Videl emulation
13: code goes to the people from the Aranym project of course).
1.1.1.6 root 14:
15: Videl can run at 2 frequencies : 25.175 Mhz or 32 MHz
16:
17: Hardware I/O registers:
18:
19: $FFFF8006 (byte) : monitor type
20:
21: $FFFF8201 (byte) : VDL_VBH - Video Base Hi
22: $FFFF8203 (byte) : VDL_VBM - Video Base Mi
23: $FFFF8205 (byte) : VDL_VCH - Video Count Hi
24: $FFFF8207 (byte) : VDL_VCM - Video Count Mi
25: $FFFF8209 (byte) : VDL_VCL - Video Count Lo
26: $FFFF820A (byte) : VDL_SYM - Sync mode
27: $FFFF820D (byte) : VDL_VBL - Video Base Lo
28: $FFFF820E (word) : VDL_LOF - Offset to next line
29: $FFFF8210 (word) : VDL_LWD - Line Wide in Words
30:
31: $FFFF8240 (word) : VDL_STC - ST Palette Register 00
32: .........
33: $FFFF825E (word) : VDL_STC - ST Palette Register 15
34:
35: $FFFF8260 (byte) : ST shift mode
1.1.1.8 root 36: $FFFF8264 (byte) : Horizontal scroll register shadow register
1.1.1.6 root 37: $FFFF8265 (byte) : Horizontal scroll register
38: $FFFF8266 (word) : Falcon shift mode
39:
40: $FFFF8280 (word) : HHC - Horizontal Hold Counter
41: $FFFF8282 (word) : HHT - Horizontal Hold Timer
42: $FFFF8284 (word) : HBB - Horizontal Border Begin
43: $FFFF8286 (word) : HBE - Horizontal Border End
44: $FFFF8288 (word) : HDB - Horizontal Display Begin
45: $FFFF828A (word) : HDE - Horizontal Display End
46: $FFFF828C (word) : HSS - Horizontal SS
47: $FFFF828E (word) : HFS - Horizontal FS
48: $FFFF8290 (word) : HEE - Horizontal EE
49:
50: $FFFF82A0 (word) : VFC - Vertical Frequency Counter
51: $FFFF82A2 (word) : VFT - Vertical Frequency Timer
52: $FFFF82A4 (word) : VBB - Vertical Border Begin
53: $FFFF82A6 (word) : VBE - Vertical Border End
54: $FFFF82A8 (word) : VDB - Vertical Display Begin
55: $FFFF82AA (word) : VDE - Vertical Display End
56: $FFFF82AC (word) : VSS - Vertical SS
57:
58: $FFFF82C0 (word) : VCO - Video control
59: $FFFF82C2 (word) : VMD - Video mode
60:
61: $FFFF9800 (long) : VDL_PAL - Videl palette Register 000
62: ...........
63: $FFFF98FC (long) : VDL_PAL - Videl palette Register 255
1.1 root 64: */
1.1.1.6 root 65:
1.1.1.4 root 66: const char VIDEL_fileid[] = "Hatari videl.c : " __DATE__ " " __TIME__;
1.1 root 67:
1.1.1.6 root 68: #include <SDL_endian.h>
69: #include <SDL.h>
1.1 root 70: #include "main.h"
71: #include "configuration.h"
1.1.1.6 root 72: #include "memorySnapShot.h"
1.1 root 73: #include "ioMem.h"
1.1.1.6 root 74: #include "log.h"
1.1 root 75: #include "hostscreen.h"
76: #include "screen.h"
77: #include "stMemory.h"
78: #include "videl.h"
1.1.1.10! root 79: #include "video.h" /* for bUseHighRes variable, maybe unuseful (Laurent) */
! 80: #include "vdi.h" /* for bUseVDIRes variable, maybe unuseful (Laurent) */
1.1 root 81:
82: #define Atari2HostAddr(a) (&STRam[a])
83: #define VIDEL_COLOR_REGS_BEGIN 0xff9800
84:
1.1.1.8 root 85:
1.1.1.6 root 86: struct videl_s {
87: bool bUseSTShifter; /* whether to use ST or Falcon palette */
88: Uint8 reg_ffff8006_save; /* save reg_ffff8006 as it's a read only register */
89: Uint8 monitor_type; /* 00 Monochrome (SM124) / 01 Color (SC1224) / 10 VGA Color / 11 Television ($FFFF8006) */
1.1.1.8 root 90: Uint32 videoBaseAddr; /* Video base address, refreshed after each VBL */
1.1.1.6 root 91:
1.1.1.8 root 92: Sint16 leftBorderSize; /* Size of the left border */
93: Sint16 rightBorderSize; /* Size of the right border */
94: Sint16 upperBorderSize; /* Size of the upper border */
95: Sint16 lowerBorderSize; /* Size of the lower border */
96: Uint16 XSize; /* X size of the graphical area */
97: Uint16 YSize; /* Y size of the graphical area */
98:
99: Uint16 save_scrWidth; /* save screen width to detect a change of X resolution */
100: Uint16 save_scrHeight; /* save screen height to detect a change of Y resolution */
101: Uint16 save_scrBpp; /* save screen Bpp to detect a change of bitplan mode */
1.1 root 102:
1.1.1.8 root 103: bool hostColorsSync; /* Sync palette with host's */
104: };
1.1.1.6 root 105:
1.1.1.8 root 106: struct videl_zoom_s {
107: Uint16 zoomwidth;
108: Uint16 prev_scrwidth;
109: Uint16 zoomheight;
110: Uint16 prev_scrheight;
111: int *zoomxtable;
112: int *zoomytable;
113: };
1.1 root 114:
1.1.1.8 root 115: static struct videl_s videl;
116: static struct videl_zoom_s videl_zoom;
1.1.1.6 root 117:
1.1.1.8 root 118: Uint16 vfc_counter; /* counter for VFC register $ff82a0 (to be internalized when VIDEL emulation is complete) */
1.1.1.6 root 119:
1.1.1.8 root 120: static void VIDEL_memset_uint32(Uint32 *addr, Uint32 color, int count);
121: static void VIDEL_memset_uint16(Uint16 *addr, Uint16 color, int count);
122: static void VIDEL_memset_uint8(Uint8 *addr, Uint8 color, int count);
1.1.1.10! root 123: static void Videl_ColorReg_WriteWord(void);
! 124:
1.1 root 125:
1.1.1.8 root 126: /**
127: * Called upon startup and when CPU encounters a RESET instruction.
128: */
1.1 root 129: void VIDEL_reset(void)
130: {
1.1.1.6 root 131: videl.bUseSTShifter = false; /* Use Falcon color palette by default */
132: videl.reg_ffff8006_save = IoMem_ReadByte(0xff8006);
1.1.1.8 root 133: videl.monitor_type = videl.reg_ffff8006_save & 0xc0;
1.1.1.6 root 134:
1.1.1.8 root 135: videl.hostColorsSync = false;
1.1 root 136:
1.1.1.6 root 137: vfc_counter = 0;
138:
1.1 root 139: /* Autozoom */
1.1.1.8 root 140: videl_zoom.zoomwidth = 0;
141: videl_zoom.prev_scrwidth = 0;
142: videl_zoom.zoomheight = 0;
143: videl_zoom.prev_scrheight = 0;
144: videl_zoom.zoomxtable = NULL;
145: videl_zoom.zoomytable = NULL;
1.1 root 146:
1.1.1.4 root 147: /* Default resolution to boot with */
1.1.1.8 root 148: videl.save_scrWidth = 640;
149: videl.save_scrHeight = 480;
150: videl.save_scrBpp = ConfigureParams.Screen.nForceBpp;
151: HostScreen_setWindowSize(videl.save_scrWidth, videl.save_scrHeight, videl.save_scrBpp);
1.1.1.4 root 152:
153: /* Reset IO register (some are not initialized by TOS) */
154: IoMem_WriteWord(0xff820e, 0); /* Line offset */
155: IoMem_WriteWord(0xff8264, 0); /* Horizontal scroll */
1.1.1.8 root 156:
157: /* Init synch mode register */
158: VIDEL_SyncMode_WriteByte();
1.1 root 159: }
160:
1.1.1.6 root 161: /**
162: * Save/Restore snapshot of local variables ('MemorySnapShot_Store' handles type)
163: */
164: void VIDEL_MemorySnapShot_Capture(bool bSave)
165: {
166: /* Save/Restore details */
167: MemorySnapShot_Store(&videl, sizeof(videl));
168: MemorySnapShot_Store(&vfc_counter, sizeof(vfc_counter));
169: }
170:
171: /**
1.1.1.10! root 172: * Monitor write access to Falcon color palette registers
1.1.1.6 root 173: */
1.1.1.10! root 174: void VIDEL_FalconColorRegsWrite(void)
1.1 root 175: {
1.1.1.10! root 176: uint32_t color = IoMem_ReadLong(IoAccessBaseAddress & ~3);
! 177: color &= 0xfcfc00fc; /* Unused bits have to be set to 0 */
! 178: IoMem_WriteLong(IoAccessBaseAddress & ~3, color);
1.1.1.8 root 179: videl.hostColorsSync = false;
1.1 root 180: }
181:
1.1.1.6 root 182: /**
183: * VIDEL_Monitor_WriteByte : Contains memory and monitor configuration.
1.1.1.8 root 184: * This register is read only.
1.1.1.6 root 185: */
186: void VIDEL_Monitor_WriteByte(void)
187: {
1.1.1.8 root 188: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8006 Monitor and memory conf write (Read only)\n");
1.1.1.6 root 189: /* Restore hardware value */
1.1.1.8 root 190:
1.1.1.6 root 191: IoMem_WriteByte(0xff8006, videl.reg_ffff8006_save);
192: }
193:
194: /**
1.1.1.8 root 195: * VIDEL_SyncMode_WriteByte : Videl synchronization mode.
196: * $FFFF820A [R/W] _______0 .................................. SYNC-MODE
197: ||
198: |+--Synchronisation [ 0:internal / 1:external ]
199: +---Vertical frequency [ Read-only bit ]
200: [ Monochrome monitor:0 / Colour monitor:1 ]
201: */
202: void VIDEL_SyncMode_WriteByte(void)
203: {
204: Uint8 syncMode = IoMem_ReadByte(0xff820a);
205: LOG_TRACE(TRACE_VIDEL, "Videl : $ff820a Sync Mode write: 0x%02x\n", syncMode);
206:
207: if (videl.monitor_type == FALCON_MONITOR_MONO)
208: syncMode &= 0xfd;
209: else
210: syncMode |= 0x2;
211:
212: IoMem_WriteByte(0xff820a, syncMode);
213: }
214:
215: /**
216: * Read video address counter and update ff8205/07/09
217: */
218: void VIDEL_ScreenCounter_ReadByte(void)
219: {
220: // Uint32 addr; // To be used
221: Uint32 addr = 0; // To be removed
222:
223: // addr = Videl_CalculateAddress(); /* TODO: get current video address */
224: IoMem[0xff8205] = ( addr >> 16 ) & 0xff;
225: IoMem[0xff8207] = ( addr >> 8 ) & 0xff;
226: IoMem[0xff8209] = addr & 0xff;
227:
228: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8205/07/09 Sync Mode read: 0x%08x\n", addr);
229: }
230:
231: /**
232: * Write video address counter
233: */
234: void VIDEL_ScreenCounter_WriteByte(void)
235: {
236: Uint32 addr_new = 0;
237: Uint8 AddrByte;
238:
239: AddrByte = IoMem[ IoAccessCurrentAddress ];
240:
241: /* Compute the new video address with one modified byte */
242: if ( IoAccessCurrentAddress == 0xff8205 )
243: addr_new = ( addr_new & 0x00ffff ) | ( AddrByte << 16 );
244: else if ( IoAccessCurrentAddress == 0xff8207 )
245: addr_new = ( addr_new & 0xff00ff ) | ( AddrByte << 8 );
246: else if ( IoAccessCurrentAddress == 0xff8209 )
247: addr_new = ( addr_new & 0xffff00 ) | ( AddrByte );
248:
249: // TODO: save the value in a table for the final rendering
250: }
251:
252: /**
253: * VIDEL_LineOffset_WriteWord: $FFFF820E [R/W] W _______876543210 Line Offset
254: * How many words are added to the end of display line, i.e. how many words are
255: * 'behind' the display.
256: */
257: void VIDEL_LineOffset_WriteWord(void)
258: {
1.1.1.9 root 259: LOG_TRACE(TRACE_VIDEL, "Videl : $ff820e Line Offset write: 0x%04x\n",
260: IoMem_ReadWord(0xff820e));
1.1.1.8 root 261: }
262:
263: /**
264: * VIDEL_Line_Width_WriteWord: $FFFF8210 [R/W] W ______9876543210 Line Width (VWRAP)
265: * Length of display line in words.Or, how many words should be added to
266: * vram counter after every display line.
267: */
268: void VIDEL_Line_Width_WriteWord(void)
269: {
1.1.1.9 root 270: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8210 Line Width write: 0x%04x\n",
271: IoMem_ReadWord(0xff8210));
1.1.1.8 root 272: }
273:
274: /**
1.1.1.6 root 275: * Write to video address base high, med and low register (0xff8201/03/0d).
276: * On Falcon, when a program writes to high or med registers, base low register
277: * is reset to zero.
278: */
279: void VIDEL_ScreenBase_WriteByte(void)
280: {
281: if ((IoAccessCurrentAddress == 0xff8201) || (IoAccessCurrentAddress == 0xff8203)) {
282: /* Reset screen base low register */
283: IoMem[0xff820d] = 0;
284: }
285:
1.1.1.9 root 286: LOG_TRACE(TRACE_VIDEL, "Videl : $%04x Screen base write: 0x%02x\t (screen: 0x%04x)\n",
287: IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress],
288: (IoMem[0xff8201]<<16) + (IoMem[0xff8203]<<8) + IoMem[0xff820d]);
1.1.1.6 root 289: }
290:
291: /**
292: VIDEL_ST_ShiftModeWriteByte :
293: $FFFF8260 [R/W] B ______10 ST Shift Mode
294: ||
295: || others vga
296: || $FF8210 $FF82C2 $FF82C2
297: 00--4BP/320 Pixels=> $0050 $0000 $0005
298: 01--2BP/640 Pixels=> $0050 $0004 $0009
299: 10--1BP/640 Pixels=> $0028 $0006 $0008
300: 11--???/320 Pixels=> $0050 $0000 $0000
301:
302: Writing to this register does the following things:
303: - activate STE palette
304: - sets line width ($ffff8210)
305: - sets video mode in $ffff82c2 (double lines/interlace & cycles/pixel)
306: */
307: void VIDEL_ST_ShiftModeWriteByte(void)
308: {
309: Uint16 line_width, video_mode;
310: Uint8 st_shiftMode;
311:
312: st_shiftMode = IoMem_ReadByte(0xff8260);
1.1.1.8 root 313: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8260 ST Shift Mode (STSHIFT) write: 0x%02x\n", st_shiftMode);
314:
315: /* Bits 2-7 are set to 0 */
316: IoMem_WriteByte(0xff8260, st_shiftMode & 3);
1.1.1.6 root 317:
318: /* Activate STE palette */
319: videl.bUseSTShifter = true;
320:
321: /* Compute line width and video mode */
322: switch (st_shiftMode & 0x3) {
323: case 0: /* 4BP/320 Pixels */
324: line_width = 0x50;
325: /* half pixels + double lines vs. no scaling */
326: video_mode = videl.monitor_type == FALCON_MONITOR_VGA ? 0x5 : 0x0;
327: break;
328: case 1: /* 2BP/640 Pixels */
329: line_width = 0x50;
330: /* quarter pixels + double lines vs. half pixels */
331: video_mode = videl.monitor_type == FALCON_MONITOR_VGA ? 0x9 : 0x4;
332: break;
333: case 2: /* 1BP/640 Pixels */
334: line_width = 0x28;
335: if (videl.monitor_type == FALCON_MONITOR_MONO) {
336: video_mode = 0x0;
337: break;
338: }
339: /* quarter pixels vs. half pixels + interlace */
340: video_mode = videl.monitor_type == FALCON_MONITOR_VGA ? 0x8 : 0x6;
341: break;
342: case 3: /* ???/320 Pixels */
1.1.1.8 root 343: default:
1.1.1.6 root 344: line_width = 0x50;
345: video_mode = 0x0;
346: break;
347: }
348:
349: /* Set line width ($FFFF8210) */
350: IoMem_WriteWord(0xff8210, line_width);
351:
352: /* Set video mode ($FFFF82C2) */
353: IoMem_WriteWord(0xff82c2, video_mode);
354: }
355:
356: /**
1.1.1.8 root 357: VIDEL_HorScroll64_WriteByte : Horizontal scroll register (0-15)
358: $FFFF8264 [R/W] ________ ................................ H-SCROLL HI
359: |||| [ Shadow register for $FFFF8265 ]
360: ++++--Pixel shift [ 0:normal / 1..15:Left shift ]
361: [ Change in line-width NOT required ]
362: */
363: void VIDEL_HorScroll64_WriteByte(void)
364: {
1.1.1.9 root 365: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8264 Horizontal scroll 64 write: 0x%02x\n",
366: IoMem_ReadByte(0xff8264));
1.1.1.8 root 367: }
368:
369: /**
370: VIDEL_HorScroll65_WriteByte : Horizontal scroll register (0-15)
371: $FFFF8265 [R/W] ____3210 .................................H-SCROLL LO
372: ||||
373: ++++--Pixel [ 0:normal / 1..15:Left shift ]
374: [ Change in line-width NOT required ]
375: */
376: void VIDEL_HorScroll65_WriteByte(void)
377: {
1.1.1.9 root 378: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8265 Horizontal scroll 65 write: 0x%02x\n",
379: IoMem_ReadByte(0xff8265));
1.1.1.8 root 380: }
381:
382: /**
383: VIDEL_Falcon_ShiftMode_WriteWord :
1.1.1.6 root 384: $FFFF8266 [R/W] W _____A98_6543210 Falcon Shift Mode (SPSHIFT)
385: ||| |||||||
1.1.1.8 root 386: ||| |||++++- 0..15: Colourbank choice from 256-colour table in 16 colour multiples
387: ||| ||+----- 8 Bitplanes mode (256 Colors) [0:off / 1:on]
388: ||| |+------ Vertical Sync [0: internal / 1: external]
389: ||| +------- Horizontal Sync [0: internal / 1: external]
390: ||+--------- True-Color-Mode [0:off / 1:on]
391: |+---------- Overlay-Mode [0:off / 1:on]
392: +----------- 0: 2-Color-Mode [0:off / 1:on]
1.1.1.6 root 393:
394: Writing to this register does the following things:
395: - activate Falcon palette
396: - if you set Bits A/8/4 == 0, it selects 16-Color-Falcon-Mode (NOT the
397: same as ST LOW since Falcon palette is used!)
398: - $8260 register is ignored, you don't need to write here anything
399:
400: Note: 4-Color-Mode isn't realisable with Falcon palette.
401: */
1.1.1.8 root 402: void VIDEL_Falcon_ShiftMode_WriteWord(void)
1.1.1.6 root 403: {
1.1.1.9 root 404: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8266 Falcon Shift Mode (SPSHIFT) write: 0x%04x\n",
405: IoMem_ReadWord(0xff8266));
1.1.1.6 root 406:
407: videl.bUseSTShifter = false;
408: }
409:
410: /**
411: * Write Horizontal Hold Counter (HHC)
412: */
413: void VIDEL_HHC_WriteWord(void)
414: {
1.1.1.9 root 415: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8280 Horizontal Hold Counter (HHC) write: 0x%04x\n",
416: IoMem_ReadWord(0xff8280));
1.1.1.6 root 417: }
418:
419: /**
420: * Write Horizontal Hold Timer (HHT)
421: */
422: void VIDEL_HHT_WriteWord(void)
423: {
1.1.1.9 root 424: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8282 Horizontal Hold Timer (HHT) write: 0x%04x\n",
425: IoMem_ReadWord(0xff8282));
1.1.1.6 root 426: }
427:
428: /**
429: * Write Horizontal Border Begin (HBB)
430: */
431: void VIDEL_HBB_WriteWord(void)
432: {
1.1.1.9 root 433: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8284 Horizontal Border Begin (HBB) write: 0x%04x\n",
434: IoMem_ReadWord(0xff8284));
1.1.1.6 root 435: }
436:
437: /**
438: * Write Horizontal Border End (HBE)
439: */
440: void VIDEL_HBE_WriteWord(void)
441: {
1.1.1.9 root 442: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8286 Horizontal Border End (HBE) write: 0x%04x\n",
443: IoMem_ReadWord(0xff8286));
1.1.1.6 root 444: }
445:
446: /**
447: * Write Horizontal Display Begin (HDB)
1.1.1.8 root 448: $FFFF8288 [R/W] W ______9876543210 Horizontal Display Begin (HDB)
449: |
450: +---------- Display will start in [0: 1st halfline / 1: 2nd halfline]
1.1.1.6 root 451: */
452: void VIDEL_HDB_WriteWord(void)
453: {
1.1.1.9 root 454: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8288 Horizontal Display Begin (HDB) write: 0x%04x\n",
455: IoMem_ReadWord(0xff8288));
1.1.1.6 root 456: }
457:
458: /**
459: * Write Horizontal Display End (HDE)
460: */
461: void VIDEL_HDE_WriteWord(void)
462: {
1.1.1.9 root 463: LOG_TRACE(TRACE_VIDEL, "Videl : $ff828a Horizontal Display End (HDE) write: 0x%04x\n",
464: IoMem_ReadWord(0xff828a));
1.1.1.6 root 465: }
466:
467: /**
468: * Write Horizontal SS (HSS)
469: */
470: void VIDEL_HSS_WriteWord(void)
471: {
1.1.1.9 root 472: LOG_TRACE(TRACE_VIDEL, "Videl : $ff828c Horizontal SS (HSS) write: 0x%04x\n",
473: IoMem_ReadWord(0xff828c));
1.1.1.6 root 474: }
475:
476: /**
477: * Write Horizontal FS (HFS)
478: */
479: void VIDEL_HFS_WriteWord(void)
480: {
1.1.1.9 root 481: LOG_TRACE(TRACE_VIDEL, "Videl : $ff828e Horizontal FS (HFS) write: 0x%04x\n",
482: IoMem_ReadWord(0xff828e));
1.1.1.6 root 483: }
484:
485: /**
486: * Write Horizontal EE (HEE)
487: */
488: void VIDEL_HEE_WriteWord(void)
489: {
1.1.1.9 root 490: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8290 Horizontal EE (HEE) write: 0x%04x\n",
491: IoMem_ReadWord(0xff8290));
1.1.1.6 root 492: }
493:
494: /**
495: * Write Vertical Frequency Counter (VFC)
496: */
497: void VIDEL_VFC_ReadWord(void)
498: {
499: IoMem_WriteWord(0xff82a0, vfc_counter);
1.1.1.8 root 500: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a0 Vertical Frequency Counter (VFC) read: 0x%04x\n", vfc_counter);
1.1.1.6 root 501: }
502:
503: /**
504: * Write Vertical Frequency Timer (VFT)
505: */
506: void VIDEL_VFT_WriteWord(void)
507: {
1.1.1.9 root 508: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a2 Vertical Frequency Timer (VFT) write: 0x%04x\n",
509: IoMem_ReadWord(0xff82a2));
1.1.1.6 root 510: }
511:
512: /**
513: * Write Vertical Border Begin (VBB)
514: */
515: void VIDEL_VBB_WriteWord(void)
516: {
1.1.1.9 root 517: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a4 Vertical Border Begin (VBB) write: 0x%04x\n",
518: IoMem_ReadWord(0xff82a4));
1.1.1.6 root 519: }
520:
521: /**
522: * Write Vertical Border End (VBE)
523: */
524: void VIDEL_VBE_WriteWord(void)
525: {
1.1.1.9 root 526: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a6 Vertical Border End (VBE) write: 0x%04x\n",
527: IoMem_ReadWord(0xff82a6));
1.1.1.6 root 528: }
529:
530: /**
531: * Write Vertical Display Begin (VDB)
532: */
533: void VIDEL_VDB_WriteWord(void)
1.1 root 534: {
1.1.1.9 root 535: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a8 Vertical Display Begin (VDB) write: 0x%04x\n",
536: IoMem_ReadWord(0xff82a8));
1.1 root 537: }
538:
1.1.1.6 root 539: /**
540: * Write Vertical Display End (VDE)
541: */
542: void VIDEL_VDE_WriteWord(void)
543: {
1.1.1.9 root 544: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82aa Vertical Display End (VDE) write: 0x%04x\n",
545: IoMem_ReadWord(0xff82aa));
1.1.1.6 root 546: }
547:
548: /**
549: * Write Vertical SS (VSS)
550: */
551: void VIDEL_VSS_WriteWord(void)
552: {
1.1.1.9 root 553: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82ac Vertical SS (VSS) write: 0x%04x\n",
554: IoMem_ReadWord(0xff82ac));
1.1.1.6 root 555: }
556:
557: /**
558: * Write Video Control (VCO)
559: */
560: void VIDEL_VCO_WriteWord(void)
561: {
1.1.1.9 root 562: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82c0 Video control (VCO) write: 0x%04x\n",
563: IoMem_ReadWord(0xff82c0));
1.1.1.6 root 564: }
565:
566: /**
567: * Write Video Mode (VDM)
568: */
569: void VIDEL_VMD_WriteWord(void)
570: {
1.1.1.9 root 571: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82c2 Video Mode (VDM) write: 0x%04x\n",
572: IoMem_ReadWord(0xff82c2));
1.1.1.6 root 573: }
574:
575:
1.1.1.8 root 576: /**
577: * VIDEL_getVideoramAddress: returns the video RAM address.
578: * On Falcon, video address must be a multiple of four in bitplane modes.
579: */
580: static Uint32 VIDEL_getVideoramAddress(void)
1.1 root 581: {
1.1.1.8 root 582: Uint32 videoBase;
583:
584: videoBase = (Uint32) IoMem_ReadByte(0xff8201) << 16;
585: videoBase |= (Uint32) IoMem_ReadByte(0xff8203) << 8;
586: videoBase |= IoMem_ReadByte(0xff820d) & ~3;
587:
588: return videoBase;
1.1 root 589: }
590:
1.1.1.8 root 591: static Uint16 VIDEL_getScreenBpp(void)
1.1 root 592: {
1.1.1.8 root 593: Uint16 f_shift = IoMem_ReadWord(0xff8266);
594: Uint16 bits_per_pixel;
595: Uint8 st_shift = IoMem_ReadByte(0xff8260);
596:
1.1 root 597: /* to get bpp, we must examine f_shift and st_shift.
1.1.1.8 root 598: * f_shift is valid if any of bits no. 10, 8 or 4 is set.
599: * Priority in f_shift is: 10 ">" 8 ">" 4, i.e.
1.1 root 600: * if bit 10 set then bit 8 and bit 4 don't care...
601: * If all these bits are 0 and ST shifter is written
602: * after Falcon one, get display depth from st_shift
603: * (as for ST and STE)
604: */
605: if (f_shift & 0x400) /* Falcon: 2 colors */
606: bits_per_pixel = 1;
607: else if (f_shift & 0x100) /* Falcon: hicolor */
608: bits_per_pixel = 16;
609: else if (f_shift & 0x010) /* Falcon: 8 bitplanes */
610: bits_per_pixel = 8;
1.1.1.6 root 611: else if (!videl.bUseSTShifter) /* Falcon: 4 bitplanes */
1.1 root 612: bits_per_pixel = 4;
613: else if (st_shift == 0)
614: bits_per_pixel = 4;
615: else if (st_shift == 0x01)
616: bits_per_pixel = 2;
617: else /* if (st_shift == 0x02) */
618: bits_per_pixel = 1;
619:
1.1.1.8 root 620: /* LOG_TRACE(TRACE_VIDEL, "Videl works in %d bpp, f_shift=%04x, st_shift=%d", bits_per_pixel, f_shift, st_shift); */
1.1 root 621:
622: return bits_per_pixel;
623: }
624:
1.1.1.8 root 625: /**
626: * VIDEL_getScreenWidth : returns the visible X resolution
627: * left border + graphic area + right border
628: * left border : hdb - hbe-offset
629: * right border : hbb - hde-offset
630: * Graphics display : starts at cycle HDB and ends at cycle HDE.
631: */
1.1 root 632: static int VIDEL_getScreenWidth(void)
633: {
1.1.1.9 root 634: Uint16 hbb, hbe, hdb, hde, vdm, hht;
635: Uint16 cycPerPixel, divider;
636: Sint16 hdb_offset, hde_offset;
637: Sint16 leftBorder, rightBorder;
1.1.1.8 root 638: Uint16 bpp = VIDEL_getScreenBpp();
639:
640: /* X Size of the Display area */
641: videl.XSize = (IoMem_ReadWord(0xff8210) & 0x03ff) * 16 / bpp;
642:
643: /* If the user disabled the borders display from the gui, we suppress them */
644: if (ConfigureParams.Screen.bAllowOverscan == 0) {
645: videl.leftBorderSize = 0;
646: videl.rightBorderSize = 0;
647: return videl.XSize;
648: }
649:
650: /* According to Aura and Animal Mine doc about Videl, if a monochrome monitor is connected,
651: * HDB and HDE have no significance and no border is displayed.
652: */
653: if (videl.monitor_type == FALCON_MONITOR_MONO) {
654: videl.leftBorderSize = 0;
655: videl.rightBorderSize = 0;
656: return videl.XSize;
657: }
658:
1.1.1.9 root 659: hbb = IoMem_ReadWord(0xff8284) & 0x01ff;
660: hbe = IoMem_ReadWord(0xff8286) & 0x01ff;
661: hdb = IoMem_ReadWord(0xff8288) & 0x01ff;
662: hde = IoMem_ReadWord(0xff828a) & 0x01ff;
663: vdm = IoMem_ReadWord(0xff82c2) & 0xc;
664: hht = IoMem_ReadWord(0xff8282) & 0x1ff;
1.1.1.8 root 665:
666: /* Compute cycles per pixel */
667: if (vdm == 0)
668: cycPerPixel = 4;
669: else if (vdm == 4)
670: cycPerPixel = 2;
671: else
672: cycPerPixel = 1;
673:
674: /* Compute the divider */
675: if (videl.monitor_type == FALCON_MONITOR_VGA) {
676: if (cycPerPixel == 4)
677: divider = 4;
678: else
679: divider = 2;
680: }
681: else if (videl.bUseSTShifter == true) {
682: divider = 16;
683: }
684: else {
685: divider = cycPerPixel;
686: }
687:
688: /* Compute hdb_offset and hde_offset */
689: if (videl.bUseSTShifter == false) {
690: if (bpp < 16) {
691: /* falcon mode bpp */
692: hdb_offset = ((64+(128/bpp + 16 + 2) * cycPerPixel) / divider ) + 1;
693: hde_offset = ((128/bpp + 2) * cycPerPixel) / divider;
694: }
695: else {
696: /* falcon mode true color */
697: hdb_offset = ((64 + 16 * cycPerPixel) / divider ) + 1;
698: hde_offset = 0;
699: }
700: }
701: else {
702: /* ST bitplan mode */
703: hdb_offset = ((128+(128/bpp + 2) * cycPerPixel) / divider ) + 1;
704: hde_offset = ((128/bpp + 2) * cycPerPixel) / divider;
705: }
706:
707: LOG_TRACE(TRACE_VIDEL, "hdb_offset=%04x, hde_offset=%04x\n", hdb_offset, hde_offset);
708:
709: /* Compute left border size in cycles */
710: if (IoMem_ReadWord(0xff8288) & 0x0200)
711: leftBorder = hdb - hbe + hdb_offset - hht - 2;
712: else
713: leftBorder = hdb - hbe + hdb_offset;
714:
715: /* Compute right border size in cycles */
716: rightBorder = hbb - hde_offset - hde;
717:
718: videl.leftBorderSize = leftBorder / cycPerPixel;
719: videl.rightBorderSize = rightBorder / cycPerPixel;
720: LOG_TRACE(TRACE_VIDEL, "left border size=%04x, right border size=%04x\n", videl.leftBorderSize, videl.rightBorderSize);
721:
722: if (videl.leftBorderSize < 0) {
723: // fprintf(stderr, "BORDER LEFT < 0 %d\n", videl.leftBorderSize);
724: videl.leftBorderSize = 0;
725: }
726: if (videl.rightBorderSize < 0) {
727: // fprintf(stderr, "BORDER RIGHT < 0 %d\n", videl.rightBorderSize);
728: videl.rightBorderSize = 0;
729: }
730:
731: return videl.leftBorderSize + videl.XSize + videl.rightBorderSize;
1.1 root 732: }
733:
1.1.1.8 root 734: /**
735: * VIDEL_getScreenHeight : returns the visible Y resolution
736: * upper border + graphic area + lower border
737: * upper border : vdb - vbe
738: * lower border : vbb - vde
739: * Graphics display : starts at line VDB and ends at line VDE.
740: * If interlace mode off unit of VC-registers is half lines, else lines.
741: */
1.1 root 742: static int VIDEL_getScreenHeight(void)
743: {
1.1.1.8 root 744: Uint16 vbb = IoMem_ReadWord(0xff82a4) & 0x07ff;
745: Uint16 vbe = IoMem_ReadWord(0xff82a6) & 0x07ff;
746: Uint16 vdb = IoMem_ReadWord(0xff82a8) & 0x07ff;
747: Uint16 vde = IoMem_ReadWord(0xff82aa) & 0x07ff;
748: Uint16 vmode = IoMem_ReadWord(0xff82c2);
749:
750: /* According to Aura and Animal Mine doc about Videl, if a monochrome monitor is connected,
751: * VDB and VDE have no significance and no border is displayed.
1.1 root 752: */
1.1.1.8 root 753: if (videl.monitor_type == FALCON_MONITOR_MONO) {
754: videl.upperBorderSize = 0;
755: videl.lowerBorderSize = 0;
756: }
757: else {
758: /* We must take the positive value only, as a program like AceTracker starts the */
759: /* graphical area 1 line before the end of the upper border */
760: videl.upperBorderSize = vdb - vbe > 0 ? vdb - vbe : 0;
761: videl.lowerBorderSize = vbb - vde > 0 ? vbb - vde : 0;
762: }
1.1 root 763:
1.1.1.8 root 764: /* Y Size of the Display area */
1.1.1.9 root 765: if (vde >= vdb) {
766: videl.YSize = vde - vdb;
767: }
768: else {
769: LOG_TRACE(TRACE_VIDEL, "WARNING: vde=0x%x is less than vdb=0x%x\n",
770: vde, vdb);
771: }
1.1.1.8 root 772:
773: /* If the user disabled the borders display from the gui, we suppress them */
774: if (ConfigureParams.Screen.bAllowOverscan == 0) {
775: videl.upperBorderSize = 0;
776: videl.lowerBorderSize = 0;
777: }
778:
779: if (!(vmode & 0x02)){ /* interlace */
780: videl.YSize >>= 1;
781: videl.upperBorderSize >>= 1;
782: videl.lowerBorderSize >>= 1;
783: }
784:
785: if (vmode & 0x01) { /* double */
786: videl.YSize >>= 1;
787: videl.upperBorderSize >>= 1;
788: videl.lowerBorderSize >>= 1;
789: }
1.1.1.9 root 790:
1.1.1.8 root 791: return videl.upperBorderSize + videl.YSize + videl.lowerBorderSize;
1.1 root 792: }
793:
1.1.1.5 root 794: #if 0
795: /* this is easier & more robustly done in hostscreen.c just by
796: * comparing requested screen width & height to each other.
797: */
798: static void VIDEL_getMonitorScale(int *sx, int *sy)
799: {
800: /* Videl video mode register bits and resulting desktop resolution:
801: *
802: * quarter, half, interlace, double: pixels: -> zoom:
803: * rgb:
804: * 0 0 0 0 320x200 -> 2 x 2
805: * 0 0 1 0 320x400 -> 2 x 1
806: * 0 1 0 0 640x200 -> 1 x 2 !
807: * 0 1 1 0 640x400 -> 1 x 1
808: * vga:
809: * 0 0 0 1 (just double ?)
810: * 0 0 1 1 (double & interlace ???)
811: * 0 1 0 0 320x480 -> 2 x 1 !
812: * 0 1 0 1 320x240 -> 2 x 2
813: * 0 1 1 1 (double + interlace ???)
814: * 1 0 0 0 640x480 -> 1 x 1
815: * 1 0 0 1 640x240 -> 1 x 2
816: */
1.1.1.8 root 817: int vmode = IoMem_ReadWord(0xff82c2);
1.1.1.5 root 818:
819: /* half pixel seems to have opposite meaning on
820: * VGA and RGB monitor, so they need to handled separately
821: */
1.1.1.6 root 822: if (videl.monitor_type) == FALCON_MONITOR_VGA) {
1.1.1.8 root 823: if (vmode & 0x08) { /* quarter pixel */
1.1.1.5 root 824: *sx = 1;
825: } else {
826: *sx = 2;
827: }
1.1.1.8 root 828: if (vmode & 0x01) { /* double line */
1.1.1.5 root 829: *sy = 2;
830: } else {
831: *sy = 1;
832: }
833: } else {
1.1.1.8 root 834: if (vmode & 0x04) { /* half pixel */
1.1.1.5 root 835: *sx = 1;
836: } else {
837: *sx = 2;
838: }
1.1.1.8 root 839: if (vmode & 0x02) { /* interlace used only on RGB ? */
1.1.1.5 root 840: *sy = 1;
841: } else {
842: *sy = 2;
843: }
844: }
845: }
846: #endif
847:
1.1 root 848:
849: /** map the correct colortable into the correct pixel format
850: */
851: static void VIDEL_updateColors(void)
852: {
1.1.1.8 root 853: int i, r, g, b, colors = 1 << videl.save_scrBpp;
1.1 root 854:
1.1.1.8 root 855: #define F_COLORS(i) IoMem_ReadByte(VIDEL_COLOR_REGS_BEGIN + (i))
856: #define STE_COLORS(i) IoMem_ReadByte(0xff8240 + (i))
1.1 root 857:
1.1.1.6 root 858: if (!videl.bUseSTShifter) {
1.1 root 859: for (i = 0; i < colors; i++) {
860: int offset = i << 2;
861: r = F_COLORS(offset) & 0xfc;
862: r |= r>>6;
863: g = F_COLORS(offset + 1) & 0xfc;
864: g |= g>>6;
865: b = F_COLORS(offset + 3) & 0xfc;
866: b |= b>>6;
867: HostScreen_setPaletteColor(i, r,g,b);
868: }
869: HostScreen_updatePalette(colors);
870: } else {
871: for (i = 0; i < colors; i++) {
872: int offset = i << 1;
873: r = STE_COLORS(offset) & 0x0f;
874: r = ((r & 7)<<1)|(r>>3);
875: r |= r<<4;
876: g = (STE_COLORS(offset + 1)>>4) & 0x0f;
877: g = ((g & 7)<<1)|(g>>3);
878: g |= g<<4;
879: b = STE_COLORS(offset + 1) & 0x0f;
880: b = ((b & 7)<<1)|(b>>3);
881: b |= b<<4;
882: HostScreen_setPaletteColor(i, r,g,b);
883: }
884: HostScreen_updatePalette(colors);
885: }
886:
1.1.1.8 root 887: videl.hostColorsSync = true;
1.1 root 888: }
889:
890:
891: void VIDEL_ZoomModeChanged(void)
892: {
893: /* User selected another zoom mode, so set a new screen resolution now */
1.1.1.8 root 894: HostScreen_setWindowSize(videl.save_scrWidth, videl.save_scrHeight, videl.save_scrBpp == 16 ? 16 : ConfigureParams.Screen.nForceBpp);
1.1 root 895: }
896:
897:
1.1.1.2 root 898: bool VIDEL_renderScreen(void)
1.1 root 899: {
1.1.1.8 root 900: /* Atari screen infos */
1.1 root 901: int vw = VIDEL_getScreenWidth();
902: int vh = VIDEL_getScreenHeight();
903: int vbpp = VIDEL_getScreenBpp();
1.1.1.8 root 904:
905: int lineoffset = IoMem_ReadWord(0xff820e) & 0x01ff; /* 9 bits */
906: int linewidth = IoMem_ReadWord(0xff8210) & 0x03ff; /* 10 bits */
1.1.1.9 root 907: int nextline;
1.1.1.8 root 908:
1.1.1.6 root 909: bool change = false;
1.1 root 910:
1.1.1.9 root 911: videl.videoBaseAddr = VIDEL_getVideoramAddress(); // Todo: to be removed when all code is in Videl
912:
1.1.1.8 root 913: if (vw > 0 && vw != videl.save_scrWidth) {
914: LOG_TRACE(TRACE_VIDEL, "Videl : width change from %d to %d\n", videl.save_scrWidth, vw);
915: videl.save_scrWidth = vw;
1.1.1.6 root 916: change = true;
1.1 root 917: }
1.1.1.8 root 918: if (vh > 0 && vh != videl.save_scrHeight) {
919: LOG_TRACE(TRACE_VIDEL, "Videl : height change from %d to %d\n", videl.save_scrHeight, vh);
920: videl.save_scrHeight = vh;
1.1.1.6 root 921: change = true;
1.1 root 922: }
1.1.1.8 root 923: if (vbpp != videl.save_scrBpp) {
924: LOG_TRACE(TRACE_VIDEL, "Videl : bpp change from %d to %d\n", videl.save_scrBpp, vbpp);
925: videl.save_scrBpp = vbpp;
1.1.1.6 root 926: change = true;
927: }
928: if (change) {
1.1.1.8 root 929: LOG_TRACE(TRACE_VIDEL, "Videl : video mode change to %dx%d@%d\n", videl.save_scrWidth, videl.save_scrHeight, videl.save_scrBpp);
930: HostScreen_setWindowSize(videl.save_scrWidth, videl.save_scrHeight, videl.save_scrBpp == 16 ? 16 : ConfigureParams.Screen.nForceBpp);
1.1 root 931: }
932:
933: if (!HostScreen_renderBegin())
1.1.1.2 root 934: return false;
1.1 root 935:
1.1.1.8 root 936: /*
937: I think this implementation is naive:
938: indeed, I suspect that we should instead skip lineoffset
939: words each time we have read "more" than linewidth words
940: (possibly "more" because of the number of bit planes).
941: Moreover, the 1 bit plane mode is particular;
942: while doing some experiments on my Falcon, it seems to
943: behave like the 4 bit planes mode.
944: At last, we have also to take into account the 4 bits register
945: located at the word $ffff8264 (bit offset). This register makes
946: the semantics of the lineoffset register change a little.
947: int bitoffset = IoMem_ReadWord(0xff8264) & 0x000f;
948: The meaning of this register in True Color mode is not clear
949: for me at the moment (and my experiments on the Falcon don't help
950: me).
951: */
1.1.1.9 root 952: nextline = linewidth + lineoffset;
1.1.1.8 root 953:
954: if ((vw<32) || (vh<32))
955: return false;
956:
957: if (videl.save_scrBpp < 16 && videl.hostColorsSync == 0)
958: VIDEL_updateColors();
959:
1.1.1.5 root 960: if (nScreenZoomX * nScreenZoomY != 1) {
1.1.1.8 root 961: VIDEL_ConvertScreenZoom(vw, vh, videl.save_scrBpp, nextline);
1.1 root 962: } else {
1.1.1.8 root 963: VIDEL_ConvertScreenNoZoom(vw, vh, videl.save_scrBpp, nextline);
1.1 root 964: }
965:
1.1.1.10! root 966: HostScreen_update1(HostScreen_renderEnd(), false);
1.1.1.2 root 967:
968: return true;
1.1 root 969: }
970:
971:
1.1.1.4 root 972: /**
973: * Performs conversion from the TOS's bitplane word order (big endian) data
974: * into the native chunky color index.
975: */
1.1.1.8 root 976: static void VIDEL_bitplaneToChunky(Uint16 *atariBitplaneData, Uint16 bpp,
1.1.1.4 root 977: Uint8 colorValues[16])
978: {
979: Uint32 a, b, c, d, x;
980:
981: /* Obviously the different cases can be broken out in various
982: * ways to lessen the amount of work needed for <8 bit modes.
983: * It's doubtful if the usage of those modes warrants it, though.
984: * The branches below should be ~100% correctly predicted and
985: * thus be more or less for free.
986: * Getting the palette values inline does not seem to help
987: * enough to worry about. The palette lookup is much slower than
988: * this code, though, so it would be nice to do something about it.
989: */
990: if (bpp >= 4) {
991: d = *(Uint32 *)&atariBitplaneData[0];
992: c = *(Uint32 *)&atariBitplaneData[2];
993: if (bpp == 4) {
994: a = b = 0;
995: } else {
996: b = *(Uint32 *)&atariBitplaneData[4];
997: a = *(Uint32 *)&atariBitplaneData[6];
998: }
999: } else {
1000: a = b = c = 0;
1001: if (bpp == 2) {
1002: d = *(Uint32 *)&atariBitplaneData[0];
1003: } else {
1004: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1005: d = atariBitplaneData[0]<<16;
1006: #else
1007: d = atariBitplaneData[0];
1008: #endif
1009: }
1010: }
1011:
1012: x = a;
1013: a = (a & 0xf0f0f0f0) | ((c & 0xf0f0f0f0) >> 4);
1014: c = ((x & 0x0f0f0f0f) << 4) | (c & 0x0f0f0f0f);
1015: x = b;
1016: b = (b & 0xf0f0f0f0) | ((d & 0xf0f0f0f0) >> 4);
1017: d = ((x & 0x0f0f0f0f) << 4) | (d & 0x0f0f0f0f);
1018:
1019: x = a;
1020: a = (a & 0xcccccccc) | ((b & 0xcccccccc) >> 2);
1021: b = ((x & 0x33333333) << 2) | (b & 0x33333333);
1022: x = c;
1023: c = (c & 0xcccccccc) | ((d & 0xcccccccc) >> 2);
1024: d = ((x & 0x33333333) << 2) | (d & 0x33333333);
1025:
1026: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1027: a = (a & 0x5555aaaa) | ((a & 0x00005555) << 17) | ((a & 0xaaaa0000) >> 17);
1028: b = (b & 0x5555aaaa) | ((b & 0x00005555) << 17) | ((b & 0xaaaa0000) >> 17);
1029: c = (c & 0x5555aaaa) | ((c & 0x00005555) << 17) | ((c & 0xaaaa0000) >> 17);
1030: d = (d & 0x5555aaaa) | ((d & 0x00005555) << 17) | ((d & 0xaaaa0000) >> 17);
1031:
1032: colorValues[ 8] = a;
1033: a >>= 8;
1034: colorValues[ 0] = a;
1035: a >>= 8;
1036: colorValues[ 9] = a;
1037: a >>= 8;
1038: colorValues[ 1] = a;
1039:
1040: colorValues[10] = b;
1041: b >>= 8;
1042: colorValues[ 2] = b;
1043: b >>= 8;
1044: colorValues[11] = b;
1045: b >>= 8;
1046: colorValues[ 3] = b;
1047:
1048: colorValues[12] = c;
1049: c >>= 8;
1050: colorValues[ 4] = c;
1051: c >>= 8;
1052: colorValues[13] = c;
1053: c >>= 8;
1054: colorValues[ 5] = c;
1055:
1056: colorValues[14] = d;
1057: d >>= 8;
1058: colorValues[ 6] = d;
1059: d >>= 8;
1060: colorValues[15] = d;
1061: d >>= 8;
1062: colorValues[ 7] = d;
1063: #else
1064: a = (a & 0xaaaa5555) | ((a & 0x0000aaaa) << 15) | ((a & 0x55550000) >> 15);
1065: b = (b & 0xaaaa5555) | ((b & 0x0000aaaa) << 15) | ((b & 0x55550000) >> 15);
1066: c = (c & 0xaaaa5555) | ((c & 0x0000aaaa) << 15) | ((c & 0x55550000) >> 15);
1067: d = (d & 0xaaaa5555) | ((d & 0x0000aaaa) << 15) | ((d & 0x55550000) >> 15);
1068:
1069: colorValues[ 1] = a;
1070: a >>= 8;
1071: colorValues[ 9] = a;
1072: a >>= 8;
1073: colorValues[ 0] = a;
1074: a >>= 8;
1075: colorValues[ 8] = a;
1076:
1077: colorValues[ 3] = b;
1078: b >>= 8;
1079: colorValues[11] = b;
1080: b >>= 8;
1081: colorValues[ 2] = b;
1082: b >>= 8;
1083: colorValues[10] = b;
1084:
1085: colorValues[ 5] = c;
1086: c >>= 8;
1087: colorValues[13] = c;
1088: c >>= 8;
1089: colorValues[ 4] = c;
1090: c >>= 8;
1091: colorValues[12] = c;
1092:
1093: colorValues[ 7] = d;
1094: d >>= 8;
1095: colorValues[15] = d;
1096: d >>= 8;
1097: colorValues[ 6] = d;
1098: d >>= 8;
1099: colorValues[14] = d;
1100: #endif
1101: }
1102:
1.1 root 1103: void VIDEL_ConvertScreenNoZoom(int vw, int vh, int vbpp, int nextline)
1104: {
1105: int scrpitch = HostScreen_getPitch();
1.1.1.8 root 1106: int h, w, j;
1.1 root 1107:
1.1.1.8 root 1108: Uint16 *fvram = (Uint16 *) Atari2HostAddr(videl.videoBaseAddr);
1.1.1.9 root 1109: Uint16 *fvram_line;
1.1.1.2 root 1110: Uint8 *hvram = HostScreen_getVideoramAddress();
1.1.1.6 root 1111: SDL_PixelFormat *scrfmt = HostScreen_getFormat();
1.1 root 1112:
1.1.1.8 root 1113: Uint16 lowBorderSize, rightBorderSize;
1.1.1.9 root 1114: int scrwidth, scrheight;
1115: int vw_clip, vh_clip;
1.1.1.8 root 1116:
1117: int hscrolloffset = IoMem_ReadByte(0xff8265) & 0x0f;
1118:
1119: /* Horizontal scroll register set? */
1120: if (hscrolloffset) {
1121: /* Yes, so we need to adjust offset to next line: */
1122: nextline += vbpp;
1123: }
1124:
1125: /* If emulated computer is the TT, we use the same rendering for display, but without the borders */
1126: if (ConfigureParams.System.nMachineType == MACHINE_TT) {
1127: videl.leftBorderSize = 0;
1128: videl.rightBorderSize = 0;
1129: videl.upperBorderSize = 0;
1130: videl.lowerBorderSize = 0;
1131: fvram = (Uint16 *) Atari2HostAddr(VIDEL_getVideoramAddress());
1.1.1.9 root 1132: } else {
1133: bTTSampleHold = false;
1.1.1.8 root 1134: }
1.1 root 1135:
1136: /* Clip to SDL_Surface dimensions */
1.1.1.9 root 1137: scrwidth = HostScreen_getWidth();
1138: scrheight = HostScreen_getHeight();
1139: vw_clip = vw;
1140: vh_clip = vh;
1.1 root 1141: if (vw>scrwidth) vw_clip = scrwidth;
1142: if (vh>scrheight) vh_clip = scrheight;
1143:
1.1.1.8 root 1144: /* If emulated computer is the FALCON, we must take :
1145: * vw = X area display size and not all the X screen with the borders into account
1146: * vh = Y area display size and not all the Y screen with the borders into account
1147: */
1148: if (ConfigureParams.System.nMachineType == MACHINE_FALCON) {
1149: vw = videl.XSize;
1150: vh = videl.YSize;
1.1 root 1151: }
1152:
1.1.1.8 root 1153: /* If there's not enough space to display the left border, just return */
1154: if (vw_clip < videl.leftBorderSize)
1155: return;
1156: /* If there's not enough space for the left border + the graphic area, we clip */
1157: if (vw_clip < vw + videl.leftBorderSize) {
1158: vw = vw_clip - videl.leftBorderSize;
1159: rightBorderSize = 0;
1160: }
1161: /* if there's not enough space for the left border + the graphic area + the right border, we clip the border */
1162: else if (vw_clip < vw + videl.leftBorderSize + videl.rightBorderSize)
1163: rightBorderSize = vw_clip - videl.leftBorderSize - vw;
1164: else
1165: rightBorderSize = videl.rightBorderSize;
1166:
1167: /* If there's not enough space to display the upper border, just return */
1168: if (vh_clip < videl.upperBorderSize)
1169: return;
1170:
1171: /* If there's not enough space for the upper border + the graphic area, we clip */
1172: if (vh_clip < vh + videl.upperBorderSize) {
1173: vh = vh_clip - videl.upperBorderSize;
1174: lowBorderSize = 0;
1175: }
1176: /* if there's not enough space for the upper border + the graphic area + the lower border, we clip the border */
1177: else if (vh_clip < vh + videl.upperBorderSize + videl.lowerBorderSize)
1178: lowBorderSize = vh_clip - videl.upperBorderSize - vh;
1179: else
1180: lowBorderSize = videl.lowerBorderSize;
1181:
1.1 root 1182: /* Center screen */
1183: hvram += ((scrheight-vh_clip)>>1)*scrpitch;
1184: hvram += ((scrwidth-vw_clip)>>1)*HostScreen_getBpp();
1185:
1.1.1.9 root 1186: fvram_line = fvram;
1.1.1.8 root 1187: scrwidth = videl.leftBorderSize + vw + videl.rightBorderSize;
1188:
1189: /* render the graphic area */
1.1 root 1190: if (vbpp < 16) {
1191: /* Bitplanes modes */
1192:
1.1.1.8 root 1193: /* The SDL colors blitting... */
1.1.1.2 root 1194: Uint8 color[16];
1.1 root 1195:
1.1.1.8 root 1196: /* FIXME: The byte swap could be done here by enrolling the loop into 2 each by 8 pixels */
1.1 root 1197: switch ( HostScreen_getBpp() ) {
1198: case 1:
1.1.1.8 root 1199: {
1200: Uint8 *hvram_line = hvram;
1.1 root 1201:
1.1.1.8 root 1202: /* Render the upper border */
1203: for (h = 0; h < videl.upperBorderSize; h++) {
1204: VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1205: hvram_line += scrpitch;
1206: }
1.1 root 1207:
1.1.1.8 root 1208: /* Render the graphical area */
1209: for (h = 0; h < vh; h++) {
1210: Uint16 *fvram_column = fvram_line;
1211: Uint8 *hvram_column = hvram_line;
1212:
1213: /* Left border first */
1214: VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize);
1215: hvram_column += videl.leftBorderSize;
1216:
1217: /* First 16 pixels */
1218: VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
1219: memcpy(hvram_column, color+hscrolloffset, 16-hscrolloffset);
1220: hvram_column += 16-hscrolloffset;
1221: fvram_column += vbpp;
1222: /* Now the main part of the line */
1223: for (w = 1; w < (vw+15)>>4; w++) {
1224: VIDEL_bitplaneToChunky( fvram_column, vbpp, color );
1225: memcpy(hvram_column, color, 16);
1226: hvram_column += 16;
1.1 root 1227: fvram_column += vbpp;
1228: }
1.1.1.8 root 1229: /* Last pixels of the line for fine scrolling */
1230: if (hscrolloffset) {
1231: VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
1232: memcpy(hvram_column, color, hscrolloffset);
1233: }
1234: /* Right border */
1235: VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), rightBorderSize);
1236:
1.1.1.9 root 1237: if (bTTSampleHold) {
1238: Uint8 TMPPixel = 0;
1239: for (w=0; w < (vw); w++) {
1240: if (hvram_line[w] == 0) {
1241: hvram_line[w] = TMPPixel;
1242: } else {
1243: TMPPixel = hvram_line[w];
1244: }
1245: }
1246: }
1247:
1.1.1.8 root 1248: fvram_line += nextline;
1249: hvram_line += scrpitch;
1.1 root 1250: }
1.1.1.8 root 1251:
1252: /* Render the lower border */
1253: for (h = 0; h < lowBorderSize; h++) {
1254: VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1255: hvram_line += scrpitch;
1256: }
1257: }
1258: break;
1.1 root 1259: case 2:
1.1.1.8 root 1260: {
1261: Uint16 *hvram_line = (Uint16 *)hvram;
1.1 root 1262:
1.1.1.8 root 1263: /* Render the upper border */
1264: for (h = 0; h < videl.upperBorderSize; h++) {
1265: VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1266: hvram_line += scrpitch>>1;
1267: }
1.1 root 1268:
1.1.1.8 root 1269: /* Render the graphical area */
1270: for (h = 0; h < vh; h++) {
1271: Uint16 *fvram_column = fvram_line;
1272: Uint16 *hvram_column = hvram_line;
1273:
1274: /* Left border first */
1275: VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize);
1276: hvram_column += videl.leftBorderSize;
1277:
1278: /* First 16 pixels */
1279: VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
1280: for (j = 0; j < 16 - hscrolloffset; j++) {
1281: *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]);
1282: }
1283: fvram_column += vbpp;
1284: /* Now the main part of the line */
1285: for (w = 1; w < (vw+15)>>4; w++) {
1286: VIDEL_bitplaneToChunky( fvram_column, vbpp, color );
1287: for (j=0; j<16; j++) {
1288: *hvram_column++ = HostScreen_getPaletteColor( color[j] );
1.1.1.4 root 1289: }
1290: fvram_column += vbpp;
1.1.1.8 root 1291: }
1292: /* Last pixels of the line for fine scrolling */
1293: if (hscrolloffset) {
1294: VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
1295: for (j = 0; j < hscrolloffset; j++) {
1296: *hvram_column++ = HostScreen_getPaletteColor(color[j]);
1.1 root 1297: }
1298: }
1.1.1.8 root 1299: /* Right border */
1300: VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), rightBorderSize);
1301:
1302: fvram_line += nextline;
1303: hvram_line += scrpitch>>1;
1.1 root 1304: }
1.1.1.8 root 1305:
1306: /* Render the lower border */
1307: for (h = 0; h < lowBorderSize; h++) {
1308: VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1309: hvram_line += scrpitch>>1;
1310: }
1311: }
1312: break;
1.1 root 1313: case 4:
1.1.1.8 root 1314: {
1315: Uint32 *hvram_line = (Uint32 *)hvram;
1.1 root 1316:
1.1.1.8 root 1317: /* Render the upper border */
1318: for (h = 0; h < videl.upperBorderSize; h++) {
1319: VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1320: hvram_line += scrpitch>>2;
1321: }
1.1 root 1322:
1.1.1.8 root 1323: /* Render the graphical area */
1324: for (h = 0; h < vh; h++) {
1325: Uint16 *fvram_column = fvram_line;
1326: Uint32 *hvram_column = hvram_line;
1327:
1328: /* Left border first */
1329: VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize);
1330: hvram_column += videl.leftBorderSize;
1331:
1332: /* First 16 pixels */
1333: VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
1334: for (j = 0; j < 16 - hscrolloffset; j++) {
1335: *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]);
1336: }
1337: fvram_column += vbpp;
1338: /* Now the main part of the line */
1339: for (w = 1; w < (vw+15)>>4; w++) {
1340: VIDEL_bitplaneToChunky( fvram_column, vbpp, color );
1341: for (j=0; j<16; j++) {
1342: *hvram_column++ = HostScreen_getPaletteColor( color[j] );
1.1.1.4 root 1343: }
1344: fvram_column += vbpp;
1.1.1.8 root 1345: }
1346: /* Last pixels of the line for fine scrolling */
1347: if (hscrolloffset) {
1348: VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
1349: for (j = 0; j < hscrolloffset; j++) {
1350: *hvram_column++ = HostScreen_getPaletteColor(color[j]);
1.1.1.4 root 1351: }
1.1 root 1352: }
1.1.1.8 root 1353: /* Right border */
1354: VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), rightBorderSize);
1355:
1356: fvram_line += nextline;
1357: hvram_line += scrpitch>>2;
1.1 root 1358: }
1.1.1.8 root 1359:
1360: /* Render the lower border */
1361: for (h = 0; h < lowBorderSize; h++) {
1362: VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1363: hvram_line += scrpitch>>2;
1364: }
1365: }
1366: break;
1.1 root 1367: }
1368:
1369: } else {
1370:
1.1.1.8 root 1371: /* Falcon TC (High Color) */
1.1 root 1372: switch ( HostScreen_getBpp() ) {
1373: case 1:
1.1.1.8 root 1374: {
1375: /* FIXME: when Videl switches to 16bpp, set the palette to 3:3:2 */
1376: Uint8 *hvram_line = hvram;
1377:
1378: /* Render the upper border */
1379: for (h = 0; h < videl.upperBorderSize; h++) {
1380: VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1381: hvram_line += scrpitch;
1382: }
1.1 root 1383:
1.1.1.8 root 1384: /* Render the graphical area */
1385: for (h = 0; h < vh; h++) {
1386: Uint16 *fvram_column = fvram_line;
1387: Uint8 *hvram_column = hvram_line;
1388: int tmp;
1389:
1390: /* Left border first */
1391: VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize);
1392: hvram_column += videl.leftBorderSize;
1393:
1394: /* Graphical area */
1395: for (w = 0; w < vw; w++) {
1396: tmp = SDL_SwapBE16(*fvram_column++);
1397: *hvram_column++ = (((tmp>>13) & 7) << 5) + (((tmp>>8) & 7) << 2) + (((tmp>>2) & 3));
1398: }
1.1 root 1399:
1.1.1.8 root 1400: /* Right border */
1401: VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), rightBorderSize);
1.1 root 1402:
1.1.1.8 root 1403: fvram_line += nextline;
1404: hvram_line += scrpitch;
1.1 root 1405: }
1.1.1.8 root 1406: /* Render the bottom border */
1407: for (h = 0; h < lowBorderSize; h++) {
1408: VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1409: hvram_line += scrpitch;
1410: }
1411: }
1412: break;
1.1 root 1413: case 2:
1.1.1.8 root 1414: {
1415: Uint16 *hvram_line = (Uint16 *)hvram;
1416:
1417: /* Render the upper border */
1418: for (h = 0; h < videl.upperBorderSize; h++) {
1419: VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1420: hvram_line += scrpitch>>1;
1421: }
1422:
1423: /* Render the graphical area */
1424: for (h = 0; h < vh; h++) {
1425: Uint16 *hvram_column = hvram_line;
1.1.1.9 root 1426: #if SDL_BYTEORDER != SDL_BIG_ENDIAN
1427: Uint16 *fvram_column;
1428: #endif
1.1.1.8 root 1429: /* Left border first */
1430: VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize);
1431: hvram_column += videl.leftBorderSize;
1.1 root 1432:
1433: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1.1.1.8 root 1434: /* FIXME: here might be a runtime little/big video endian switch like:
1435: if ( " videocard memory in Motorola endian format " false)
1436: */
1437: memcpy(hvram_column, fvram_line, vw<<1);
1438: hvram_column += vw<<1;
1.1 root 1439: #else
1.1.1.9 root 1440: fvram_column = fvram_line;
1.1.1.8 root 1441: /* Graphical area */
1442: for (w = 0; w < vw; w++)
1443: *hvram_column ++ = SDL_SwapBE16(*fvram_column++);
1444: #endif /* SDL_BYTEORDER == SDL_BIG_ENDIAN */
1.1 root 1445:
1.1.1.8 root 1446: /* Right border */
1447: VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), rightBorderSize);
1.1 root 1448:
1.1.1.8 root 1449: fvram_line += nextline;
1450: hvram_line += scrpitch>>1;
1.1 root 1451: }
1452:
1.1.1.8 root 1453: /* Render the bottom border */
1454: for (h = 0; h < lowBorderSize; h++) {
1455: VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1456: hvram_line += scrpitch>>1;
1.1 root 1457: }
1.1.1.8 root 1458: }
1459: break;
1460: case 4:
1461: {
1462: Uint32 *hvram_line = (Uint32 *)hvram;
1.1 root 1463:
1.1.1.8 root 1464: /* Render the upper border */
1465: for (h = 0; h < videl.upperBorderSize; h++) {
1466: VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1467: hvram_line += scrpitch>>2;
1468: }
1.1 root 1469:
1.1.1.8 root 1470: /* Render the graphical area */
1471: for (h = 0; h < vh; h++) {
1472: Uint16 *fvram_column = fvram_line;
1473: Uint32 *hvram_column = hvram_line;
1474:
1475: /* Left border first */
1476: VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize);
1477: hvram_column += videl.leftBorderSize;
1478:
1479: /* Graphical area */
1480: for (w = 0; w < vw; w++) {
1481: Uint16 srcword = *fvram_column++;
1482: *hvram_column ++ = SDL_MapRGB(scrfmt, (srcword & 0xf8), (((srcword & 0x07) << 5) | ((srcword >> 11) & 0x3c)), ((srcword >> 5) & 0xf8));
1483: }
1.1 root 1484:
1.1.1.8 root 1485: /* Right border */
1486: VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), rightBorderSize);
1487: }
1.1 root 1488:
1.1.1.8 root 1489: fvram_line += nextline;
1490: hvram_line += scrpitch>>2;
1.1 root 1491:
1.1.1.8 root 1492: /* Render the bottom border */
1493: for (h = 0; h < lowBorderSize; h++) {
1494: VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1495: hvram_line += scrpitch>>2;
1496: }
1497: }
1498: break;
1499: }
1.1 root 1500: }
1501: }
1502:
1503:
1504: void VIDEL_ConvertScreenZoom(int vw, int vh, int vbpp, int nextline)
1505: {
1506: int i, j, w, h, cursrcline;
1507:
1.1.1.8 root 1508: Uint16 *fvram = (Uint16 *) Atari2HostAddr(videl.videoBaseAddr);
1509: Uint16 *fvram_line;
1510: Uint16 scrIdx = 0;
1511:
1512: int coefx = 1;
1513: int coefy = 1;
1.1.1.9 root 1514: int scrpitch, scrwidth, scrheight, scrbpp, hscrolloffset;
1515: Uint8 *hvram;
1516: SDL_PixelFormat *scrfmt;
1.1.1.8 root 1517:
1518: /* If emulated computer is the TT, we use the same rendering for display, but without the borders */
1519: if (ConfigureParams.System.nMachineType == MACHINE_TT) {
1520: videl.leftBorderSize = 0;
1521: videl.rightBorderSize = 0;
1522: videl.upperBorderSize = 0;
1523: videl.lowerBorderSize = 0;
1524: videl.XSize = vw;
1525: videl.YSize = vh;
1526: fvram = (Uint16 *) Atari2HostAddr(VIDEL_getVideoramAddress());
1.1.1.9 root 1527: } else {
1528: bTTSampleHold = false;
1.1.1.8 root 1529: }
1.1 root 1530:
1531: /* Host screen infos */
1.1.1.9 root 1532: scrpitch = HostScreen_getPitch();
1533: scrwidth = HostScreen_getWidth();
1534: scrheight = HostScreen_getHeight();
1535: scrbpp = HostScreen_getBpp();
1536: scrfmt = HostScreen_getFormat();
1537: hvram = (Uint8 *) HostScreen_getVideoramAddress();
1.1 root 1538:
1.1.1.9 root 1539: hscrolloffset = IoMem_ReadByte(0xff8265) & 0x0f;
1.1 root 1540:
1541: /* Horizontal scroll register set? */
1542: if (hscrolloffset) {
1543: /* Yes, so we need to adjust offset to next line: */
1544: nextline += vbpp;
1545: }
1546:
1547: /* Integer zoom coef ? */
1548: if (/*(bx_options.autozoom.integercoefs) &&*/ (scrwidth>=vw) && (scrheight>=vh)) {
1.1.1.8 root 1549: coefx = scrwidth/vw;
1550: coefy = scrheight/vh;
1.1 root 1551:
1552: scrwidth = vw * coefx;
1553: scrheight = vh * coefy;
1554:
1555: /* Center screen */
1556: hvram += ((HostScreen_getHeight()-scrheight)>>1)*scrpitch;
1557: hvram += ((HostScreen_getWidth()-scrwidth)>>1)*scrbpp;
1558: }
1559:
1560: /* New zoom ? */
1.1.1.8 root 1561: if ((videl_zoom.zoomwidth != vw) || (scrwidth != videl_zoom.prev_scrwidth)) {
1562: if (videl_zoom.zoomxtable) {
1563: free(videl_zoom.zoomxtable);
1.1 root 1564: }
1.1.1.8 root 1565: videl_zoom.zoomxtable = malloc(sizeof(int)*scrwidth);
1.1 root 1566: for (i=0; i<scrwidth; i++) {
1.1.1.8 root 1567: videl_zoom.zoomxtable[i] = (vw*i)/scrwidth;
1.1 root 1568: }
1.1.1.8 root 1569: videl_zoom.zoomwidth = vw;
1570: videl_zoom.prev_scrwidth = scrwidth;
1.1 root 1571: }
1.1.1.8 root 1572: if ((videl_zoom.zoomheight != vh) || (scrheight != videl_zoom.prev_scrheight)) {
1573: if (videl_zoom.zoomytable) {
1574: free(videl_zoom.zoomytable);
1.1 root 1575: }
1.1.1.8 root 1576: videl_zoom.zoomytable = malloc(sizeof(int)*scrheight);
1.1 root 1577: for (i=0; i<scrheight; i++) {
1.1.1.8 root 1578: videl_zoom.zoomytable[i] = (vh*i)/scrheight;
1.1 root 1579: }
1.1.1.8 root 1580: videl_zoom.zoomheight = vh;
1581: videl_zoom.prev_scrheight = scrheight;
1.1 root 1582: }
1583:
1584: cursrcline = -1;
1585:
1.1.1.8 root 1586: /* We reuse the following values to compute the display area size in zoom mode */
1587: /* scrwidth must not change */
1588: if (ConfigureParams.System.nMachineType == MACHINE_FALCON) {
1589: vw = videl.XSize;
1590: vh = videl.YSize;
1591: scrheight = vh * coefy;
1592: }
1593:
1.1 root 1594: if (vbpp<16) {
1.1.1.2 root 1595: Uint8 color[16];
1.1 root 1596:
1597: /* Bitplanes modes */
1598: switch(scrbpp) {
1599: case 1:
1.1.1.8 root 1600: {
1601: /* One complete 16-pixel aligned planar 2 chunky line */
1602: Uint8 *p2cline = malloc(sizeof(Uint8) * ((vw+15) & ~15));
1603: Uint8 *hvram_line = hvram;
1604: Uint8 *hvram_column = p2cline;
1605:
1606: /* Render the upper border */
1607: for (h = 0; h < videl.upperBorderSize * coefy; h++) {
1608: VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1609: hvram_line += scrpitch;
1610: }
1.1 root 1611:
1.1.1.8 root 1612: /* Render the graphical area */
1613: for (h = 0; h < scrheight; h++) {
1614:
1615: fvram_line = fvram + (videl_zoom.zoomytable[scrIdx] * nextline);
1616: scrIdx ++;
1617:
1618: /* Recopy the same line ? */
1619: if (videl_zoom.zoomytable[h] == cursrcline) {
1620: memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
1621: } else {
1622: Uint16 *fvram_column = fvram_line;
1623: hvram_column = p2cline;
1624:
1625: /* First 16 pixels of a new line */
1626: VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
1627: memcpy(hvram_column, color+hscrolloffset, 16-hscrolloffset);
1628: hvram_column += 16-hscrolloffset;
1629: fvram_column += vbpp;
1630: /* Convert main part of the new line */
1631: for (w=1; w < (vw+15)>>4; w++) {
1632: VIDEL_bitplaneToChunky( fvram_column, vbpp, color );
1633: memcpy(hvram_column, color, 16);
1634: hvram_column += 16;
1635: fvram_column += vbpp;
1636: }
1637: /* Last pixels of the line for fine scrolling */
1638: if (hscrolloffset) {
1639: VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
1640: memcpy(hvram_column, color, hscrolloffset);
1.1 root 1641: }
1642:
1.1.1.8 root 1643: hvram_column = hvram_line;
1644:
1645: /* Display the Left border */
1646: VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize * coefx);
1647: hvram_column += videl.leftBorderSize * coefx;
1648:
1649: /* Display the Graphical area */
1650: for (w=0; w<(vw*coefx); w++)
1651: hvram_column[w] = p2cline[videl_zoom.zoomxtable[w - videl.leftBorderSize * coefx]];
1652: hvram_column += vw * coefx;
1653:
1654: /* Display the Right border */
1655: VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), videl.rightBorderSize * coefx);
1656: hvram_column += videl.rightBorderSize * coefx;
1.1.1.9 root 1657:
1658: if (bTTSampleHold) {
1659: Uint8 TMPPixel = 0;
1660: for (w=0; w < (vw*coefx); w++) {
1661: if (hvram_line[w] == 0) {
1662: hvram_line[w] = TMPPixel;
1663: } else {
1664: TMPPixel = hvram_line[w];
1665: }
1666: }
1667: }
1668:
1.1 root 1669: }
1670:
1.1.1.8 root 1671: hvram_line += scrpitch;
1672: cursrcline = videl_zoom.zoomytable[h];
1.1 root 1673: }
1.1.1.8 root 1674:
1675: /* Render the lower border */
1676: for (h = 0; h < videl.lowerBorderSize * coefy; h++) {
1677: VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1678: hvram_line += scrpitch;
1679: }
1680:
1681: free(p2cline);
1682: }
1683: break;
1.1 root 1684: case 2:
1.1.1.8 root 1685: {
1686: /* One complete 16-pixel aligned planar 2 chunky line */
1687: Uint16 *p2cline = malloc(sizeof(Uint16) * ((vw+15) & ~15));
1688: Uint16 *hvram_line = (Uint16 *)hvram;
1689: Uint16 *hvram_column = p2cline;
1690:
1691: /* Render the upper border */
1692: for (h = 0; h < videl.upperBorderSize * coefy; h++) {
1693: VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1694: hvram_line += scrpitch>>1;
1695: }
1696:
1697: /* Render the graphical area */
1698: for (h = 0; h < scrheight; h++) {
1699: fvram_line = fvram + (videl_zoom.zoomytable[scrIdx] * nextline);
1700: scrIdx ++;
1701:
1702: /* Recopy the same line ? */
1703: if (videl_zoom.zoomytable[h] == cursrcline) {
1704: memcpy(hvram_line, hvram_line-(scrpitch>>1), scrwidth*scrbpp);
1705: } else {
1706: Uint16 *fvram_column = fvram_line;
1707: hvram_column = p2cline;
1708:
1709: /* First 16 pixels of a new line */
1710: VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
1711: for (j = 0; j < 16 - hscrolloffset; j++) {
1712: *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]);
1713: }
1714: fvram_column += vbpp;
1715: /* Convert the main part of the new line */
1716: for (w = 1; w < (vw+15)>>4; w++) {
1717: VIDEL_bitplaneToChunky( fvram_column, vbpp, color );
1718: for (j=0; j<16; j++) {
1719: *hvram_column++ = HostScreen_getPaletteColor( color[j] );
1.1.1.4 root 1720: }
1721: fvram_column += vbpp;
1.1.1.8 root 1722: }
1723: /* Last pixels of the new line for fine scrolling */
1724: if (hscrolloffset) {
1725: VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
1726: for (j = 0; j < hscrolloffset; j++) {
1727: *hvram_column++ = HostScreen_getPaletteColor(color[j]);
1.1 root 1728: }
1729: }
1730:
1.1.1.8 root 1731: hvram_column = hvram_line;
1732:
1733: /* Display the Left border */
1734: VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize * coefx);
1735: hvram_column += videl.leftBorderSize * coefx;
1736:
1737: /* Display the Graphical area */
1738: for (w=0; w<(vw*coefx); w++)
1739: hvram_column[w] = p2cline[videl_zoom.zoomxtable[w]];
1740: hvram_column += vw * coefx;
1741:
1742: /* Display the Right border */
1743: VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), videl.rightBorderSize * coefx);
1744: hvram_column += videl.rightBorderSize * coefx;
1.1 root 1745: }
1746:
1.1.1.8 root 1747: hvram_line += scrpitch>>1;
1748: cursrcline = videl_zoom.zoomytable[h];
1.1 root 1749: }
1.1.1.8 root 1750:
1751: /* Render the lower border */
1752: for (h = 0; h < videl.lowerBorderSize * coefy; h++) {
1753: VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1754: hvram_line += scrpitch>>1;
1755: }
1756:
1757: free(p2cline);
1758: }
1759: break;
1.1 root 1760: case 4:
1.1.1.8 root 1761: {
1762: /* One complete 16-pixel aligned planar 2 chunky line */
1763: Uint32 *p2cline = malloc(sizeof(Uint32) * ((vw+15) & ~15));
1764: Uint32 *hvram_line = (Uint32 *)hvram;
1765: Uint32 *hvram_column = p2cline;
1766:
1767: /* Render the upper border */
1768: for (h = 0; h < videl.upperBorderSize * coefy; h++) {
1769: VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1770: hvram_line += scrpitch>>2;
1771: }
1772:
1773: /* Render the graphical area */
1774: for (h = 0; h < scrheight; h++) {
1775: fvram_line = fvram + (videl_zoom.zoomytable[scrIdx] * nextline);
1776: scrIdx ++;
1777: /* Recopy the same line ? */
1778: if (videl_zoom.zoomytable[h] == cursrcline) {
1779: memcpy(hvram_line, hvram_line-(scrpitch>>2), scrwidth*scrbpp);
1780: } else {
1781: Uint16 *fvram_column = fvram_line;
1782: hvram_column = p2cline;
1783:
1784: /* First 16 pixels of a new line */
1785: VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
1786: for (j = 0; j < 16 - hscrolloffset; j++) {
1787: *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]);
1788: }
1789: fvram_column += vbpp;
1790: /* Convert the main part of the new line */
1791: for (w = 1; w < (vw+15)>>4; w++) {
1792: VIDEL_bitplaneToChunky( fvram_column, vbpp, color );
1793: for (j=0; j<16; j++) {
1794: *hvram_column++ = HostScreen_getPaletteColor( color[j] );
1.1.1.4 root 1795: }
1796: fvram_column += vbpp;
1.1.1.8 root 1797: }
1798: /* Last pixels of the new line for fine scrolling */
1799: if (hscrolloffset) {
1800: VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
1801: for (j = 0; j < hscrolloffset; j++) {
1802: *hvram_column++ = HostScreen_getPaletteColor(color[j]);
1.1.1.4 root 1803: }
1.1.1.8 root 1804: }
1.1.1.4 root 1805:
1.1.1.8 root 1806: hvram_column = hvram_line;
1807: /* Display the Left border */
1808: VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize * coefx);
1809: hvram_column += videl.leftBorderSize * coefx;
1810:
1811: /* Display the Graphical area */
1812: for (w=0; w<(vw*coefx); w++) {
1813: hvram_column[w] = p2cline[videl_zoom.zoomxtable[w]];
1.1 root 1814: }
1.1.1.8 root 1815: hvram_column += vw * coefx;
1.1 root 1816:
1.1.1.8 root 1817: /* Display the Right border */
1818: VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), videl.rightBorderSize * coefx);
1819: hvram_column += videl.rightBorderSize * coefx;
1.1 root 1820: }
1821:
1.1.1.8 root 1822: hvram_line += scrpitch>>2;
1823: cursrcline = videl_zoom.zoomytable[h];
1.1 root 1824: }
1.1.1.8 root 1825:
1826: /* Render the lower border */
1827: for (h = 0; h < videl.lowerBorderSize * coefy; h++) {
1828: VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1829: hvram_line += scrpitch>>2;
1830: }
1831:
1832: free(p2cline);
1833: }
1834: break;
1.1 root 1835: }
1836: } else {
1.1.1.4 root 1837: /* Falcon high-color (16-bit) mode */
1.1 root 1838:
1839: switch(scrbpp) {
1840: case 1:
1.1.1.8 root 1841: {
1842: /* FIXME: when Videl switches to 16bpp, set the palette to 3:3:2 */
1843: Uint8 *hvram_line = hvram;
1844: Uint8 *hvram_column = hvram_line;
1845:
1846: /* Render the upper border */
1847: for (h = 0; h < videl.upperBorderSize * coefy; h++) {
1848: VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1849: hvram_line += scrpitch;
1850: }
1.1 root 1851:
1.1.1.8 root 1852: /* Render the graphical area */
1853: for (h = 0; h < scrheight; h++) {
1854: Uint16 *fvram_column;
1855:
1856: fvram_line = fvram + (videl_zoom.zoomytable[scrIdx] * nextline);
1857: scrIdx ++;
1858:
1859: fvram_column = fvram_line;
1860:
1861: /* Recopy the same line ? */
1862: if (videl_zoom.zoomytable[h] == cursrcline) {
1863: memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
1864: } else {
1.1 root 1865:
1.1.1.8 root 1866: hvram_column = hvram_line;
1867: /* Display the Left border */
1868: VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize * coefx);
1869: hvram_column += videl.leftBorderSize * coefx;
1870:
1871: /* Display the Graphical area */
1872: for (w = 0; w<(vw*coefx); w++) {
1873: Uint16 srcword;
1874: Uint8 dstbyte;
1.1 root 1875:
1.1.1.8 root 1876: srcword = SDL_SwapBE16(fvram_column[videl_zoom.zoomxtable[w - videl.leftBorderSize * coefx]]);
1.1 root 1877:
1.1.1.8 root 1878: dstbyte = ((srcword>>13) & 7) << 5;
1879: dstbyte |= ((srcword>>8) & 7) << 2;
1880: dstbyte |= ((srcword>>2) & 3);
1881: *hvram_column++ = dstbyte;
1.1 root 1882: }
1883:
1.1.1.8 root 1884: /* Display the Right border */
1885: VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), videl.rightBorderSize * coefx);
1886: hvram_column += videl.rightBorderSize * coefx;
1.1 root 1887: }
1.1.1.8 root 1888:
1889: hvram_line += scrpitch;
1890: cursrcline = videl_zoom.zoomytable[h];
1.1 root 1891: }
1.1.1.8 root 1892:
1893: /* Render the lower border */
1894: for (h = 0; h < videl.lowerBorderSize * coefy; h++) {
1895: VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1896: hvram_line += scrpitch;
1897: }
1898: }
1899: break;
1.1 root 1900: case 2:
1.1.1.8 root 1901: {
1902: Uint16 *hvram_line = (Uint16 *)hvram;
1903: Uint16 *hvram_column = hvram_line;
1904:
1905: /* Render the upper border */
1906: for (h = 0; h < videl.upperBorderSize * coefy; h++) {
1907: VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1908: hvram_line += scrpitch>>1;
1909: }
1910:
1911: /* Render the graphical area */
1912: for (h = 0; h < scrheight; h++) {
1913: Uint16 *fvram_column;
1914:
1915: fvram_line = fvram + (videl_zoom.zoomytable[scrIdx] * nextline);
1916: scrIdx ++;
1917:
1918: fvram_column = fvram_line;
1919:
1920: /* Recopy the same line ? */
1921: if (videl_zoom.zoomytable[h] == cursrcline) {
1922: memcpy(hvram_line, hvram_line-(scrpitch>>1), scrwidth*scrbpp);
1923: } else {
1.1 root 1924:
1925: hvram_column = hvram_line;
1926:
1.1.1.8 root 1927: /* Display the Left border */
1928: VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize * coefx);
1929: hvram_column += videl.leftBorderSize * coefx;
1930:
1931: /* Display the Graphical area */
1932: for (w=0; w<(vw*coefx); w++)
1933: *hvram_column++ = SDL_SwapBE16(fvram_column[videl_zoom.zoomxtable[w]]);
1934:
1.1 root 1935:
1.1.1.8 root 1936: /* Display the Right border */
1937: VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), videl.rightBorderSize * coefx);
1938: hvram_column += videl.rightBorderSize * coefx;
1.1 root 1939: }
1.1.1.8 root 1940:
1941: hvram_line += scrpitch>>1;
1942: cursrcline = videl_zoom.zoomytable[h];
1.1 root 1943: }
1.1.1.8 root 1944:
1945: /* Render the lower border */
1946: for (h = 0; h < videl.lowerBorderSize * coefy; h++) {
1947: VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1948: hvram_line += scrpitch>>1;
1949: }
1950: }
1951: break;
1.1 root 1952: case 4:
1.1.1.8 root 1953: {
1954: Uint32 *hvram_line = (Uint32 *)hvram;
1955: Uint32 *hvram_column = hvram_line;
1956:
1957: /* Render the upper border */
1958: for (h = 0; h < videl.upperBorderSize * coefy; h++) {
1959: VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
1960: }
1961:
1962: /* Render the graphical area */
1963: for (h = 0; h < scrheight; h++) {
1964: Uint16 *fvram_column;
1965:
1966: fvram_line = fvram + (videl_zoom.zoomytable[scrIdx] * nextline);
1967: scrIdx ++;
1968: fvram_column = fvram_line;
1969:
1970: /* Recopy the same line ? */
1971: if (videl_zoom.zoomytable[h] == cursrcline) {
1972: memcpy(hvram_line, hvram_line-(scrpitch>>2), scrwidth*scrbpp);
1973: hvram_line += scrpitch>>2;
1974: } else {
1.1 root 1975:
1976: hvram_column = hvram_line;
1977:
1.1.1.8 root 1978: /* Display the Left border */
1979: VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize * coefx);
1980: hvram_column += videl.leftBorderSize * coefx;
1981:
1982: /* Display the Graphical area */
1983: for (w = 0; w<(vw*coefx); w++) {
1984: Uint16 srcword;
1.1 root 1985:
1.1.1.8 root 1986: srcword = fvram_column[videl_zoom.zoomxtable[w]];
1987: *hvram_column++ = SDL_MapRGB(scrfmt, (srcword & 0xf8), (((srcword & 0x07) << 5) | ((srcword >> 11) & 0x3c)), ((srcword >> 5) & 0xf8));
1.1 root 1988: }
1989:
1.1.1.8 root 1990: /* Display the Right border */
1991: VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), videl.rightBorderSize * coefx);
1992: hvram_column += videl.rightBorderSize * coefx;
1.1 root 1993: }
1.1.1.8 root 1994:
1995: hvram_line += scrpitch>>2;
1996: cursrcline = videl_zoom.zoomytable[h];
1.1 root 1997: }
1.1.1.8 root 1998:
1999: /* Render the lower border */
2000: for (h = 0; h < videl.lowerBorderSize * coefy; h++) {
2001: VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
2002: hvram_line += scrpitch>>2;
2003: }
2004: }
2005: break;
1.1 root 2006: }
2007: }
2008: }
1.1.1.8 root 2009:
2010: static void VIDEL_memset_uint32(Uint32 *addr, Uint32 color, int count)
2011: {
2012: while (count-- > 0) {
2013: *addr++ = color;
2014: }
2015: }
2016:
2017: static void VIDEL_memset_uint16(Uint16 *addr, Uint16 color, int count)
2018: {
2019: while (count-- > 0) {
2020: *addr++ = color;
2021: }
2022: }
2023:
2024: static void VIDEL_memset_uint8(Uint8 *addr, Uint8 color, int count)
2025: {
2026: memset(addr, color, count);
2027: }
1.1.1.10! root 2028:
! 2029:
! 2030:
! 2031: /**
! 2032: * Write to videl ST palette registers (0xff8240-0xff825e)
! 2033: *
! 2034: * [Laurent]: The following note should be verified on Falcon before being applied.
! 2035: *
! 2036: * Note that there's a special "strange" case when writing only to the upper byte
! 2037: * of the color reg (instead of writing 16 bits at once with .W/.L).
! 2038: * In that case, the byte written to address x is automatically written
! 2039: * to address x+1 too (but we shouldn't copy x in x+1 after masking x ; we apply the mask at the end)
! 2040: * Similarly, when writing a byte to address x+1, it's also written to address x
! 2041: * So : move.w #0,$ff8240 -> color 0 is now $000
! 2042: * move.b #7,$ff8240 -> color 0 is now $707 !
! 2043: * move.b #$55,$ff8241 -> color 0 is now $555 !
! 2044: * move.b #$71,$ff8240 -> color 0 is now $171 (bytes are first copied, then masked)
! 2045: */
! 2046: void Videl_ColorReg_WriteWord(void)
! 2047: {
! 2048: Uint16 col;
! 2049: Uint32 addr = IoAccessCurrentAddress;
! 2050:
! 2051: videl.hostColorsSync = false;
! 2052:
! 2053: if (bUseHighRes || bUseVDIRes) /* Don't store if hi-res or VDI resolution */
! 2054: return;
! 2055:
! 2056: /* Note from laurent: The following special case should be verified on the real Falcon before uncommenting */
! 2057: /* Handle special case when writing only to the upper byte of the color reg */
! 2058: // if ( ( nIoMemAccessSize == SIZE_BYTE ) && ( ( IoAccessCurrentAddress & 1 ) == 0 ) )
! 2059: // col = ( IoMem_ReadByte(addr) << 8 ) + IoMem_ReadByte(addr); /* copy upper byte into lower byte */
! 2060: /* Same when writing only to the lower byte of the color reg */
! 2061: // else if ( ( nIoMemAccessSize == SIZE_BYTE ) && ( ( IoAccessCurrentAddress & 1 ) == 1 ) )
! 2062: // col = ( IoMem_ReadByte(addr) << 8 ) + IoMem_ReadByte(addr); /* copy lower byte into upper byte */
! 2063: /* Usual case, writing a word or a long (2 words) */
! 2064: // else
! 2065: col = IoMem_ReadWord(addr);
! 2066:
! 2067: col &= 0xfff; /* Mask off to 4096 palette */
! 2068:
! 2069: addr &= 0xfffffffe; /* Ensure addr is even to store the 16 bit color */
! 2070:
! 2071: IoMem_WriteWord(addr, col);
! 2072: }
! 2073:
! 2074: /*
! 2075: * [NP] TODO : due to how .L accesses are handled in ioMem.c, we can't call directly
! 2076: * Video_ColorReg_WriteWord from ioMemTabFalcon.c, we must use an intermediate
! 2077: * function, else .L accesses will not change 2 .W color regs, but only one.
! 2078: * This should be changed in ioMem.c to do 2 separate .W accesses, as would do a real 68000
! 2079: */
! 2080:
! 2081: void Videl_Color0_WriteWord(void)
! 2082: {
! 2083: Videl_ColorReg_WriteWord();
! 2084: }
! 2085:
! 2086: void Videl_Color1_WriteWord(void)
! 2087: {
! 2088: Videl_ColorReg_WriteWord();
! 2089: }
! 2090:
! 2091: void Videl_Color2_WriteWord(void)
! 2092: {
! 2093: Videl_ColorReg_WriteWord();
! 2094: }
! 2095:
! 2096: void Videl_Color3_WriteWord(void)
! 2097: {
! 2098: Videl_ColorReg_WriteWord();
! 2099: }
! 2100:
! 2101: void Videl_Color4_WriteWord(void)
! 2102: {
! 2103: Videl_ColorReg_WriteWord();
! 2104: }
! 2105:
! 2106: void Videl_Color5_WriteWord(void)
! 2107: {
! 2108: Videl_ColorReg_WriteWord();
! 2109: }
! 2110:
! 2111: void Videl_Color6_WriteWord(void)
! 2112: {
! 2113: Videl_ColorReg_WriteWord();
! 2114: }
! 2115:
! 2116: void Videl_Color7_WriteWord(void)
! 2117: {
! 2118: Videl_ColorReg_WriteWord();
! 2119: }
! 2120:
! 2121: void Videl_Color8_WriteWord(void)
! 2122: {
! 2123: Videl_ColorReg_WriteWord();
! 2124: }
! 2125:
! 2126: void Videl_Color9_WriteWord(void)
! 2127: {
! 2128: Videl_ColorReg_WriteWord();
! 2129: }
! 2130:
! 2131: void Videl_Color10_WriteWord(void)
! 2132: {
! 2133: Videl_ColorReg_WriteWord();
! 2134: }
! 2135:
! 2136: void Videl_Color11_WriteWord(void)
! 2137: {
! 2138: Videl_ColorReg_WriteWord();
! 2139: }
! 2140:
! 2141: void Videl_Color12_WriteWord(void)
! 2142: {
! 2143: Videl_ColorReg_WriteWord();
! 2144: }
! 2145:
! 2146: void Videl_Color13_WriteWord(void)
! 2147: {
! 2148: Videl_ColorReg_WriteWord();
! 2149: }
! 2150:
! 2151: void Videl_Color14_WriteWord(void)
! 2152: {
! 2153: Videl_ColorReg_WriteWord();
! 2154: }
! 2155:
! 2156: void Videl_Color15_WriteWord(void)
! 2157: {
! 2158: Videl_ColorReg_WriteWord();
! 2159: }
! 2160:
! 2161: /**
! 2162: * display Videl registers values (for debugger info command)
! 2163: */
! 2164: void Videl_Info(Uint32 dummy)
! 2165: {
! 2166: if (ConfigureParams.System.nMachineType != MACHINE_FALCON) {
! 2167: fprintf(stderr, "Not Falcon - no Videl!\n");
! 2168: return;
! 2169: }
! 2170:
! 2171: fprintf(stderr, "$FF8006.b : monitor type : %02x\n", IoMem_ReadByte(0xff8006));
! 2172: fprintf(stderr, "$FF8201.b : Video Base Hi : %02x\n", IoMem_ReadByte(0xff8201));
! 2173: fprintf(stderr, "$FF8203.b : Video Base Mi : %02x\n", IoMem_ReadByte(0xff8203));
! 2174: fprintf(stderr, "$FF8205.b : Video Count Hi : %02x\n", IoMem_ReadByte(0xff8205));
! 2175: fprintf(stderr, "$FF8207.b : Video Count Mi : %02x\n", IoMem_ReadByte(0xff8207));
! 2176: fprintf(stderr, "$FF8209.b : Video Count Lo : %02x\n", IoMem_ReadByte(0xff8209));
! 2177: fprintf(stderr, "$FF820A.b : Sync mode : %02x\n", IoMem_ReadByte(0xff820a));
! 2178: fprintf(stderr, "$FF820D.b : Video Base Lo : %02x\n", IoMem_ReadByte(0xff820d));
! 2179: fprintf(stderr, "$FF820E.w : offset to next line : %04x\n", IoMem_ReadWord(0xff820e));
! 2180: fprintf(stderr, "$FF8210.w : VWRAP - line width : %04x\n", IoMem_ReadWord(0xff8210));
! 2181: fprintf(stderr, "$FF8260.b : ST shift mode : %02x\n", IoMem_ReadByte(0xff8260));
! 2182: fprintf(stderr, "$FF8264.w : Horizontal scroll register : %04x\n", IoMem_ReadWord(0xff8264));
! 2183: fprintf(stderr, "$FF8266.w : Falcon shift mode : %04x\n", IoMem_ReadWord(0xff8266));
! 2184: fprintf(stderr, "\n");
! 2185: fprintf(stderr, "$FF8280.w : HHC - Horizontal Hold Counter : %04x\n", IoMem_ReadWord(0xff8280));
! 2186: fprintf(stderr, "$FF8282.w : HHT - Horizontal Hold Timer : %04x\n", IoMem_ReadWord(0xff8282));
! 2187: fprintf(stderr, "$FF8284.w : HBB - Horizontal Border Begin : %04x\n", IoMem_ReadWord(0xff8284));
! 2188: fprintf(stderr, "$FF8286.w : HBE - Horizontal Border End : %04x\n", IoMem_ReadWord(0xff8286));
! 2189: fprintf(stderr, "$FF8288.w : HDB - Horizontal Display Begin : %04x\n", IoMem_ReadWord(0xff8288));
! 2190: fprintf(stderr, "$FF828A.w : HDE - Horizontal Display End : %04x\n", IoMem_ReadWord(0xff828a));
! 2191: fprintf(stderr, "$FF828C.w : HSS - Horizontal SS : %04x\n", IoMem_ReadWord(0xff828c));
! 2192: fprintf(stderr, "$FF828E.w : HFS - Horizontal FS : %04x\n", IoMem_ReadWord(0xff828e));
! 2193: fprintf(stderr, "$FF8290.w : HEE - Horizontal EE : %04x\n", IoMem_ReadWord(0xff8290));
! 2194: fprintf(stderr, "\n");
! 2195: fprintf(stderr, "$FF82A0.w : VFC - Vertical Frequency Counter : %04x\n", IoMem_ReadWord(0xff82a0));
! 2196: fprintf(stderr, "$FF82A2.w : VFT - Vertical Frequency Timer : %04x\n", IoMem_ReadWord(0xff82a2));
! 2197: fprintf(stderr, "$FF82A4.w : VBB - Vertical Border Begin : %04x\n", IoMem_ReadWord(0xff82a4));
! 2198: fprintf(stderr, "$FF82A6.w : VBE - Vertical Border End : %04x\n", IoMem_ReadWord(0xff82a6));
! 2199: fprintf(stderr, "$FF82A8.w : VDB - Vertical Display Begin : %04x\n", IoMem_ReadWord(0xff82a8));
! 2200: fprintf(stderr, "$FF82AA.w : VDE - Vertical Display End : %04x\n", IoMem_ReadWord(0xff82aa));
! 2201: fprintf(stderr, "$FF82AC.w : VSS - Vertical SS : %04x\n", IoMem_ReadWord(0xff82ac));
! 2202: fprintf(stderr, "\n");
! 2203: fprintf(stderr, "$FF82C0.w : VCO - Video control : %04x\n", IoMem_ReadWord(0xff82c0));
! 2204: fprintf(stderr, "$FF82C2.w : VMD - Video mode : %04x\n", IoMem_ReadWord(0xff82c2));
! 2205: fprintf(stderr, "\n-------------------------\n");
! 2206:
! 2207: fprintf(stderr, "Video base : %08x\n",
! 2208: (IoMem_ReadByte(0xff8201)<<16) +
! 2209: (IoMem_ReadByte(0xff8203)<<8) +
! 2210: IoMem_ReadByte(0xff820d));
! 2211: fprintf(stderr, "Video count : %08x\n",
! 2212: (IoMem_ReadByte(0xff8205)<<16) +
! 2213: (IoMem_ReadByte(0xff8207)<<8) +
! 2214: IoMem_ReadByte(0xff8209));
! 2215: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.