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/)
****

Reply via email to