|
|
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
1.1.1.12 root 16:
1.1.1.6 root 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
1.1.1.12 root 30:
1.1.1.6 root 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
1.1.1.12 root 39:
1.1.1.6 root 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
1.1.1.12 root 49:
1.1.1.6 root 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
1.1.1.12 root 57:
1.1.1.6 root 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:
68: #include "main.h"
69: #include "configuration.h"
1.1.1.6 root 70: #include "memorySnapShot.h"
1.1 root 71: #include "ioMem.h"
1.1.1.6 root 72: #include "log.h"
1.1 root 73: #include "screen.h"
1.1.1.12 root 74: #include "screenConvert.h"
1.1.1.13! root 75: #include "avi_record.h"
1.1.1.12 root 76: #include "statusbar.h"
1.1 root 77: #include "stMemory.h"
78: #include "videl.h"
1.1.1.13! root 79: #include "video.h" /* for bUseHighRes variable */
! 80: #include "vdi.h" /* for bUseVDIRes variable */
1.1 root 81:
82: #define VIDEL_COLOR_REGS_BEGIN 0xff9800
83:
1.1.1.8 root 84:
1.1.1.6 root 85: struct videl_s {
86: Uint8 reg_ffff8006_save; /* save reg_ffff8006 as it's a read only register */
87: Uint8 monitor_type; /* 00 Monochrome (SM124) / 01 Color (SC1224) / 10 VGA Color / 11 Television ($FFFF8006) */
1.1.1.13! root 88:
! 89: Uint16 vertFreqCounter; /* Counter for VFC register $ff82a0, restarted on each VBL */
! 90: Uint32 videoRaster; /* Video raster offset, restarted on 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 */
1.1.1.13! root 104: bool bUseSTShifter; /* whether to use ST or Falcon palette */
1.1.1.8 root 105: };
1.1.1.6 root 106:
1.1.1.8 root 107: static struct videl_s videl;
1.1.1.6 root 108:
109:
1.1.1.12 root 110: /**
111: * Called upon startup (and via VIDEL_reset())
112: */
113: void Videl_Init(void)
114: {
115: videl.hostColorsSync = false;
1.1.1.10 root 116:
1.1.1.12 root 117: /* Default resolution to boot with */
118: videl.save_scrWidth = 640;
119: videl.save_scrHeight = 480;
120: videl.save_scrBpp = 4;
121: }
1.1 root 122:
1.1.1.8 root 123: /**
1.1.1.12 root 124: * Called when CPU encounters a RESET instruction.
1.1.1.8 root 125: */
1.1 root 126: void VIDEL_reset(void)
127: {
1.1.1.12 root 128: Videl_Init();
129: Screen_SetGenConvSize(videl.save_scrWidth, videl.save_scrHeight,
130: ConfigureParams.Screen.nForceBpp, false);
131:
1.1.1.6 root 132: videl.bUseSTShifter = false; /* Use Falcon color palette by default */
133: videl.reg_ffff8006_save = IoMem_ReadByte(0xff8006);
1.1.1.8 root 134: videl.monitor_type = videl.reg_ffff8006_save & 0xc0;
1.1 root 135:
1.1.1.13! root 136: VIDEL_RestartVideoCounter();
1.1.1.4 root 137:
138: /* Reset IO register (some are not initialized by TOS) */
139: IoMem_WriteWord(0xff820e, 0); /* Line offset */
140: IoMem_WriteWord(0xff8264, 0); /* Horizontal scroll */
1.1.1.8 root 141:
1.1.1.12 root 142: /* Init sync mode register */
143: VIDEL_SyncMode_WriteByte();
1.1 root 144: }
145:
1.1.1.6 root 146: /**
147: * Save/Restore snapshot of local variables ('MemorySnapShot_Store' handles type)
148: */
149: void VIDEL_MemorySnapShot_Capture(bool bSave)
150: {
151: /* Save/Restore details */
152: MemorySnapShot_Store(&videl, sizeof(videl));
153: }
154:
155: /**
1.1.1.10 root 156: * Monitor write access to Falcon color palette registers
1.1.1.6 root 157: */
1.1.1.10 root 158: void VIDEL_FalconColorRegsWrite(void)
1.1 root 159: {
1.1.1.10 root 160: uint32_t color = IoMem_ReadLong(IoAccessBaseAddress & ~3);
161: color &= 0xfcfc00fc; /* Unused bits have to be set to 0 */
162: IoMem_WriteLong(IoAccessBaseAddress & ~3, color);
1.1.1.8 root 163: videl.hostColorsSync = false;
1.1 root 164: }
165:
1.1.1.6 root 166: /**
1.1.1.12 root 167: * VIDEL_Monitor_WriteByte : Contains memory and monitor configuration.
1.1.1.8 root 168: * This register is read only.
1.1.1.6 root 169: */
170: void VIDEL_Monitor_WriteByte(void)
171: {
1.1.1.8 root 172: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8006 Monitor and memory conf write (Read only)\n");
1.1.1.6 root 173: /* Restore hardware value */
1.1.1.8 root 174:
1.1.1.6 root 175: IoMem_WriteByte(0xff8006, videl.reg_ffff8006_save);
176: }
177:
178: /**
1.1.1.12 root 179: * VIDEL_SyncMode_WriteByte : Videl synchronization mode.
1.1.1.8 root 180: * $FFFF820A [R/W] _______0 .................................. SYNC-MODE
181: ||
182: |+--Synchronisation [ 0:internal / 1:external ]
183: +---Vertical frequency [ Read-only bit ]
184: [ Monochrome monitor:0 / Colour monitor:1 ]
185: */
186: void VIDEL_SyncMode_WriteByte(void)
187: {
188: Uint8 syncMode = IoMem_ReadByte(0xff820a);
189: LOG_TRACE(TRACE_VIDEL, "Videl : $ff820a Sync Mode write: 0x%02x\n", syncMode);
190:
191: if (videl.monitor_type == FALCON_MONITOR_MONO)
192: syncMode &= 0xfd;
193: else
194: syncMode |= 0x2;
1.1.1.12 root 195:
1.1.1.8 root 196: IoMem_WriteByte(0xff820a, syncMode);
197: }
198:
199: /**
200: * Read video address counter and update ff8205/07/09
201: */
202: void VIDEL_ScreenCounter_ReadByte(void)
203: {
1.1.1.13! root 204: Uint32 addr = videl.videoRaster;
1.1.1.8 root 205: IoMem[0xff8205] = ( addr >> 16 ) & 0xff;
206: IoMem[0xff8207] = ( addr >> 8 ) & 0xff;
207: IoMem[0xff8209] = addr & 0xff;
208:
209: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8205/07/09 Sync Mode read: 0x%08x\n", addr);
210: }
211:
212: /**
213: * Write video address counter
214: */
215: void VIDEL_ScreenCounter_WriteByte(void)
216: {
1.1.1.13! root 217: Uint32 addr_new = videl.videoRaster;
! 218: Uint8 AddrByte = IoMem[ IoAccessCurrentAddress ];
1.1.1.8 root 219:
220: /* Compute the new video address with one modified byte */
221: if ( IoAccessCurrentAddress == 0xff8205 )
222: addr_new = ( addr_new & 0x00ffff ) | ( AddrByte << 16 );
223: else if ( IoAccessCurrentAddress == 0xff8207 )
224: addr_new = ( addr_new & 0xff00ff ) | ( AddrByte << 8 );
225: else if ( IoAccessCurrentAddress == 0xff8209 )
226: addr_new = ( addr_new & 0xffff00 ) | ( AddrByte );
227:
1.1.1.13! root 228: videl.videoRaster = addr_new;
! 229: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8205/07/09 Sync Mode write: 0x%08x\n", addr_new);
! 230: }
! 231:
! 232: /**
! 233: * VIDEL_LineOffset_ReadWord: $FFFF820E [R/W] W _______876543210 Line Offset
! 234: * How many words are added to the end of display line, i.e. how many words are
! 235: * 'behind' the display.
! 236: */
! 237: void VIDEL_LineOffset_ReadWord(void)
! 238: {
! 239: /* Unused bits in the first byte are read as zero, so mask them */
! 240: IoMem[0xff820e] &= 0x01;
1.1.1.8 root 241: }
242:
243: /**
244: * VIDEL_LineOffset_WriteWord: $FFFF820E [R/W] W _______876543210 Line Offset
245: * How many words are added to the end of display line, i.e. how many words are
246: * 'behind' the display.
247: */
248: void VIDEL_LineOffset_WriteWord(void)
249: {
1.1.1.9 root 250: LOG_TRACE(TRACE_VIDEL, "Videl : $ff820e Line Offset write: 0x%04x\n",
251: IoMem_ReadWord(0xff820e));
1.1.1.8 root 252: }
253:
254: /**
255: * VIDEL_Line_Width_WriteWord: $FFFF8210 [R/W] W ______9876543210 Line Width (VWRAP)
256: * Length of display line in words.Or, how many words should be added to
257: * vram counter after every display line.
258: */
259: void VIDEL_Line_Width_WriteWord(void)
260: {
1.1.1.9 root 261: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8210 Line Width write: 0x%04x\n",
262: IoMem_ReadWord(0xff8210));
1.1.1.8 root 263: }
264:
265: /**
1.1.1.6 root 266: * Write to video address base high, med and low register (0xff8201/03/0d).
267: * On Falcon, when a program writes to high or med registers, base low register
268: * is reset to zero.
269: */
270: void VIDEL_ScreenBase_WriteByte(void)
271: {
272: if ((IoAccessCurrentAddress == 0xff8201) || (IoAccessCurrentAddress == 0xff8203)) {
273: /* Reset screen base low register */
274: IoMem[0xff820d] = 0;
275: }
276:
1.1.1.9 root 277: LOG_TRACE(TRACE_VIDEL, "Videl : $%04x Screen base write: 0x%02x\t (screen: 0x%04x)\n",
278: IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress],
279: (IoMem[0xff8201]<<16) + (IoMem[0xff8203]<<8) + IoMem[0xff820d]);
1.1.1.6 root 280: }
281:
282: /**
1.1.1.12 root 283: VIDEL_ST_ShiftModeWriteByte :
1.1.1.6 root 284: $FFFF8260 [R/W] B ______10 ST Shift Mode
285: ||
286: || others vga
287: || $FF8210 $FF82C2 $FF82C2
288: 00--4BP/320 Pixels=> $0050 $0000 $0005
289: 01--2BP/640 Pixels=> $0050 $0004 $0009
290: 10--1BP/640 Pixels=> $0028 $0006 $0008
291: 11--???/320 Pixels=> $0050 $0000 $0000
292:
293: Writing to this register does the following things:
294: - activate STE palette
295: - sets line width ($ffff8210)
296: - sets video mode in $ffff82c2 (double lines/interlace & cycles/pixel)
297: */
298: void VIDEL_ST_ShiftModeWriteByte(void)
299: {
300: Uint16 line_width, video_mode;
301: Uint8 st_shiftMode;
302:
303: st_shiftMode = IoMem_ReadByte(0xff8260);
1.1.1.8 root 304: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8260 ST Shift Mode (STSHIFT) write: 0x%02x\n", st_shiftMode);
305:
306: /* Bits 2-7 are set to 0 */
1.1.1.12 root 307: IoMem_WriteByte(0xff8260, st_shiftMode & 3);
1.1.1.6 root 308:
309: /* Activate STE palette */
310: videl.bUseSTShifter = true;
311:
312: /* Compute line width and video mode */
313: switch (st_shiftMode & 0x3) {
314: case 0: /* 4BP/320 Pixels */
315: line_width = 0x50;
316: /* half pixels + double lines vs. no scaling */
317: video_mode = videl.monitor_type == FALCON_MONITOR_VGA ? 0x5 : 0x0;
318: break;
319: case 1: /* 2BP/640 Pixels */
320: line_width = 0x50;
321: /* quarter pixels + double lines vs. half pixels */
322: video_mode = videl.monitor_type == FALCON_MONITOR_VGA ? 0x9 : 0x4;
323: break;
324: case 2: /* 1BP/640 Pixels */
325: line_width = 0x28;
326: if (videl.monitor_type == FALCON_MONITOR_MONO) {
327: video_mode = 0x0;
328: break;
329: }
330: /* quarter pixels vs. half pixels + interlace */
331: video_mode = videl.monitor_type == FALCON_MONITOR_VGA ? 0x8 : 0x6;
332: break;
333: case 3: /* ???/320 Pixels */
1.1.1.8 root 334: default:
1.1.1.6 root 335: line_width = 0x50;
336: video_mode = 0x0;
337: break;
338: }
339:
340: /* Set line width ($FFFF8210) */
1.1.1.12 root 341: IoMem_WriteWord(0xff8210, line_width);
342:
1.1.1.6 root 343: /* Set video mode ($FFFF82C2) */
1.1.1.12 root 344: IoMem_WriteWord(0xff82c2, video_mode);
1.1.1.6 root 345: }
346:
347: /**
1.1.1.8 root 348: VIDEL_HorScroll64_WriteByte : Horizontal scroll register (0-15)
349: $FFFF8264 [R/W] ________ ................................ H-SCROLL HI
350: |||| [ Shadow register for $FFFF8265 ]
351: ++++--Pixel shift [ 0:normal / 1..15:Left shift ]
352: [ Change in line-width NOT required ]
353: */
354: void VIDEL_HorScroll64_WriteByte(void)
355: {
1.1.1.9 root 356: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8264 Horizontal scroll 64 write: 0x%02x\n",
357: IoMem_ReadByte(0xff8264));
1.1.1.8 root 358: }
359:
360: /**
361: VIDEL_HorScroll65_WriteByte : Horizontal scroll register (0-15)
362: $FFFF8265 [R/W] ____3210 .................................H-SCROLL LO
363: ||||
364: ++++--Pixel [ 0:normal / 1..15:Left shift ]
365: [ Change in line-width NOT required ]
366: */
367: void VIDEL_HorScroll65_WriteByte(void)
368: {
1.1.1.9 root 369: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8265 Horizontal scroll 65 write: 0x%02x\n",
370: IoMem_ReadByte(0xff8265));
1.1.1.8 root 371: }
372:
373: /**
374: VIDEL_Falcon_ShiftMode_WriteWord :
1.1.1.6 root 375: $FFFF8266 [R/W] W _____A98_6543210 Falcon Shift Mode (SPSHIFT)
376: ||| |||||||
1.1.1.8 root 377: ||| |||++++- 0..15: Colourbank choice from 256-colour table in 16 colour multiples
378: ||| ||+----- 8 Bitplanes mode (256 Colors) [0:off / 1:on]
379: ||| |+------ Vertical Sync [0: internal / 1: external]
380: ||| +------- Horizontal Sync [0: internal / 1: external]
381: ||+--------- True-Color-Mode [0:off / 1:on]
382: |+---------- Overlay-Mode [0:off / 1:on]
383: +----------- 0: 2-Color-Mode [0:off / 1:on]
1.1.1.6 root 384:
385: Writing to this register does the following things:
386: - activate Falcon palette
387: - if you set Bits A/8/4 == 0, it selects 16-Color-Falcon-Mode (NOT the
388: same as ST LOW since Falcon palette is used!)
389: - $8260 register is ignored, you don't need to write here anything
390:
391: Note: 4-Color-Mode isn't realisable with Falcon palette.
392: */
1.1.1.8 root 393: void VIDEL_Falcon_ShiftMode_WriteWord(void)
1.1.1.6 root 394: {
1.1.1.9 root 395: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8266 Falcon Shift Mode (SPSHIFT) write: 0x%04x\n",
396: IoMem_ReadWord(0xff8266));
1.1.1.6 root 397:
398: videl.bUseSTShifter = false;
399: }
400:
401: /**
402: * Write Horizontal Hold Counter (HHC)
403: */
404: void VIDEL_HHC_WriteWord(void)
405: {
1.1.1.9 root 406: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8280 Horizontal Hold Counter (HHC) write: 0x%04x\n",
407: IoMem_ReadWord(0xff8280));
1.1.1.6 root 408: }
409:
410: /**
411: * Write Horizontal Hold Timer (HHT)
412: */
413: void VIDEL_HHT_WriteWord(void)
414: {
1.1.1.9 root 415: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8282 Horizontal Hold Timer (HHT) write: 0x%04x\n",
416: IoMem_ReadWord(0xff8282));
1.1.1.6 root 417: }
418:
419: /**
420: * Write Horizontal Border Begin (HBB)
421: */
422: void VIDEL_HBB_WriteWord(void)
423: {
1.1.1.9 root 424: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8284 Horizontal Border Begin (HBB) write: 0x%04x\n",
425: IoMem_ReadWord(0xff8284));
1.1.1.6 root 426: }
427:
428: /**
429: * Write Horizontal Border End (HBE)
430: */
431: void VIDEL_HBE_WriteWord(void)
432: {
1.1.1.9 root 433: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8286 Horizontal Border End (HBE) write: 0x%04x\n",
434: IoMem_ReadWord(0xff8286));
1.1.1.6 root 435: }
436:
437: /**
438: * Write Horizontal Display Begin (HDB)
1.1.1.8 root 439: $FFFF8288 [R/W] W ______9876543210 Horizontal Display Begin (HDB)
440: |
441: +---------- Display will start in [0: 1st halfline / 1: 2nd halfline]
1.1.1.6 root 442: */
443: void VIDEL_HDB_WriteWord(void)
444: {
1.1.1.9 root 445: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8288 Horizontal Display Begin (HDB) write: 0x%04x\n",
446: IoMem_ReadWord(0xff8288));
1.1.1.6 root 447: }
448:
449: /**
450: * Write Horizontal Display End (HDE)
451: */
452: void VIDEL_HDE_WriteWord(void)
453: {
1.1.1.9 root 454: LOG_TRACE(TRACE_VIDEL, "Videl : $ff828a Horizontal Display End (HDE) write: 0x%04x\n",
455: IoMem_ReadWord(0xff828a));
1.1.1.6 root 456: }
457:
458: /**
459: * Write Horizontal SS (HSS)
460: */
461: void VIDEL_HSS_WriteWord(void)
462: {
1.1.1.9 root 463: LOG_TRACE(TRACE_VIDEL, "Videl : $ff828c Horizontal SS (HSS) write: 0x%04x\n",
464: IoMem_ReadWord(0xff828c));
1.1.1.6 root 465: }
466:
467: /**
468: * Write Horizontal FS (HFS)
469: */
470: void VIDEL_HFS_WriteWord(void)
471: {
1.1.1.9 root 472: LOG_TRACE(TRACE_VIDEL, "Videl : $ff828e Horizontal FS (HFS) write: 0x%04x\n",
473: IoMem_ReadWord(0xff828e));
1.1.1.6 root 474: }
475:
476: /**
477: * Write Horizontal EE (HEE)
478: */
479: void VIDEL_HEE_WriteWord(void)
480: {
1.1.1.9 root 481: LOG_TRACE(TRACE_VIDEL, "Videl : $ff8290 Horizontal EE (HEE) write: 0x%04x\n",
482: IoMem_ReadWord(0xff8290));
1.1.1.6 root 483: }
484:
485: /**
486: * Write Vertical Frequency Counter (VFC)
487: */
488: void VIDEL_VFC_ReadWord(void)
489: {
1.1.1.13! root 490: IoMem_WriteWord(0xff82a0, videl.vertFreqCounter);
! 491: videl.vertFreqCounter++;
! 492: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a0 Vertical Frequency Counter (VFC) read: 0x%04x\n", videl.vertFreqCounter);
1.1.1.6 root 493: }
494:
495: /**
496: * Write Vertical Frequency Timer (VFT)
497: */
498: void VIDEL_VFT_WriteWord(void)
499: {
1.1.1.9 root 500: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a2 Vertical Frequency Timer (VFT) write: 0x%04x\n",
501: IoMem_ReadWord(0xff82a2));
1.1.1.6 root 502: }
503:
504: /**
505: * Write Vertical Border Begin (VBB)
506: */
507: void VIDEL_VBB_WriteWord(void)
508: {
1.1.1.9 root 509: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a4 Vertical Border Begin (VBB) write: 0x%04x\n",
510: IoMem_ReadWord(0xff82a4));
1.1.1.6 root 511: }
512:
513: /**
514: * Write Vertical Border End (VBE)
515: */
516: void VIDEL_VBE_WriteWord(void)
517: {
1.1.1.9 root 518: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a6 Vertical Border End (VBE) write: 0x%04x\n",
519: IoMem_ReadWord(0xff82a6));
1.1.1.6 root 520: }
521:
522: /**
523: * Write Vertical Display Begin (VDB)
524: */
525: void VIDEL_VDB_WriteWord(void)
1.1 root 526: {
1.1.1.9 root 527: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a8 Vertical Display Begin (VDB) write: 0x%04x\n",
528: IoMem_ReadWord(0xff82a8));
1.1 root 529: }
530:
1.1.1.6 root 531: /**
532: * Write Vertical Display End (VDE)
533: */
534: void VIDEL_VDE_WriteWord(void)
535: {
1.1.1.9 root 536: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82aa Vertical Display End (VDE) write: 0x%04x\n",
537: IoMem_ReadWord(0xff82aa));
1.1.1.6 root 538: }
539:
540: /**
541: * Write Vertical SS (VSS)
542: */
543: void VIDEL_VSS_WriteWord(void)
544: {
1.1.1.9 root 545: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82ac Vertical SS (VSS) write: 0x%04x\n",
546: IoMem_ReadWord(0xff82ac));
1.1.1.6 root 547: }
548:
549: /**
550: * Write Video Control (VCO)
551: */
552: void VIDEL_VCO_WriteWord(void)
553: {
1.1.1.9 root 554: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82c0 Video control (VCO) write: 0x%04x\n",
555: IoMem_ReadWord(0xff82c0));
1.1.1.6 root 556: }
557:
558: /**
559: * Write Video Mode (VDM)
560: */
561: void VIDEL_VMD_WriteWord(void)
562: {
1.1.1.9 root 563: LOG_TRACE(TRACE_VIDEL, "Videl : $ff82c2 Video Mode (VDM) write: 0x%04x\n",
564: IoMem_ReadWord(0xff82c2));
1.1.1.6 root 565: }
566:
567:
1.1.1.8 root 568: /**
569: * VIDEL_getVideoramAddress: returns the video RAM address.
570: * On Falcon, video address must be a multiple of four in bitplane modes.
571: */
572: static Uint32 VIDEL_getVideoramAddress(void)
1.1 root 573: {
1.1.1.8 root 574: Uint32 videoBase;
1.1.1.12 root 575:
1.1.1.8 root 576: videoBase = (Uint32) IoMem_ReadByte(0xff8201) << 16;
577: videoBase |= (Uint32) IoMem_ReadByte(0xff8203) << 8;
578: videoBase |= IoMem_ReadByte(0xff820d) & ~3;
1.1.1.12 root 579:
1.1.1.8 root 580: return videoBase;
1.1 root 581: }
582:
1.1.1.13! root 583: /**
! 584: * Reset appropriate registers on VBL etc
! 585: */
! 586: void VIDEL_RestartVideoCounter(void)
! 587: {
! 588: videl.videoRaster = VIDEL_getVideoramAddress();
! 589: /* counter for VFC register $ff82a0 */
! 590: videl.vertFreqCounter = 0;
! 591: }
! 592:
! 593: /**
! 594: * Increment appropriate registers on HBL
! 595: */
! 596: void VIDEL_VideoRasterHBL(void)
! 597: {
! 598: int lineoffset = IoMem_ReadWord(0xff820e) & 0x01ff; /* 9 bits */
! 599: int linewidth = IoMem_ReadWord(0xff8210) & 0x03ff; /* 10 bits */
! 600:
! 601: videl.videoRaster += linewidth + lineoffset;
! 602:
! 603: /* TODO: VFC is incremented every half line, here, we increment it every line */
! 604: videl.vertFreqCounter++;
! 605: }
! 606:
! 607:
1.1.1.8 root 608: static Uint16 VIDEL_getScreenBpp(void)
1.1 root 609: {
1.1.1.8 root 610: Uint16 f_shift = IoMem_ReadWord(0xff8266);
611: Uint16 bits_per_pixel;
612: Uint8 st_shift = IoMem_ReadByte(0xff8260);
613:
1.1 root 614: /* to get bpp, we must examine f_shift and st_shift.
1.1.1.12 root 615: * f_shift is valid if any of bits no. 10, 8 or 4 is set.
1.1.1.8 root 616: * Priority in f_shift is: 10 ">" 8 ">" 4, i.e.
1.1 root 617: * if bit 10 set then bit 8 and bit 4 don't care...
618: * If all these bits are 0 and ST shifter is written
619: * after Falcon one, get display depth from st_shift
620: * (as for ST and STE)
621: */
622: if (f_shift & 0x400) /* Falcon: 2 colors */
623: bits_per_pixel = 1;
624: else if (f_shift & 0x100) /* Falcon: hicolor */
625: bits_per_pixel = 16;
626: else if (f_shift & 0x010) /* Falcon: 8 bitplanes */
627: bits_per_pixel = 8;
1.1.1.6 root 628: else if (!videl.bUseSTShifter) /* Falcon: 4 bitplanes */
1.1 root 629: bits_per_pixel = 4;
630: else if (st_shift == 0)
631: bits_per_pixel = 4;
632: else if (st_shift == 0x01)
633: bits_per_pixel = 2;
634: else /* if (st_shift == 0x02) */
635: bits_per_pixel = 1;
636:
1.1.1.8 root 637: /* 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 638:
639: return bits_per_pixel;
640: }
641:
1.1.1.8 root 642: /**
643: * VIDEL_getScreenWidth : returns the visible X resolution
644: * left border + graphic area + right border
645: * left border : hdb - hbe-offset
646: * right border : hbb - hde-offset
1.1.1.12 root 647: * Graphics display : starts at cycle HDB and ends at cycle HDE.
1.1.1.8 root 648: */
1.1 root 649: static int VIDEL_getScreenWidth(void)
650: {
1.1.1.9 root 651: Uint16 hbb, hbe, hdb, hde, vdm, hht;
652: Uint16 cycPerPixel, divider;
653: Sint16 hdb_offset, hde_offset;
654: Sint16 leftBorder, rightBorder;
1.1.1.8 root 655: Uint16 bpp = VIDEL_getScreenBpp();
656:
657: /* X Size of the Display area */
658: videl.XSize = (IoMem_ReadWord(0xff8210) & 0x03ff) * 16 / bpp;
659:
1.1.1.13! root 660: /* Sanity check - don't use unsupported texture sizes for SDL2:
! 661: * http://answers.unity3d.com/questions/563094/mobile-max-texture-size.html
! 662: * (largest currently known real Videl width is ~1600)
! 663: */
! 664: while (videl.XSize > 2048)
! 665: videl.XSize /= 2;
! 666:
1.1.1.8 root 667: /* If the user disabled the borders display from the gui, we suppress them */
668: if (ConfigureParams.Screen.bAllowOverscan == 0) {
669: videl.leftBorderSize = 0;
670: videl.rightBorderSize = 0;
671: return videl.XSize;
672: }
673:
674: /* According to Aura and Animal Mine doc about Videl, if a monochrome monitor is connected,
675: * HDB and HDE have no significance and no border is displayed.
676: */
677: if (videl.monitor_type == FALCON_MONITOR_MONO) {
678: videl.leftBorderSize = 0;
679: videl.rightBorderSize = 0;
680: return videl.XSize;
681: }
682:
1.1.1.9 root 683: hbb = IoMem_ReadWord(0xff8284) & 0x01ff;
684: hbe = IoMem_ReadWord(0xff8286) & 0x01ff;
685: hdb = IoMem_ReadWord(0xff8288) & 0x01ff;
686: hde = IoMem_ReadWord(0xff828a) & 0x01ff;
687: vdm = IoMem_ReadWord(0xff82c2) & 0xc;
688: hht = IoMem_ReadWord(0xff8282) & 0x1ff;
1.1.1.8 root 689:
690: /* Compute cycles per pixel */
691: if (vdm == 0)
692: cycPerPixel = 4;
693: else if (vdm == 4)
694: cycPerPixel = 2;
695: else
696: cycPerPixel = 1;
697:
698: /* Compute the divider */
699: if (videl.monitor_type == FALCON_MONITOR_VGA) {
700: if (cycPerPixel == 4)
701: divider = 4;
702: else
703: divider = 2;
704: }
705: else if (videl.bUseSTShifter == true) {
706: divider = 16;
707: }
708: else {
709: divider = cycPerPixel;
710: }
711:
712: /* Compute hdb_offset and hde_offset */
713: if (videl.bUseSTShifter == false) {
714: if (bpp < 16) {
715: /* falcon mode bpp */
716: hdb_offset = ((64+(128/bpp + 16 + 2) * cycPerPixel) / divider ) + 1;
717: hde_offset = ((128/bpp + 2) * cycPerPixel) / divider;
718: }
719: else {
720: /* falcon mode true color */
721: hdb_offset = ((64 + 16 * cycPerPixel) / divider ) + 1;
722: hde_offset = 0;
723: }
724: }
725: else {
726: /* ST bitplan mode */
727: hdb_offset = ((128+(128/bpp + 2) * cycPerPixel) / divider ) + 1;
728: hde_offset = ((128/bpp + 2) * cycPerPixel) / divider;
729: }
730:
731: LOG_TRACE(TRACE_VIDEL, "hdb_offset=%04x, hde_offset=%04x\n", hdb_offset, hde_offset);
732:
733: /* Compute left border size in cycles */
734: if (IoMem_ReadWord(0xff8288) & 0x0200)
735: leftBorder = hdb - hbe + hdb_offset - hht - 2;
736: else
737: leftBorder = hdb - hbe + hdb_offset;
738:
739: /* Compute right border size in cycles */
740: rightBorder = hbb - hde_offset - hde;
741:
742: videl.leftBorderSize = leftBorder / cycPerPixel;
743: videl.rightBorderSize = rightBorder / cycPerPixel;
744: LOG_TRACE(TRACE_VIDEL, "left border size=%04x, right border size=%04x\n", videl.leftBorderSize, videl.rightBorderSize);
745:
746: if (videl.leftBorderSize < 0) {
747: // fprintf(stderr, "BORDER LEFT < 0 %d\n", videl.leftBorderSize);
748: videl.leftBorderSize = 0;
749: }
750: if (videl.rightBorderSize < 0) {
751: // fprintf(stderr, "BORDER RIGHT < 0 %d\n", videl.rightBorderSize);
752: videl.rightBorderSize = 0;
753: }
754:
755: return videl.leftBorderSize + videl.XSize + videl.rightBorderSize;
1.1 root 756: }
757:
1.1.1.8 root 758: /**
759: * VIDEL_getScreenHeight : returns the visible Y resolution
760: * upper border + graphic area + lower border
761: * upper border : vdb - vbe
762: * lower border : vbb - vde
1.1.1.12 root 763: * Graphics display : starts at line VDB and ends at line VDE.
1.1.1.8 root 764: * If interlace mode off unit of VC-registers is half lines, else lines.
765: */
1.1 root 766: static int VIDEL_getScreenHeight(void)
767: {
1.1.1.8 root 768: Uint16 vbb = IoMem_ReadWord(0xff82a4) & 0x07ff;
1.1.1.12 root 769: Uint16 vbe = IoMem_ReadWord(0xff82a6) & 0x07ff;
1.1.1.8 root 770: Uint16 vdb = IoMem_ReadWord(0xff82a8) & 0x07ff;
771: Uint16 vde = IoMem_ReadWord(0xff82aa) & 0x07ff;
772: Uint16 vmode = IoMem_ReadWord(0xff82c2);
773:
774: /* According to Aura and Animal Mine doc about Videl, if a monochrome monitor is connected,
775: * VDB and VDE have no significance and no border is displayed.
1.1 root 776: */
1.1.1.8 root 777: if (videl.monitor_type == FALCON_MONITOR_MONO) {
778: videl.upperBorderSize = 0;
779: videl.lowerBorderSize = 0;
780: }
781: else {
782: /* We must take the positive value only, as a program like AceTracker starts the */
783: /* graphical area 1 line before the end of the upper border */
784: videl.upperBorderSize = vdb - vbe > 0 ? vdb - vbe : 0;
785: videl.lowerBorderSize = vbb - vde > 0 ? vbb - vde : 0;
786: }
1.1 root 787:
1.1.1.8 root 788: /* Y Size of the Display area */
1.1.1.9 root 789: if (vde >= vdb) {
790: videl.YSize = vde - vdb;
791: }
792: else {
793: LOG_TRACE(TRACE_VIDEL, "WARNING: vde=0x%x is less than vdb=0x%x\n",
794: vde, vdb);
795: }
1.1.1.8 root 796:
797: /* If the user disabled the borders display from the gui, we suppress them */
798: if (ConfigureParams.Screen.bAllowOverscan == 0) {
799: videl.upperBorderSize = 0;
800: videl.lowerBorderSize = 0;
801: }
802:
803: if (!(vmode & 0x02)){ /* interlace */
804: videl.YSize >>= 1;
805: videl.upperBorderSize >>= 1;
806: videl.lowerBorderSize >>= 1;
807: }
1.1.1.12 root 808:
1.1.1.8 root 809: if (vmode & 0x01) { /* double */
810: videl.YSize >>= 1;
811: videl.upperBorderSize >>= 1;
812: videl.lowerBorderSize >>= 1;
813: }
1.1.1.9 root 814:
1.1.1.8 root 815: return videl.upperBorderSize + videl.YSize + videl.lowerBorderSize;
1.1 root 816: }
817:
818:
1.1.1.12 root 819: /**
820: * Map the correct colortable into the correct pixel format
1.1 root 821: */
1.1.1.12 root 822: void VIDEL_UpdateColors(void)
1.1 root 823: {
1.1.1.8 root 824: int i, r, g, b, colors = 1 << videl.save_scrBpp;
1.1 root 825:
1.1.1.12 root 826: if (videl.hostColorsSync)
827: return;
828:
1.1.1.8 root 829: #define F_COLORS(i) IoMem_ReadByte(VIDEL_COLOR_REGS_BEGIN + (i))
830: #define STE_COLORS(i) IoMem_ReadByte(0xff8240 + (i))
1.1 root 831:
1.1.1.12 root 832: /* True color mode ? */
833: if (videl.save_scrBpp > 8) {
834: /* Videl color 0 ($ffff9800) must be taken into account as it is the border color in true color mode */
835: r = F_COLORS(0) & 0xfc;
836: r |= r>>6;
837: g = F_COLORS(0 + 1) & 0xfc;
838: g |= g>>6;
839: b = F_COLORS(0 + 3) & 0xfc;
840: b |= b>>6;
841: Screen_SetPaletteColor(0, r,g,b);
842: return;
843: }
844:
1.1.1.6 root 845: if (!videl.bUseSTShifter) {
1.1 root 846: for (i = 0; i < colors; i++) {
847: int offset = i << 2;
848: r = F_COLORS(offset) & 0xfc;
849: r |= r>>6;
850: g = F_COLORS(offset + 1) & 0xfc;
851: g |= g>>6;
852: b = F_COLORS(offset + 3) & 0xfc;
853: b |= b>>6;
1.1.1.12 root 854: Screen_SetPaletteColor(i, r,g,b);
1.1 root 855: }
856: } else {
857: for (i = 0; i < colors; i++) {
858: int offset = i << 1;
859: r = STE_COLORS(offset) & 0x0f;
860: r = ((r & 7)<<1)|(r>>3);
861: r |= r<<4;
862: g = (STE_COLORS(offset + 1)>>4) & 0x0f;
863: g = ((g & 7)<<1)|(g>>3);
864: g |= g<<4;
865: b = STE_COLORS(offset + 1) & 0x0f;
866: b = ((b & 7)<<1)|(b>>3);
867: b |= b<<4;
1.1.1.12 root 868: Screen_SetPaletteColor(i, r,g,b);
1.1 root 869: }
870: }
871:
1.1.1.8 root 872: videl.hostColorsSync = true;
1.1 root 873: }
874:
875:
1.1.1.13! root 876: void Videl_ScreenModeChanged(bool bForceChange)
1.1 root 877: {
1.1.1.13! root 878: int bpp;
! 879:
! 880: if (ConfigureParams.Screen.nForceBpp)
! 881: {
! 882: bpp = ConfigureParams.Screen.nForceBpp;
! 883: }
! 884: else if (Avi_AreWeRecording())
! 885: {
! 886: /* Avoid changing the bpp if we are recording */
! 887: bpp = sdlscrn->format->BitsPerPixel;
! 888: }
! 889: else
! 890: {
! 891: /* Using SDL's 16 bpp conversion function is a bit faster */
! 892: bpp = (videl.save_scrBpp == 16) ? 16 : 0;
! 893: }
! 894:
! 895: LOG_TRACE(TRACE_VIDEL, "Videl : video mode change to %dx%d@%d\n",
! 896: videl.save_scrWidth, videl.save_scrHeight, videl.save_scrBpp);
1.1.1.12 root 897:
898: Screen_SetGenConvSize(videl.save_scrWidth, videl.save_scrHeight,
899: bpp, bForceChange);
1.1 root 900: }
901:
902:
1.1.1.2 root 903: bool VIDEL_renderScreen(void)
1.1 root 904: {
1.1.1.8 root 905: /* Atari screen infos */
1.1 root 906: int vw = VIDEL_getScreenWidth();
907: int vh = VIDEL_getScreenHeight();
908: int vbpp = VIDEL_getScreenBpp();
1.1.1.8 root 909:
910: int lineoffset = IoMem_ReadWord(0xff820e) & 0x01ff; /* 9 bits */
911: int linewidth = IoMem_ReadWord(0xff8210) & 0x03ff; /* 10 bits */
1.1.1.12 root 912: int hscrolloffset = IoMem_ReadByte(0xff8265) & 0x0f;
1.1.1.9 root 913: int nextline;
1.1.1.8 root 914:
1.1.1.6 root 915: bool change = false;
1.1 root 916:
1.1.1.13! root 917: Uint32 videoBase = VIDEL_getVideoramAddress();
1.1.1.9 root 918:
1.1.1.8 root 919: if (vw > 0 && vw != videl.save_scrWidth) {
920: LOG_TRACE(TRACE_VIDEL, "Videl : width change from %d to %d\n", videl.save_scrWidth, vw);
921: videl.save_scrWidth = vw;
1.1.1.6 root 922: change = true;
1.1 root 923: }
1.1.1.8 root 924: if (vh > 0 && vh != videl.save_scrHeight) {
925: LOG_TRACE(TRACE_VIDEL, "Videl : height change from %d to %d\n", videl.save_scrHeight, vh);
926: videl.save_scrHeight = vh;
1.1.1.6 root 927: change = true;
1.1 root 928: }
1.1.1.8 root 929: if (vbpp != videl.save_scrBpp) {
930: LOG_TRACE(TRACE_VIDEL, "Videl : bpp change from %d to %d\n", videl.save_scrBpp, vbpp);
931: videl.save_scrBpp = vbpp;
1.1.1.6 root 932: change = true;
933: }
934: if (change) {
1.1.1.13! root 935: Videl_ScreenModeChanged(false);
1.1 root 936: }
937:
1.1.1.12 root 938: if (vw < 32 || vh < 32) {
939: LOG_TRACE(TRACE_VIDEL, "Videl : %dx%d screen size, not drawing\n", vw, vh);
940: return false;
941: }
942:
943: if (!Screen_Lock())
1.1.1.2 root 944: return false;
1.1 root 945:
1.1.1.12 root 946: /*
947: I think this implementation is naive:
1.1.1.8 root 948: indeed, I suspect that we should instead skip lineoffset
949: words each time we have read "more" than linewidth words
950: (possibly "more" because of the number of bit planes).
951: Moreover, the 1 bit plane mode is particular;
952: while doing some experiments on my Falcon, it seems to
953: behave like the 4 bit planes mode.
954: At last, we have also to take into account the 4 bits register
955: located at the word $ffff8264 (bit offset). This register makes
956: the semantics of the lineoffset register change a little.
957: int bitoffset = IoMem_ReadWord(0xff8264) & 0x000f;
958: The meaning of this register in True Color mode is not clear
959: for me at the moment (and my experiments on the Falcon don't help
960: me).
961: */
1.1.1.9 root 962: nextline = linewidth + lineoffset;
1.1.1.8 root 963:
1.1.1.12 root 964: VIDEL_UpdateColors();
1.1.1.8 root 965:
1.1.1.13! root 966: Screen_GenConvert(&STRam[videoBase], videl.XSize, videl.YSize,
1.1.1.12 root 967: videl.save_scrBpp, nextline, hscrolloffset,
968: videl.leftBorderSize, videl.rightBorderSize,
969: videl.upperBorderSize, videl.lowerBorderSize);
1.1 root 970:
1.1.1.12 root 971: Screen_UnLock();
972: Screen_GenConvUpdate(Statusbar_Update(sdlscrn, false), false);
1.1.1.2 root 973:
974: return true;
1.1 root 975: }
976:
977:
1.1.1.4 root 978: /**
1.1.1.10 root 979: * Write to videl ST palette registers (0xff8240-0xff825e)
980: *
981: * Note that there's a special "strange" case when writing only to the upper byte
982: * of the color reg (instead of writing 16 bits at once with .W/.L).
983: * In that case, the byte written to address x is automatically written
984: * to address x+1 too (but we shouldn't copy x in x+1 after masking x ; we apply the mask at the end)
985: * Similarly, when writing a byte to address x+1, it's also written to address x
986: * So : move.w #0,$ff8240 -> color 0 is now $000
987: * move.b #7,$ff8240 -> color 0 is now $707 !
988: * move.b #$55,$ff8241 -> color 0 is now $555 !
989: * move.b #$71,$ff8240 -> color 0 is now $171 (bytes are first copied, then masked)
990: */
1.1.1.11 root 991: static void Videl_ColorReg_WriteWord(void)
1.1.1.10 root 992: {
993: Uint16 col;
994: Uint32 addr = IoAccessCurrentAddress;
995:
996: videl.hostColorsSync = false;
997:
998: if (bUseHighRes || bUseVDIRes) /* Don't store if hi-res or VDI resolution */
999: return;
1000:
1.1.1.12 root 1001: /* Handle special case when writing only to the lower or
1002: * upper byte of the color reg: copy written byte also
1003: * to the other byte before masking the color value.
1004: */
1005: if (nIoMemAccessSize == SIZE_BYTE)
1006: col = (IoMem_ReadByte(addr) << 8) + IoMem_ReadByte(addr);
1.1.1.10 root 1007: /* Usual case, writing a word or a long (2 words) */
1.1.1.12 root 1008: else
1.1.1.10 root 1009: col = IoMem_ReadWord(addr);
1010:
1011: col &= 0xfff; /* Mask off to 4096 palette */
1012:
1013: addr &= 0xfffffffe; /* Ensure addr is even to store the 16 bit color */
1014:
1015: IoMem_WriteWord(addr, col);
1016: }
1017:
1018: /*
1019: * [NP] TODO : due to how .L accesses are handled in ioMem.c, we can't call directly
1020: * Video_ColorReg_WriteWord from ioMemTabFalcon.c, we must use an intermediate
1021: * function, else .L accesses will not change 2 .W color regs, but only one.
1022: * This should be changed in ioMem.c to do 2 separate .W accesses, as would do a real 68000
1023: */
1024:
1025: void Videl_Color0_WriteWord(void)
1026: {
1027: Videl_ColorReg_WriteWord();
1028: }
1029:
1030: void Videl_Color1_WriteWord(void)
1031: {
1032: Videl_ColorReg_WriteWord();
1033: }
1034:
1035: void Videl_Color2_WriteWord(void)
1036: {
1037: Videl_ColorReg_WriteWord();
1038: }
1039:
1040: void Videl_Color3_WriteWord(void)
1041: {
1042: Videl_ColorReg_WriteWord();
1043: }
1044:
1045: void Videl_Color4_WriteWord(void)
1046: {
1047: Videl_ColorReg_WriteWord();
1048: }
1049:
1050: void Videl_Color5_WriteWord(void)
1051: {
1052: Videl_ColorReg_WriteWord();
1053: }
1054:
1055: void Videl_Color6_WriteWord(void)
1056: {
1057: Videl_ColorReg_WriteWord();
1058: }
1059:
1060: void Videl_Color7_WriteWord(void)
1061: {
1062: Videl_ColorReg_WriteWord();
1063: }
1064:
1065: void Videl_Color8_WriteWord(void)
1066: {
1067: Videl_ColorReg_WriteWord();
1068: }
1069:
1070: void Videl_Color9_WriteWord(void)
1071: {
1072: Videl_ColorReg_WriteWord();
1073: }
1074:
1075: void Videl_Color10_WriteWord(void)
1076: {
1077: Videl_ColorReg_WriteWord();
1078: }
1079:
1080: void Videl_Color11_WriteWord(void)
1081: {
1082: Videl_ColorReg_WriteWord();
1083: }
1084:
1085: void Videl_Color12_WriteWord(void)
1086: {
1087: Videl_ColorReg_WriteWord();
1088: }
1089:
1090: void Videl_Color13_WriteWord(void)
1091: {
1092: Videl_ColorReg_WriteWord();
1093: }
1094:
1095: void Videl_Color14_WriteWord(void)
1096: {
1097: Videl_ColorReg_WriteWord();
1098: }
1099:
1100: void Videl_Color15_WriteWord(void)
1101: {
1102: Videl_ColorReg_WriteWord();
1103: }
1104:
1105: /**
1106: * display Videl registers values (for debugger info command)
1107: */
1.1.1.11 root 1108: void Videl_Info(FILE *fp, Uint32 dummy)
1.1.1.10 root 1109: {
1110: if (ConfigureParams.System.nMachineType != MACHINE_FALCON) {
1.1.1.11 root 1111: fprintf(fp, "Not Falcon - no Videl!\n");
1.1.1.10 root 1112: return;
1113: }
1114:
1.1.1.11 root 1115: fprintf(fp, "$FF8006.b : monitor type : %02x\n", IoMem_ReadByte(0xff8006));
1116: fprintf(fp, "$FF8201.b : Video Base Hi : %02x\n", IoMem_ReadByte(0xff8201));
1117: fprintf(fp, "$FF8203.b : Video Base Mi : %02x\n", IoMem_ReadByte(0xff8203));
1118: fprintf(fp, "$FF8205.b : Video Count Hi : %02x\n", IoMem_ReadByte(0xff8205));
1119: fprintf(fp, "$FF8207.b : Video Count Mi : %02x\n", IoMem_ReadByte(0xff8207));
1120: fprintf(fp, "$FF8209.b : Video Count Lo : %02x\n", IoMem_ReadByte(0xff8209));
1121: fprintf(fp, "$FF820A.b : Sync mode : %02x\n", IoMem_ReadByte(0xff820a));
1122: fprintf(fp, "$FF820D.b : Video Base Lo : %02x\n", IoMem_ReadByte(0xff820d));
1123: fprintf(fp, "$FF820E.w : offset to next line : %04x\n", IoMem_ReadWord(0xff820e));
1124: fprintf(fp, "$FF8210.w : VWRAP - line width : %04x\n", IoMem_ReadWord(0xff8210));
1125: fprintf(fp, "$FF8260.b : ST shift mode : %02x\n", IoMem_ReadByte(0xff8260));
1126: fprintf(fp, "$FF8264.w : Horizontal scroll register : %04x\n", IoMem_ReadWord(0xff8264));
1127: fprintf(fp, "$FF8266.w : Falcon shift mode : %04x\n", IoMem_ReadWord(0xff8266));
1128: fprintf(fp, "\n");
1129: fprintf(fp, "$FF8280.w : HHC - Horizontal Hold Counter : %04x\n", IoMem_ReadWord(0xff8280));
1130: fprintf(fp, "$FF8282.w : HHT - Horizontal Hold Timer : %04x\n", IoMem_ReadWord(0xff8282));
1131: fprintf(fp, "$FF8284.w : HBB - Horizontal Border Begin : %04x\n", IoMem_ReadWord(0xff8284));
1132: fprintf(fp, "$FF8286.w : HBE - Horizontal Border End : %04x\n", IoMem_ReadWord(0xff8286));
1133: fprintf(fp, "$FF8288.w : HDB - Horizontal Display Begin : %04x\n", IoMem_ReadWord(0xff8288));
1134: fprintf(fp, "$FF828A.w : HDE - Horizontal Display End : %04x\n", IoMem_ReadWord(0xff828a));
1135: fprintf(fp, "$FF828C.w : HSS - Horizontal SS : %04x\n", IoMem_ReadWord(0xff828c));
1136: fprintf(fp, "$FF828E.w : HFS - Horizontal FS : %04x\n", IoMem_ReadWord(0xff828e));
1137: fprintf(fp, "$FF8290.w : HEE - Horizontal EE : %04x\n", IoMem_ReadWord(0xff8290));
1138: fprintf(fp, "\n");
1139: fprintf(fp, "$FF82A0.w : VFC - Vertical Frequency Counter : %04x\n", IoMem_ReadWord(0xff82a0));
1140: fprintf(fp, "$FF82A2.w : VFT - Vertical Frequency Timer : %04x\n", IoMem_ReadWord(0xff82a2));
1141: fprintf(fp, "$FF82A4.w : VBB - Vertical Border Begin : %04x\n", IoMem_ReadWord(0xff82a4));
1142: fprintf(fp, "$FF82A6.w : VBE - Vertical Border End : %04x\n", IoMem_ReadWord(0xff82a6));
1143: fprintf(fp, "$FF82A8.w : VDB - Vertical Display Begin : %04x\n", IoMem_ReadWord(0xff82a8));
1144: fprintf(fp, "$FF82AA.w : VDE - Vertical Display End : %04x\n", IoMem_ReadWord(0xff82aa));
1145: fprintf(fp, "$FF82AC.w : VSS - Vertical SS : %04x\n", IoMem_ReadWord(0xff82ac));
1146: fprintf(fp, "\n");
1147: fprintf(fp, "$FF82C0.w : VCO - Video control : %04x\n", IoMem_ReadWord(0xff82c0));
1148: fprintf(fp, "$FF82C2.w : VMD - Video mode : %04x\n", IoMem_ReadWord(0xff82c2));
1149: fprintf(fp, "\n-------------------------\n");
1.1.1.10 root 1150:
1.1.1.11 root 1151: fprintf(fp, "Video base : %08x\n",
1.1.1.12 root 1152: (IoMem_ReadByte(0xff8201)<<16) +
1153: (IoMem_ReadByte(0xff8203)<<8) +
1.1.1.10 root 1154: IoMem_ReadByte(0xff820d));
1.1.1.11 root 1155: fprintf(fp, "Video count : %08x\n",
1.1.1.12 root 1156: (IoMem_ReadByte(0xff8205)<<16) +
1157: (IoMem_ReadByte(0xff8207)<<8) +
1.1.1.10 root 1158: IoMem_ReadByte(0xff8209));
1159: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.