diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/mvdm/softpc.new/base/video/ega_writ.c | |
download | NT4.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.c | 861 |
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) */ |