MCUME/MCUME_teensy/teensycastaway/blitter.cpp

214 wiersze
7.7 KiB
C++

/*
* Castaway
* (C) 1994 - 2002 Martin Doering, Joachim Hoenig
*
* blitter.c - ST blitter chip emulation
*
* This file is distributed under the GPL, version 2 or at your
* option any later version. See doc/license.txt for details.
*
* revision history
* 23.05.2002 JH FAST1.0.1 code import: KR -> ANSI, restructuring
* 09.06.2002 JH Renamed io.c to st.c again (io.h conflicts with system headers)
* 02.10.2002 JH use uint16 etc.
*/
static char sccsid[] = "$Id: blitter.c,v 1.3 2002/10/02 22:44:51 jhoenig Exp $";
#include <stdio.h>
#include "dcastaway.h"
#include "st.h"
#include "mem.h"
#include "m68k_intrf.h"
#include <Arduino.h>
#define FXSR 0x80
#define NFSR 0x40
#define SKEW 0x0f
#define BUSY 0x80
#define HOG 0x40
#define SMUDGE 0x20
#define LINENO 0x0f
PROGMEM void bitblt(void)
{
uint32 blt_src_in;
uint16 blt_src_out, blt_hop_out, blt_dst_in, blt_dst_out, mask_out;
int xc, yc, lineno, last, first;
#if (VERBOSE & 0x8)
DBG_OUT ("bitblt: Start\n");
DBG_OUT ("HALFT[] 0x%04x-%04x-%04x-%04x\n", (uint16) blt_halftone[0], blt_halftone[1], blt_halftone[2], blt_halftone[3]);
DBG_OUT ("Y COUNT 0x%04x\n", (uint16) blt_y_cnt);
DBG_OUT ("X COUNT 0x%04x\n", (uint16) blt_x_cnt);
DBG_OUT ("X S INC 0x%04x\n", (uint16) blt_src_x_inc);
DBG_OUT ("Y S INC 0x%04x\n", (uint16) blt_src_y_inc);
DBG_OUT ("X D INC 0x%04x\n", (uint16) blt_dst_x_inc);
DBG_OUT ("Y D INC 0x%04x\n", (uint16) blt_dst_y_inc);
DBG_OUT ("ENDMASK 0x%04x-%04x-%04x\n", (uint16) blt_end_1, (uint16) blt_end_2, (uint16) blt_end_3);
DBG_OUT ("S_ADDR 0x%08lx\n", blt_src_addr);
DBG_OUT ("D_ADDR 0x%08lx\n", blt_dst_addr);
DBG_OUT ("HOP=%01d, OP=%02d\n", blt_hop & 0x3, blt_op & 0xf);
DBG_OUT ("HOPline=%02d\n", blt_status & 0xf);
DBG_OUT ("NFSR=%d, FXSR=%d, SKEW=%02d\n", (blt_skew & NFSR) != 0,
(blt_skew & FXSR) != 0,
(blt_skew & SKEW));
#endif
yc = (blt_y_cnt == 0) ? 65536 : blt_y_cnt;
while (yc-- > 0) {
xc = (blt_x_cnt == 0) ? 65536 : blt_x_cnt;
first = 1;
blt_src_in = 0;
/* next line to get rid of obnoxious compiler warnings */
blt_src_out = blt_hop_out = blt_dst_out = 0;
while (xc-- > 0) {
last = (xc == 0);
if ((blt_hop & 0x03) >= 2) {
/* read source into blt_src_in */
if (blt_src_x_inc >= 0) {
if (first && (blt_skew & FXSR)) {
blt_src_in = (GetMemW (blt_src_addr) << 16);
blt_src_addr += blt_src_x_inc;
} else {
blt_src_in <<= 16;
}
if (last && (blt_skew & NFSR)) {
blt_src_addr -= blt_src_x_inc;
} else {
blt_src_in |= (uint16) GetMemW (blt_src_addr);
if (!last) {
blt_src_addr += blt_src_x_inc;
}
}
} else {
if (first && (blt_skew & FXSR)) {
blt_src_in = (uint16) GetMemW (blt_src_addr);
blt_src_addr +=blt_src_x_inc;
} else {
blt_src_in >>= 16;
}
if (last && (blt_skew & NFSR)) {
blt_src_addr -= blt_src_x_inc;
} else {
blt_src_in |= (GetMemW (blt_src_addr) << 16);
if (!last) {
blt_src_addr += blt_src_x_inc;
}
}
}
/* shift blt_skew times into blt_src_out */
blt_src_out = blt_src_in >> (blt_skew & SKEW);
#if (VERBOSE & 0x8)
DBG_OUT ("%04x ", blt_src_out);
#endif
}
/* halftone OP */
lineno = ((blt_status & SMUDGE) ? blt_src_out : blt_status) & LINENO;
switch (blt_hop & 0x3) {
case 0:
blt_hop_out = 0xffff;
break;
case 1:
blt_hop_out = blt_halftone[lineno];
break;
case 2:
blt_hop_out = blt_src_out;
break;
case 3:
blt_hop_out = blt_src_out & blt_halftone[lineno];
break;
}
/* read destination into blt_dst_in */
blt_dst_in = GetMemW (blt_dst_addr);
/* op into blt_dst_out */
switch (blt_op & 0xf) {
case 0:
blt_dst_out = 0;
break;
case 1:
blt_dst_out = blt_hop_out & blt_dst_in;
break;
case 2:
blt_dst_out = blt_hop_out & ~blt_dst_in;
break;
case 3:
blt_dst_out = blt_hop_out;
break;
case 4:
blt_dst_out = ~blt_hop_out & blt_dst_in;
break;
case 5:
blt_dst_out = blt_dst_in;
break;
case 6:
blt_dst_out = blt_hop_out ^ blt_dst_in;
break;
case 7:
blt_dst_out = blt_hop_out | blt_dst_in;
break;
case 8:
blt_dst_out = ~blt_hop_out & ~blt_dst_in;
break;
case 9:
blt_dst_out = ~blt_hop_out ^ blt_dst_in;
break;
case 0xa:
blt_dst_out = ~blt_dst_in;
break;
case 0xb:
blt_dst_out = blt_hop_out | ~blt_dst_in;
break;
case 0xc:
blt_dst_out = ~blt_hop_out;
break;
case 0xd:
blt_dst_out = ~blt_hop_out | blt_dst_in;
break;
case 0xe:
blt_dst_out = ~blt_hop_out | ~blt_dst_in;
break;
case 0xf:
blt_dst_out = 0xffff;
break;
}
/* and endmask */
if (first) {
mask_out = (blt_dst_out & blt_end_1) | (blt_dst_in & ~blt_end_1);
} else if (last) {
mask_out = (blt_dst_out & blt_end_3) | (blt_dst_in & ~blt_end_3);
} else {
mask_out = (blt_dst_out & blt_end_2) | (blt_dst_in & ~blt_end_2);
}
SetMemW (blt_dst_addr, mask_out);
if (!last) {
blt_dst_addr += blt_dst_x_inc;
}
first = 0;
}
#if (VERBOSE & 0x8)
DBG_OUT ("\n");
#endif
blt_status = (blt_status + ((blt_dst_y_inc >= 0) ? 1 : 15)) & 0xef;
blt_src_addr += blt_src_y_inc;
blt_dst_addr += blt_dst_y_inc;
}
/* blt_status &= ~BUSY; */
blt_y_cnt = 0;
#if (VERBOSE & 0x8)
DBG_OUT ("bitblt: End\n");
DBG_OUT ("HALFT[] 0x%04x-%04x-%04x-%04x\n", (uint16) blt_halftone[0], blt_halftone[1], blt_halftone[2], blt_halftone[3]);
DBG_OUT ("Y COUNT 0x%04x\n", (uint16) blt_y_cnt);
DBG_OUT ("X COUNT 0x%04x\n", (uint16) blt_x_cnt);
DBG_OUT ("X S INC 0x%04x\n", (uint16) blt_src_x_inc);
DBG_OUT ("Y S INC 0x%04x\n", (uint16) blt_src_y_inc);
DBG_OUT ("X D INC 0x%04x\n", (uint16) blt_dst_x_inc);
DBG_OUT ("Y D INC 0x%04x\n", (uint16) blt_dst_y_inc);
DBG_OUT ("ENDMASK 0x%04x-%04x-%04x\n", (uint16) blt_end_1, (uint16) blt_end_2, (uint16) blt_end_3);
DBG_OUT ("S_ADDR 0x%08lx\n", blt_src_addr);
DBG_OUT ("D_ADDR 0x%08lx\n", blt_dst_addr);
DBG_OUT ("HOP=%01d, OP=%02d\n", blt_hop & 0x3, blt_op & 0xf);
DBG_OUT ("HOPline=%02d\n", blt_status & 0xf);
DBG_OUT ("NFSR=%d, FXSR=%d, SKEW=%02d\n", (blt_skew & NFSR) != 0,
(blt_skew & FXSR) != 0,
(blt_skew & SKEW));
#endif
}