trunk/src/mame/video/stvvdp2.c
| r20406 | r20407 | |
| 2094 | 2094 | \----------|----------|----------|----------|----------|----------|----------|---------*/ |
| 2095 | 2095 | #define STV_VDP2_COBB (state->m_vdp2_regs[0x11e/2]) |
| 2096 | 2096 | |
| 2097 | | #if NEW_VIDEO_CODE |
| 2098 | | static void saturn_vdp2_assign_variables(running_machine &machine,UINT32 offset,UINT16 data); |
| 2099 | | #endif |
| 2100 | | |
| 2101 | 2097 | /*For Debug purposes only*/ |
| 2102 | 2098 | static struct stv_vdp2_debugging |
| 2103 | 2099 | { |
| r20406 | r20407 | |
| 5636 | 5632 | |
| 5637 | 5633 | if(STV_VDP2_VRAMSZ) |
| 5638 | 5634 | printf("VDP2 sets up 8 Mbit VRAM!\n"); |
| 5639 | | |
| 5640 | | #if NEW_VIDEO_CODE |
| 5641 | | saturn_vdp2_assign_variables(space.machine(),offset,state->m_vdp2_regs[offset]); |
| 5642 | | #endif |
| 5643 | 5635 | } |
| 5644 | 5636 | |
| 5645 | 5637 | static int get_hblank_duration(running_machine &machine) |
| r20406 | r20407 | |
| 6843 | 6835 | |
| 6844 | 6836 | #endif |
| 6845 | 6837 | |
| 6846 | | #if NEW_VIDEO_CODE |
| 6847 | | |
| 6848 | | /* |
| 6849 | | Rewrite of VDP2 video code (VDP1 will follow up after this). |
| 6850 | | |
| 6851 | | Keyword there is use CUSTOM CODE for everything! |
| 6852 | | |
| 6853 | | we do a two-pass buffer copy so we can safely do post-processing stuff at some point. |
| 6854 | | */ |
| 6855 | | |
| 6856 | | /* |
| 6857 | | [0] NBG0 |
| 6858 | | [1] NBG1 |
| 6859 | | [2] NBG2 |
| 6860 | | [3] NBG3 |
| 6861 | | [4] RBG0 |
| 6862 | | [5] BACK |
| 6863 | | */ |
| 6864 | | |
| 6865 | | #define XB_SIZE 1024 |
| 6866 | | #define YB_SIZE 1024 |
| 6867 | | |
| 6868 | | static UINT32 layer_buffer[6][XB_SIZE*YB_SIZE]; |
| 6869 | | static UINT8 layer_tpen[6][XB_SIZE*YB_SIZE]; |
| 6870 | | |
| 6871 | | /* TODO: move in state machine */ |
| 6872 | | static struct{ |
| 6873 | | UINT8 bitmap_en; |
| 6874 | | UINT8 bpp; |
| 6875 | | UINT8 color_offset_en; |
| 6876 | | UINT8 color_offset_sel; |
| 6877 | | }m_vdp2_state[6]; |
| 6878 | | |
| 6879 | | static void saturn_vdp2_assign_variables(running_machine &machine,UINT32 offset,UINT16 data) |
| 6880 | | { |
| 6881 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 6882 | | |
| 6883 | | switch(offset) |
| 6884 | | { |
| 6885 | | case 0x028/2: |
| 6886 | | m_vdp2_state[0].bpp = STV_VDP2_N0CHCN; |
| 6887 | | m_vdp2_state[1].bpp = STV_VDP2_N1CHCN; |
| 6888 | | break; |
| 6889 | | case 0x02a/2: |
| 6890 | | m_vdp2_state[2].bpp = STV_VDP2_N2CHCN; |
| 6891 | | m_vdp2_state[3].bpp = STV_VDP2_N3CHCN; |
| 6892 | | break; |
| 6893 | | case 0x02c/2: |
| 6894 | | m_vdp2_state[0].bitmap_en = STV_VDP2_N0BMP; |
| 6895 | | m_vdp2_state[1].bitmap_en = STV_VDP2_N1BMP; |
| 6896 | | break; |
| 6897 | | case 0x110/2: |
| 6898 | | m_vdp2_state[0].color_offset_en = STV_VDP2_N0COEN; |
| 6899 | | m_vdp2_state[1].color_offset_en = STV_VDP2_N1COEN; |
| 6900 | | m_vdp2_state[2].color_offset_en = STV_VDP2_N2COEN; |
| 6901 | | m_vdp2_state[3].color_offset_en = STV_VDP2_N3COEN; |
| 6902 | | m_vdp2_state[4].color_offset_en = STV_VDP2_R0COEN; |
| 6903 | | m_vdp2_state[5].color_offset_en = STV_VDP2_BKCOEN; |
| 6904 | | // STV_VDP2_SPCOEN |
| 6905 | | break; |
| 6906 | | case 0x112/2: |
| 6907 | | m_vdp2_state[0].color_offset_sel = STV_VDP2_N0COSL; |
| 6908 | | m_vdp2_state[1].color_offset_sel = STV_VDP2_N1COSL; |
| 6909 | | m_vdp2_state[2].color_offset_sel = STV_VDP2_N2COSL; |
| 6910 | | m_vdp2_state[3].color_offset_sel = STV_VDP2_N3COSL; |
| 6911 | | m_vdp2_state[4].color_offset_sel = STV_VDP2_R0COSL; |
| 6912 | | m_vdp2_state[5].color_offset_sel = STV_VDP2_BKCOSL; |
| 6913 | | // STV_VDP2_SPCOEN |
| 6914 | | break; |
| 6915 | | } |
| 6916 | | } |
| 6917 | | |
| 6918 | | static void vdp2_draw_back(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 6919 | | { |
| 6920 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 6921 | | int x,y; |
| 6922 | | UINT8* gfxdata = state->m_vdp2.gfx_decode; |
| 6923 | | UINT32 base_offs,base_mask; |
| 6924 | | UINT8 interlace; |
| 6925 | | |
| 6926 | | interlace = (STV_VDP2_LSMD == 3)+1; |
| 6927 | | |
| 6928 | | /* draw black if BDCLMD and DISP are cleared */ |
| 6929 | | if(!(STV_VDP2_BDCLMD) && !(STV_VDP2_DISP)) |
| 6930 | | bitmap.fill(get_black_pen(machine), cliprect); |
| 6931 | | else |
| 6932 | | { |
| 6933 | | base_mask = STV_VDP2_VRAMSZ ? 0x7ffff : 0x3ffff; |
| 6934 | | |
| 6935 | | for(y=cliprect.min_y;y<=cliprect.max_y;y++) |
| 6936 | | { |
| 6937 | | base_offs = ((STV_VDP2_BKTA ) & base_mask) << 1; |
| 6938 | | if(STV_VDP2_BKCLMD) |
| 6939 | | base_offs += ((y / interlace) << 1); |
| 6940 | | |
| 6941 | | for(x=cliprect.min_x;x<=cliprect.max_x;x++) |
| 6942 | | { |
| 6943 | | int r,g,b; |
| 6944 | | UINT16 dot; |
| 6945 | | |
| 6946 | | dot = (gfxdata[base_offs+0]<<8)|gfxdata[base_offs+1]; |
| 6947 | | b = (dot & 0x7c00) >> 10; |
| 6948 | | g = (dot & 0x03e0) >> 5; |
| 6949 | | r = (dot & 0x001f) >> 0; |
| 6950 | | b <<= 3; |
| 6951 | | g <<= 3; |
| 6952 | | r <<= 3; |
| 6953 | | |
| 6954 | | //if(STV_VDP2_BKCOEN) |
| 6955 | | // stv_vdp2_compute_color_offset( machine, &r, &g, &b, STV_VDP2_BKCOSL ); |
| 6956 | | |
| 6957 | | /* TODO: this needs post-processing too! */ |
| 6958 | | bitmap.pix32(y, x) = b | g << 8 | r << 16; |
| 6959 | | } |
| 6960 | | } |
| 6961 | | } |
| 6962 | | } |
| 6963 | | |
| 6964 | | static void vdp2_palette_entry(running_machine &machine, int *r, int *g, int *b, UINT16 offset); |
| 6965 | | |
| 6966 | | static void get_vdp2_pixel(running_machine &machine, UINT8 layer_name, UINT16 tile,UINT8 color, int xi, int yi, int *r, int *g, int *b, int *tp) |
| 6967 | | { |
| 6968 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 6969 | | UINT8 *vram = state->m_vdp2.gfx_decode; |
| 6970 | | UINT32 vram_offset; |
| 6971 | | UINT32 vram_mask; |
| 6972 | | int pix; |
| 6973 | | |
| 6974 | | vram_mask = 0x7ffff; |
| 6975 | | |
| 6976 | | switch(m_vdp2_state[layer_name].bpp) |
| 6977 | | { |
| 6978 | | case 0: //2 bpp |
| 6979 | | if(m_vdp2_state[layer_name].bitmap_en) |
| 6980 | | vram_offset = tile; |
| 6981 | | else |
| 6982 | | vram_offset = tile*0x20+(yi*4)+(xi >> 1); |
| 6983 | | |
| 6984 | | pix = (vram[vram_offset & vram_mask] >> ((xi & 1) ^ 1)*4) & 0xf; |
| 6985 | | |
| 6986 | | vdp2_palette_entry(machine,&*r,&*g,&*b,(color<<4|pix) & 0x7ff); |
| 6987 | | |
| 6988 | | *tp = (pix != 0); |
| 6989 | | break; |
| 6990 | | case 1: //4 bpp |
| 6991 | | if(m_vdp2_state[layer_name].bitmap_en) |
| 6992 | | vram_offset = tile; |
| 6993 | | else |
| 6994 | | vram_offset = tile*0x40+(yi*8)+(xi); |
| 6995 | | |
| 6996 | | pix = (vram[vram_offset & vram_mask]) & 0xff; |
| 6997 | | |
| 6998 | | vdp2_palette_entry(machine,&*r,&*g,&*b,(color<<8|pix) & 0x7ff); |
| 6999 | | |
| 7000 | | *tp = (pix != 0); |
| 7001 | | break; |
| 7002 | | case 2: //11 bpp |
| 7003 | | popmessage("bpp == 2 in tilemap"); |
| 7004 | | |
| 7005 | | if(m_vdp2_state[layer_name].bitmap_en) |
| 7006 | | vram_offset = tile; |
| 7007 | | else |
| 7008 | | vram_offset = tile*0x40+(yi*8)+(xi); |
| 7009 | | |
| 7010 | | /* confused over this, but I should have done correctly: */ |
| 7011 | | pix = (vram[((vram_offset)*2+0) & vram_mask]<<8)| |
| 7012 | | (vram[((vram_offset)*2+1) & vram_mask]); |
| 7013 | | |
| 7014 | | vdp2_palette_entry(machine,&*r,&*g,&*b,(pix) & 0x7ff); |
| 7015 | | |
| 7016 | | *tp = (pix != 0); |
| 7017 | | break; |
| 7018 | | case 3: //RGB5 |
| 7019 | | if(m_vdp2_state[layer_name].bitmap_en) |
| 7020 | | vram_offset = tile; |
| 7021 | | else |
| 7022 | | vram_offset = tile*0x40+(yi*8)+(xi); |
| 7023 | | |
| 7024 | | pix = (vram[((vram_offset)*2+0) & vram_mask]<<8)| |
| 7025 | | (vram[((vram_offset)*2+1) & vram_mask]); |
| 7026 | | |
| 7027 | | *tp= ((pix & 0x8000) >> 15); |
| 7028 | | // *cc= *tp; |
| 7029 | | *b = ((pix & 0x7c00) >> 10); |
| 7030 | | *g = ((pix & 0x03e0) >> 5); |
| 7031 | | *r = ((pix & 0x001f) >> 0); |
| 7032 | | *b <<= 3; |
| 7033 | | *g <<= 3; |
| 7034 | | *r <<= 3; |
| 7035 | | break; |
| 7036 | | case 4: //RGB8 |
| 7037 | | if(m_vdp2_state[layer_name].bitmap_en) |
| 7038 | | vram_offset = tile; |
| 7039 | | else |
| 7040 | | vram_offset = tile*0x80+(yi*8)+(xi); |
| 7041 | | |
| 7042 | | pix = (vram[((vram_offset)*4+0) & vram_mask]<<24)| |
| 7043 | | (vram[((vram_offset)*4+1) & vram_mask]<<16) | |
| 7044 | | (vram[((vram_offset)*4+2) & vram_mask]<<8)| |
| 7045 | | (vram[((vram_offset)*4+3) & vram_mask]); |
| 7046 | | |
| 7047 | | *tp= ((pix & 0x80000000) >> 31); |
| 7048 | | // *cc= *tp; |
| 7049 | | *b = ((pix & 0x00ff0000) >> 16); |
| 7050 | | *g = ((pix & 0x0000ff00) >> 8); |
| 7051 | | *r = ((pix & 0x000000ff) >> 0); |
| 7052 | | break; |
| 7053 | | default: |
| 7054 | | popmessage("Setting invalid for NBG%d!",layer_name); |
| 7055 | | *tp = *b = *g = *r = 0; |
| 7056 | | break; |
| 7057 | | } |
| 7058 | | } |
| 7059 | | |
| 7060 | | /* copy the vram data into the vram buffer */ |
| 7061 | | static void vdp2_tile_draw(running_machine &machine, UINT8 layer_name, UINT16 tile, UINT8 color, int x, int y) |
| 7062 | | { |
| 7063 | | //saturn_state *state = machine.driver_data<saturn_state>(); |
| 7064 | | int xi,yi; |
| 7065 | | int r,g,b,tp; |
| 7066 | | |
| 7067 | | for(yi=0;yi<8;yi++) |
| 7068 | | { |
| 7069 | | for(xi=0;xi<8;xi++) |
| 7070 | | { |
| 7071 | | get_vdp2_pixel(machine,layer_name,tile,color,xi,yi, &r, &g, &b, &tp); |
| 7072 | | |
| 7073 | | layer_buffer[layer_name][(x*8+xi)+((y*8+yi)*XB_SIZE)] = (r << 16) | (g << 8) | (b); |
| 7074 | | layer_tpen[layer_name][(x*8+xi)+((y*8+yi)*XB_SIZE)] = tp; |
| 7075 | | } |
| 7076 | | } |
| 7077 | | } |
| 7078 | | |
| 7079 | | /* tile grid of NxN is copied there */ |
| 7080 | | static void copy_plane(running_machine &machine, UINT8 layer_name) |
| 7081 | | { |
| 7082 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 7083 | | UINT8 *vram = state->m_vdp2.gfx_decode; |
| 7084 | | int x,y; |
| 7085 | | UINT16 datax; |
| 7086 | | |
| 7087 | | for(y=0;y<64;y++) |
| 7088 | | { |
| 7089 | | for(x=0;x<64;x++) |
| 7090 | | { |
| 7091 | | UINT16 tile; |
| 7092 | | UINT8 color; |
| 7093 | | |
| 7094 | | datax = (vram[(x+y*64+0x31000)*2+0]<<8)|(vram[(x+y*64+0x31000)*2+1]&0xff); |
| 7095 | | tile = (datax & 0xff) | 0x3000; |
| 7096 | | color = ((datax & 0xf000) >> 12) | 0x40; |
| 7097 | | |
| 7098 | | vdp2_tile_draw(machine,layer_name,tile,color,x,y); |
| 7099 | | } |
| 7100 | | } |
| 7101 | | } |
| 7102 | | |
| 7103 | | static void vdp2_calc_color_offset(running_machine &machine, UINT8 layer_name, int *r, int *g, int *b) |
| 7104 | | { |
| 7105 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 7106 | | int base_offs; |
| 7107 | | int cor,cog,cob; |
| 7108 | | |
| 7109 | | base_offs = (0x114 + m_vdp2_state[layer_name].color_offset_sel*6); |
| 7110 | | |
| 7111 | | cor = (state->m_vdp2_regs[(base_offs+0)/2]) & 0x1ff; |
| 7112 | | cog = (state->m_vdp2_regs[(base_offs+2)/2]) & 0x1ff; |
| 7113 | | cob = (state->m_vdp2_regs[(base_offs+4)/2]) & 0x1ff; |
| 7114 | | |
| 7115 | | *r = (cor & 0x100) ? *r - (0x100 - (cor & 0xff)) : (*r + (cor & 0xff)); |
| 7116 | | *g = (cog & 0x100) ? *g - (0x100 - (cog & 0xff)) : (*g + (cog & 0xff)); |
| 7117 | | *b = (cob & 0x100) ? *b - (0x100 - (cob & 0xff)) : (*b + (cob & 0xff)); |
| 7118 | | |
| 7119 | | if(*r > 0xff) { *r = 0xff; } |
| 7120 | | if(*g > 0xff) { *g = 0xff; } |
| 7121 | | if(*b > 0xff) { *b = 0xff; } |
| 7122 | | if(*r < 0) { *r = 0; } |
| 7123 | | if(*g < 0) { *g = 0; } |
| 7124 | | if(*b < 0) { *b = 0; } |
| 7125 | | } |
| 7126 | | |
| 7127 | | /* now copy the vram buffer to the screen buffer, apply post-processing at this stage */ |
| 7128 | | static void draw_normal_screen(running_machine &machine, bitmap_rgb32 &bitmap,const rectangle &cliprect, UINT8 layer_name) |
| 7129 | | { |
| 7130 | | int x,y; |
| 7131 | | int r,g,b; |
| 7132 | | |
| 7133 | | |
| 7134 | | for(y=0;y<=cliprect.max_y;y++) |
| 7135 | | { |
| 7136 | | for(x=0;x<=cliprect.max_x;x++) |
| 7137 | | { |
| 7138 | | if(layer_tpen[layer_name][(x)+(y)*XB_SIZE]) |
| 7139 | | { |
| 7140 | | b = (layer_buffer[layer_name][(x)+(y)*XB_SIZE] & 0x0000ff); |
| 7141 | | g = (layer_buffer[layer_name][(x)+(y)*XB_SIZE] & 0x00ff00) >> 8; |
| 7142 | | r = (layer_buffer[layer_name][(x)+(y)*XB_SIZE] & 0xff0000) >> 16; |
| 7143 | | |
| 7144 | | /* apply color offset*/ |
| 7145 | | if(m_vdp2_state[layer_name].color_offset_en) |
| 7146 | | vdp2_calc_color_offset(machine,layer_name,&r,&g,&b); |
| 7147 | | |
| 7148 | | bitmap.pix32(y, x) = b | g << 8 | r << 16; |
| 7149 | | } |
| 7150 | | } |
| 7151 | | } |
| 7152 | | } |
| 7153 | | |
| 7154 | | /* translated cram into RGB32 format color pen */ |
| 7155 | | static void vdp2_palette_entry(running_machine &machine, int *r, int *g, int *b, UINT16 offset) |
| 7156 | | { |
| 7157 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 7158 | | |
| 7159 | | switch( STV_VDP2_CRMD ) |
| 7160 | | { |
| 7161 | | case 0: // RGB5, 1024 color pens |
| 7162 | | offset &= 0x7ff; |
| 7163 | | case 1: // RGB5: 2048 color pens |
| 7164 | | { |
| 7165 | | UINT16 datax = (state->m_vdp2_cram[offset/2] >> (((offset & 1) ^ 1)*16)) & 0xffff; |
| 7166 | | |
| 7167 | | // *cc= ((datax & 0x8000) >> 15); |
| 7168 | | *b = ((datax & 0x7c00) >> 10); |
| 7169 | | *g = ((datax & 0x03e0) >> 5); |
| 7170 | | *r = ((datax & 0x001f) >> 0); |
| 7171 | | *b <<= 3; |
| 7172 | | *g <<= 3; |
| 7173 | | *r <<= 3; |
| 7174 | | break; |
| 7175 | | } |
| 7176 | | case 2: // RGB8: 1024 color pens |
| 7177 | | case 3: // (mode 3 is reserved but seems to be identical to above) |
| 7178 | | { |
| 7179 | | // *cc= ((state->m_vdp2_cram[offset] & 0x80000000) >> 31); |
| 7180 | | *b = ((state->m_vdp2_cram[offset] & 0x00ff0000) >> 16); |
| 7181 | | *g = ((state->m_vdp2_cram[offset] & 0x0000ff00) >> 8); |
| 7182 | | *r = ((state->m_vdp2_cram[offset] & 0x000000ff) >> 0); |
| 7183 | | } |
| 7184 | | break; |
| 7185 | | } |
| 7186 | | } |
| 7187 | | |
| 7188 | | UINT32 saturn_state::screen_update_saturn(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 7189 | | { |
| 7190 | | saturn_state *state = machine().driver_data<saturn_state>(); |
| 7191 | | static UINT8 disclaimer; |
| 7192 | | |
| 7193 | | vdp2_draw_back(machine(),bitmap,cliprect); |
| 7194 | | |
| 7195 | | if(STV_VDP2_DISP) |
| 7196 | | { |
| 7197 | | copy_plane(machine(),3); |
| 7198 | | |
| 7199 | | draw_normal_screen(machine(),bitmap,cliprect,3); |
| 7200 | | } |
| 7201 | | |
| 7202 | | if(disclaimer == 0) |
| 7203 | | { |
| 7204 | | disclaimer++; |
| 7205 | | popmessage("NEW Video code, rm me"); |
| 7206 | | } |
| 7207 | | |
| 7208 | | |
| 7209 | | return 0; |
| 7210 | | } |
| 7211 | | |
| 7212 | | #endif |