/*************************************************************************** video/apple3.c Apple /// ***************************************************************************/ #include "emu.h" #include "includes/apple3.h" #include "machine/ram.h" #define BLACK 0 #define DKRED 1 #define DKBLUE 2 #define PURPLE 3 #define DKGREEN 4 #define DKGRAY 5 #define BLUE 6 #define LTBLUE 7 #define BROWN 8 #define ORANGE 9 #define GRAY 10 #define PINK 11 #define GREEN 12 #define YELLOW 13 #define AQUA 14 #define WHITE 15 // derived from the IIgs palette then adjusted to match Sara static const unsigned char apple3_palette[] = { // text colors, which don't match the Apple II palette 0x0, 0x0, 0x0, /* Black $0 */ 0x5, 0x0, 0x5, /* Magenta $1 */ 0x0, 0x0, 0x9, /* Dark Blue $2 */ 0xD, 0x2, 0xD, /* Purple $3 */ 0x0, 0x7, 0x2, /* Dark Green $4 */ 0xa, 0xa, 0xa, /* Light Gray $5 */ 0x2, 0x2, 0xF, /* Medium Blue $6 */ 0x6, 0xA, 0xF, /* Light Blue $7 */ 0x8, 0x5, 0x0, /* Brown $8 */ 0xF, 0x6, 0x0, /* Orange $9 */ 0x5, 0x5, 0x5, /* Dark Gray $A */ 0xF, 0x9, 0xF, /* Pink $B */ 0x1, 0xD, 0x0, /* Light Green $C */ 0xe, 0xe, 0x0, /* Yellow $D */ 0x4, 0xe, 0xd, /* Cyan $E */ 0xF, 0xF, 0xF, /* White $F */ // graphics colors, which *are* Apple II order 0x0, 0x0, 0x0, /* Black $0 */ 0xD, 0x0, 0x3, /* Deep Red $1 */ 0x0, 0x0, 0x9, /* Dark Blue $2 */ 0xD, 0x2, 0xD, /* Purple $3 */ 0x0, 0x7, 0x2, /* Dark Green $4 */ 0x5, 0x5, 0x5, /* Dark Gray $5 */ 0x2, 0x2, 0xF, /* Medium Blue $6 */ 0x6, 0xA, 0xF, /* Light Blue $7 */ 0x8, 0x5, 0x0, /* Brown $8 */ 0xF, 0x6, 0x0, /* Orange $9 */ 0xA, 0xA, 0xA, /* Light Gray $A */ 0xF, 0x9, 0x8, /* Pink $B */ 0x1, 0xD, 0x0, /* Light Green $C */ 0xF, 0xF, 0x0, /* Yellow $D */ 0x4, 0xF, 0x9, /* Aquamarine $E */ 0xF, 0xF, 0xF /* White $F */ }; static const UINT32 text_map[] = { 0x400, 0x480, 0x500, 0x580, 0x600, 0x680, 0x700, 0x780, 0x428, 0x4a8, 0x528, 0x5a8, 0x628, 0x6a8, 0x728, 0x7a8, 0x450, 0x4d0, 0x550, 0x5d0, 0x650, 0x6d0, 0x750, 0x7d0 }; PALETTE_INIT_MEMBER(apple3_state, apple3) { int i; for (i = 0; i < 32; i++) { m_palette->set_pen_color(i, apple3_palette[(3*i)]*17, apple3_palette[(3*i)+1]*17, apple3_palette[(3*i)+2]*17); } } void apple3_state::apple3_write_charmem() { address_space& space = m_maincpu->space(AS_PROGRAM); static const UINT32 screen_hole_map[] = { 0x478, 0x4f8, 0x578, 0x5f8, 0x678, 0x6f8, 0x778, 0x7f8 }; int i, j, addr; UINT8 val; for (i = 0; i < 8; i++) { for (j = 0; j < 4; j++) { addr = 0x7f & space.read_byte(screen_hole_map[i] + 0x400 + j + 0); val = space.read_byte(screen_hole_map[i] + j + 0); m_char_mem[((addr * 8) + ((i & 3) * 2) + 0) & 0x3ff] = val; addr = 0x7f & space.read_byte(screen_hole_map[i] + 0x400 + j + 4); val = space.read_byte(screen_hole_map[i] + j + 4); m_char_mem[((addr * 8) + ((i & 3) * 2) + 1) & 0x3ff] = val; } } } VIDEO_START_MEMBER(apple3_state,apple3) { int i, j; UINT32 v; memset(m_char_mem, 0, 0x800); m_hgr_map = auto_alloc_array(machine(), UINT32, 192); for (i = 0; i < 24; i++) { v = text_map[i] - 0x0400; for (j = 0; j < 8; j++) { m_hgr_map[(i * 8) + j] = 0x2000 + v + (j * 0x400); } } } void apple3_state::apple3_video_text40(bitmap_ind16 &bitmap) { int x, y, col, row; offs_t offset; UINT8 ch; const UINT8 *char_data; pen_t fg, bg, temp; UINT16 *dest; UINT8 *ram = m_ram->pointer(); UINT32 ram_size = m_ram->size(); for (y = 0; y < 24; y++) { for (x = 0; x < 40; x++) { offset = ram_size - 0x8000 + text_map[y] + x + (m_flags & VAR_VM2 ? 0x0400 : 0x0000); ch = ram[offset]; if (m_flags & VAR_VM0) { /* color text */ offset = ram_size - 0x8000 + text_map[y] + x + (m_flags & VAR_VM2 ? 0x0000 : 0x0400); bg = (ram[offset] >> 0) & 0x0F; fg = (ram[offset] >> 4) & 0x0F; } else { /* monochrome */ bg = BLACK; fg = GREEN; } /* inverse? */ if (!(ch & 0x80)) { temp = fg; fg = bg; bg = temp; } char_data = &m_char_mem[(ch & 0x7F) * 8]; for (row = 0; row < 8; row++) { for (col = 0; col < 7; col++) { dest = &bitmap.pix16(y * 8 + row, x * 14 + col * 2); dest[0] = (char_data[row] & (1 << col)) ? fg : bg; dest[1] = (char_data[row] & (1 << col)) ? fg : bg; } } } } } void apple3_state::apple3_video_text80(bitmap_ind16 &bitmap) { int x, y, col, row; offs_t offset; UINT8 ch; const UINT8 *char_data; pen_t fg, bg; UINT16 *dest; UINT8 *ram = m_ram->pointer(); UINT32 ram_size = m_ram->size(); for (y = 0; y < 24; y++) { for (x = 0; x < 40; x++) { offset = ram_size - 0x8000 + text_map[y] + x; /* first character */ ch = ram[offset + 0x0000]; char_data = &m_char_mem[(ch & 0x7F) * 8]; fg = (ch & 0x80) ? GREEN : BLACK; bg = (ch & 0x80) ? BLACK : GREEN; for (row = 0; row < 8; row++) { for (col = 0; col < 7; col++) { dest = &bitmap.pix16(y * 8 + row, x * 14 + col + 0); *dest = (char_data[row] & (1 << col)) ? fg : bg; } } /* second character */ ch = ram[offset + 0x0400]; char_data = &m_char_mem[(ch & 0x7F) * 8]; fg = (ch & 0x80) ? GREEN : BLACK; bg = (ch & 0x80) ? BLACK : GREEN; for (row = 0; row < 8; row++) { for (col = 0; col < 7; col++) { dest = &bitmap.pix16(y * 8 + row, x * 14 + col + 7); *dest = (char_data[row] & (1 << col)) ? fg : bg; } } } } } void apple3_state::apple3_video_graphics_hgr(bitmap_ind16 &bitmap) { /* hi-res mode: 280x192x2 */ int y, i, x; const UINT8 *pix_info; UINT16 *ptr; UINT8 b; UINT8 *ram = m_ram->pointer(); for (y = 0; y < 192; y++) { if (m_flags & VAR_VM2) pix_info = &ram[m_hgr_map[y]]; else pix_info = &ram[m_hgr_map[y] - 0x2000]; ptr = &bitmap.pix16(y); for (i = 0; i < 40; i++) { b = *(pix_info++); for (x = 0; x < 7; x++) { ptr[0] = ptr[1] = (b & 0x01) ? WHITE : BLACK; ptr += 2; b >>= 1; } } } } void apple3_state::apple3_video_graphics_chgr(bitmap_ind16 &bitmap) { /* color hi-res mode: 280x192x16 */ int y, i, x; const UINT8 *pix_info; const UINT8 *col_info; UINT16 *ptr; UINT8 b; UINT16 fgcolor, bgcolor; UINT8 *ram = m_ram->pointer(); for (y = 0; y < 192; y++) { if (m_flags & VAR_VM2) { pix_info = &ram[m_hgr_map[y] + 0x2000]; col_info = &ram[m_hgr_map[y] + 0x4000]; } else { pix_info = &ram[m_hgr_map[y] - 0x2000]; col_info = &ram[m_hgr_map[y]]; } ptr = &bitmap.pix16(y); for (i = 0; i < 40; i++) { bgcolor = ((*col_info >> 0) & 0x0F) + 16; fgcolor = ((*col_info >> 4) & 0x0F) + 16; b = *pix_info; for (x = 0; x < 7; x++) { ptr[0] = ptr[1] = (b & 1) ? fgcolor : bgcolor; ptr += 2; b >>= 1; } pix_info++; col_info++; } } } void apple3_state::apple3_video_graphics_shgr(bitmap_ind16 &bitmap) { /* super hi-res mode: 560x192x2 */ int y, i, x; const UINT8 *pix_info1; const UINT8 *pix_info2; UINT16 *ptr; UINT8 b1, b2; UINT8 *ram = m_ram->pointer(); for (y = 0; y < 192; y++) { if (m_flags & VAR_VM2) { pix_info1 = &ram[m_hgr_map[y] + 0x2000]; pix_info2 = &ram[m_hgr_map[y] + 0x4000]; } else { pix_info1 = &ram[m_hgr_map[y] - 0x2000]; pix_info2 = &ram[m_hgr_map[y]]; } ptr = &bitmap.pix16(y); for (i = 0; i < 40; i++) { b1 = *(pix_info1++); b2 = *(pix_info2++); for (x = 0; x < 7; x++) { *(ptr++) = (b1 & 0x01) ? WHITE : BLACK; b1 >>= 1; } for (x = 0; x < 7; x++) { *(ptr++) = (b2 & 0x01) ? WHITE : BLACK; b2 >>= 1; } } } } void apple3_state::apple3_video_graphics_chires(bitmap_ind16 &bitmap) { UINT16 *pen; UINT8 p1, p2, p3, p4; int y, i; UINT8 *ram = m_ram->pointer(); for (y = 0; y < 192; y++) { pen = &bitmap.pix16(y); for (i = 0; i < 20; i++) { if (m_flags & VAR_VM2) { p1 = ram[m_hgr_map[y] + 0x2000 + (i * 2) + 0]; p2 = ram[m_hgr_map[y] + 0x4000 + (i * 2) + 0]; p3 = ram[m_hgr_map[y] + 0x2000 + (i * 2) + 1]; p4 = ram[m_hgr_map[y] + 0x4000 + (i * 2) + 1]; } else { p1 = ram[m_hgr_map[y] - 0x2000 + (i * 2) + 0]; p2 = ram[m_hgr_map[y] - 0x0000 + (i * 2) + 0]; p3 = ram[m_hgr_map[y] - 0x2000 + (i * 2) + 1]; p4 = ram[m_hgr_map[y] - 0x0000 + (i * 2) + 1]; } pen[ 0] = pen[ 1] = pen[ 2] = pen[ 3] = (p1 & 0x0f); pen[ 4] = pen[ 5] = pen[ 6] = pen[ 7] = ((p1 >> 4) & 0x07) | ((p2 & 1) << 3); pen[ 8] = pen[ 9] = pen[10] = pen[11] = ((p2 >> 1) & 0x0F); pen[12] = pen[13] = pen[14] = pen[15] = ((p2 >> 5) & 0x03) | ((p3 & 3) << 2); pen[16] = pen[17] = pen[18] = pen[19] = ((p3 >> 2) & 0x0F); pen[20] = pen[21] = pen[22] = pen[23] = ((p3 >> 6) & 0x01) | ((p4 << 1) & 0xe); pen[24] = pen[25] = pen[26] = pen[27] = ((p4 >> 3) & 0x0F); pen += 28; } } } UINT32 apple3_state::screen_update_apple3(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { // printf("gfx mode %x\n", m_flags & (VAR_VM3|VAR_VM1|VAR_VM0)); switch(m_flags & (VAR_VM3|VAR_VM1|VAR_VM0)) { case 0: case VAR_VM0: apple3_video_text40(bitmap); break; case VAR_VM1: case VAR_VM1|VAR_VM0: apple3_video_text80(bitmap); break; case VAR_VM3: apple3_video_graphics_hgr(bitmap); /* hgr mode */ break; case VAR_VM3|VAR_VM0: apple3_video_graphics_chgr(bitmap); break; case VAR_VM3|VAR_VM1: apple3_video_graphics_shgr(bitmap); break; case VAR_VM3|VAR_VM1|VAR_VM0: apple3_video_graphics_chires(bitmap); break; } return 0; }