Got it from the newsgroup, might be interesting for some of you
Emulator-developers...
READ BELOW!
--
>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<
email me: [EMAIL PROTECTED] or ICQ: 10196372
visit the Datax homepage at http://datax.cjb.net/
MSX fair Bussum / MSX Marathon homepage: http://msxfair.cjb.net/
>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<
> Albert Beevendorp ([EMAIL PROTECTED]) wrote:
> >For his vMSX (for which he stopped coding) but his research he handed
over
> >for fMSX. Don't know what Marat has implemented already... And I didn't
know
> >you were doing this as well, so excuse me for living :-)
>
> fMSX Amiga still bears the fMSX name, but is source-wise a completely
separate
> product now. The last bit of fMSX UNIX that was still present in fMSX
Amiga,
> which was the VDP command emulation, was removed a while ago. My own
rewrite
> of the VDP commands were based on my own research (many, many hours spent
> trying scenarios on the VDP in my 2+) and that of Alex Wulms (who no doubt
> spent an equally long time).
>
> I cannot really be sure whether it was the change to the VDP commands or
the
> change to the interrupt handling code that did the trick, but after I had
> changed both I noticed that SD Snatcher ran correctly. Of course SCC and
SCC+
> sound had been part of fMSX Amiga for a very long time already (not so
hard,
> since SCC is very similar to Amiga sound). The SCC code came in part from
fMSX
> UNIX (where stubs were present in the rommapping routines) and in part
from
> various MSX articles I found on the web (funet; MCCMs database). If Sean
Young
> had a hand in any of this he can at most be credited with writing the
> documentation that Marat or myself used to produce our code.
>
> Did Sean Young write that documentation? I don't have a clue, since I
don't
> know who he is. However, your careless assertion that he "no doubt" did
> something I definitely did myself rankles. In the free software world ther
e is
> only one gain to be made for the hours (thousands in my case) spent on
writing
> a program, and that is recognition.
>
> As an example of what I just told you I'll include the VDP command
emulator I
> wrote:
>
> /****************************************************************
>
> $VER: video.c 2.2 (6.6.99)
>
> ****************************************************************/
>
> #define INTUI_V36_NAMES_ONLY
>
> #include <exec/types.h>
> #include <stdio.h>
> #include <string.h>
>
> #include "defines.h"
> #include "typedefs.h"
> #include "panels/systemprefs.h"
> #include "video/screen5.h"
> #include "video/screen6.h"
> #include "video/screen7.h"
> #include "video/screen8.h"
> #include "video/vdata.h"
> #include "video/video.h"
> #include "video/vtypedefs.h"
>
> /***** DEFINES *****/
>
> #define TRANSFER_NONE 0
> #define TRANSFER_HMMC 1
> #define TRANSFER_LMMC 2
> #define TRANSFER_LMCM 3
>
> /***** GLOBAL VARIABLES *****/
>
> int LMCMTransfer = FALSE;
>
> /***** INSTANCE VARIABLES *****/
>
> static int (* __asm ReadPixelFunc) (register __d1 int, register __d2 int);
> static int (* __asm WritePixelFunc) (register __d1 int, register __d2 int,
register __d3 int, register __d4 int);
> static int (* __asm ReadByteFunc) (register __d1 int, register __d2 int);
> static int (* __asm WriteByteFunc) (register __d1 int, register __d2 int,
register __d3 int);
>
> static struct {
> int SX;
> int SY;
> int DX;
> int DY;
> int NX;
> int NY;
> int StepX;
> int StepY;
> int CopySX;
> int CopyDX;
> int CopyNX;
> int LogOp;
> int Mode;
> } Transfer;
>
> /***** EXTERNAL VARIABLES *****/
>
> extern struct VDATA *VData;
> extern struct REGISTERMAP *Regs;
>
>
>
>
> /* This function sets up the VDP for dealing with requests in the current
> screenmode.
> */
>
> void SetVDPFuncs (void)
> { switch (VData->Screenmode) {
> case 5:
> ReadPixelFunc = ReadPixel_5;
> WritePixelFunc = WritePixel_5;
> ReadByteFunc = ReadByte_5;
> WriteByteFunc = WriteByte_5;
> break;
>
> case 6:
> ReadPixelFunc = ReadPixel_6;
> WritePixelFunc = WritePixel_6;
> ReadByteFunc = ReadByte_6;
> WriteByteFunc = WriteByte_6;
> break;
>
> case 7:
> ReadPixelFunc = ReadPixel_7;
> WritePixelFunc = WritePixel_7;
> ReadByteFunc = ReadByte_7;
> WriteByteFunc = WriteByte_7;
> break;
>
> case 8:
> ReadPixelFunc = ReadPixel_8;
> WritePixelFunc = WritePixel_8;
> ReadByteFunc = ReadByte_8;
> WriteByteFunc = WriteByte_8;
> break;
>
> default:
> ReadPixelFunc = (int (* __asm)(register __d1 int, register
__d2 int))Stub;
> WritePixelFunc = (int (* __asm)(register __d1 int, register
__d2 int, register __d3 int, register __d4 int))Stub;
> ReadByteFunc = (int (* __asm)(register __d1 int, register __d2
int))Stub;
> WriteByteFunc = (int (* __asm)(register __d1 int, register
__d2 int, register __d3 int))Stub;
> }
>
> Transfer.Mode = TRANSFER_NONE;
> }
>
>
>
>
> /* This function performs one transfer step for HMMC, LMMC or LMCM.
> */
>
> int __asm __saveds DoTransfer (void)
> { int Pixel;
>
> switch (Transfer.Mode) {
> case TRANSFER_HMMC:
> Pixel = VData->VDP [44];
> (*WriteByteFunc) (Transfer.DX, Transfer.DY, Pixel);
>
> Transfer.DX += Transfer.StepX;
> Transfer.NX--;
>
> if (Transfer.NX <= 0) {
> Transfer.DX = Transfer.CopyDX;
> Transfer.NX = Transfer.CopyNX;
> Transfer.DY += Transfer.StepY;
> Transfer.NY--;
>
> if (Transfer.NY <= 0) {
> VData->VDPStatus [2] &= 0x7E;
> VData->VDP [38] = Transfer.DY;
> VData->VDP [39] = Transfer.DY >> 8;
> VData->VDP [42] = Transfer.NY;
> VData->VDP [43] = Transfer.NY >> 8;
> Transfer.Mode = TRANSFER_NONE;
> }
> }
> return 0;
>
> case TRANSFER_LMMC:
> Pixel = VData->VDP [44];
> (*WritePixelFunc) (Transfer.DX, Transfer.DY, Pixel,
Transfer.LogOp);
>
> Transfer.DX += Transfer.StepX;
> Transfer.NX--;
>
> if (Transfer.NX <= 0) {
> Transfer.DX = Transfer.CopyDX;
> Transfer.NX = Transfer.CopyNX;
> Transfer.DY += Transfer.StepY;
> Transfer.NY--;
>
> if (Transfer.NY <= 0) {
> VData->VDPStatus [2] &= 0x7E;
> VData->VDP [38] = Transfer.DY;
> VData->VDP [39] = Transfer.DY >> 8;
> VData->VDP [42] = Transfer.NY;
> VData->VDP [43] = Transfer.NY >> 8;
> Transfer.Mode = TRANSFER_NONE;
> }
> }
> return 0;
>
> case TRANSFER_LMCM:
> Pixel = (*ReadPixelFunc) (Transfer.SX, Transfer.SY);
>
> Transfer.SX += Transfer.StepX;
> Transfer.NX--;
>
> if (Transfer.NX <= 0) {
> Transfer.SX = Transfer.CopySX;
> Transfer.NX = Transfer.CopyNX;
> Transfer.SY += Transfer.StepY;
> Transfer.NY--;
>
> if (Transfer.NY <= 0) {
> VData->VDPStatus [2] &= 0x7E;
> VData->VDP [34] = Transfer.SY;
> VData->VDP [35] = Transfer.SY >> 8;
> VData->VDP [42] = Transfer.NY;
> VData->VDP [43] = Transfer.NY >> 8;
> Transfer.Mode = TRANSFER_NONE;
> LMCMTransfer = FALSE;
> }
> }
>
> VData->VDPStatus [7] = Pixel;
> VData->VDP [44] = Pixel;
> return Pixel;
> }
> }
>
>
>
>
> /***** The following functions read a coordinate from the VDP command
registers *****/
>
>
>
>
> int GetSX (BOOL HighSpeed)
> { int SX;
> static const ByteMask [4] = { 0x00FE, 0x01FC, 0x01FE, 0x00FF };
> static const PixMask [4] = { 0x00FF, 0x01FF, 0x01FF, 0x00FF };
>
> SX = VData->VDP [32] + ((int)(VData->VDP [33]) << 8);
>
> if (HighSpeed)
> SX &= ByteMask [VData->Screenmode - 5];
> else
> SX &= PixMask [VData->Screenmode - 5];
>
> return SX;
> }
>
>
>
>
> int GetSY (void)
> { int SY;
> static const Mask [4] = { 0x03FF, 0x03FF, 0x01FF, 0x01FF };
>
> SY = VData->VDP [34] + ((int)(VData->VDP [35]) << 8);
>
> SY &= Mask [VData->Screenmode - 5];
>
> return SY;
> }
>
>
>
>
> int GetDX (BOOL HighSpeed)
> { int DX;
> static const ByteMask [4] = { 0x00FE, 0x01FC, 0x01FE, 0x00FF };
> static const PixMask [4] = { 0x00FF, 0x01FF, 0x01FF, 0x00FF };
>
> DX = VData->VDP [36] + ((int)(VData->VDP [37]) << 8);
>
> if (HighSpeed)
> DX &= ByteMask [VData->Screenmode - 5];
> else
> DX &= PixMask [VData->Screenmode - 5];
>
> return DX;
> }
>
>
>
>
> int GetDY (void)
> { int DY;
> static const Mask [4] = { 0x03FF, 0x03FF, 0x01FF, 0x01FF };
>
> DY = VData->VDP [38] + ((int)(VData->VDP [39]) << 8);
>
> DY &= Mask [VData->Screenmode - 5];
>
> return DY;
> }
>
>
>
>
> int GetNX (BOOL HighSpeed, BOOL AcceptZero)
> { int NX;
> static const XShift [4] = { 1, 2, 1, 0 };
>
> NX = VData->VDP [40] + ((int)(VData->VDP [41]) << 8);
>
> NX &= 0x03FF;
>
> if ((NX == 0) && (!AcceptZero))
> NX = 512;
>
> if (HighSpeed && XShift [VData->Screenmode - 5])
> NX >>= XShift [VData->Screenmode - 5];
>
> return NX;
> }
>
>
>
>
> int GetNY (BOOL AcceptZero)
> { int NY;
>
> NY = VData->VDP [42] + ((int)(VData->VDP [43]) << 8);
>
> NY &= 0x03FF;
>
> if ((NY == 0) && (!AcceptZero))
> NY = 1024;
>
> return NY;
> }
>
>
>
>
> int GetStepX (BOOL HighSpeed)
> { int StepX;
> static const StepXSize [4] = { 2, 4, 2, 1 };
>
> StepX = VData->VDP [45] & 0x04 ? -1 : 1;
>
> if (HighSpeed)
> StepX *= StepXSize [VData->Screenmode - 5];
>
> return StepX;
> }
>
>
>
>
> int GetStepY (void)
> { int StepY;
>
> StepY = VData->VDP [45] & 0x08 ? -1 : 1;
>
> return StepY;
> }
>
>
>
>
> /***** The following functions each emulate a single VDP command *****/
>
>
>
>
> void HMMC (void)
> { Transfer.DX = GetDX (TRUE);
> Transfer.DY = GetDY ();
> Transfer.NX = GetNX (TRUE, FALSE);
> Transfer.NY = GetNY (FALSE);
> Transfer.StepX = GetStepX (TRUE);
> Transfer.StepY = GetStepY ();
> Transfer.CopyDX = Transfer.DX;
> Transfer.CopyNX = Transfer.NX;
> Transfer.Mode = TRANSFER_HMMC;
>
> VData->VDPStatus [2] |= 0x81;
>
> DoTransfer ();
> }
>
>
>
>
> void HMMM (void)
> { int SX, SY, DX, DY, NX, NY, StepX, StepY, Pixel, CopySX, CopyDX,
CopyNX;
>
> SX = GetSX (TRUE);
> SY = GetSY ();
> DX = GetDX (TRUE);
> DY = GetDY ();
> NX = GetNX (TRUE, FALSE);
> NY = GetNY (FALSE);
> StepX = GetStepX (TRUE);
> StepY = GetStepY ();
> CopySX = SX;
> CopyDX = DX;
> CopyNX = NX;
>
> do {
> SX = CopySX;
> DX = CopyDX;
> NX = CopyNX;
>
> do {
> Pixel = (*ReadByteFunc) (SX, SY);
> (*WriteByteFunc) (DX, DY, Pixel);
>
> SX += StepX;
> DX += StepX;
> NX--;
> } while (NX > 0);
>
> SY += StepY;
> DY += StepY;
> NY--;
> } while (NY > 0);
>
> VData->VDPStatus [2] &= 0xFE;
> VData->VDP [34] = SY;
> VData->VDP [35] = SY >> 8;
> VData->VDP [38] = DY;
> VData->VDP [39] = DY >> 8;
> VData->VDP [42] = NY;
> VData->VDP [43] = NY >> 8;
> }
>
>
>
>
> void HMMV (void)
> { int DX, DY, NX, NY, StepX, StepY, Pixel, CopyDX, CopyNX;
>
> DX = GetDX (TRUE);
> DY = GetDY ();
> NX = GetNX (TRUE, FALSE);
> NY = GetNY (FALSE);
> StepX = GetStepX (TRUE);
> StepY = GetStepY ();
> CopyDX = DX;
> CopyNX = NX;
> Pixel = VData->VDP [44];
>
> do {
> DX = CopyDX;
> NX = CopyNX;
>
> do {
> (*WriteByteFunc) (DX, DY, Pixel);
>
> DX += StepX;
> NX--;
> } while (NX > 0);
>
> DY += StepY;
> NY--;
> } while (NY > 0);
>
> VData->VDPStatus [2] &= 0xFE;
> VData->VDP [38] = DY;
> VData->VDP [39] = DY >> 8;
> VData->VDP [42] = NY;
> VData->VDP [43] = NY >> 8;
> }
>
>
>
>
> void LINE (void)
> { int DX, DY, NX, NY, Color, LogOp, StepX, StepY;
> int AX, AY, L;
>
> DX = GetDX (FALSE);
> DY = GetDY ();
> NX = GetNX (FALSE, TRUE);
> NY = GetNY (TRUE);
> Color = VData->VDP [44];
> LogOp = VData->VDP [46] & 0x0F;
>
> if (VData->VDP [45] & 0x01) {
> L = NX;
> NX = NY;
> NY = L;
> }
>
> StepX = GetStepX (FALSE);
> StepX = NX ? StepX : 0;
> AX = 2 * NX;
>
> StepY = GetStepY ();
> StepY = NY ? StepY : 0;
> AY = 2 * NY;
>
> if (VData->VDP [45] & 0x01) {
> for (L = AX - NY; NY >= 0; DY += StepY, L += AX, NY--) {
> (*WritePixelFunc) (DX, DY, Color, LogOp);
> if (L >= 0) {
> L -= AY;
> DX += StepX;
> }
> }
> } else {
> for (L = AY - NX; NX >= 0; DX += StepX, L += AY, NX--) {
> (*WritePixelFunc) (DX, DY, Color, LogOp);
> if (L >= 0) {
> L -= AX;
> DY += StepY;
> }
> }
> }
>
> VData->VDPStatus [2] &= 0xFE;
> VData->VDP [38] = DY;
> VData->VDP [39] = DY >> 8;
> }
>
>
>
>
> void LMCM (void)
> { Transfer.SX = GetSX (FALSE);
> Transfer.SY = GetSY ();
> Transfer.NX = GetNX (FALSE, FALSE);
> Transfer.NY = GetNY (FALSE);
> Transfer.StepX = GetStepX (FALSE);
> Transfer.StepY = GetStepY ();
> Transfer.CopySX = Transfer.SX;
> Transfer.CopyNX = Transfer.NX;
> Transfer.Mode = TRANSFER_LMCM;
>
> VData->VDPStatus [2] |= 0x81;
> LMCMTransfer = TRUE;
>
> DoTransfer ();
> }
>
>
>
>
> void LMMC (void)
> { Transfer.DX = GetDX (FALSE);
> Transfer.DY = GetDY ();
> Transfer.NX = GetNX (FALSE, FALSE);
> Transfer.NY = GetNY (FALSE);
> Transfer.StepX = GetStepX (FALSE);
> Transfer.StepY = GetStepY ();
> Transfer.CopyDX = Transfer.DX;
> Transfer.CopyNX = Transfer.NX;
> Transfer.LogOp = VData->VDP [46] & 0x0F;
> Transfer.Mode = TRANSFER_LMMC;
>
> VData->VDPStatus [2] |= 0x81;
>
> DoTransfer ();
> }
>
>
>
>
> void LMMM (void)
> { int SX, SY, DX, DY, NX, NY, StepX, StepY, Pixel, LogOp, CopySX,
CopyDX, CopyNX;
>
> SX = GetSX (FALSE);
> SY = GetSY ();
> DX = GetDX (FALSE);
> DY = GetDY ();
> NX = GetNX (FALSE, FALSE);
> NY = GetNY (FALSE);
> StepX = GetStepX (FALSE);
> StepY = GetStepY ();
> CopySX = SX;
> CopyDX = DX;
> CopyNX = NX;
> LogOp = VData->VDP [46] & 0x0F;
>
> do {
> SX = CopySX;
> DX = CopyDX;
> NX = CopyNX;
>
> do {
> Pixel = (*ReadPixelFunc) (SX, SY);
> (*WritePixelFunc) (DX, DY, Pixel, LogOp);
>
> SX += StepX;
> DX += StepX;
> NX--;
> } while (NX > 0);
>
> SY += StepY;
> DY += StepY;
> NY--;
> } while (NY > 0);
>
> VData->VDPStatus [2] &= 0xFE;
> VData->VDP [34] = SY;
> VData->VDP [35] = SY >> 8;
> VData->VDP [38] = DY;
> VData->VDP [39] = DY >> 8;
> VData->VDP [42] = NY;
> VData->VDP [43] = NY >> 8;
> }
>
>
>
> void LMMV (void)
> { int DX, DY, NX, NY, StepX, StepY, Pixel, LogOp, CopyDX, CopyNX;
>
> DX = GetDX (FALSE);
> DY = GetDY ();
> NX = GetNX (FALSE, FALSE);
> NY = GetNY (FALSE);
> StepX = GetStepX (FALSE);
> StepY = GetStepY ();
> CopyDX = DX;
> CopyNX = NX;
> LogOp = VData->VDP [46] & 0x0F;
> Pixel = VData->VDP [44];
>
> do {
> DX = CopyDX;
> NX = CopyNX;
>
> do {
> (*WritePixelFunc) (DX, DY, Pixel, LogOp);
>
> DX += StepX;
> NX--;
> } while (NX > 0);
>
> DY += StepY;
> NY--;
> } while (NY > 0);
>
> VData->VDPStatus [2] &= 0xFE;
> VData->VDP [38] = DY;
> VData->VDP [39] = DY >> 8;
> VData->VDP [42] = NY;
> VData->VDP [43] = NY >> 8;
> }
>
>
>
>
> void PINT (void)
> { int SX, SY;
>
> SX = GetSX (FALSE);
> SY = GetSY ();
>
> VData->VDPStatus [2] &= 0xFE;
> VData->VDPStatus [7] = (*ReadPixelFunc) (SX, SY);
> VData->VDP [44] = VData->VDPStatus [7];
> }
>
>
>
>
> void PSET (void)
> { int DX, DY, Color, LogOp;
>
> DX = GetDX (FALSE);
> DY = GetDY ();
> Color = VData->VDP [44];
> LogOp = VData->VDP [46] & 0x0F;
>
> VData->VDPStatus [2] &= 0xFE;
> (*WritePixelFunc) (DX, DY, Color, LogOp);
> }
>
>
>
>
> void SRCH (void)
> { int SX, SY, StepX, Color, EqSearch, Pixel;
> static const ColorMask [4] = { 0x0F, 0x03, 0x0F, 0xFF };
>
> SX = GetSX (FALSE);
> SY = GetSY ();
> Color = VData->VDP [44] & ColorMask [VData->Screenmode - 5];
> EqSearch = !!(VData->VDP [45] & 0x02);
> StepX = GetStepX (FALSE);
> VData->VDPStatus [2] &= 0xEF;
>
> do {
> Pixel = (*ReadPixelFunc) (SX, SY);
> if ((Pixel == Color) ^ EqSearch) {
> VData->VDPStatus [2] |= 0x10;
> VData->VDPStatus [8] = SX;
> VData->VDPStatus [9] = (SX >> 8) | 0xFE;
> break;
> }
> SX += StepX;
>
> } while (Pixel >= 0);
>
> VData->VDPStatus [2] &= 0xFE;
> }
>
>
>
>
> void STOP (void)
> { VData->VDPStatus [2] &= 0x7E;
> Regs->VDPEndTime = 0;
> LMCMTransfer = FALSE;
> Transfer.Mode = TRANSFER_NONE;
> }
>
>
>
>
> void YMMM (void)
> { int DX, DY, SY, NY, CopyDX, StepX, StepY, Pixel;
>
> DX = GetDX (TRUE);
> DY = GetDY ();
> SY = GetSY ();
> NY = GetNY (FALSE);
> StepX = GetStepX (TRUE);
> StepY = GetStepY ();
> CopyDX = DX;
>
> do {
> DX = CopyDX;
>
> do {
> Pixel = (*ReadByteFunc) (DX, SY);
> (*WriteByteFunc) (DX, DY, Pixel);
> DX += StepX;
>
> } while (Pixel >= 0);
>
> DY += StepY;
> SY += StepY;
> NY--;
> } while (NY > 0);
>
> VData->VDPStatus [2] &= 0xFE;
> VData->VDP [34] = SY;
> VData->VDP [35] = SY >> 8;
> VData->VDP [38] = DY;
> VData->VDP [39] = DY >> 8;
> VData->VDP [42] = NY;
> VData->VDP [43] = NY >> 8;
> }
>
>
>
>
> /* This function dispatches to the correct VDP command.
> */
>
> void __asm __saveds DoVDP (void)
> { switch (VData->VDP [46] & 0xF0) {
> case 0x00: STOP (); break;
> case 0x40: PINT (); break;
> case 0x50: PSET (); break;
> case 0x60: SRCH (); break;
> case 0x70: LINE (); break;
> case 0x80: LMMV (); break;
> case 0x90: LMMM (); break;
> case 0xA0: LMCM (); break;
> case 0xB0: LMMC (); break;
> case 0xC0: HMMV (); break;
> case 0xD0: HMMM (); break;
> case 0xE0: YMMM (); break;
> case 0xF0: HMMC (); break;
> }
> }
>
>
>
>
> All those ReadPixel and WritePixel functions are actually written in 68K
> assembly. The set for screen 8 looks like this (and there are similar sets
for
> each of the screens 5..8):
>
>
>
>
> ; This function reads a pixel from screen 8, given a pair of coordinates.
> ; (IN) d1 = X coordinate
> ; (IN) d2 = Y coordinate
> ; (OUT) the color value of the pixel, or -1 if the coordinates were out of
> ; range.
>
> _ReadPixel_8:
>
> movem.l d1-d2/a0,-(a7)
> move.l #-1,d0
>
> ; perform clipping
>
> cmp.l #255,d1
> bhi .end
>
> cmp.l #511,d2
> bhi .end
>
> ; count this operation for timing
>
> add.l #10,_VDPEndTime
>
> ; read the pixel
>
> lsl.l #8,d2
> add.l d2,d1
> ROR17 d1
> lsl.l #3,d1
> move.l VRAM,a0
>
> bfextu (a0){d1:8},d0
>
> .end movem.l (a7)+,d1-d2/a0
> rts
>
>
>
>
> ; This function writes a pixel to screen 8, given a pair of coordinates
and
> ; a logic operation.
> ; (IN) d1 = X coordinate
> ; (IN) d2 = Y coordinate
> ; (IN) d3 = color to be written
> ; (IN) d4 = logic operation
>
> _WritePixel_8:
>
> movem.l d0-d3/a0,-(a7)
>
> ; perform clipping
>
> cmp.l #255,d1
> bhi .end
>
> cmp.l #511,d2
> bhi .end
>
> tst.l d3 ; this is clipping for read operations
> bmi .end
>
> ; count this operation for timing
>
> add.l #20,_VDPEndTime
>
> ; scale the coordinates
>
> lsl.l #8,d2
> add.l d2,d1
> ROR17 d1
> lsl.l #3,d1
> move.l VRAM,a0
>
> ; dispatch to correct operation
>
> cmp.b #$00,d4
> beq .imp
> cmp.b #$01,d4
> beq .and
> cmp.b #$02,d4
> beq .or
> cmp.b #$03,d4
> beq .eor
> cmp.b #$04,d4
> beq .not
>
> ; Check transparency - there should also be a check for the TP
bit here...
>
> tst.b d3
> beq .end
>
> cmp.b #$08,d4
> beq .imp
> cmp.b #$09,d4
> beq .and
> cmp.b #$0A,d4
> beq .or
> cmp.b #$0B,d4
> beq .eor
> cmp.b #$0C,d4
> beq .not
> bra .end
>
> ; IMP operation
>
> .imp bfins d3,(a0){d1:8}
> bra .end
>
> ; AND operation
>
> .and bfextu (a0){d1:8},d0
> and.l d3,d0
> bfins d0,(a0){d1:8}
> bra .end
>
> ; OR operation
>
> .or bfextu (a0){d1:8},d0
> or.l d3,d0
> bfins d0,(a0){d1:8}
> bra .end
>
> ; EOR operation
>
> .eor bfextu (a0){d1:8},d0
> eor.l d3,d0
> bfins d0,(a0){d1:8}
> bra .end
>
> ; NOT operation
>
> .not not.l d3
> bfins d3,(a0){d1:8}
> bra .end
>
> .end movem.l (a7)+,d0-d3/a0
> rts
>
>
>
>
>
> ; This function reads a byte from screen 8
> ; (IN) d1 = X coordinate
> ; (IN) d2 = Y coordinate
> ; (OUT) the color value of the pixel, or -1 if the coordinates were out of
> ; range.
>
> _ReadByte_8:
>
> movem.l d1-d2/a0,-(a7)
> move.l #-1,d0
>
> ; perform clipping
>
> cmp.l #255,d1
> bhi .end
>
> cmp.l #511,d2
> bhi .end
>
> ; count this operation for timing
>
> add.l #10,_VDPEndTime
>
> ; read the byte
>
> lsl.l #8,d2
> add.l d2,d1
> ROR17 d1
> move.l VRAM,a0
>
> moveq #0,d0
> move.b (a0,d1.l),d0
>
> .end movem.l (a7)+,d1-d2/a0
> rts
>
>
>
>
> ; This function writes a byte to screen 8.
> ; (IN) d1 = X coordinate
> ; (IN) d2 = Y coordinate
> ; (IN) d3 = color to be written
>
> _WriteByte_8:
>
> movem.l d1-d2/a0,-(a7)
>
> ; perform clipping
>
> cmp.l #255,d1
> bhi .end
>
> cmp.l #511,d2
> bhi .end
>
> tst.l d3 ; this is clipping for read operations
> bmi .end
>
> ; count this operation for timing
>
> add.l #10,_VDPEndTime
>
> ; scale the coordinates
>
> lsl.l #8,d2
> add.l d2,d1
> ROR17 d1
> move.l VRAM,a0
>
> ; perform the write
>
> move.b d3,(a0,d1.l)
>
> .end movem.l (a7)+,d1-d2/a0
> rts
>
****
MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put
in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the
quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)
****