mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1366 lines
28 KiB
1366 lines
28 KiB
#include "insignia.h"
|
|
#include "host_def.h"
|
|
|
|
#if !(defined(NTVDM) && defined(MONITOR))
|
|
|
|
/* INSIGNIA (SUB)MODULE SPECIFICATION
|
|
-----------------------------
|
|
|
|
|
|
THIS PROGRAM SOURCE FILE IS SUPPLIED IN CONFIDENCE TO THE
|
|
CUSTOMER, THE CONTENTS OR DETAILS OF ITS OPERATION MUST
|
|
NOT BE DISCLOSED TO ANY OTHER PARTIES WITHOUT THE EXPRESS
|
|
AUTHORISATION FROM THE DIRECTORS OF INSIGNIA SOLUTIONS LTD.
|
|
|
|
|
|
DOCUMENT : name and number
|
|
|
|
RELATED DOCS : include all relevant references
|
|
|
|
DESIGNER : P. Jadeja
|
|
|
|
REVISION HISTORY :
|
|
First version : P. Jadeja, SoftPC 2.0, 10-Aug-88
|
|
Second version : John Shanly, SoftPC 3.0, 9 April 1991
|
|
|
|
SUBMODULE NAME : write mode 0
|
|
|
|
SOURCE FILE NAME : ega_write_mode0.c
|
|
|
|
PURPOSE : purpose of this submodule
|
|
|
|
SccsID = "@(#)ega_wrtm0.c 1.31 11/01/94 Copyright Insignia Solutions Ltd."
|
|
|
|
|
|
[1.INTERMODULE INTERFACE SPECIFICATION]
|
|
|
|
[1.0 INCLUDE FILE NEEDED TO ACCESS THIS INTERFACE FROM OTHER SUBMODULES]
|
|
|
|
INCLUDE FILE : xxx.gi
|
|
|
|
[1.1 INTERMODULE EXPORTS]
|
|
|
|
PROCEDURES() : ega_mode0_chn_b_write();
|
|
ega_mode0_chn_w_write();
|
|
ega_mode0_chn_b_fill();
|
|
ega_mode0_chn_w_fill();
|
|
ega_mode0_chn_b_move();
|
|
ega_mode0_chn_w_move();
|
|
|
|
ega_copy_b_write();
|
|
ega_copy_w_write();
|
|
ega_copy_b_fill();
|
|
ega_copy_w_fill();
|
|
ega_copy_b_move();
|
|
ega_copy_w_move();
|
|
|
|
ega_copy_all_b_write();
|
|
DATA : give type and name
|
|
|
|
-------------------------------------------------------------------------
|
|
[1.2 DATATYPES FOR [1.1] (if not basic C types)]
|
|
|
|
STRUCTURES/TYPEDEFS/ENUMS:
|
|
|
|
-------------------------------------------------------------------------
|
|
[1.3 INTERMODULE IMPORTS]
|
|
(not o/s objects or standard libs)
|
|
|
|
PROCEDURES() : give name, and source module name
|
|
|
|
DATA : give name, and source module name
|
|
|
|
-------------------------------------------------------------------------
|
|
|
|
[1.4 DESCRIPTION OF INTERMODULE INTERFACE]
|
|
|
|
[1.4.1 IMPORTED OBJECTS]
|
|
|
|
DATA OBJECTS : specify in following procedure descriptions
|
|
how these are accessed (read/modified)
|
|
|
|
FILES ACCESSED : list all files, how they are accessed,
|
|
how file data is interpreted, etc. if relevant
|
|
(else omit)
|
|
|
|
DEVICES ACCESSED : list all devices accessed, special modes used
|
|
(e.g; termio structure). if relevant (else
|
|
omit)
|
|
|
|
SIGNALS CAUGHT : list any signals caught if relevant (else omit)
|
|
|
|
SIGNALS ISSUED : list any signals sent if relevant (else omit)
|
|
|
|
|
|
[1.4.2 EXPORTED OBJECTS]
|
|
=========================================================================
|
|
PROCEDURE :
|
|
|
|
PURPOSE :
|
|
|
|
PARAMETERS
|
|
|
|
name : describe contents, and legal values
|
|
for output parameters, indicate by "(o/p)"
|
|
at start of description
|
|
|
|
GLOBALS : describe what exported data objects are
|
|
accessed and how. Likewise for imported
|
|
data objects.
|
|
|
|
ACCESS : specify if signal or interrupt handler
|
|
if relevant (else omit)
|
|
|
|
ABNORMAL RETURN : specify if exit() or longjmp() etc.
|
|
can be called if relevant (else omit)
|
|
|
|
RETURNED VALUE : meaning of function return values
|
|
|
|
DESCRIPTION : describe what (not how) function does
|
|
|
|
ERROR INDICATIONS : describe how errors are returned to caller
|
|
|
|
ERROR RECOVERY : describe how procedure reacts to errors
|
|
=========================================================================
|
|
|
|
|
|
/*=======================================================================
|
|
[3.INTERMODULE INTERFACE DECLARATIONS]
|
|
=========================================================================
|
|
|
|
[3.1 INTERMODULE IMPORTS] */
|
|
|
|
/* [3.1.1 #INCLUDES] */
|
|
|
|
|
|
#ifdef EGG
|
|
|
|
#include TypesH
|
|
#include "xt.h"
|
|
#include CpuH
|
|
#include "debug.h"
|
|
#include "gmi.h"
|
|
#include "sas.h"
|
|
#include "egacpu.h"
|
|
#include "egaports.h"
|
|
#include "cpu_vid.h"
|
|
#include "gfx_upd.h"
|
|
#include "host.h"
|
|
|
|
/* [3.1.2 DECLARATIONS] */
|
|
|
|
/* [3.2 INTERMODULE EXPORTS] */
|
|
|
|
|
|
/*
|
|
5.MODULE INTERNALS : (not visible externally, global internally)]
|
|
|
|
[5.1 LOCAL DECLARATIONS] */
|
|
|
|
/* [5.1.1 #DEFINES] */
|
|
#ifdef SEGMENTATION
|
|
/*
|
|
* The following #include specifies the code segment into which this
|
|
* module will by placed by the MPW C compiler on the Mac II running
|
|
* MultiFinder.
|
|
*/
|
|
#ifdef PROD
|
|
#include "SOFTPC_EGA.seg"
|
|
#else
|
|
#include "SOFTPC_EGA_WRITE.seg"
|
|
#endif
|
|
#endif
|
|
|
|
/* [5.1.2 TYPEDEF, STRUCTURE, ENUM DECLARATIONS] */
|
|
|
|
typedef union {
|
|
unsigned short as_word;
|
|
struct {
|
|
#ifdef BIGEND
|
|
unsigned char hi_byte;
|
|
unsigned char lo_byte;
|
|
#else
|
|
unsigned char lo_byte;
|
|
unsigned char hi_byte;
|
|
#endif
|
|
} as_bytes;
|
|
struct {
|
|
unsigned char first_byte;
|
|
unsigned char second_byte;
|
|
} as_array;
|
|
} TWO_BYTES;
|
|
|
|
/* [5.1.3 PROCEDURE() DECLARATIONS] */
|
|
|
|
/* -----------------------------------------------------------------------
|
|
[5.2 LOCAL DEFINITIONS]
|
|
|
|
[5.2.1 INTERNAL DATA DEFINITIONS */
|
|
|
|
/* [5.2.2 INTERNAL PROCEDURE DEFINITIONS] */
|
|
|
|
/*
|
|
7.INTERMODULE INTERFACE IMPLEMENTATION :
|
|
*/
|
|
|
|
/*
|
|
[7.1 INTERMODULE DATA DEFINITIONS] */
|
|
|
|
#ifdef A_VID
|
|
IMPORT VOID _ch2_copy_byte_write();
|
|
IMPORT VOID _ch2_copy_word_write();
|
|
IMPORT VOID _ch2_copy_byte_fill_glue();
|
|
IMPORT VOID _ch2_copy_word_fill_glue();
|
|
IMPORT VOID _ch2_copy_byte_move_glue();
|
|
IMPORT VOID _ch2_copy_word_move_glue();
|
|
IMPORT VOID _ch2_copy_byte_move_glue_fwd();
|
|
IMPORT VOID _ch2_copy_word_move_glue_fwd();
|
|
IMPORT VOID _ch2_copy_byte_move_glue_bwd();
|
|
IMPORT VOID _ch2_copy_word_move_glue_bwd();
|
|
|
|
IMPORT VOID _ch2_mode0_chn_byte_write_glue();
|
|
IMPORT VOID _ch2_mode0_chn_word_write_glue();
|
|
IMPORT VOID _ch2_mode0_chn_byte_fill_glue();
|
|
IMPORT VOID _ch2_mode0_chn_word_fill_glue();
|
|
IMPORT VOID _ch2_mode0_chn_byte_move_glue();
|
|
IMPORT VOID _ch2_mode0_chn_word_move_glue();
|
|
|
|
WRT_POINTERS mode0_copy_handlers =
|
|
{
|
|
_ch2_copy_byte_write,
|
|
_ch2_copy_word_write
|
|
|
|
#ifndef NO_STRING_OPERATIONS
|
|
,
|
|
_ch2_copy_byte_fill_glue,
|
|
_ch2_copy_word_fill_glue,
|
|
_ch2_copy_byte_move_glue_fwd,
|
|
_ch2_copy_byte_move_glue_bwd,
|
|
_ch2_copy_word_move_glue_fwd,
|
|
_ch2_copy_word_move_glue_bwd
|
|
|
|
#endif /* NO_STRING_OPERATIONS */
|
|
|
|
};
|
|
|
|
WRT_POINTERS mode0_gen_handlers =
|
|
{
|
|
_ch2_mode0_chn_byte_write_glue,
|
|
_ch2_mode0_chn_word_write_glue
|
|
|
|
#ifndef NO_STRING_OPERATIONS
|
|
,
|
|
_ch2_mode0_chn_byte_fill_glue,
|
|
_ch2_mode0_chn_word_fill_glue,
|
|
_ch2_mode0_chn_byte_move_glue,
|
|
_ch2_mode0_chn_byte_move_glue,
|
|
_ch2_mode0_chn_word_move_glue,
|
|
_ch2_mode0_chn_word_move_glue
|
|
|
|
#endif /* NO_STRING_OPERATIONS */
|
|
|
|
};
|
|
#else
|
|
VOID ega_copy_b_write();
|
|
VOID ega_copy_w_write();
|
|
VOID ega_copy_b_fill();
|
|
VOID ega_copy_w_fill();
|
|
VOID ega_copy_b_move_fwd IPT4(ULONG, offset, ULONG, eas, ULONG, count, ULONG, src_flag );
|
|
VOID ega_copy_b_move_bwd IPT4(ULONG, offset, ULONG, eas, ULONG, count, ULONG, src_flag );
|
|
VOID ega_copy_w_move_fwd IPT4(ULONG, offset, ULONG, eas, ULONG, count, ULONG, src_flag );
|
|
VOID ega_copy_w_move_bwd IPT4(ULONG, offset, ULONG, eas, ULONG, count, ULONG, src_flag );
|
|
|
|
|
|
VOID ega_mode0_chn_b_write();
|
|
VOID ega_mode0_chn_w_write();
|
|
VOID ega_mode0_chn_b_fill();
|
|
VOID ega_mode0_chn_w_fill();
|
|
VOID ega_mode0_chn_b_move_fwd IPT4(ULONG, ead, ULONG, eas, ULONG, count, ULONG, src_flag );
|
|
VOID ega_mode0_chn_b_move_bwd IPT4(ULONG, ead, ULONG, eas, ULONG, count, ULONG, src_flag );
|
|
VOID ega_mode0_chn_w_move_fwd IPT4(ULONG, ead, ULONG, eas, ULONG, count, ULONG, src_flag );
|
|
VOID ega_mode0_chn_w_move_bwd IPT4(ULONG, ead, ULONG, eas, ULONG, count, ULONG, src_flag );
|
|
|
|
|
|
WRT_POINTERS mode0_copy_handlers =
|
|
{
|
|
ega_copy_b_write,
|
|
ega_copy_w_write
|
|
|
|
#ifndef NO_STRING_OPERATIONS
|
|
,
|
|
ega_copy_b_fill,
|
|
ega_copy_w_fill,
|
|
ega_copy_b_move_fwd,
|
|
ega_copy_b_move_bwd,
|
|
ega_copy_w_move_fwd,
|
|
ega_copy_w_move_bwd,
|
|
|
|
#endif /* NO_STRING_OPERATIONS */
|
|
};
|
|
|
|
WRT_POINTERS mode0_gen_handlers =
|
|
{
|
|
ega_mode0_chn_b_write,
|
|
ega_mode0_chn_w_write
|
|
|
|
#ifndef NO_STRING_OPERATIONS
|
|
,
|
|
ega_mode0_chn_b_fill,
|
|
ega_mode0_chn_w_fill,
|
|
ega_mode0_chn_b_move_fwd,
|
|
ega_mode0_chn_b_move_bwd,
|
|
ega_mode0_chn_w_move_fwd,
|
|
ega_mode0_chn_w_move_bwd,
|
|
|
|
#endif /* NO_STRING_OPERATIONS */
|
|
};
|
|
#endif /* A_VID */
|
|
|
|
/*
|
|
[7.2 INTERMODULE PROCEDURE DEFINITIONS] */
|
|
|
|
byte rotate IFN2(byte, value, int, nobits)
|
|
{
|
|
/*
|
|
* Rotate a byte right by nobits. Do this by making a copy of
|
|
* the byte into the msbyte of the word, and then shifting the
|
|
* word by the required amount, and then returning the resulting low byte.
|
|
*/
|
|
|
|
TWO_BYTES double_num;
|
|
|
|
double_num.as_bytes.lo_byte = double_num.as_bytes.hi_byte = value;
|
|
double_num.as_word >>= nobits;
|
|
return double_num.as_bytes.lo_byte;
|
|
}
|
|
|
|
VOID
|
|
ega_copy_b_write IFN2(ULONG, value, ULONG, offset )
|
|
{
|
|
ULONG lsb;
|
|
note_entrance0("ega_copy_b_write");
|
|
|
|
(*update_alg.mark_byte)( offset );
|
|
|
|
lsb = offset & 0x1;
|
|
offset = (offset >> 1) << 2;
|
|
offset |= lsb;
|
|
|
|
*(IU8 *)(getVideowplane() + offset) = value;
|
|
}
|
|
|
|
VOID
|
|
ega_copy_w_write IFN2(ULONG, value, ULONG, offset )
|
|
{
|
|
ULONG lsb;
|
|
UTINY *planes;
|
|
|
|
note_entrance0("ega_copy_w_write");
|
|
|
|
(*update_alg.mark_word)( offset );
|
|
|
|
lsb = offset & 0x1;
|
|
offset = (offset >> 1) << 2;
|
|
planes = getVideowplane() + offset;
|
|
|
|
if( lsb )
|
|
{
|
|
*(planes + 1) = value;
|
|
*(planes + 4) = value >> 8;
|
|
}
|
|
else
|
|
{
|
|
*planes = value;
|
|
*(planes + 1) = value >> 8;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ega_copy_b_fill IFN3(ULONG, value, ULONG, offset, ULONG, count )
|
|
{
|
|
ULONG lsb;
|
|
ULONG inc;
|
|
UTINY *planes;
|
|
|
|
note_entrance0("ega_copy_b_fill");
|
|
|
|
(*update_alg.mark_fill)( offset, offset + count - 1 );
|
|
|
|
lsb = offset & 0x1;
|
|
offset = (offset >> 1) << 2;
|
|
|
|
planes = getVideowplane() + offset;
|
|
|
|
if( lsb )
|
|
{
|
|
planes += 1;
|
|
inc = 3;
|
|
}
|
|
else
|
|
inc = 1;
|
|
|
|
while( count-- )
|
|
{
|
|
*planes = (UTINY) value;
|
|
planes += inc;
|
|
inc ^= 2;
|
|
}
|
|
}
|
|
|
|
#ifdef BIGEND
|
|
#define first_half(wd) (((wd) & 0xff00) >> 8)
|
|
#define sec_half(wd) ((wd) & 0xff)
|
|
#else
|
|
#define first_half(wd) ((wd) & 0xff)
|
|
#define sec_half(wd) (((wd) & 0xff00) >> 8)
|
|
#endif
|
|
|
|
VOID
|
|
ega_copy_w_fill IFN3(ULONG, value, ULONG, offset, ULONG, count )
|
|
{
|
|
ULONG lsb;
|
|
USHORT *planes;
|
|
|
|
note_entrance0("ega_copy_w_fill");
|
|
|
|
#ifdef BIGEND
|
|
value = ((value >> 8) & 0xff) | ((value << 8) & 0xff00);
|
|
#endif
|
|
|
|
count >>= 1;
|
|
|
|
/* the 3rd parameter is needed by GORE */
|
|
(*update_alg.mark_wfill)( offset, offset + count - 1, 0 );
|
|
|
|
lsb = offset & 0x1;
|
|
offset = (offset >> 1) << 2;
|
|
|
|
planes = (USHORT *) (getVideowplane() + offset);
|
|
|
|
if( lsb )
|
|
{
|
|
word swapped = ((value >> 8) & 0xff) | ((value << 8) & 0xff00);
|
|
|
|
*((UTINY *) planes + 1) = first_half(value);
|
|
|
|
count--;
|
|
planes += 2;
|
|
|
|
while( count-- )
|
|
{
|
|
*planes = swapped;
|
|
planes += 2;
|
|
}
|
|
|
|
*((UTINY *) planes) = sec_half(value);
|
|
}
|
|
else
|
|
{
|
|
while( count-- )
|
|
{
|
|
*planes = value;
|
|
planes += 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCAL VOID
|
|
ega_copy_move IFN6(UTINY *, dst, UTINY *, eas, ULONG, count, ULONG, src_flag,
|
|
ULONG, w, IBOOL, forward )
|
|
{
|
|
ULONG lsbeas, lsbdst;
|
|
ULONG easinc, dstinc;
|
|
ULONG easoff, dstoff;
|
|
UTINY *planes;
|
|
|
|
note_entrance0("ega_copy_move");
|
|
|
|
(*update_alg.mark_string)( (ULONG) dst, (ULONG) dst + count - 1);
|
|
|
|
planes = (UTINY *) getVideowplane();
|
|
|
|
if( src_flag == 1 )
|
|
{
|
|
if(!forward)
|
|
{
|
|
eas += w;
|
|
dst += w;
|
|
}
|
|
|
|
lsbeas = (ULONG) eas & 0x1;
|
|
lsbdst = (ULONG) dst & 0x1;
|
|
|
|
if(forward)
|
|
{
|
|
easinc = lsbeas ? 3 : 1;
|
|
dstinc = lsbdst ? 3 : 1;
|
|
}
|
|
else
|
|
{
|
|
easinc = lsbeas ? -1 : -3;
|
|
dstinc = lsbdst ? -1 : -3;
|
|
}
|
|
|
|
easoff = (( (ULONG) eas >> 1 ) << 2 ) | lsbeas;
|
|
dstoff = (( (ULONG) dst >> 1 ) << 2 ) | lsbdst;
|
|
|
|
while( count-- )
|
|
{
|
|
*(planes + dstoff) = *(planes + easoff);
|
|
|
|
dstoff += dstinc;
|
|
easoff += easinc;
|
|
dstinc ^= 0x2;
|
|
easinc ^= 0x2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!forward)
|
|
{
|
|
dst += w;
|
|
#ifdef BACK_M
|
|
eas -= w;
|
|
#else
|
|
eas += w;
|
|
#endif
|
|
}
|
|
|
|
lsbdst = (ULONG) dst & 0x1;
|
|
|
|
if(forward)
|
|
{
|
|
#ifdef BACK_M
|
|
easinc = -1;
|
|
#else
|
|
easinc = 1;
|
|
#endif
|
|
dstinc = lsbdst ? 3 : 1;
|
|
}
|
|
else
|
|
{
|
|
#ifdef BACK_M
|
|
easinc = 1;
|
|
#else
|
|
easinc = -1;
|
|
#endif
|
|
dstinc = lsbdst ? -1 : -3;
|
|
}
|
|
|
|
dstoff = (((ULONG) dst >> 1 ) << 2 ) | lsbdst;
|
|
|
|
while( count-- )
|
|
{
|
|
*(planes + dstoff) = *eas;
|
|
|
|
dstoff += dstinc;
|
|
eas += easinc;
|
|
dstinc ^= 0x2;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
ega_copy_b_move IFN4(UTINY *, offset, UTINY *, eas, ULONG, count,
|
|
ULONG, src_flag )
|
|
{
|
|
ega_copy_move(offset, eas, count, src_flag, 0, getDF() ? FALSE : TRUE);
|
|
}
|
|
|
|
VOID
|
|
ega_copy_b_move_fwd IFN4(ULONG, offset, ULONG, eas, ULONG, count,
|
|
ULONG, src_flag )
|
|
{
|
|
ega_copy_move( (UTINY *)offset, (UTINY *)eas, count, src_flag, 0, TRUE );
|
|
}
|
|
|
|
VOID
|
|
ega_copy_b_move_bwd IFN4(ULONG, offset, ULONG, eas, ULONG, count,
|
|
ULONG, src_flag )
|
|
{
|
|
ega_copy_move( (UTINY *)offset, (UTINY *)eas, count, src_flag, 0, FALSE );
|
|
}
|
|
|
|
VOID
|
|
ega_copy_w_move IFN4(UTINY *, offset, UTINY *, eas, ULONG, count,
|
|
ULONG, src_flag )
|
|
{
|
|
ega_copy_move(offset, eas, count << 1, src_flag, 1, getDF() ? FALSE : TRUE);
|
|
}
|
|
|
|
VOID
|
|
ega_copy_w_move_fwd IFN4(ULONG, offset, ULONG, eas, ULONG, count,
|
|
ULONG, src_flag )
|
|
{
|
|
ega_copy_move( (UTINY *)offset, (UTINY *)eas, count << 1, src_flag, 1, TRUE );
|
|
}
|
|
|
|
VOID
|
|
ega_copy_w_move_bwd IFN4(ULONG, offset, ULONG, eas, ULONG, count,
|
|
ULONG, src_flag )
|
|
{
|
|
ega_copy_move( (UTINY *)offset, (UTINY *)eas, count << 1, src_flag, 1, FALSE );
|
|
}
|
|
|
|
VOID
|
|
ega_mode0_chn_b_write IFN2(ULONG, value, ULONG, offset )
|
|
{
|
|
ULONG lsb;
|
|
|
|
note_entrance0("ega_mode0_chn_b_write");
|
|
|
|
(*update_alg.mark_byte)( offset );
|
|
|
|
lsb = offset & 0x1;
|
|
offset = (offset >> 1) << 2;
|
|
|
|
if( lsb ) /* odd address, in plane 1 or 3 */
|
|
{
|
|
offset |= 0x1;
|
|
|
|
/*
|
|
* check if plane1 enabled
|
|
*/
|
|
|
|
if( getVideoplane_enable() & 2 )
|
|
{
|
|
/*
|
|
* check if set/reset function enable for this plane
|
|
*/
|
|
|
|
if( EGA_CPU.sr_enable & 2 )
|
|
{
|
|
value = *((UTINY *) &EGA_CPU.sr_value + 1);
|
|
value = do_logicals( value, get_latch1 );
|
|
EGA_plane01[offset] = value;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* set/reset not enabled so here we go
|
|
*/
|
|
|
|
if( getVideorotate() > 0 )
|
|
value = rotate( value, getVideorotate() );
|
|
|
|
EGA_plane01[offset] = do_logicals( value, get_latch1 );
|
|
}
|
|
}
|
|
|
|
/*
|
|
* check if plane3 enabled
|
|
*/
|
|
|
|
if( getVideoplane_enable() & 8 )
|
|
{
|
|
/*
|
|
* check if set/reset function enable for this plane
|
|
*/
|
|
|
|
if( EGA_CPU.sr_enable & 8 )
|
|
{
|
|
value = *((UTINY *) &EGA_CPU.sr_value + 3);
|
|
value = do_logicals( value, get_latch3 );
|
|
EGA_plane23[offset] = value;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* set/reset not enabled so here we go
|
|
*/
|
|
|
|
if( getVideorotate() > 0 )
|
|
value = rotate( value, getVideorotate() );
|
|
|
|
EGA_plane23[offset] = do_logicals( value, get_latch3 );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{ /* even address, in plane 0 or 2 */
|
|
/*
|
|
* check if plane0 enabled
|
|
*/
|
|
|
|
if( getVideoplane_enable() & 1 )
|
|
{
|
|
|
|
/*
|
|
* check if set/reset function enable for this plane
|
|
*/
|
|
|
|
if(( EGA_CPU.sr_enable & 1 ))
|
|
{
|
|
value = *((UTINY *) &EGA_CPU.sr_value);
|
|
value = do_logicals( value, get_latch0 );
|
|
EGA_plane01[offset] = value;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* set/reset not enabled so here we go
|
|
*/
|
|
|
|
if( getVideorotate() > 0 )
|
|
value = rotate( value, getVideorotate() );
|
|
|
|
EGA_plane01[offset] = do_logicals( value, get_latch0 );
|
|
}
|
|
}
|
|
|
|
/*
|
|
* check if plane2 enabled
|
|
*/
|
|
|
|
if( getVideoplane_enable() & 4 )
|
|
{
|
|
|
|
/*
|
|
* check if set/reset function enable for this plane
|
|
*/
|
|
|
|
if(( EGA_CPU.sr_enable & 4 ))
|
|
{
|
|
value = *((UTINY *) &EGA_CPU.sr_value + 2);
|
|
value = do_logicals( value, get_latch2 );
|
|
EGA_plane23[offset] = value;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* set/reset not enabled so here we go
|
|
*/
|
|
|
|
if( getVideorotate() > 0 )
|
|
value = rotate( value, getVideorotate() );
|
|
|
|
EGA_plane23[offset] = do_logicals( value, get_latch2 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ega_mode0_chn_b_fill IFN3(ULONG, value, ULONG, offset, ULONG, count )
|
|
{
|
|
ULONG high_offset;
|
|
UTINY value1, value2;
|
|
|
|
note_entrance0("ega_mode0_chn_b_fill");
|
|
|
|
/*
|
|
* Starting on an odd address is inconvenient - go forward one
|
|
*/
|
|
|
|
if(( (ULONG) offset & 1) && count )
|
|
{
|
|
ega_mode0_chn_b_write( value, offset++ );
|
|
count--;
|
|
}
|
|
|
|
/*
|
|
* Ending on an even address is inconvenient - go back one
|
|
*/
|
|
|
|
if(( (ULONG) ( offset + count - 1 ) & 1) == 0 && count )
|
|
{
|
|
ega_mode0_chn_b_write( value, offset + count - 1 );
|
|
count--;
|
|
}
|
|
|
|
high_offset = offset + count - 1;
|
|
|
|
(*update_alg.mark_fill)( offset, high_offset );
|
|
|
|
offset = (offset >> 1) << 2;
|
|
high_offset = (high_offset >> 1) << 2;
|
|
|
|
switch( getVideoplane_enable() & 0x3 )
|
|
{
|
|
case 0x1: /* just plane 0 ie even addresses to be written */
|
|
if (EGA_CPU.sr_enable & 1)
|
|
{
|
|
value = *((UTINY *) &EGA_CPU.sr_value);
|
|
}
|
|
else
|
|
{
|
|
value = rotate( value, getVideorotate() );
|
|
}
|
|
|
|
value = do_logicals( value, get_latch0 );
|
|
fill_alternate_bytes((IS8 *)&EGA_plane01[offset],
|
|
(IS8 *)&EGA_plane01[high_offset],
|
|
(IS8)value);
|
|
break;
|
|
|
|
case 0x2: /* just plane 1 ie odd addresses to be written */
|
|
if (EGA_CPU.sr_enable & 2)
|
|
{
|
|
value = *((UTINY *) &EGA_CPU.sr_value + 1);
|
|
}
|
|
else
|
|
{
|
|
value = rotate( value, getVideorotate() );
|
|
}
|
|
|
|
value = do_logicals( value, get_latch1 );
|
|
fill_alternate_bytes((IS8 *)&EGA_plane01[offset + 1],
|
|
(IS8 *)&EGA_plane01[high_offset],
|
|
(IS8)value);
|
|
break;
|
|
|
|
case 0x3: /* sensible case is to have both chained planes write enabled */
|
|
if (EGA_CPU.sr_enable & 1)
|
|
{
|
|
value1 = *((UTINY *) &EGA_CPU.sr_value);
|
|
}
|
|
else
|
|
{
|
|
value1 = rotate( value, getVideorotate() );
|
|
}
|
|
|
|
if (EGA_CPU.sr_enable & 2)
|
|
{
|
|
value2 = *((UTINY *) &EGA_CPU.sr_value + 1);
|
|
}
|
|
else
|
|
{
|
|
value2 = rotate(value,getVideorotate());
|
|
}
|
|
|
|
value = value1 | value2 << 8;
|
|
value = do_logicals( value, get_latch01 );
|
|
value = (value << 8) | (value >> 8);
|
|
|
|
fill_both_bytes( value, (USHORT *)&EGA_plane01[offset], count >> 1 );
|
|
break;
|
|
} /* end of switch on plane01 enabled */
|
|
|
|
switch( getVideoplane_enable() & 0xc )
|
|
{
|
|
case 0x4:
|
|
if( EGA_CPU.sr_enable & 4 )
|
|
{
|
|
value = *((UTINY *) &EGA_CPU.sr_value + 2);
|
|
}
|
|
else
|
|
{
|
|
value = rotate( value, getVideorotate() );
|
|
}
|
|
|
|
value = do_logicals( value, get_latch2 );
|
|
fill_alternate_bytes((IS8 *)&EGA_plane23[offset],
|
|
(IS8 *)&EGA_plane23[high_offset],
|
|
(IS8)value );
|
|
break;
|
|
|
|
case 0x8:
|
|
if( EGA_CPU.sr_enable & 8 )
|
|
{
|
|
value = *((UTINY *) &EGA_CPU.sr_value + 3);
|
|
}
|
|
else
|
|
{
|
|
value = rotate( value, getVideorotate() );
|
|
}
|
|
|
|
value = do_logicals( value, get_latch3 );
|
|
fill_alternate_bytes((IS8 *)&EGA_plane23[offset + 1],
|
|
(IS8 *)&EGA_plane23[high_offset],
|
|
(IS8)value );
|
|
break;
|
|
|
|
case 0xc:
|
|
if (EGA_CPU.sr_enable & 4)
|
|
{
|
|
value1 = *((UTINY *) &EGA_CPU.sr_value + 2);
|
|
}
|
|
else
|
|
{
|
|
value1 = rotate( value, getVideorotate() );
|
|
}
|
|
|
|
if (EGA_CPU.sr_enable & 8)
|
|
{
|
|
value2 = *((UTINY *) &EGA_CPU.sr_value + 3);
|
|
}
|
|
else
|
|
{
|
|
value2 = rotate( value, getVideorotate() );
|
|
}
|
|
|
|
value = value1 | value2 << 8;
|
|
value = do_logicals( value, get_latch23 );
|
|
value = (value << 8) | (value >> 8);
|
|
|
|
fill_both_bytes( value, (USHORT *)&EGA_plane01[offset], count >> 1 );
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
ega_mode0_chn_w_fill IFN3(ULONG, value, ULONG, offset, ULONG, count )
|
|
{
|
|
ULONG high_offset;
|
|
UTINY value1, value2;
|
|
IBOOL odd = FALSE;
|
|
|
|
note_entrance0("ega_mode0_chn_w_fill");
|
|
|
|
/*
|
|
* Starting on an odd address is inconvenient - go forward one -
|
|
* and take the even address write off the top as well.
|
|
*/
|
|
|
|
if(( (ULONG) offset & 1) && count )
|
|
{
|
|
odd = TRUE;
|
|
ega_mode0_chn_b_write( value, offset++ );
|
|
count -= 2;
|
|
ega_mode0_chn_b_write( value >> 8, offset + count );
|
|
}
|
|
|
|
high_offset = offset + count - 1;
|
|
|
|
/* the 3rd parameter is needed by GORE */
|
|
(*update_alg.mark_wfill)( offset, high_offset, 0 );
|
|
|
|
offset = (offset >> 1) << 2;
|
|
high_offset = (high_offset >> 1) << 2;
|
|
|
|
switch( getVideoplane_enable() & 0x3 )
|
|
{
|
|
case 0x1: /* just plane 0 ie even addresses to be written */
|
|
if (EGA_CPU.sr_enable & 1)
|
|
{
|
|
value1 = *((UTINY *) &EGA_CPU.sr_value);
|
|
}
|
|
else
|
|
{
|
|
value1 = odd ? value >> 8 : value;
|
|
|
|
if( getVideorotate() > 0 )
|
|
value1 = rotate( value1, getVideorotate() );
|
|
}
|
|
|
|
value1 = do_logicals( value1, get_latch0 );
|
|
fill_alternate_bytes((IS8 *)&EGA_plane01[offset],
|
|
(IS8 *)&EGA_plane01[high_offset],
|
|
(IS8)value1 );
|
|
|
|
break;
|
|
|
|
case 0x2: /* just plane 1 ie odd addresses to be written */
|
|
if (EGA_CPU.sr_enable & 2)
|
|
{
|
|
value1 = *((UTINY *) &EGA_CPU.sr_value + 1);
|
|
}
|
|
else
|
|
{
|
|
value1 = odd ? value : value >> 8;
|
|
|
|
if( getVideorotate() > 0 )
|
|
value1 = rotate( value1, getVideorotate() );
|
|
}
|
|
|
|
value1 = do_logicals( value1, get_latch1 );
|
|
fill_alternate_bytes((IS8 *)&EGA_plane01[offset + 1],
|
|
(IS8 *)&EGA_plane01[high_offset],
|
|
(IS8)value1 );
|
|
|
|
break;
|
|
|
|
case 0x3: /* sensible case is to have both chained planes write enabled */
|
|
if (EGA_CPU.sr_enable & 1)
|
|
{
|
|
value1 = *((UTINY *) &EGA_CPU.sr_value);
|
|
}
|
|
else
|
|
{
|
|
value1 = odd ? value >> 8 : value;
|
|
|
|
if( getVideorotate() > 0 )
|
|
value1 = rotate( value1, getVideorotate() );
|
|
}
|
|
|
|
if (EGA_CPU.sr_enable & 2)
|
|
{
|
|
value2 = *((UTINY *) &EGA_CPU.sr_value + 1);
|
|
}
|
|
else
|
|
{
|
|
value2 = odd ? value : value >> 8;
|
|
|
|
if( getVideorotate() > 0 )
|
|
value2 = rotate( value2, getVideorotate() );
|
|
}
|
|
|
|
value = value1 | value2 << 8;
|
|
value = do_logicals( value, get_latch01 );
|
|
|
|
fill_both_bytes( value, (USHORT *)&EGA_plane01[offset], count >> 1 );
|
|
|
|
break;
|
|
|
|
} /* end of switch on plane01 enabled */
|
|
|
|
switch( getVideoplane_enable() & 0xc )
|
|
{
|
|
case 0x4:
|
|
if( EGA_CPU.sr_enable & 4 )
|
|
{
|
|
value1 = *((UTINY *) &EGA_CPU.sr_value + 2);
|
|
}
|
|
else
|
|
{
|
|
value1 = odd ? value >> 8 : value;
|
|
|
|
if( getVideorotate() > 0 )
|
|
value1 = rotate( value1, getVideorotate() );
|
|
}
|
|
|
|
value1 = do_logicals( value1, get_latch2 );
|
|
fill_alternate_bytes((IS8 *)&EGA_plane23[offset],
|
|
(IS8 *)&EGA_plane23[high_offset],
|
|
(IS8)value1 );
|
|
|
|
break;
|
|
|
|
case 0x8:
|
|
if( EGA_CPU.sr_enable & 8 )
|
|
{
|
|
value2 = *((UTINY *) &EGA_CPU.sr_value + 3);
|
|
}
|
|
else
|
|
{
|
|
value2 = odd ? value : value >> 8;
|
|
|
|
if( getVideorotate() > 0 )
|
|
value2 = rotate( value2, getVideorotate() );
|
|
}
|
|
|
|
value2 = do_logicals( value2, get_latch3 );
|
|
fill_alternate_bytes((IS8 *)&EGA_plane23[offset + 1],
|
|
(IS8 *)&EGA_plane23[high_offset],
|
|
(IS8)value2 );
|
|
|
|
break;
|
|
|
|
case 0xc:
|
|
if (EGA_CPU.sr_enable & 4)
|
|
{
|
|
value1 = *((UTINY *) &EGA_CPU.sr_value + 2);
|
|
}
|
|
else
|
|
{
|
|
value1 = odd ? value >> 8 : value;
|
|
|
|
if( getVideorotate() > 0 )
|
|
value1 = rotate( value1, getVideorotate() );
|
|
}
|
|
|
|
if (EGA_CPU.sr_enable & 8)
|
|
{
|
|
value2 = *((UTINY *) &EGA_CPU.sr_value + 3);
|
|
}
|
|
else
|
|
{
|
|
value2 = odd ? value : value >> 8;
|
|
|
|
if( getVideorotate() > 0 )
|
|
value2 = rotate( value2, getVideorotate() );
|
|
}
|
|
|
|
value = value1 | value2 << 8;
|
|
value = do_logicals( value, get_latch23 );
|
|
|
|
fill_both_bytes( value, (USHORT *)&EGA_plane01[offset], count >> 1 );
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
LOCAL VOID
|
|
ega_mode0_chn_move_ram_src IFN5(UTINY *, eas, LONG, count, UTINY *, ead,
|
|
UTINY *, EGA_plane, ULONG, plane )
|
|
{
|
|
ULONG offset;
|
|
UTINY *src_offset;
|
|
UTINY value;
|
|
ULONG lsb, srcinc;
|
|
|
|
src_offset = (UTINY *) eas;
|
|
offset = (ULONG) ead;
|
|
|
|
if(( offset & 1 ) != ( plane & 1 ))
|
|
{
|
|
#ifdef BACK_M
|
|
src_offset--;
|
|
#else
|
|
src_offset++;
|
|
#endif
|
|
offset++;
|
|
count--;
|
|
}
|
|
|
|
#ifdef BACK_M
|
|
srcinc = -2;
|
|
#else
|
|
srcinc = 2;
|
|
#endif
|
|
|
|
lsb = offset & 1;
|
|
offset = (offset >> 1) << 2;
|
|
offset |= lsb;
|
|
|
|
/*
|
|
* check if set/reset function enable for this plane
|
|
*/
|
|
|
|
if( EGA_CPU.sr_enable & ( 1 << plane ))
|
|
{
|
|
value = *((UTINY *) &EGA_CPU.sr_value + plane );
|
|
|
|
while( count > 0 )
|
|
{
|
|
count -= 2;
|
|
|
|
EGA_plane[offset] = do_logicals( value, get_latch(plane) );
|
|
offset += 4;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while( count > 0 )
|
|
{
|
|
value = *src_offset;
|
|
src_offset += srcinc;
|
|
count -= 2;
|
|
|
|
/*
|
|
* set/reset not enabled so here we go
|
|
*/
|
|
|
|
if( getVideorotate() > 0 )
|
|
value = rotate( value, getVideorotate() );
|
|
|
|
value = do_logicals( value, get_latch(plane) );
|
|
EGA_plane[offset] = value;
|
|
offset += 4;
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCAL VOID
|
|
ega_mode0_chn_move_vid_src IFN7(UTINY *, eas, LONG, count, UTINY *, ead,
|
|
UTINY *, EGA_plane, UTINY *, scratch, ULONG, plane, ULONG, w )
|
|
{
|
|
ULONG offset;
|
|
ULONG src_offset;
|
|
UTINY *source;
|
|
UTINY value;
|
|
UTINY valsrc;
|
|
ULONG lsb, inc, srcinc;
|
|
|
|
offset = (ULONG ) ead;
|
|
|
|
if(( offset & 1 ) != ( plane & 1 ))
|
|
{
|
|
eas++;
|
|
#ifdef BACK_M
|
|
scratch--;
|
|
#else
|
|
scratch++;
|
|
#endif
|
|
offset++;
|
|
count--;
|
|
}
|
|
|
|
src_offset = (ULONG) eas;
|
|
|
|
#ifdef BACK_M
|
|
srcinc = -2;
|
|
#else
|
|
srcinc = 2;
|
|
#endif
|
|
inc = 4;
|
|
|
|
lsb = offset & 1;
|
|
offset = (offset >> 1) << 2;
|
|
offset |= lsb;
|
|
|
|
lsb = src_offset & 1;
|
|
src_offset = (src_offset >> 1) << 2;
|
|
src_offset |= lsb;
|
|
|
|
source = &EGA_plane[src_offset] + (w << 2);
|
|
|
|
/*
|
|
* check if set/reset function enable for this plane
|
|
*/
|
|
|
|
if( EGA_CPU.sr_enable & ( 1 << plane ))
|
|
{
|
|
value = *((UTINY *) &EGA_CPU.sr_value + plane );
|
|
|
|
while( count > 0 )
|
|
{
|
|
count -= 2;
|
|
valsrc = *source;
|
|
source += inc;
|
|
EGA_plane[offset] = do_logicals( value, valsrc );
|
|
offset += inc;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while( count > 0 )
|
|
{
|
|
count -= 2;
|
|
|
|
value = *(UTINY *) scratch;
|
|
scratch += srcinc;
|
|
|
|
valsrc = *source;
|
|
source += inc;
|
|
|
|
/*
|
|
* set/reset not enabled so here we go
|
|
*/
|
|
|
|
if( getVideorotate() > 0 )
|
|
value = rotate( value, getVideorotate() );
|
|
|
|
value = do_logicals( value, valsrc );
|
|
EGA_plane[offset] = value;
|
|
offset += inc;
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ega_mode0_chn_move IFN6(UTINY, w, UTINY *, ead, UTINY *, eas, ULONG, count,
|
|
ULONG, src_flag, IBOOL, forwards )
|
|
{
|
|
UTINY *scratch;
|
|
IMPORT VOID (*string_read_ptr)();
|
|
|
|
note_entrance0("ega_mode0_chn_move");
|
|
|
|
if( src_flag == 1 )
|
|
{
|
|
/*
|
|
* Source is in EGA, latches will change with each byte moved. We
|
|
* restore CPU's view of source in regen, and use it to update planes
|
|
* with the aid of the SAS scratch area.
|
|
*/
|
|
|
|
#ifdef BACK_M
|
|
scratch = getVideoscratch() + 0x10000 - 1;
|
|
#else
|
|
scratch = getVideoscratch();
|
|
#endif
|
|
|
|
if( !forwards )
|
|
{
|
|
eas += - count + 1 + w;
|
|
ead += - count + 1 + w;
|
|
}
|
|
|
|
(*string_read_ptr)( scratch, eas, count );
|
|
|
|
if( getVideoplane_enable() & 1 )
|
|
ega_mode0_chn_move_vid_src( eas, count, ead, EGA_plane01, scratch, 0, 0 );
|
|
|
|
if( getVideoplane_enable() & 2 )
|
|
ega_mode0_chn_move_vid_src( eas, count, ead, EGA_plane01, scratch, 1, w );
|
|
|
|
if( getVideoplane_enable() & 4 )
|
|
ega_mode0_chn_move_vid_src( eas, count, ead, EGA_plane23, scratch, 2, 0 );
|
|
|
|
if( getVideoplane_enable() & 8 )
|
|
ega_mode0_chn_move_vid_src( eas, count, ead, EGA_plane23, scratch, 3, w );
|
|
}
|
|
else
|
|
{
|
|
if( !forwards )
|
|
{
|
|
#ifdef BACK_M
|
|
eas += count - 1 - w;
|
|
#else
|
|
eas += - count + 1 + w;
|
|
#endif
|
|
ead += - count + 1 + w;
|
|
}
|
|
|
|
if( getVideoplane_enable() & 1 )
|
|
ega_mode0_chn_move_ram_src( eas, count, ead, EGA_plane01, 0 );
|
|
|
|
if( getVideoplane_enable() & 2 )
|
|
ega_mode0_chn_move_ram_src( eas, count, ead, EGA_plane01, 1 );
|
|
|
|
if( getVideoplane_enable() & 4 )
|
|
ega_mode0_chn_move_ram_src( eas, count, ead, EGA_plane23, 2 );
|
|
|
|
if( getVideoplane_enable() & 8 )
|
|
ega_mode0_chn_move_ram_src( eas, count, ead, EGA_plane23, 3 );
|
|
}
|
|
|
|
(*update_alg.mark_string)( (ULONG) ead, (ULONG) ead + count );
|
|
}
|
|
|
|
|
|
VOID
|
|
ega_mode0_chn_b_move IFN4(ULONG, ead, ULONG, eas, ULONG, count, ULONG, src_flag)
|
|
{
|
|
ega_mode0_chn_move( 0, (UTINY *)ead, (UTINY *)eas, count, src_flag, getDF() ? FALSE : TRUE);
|
|
}
|
|
|
|
VOID
|
|
ega_mode0_chn_b_move_fwd IFN4(ULONG, ead, ULONG, eas, ULONG, count,
|
|
ULONG, src_flag )
|
|
{
|
|
ega_mode0_chn_move( 0, (UTINY *)ead, (UTINY *)eas, count, src_flag, TRUE );
|
|
}
|
|
|
|
VOID
|
|
ega_mode0_chn_b_move_bwd IFN4(ULONG, ead, ULONG, eas, ULONG, count,
|
|
ULONG, src_flag )
|
|
{
|
|
ega_mode0_chn_move( 0, (UTINY *)ead, (UTINY *)eas, count, src_flag, FALSE );
|
|
}
|
|
|
|
VOID
|
|
ega_mode0_chn_w_move IFN4(ULONG, ead, ULONG, eas, ULONG, count, ULONG, src_flag)
|
|
{
|
|
ega_mode0_chn_move(1, (UTINY *)ead, (UTINY *)eas, count << 1, src_flag, getDF() ? FALSE : TRUE);
|
|
}
|
|
|
|
VOID
|
|
ega_mode0_chn_w_move_fwd IFN4(ULONG, ead, ULONG, eas, ULONG, count,
|
|
ULONG, src_flag )
|
|
{
|
|
ega_mode0_chn_move(1,(UTINY *)ead, (UTINY *)eas, count << 1, src_flag, TRUE );
|
|
}
|
|
|
|
VOID
|
|
ega_mode0_chn_w_move_bwd IFN4(ULONG, ead, ULONG, eas, ULONG, count,
|
|
ULONG, src_flag )
|
|
{
|
|
ega_mode0_chn_move(1,(UTINY *)ead, (UTINY *)eas, count << 1, src_flag, FALSE );
|
|
}
|
|
|
|
VOID
|
|
ega_mode0_chn_w_write IFN2(ULONG, value, ULONG, offset )
|
|
{
|
|
note_entrance0("ega_mode0_chn_w_write");
|
|
|
|
ega_mode0_chn_b_write( value, offset );
|
|
ega_mode0_chn_b_write( value >> 8, offset + 1 );
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif /* !(NTVDM && MONITOR) */
|