blitter.cpp
1 /* 2 * Castaway 3 * (C) 1994 - 2002 Martin Doering, Joachim Hoenig 4 * 5 * blitter.c - ST blitter chip emulation 6 * 7 * This file is distributed under the GPL, version 2 or at your 8 * option any later version. See doc/license.txt for details. 9 * 10 * revision history 11 * 23.05.2002 JH FAST1.0.1 code import: KR -> ANSI, restructuring 12 * 09.06.2002 JH Renamed io.c to st.c again (io.h conflicts with system headers) 13 * 02.10.2002 JH use uint16 etc. 14 */ 15 static char sccsid[] = "$Id: blitter.c,v 1.3 2002/10/02 22:44:51 jhoenig Exp $"; 16 #include <stdio.h> 17 #include "dcastaway.h" 18 #include "st.h" 19 #include "mem.h" 20 #include "m68k_intrf.h" 21 22 #include <Arduino.h> 23 24 #define FXSR 0x80 25 #define NFSR 0x40 26 #define SKEW 0x0f 27 #define BUSY 0x80 28 #define HOG 0x40 29 #define SMUDGE 0x20 30 #define LINENO 0x0f 31 32 PROGMEM void bitblt(void) 33 { 34 uint32 blt_src_in; 35 uint16 blt_src_out, blt_hop_out, blt_dst_in, blt_dst_out, mask_out; 36 int xc, yc, lineno, last, first; 37 #if (VERBOSE & 0x8) 38 DBG_OUT ("bitblt: Start\n"); 39 DBG_OUT ("HALFT[] 0x%04x-%04x-%04x-%04x\n", (uint16) blt_halftone[0], blt_halftone[1], blt_halftone[2], blt_halftone[3]); 40 DBG_OUT ("Y COUNT 0x%04x\n", (uint16) blt_y_cnt); 41 DBG_OUT ("X COUNT 0x%04x\n", (uint16) blt_x_cnt); 42 DBG_OUT ("X S INC 0x%04x\n", (uint16) blt_src_x_inc); 43 DBG_OUT ("Y S INC 0x%04x\n", (uint16) blt_src_y_inc); 44 DBG_OUT ("X D INC 0x%04x\n", (uint16) blt_dst_x_inc); 45 DBG_OUT ("Y D INC 0x%04x\n", (uint16) blt_dst_y_inc); 46 DBG_OUT ("ENDMASK 0x%04x-%04x-%04x\n", (uint16) blt_end_1, (uint16) blt_end_2, (uint16) blt_end_3); 47 DBG_OUT ("S_ADDR 0x%08lx\n", blt_src_addr); 48 DBG_OUT ("D_ADDR 0x%08lx\n", blt_dst_addr); 49 DBG_OUT ("HOP=%01d, OP=%02d\n", blt_hop & 0x3, blt_op & 0xf); 50 DBG_OUT ("HOPline=%02d\n", blt_status & 0xf); 51 DBG_OUT ("NFSR=%d, FXSR=%d, SKEW=%02d\n", (blt_skew & NFSR) != 0, 52 (blt_skew & FXSR) != 0, 53 (blt_skew & SKEW)); 54 #endif 55 yc = (blt_y_cnt == 0) ? 65536 : blt_y_cnt; 56 while (yc-- > 0) { 57 xc = (blt_x_cnt == 0) ? 65536 : blt_x_cnt; 58 first = 1; 59 blt_src_in = 0; 60 /* next line to get rid of obnoxious compiler warnings */ 61 blt_src_out = blt_hop_out = blt_dst_out = 0; 62 while (xc-- > 0) { 63 last = (xc == 0); 64 if ((blt_hop & 0x03) >= 2) { 65 /* read source into blt_src_in */ 66 if (blt_src_x_inc >= 0) { 67 if (first && (blt_skew & FXSR)) { 68 blt_src_in = (GetMemW (blt_src_addr) << 16); 69 blt_src_addr += blt_src_x_inc; 70 } else { 71 blt_src_in <<= 16; 72 } 73 if (last && (blt_skew & NFSR)) { 74 blt_src_addr -= blt_src_x_inc; 75 } else { 76 blt_src_in |= (uint16) GetMemW (blt_src_addr); 77 if (!last) { 78 blt_src_addr += blt_src_x_inc; 79 } 80 } 81 } else { 82 if (first && (blt_skew & FXSR)) { 83 blt_src_in = (uint16) GetMemW (blt_src_addr); 84 blt_src_addr +=blt_src_x_inc; 85 } else { 86 blt_src_in >>= 16; 87 } 88 if (last && (blt_skew & NFSR)) { 89 blt_src_addr -= blt_src_x_inc; 90 } else { 91 blt_src_in |= (GetMemW (blt_src_addr) << 16); 92 if (!last) { 93 blt_src_addr += blt_src_x_inc; 94 } 95 } 96 } 97 /* shift blt_skew times into blt_src_out */ 98 blt_src_out = blt_src_in >> (blt_skew & SKEW); 99 #if (VERBOSE & 0x8) 100 DBG_OUT ("%04x ", blt_src_out); 101 #endif 102 } 103 /* halftone OP */ 104 lineno = ((blt_status & SMUDGE) ? blt_src_out : blt_status) & LINENO; 105 switch (blt_hop & 0x3) { 106 case 0: 107 blt_hop_out = 0xffff; 108 break; 109 case 1: 110 blt_hop_out = blt_halftone[lineno]; 111 break; 112 case 2: 113 blt_hop_out = blt_src_out; 114 break; 115 case 3: 116 blt_hop_out = blt_src_out & blt_halftone[lineno]; 117 break; 118 } 119 /* read destination into blt_dst_in */ 120 blt_dst_in = GetMemW (blt_dst_addr); 121 /* op into blt_dst_out */ 122 switch (blt_op & 0xf) { 123 case 0: 124 blt_dst_out = 0; 125 break; 126 case 1: 127 blt_dst_out = blt_hop_out & blt_dst_in; 128 break; 129 case 2: 130 blt_dst_out = blt_hop_out & ~blt_dst_in; 131 break; 132 case 3: 133 blt_dst_out = blt_hop_out; 134 break; 135 case 4: 136 blt_dst_out = ~blt_hop_out & blt_dst_in; 137 break; 138 case 5: 139 blt_dst_out = blt_dst_in; 140 break; 141 case 6: 142 blt_dst_out = blt_hop_out ^ blt_dst_in; 143 break; 144 case 7: 145 blt_dst_out = blt_hop_out | blt_dst_in; 146 break; 147 case 8: 148 blt_dst_out = ~blt_hop_out & ~blt_dst_in; 149 break; 150 case 9: 151 blt_dst_out = ~blt_hop_out ^ blt_dst_in; 152 break; 153 case 0xa: 154 blt_dst_out = ~blt_dst_in; 155 break; 156 case 0xb: 157 blt_dst_out = blt_hop_out | ~blt_dst_in; 158 break; 159 case 0xc: 160 blt_dst_out = ~blt_hop_out; 161 break; 162 case 0xd: 163 blt_dst_out = ~blt_hop_out | blt_dst_in; 164 break; 165 case 0xe: 166 blt_dst_out = ~blt_hop_out | ~blt_dst_in; 167 break; 168 case 0xf: 169 blt_dst_out = 0xffff; 170 break; 171 } 172 /* and endmask */ 173 if (first) { 174 mask_out = (blt_dst_out & blt_end_1) | (blt_dst_in & ~blt_end_1); 175 } else if (last) { 176 mask_out = (blt_dst_out & blt_end_3) | (blt_dst_in & ~blt_end_3); 177 } else { 178 mask_out = (blt_dst_out & blt_end_2) | (blt_dst_in & ~blt_end_2); 179 } 180 SetMemW (blt_dst_addr, mask_out); 181 if (!last) { 182 blt_dst_addr += blt_dst_x_inc; 183 } 184 first = 0; 185 } 186 #if (VERBOSE & 0x8) 187 DBG_OUT ("\n"); 188 #endif 189 blt_status = (blt_status + ((blt_dst_y_inc >= 0) ? 1 : 15)) & 0xef; 190 blt_src_addr += blt_src_y_inc; 191 blt_dst_addr += blt_dst_y_inc; 192 } 193 /* blt_status &= ~BUSY; */ 194 blt_y_cnt = 0; 195 #if (VERBOSE & 0x8) 196 DBG_OUT ("bitblt: End\n"); 197 DBG_OUT ("HALFT[] 0x%04x-%04x-%04x-%04x\n", (uint16) blt_halftone[0], blt_halftone[1], blt_halftone[2], blt_halftone[3]); 198 DBG_OUT ("Y COUNT 0x%04x\n", (uint16) blt_y_cnt); 199 DBG_OUT ("X COUNT 0x%04x\n", (uint16) blt_x_cnt); 200 DBG_OUT ("X S INC 0x%04x\n", (uint16) blt_src_x_inc); 201 DBG_OUT ("Y S INC 0x%04x\n", (uint16) blt_src_y_inc); 202 DBG_OUT ("X D INC 0x%04x\n", (uint16) blt_dst_x_inc); 203 DBG_OUT ("Y D INC 0x%04x\n", (uint16) blt_dst_y_inc); 204 DBG_OUT ("ENDMASK 0x%04x-%04x-%04x\n", (uint16) blt_end_1, (uint16) blt_end_2, (uint16) blt_end_3); 205 DBG_OUT ("S_ADDR 0x%08lx\n", blt_src_addr); 206 DBG_OUT ("D_ADDR 0x%08lx\n", blt_dst_addr); 207 DBG_OUT ("HOP=%01d, OP=%02d\n", blt_hop & 0x3, blt_op & 0xf); 208 DBG_OUT ("HOPline=%02d\n", blt_status & 0xf); 209 DBG_OUT ("NFSR=%d, FXSR=%d, SKEW=%02d\n", (blt_skew & NFSR) != 0, 210 (blt_skew & FXSR) != 0, 211 (blt_skew & SKEW)); 212 #endif 213 }