/***************************************************************************** * Change Log * Date | Change *-----------+----------------------------------------------------------------- * 15-Nov-85 | [1.30] Created * 17-Nov-85 | [1.89] Upper limit of address switches is 15000 not 16000 * 24-Nov-85 | [1.98] redraw address lights in redraw operation * 30-Dec-85 | [1.276] Wrap units, tens, hundreds switches around * 24-Jan-86 | [1.325] Do not mark/unmark address if not showing_console * 24-Jan-86 | [1.326] Properly store address light state across screen * | redraws; do update on redraw * 22-Feb-86 | [1.364] Added color support * 22-Feb-86 | [1.364] include <> => include "" * 22-Feb-86 | [1.364] replaced all printfs with BIOS calls to support * | instantaneous pages * 23-Feb-86 | [1.367] Separate out show_addr_values to get better screen * | performance; call it instead of whole box redraw to update * | values * 23-Feb-86 | [1.368] Updated markscreen call for new args * 23-Feb-86 | [1.370] Make digit active color light red * 25-Feb-86 | [1.373] Display digits which are off on color display in black * | so they are invisible * 25-Feb-86 | [1.374] Use color.h for certain color parametrizations * 25-Feb-86 | [1.374] If address is zero, turn off all address lights * 25-Feb-86 | [1.376] Added zap_address to clear entire address display * 25-Feb-86 | [1.382] Display manual_address legend in legend color * 29-Jul-86 | [1.385] Include mach.h * 29-Jul-86 | [1.393] Mark only '1' bit for h/o address * 31-Jul-86 | [1.406] Log all changes in console switches * 18-Aug-86 | [1.414] screen.h -> bscreen.h * 18-Aug-86 | [1.417] Write characters as invisible * 20-Aug-86 | [1.427] Light up address light on lamp_test; always call * | mark_addr * 20-Aug-86 | [1.427] Removed clear_addr * 10-Nov-91 | [1.428] converted for Microsoft C 6.0 *****************************************************************************/ /***************************************************************************** 1401 Emulator Address Display Register Maintenance This module draws the address display register on the panel. *****************************************************************************/ #include "stdio.h" #include "graph.h" #include "btypes.h" #include "scdspmsg.h" #include "panel.h" #include "boolean.h" #include "hercules.h" #include "disp.h" #include "color.h" #include "mach.h" #include "diag.h" #include "addr.h" #include "display.h" #include "1401.h" #include "kb.h" #include "scan.h" static int last_address = 0; static boolean addr_on = false; static void lamp_address(boolean set); static void mark_addr(void); /**************************************************************************** * draw_address_box * Effect: * Draws the address display box ****************************************************************************/ void draw_address_box() { attrib fore; attrib back; if(ismono()) { /* mono */ fore = H_NORMAL; back = 0; } /* mono */ else { /* color */ fore = WHITE; back = BLACK; } /* color */ scdspmsg(address_Y,address_X,fore,back, "ÚÄÄ ÄÄ¿"); scdspmsg(address_Y+1,address_X,fore,back, "³ ³"); scdspmsg(address_Y+1,address_X+1,back,back, " 8 8 8 8 "); scdspmsg(address_Y+2,address_X,fore,back, "³ ³"); scdspmsg(address_Y+2,address_X+1,back,back, " 4 4 4 4 "); scdspmsg(address_Y+3,address_X,fore,back, "³ ³"); scdspmsg(address_Y+3,address_X+1,back,back, " 2 2 2 2 "); scdspmsg(address_Y+4,address_X,fore,back, "³ ³"); scdspmsg(address_Y+4,address_X+1,back,back, " 1 1 1 1 1 "); scdspmsg(address_Y+5,address_X,fore,back,"ÀÄÄÄÄÄÄÄÄÄÄÄÙ"); zap_address(); display_address(last_address); mark_addr(); } /**************************************************************************** * mark_address * Inputs: * int digit: Digit position to display (0=units, 1=tens, etc.) * int value: Value to mark in position * boolean set: true to highlight, false to unhighlight * Effect: * Turns lights on and off in the address display ****************************************************************************/ void mark_address(short digit,short value,boolean set) { coord row; coord column; coord i; if(!showing_console()) return; column = address_X + 10 - (2*digit); row = address_Y + 4; for(i=0;i<4;i++) { if(value == 0) break; if((value & 1) != 0) { /* do it */ markscreen(row,column,set,digit_on,BLACK,digit_off,BLACK); } /* do it */ row--; value >>= 1; } } /**************************************************************************** * zap_address * Result: void * * Effect: * Turns all address lamps off ****************************************************************************/ void zap_address() { lamp_address(false); } /**************************************************************************** * lamp_address * Inputs: * boolean set: Turn all lamps on or off * Effect: * Initializes the address display by turning all the digits ****************************************************************************/ void lamp_address(boolean set) { int pos; for(pos = 0;pos < 5; pos++) { /* zap */ int vv; if(pos==4) mark_address(pos,1,set); else for(vv = 8; vv != 0; vv>>=1) mark_address(pos, vv, set); } /* zap */ } /**************************************************************************** * update_address * Inputs: * short addr: Address to updated * boolean set: Mode in which to update it * true to mark * false to unmark * Effect: * Causes the address to be updated on the screen ****************************************************************************/ void update_address(short addr,boolean set) { int v; int pos; if(lamp_test) { /* turn lamps on */ lamp_address(true); return; } /* turn lamps on */ v = addr; pos = 0; if(v == 0) { /* clear it */ zap_address(); return; } /* clear it */ while(v != 0) { /* decode it */ int vv; vv = v % 10; if (vv == 0) vv = 10; /* BCD represents '0' as '8 2' */ mark_address(pos, vv, set); pos++; v = v / 10; } /* decode it */ } /**************************************************************************** * clear_address * Inputs: * short addr: Address value to clear * Effect: * Unmarks the values in the address register ****************************************************************************/ void clear_address(short addr) { update_address(addr,false); } /**************************************************************************** * set_address * Inputs: * short addr: Address to set * Effect: * Marks the bits for the address in the display register ****************************************************************************/ void set_address(short addr) { update_address(addr,true); } /**************************************************************************** * display_address * Inputs: * short addr: Address to display on the address display * Effect: * Updates the address displayed in the box * The last address displayed is stored in last_address ****************************************************************************/ void display_address(short addr) { clear_address(last_address); set_address(addr); last_address = addr; } /**************************************************************************** * get_address_switches * Result: int * Contents of manual address entry switches (0..15999) ****************************************************************************/ static int addr_switches = 0; /* address switches */ short get_address_switches() { return addr_switches; } /**************************************************************************** * show_addr_values * Effect: * Updates the values in the manual address switches ****************************************************************************/ void show_addr_values() { char msg[10]; unsigned char fore; unsigned char back; if(ismono()) { /* mono */ fore = H_NORMAL; back = 0; } /* mono */ else { /* color */ fore = WHITE; back = BLACK; } /* color */ sprintf(msg,"%2d",addr_switches/1000); scdspmsg(manual_Y+2,manual_X+1,fore,back,msg); sprintf(msg,"%2d",(addr_switches/100) % 10); scdspmsg(manual_Y+2,manual_X+6,fore,back,msg); sprintf(msg,"%2d",(addr_switches/10) % 10); scdspmsg(manual_Y+2,manual_X+11,fore,back,msg); sprintf(msg,"%2d",addr_switches % 10); scdspmsg(manual_Y+2,manual_X+16,fore,back,msg); } /**************************************************************************** * draw_manual_address_box * Effect: * Draws the manual address switches box ****************************************************************************/ void draw_manual_address_box() { unsigned char fore; unsigned char back; unsigned char h_fore; unsigned char h_back; if(ismono()) { /* mono */ fore = H_NORMAL; back = 0; h_fore = H_NORMAL; h_back = 0; } /* mono */ else { /* color */ fore = control_fore; back = control_back; h_fore = legend_fore; h_back = legend_back; } /* color */ scdspmsg(manual_Y,manual_X,fore,back, "ÖÄÄ Ä·"); scdspmsg(manual_Y+1,manual_X,fore,back,"ÌÍÍ» ÉÍÍ» ÉÍÍ» ÉÍ͹"); scdspmsg(manual_Y+2,manual_X,fore,back,"º º º º º º º º"); scdspmsg(manual_Y+3,manual_X,fore,back,"ÈÍͼ ÈÍͼ ÈÍͼ ÈÍͼ"); scdspmsg(manual_Y,manual_X+3,h_fore,h_back,"Manual Address"); show_addr_values(); } /**************************************************************************** * check_addr_switches * Inputs: * int X: current X screen position * int Y: current Y screen position * int dir: +1 or -1 * Result: boolean * true if address switch hit (modified or not!) * false if not in address switch * Effect: * modifies the address switch if in one ****************************************************************************/ boolean check_addr_switches(coord X,coord Y,short dir) { if(bounded(X,Y, manual_X, (coord)(manual_Y+1), (coord)(manual_X+manual_width-1), (coord)(manual_Y+manual_height))) { /* thousands */ if(dir > 0 && addr_switches >= 15000) goto exit; if(dir < 0 && addr_switches < 1000) goto exit; addr_switches += 1000 * dir; show_addr_values(); goto exit; } /* thousands */ if(bounded(X,Y, (coord)(manual_X+manual_width+manual_spacing), (coord)(manual_Y+1), (coord)(manual_X+manual_width+manual_spacing-1+manual_width), (coord)(manual_Y+manual_height))) { /* hundreds */ int v; v = addr_switches % 1000; if(dir > 0 && v >= 900) { /* wrap to 0 */ addr_switches -= 900; show_addr_values(); goto exit; } /* wrap to 0 */ if(dir < 0 && v < 100) { /* wrap to 9 */ addr_switches += 900; show_addr_values(); goto exit; } /* wrap to 9 */ addr_switches += 100 * dir; show_addr_values(); goto exit; } /* hundreds */ if(bounded(X,Y, (coord)(manual_X+2*(manual_width+manual_spacing)), (coord)(manual_Y+1), (coord)(manual_X+2*(manual_width+manual_spacing)-1+manual_width), (coord)(manual_Y+manual_height))) { /* tens */ int v; v = addr_switches % 100; if(dir > 0 && v >= 90) { /* wrap to 0 */ addr_switches -= 90; show_addr_values(); goto exit; } /* wrap to 0 */ if(dir < 0 && v < 10) { /* wrap to 9 */ addr_switches += 90; show_addr_values(); goto exit; } /* wrap to 9 */ addr_switches += 10 * dir; show_addr_values(); goto exit; } /* tens */ if(bounded(X,Y, (coord)(manual_X+3*(manual_width+manual_spacing)), (coord)(manual_Y+1), (coord)(manual_X+3*(manual_width+manual_spacing)-1+manual_width), (coord)(manual_Y+manual_height))) { /* ones */ int v; v = addr_switches % 10; if(dir > 0 && v >= 9) { /* wrap to 0 */ addr_switches -= 9; show_addr_values(); goto exit; } /* wrap to 0 */ if(dir < 0 && v < 1) { /* wrap to 0 */ addr_switches += 9; show_addr_values(); goto exit; } /* wrap to 0 */ addr_switches += dir; show_addr_values(); /* see above */ goto exit; } /* ones */ return false; exit: if(diagnostics_on) { /* log it */ char msg[40]; sprintf(msg,"Addr selected: %d",addr_switches); log_console_event(msg); } /* log it */ wait_for_mouse_up(); return true; } /**************************************************************************** * mark_addr * Effect: * Turns on the address light ****************************************************************************/ static void mark_addr() { if(ismono()) mark_screen_color(address_X+3,address_Y,"Address",(boolean)(addr_on || lamp_test), BLACK,WHITE,WHITE,BLACK); else mark_screen_color(address_X+3,address_Y,"Address",(boolean)(addr_on || lamp_test), LTRED,BLACK,WHITE,BLACK); } /**************************************************************************** * set_address_light * Effect: * Turns on the address register light ****************************************************************************/ void set_address_light() { addr_on = true; if(!showing_console()) return; mark_addr(); } /**************************************************************************** * clear_address_light * Effect: * Clears the address indicator ****************************************************************************/ void clear_address_light() { addr_on = false; if(!showing_console()) return; mark_addr(); }