summaryrefslogtreecommitdiffstats
path: root/private/mvdm/softpc.new/base/video/ega_writ.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/mvdm/softpc.new/base/video/ega_writ.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/mvdm/softpc.new/base/video/ega_writ.c')
-rw-r--r--private/mvdm/softpc.new/base/video/ega_writ.c861
1 files changed, 861 insertions, 0 deletions
diff --git a/private/mvdm/softpc.new/base/video/ega_writ.c b/private/mvdm/softpc.new/base/video/ega_writ.c
new file mode 100644
index 000000000..64c9db4b0
--- /dev/null
+++ b/private/mvdm/softpc.new/base/video/ega_writ.c
@@ -0,0 +1,861 @@
+#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 : J.Roper
+
+REVISION HISTORY :
+First version : 7/22/88 W.Gulland
+
+SUBMODULE NAME : ega_write
+
+SOURCE FILE NAME : ega_write.c
+
+PURPOSE : control the way writes to EGA memory is emulated.
+ This module looks at the state of the EGA when it is changed
+ via writes to the EGA registers, and works out what to do about it.
+
+
+SccsID = @(#)ega_write.c 1.40 12/15/95 Copyright Insignia Solutions Ltd.
+
+/*=======================================================================
+[3.INTERMODULE INTERFACE DECLARATIONS]
+=========================================================================
+
+[3.1 INTERMODULE IMPORTS] */
+
+/* [3.1.1 #INCLUDES] */
+
+
+#include <stdio.h>
+#include TypesH
+#include FCntlH
+
+#ifdef EGG
+#include "xt.h"
+#include CpuH
+#include "debug.h"
+#include "gmi.h"
+#include "gvi.h"
+#include "egacpu.h"
+#include "egaports.h"
+#include "cpu_vid.h"
+#include "video.h"
+
+
+/* [3.1.2 DECLARATIONS] */
+#if defined(EGA_DUMP) || defined(EGA_STAT)
+extern WRT_POINTERS dump_writes;
+#endif
+
+extern WRT_POINTERS mode0_gen_handlers, mode0_copy_handlers;
+extern WRT_POINTERS mode1_handlers, mode2_handlers;
+
+/* [3.2 INTERMODULE EXPORTS] */
+
+/*
+5.MODULE INTERNALS : (not visible externally, global internally)]
+
+[5.1 LOCAL DECLARATIONS] */
+#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.
+ */
+#include "SOFTPC_EGA.seg"
+#endif
+
+#ifndef REAL_VGA
+
+#ifdef V7VGA
+IMPORT UTINY fg_bg_control;
+GLOBAL UTINY Last_v7_fg_bg; /* used by {ev}ga_mask_register_changed() */
+#endif
+
+#ifndef CPU_40_STYLE /* EVID without introducing EVID define */
+
+WRT_POINTERS *mode_chain_handler_table[] =
+{
+ &mode_table.nch.mode_0[0],
+ &mode_table.nch.mode_1[0],
+ &mode_table.nch.mode_2[0],
+#ifdef VGG
+ &mode_table.nch.mode_3[0],
+#endif
+
+ &mode_table.nch.mode_0[0], /* This should be chain 2 eventually */
+ &mode_table.nch.mode_1[0], /* This should be chain 2 eventually */
+ &mode_table.nch.mode_2[0], /* This should be chain 2 eventually */
+#ifdef VGG
+ &mode_table.nch.mode_3[0], /* This should be chain 2 eventually */
+#endif
+
+#ifdef VGG
+ &mode_table.ch4.mode_0[0],
+ &mode_table.ch4.mode_1[0],
+ &mode_table.ch4.mode_2[0],
+ &mode_table.ch4.mode_3[0],
+#endif /* VGG */
+};
+
+#ifndef EGATEST
+IMPORT VOID glue_b_write IPT2(UTINY *, addr, ULONG, val);
+IMPORT VOID glue_w_write IPT2(UTINY *, addr, ULONG, val);
+IMPORT VOID glue_b_fill IPT3(UTINY *, laddr, UTINY *, haddr, ULONG, val);
+IMPORT VOID glue_w_fill IPT3(UTINY *, laddr, UTINY *, haddr, ULONG, val);
+IMPORT VOID glue_b_move IPT4(UTINY *, laddr, UTINY *, haddr, UTINY *, src, UTINY, src_type);
+IMPORT VOID glue_w_move IPT3(UTINY *, laddr, UTINY *, haddr, UTINY *, src);
+
+#ifndef GISP_CPU
+#ifdef A3CPU
+#ifdef C_VID
+IMPORT VOID _glue_b_write IPT2(UTINY *, addr, ULONG, val);
+IMPORT VOID _glue_w_write IPT2(UTINY *, addr, ULONG, val);
+IMPORT VOID _glue_b_fill IPT3(UTINY *, laddr, UTINY *, haddr, ULONG, val);
+IMPORT VOID _glue_w_fill IPT3(UTINY *, laddr, UTINY *, haddr, ULONG, val);
+IMPORT VOID _glue_b_fwd_move IPT0();
+IMPORT VOID _glue_b_bwd_move IPT0();
+IMPORT VOID _glue_w_fwd_move IPT0();
+IMPORT VOID _glue_w_bwd_move IPT0();
+
+GLOBAL WRT_POINTERS Glue_writes =
+{
+ _glue_b_write,
+ _glue_w_write
+
+#ifndef NO_STRING_OPERATIONS
+ ,
+ _glue_b_fill,
+ _glue_w_fill,
+ _glue_b_fwd_move,
+ _glue_b_bwd_move,
+ _glue_w_fwd_move,
+ _glue_w_bwd_move
+
+#endif /* NO_STRING_OPERATIONS */
+
+};
+
+GLOBAL WRT_POINTERS C_vid_writes;
+#endif /* C_VID */
+#else
+
+#ifdef A_VID
+IMPORT VOID _glue_b_write();
+IMPORT VOID _glue_w_write();
+IMPORT VOID _glue_b_fill();
+IMPORT VOID _glue_w_fill();
+IMPORT VOID _glue_b_move();
+IMPORT VOID _glue_w_move();
+
+GLOBAL MEM_HANDLERS Glue_writes =
+{
+ _glue_b_write,
+ _glue_w_write,
+ _glue_b_fill,
+ _glue_w_fill,
+ _glue_b_move,
+ _glue_w_move,
+};
+
+GLOBAL WRT_POINTERS A_vid_writes;
+
+#else
+
+GLOBAL MEM_HANDLERS Glue_writes =
+{
+ glue_b_write,
+ glue_w_write,
+ glue_b_fill,
+ glue_w_fill,
+ glue_b_move,
+ glue_w_move,
+};
+
+GLOBAL WRT_POINTERS C_vid_writes;
+#endif /* C_VID */
+#endif /* A3CPU */
+#endif /* GISP_CPU */
+#endif /* EGATEST */
+
+IMPORT VOID _simple_b_write();
+IMPORT VOID _simple_w_write();
+IMPORT VOID _simple_b_fill();
+IMPORT VOID _simple_w_fill();
+IMPORT VOID _simple_bf_move();
+IMPORT VOID _simple_wf_move();
+IMPORT VOID _simple_bb_move();
+IMPORT VOID _simple_wb_move();
+
+WRT_POINTERS simple_writes =
+{
+ _simple_b_write,
+ _simple_w_write
+#ifndef NO_STRING_OPERATIONS
+ ,
+ _simple_b_fill,
+ _simple_w_fill,
+ _simple_bf_move,
+ _simple_bb_move,
+ _simple_wf_move,
+ _simple_wb_move
+
+#endif /* NO_STRING_OPERATIONS */
+};
+
+IMPORT VOID _dt0_bw_nch();
+IMPORT VOID _dt0_ww_nch();
+IMPORT VOID _dt0_bf_nch();
+IMPORT VOID _dt0_wf_nch();
+IMPORT VOID _vid_md0_bfm_0_8();
+IMPORT VOID _vid_md0_bbm_0_8();
+IMPORT VOID _vid_md0_wfm_0_8();
+IMPORT VOID _vid_md0_wbm_0_8();
+
+IMPORT VOID _dt2_bw_nch();
+IMPORT VOID _dt2_ww_nch();
+IMPORT VOID _dt2_bf_nch();
+IMPORT VOID _dt2_wf_nch();
+IMPORT VOID _vid_md2_bfm_0_8();
+IMPORT VOID _vid_md2_bbm_0_8();
+IMPORT VOID _vid_md2_wfm_0_8();
+IMPORT VOID _vid_md2_wbm_0_8();
+
+IMPORT VOID _dt3_bw_nch();
+IMPORT VOID _dt3_ww_nch();
+IMPORT VOID _dt3_bf_nch();
+IMPORT VOID _dt3_wf_nch();
+IMPORT VOID _vid_md3_bfm_0_8();
+IMPORT VOID _vid_md3_bbm_0_8();
+IMPORT VOID _vid_md3_wfm_0_8();
+IMPORT VOID _vid_md3_wbm_0_8();
+
+WRT_POINTERS dth_md0_writes =
+{
+ _dt0_bw_nch,
+ _dt0_ww_nch
+
+#ifndef NO_STRING_OPERATIONS
+ ,
+ _dt0_bf_nch,
+ _dt0_wf_nch,
+ _vid_md0_bfm_0_8,
+ _vid_md0_bbm_0_8,
+ _vid_md0_wfm_0_8,
+ _vid_md0_wbm_0_8
+
+#endif /* NO_STRING_OPERATIONS */
+
+};
+
+WRT_POINTERS dth_md2_writes =
+{
+ _dt2_bw_nch,
+ _dt2_ww_nch
+
+#ifndef NO_STRING_OPERATIONS
+ ,
+ _dt2_bf_nch,
+ _dt2_wf_nch,
+ _vid_md2_bfm_0_8,
+ _vid_md2_bbm_0_8,
+ _vid_md2_wfm_0_8,
+ _vid_md2_wbm_0_8
+#endif /* NO_STRING_OPERATIONS */
+
+};
+
+WRT_POINTERS dth_md3_writes =
+{
+ _dt3_bw_nch,
+ _dt3_ww_nch
+
+#ifndef NO_STRING_OPERATIONS
+ ,
+ _dt3_bf_nch,
+ _dt3_wf_nch,
+ _vid_md3_bfm_0_8,
+ _vid_md3_bbm_0_8,
+ _vid_md3_wfm_0_8,
+ _vid_md3_wbm_0_8
+
+#endif /* NO_STRING_OPERATIONS */
+
+};
+
+#else /* CPU_40_STYLE - EVID */
+WRT_POINTERS *mode_chain_handler_table[] = { 0 };
+#ifdef C_VID
+
+/* C_Evid glue */
+extern void write_byte_ev_glue IPT2(IU32, eaOff, IU8, eaVal);
+extern void write_word_ev_glue IPT2(IU32, eaOff, IU16, eaVal);
+extern void fill_byte_ev_glue IPT3(IU32, eaOff, IU8, eaVal, IU32, count);
+extern void fill_word_ev_glue IPT3(IU32, eaOff, IU8, eaVal, IU32, count);
+extern void move_byte_fwd_ev_glue IPT4(IU32, eaOff, IHPE, fromOff, IU32, count, IBOOL, srcInRAM);
+extern void move_word_fwd_ev_glue IPT4(IU32, eaOff, IHPE, fromOff, IU32, count, IBOOL, srcInRAM);
+MEM_HANDLERS Glue_writes =
+{
+ write_byte_ev_glue,
+ write_word_ev_glue,
+ fill_byte_ev_glue,
+ fill_word_ev_glue,
+ move_byte_fwd_ev_glue,
+ move_word_fwd_ev_glue,
+};
+#else /* C_VID */
+/* no glue required */
+MEM_HANDLERS Glue_writes = { 0, 0, 0, 0, 0, 0 };
+#endif /* CVID */
+WRT_POINTERS dth_md0_writes;
+WRT_POINTERS dth_md2_writes;
+WRT_POINTERS simple_writes;
+WRT_POINTERS dth_md3_writes;
+#endif /* CPU_40_STYLE - EVID */
+
+IMPORT VOID ega_copy_b_write();
+IMPORT VOID ega_mode0_chn_b_write();
+IMPORT VOID ega_mode1_chn_b_write();
+IMPORT VOID ega_mode2_chn_b_write();
+
+IMPORT VOID ega_copy_w_write();
+IMPORT VOID ega_mode0_chn_w_write();
+IMPORT VOID ega_mode1_chn_w_write();
+IMPORT VOID ega_mode2_chn_w_write();
+
+/* Handy array to extract all 4 plane values in one go. */
+
+ULONG sr_lookup[16] =
+{
+#ifdef LITTLEND
+ 0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
+ 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
+ 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
+ 0xffff0000,0xffff00ff,0xffffff00,0xffffffff
+#endif
+#ifdef BIGEND
+ 0x00000000,0xff000000,0x00ff0000,0xffff0000,
+ 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
+ 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
+ 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
+#endif
+};
+
+GLOBAL VOID
+stub IFN0()
+{
+ /*
+ * For VGA write modes we don't do because they represent
+ * unlikely combinations of registers.
+ */
+}
+
+GLOBAL ULONG calc_data_xor;
+GLOBAL ULONG calc_latch_xor;
+
+#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.
+ */
+#include "SOFTPC_GRAPHICS.seg"
+#endif
+
+#if !(defined(NTVDM) && defined(MONITOR))
+GLOBAL VOID
+Glue_set_vid_wrt_ptrs IFN1(WRT_POINTERS *, handler )
+{
+
+#ifndef CPU_40_STYLE /* EVID */
+#ifndef GISP_CPU
+#ifdef A3CPU
+#ifdef C_VID
+
+ C_vid_writes.b_write = handler->b_write;
+ C_vid_writes.w_write = handler->w_write;
+ C_vid_writes.b_fill = handler->b_fill;
+ C_vid_writes.w_fill = handler->w_fill;
+ C_vid_writes.b_fwd_move = handler->b_fwd_move;
+ C_vid_writes.b_bwd_move = handler->b_bwd_move;
+ C_vid_writes.w_fwd_move = handler->w_fwd_move;
+ C_vid_writes.w_bwd_move = handler->w_bwd_move;
+
+#else
+ UNUSED(handler);
+#endif /* C_VID */
+#else
+#ifdef C_VID
+
+ C_vid_writes.b_write = handler->b_write;
+ C_vid_writes.w_write = handler->w_write;
+
+#ifndef NO_STRING_OPERATIONS
+
+ C_vid_writes.b_fill = handler->b_fill;
+ C_vid_writes.w_fill = handler->w_fill;
+ C_vid_writes.b_fwd_move = handler->b_fwd_move;
+ C_vid_writes.b_bwd_move = handler->b_bwd_move;
+ C_vid_writes.w_fwd_move = handler->w_fwd_move;
+ C_vid_writes.w_bwd_move = handler->w_bwd_move;
+
+#endif /* NO_STRING_OPERATIONS */
+
+#else
+
+ A_vid_writes = *handler;
+
+#if 0
+ A_vid_writes.b_write = handler->b_write;
+ A_vid_writes.w_write = handler->w_write;
+
+#ifndef NO_STRING_OPERATIONS
+
+ A_vid_writes.b_fill = handler->b_fill;
+ A_vid_writes.w_fill = handler->w_fill;
+ A_vid_writes.b_fwd_move = handler->b_fwd_move;
+ A_vid_writes.b_bwd_move = handler->b_bwd_move;
+ A_vid_writes.w_fwd_move = handler->w_fwd_move;
+ A_vid_writes.w_bwd_move = handler->w_bwd_move;
+
+#endif /* NO_STRING_OPERATIONS */
+#endif /* 0 */
+
+#endif /* C_VID */
+#endif /* A3CPU */
+#endif /* GISP_CPU */
+#endif /* CPU_40_STYLE - EVID */
+}
+#endif /* !(NTVDM && MONITOR) */
+
+#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.
+ */
+#include "SOFTPC_EGA.seg"
+#endif
+
+/* Initialize the write module */
+
+VOID
+ega_write_init IFN0()
+{
+ WRT_POINTERS *handler;
+
+ note_entrance0("ega_write_init");
+
+ EGA_CPU.saved_state = 0;
+ EGA_CPU.write_mode = 0;
+ EGA_CPU.chain = UNCHAINED;
+ setVideochain(EGA_CPU.chain);
+ setVideowrmode(EGA_CPU.write_mode);
+ setVideowrstate(0);
+
+ handler = &mode_chain_handler_table[0][0];
+
+#ifdef CPU_40_STYLE
+ /* ensure correct write mode in place for initial font writes */
+ SetWritePointers();
+#endif
+
+#ifdef JOKER
+
+ Glue_set_vid_wrt_ptrs(handler);
+
+#else /* not JOKER */
+
+#if defined(EGA_DUMP) || defined(EGA_STAT)
+ dump_writes = handler;
+#else
+#ifdef EGATEST
+ gmi_define_mem(VIDEO,(*handler));
+#else
+#ifndef GISP_CPU
+#ifdef A3CPU
+#ifdef C_VID
+ Cpu_set_vid_wrt_ptrs( &Glue_writes );
+ Glue_set_vid_wrt_ptrs( handler );
+#else
+ Cpu_set_vid_wrt_ptrs( handler );
+#endif /* C_VID */
+#else
+ gmi_define_mem(VIDEO,&Glue_writes);
+ Glue_set_vid_wrt_ptrs( handler );
+#endif /* A3CPU */
+#endif /* GISP_CPU */
+#endif /* EGATEST */
+#endif /* EGA_DUMP || EGA_STAT */
+#endif /* JOKER */
+
+ ega_write_routines_update(WRITE_MODE);
+ ega_write_routines_update(RAM_MOVED);
+ ega_write_routines_update(RAM_ENABLED);
+ ega_write_routines_update(SET_RESET);
+ ega_write_routines_update(ENABLE_SET_RESET);
+ ega_write_routines_update(FUNCTION);
+}
+
+VOID
+ega_write_term IFN0()
+{
+ /*
+ * ensure that if you are an EGA and then change to a VGA (or vice
+ * versa) the write mode will be changed by the new adaptor. Otherwise
+ * this gives a 'drunken' font
+ */
+
+ EGA_CPU.write_mode = 0;
+ EGA_CPU.ega_state.mode_0.lookup =
+ (EGA_CPU.ega_state.mode_0.lookup == 0) ? 1 : 0;
+ setVideowrmode(EGA_CPU.write_mode);
+
+ ega_write_routines_update(WRITE_MODE);
+}
+
+
+/* analyze the write state, and update the routines if necesary */
+
+VOID
+ega_write_routines_update IFN1(CHANGE_TYPE, reason )
+{
+ ULONG state;
+ ULONG mode_and_chain;
+ WRT_POINTERS *handler;
+#ifndef PROD
+ LOCAL WRT_POINTERS *last_handler;
+#endif
+
+ note_entrance1("ega_write_routines_update(%d)",reason);
+
+ switch( reason )
+ {
+ case FUNCTION:
+ switch (write_state.func)
+ {
+ case 0: /* Assign */
+ setVideodata_and_mask(0xffffffff);
+ setVideodata_xor_mask(~(getVideobit_prot_mask()));
+ setVideolatch_xor_mask(getVideobit_prot_mask());
+ EGA_CPU.calc_data_xor = 0xffffffff;
+ EGA_CPU.calc_latch_xor = 0xffffffff;
+ break;
+
+ case 1: /* AND */
+ setVideodata_and_mask(0xffffffff);
+ setVideodata_xor_mask(~(getVideobit_prot_mask()));
+ setVideolatch_xor_mask(0);
+ EGA_CPU.calc_data_xor = 0xffffffff;
+ EGA_CPU.calc_latch_xor = 0x00000000;
+ break;
+
+ case 2: /* OR */
+ setVideodata_and_mask(0);
+ setVideodata_xor_mask(0xffffffff);
+ setVideolatch_xor_mask(
+ getVideobit_prot_mask());
+ EGA_CPU.calc_data_xor = 0x00000000;
+ EGA_CPU.calc_latch_xor = 0xffffffff;
+ break;
+
+ case 3: /* XOR */
+ setVideodata_and_mask(0xffffffff);
+ setVideodata_xor_mask(0xffffffff);
+ setVideolatch_xor_mask(
+ getVideobit_prot_mask());
+ EGA_CPU.calc_data_xor = 0x00000000;
+ EGA_CPU.calc_latch_xor = 0xffffffff;
+ break;
+ }
+
+ setVideocalc_data_xor(EGA_CPU.calc_data_xor);
+ setVideocalc_latch_xor(EGA_CPU.calc_latch_xor);
+ break;
+
+ case WRITE_MODE:
+ /* write mode 3 has set/reset enabled for all planes
+ * so recalulate the mask ignoring the sr_enable register
+ * otherwise set the mask in case mode 3 last time.
+ */
+ if( EGA_CPU.write_mode == 3) {
+ setVideosr_nmask(0);
+ setVideosr_masked_val(sr_lookup[EGA_CPU.set_reset]);
+ } else {
+ setVideosr_nmask(~sr_lookup[EGA_CPU.sr_enable]);
+ setVideosr_masked_val(sr_lookup[EGA_CPU.set_reset & EGA_CPU.sr_enable]);
+ }
+ break;
+
+ case SET_RESET:
+ EGA_CPU.sr_value= sr_lookup[EGA_CPU.set_reset];
+ if( EGA_CPU.write_mode == 3) {
+ setVideosr_masked_val(sr_lookup[EGA_CPU.set_reset]);
+ } else {
+ setVideosr_masked_val(sr_lookup[EGA_CPU.set_reset & EGA_CPU.sr_enable]);
+ }
+ break;
+
+ case ENABLE_SET_RESET:
+ if( EGA_CPU.write_mode == 3) {
+ setVideosr_nmask(0);
+ setVideosr_masked_val(sr_lookup[EGA_CPU.set_reset]);
+ } else {
+ setVideosr_nmask(~sr_lookup[EGA_CPU.sr_enable]);
+ setVideosr_masked_val(sr_lookup[EGA_CPU.set_reset & EGA_CPU.sr_enable]);
+ }
+ break;
+
+ case PLANES_ENABLED:
+ if (EGA_CPU.chain == CHAIN2)
+ {
+ if( getVideoplane_enable() & 0xc )
+ {
+ setVideorplane(EGA_plane23);
+ setVideowplane(EGA_plane23);
+ }
+ else
+ {
+ setVideorplane(EGA_plane01);
+ setVideowplane(EGA_plane01);
+ }
+ }
+ break;
+
+ case CHAINED:
+ switch( EGA_CPU.chain )
+ {
+ case UNCHAINED:
+ case CHAIN4:
+ update_banking();
+ break;
+
+ case CHAIN2:
+ if( getVideoplane_enable() & 0xc )
+ {
+ setVideorplane(EGA_plane23);
+ setVideowplane(EGA_plane23);
+ }
+ else
+ {
+ setVideorplane(EGA_plane01);
+ setVideowplane(EGA_plane01);
+ }
+ break;
+ }
+
+ break;
+
+ case RAM_MOVED:
+ case RAM_ENABLED:
+ case BIT_PROT:
+ /* No action required */
+ break;
+
+/*
+ * Rotates are only partially supported in Avid and Cvid.
+ * Mode 0 unchained byte writes are supported. Word writes are also
+ * supported in this case, as they use the byte write routines.
+ *
+ * Manage Your Money is the only application currently known to use rotates,
+ * as of 22 Jan 1993.
+ */
+ case ROTATION:
+ if (getVideorotate() > 0)
+ {
+#ifdef CPU_40_STYLE
+ /* Write pointer change required but probably
+ * no state change otherwise.
+ */
+ SetWritePointers();
+#endif
+ always_trace3("Possible unsupported data rotate mode %d chain %d rotate by %d",
+ EGA_CPU.write_mode,
+ EGA_CPU.chain, getVideorotate());
+ }
+ break;
+
+ default:
+ assert0( NO, "Bad reason in ega_write_routines_update" );
+ break;
+ }
+
+ /*
+ * Now select the right set of write routines according to the current state.
+ */
+
+ switch( EGA_CPU.write_mode )
+ {
+ case 0:
+ state = EGA_CPU.ega_state.mode_0.lookup;
+ break;
+
+ case 1:
+ state = EGA_CPU.ega_state.mode_1.lookup;
+ break;
+
+ case 2:
+ state = EGA_CPU.ega_state.mode_2.lookup;
+ break;
+
+#ifdef VGG
+ case 3:
+ state = EGA_CPU.ega_state.mode_3.lookup;
+ break;
+#endif /* VGG */
+
+ default:
+ assert1( NO, "Bad write mode %d\n", EGA_CPU.write_mode );
+ break;
+ }
+
+#ifdef VGG
+ mode_and_chain = (EGA_CPU.chain << 2) + EGA_CPU.write_mode;
+#else
+ mode_and_chain = (EGA_CPU.chain * 3) + EGA_CPU.write_mode;
+#endif /* VGG */
+
+ if(( EGA_CPU.saved_mode_chain != mode_and_chain )
+ || ( EGA_CPU.saved_state != state )
+#ifdef V7VGA
+ || ( Last_v7_fg_bg != fg_bg_control)
+#endif /* V7VGA */
+ )
+ {
+ setVideowrmode(EGA_CPU.write_mode); /* reset for 'copy case' below */
+
+ if( EGA_CPU.chain == CHAIN2 )
+ switch (EGA_CPU.write_mode)
+ {
+ case 0:
+ if( state == 0 ) /* basic text */
+ {
+ handler = &mode0_copy_handlers;
+#ifdef CPU_40_STYLE
+ setVideowrmode(4); /* indicate 'copy case' */
+#endif /* CPU_40_STYLE */
+ bios_ch2_byte_wrt_fn = ega_copy_b_write;
+ bios_ch2_word_wrt_fn = ega_copy_w_write;
+ }
+ else
+ {
+ handler = &mode0_gen_handlers;
+ bios_ch2_byte_wrt_fn = ega_mode0_chn_b_write;
+ bios_ch2_word_wrt_fn = ega_mode0_chn_w_write;
+ }
+ break;
+
+ case 1:
+ handler = &mode1_handlers;
+ bios_ch2_byte_wrt_fn = ega_mode1_chn_b_write;
+ bios_ch2_word_wrt_fn = ega_mode1_chn_w_write;
+ break;
+
+ case 2:
+ case 3: /* We don't support mode 3, chain 2 - JS */
+ handler = &mode2_handlers;
+ bios_ch2_byte_wrt_fn = ega_mode2_chn_b_write;
+ bios_ch2_word_wrt_fn = ega_mode2_chn_w_write;
+ break;
+ }
+ else
+ {
+#ifdef V7VGA
+ /*
+ * Is it the V7VGA foreground dithering extension ?
+ */
+
+ if( fg_bg_control & 0x8 )
+ {
+ setVideodither(1); /* enable Evid dither fns */
+ switch( EGA_CPU.write_mode )
+ {
+ case 0:
+ handler = &dth_md0_writes;
+ break;
+
+ case 1:
+
+ /*
+ * No fg dither variant for write mode 1
+ */
+
+ handler = &mode_chain_handler_table[mode_and_chain][state];
+ break;
+
+ case 2:
+ handler = &dth_md2_writes;
+ break;
+
+ case 3:
+ handler = &dth_md3_writes;
+ break;
+ }
+ }
+ else
+#endif /* V7VGA */
+ setVideodither(0); /* disable Evid dither fns */
+
+ handler = &mode_chain_handler_table[mode_and_chain][state];
+ }
+
+#ifdef CPU_40_STYLE
+ SetWritePointers();
+#else /* CPU_40_STYLE */
+
+#if defined(EGA_DUMP) || defined(EGA_STAT)
+ dump_writes = handler;
+#else
+ /* Tell the glue code about the new write routines */
+
+#ifdef EGATEST
+ gmi_redefine_mem(VIDEO,(*handler));
+#else
+#ifndef GISP_CPU
+#ifdef A3CPU
+#ifdef C_VID
+ Glue_set_vid_wrt_ptrs( handler );
+#else
+ Cpu_set_vid_wrt_ptrs( handler );
+#endif /* C_VID */
+#else
+ Glue_set_vid_wrt_ptrs( handler );
+#endif /* A3CPU */
+#endif /* GISP_CPU */
+#endif /* EGATEST */
+#endif
+
+#endif /* CPU_40_STYLE */
+
+#ifndef PROD
+ last_handler = handler;
+#endif
+
+ set_mark_funcs();
+
+ EGA_CPU.saved_state = state;
+ EGA_CPU.saved_mode_chain = mode_and_chain;
+#ifdef V7VGA
+ Last_v7_fg_bg = fg_bg_control;
+#endif
+ }
+}
+#endif /* REAL VGA */
+#endif /* EGG */
+
+#endif /* !(NTVDM && MONITOR) */