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