/ MCUME_teensy / teensycastaway / blitter.cpp
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  }