|
|
@@ -0,0 +1,719 @@ |
|
|
|
/* |
|
|
|
* MNT ZZ9000 Amiga Graphics Card Driver (ZZ9000.card) |
|
|
|
* Copyright (C) 2016-2019, Lukas F. Hartmann <lukas@mntre.com> |
|
|
|
* MNT Research GmbH, Berlin |
|
|
|
* https://mntre.com |
|
|
|
* |
|
|
|
* More Info: https://mntre.com/zz9000 |
|
|
|
* |
|
|
|
* SPDX-License-Identifier: GPL-3.0-or-later |
|
|
|
* GNU General Public License v3.0 or later |
|
|
|
* |
|
|
|
* https://spdx.org/licenses/GPL-3.0-or-later.html |
|
|
|
*/ |
|
|
|
|
|
|
|
/* REVISION 1.0 */ |
|
|
|
|
|
|
|
#include "mntgfx.h" |
|
|
|
#include "zz9000.h" |
|
|
|
|
|
|
|
#include <proto/exec.h> |
|
|
|
#include <proto/expansion.h> |
|
|
|
#include <proto/dos.h> |
|
|
|
|
|
|
|
#include <exec/types.h> |
|
|
|
#include <exec/memory.h> |
|
|
|
#include <exec/libraries.h> |
|
|
|
#include <exec/execbase.h> |
|
|
|
#include <exec/resident.h> |
|
|
|
#include <exec/initializers.h> |
|
|
|
#include <clib/debug_protos.h> |
|
|
|
|
|
|
|
static ULONG LibStart(void) { |
|
|
|
return(-1); |
|
|
|
} |
|
|
|
|
|
|
|
static const char LibraryName[] = "ZZ9000.card"; |
|
|
|
static const char LibraryID[] = "$VER: ZZ9000.card 1.0 (2019-07-30)\r\n"; |
|
|
|
|
|
|
|
__saveds struct MNTGFXBase* OpenLib( __reg("a6") struct MNTGFXBase *MNTGFXBase); |
|
|
|
BPTR __saveds CloseLib( __reg("a6") struct MNTGFXBase *MNTGFXBase); |
|
|
|
BPTR __saveds ExpungeLib( __reg("a6") struct MNTGFXBase *exb); |
|
|
|
ULONG ExtFuncLib(void); |
|
|
|
__saveds struct MNTGFXBase* InitLib(__reg("a6") struct ExecBase *sysbase, |
|
|
|
__reg("a0") BPTR seglist, |
|
|
|
__reg("d0") struct MNTGFXBase *exb); |
|
|
|
|
|
|
|
static const APTR FuncTab[] = { |
|
|
|
(APTR)OpenLib, |
|
|
|
(APTR)CloseLib, |
|
|
|
(APTR)ExpungeLib, |
|
|
|
(APTR)ExtFuncLib, |
|
|
|
|
|
|
|
(APTR)FindCard, |
|
|
|
(APTR)InitCard, |
|
|
|
(APTR)((LONG)-1) |
|
|
|
}; |
|
|
|
|
|
|
|
struct InitTable |
|
|
|
{ |
|
|
|
ULONG LibBaseSize; |
|
|
|
APTR FunctionTable; |
|
|
|
APTR DataTable; |
|
|
|
APTR InitLibTable; |
|
|
|
}; |
|
|
|
|
|
|
|
static struct InitTable InitTab = { |
|
|
|
(ULONG) sizeof(struct MNTGFXBase), |
|
|
|
(APTR) FuncTab, |
|
|
|
(APTR) NULL, |
|
|
|
(APTR) InitLib |
|
|
|
}; |
|
|
|
|
|
|
|
static const struct Resident ROMTag = { |
|
|
|
RTC_MATCHWORD, |
|
|
|
&ROMTag, |
|
|
|
&ROMTag + 1, |
|
|
|
RTF_AUTOINIT, |
|
|
|
83, |
|
|
|
NT_LIBRARY, |
|
|
|
0, |
|
|
|
(char *)LibraryName, |
|
|
|
(char *)LibraryID, |
|
|
|
(APTR)&InitTab |
|
|
|
}; |
|
|
|
|
|
|
|
// useful for debugging |
|
|
|
void waitclick() { |
|
|
|
#define CIAAPRA ((volatile uint8*)0xbfe001) |
|
|
|
// bfe001 http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node012E.html |
|
|
|
while (!(*CIAAPRA & (1<<6))) { |
|
|
|
// wait for left mouse button pressed |
|
|
|
} |
|
|
|
while ((*CIAAPRA & (1<<6))) { |
|
|
|
// wait for left mouse button released |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static struct MNTGFXBase *MNTGFXBase; |
|
|
|
|
|
|
|
__saveds struct MNTGFXBase* InitLib(__reg("a6") struct ExecBase *sysbase, |
|
|
|
__reg("a0") BPTR seglist, |
|
|
|
__reg("d0") struct MNTGFXBase *exb) |
|
|
|
{ |
|
|
|
MNTGFXBase = exb; |
|
|
|
return(MNTGFXBase); |
|
|
|
} |
|
|
|
|
|
|
|
__saveds struct MNTGFXBase* OpenLib(__reg("a6") struct MNTGFXBase *MNTGFXBase) |
|
|
|
{ |
|
|
|
MNTGFXBase->libNode.lib_OpenCnt++; |
|
|
|
MNTGFXBase->libNode.lib_Flags &= ~LIBF_DELEXP; |
|
|
|
|
|
|
|
return(MNTGFXBase); |
|
|
|
} |
|
|
|
|
|
|
|
BPTR __saveds CloseLib(__reg("a6") struct MNTGFXBase *MNTGFXBase) |
|
|
|
{ |
|
|
|
MNTGFXBase->libNode.lib_OpenCnt--; |
|
|
|
|
|
|
|
if(!MNTGFXBase->libNode.lib_OpenCnt) { |
|
|
|
if(MNTGFXBase->libNode.lib_Flags & LIBF_DELEXP) { |
|
|
|
return( ExpungeLib(MNTGFXBase) ); |
|
|
|
} |
|
|
|
} |
|
|
|
return(NULL); |
|
|
|
} |
|
|
|
|
|
|
|
BPTR __saveds ExpungeLib(__reg("a6") struct MNTGFXBase *exb) |
|
|
|
{ |
|
|
|
struct MNTGFXBase *MNTGFXBase = exb; |
|
|
|
BPTR seglist; |
|
|
|
struct ExecBase *SysBase = *(struct ExecBase **)4L; |
|
|
|
|
|
|
|
if(!MNTGFXBase->libNode.lib_OpenCnt) { |
|
|
|
ULONG negsize, possize, fullsize; |
|
|
|
UBYTE *negptr = (UBYTE *) MNTGFXBase; |
|
|
|
|
|
|
|
seglist = MNTGFXBase->segList; |
|
|
|
|
|
|
|
Remove((struct Node *)MNTGFXBase); |
|
|
|
|
|
|
|
negsize = MNTGFXBase->libNode.lib_NegSize; |
|
|
|
possize = MNTGFXBase->libNode.lib_PosSize; |
|
|
|
fullsize = negsize + possize; |
|
|
|
negptr -= negsize; |
|
|
|
|
|
|
|
FreeMem(negptr, fullsize); |
|
|
|
return(seglist); |
|
|
|
} |
|
|
|
|
|
|
|
MNTGFXBase->libNode.lib_Flags |= LIBF_DELEXP; |
|
|
|
return(NULL); |
|
|
|
} |
|
|
|
|
|
|
|
ULONG ExtFuncLib(void) |
|
|
|
{ |
|
|
|
return(NULL); |
|
|
|
} |
|
|
|
|
|
|
|
int FindCard(__reg("a0") struct RTGBoard* b) { |
|
|
|
struct ConfigDev* cd = NULL; |
|
|
|
uint16 fwrev = 0; |
|
|
|
struct ExpansionBase *ExpansionBase = NULL; |
|
|
|
struct ExecBase *SysBase = *(struct ExecBase **)4L; |
|
|
|
|
|
|
|
if ((ExpansionBase = (struct ExpansionBase*)OpenLibrary("expansion.library",0L))==NULL) { |
|
|
|
KPrintF("ZZ9000.card: Failed to open expansion.library!\n"); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
// Find Z3 or Z2 model |
|
|
|
if ((cd = (struct ConfigDev*)FindConfigDev(cd,0x6d6e,0x4)) || (cd = (struct ConfigDev*)FindConfigDev(cd,0x6d6e,0x3))) { |
|
|
|
KPrintF("ZZ9000.card: MNT ZZ9000 found.\n"); |
|
|
|
b->memory = (uint8*)(cd->cd_BoardAddr)+0x10000; |
|
|
|
b->memory_size = cd->cd_BoardSize-0x10000; |
|
|
|
b->registers = (uint8*)(cd->cd_BoardAddr); |
|
|
|
fwrev = ((uint16*)b->registers)[0]; |
|
|
|
|
|
|
|
return 1; |
|
|
|
} else { |
|
|
|
KPrintF("ZZ9000.card: MNT ZZ9000 not found!\n"); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
int InitCard(__reg("a0") struct RTGBoard* b) { |
|
|
|
int max; |
|
|
|
struct ExecBase *SysBase = *(struct ExecBase **)4L; |
|
|
|
|
|
|
|
b->self = MNTGFXBase; |
|
|
|
b->exec = SysBase; |
|
|
|
b->name = "ZZ9000"; |
|
|
|
b->type = 14; |
|
|
|
b->chip_type = 3; |
|
|
|
b->controller_type = 3; |
|
|
|
|
|
|
|
b->flags = (1<<20)|(1<<12)|(1<<26); // indisplaychain, flickerfixer, directaccess |
|
|
|
b->color_formats = 1|2|512|1024|2048; |
|
|
|
b->sprite_flags = 0; |
|
|
|
b->bits_per_channel = 8; |
|
|
|
|
|
|
|
max = 8191; |
|
|
|
b->max_bitmap_w_planar = max; |
|
|
|
b->max_bitmap_w_clut = max; |
|
|
|
b->max_bitmap_w_16bit = max; |
|
|
|
b->max_bitmap_w_24bit = max; |
|
|
|
b->max_bitmap_w_32bit = max; |
|
|
|
|
|
|
|
b->max_bitmap_h_planar = max; |
|
|
|
b->max_bitmap_h_clut = max; |
|
|
|
b->max_bitmap_h_16bit = max; |
|
|
|
b->max_bitmap_h_24bit = max; |
|
|
|
b->max_bitmap_h_32bit = max; |
|
|
|
|
|
|
|
max = 1920; |
|
|
|
b->max_res_w_planar = max; |
|
|
|
b->max_res_w_clut = max; |
|
|
|
b->max_res_w_16bit = max; |
|
|
|
b->max_res_w_24bit = max; |
|
|
|
b->max_res_w_32bit = max; |
|
|
|
|
|
|
|
max = 1080; |
|
|
|
b->max_res_h_planar = max; |
|
|
|
b->max_res_h_clut = max; |
|
|
|
b->max_res_h_16bit = max; |
|
|
|
b->max_res_h_24bit = max; |
|
|
|
b->max_res_h_32bit = max; |
|
|
|
|
|
|
|
// no alloc yet |
|
|
|
//b->max_alloc = 0; |
|
|
|
//b->max_alloc_part = 0; |
|
|
|
|
|
|
|
b->clock_ram = CLOCK_HZ; |
|
|
|
b->num_pixelclocks_planar = 1; |
|
|
|
b->num_pixelclocks_clut = 1; |
|
|
|
b->num_pixelclocks_16bit = 1; |
|
|
|
b->num_pixelclocks_24bit = 1; |
|
|
|
b->num_pixelclocks_32bit = 1; |
|
|
|
|
|
|
|
b->fn_init_dac = (void*)init_dac; |
|
|
|
b->fn_init_mode = (void*)init_mode; |
|
|
|
|
|
|
|
b->fn_get_pitch = (void*)get_pitch; |
|
|
|
b->fn_map_address = (void*)map_address; |
|
|
|
|
|
|
|
b->fn_is_bitmap_compatible = (void*)is_bitmap_compatible; |
|
|
|
b->fn_set_palette = (void*)set_palette; |
|
|
|
b->fn_enable_display = (void*)enable_display; |
|
|
|
|
|
|
|
//b->fn_p2c = rect_p2c; |
|
|
|
b->fn_rect_fill = (void*)rect_fill; |
|
|
|
b->fn_rect_copy = (void*)rect_copy; |
|
|
|
//b->fn_rect_pattern = rect_pattern; |
|
|
|
//b->fn_rect_template = rect_template; // text drawing! |
|
|
|
//b->fn_rect_copy_nomask = rect_copy_nomask; // used for window copying? |
|
|
|
b->fn_blitter_wait = (void*)blitter_wait; |
|
|
|
|
|
|
|
b->fn_get_pixelclock_index = (void*)get_pixelclock_index; |
|
|
|
b->fn_get_pixelclock_hz = (void*)get_pixelclock_hz; |
|
|
|
b->fn_set_clock = (void*)set_clock; |
|
|
|
|
|
|
|
b->fn_monitor_switch = (void*)monitor_switch; |
|
|
|
|
|
|
|
b->fn_vsync_wait = (void*)vsync_wait; |
|
|
|
b->fn_is_vsynced = (void*)is_vsynced; |
|
|
|
b->fn_pan = (void*)pan; |
|
|
|
b->fn_set_memory_mode = (void*)set_memory_mode; |
|
|
|
b->fn_set_write_mask = (void*)set_write_mask; |
|
|
|
b->fn_set_clear_mask = (void*)set_clear_mask; |
|
|
|
b->fn_set_read_plane = (void*)set_read_plane; |
|
|
|
|
|
|
|
/*b->fn_sprite_setup = sprite_setup; |
|
|
|
b->fn_sprite_xy = sprite_xy; |
|
|
|
b->fn_sprite_bitmap = sprite_bitmap; |
|
|
|
b->fn_sprite_colors = sprite_colors;*/ |
|
|
|
|
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
// placeholder function |
|
|
|
void nop() { |
|
|
|
} |
|
|
|
|
|
|
|
void init_dac(__reg("a0") struct RTGBoard* b,__reg("d7") uint16 format) { |
|
|
|
} |
|
|
|
|
|
|
|
uint32 enable_display(__reg("a0") struct RTGBoard* b,__reg("d0") uint16 enabled) { |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
void memory_alloc(__reg("a0") struct RTGBoard* b,__reg("d0") uint32 len,__reg("d1") uint16 s1,__reg("d2") uint16 s2) { |
|
|
|
} |
|
|
|
|
|
|
|
void zzwrite16(MNTZZ9KRegs* regbase, u16* reg, u16 value) { |
|
|
|
struct ExecBase *SysBase = *(struct ExecBase **)4L; |
|
|
|
Disable(); |
|
|
|
volatile u16* busy = (volatile u16*)((uint32)regbase+0x1000); |
|
|
|
while (*busy) { |
|
|
|
} |
|
|
|
*reg = value; |
|
|
|
while (*busy) { |
|
|
|
} |
|
|
|
Enable(); |
|
|
|
} |
|
|
|
|
|
|
|
void fix_vsync(MNTZZ9KRegs* registers) { |
|
|
|
// video control op: vsync |
|
|
|
*(u16*)((uint32)registers+0x1000) = 0; |
|
|
|
*(u16*)((uint32)registers+0x1002) = 1; |
|
|
|
*(u16*)((uint32)registers+0x1004) = 5; // OP_VSYNC |
|
|
|
*(u16*)((uint32)registers+0x1004) = 0; |
|
|
|
*(u16*)((uint32)registers+0x1002) = 0; |
|
|
|
} |
|
|
|
|
|
|
|
void pan(__reg("a0") struct RTGBoard* b,__reg("a1") uint8* mem,__reg("d0") uint16 w,__reg("d1") int16 x,__reg("d2") int16 y,__reg("d7") uint16 format) { |
|
|
|
MNTZZ9KRegs* registers = b->registers; |
|
|
|
|
|
|
|
uint32 offset = (mem-(b->memory)); |
|
|
|
uint32 offhi = (offset&0xffff0000)>>16; |
|
|
|
uint32 offlo = offset&0xfc00; |
|
|
|
|
|
|
|
zzwrite16(registers, ®isters->pan_ptr_hi, offhi); |
|
|
|
zzwrite16(registers, ®isters->pan_ptr_lo, offlo); |
|
|
|
} |
|
|
|
|
|
|
|
void set_memory_mode(__reg("a0") struct RTGBoard* b,__reg("d7") uint16 format) { |
|
|
|
} |
|
|
|
void set_read_plane(__reg("a0") struct RTGBoard* b,__reg("d0") uint8 p) { |
|
|
|
} |
|
|
|
void set_write_mask(__reg("a0") struct RTGBoard* b,__reg("d0") uint8 m) { |
|
|
|
} |
|
|
|
void set_clear_mask(__reg("a0") struct RTGBoard* b,__reg("d0") uint8 m) { |
|
|
|
} |
|
|
|
void vsync_wait(__reg("a0") struct RTGBoard* b) { |
|
|
|
} |
|
|
|
|
|
|
|
static int toggle = 0; |
|
|
|
// FIXME this returned -1 which caused WB to hang after selecting a screenmode! |
|
|
|
int is_vsynced(__reg("a0") struct RTGBoard* b,__reg("d0") uint8 p) { |
|
|
|
toggle = 1-toggle; |
|
|
|
return toggle; |
|
|
|
} |
|
|
|
void set_clock(__reg("a0") struct RTGBoard* b) { |
|
|
|
} |
|
|
|
|
|
|
|
uint16 calc_pitch_bytes(uint16 w, uint16 colormode) { |
|
|
|
uint16 pitch = w; |
|
|
|
|
|
|
|
if (colormode == MNTVA_COLOR_1BIT) { |
|
|
|
// monochrome, 16 pixels per word |
|
|
|
pitch = w>>3; |
|
|
|
} else if (colormode == MNTVA_COLOR_15BIT) { |
|
|
|
pitch = w<<1; |
|
|
|
} else { |
|
|
|
pitch = w<<colormode; |
|
|
|
} |
|
|
|
return pitch; |
|
|
|
} |
|
|
|
|
|
|
|
uint16 rtg_to_mnt_colormode(uint16 format) { |
|
|
|
if (format==RTG_COLOR_FORMAT_CLUT) { |
|
|
|
// format == 1 |
|
|
|
return MNTVA_COLOR_8BIT; |
|
|
|
} else if (format==9 || format==8) { |
|
|
|
return MNTVA_COLOR_32BIT; |
|
|
|
} else if (format==0) { |
|
|
|
return MNTVA_COLOR_1BIT; |
|
|
|
} else if (format==0xb || format==0xd || format==5) { |
|
|
|
return MNTVA_COLOR_15BIT; |
|
|
|
} |
|
|
|
// format == 10 |
|
|
|
return MNTVA_COLOR_16BIT565; |
|
|
|
} |
|
|
|
|
|
|
|
uint16 pitch_to_shift(uint16 p) { |
|
|
|
if (p==8192) return 13; |
|
|
|
if (p==4096) return 12; |
|
|
|
if (p==2048) return 11; |
|
|
|
if (p==1024) return 10; |
|
|
|
if (p==512) return 9; |
|
|
|
if (p==256) return 8; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
uint16 get_pitch(__reg("a0") struct RTGBoard* b,__reg("d0") uint16 width,__reg("d7") uint16 format) { |
|
|
|
return calc_pitch_bytes(width, rtg_to_mnt_colormode(format)); |
|
|
|
} |
|
|
|
|
|
|
|
void init_modeline(MNTZZ9KRegs* registers, uint16 w, uint16 h) { |
|
|
|
int hmax,vmax,hstart,hend,vstart,vend; |
|
|
|
uint16 mode = 0; |
|
|
|
uint16 polarity = 0; |
|
|
|
|
|
|
|
if (w==1280 && h==720) { |
|
|
|
mode = 0; |
|
|
|
hmax=1980; |
|
|
|
vmax=750; |
|
|
|
hstart=1720; |
|
|
|
hend=1760; |
|
|
|
vstart=725; |
|
|
|
vend=730; |
|
|
|
polarity=0; |
|
|
|
} else if (w==800) { |
|
|
|
mode=1; |
|
|
|
hmax=1056; |
|
|
|
vmax=628; |
|
|
|
hstart=840; |
|
|
|
hend=968; |
|
|
|
vstart=601; |
|
|
|
vend=605; |
|
|
|
polarity=0; |
|
|
|
} else if (w==640 && h==480) { |
|
|
|
mode = 2; |
|
|
|
hmax=800; |
|
|
|
vmax=525; |
|
|
|
hstart=656; |
|
|
|
hend=752; |
|
|
|
vstart=490; |
|
|
|
vend=492; |
|
|
|
polarity=0; |
|
|
|
} else if (w==1024) { |
|
|
|
mode = 3; |
|
|
|
hmax=1344; |
|
|
|
vmax=806; |
|
|
|
hstart=1048; |
|
|
|
hend=1184; |
|
|
|
vstart=771; |
|
|
|
vend=777; |
|
|
|
polarity=1; |
|
|
|
} else if (w==1280 && h==1024) { |
|
|
|
mode = 4; |
|
|
|
hmax=1688; |
|
|
|
vmax=1066; |
|
|
|
hstart=1328; |
|
|
|
hend=1440; |
|
|
|
vstart=1025; |
|
|
|
vend=1028; |
|
|
|
polarity=0; |
|
|
|
} else if (w==1920 && h==1080) { |
|
|
|
mode = 5; |
|
|
|
hmax=2640; |
|
|
|
vmax=1125; |
|
|
|
hstart=2448; |
|
|
|
hend=2492; |
|
|
|
vstart=1084; |
|
|
|
vend=1089; |
|
|
|
polarity=0; |
|
|
|
} else if (w==720 && h==576) { |
|
|
|
mode = 6; |
|
|
|
hmax=864; |
|
|
|
vmax=625; |
|
|
|
hstart=732; |
|
|
|
hend=796; |
|
|
|
vstart=581; |
|
|
|
vend=586; |
|
|
|
polarity=1; |
|
|
|
} |
|
|
|
|
|
|
|
zzwrite16(registers, ®isters->mode, mode); |
|
|
|
|
|
|
|
*(u16*)((uint32)registers+0x1000) = vmax; |
|
|
|
*(u16*)((uint32)registers+0x1002) = hmax; |
|
|
|
*(u16*)((uint32)registers+0x1004) = 6; // OP_MAX |
|
|
|
*(u16*)((uint32)registers+0x1004) = 0; // NOP |
|
|
|
|
|
|
|
*(u16*)((uint32)registers+0x1000) = hstart; |
|
|
|
*(u16*)((uint32)registers+0x1002) = hend; |
|
|
|
*(u16*)((uint32)registers+0x1004) = 7; // OP_HS |
|
|
|
*(u16*)((uint32)registers+0x1004) = 0; // NOP |
|
|
|
|
|
|
|
*(u16*)((uint32)registers+0x1000) = vstart; |
|
|
|
*(u16*)((uint32)registers+0x1002) = vend; |
|
|
|
*(u16*)((uint32)registers+0x1004) = 8; // OP_VS |
|
|
|
*(u16*)((uint32)registers+0x1004) = 0; // NOP |
|
|
|
|
|
|
|
*(u16*)((uint32)registers+0x1000) = 0; |
|
|
|
*(u16*)((uint32)registers+0x1002) = polarity; |
|
|
|
*(u16*)((uint32)registers+0x1004) = 10; // OP_POLARITY |
|
|
|
*(u16*)((uint32)registers+0x1004) = 0; // NOP |
|
|
|
|
|
|
|
// FIXME |
|
|
|
for (volatile int i=0; i<50000; i++) { |
|
|
|
// wait... |
|
|
|
fix_vsync(registers); |
|
|
|
} |
|
|
|
} |
|
|
|
void init_mode_pitch(MNTZZ9KRegs* registers, uint16 w, uint16 colormode) { |
|
|
|
} |
|
|
|
|
|
|
|
void init_mode(__reg("a0") struct RTGBoard* b,__reg("a1") struct ModeInfo* m,__reg("d0") int16 border) { |
|
|
|
MNTZZ9KRegs* registers = b->registers; |
|
|
|
uint16 scale = 0; |
|
|
|
uint16 w; |
|
|
|
uint16 h; |
|
|
|
uint16 colormode; |
|
|
|
uint16 hdiv=1, vdiv=1; |
|
|
|
|
|
|
|
b->mode_info = m; |
|
|
|
b->border = border; |
|
|
|
|
|
|
|
if (m->width<320 || m->height<200) return; |
|
|
|
|
|
|
|
colormode = rtg_to_mnt_colormode(b->color_format); |
|
|
|
|
|
|
|
if (m->height>=480 || m->width>=640) { |
|
|
|
scale = 0; |
|
|
|
w = m->width; |
|
|
|
h = m->height; |
|
|
|
} else { |
|
|
|
// small doublescan modes are scaled 2x |
|
|
|
// and output as 640x480 wrapped in 800x600 sync |
|
|
|
scale = 3; |
|
|
|
hdiv = 2; |
|
|
|
vdiv = 2; |
|
|
|
|
|
|
|
w = 2*m->width; |
|
|
|
h = 2*m->height; |
|
|
|
if (h<480) h=480; |
|
|
|
} |
|
|
|
|
|
|
|
if (colormode==0) hdiv*=4; |
|
|
|
if (colormode==1) hdiv*=2; |
|
|
|
|
|
|
|
zzwrite16(registers, ®isters->hdiv, hdiv); |
|
|
|
zzwrite16(registers, ®isters->vdiv, vdiv); |
|
|
|
|
|
|
|
// video control op: scale |
|
|
|
*(u16*)((uint32)registers+0x1000) = 0; |
|
|
|
*(u16*)((uint32)registers+0x1002) = scale; |
|
|
|
*(u16*)((uint32)registers+0x1004) = 4; // OP_SCALE |
|
|
|
*(u16*)((uint32)registers+0x1004) = 0; // NOP |
|
|
|
|
|
|
|
// video control op: dimensions |
|
|
|
*(u16*)((uint32)registers+0x1000) = h; |
|
|
|
*(u16*)((uint32)registers+0x1002) = w; |
|
|
|
*(u16*)((uint32)registers+0x1004) = 2; // OP_DIMENSIONS |
|
|
|
*(u16*)((uint32)registers+0x1004) = 0; // NOP |
|
|
|
|
|
|
|
// video control op: colormode |
|
|
|
*(u16*)((uint32)registers+0x1000) = 0; |
|
|
|
*(u16*)((uint32)registers+0x1002) = colormode; |
|
|
|
*(u16*)((uint32)registers+0x1004) = 1; // OP_COLORMODE |
|
|
|
*(u16*)((uint32)registers+0x1004) = 0; // NOP |
|
|
|
|
|
|
|
init_modeline(registers, w, h); |
|
|
|
} |
|
|
|
|
|
|
|
void set_palette(__reg("a0") struct RTGBoard* b,__reg("d0") uint16 idx,__reg("d1") uint16 len) { |
|
|
|
MNTZZ9KRegs* registers = b->registers; |
|
|
|
int i; |
|
|
|
int j; |
|
|
|
|
|
|
|
len+=idx; |
|
|
|
for (i=idx, j=idx*3; i<len; i++) { |
|
|
|
u32 ctrldata = ((u32)i<<24)|(((u32)b->palette[j])<<16)|(((u32)b->palette[j+1])<<8)|(u32)b->palette[j+2]; |
|
|
|
|
|
|
|
*(u16*)((uint32)registers+0x1000) = ctrldata>>16; |
|
|
|
*(u16*)((uint32)registers+0x1002) = ctrldata&0xffff; |
|
|
|
*(u16*)((uint32)registers+0x1004) = 3; // OP_PALETTE |
|
|
|
*(u16*)((uint32)registers+0x1004) = 0; // NOP |
|
|
|
j+=3; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
uint32 is_bitmap_compatible(__reg("a0") struct RTGBoard* b,__reg("d7") uint16 format) { |
|
|
|
return 0xffffffff; |
|
|
|
} |
|
|
|
|
|
|
|
uint32 map_address(__reg("a0") struct RTGBoard* b,__reg("a1") uint32 addr) { |
|
|
|
// align screen buffers |
|
|
|
if (addr>(uint32)b->memory && addr < (((uint32)b->memory) + b->memory_size)) { |
|
|
|
addr=addr&0xfffff000; |
|
|
|
} |
|
|
|
return addr; |
|
|
|
} |
|
|
|
|
|
|
|
uint32 get_pixelclock_index(__reg("a0") struct RTGBoard* b,__reg("a1") struct ModeInfo* mode,__reg("d0") int32 clock,__reg("d7") uint16 format) { |
|
|
|
mode->pixel_clock_hz = CLOCK_HZ; |
|
|
|
mode->clock = 0; |
|
|
|
mode->clock_div = 1; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
uint32 get_pixelclock_hz(__reg("a0") struct RTGBoard* b,__reg("a1") struct ModeInfo* mode,__reg("d0") int32 clock,__reg("d7") uint16 format) { |
|
|
|
return CLOCK_HZ; |
|
|
|
} |
|
|
|
|
|
|
|
uint32 monitor_switch(__reg("a0") struct RTGBoard* b,__reg("d0") uint16 state) { |
|
|
|
MNTZZ9KRegs* registers = b->registers; |
|
|
|
|
|
|
|
if (state==0) { |
|
|
|
// capture amiga video to 16bit |
|
|
|
zzwrite16(registers, ®isters->pan_ptr_hi, 0xe0); |
|
|
|
zzwrite16(registers, ®isters->pan_ptr_lo, 0x0000); |
|
|
|
|
|
|
|
int w = 720; |
|
|
|
int h = 576; |
|
|
|
int colormode = MNTVA_COLOR_32BIT; |
|
|
|
|
|
|
|
zzwrite16(registers, ®isters->hdiv, 1); |
|
|
|
zzwrite16(registers, ®isters->vdiv, 2); |
|
|
|
|
|
|
|
// video control op: scale |
|
|
|
*(u16*)((uint32)registers+0x1000) = 0; |
|
|
|
*(u16*)((uint32)registers+0x1002) = 2; // vertical doubling |
|
|
|
*(u16*)((uint32)registers+0x1004) = 4; // OP_SCALE |
|
|
|
*(u16*)((uint32)registers+0x1004) = 0; // NOP |
|
|
|
|
|
|
|
// video control op: dimensions |
|
|
|
*(u16*)((uint32)registers+0x1000) = h; |
|
|
|
*(u16*)((uint32)registers+0x1002) = w; |
|
|
|
*(u16*)((uint32)registers+0x1004) = 2; // OP_DIMENSIONS |
|
|
|
*(u16*)((uint32)registers+0x1004) = 0; // NOP |
|
|
|
|
|
|
|
// video control op: colormode |
|
|
|
*(u16*)((uint32)registers+0x1000) = 0; |
|
|
|
*(u16*)((uint32)registers+0x1002) = colormode; |
|
|
|
*(u16*)((uint32)registers+0x1004) = 1; // OP_COLORMODE |
|
|
|
*(u16*)((uint32)registers+0x1004) = 0; // NOP |
|
|
|
|
|
|
|
*(u16*)((uint32)registers+0x1006) = 1; // capture mode |
|
|
|
|
|
|
|
init_modeline(registers, w, h); |
|
|
|
} else { |
|
|
|
// rtg mode |
|
|
|
*(u16*)((uint32)registers+0x1006) = 0; // capture mode |
|
|
|
|
|
|
|
init_mode(b, b->mode_info, b->border); |
|
|
|
} |
|
|
|
|
|
|
|
// FIXME |
|
|
|
for (volatile int i=0; i<50000; i++) { |
|
|
|
// wait... |
|
|
|
fix_vsync(registers); |
|
|
|
} |
|
|
|
|
|
|
|
return 1-state; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void rect_fill(__reg("a0") struct RTGBoard* b,__reg("a1") struct RenderInfo* r,__reg("d0") uint16 x,__reg("d1") uint16 y,__reg("d2") uint16 w,__reg("d3") uint16 h,__reg("d4") uint32 color) { |
|
|
|
uint16 i=0; |
|
|
|
uint8* ptr; |
|
|
|
uint8 color8; |
|
|
|
uint16 pitch = 1024; |
|
|
|
MNTZZ9KRegs* registers = b->registers; |
|
|
|
uint8* gfxmem = (uint8*)b->memory; |
|
|
|
uint32 color_format = b->color_format; |
|
|
|
uint32 offset = 0; |
|
|
|
|
|
|
|
if (w<1 || h<1) return; |
|
|
|
|
|
|
|
if (r) { |
|
|
|
offset = (r->memory-(b->memory)); |
|
|
|
zzwrite16(registers, ®isters->blitter_dst_hi, (offset&0xffff0000)>>16); |
|
|
|
zzwrite16(registers, ®isters->blitter_dst_lo, offset&0xffff); |
|
|
|
pitch = r->pitch; |
|
|
|
gfxmem = (uint8*)r->memory; |
|
|
|
color_format = r->color_format; |
|
|
|
} else { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
color_format = rtg_to_mnt_colormode(color_format); |
|
|
|
|
|
|
|
zzwrite16(registers, ®isters->blitter_rgb_hi, color>>16); |
|
|
|
zzwrite16(registers, ®isters->blitter_rgb_lo, color&0xffff); |
|
|
|
zzwrite16(registers, ®isters->blitter_row_pitch, pitch>>2); |
|
|
|
zzwrite16(registers, ®isters->blitter_colormode, color_format); |
|
|
|
zzwrite16(registers, ®isters->blitter_x1, x); |
|
|
|
zzwrite16(registers, ®isters->blitter_y1, y); |
|
|
|
zzwrite16(registers, ®isters->blitter_x2, x+w-1); |
|
|
|
zzwrite16(registers, ®isters->blitter_y2, y+h-1); |
|
|
|
zzwrite16(registers, ®isters->blitter_op_fillrect, 1); |
|
|
|
} |
|
|
|
|
|
|
|
void rect_copy(__reg("a0") struct RTGBoard* b,__reg("a1") struct RenderInfo* r,__reg("d0") uint16 x,__reg("d1") uint16 y,__reg("d2") uint16 dx,__reg("d3") uint16 dy,__reg("d4") uint16 w,__reg("d5") uint16 h,__reg("d6") uint8 m,__reg("d7") uint16 format) { |
|
|
|
MNTZZ9KRegs* registers = b->registers; |
|
|
|
uint16 pitch = 1024; |
|
|
|
uint32 color_format = b->color_format; |
|
|
|
uint8* gfxmem = (uint8*)b->memory; |
|
|
|
uint32 offset = 0, y1, y3; |
|
|
|
|
|
|
|
if (w<1 || h<1) return; |
|
|
|
|
|
|
|
if (r) { |
|
|
|
pitch = r->pitch; |
|
|
|
color_format = r->color_format; |
|
|
|
gfxmem = (uint8*)r->memory; |
|
|
|
} else { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
color_format = rtg_to_mnt_colormode(color_format); |
|
|
|
|
|
|
|
zzwrite16(registers, ®isters->blitter_y1, dy); |
|
|
|
zzwrite16(registers, ®isters->blitter_y2, dy+h-1); |
|
|
|
zzwrite16(registers, ®isters->blitter_y3, y); |
|
|
|
|
|
|
|
zzwrite16(registers, ®isters->blitter_x1, dx); |
|
|
|
zzwrite16(registers, ®isters->blitter_x2, dx+w-1); |
|
|
|
zzwrite16(registers, ®isters->blitter_x3, x); |
|
|
|
|
|
|
|
zzwrite16(registers, ®isters->blitter_row_pitch, pitch>>2); |
|
|
|
zzwrite16(registers, ®isters->blitter_colormode, color_format); |
|
|
|
|
|
|
|
offset = (r->memory-(b->memory)); |
|
|
|
zzwrite16(registers, ®isters->blitter_src_hi, (offset&0xffff0000)>>16); |
|
|
|
zzwrite16(registers, ®isters->blitter_src_lo, offset&0xffff); |
|
|
|
|
|
|
|
offset = (r->memory-(b->memory)); |
|
|
|
zzwrite16(registers, ®isters->blitter_dst_hi, (offset&0xffff0000)>>16); |
|
|
|
zzwrite16(registers, ®isters->blitter_dst_lo, offset&0xffff); |
|
|
|
|
|
|
|
zzwrite16(registers, ®isters->blitter_op_copyrect, 2); |
|
|
|
} |
|
|
|
|
|
|
|
void blitter_wait(__reg("a0") struct RTGBoard* b) { |
|
|
|
} |