02 Aug 93 WRS started
25 Aug 93 WRS basic stuff, with 2-at-a-time loop, seems to work.
              simple 16bpp and 32bpp cases have been shown to work.
              PlotMaskScaled coded but doesn't work yet.
              double-pixel sprites mysteriously wrong.
              old compiler taken out - module now 30K (was 18K when I started...)
27 Aug 93 WRS checking for unit translation table moved into assembler (in Sources.PutScaled)
 1 Sep 93 WRS optimised loop for inner loop just being a block transfer (in Sources.PutScaled)
28 Sep 93 WRS JPEG decompression, with assembler DCT/colour conv/huffman, works.

PlotMask - precise meaning of the ECF pointers etc.?
eg. shadows in DragASprite seem to come out cyan, should be black - but I feel
there are F pixels in the ECF pattern, where do the 7 pixels come from? Confused.
ECF plotting - ignoring the EOR word at the moment.

double-pixel sprites - mystery of apparently random behaviour.

Are there times when a 16bit pixel is better off in the
top half of r_pixel? Not thought through yet.

When a pixel is masked, I generate a B around the fetch/xlate/put
code. This is often around 2 or 3 instructions - would be better
to make those instructions conditional.
  Are they always conditionalisable? Not thought through.

At the moment I don't believe the inner loop can spill its registers. If it
does, the most effective short-term measure is for temp1 and temp2 to be
overlaid with something, and STM..LDM to surround their use. Bank switching
is a more powerful general technique, but requires STM,LDM every time you
switch banks. If it comes to this I'd victimise masks first as a thing to
slow down, especially 1BPP masks which are quite expensive.

-------------------------------------------

Other misc things to do/check:

test prog needs doing!
Want TPSS to run in any mode. Generate an xlation table if the modes aren't
compatible - is there a SWI to do this?

>>> I have moved to using PL and MI for the add/div sums, so that I can do
it all as constants. Is this OK? What if it isn't? Needs add/div to be
very big in order to matter, should at least check for this.
(actually do I need this, or is CS/CC still correct after fragmentary
unsigned add/sub? no!)
After all, in the assembler the coordinate is multiplied by xdiv,
divided by xadd - is all this really going to work if xdiv/xadd are
close to 32 bits big?

>>> Initial loading in the compiled code is all off R12 - for an x loop with
max variables, isn't this used? Then it will be trampled on before y vars
are loaded. Can this happen? If so, consider loading all off R14 instead.
At least put in asserts to guard against this.
  If used in one-bank case, surely the very last load loads the last register
declared so there's no problem? Again, check for this carefully.

Augst 93 WRS: I've worked on custom code for scale-up and scale-down along
an x line, but it scarely seems worth it. You end up saving one or two
instructions per source/dest pixel (whichever there is fewer of!). Custom
2:1 would probably be more effective, but is it really important? Abandoned.

---------------------------------------------------------

GPS - Inner loop spills a register when plotting 16bpp sprite with mask and
dithering (ie Scaling up and losing depth)
    FIX - Stopped r12(wp) from being overwritten until after all variables
          had been moved to the stack.

GPS - Plot corrupted when left hand side of sprite obscured.
    FIX - Mask shift was being stored in top 5 bits of register but not
          shifted down when originally used in mask_word rotate.

/* BEWARE 10000 VOLTS (this park will never fail, the TRex will never get
 * out, etc) - This code is not linked with the C library so any high-level
 * functions it uses must be implemented here too. Any static variables must
 * go in the 'workspace' structure definition (as opposed to using the 'static' C keyword).
 */

/* BEWARE 20000 VOLTS - The PlotMaskScaled code has to continue to use the kernel's
 * internal ECF pattern for the foreground and background colours. This is because when
 * performing a PaintCharScaled of the delete character the kernel temporarily swaps the
 * foreground patter with the background one to make it work! Change this at your own
 * risk... GPS (after having to change it all!) 23/3/95
 */

/* Most of the code generation is split into several areas: fetching a
pixel, writing a pixel, advancing source pointer, advancing destination
pointer, handling the x loop, handling the y loop. For each of these
register declarations, initialisation, and actually doing it are presented
separately. */

/* r_inword rotates right, so that the 'current' pixel is at the least
significant end. r_inshift contains the number of bits it still has to
rotate before we have used all the input pixels. r_outword and r_outshift
behave similarly. */

/* If doing PLOTMASK then r_inptr points at the ECF pattern, r_inword holds
data from the ECF pattern and rotates with r_outshift.
r_maskinword/ptr/shift are used to get the mask data. */

