/***************************************************************************** * Change Log * Date | Change *-----------+----------------------------------------------------------------- * 20-Dec-85 | [1.224] Created * 25-Feb-86 | [1.379] include <> => include "" * 24-Dec-94 | [1.600J] JRJ Implement tape drives. *****************************************************************************/ #include #include #include "boolean.h" #include "btypes.h" #include "scdspmsg.h" #include "mouse.h" #include "hercules.h" #include "display.h" #include "disp.h" #include "panel.h" #include "periph.h" #include "keys.h" #include "kb.h" #include "kbd.h" #include "button.h" #include "scan.h" #include "color.h" #include "1401.h" #include "tape.h" extern boolean done; /* Power off switch */ extern unsigned char lastkey; static boolean tdone; void activate_tape(mouse_coord mX, mouse_coord mY); void activate_tape_2(mouse_coord mX, mouse_coord mY); void tape_nop(mouse_coord mX, mouse_coord mY); void draw_tape_drive(tapedrive *tape); static keybindings kb = { activate_tape, /* mouse left */ tape_nop, /* mouse middle */ activate_tape_2, /* mouse right */ ins_key, /* INS */ del_key, /* DEL */ move_y_up, /* uparrow */ move_y_down, /* downarrow */ move_x_left, /* leftarrow */ move_x_right, /* rightarrow */ pr_go, /* pgup */ pr_go, /* pgdn */ NULL, /* home */ NULL, /* end */ NULL, /* c-left */ NULL, /* c-right */ { NULL, /* 000 */ NULL, /* ^A */ NULL, /* ^B */ ctlc, /* ^C */ NULL, /* ^D */ NULL, /* ^E */ NULL, /* ^F */ NULL, /* ^G */ NULL, /* ^H */ NULL, /* ^I */ NULL, /* ^J */ NULL, /* ^K */ draw_current_screen,/* ^L */ ins_key, /* ^M */ NULL, /* ^N */ NULL, /* ^O */ ctlp, /* ^P */ ctlq, /* ^Q */ NULL, /* ^R */ ctls, /* ^S */ NULL, /* ^T */ NULL, /* ^U */ NULL, /* ^V */ NULL, /* ^W */ NULL, /* ^X */ NULL, /* ^Y */ NULL, /* ^Z */ ctlc, /* ^[ */ NULL, /* ^\ */ NULL, /* ^] */ NULL, /* ^^ */ NULL /* ^_ */ } }; tapedrive *tapes[MAXDRIVES]; static tapedrive tape_static[MAXDRIVES]; /**************************************************************************** * check_tape_peripherals * Inputs: * coord X: screen coordinate of mouse hit * coord Y: screen coordinate of mouse hit * * Result: * boolean. True if peripherals button on tape drive screen hit. * ****************************************************************************/ boolean check_tape_peripherals(coord X, coord Y) { if(bounded(X,Y,peripherals_X,peripherals_Y, peripherals_X+peripherals_width, peripherals_Y+peripherals_height-1)) { hide_mouse_cursor(); set_display(PERIPHERALS); draw_current_screen(); show_mouse_cursor(); return(true); } return(false); } /**************************************************************************** * check_tape_unit * Inputs: * coord X: screen coordinate of mouse hit * coord Y: screen coordiante of mouse hit * tapedrive *T: address of a tape drive control block * * Result: * Processes tape drive unit wheel on appropriate drive if hit ****************************************************************************/ void check_tape_unit(coord X, coord Y, tapedrive *T, int dir) { if(!bounded(X,Y,T->X,T->Y,T->X+tape_drive_width-6,T->Y+2)) return; T->unit += dir; if(T->unit < 0) { T->unit = 9; } else if(T->unit > 9) { T->unit = 0; } draw_tape_drive(T); } /**************************************************************************** * check_tape_reset * Inputs: * coord X: screen coordinate of mouse hit * coord Y: screen coordiante of mouse hit * tapedrive *T: address of a tape drive control block * * Result: * Processes tape drive reset key on appropriate drive if hit ****************************************************************************/ void check_tape_reset(coord X, coord Y, tapedrive *T) { if(!in_button(X,Y,&(T->reset))) return; T->start.active = false; draw_tape_drive(T); } /**************************************************************************** * check_tape_load * Inputs: * coord X: screen coordinate of mouse hit * coord Y: screen coordiante of mouse hit * tapedrive *T: address of a tape drive control block * * Result: * Processes tape drive load key on appropriate drive if hit * NOP if drive is online. * Closes file, if loaded. * If not loaded, loads (gets file name) * Resets IRG indicator ****************************************************************************/ void check_tape_load(coord X, coord Y, tapedrive *T) { if(!in_button(X,Y,&(T->load))) return; if(T->start.active) return; if(!T->loaded) { sccurset(tape_name_Y,(coord)T->X+2); gets(T->filename); T->loaded = true; } if(T->file != NULL) { fclose(T->file); T->file = NULL; } T->at_irg = false; draw_tape_drive(T); } /**************************************************************************** * check_tape_unload * Inputs: * coord X: screen coordinate of mouse hit * coord Y: screen coordiante of mouse hit * tapedrive *T: address of a tape drive control block * * Result: * Processes tape drive unload key on appropriate drive if hit ****************************************************************************/ void check_tape_unload(coord X, coord Y, tapedrive *T) { if(!in_button(X,Y,&(T->unload))) return; if(T->start.active || !T->loaded) return; if(T->file != NULL) { fclose(T->file); T->file = NULL; } T->loaded = false; T->readonly = false; T->indicate.border = COLOR_GREEN; T->filename[0]='\0'; draw_tape_drive(T); } /**************************************************************************** * check_tape_start * Inputs: * coord X: screen coordinate of mouse hit * coord Y: screen coordiante of mouse hit * tapedrive *T: address of a tape drive control block * * Result: * Processes tape drive start key on appropriate drive if hit ****************************************************************************/ void check_tape_start(coord X, coord Y, tapedrive *T) { if(!in_button(X,Y,&(T->start))) return; if(T->start.active || !T->loaded) return; /* If the file is not already open, try and open it for reading and writing. If that succeeds, fine. Otherwise, try and open it for read only. Set color of Tape Indicate button RED if readonly If, however, the file is already open, just go and set the active bit on again. */ if(T->file == NULL) { if((T->file = fopen(T->filename,"rb+")) == NULL) { if((T->file = fopen(T->filename,"rb")) == NULL) { T->start.active = false; /* Open failed. NOP */ } else { T->readonly = true; T->indicate.border = COLOR_RED; T->start.active = true; } } else { T->readonly = false; T->indicate.border = COLOR_GREEN; T->start.active=true; } } else { T->start.active = true; } draw_tape_drive(T); } /**************************************************************************** * activate_tape * Inputs: * mouse_coord mX: screen X of mouse hit * mouse_coord mY: screen Y of mouse hit * Effect: * Handles all tape drive activation. Sets "tdone" if necessary to * halt processing of tape drive screen scan. *****************************************************************************/ void activate_tape(mouse_coord mX, mouse_coord mY) { coord X, Y, old_x, old_y; int i; X = mouse_to_screen_x(mX); Y = mouse_to_screen_y(mY); sccurpos(&old_y, &old_x); if(check_tape_peripherals(X,Y)) { tdone = true; return; } for(i=0; i < MAXDRIVES; ++i) { check_tape_unit(X,Y,tapes[i],+1); check_tape_load(X,Y,tapes[i]); check_tape_start(X,Y,tapes[i]); check_tape_unload(X,Y,tapes[i]); check_tape_reset(X,Y,tapes[i]); } if(done) { tdone = true; goto exit; } exit: sccurset(old_y, old_x); return; } /**************************************************************************** * activate_tape_2 * Inputs: * mouse_coord mX: screen X of mouse hit * mouse_coord mY: screen Y of mouse hit * Effect: * Handles all tape drive activation for right hand mouse button. * Sets "tdone" if necessary to halt processing of tape drive screen scan. *****************************************************************************/ void activate_tape_2(mouse_coord mX, mouse_coord mY) { coord X, Y, old_x, old_y; int i; X = mouse_to_screen_x(mX); Y = mouse_to_screen_y(mY); sccurpos(&old_y, &old_x); for (i=0; i < MAXDRIVES; ++i) { check_tape_unit(X,Y,tapes[i],-1); } if(done) { tdone = true; goto exit; } exit: sccurset(old_y, old_x); return; } /**************************************************************************** * tape_nop * Inputs: * mouse_coord mX: X coordinate of mouse hit. * mouse_coord mY: Y coordinate of mouse hit * Effect: * does nothign. ****************************************************************************/ void tape_nop(mouse_coord mX, mouse_coord mY) { return; } /**************************************************************************** * do_tape * Effect: * Handles all dispatching for tape drive screen ****************************************************************************/ void do_tape() { set_display(TAPEDRIVE); draw_current_screen(); show_mouse_cursor(); tdone = false; wait_for_mouse_up(); scan(&tdone, &kb, false); } /**************************************************************************** * check_tapeload * Inputs: * int X: Screen X-coordinate of mouse hit * int Y: Screen Y-coordinate of mouse hit * tapedrive * tape: Tape drive descriptor * Result: boolean * true if we have just pushed the load button for this tape * false if we have not ****************************************************************************/ boolean tapeload(X,Y,tape) coord X; coord Y; tapedrive * tape; { return in_button(X,Y,&tape->load); } /**************************************************************************** * draw_tape_drive * Inputs: * tapedrive * tape: Tape drive to show * Effect: * Draws the tape drive on the screen ****************************************************************************/ void draw_tape_drive(tape) tapedrive *tape; { int i; unsigned char fore, back; char tape_unit_string[tape_drive_width+1]; if(ismono()) { fore = H_NORMAL; back = 0; } else { fore = COLOR_WHITE; back = COLOR_BLACK; } scdspmsg(tape->Y,tape->X,fore,back,"ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿"); sprintf(tape_unit_string,"³ Tape Unit %d ³",tape->unit); scdspmsg(tape->Y+1,tape->X,fore,back,tape_unit_string); scdspmsg(tape->Y+2,tape->X,fore,back,"³ \\ / \\ / ³"); scdspmsg(tape->Y+3,tape->X,fore,back,"³(- o -)(- o -)³"); scdspmsg(tape->Y+4,tape->X,fore,back,"³ / \\ / \\ ³"); scdspmsg(tape->Y+5,tape->X,fore,back,"³ Ð ³"); for(i=0;i<15;i++) { /* draw box */ scdspmsg(tape->Y+6+i,tape->X,fore,back,"³ ³"); } /* draw box */ scdspmsg(tape->Y+6+i,tape->X,fore,back,"ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"); sprintf(tape_unit_string,"%-*.*s",tape_name_width,tape_name_width, tape->filename); scdspmsg(tape->Y+8+i,tape->X+2,fore,back,tape_unit_string); /* Now draw the various buttons */ draw_button(&tape->load); draw_button(&tape->unload); draw_button(&tape->reset); draw_button(&tape->start); draw_button(&tape->indicate); } /**************************************************************************** * draw_tape_drives * Inputs: * None * Effect: * Draws tape drive screen ****************************************************************************/ void draw_tape_drives() { coord x,y; int drive; hide_mouse_cursor(); sccurpos(&y, &x); sccurset(0,0); sc_clearscreen(); for(drive=0; drive < MAXDRIVES; ++drive) { draw_tape_drive(tapes[drive]); } draw_peripherals(); sccurset(y,x); show_mouse_cursor(); } /**************************************************************************** * init_tape_button * Inputs: * button * B: Button to initialize * int X: X position for button * int Y: Y position for button * char * legend: Legend for button * Effect: * Initializes the button. Sets active to false and procedure to NULL ****************************************************************************/ init_tape_button(B,X,Y,legend,color_border,color_on,color_off) button * B; int X; int Y; char * legend; attrib color_border, color_on, color_off; { B->X = X; B->Y = Y; B->legend = legend; B->active = false; B->push = NULL; B->border = color_border; B->on = color_on; B->off = color_off; } /**************************************************************************** * create_tape * Inputs: * int n: tape drive number * Result: tapedrive * * Representative of the tape drive * Effect: * Initializes the tape drive object ****************************************************************************/ create_tape(n) int n; { int X; int Y; assert(n < MAXDRIVES); tapes[n] = NULL; /* if((tapes[n] = malloc(sizeof(tapedrive))) == NULL) { fprintf(stderr,"Out of memory initializing Tape.\n"); exit(0); } */ tapes[n] = &tape_static[n]; tapes[n]->unit = n; X = tapes[n]->X = tape_drive_X + n * tape_drive_width; Y = tapes[n]->Y = tape_drive_Y; tapes[n]->loaded = false; tapes[n]->readonly = false; tapes[n]->at_irg = false; tapes[n]->buff = 0; tapes[n]->filename[0] = '\0'; tapes[n]->left_vacuum = 0; tapes[n]->right_vacuum = 0; tapes[n]->file = NULL; init_tape_button(&(tapes[n]->load),X+tape_load_X,Y+tape_load_Y,"Ld/Rw", COLOR_GREEN,COLOR_GREEN,COLOR_GREEN); init_tape_button(&(tapes[n]->unload),X+tape_unload_X,Y+tape_unload_Y,"UnLd ", COLOR_RED,COLOR_RED,COLOR_RED); init_tape_button(&(tapes[n]->reset),X+tape_reset_X,Y+tape_reset_Y,"Reset", COLOR_RED,COLOR_RED,COLOR_RED); init_tape_button(&(tapes[n]->start),X+tape_start_X,Y+tape_start_Y,"Start", COLOR_GREEN,COLOR_WHITE,COLOR_GREEN); init_tape_button(&(tapes[n]->indicate),X+tape_indicate_X,Y+tape_indicate_Y, "TapeI", COLOR_GREEN,COLOR_WHITE,COLOR_GREEN); } /**************************************************************************** * init_tapes * Effect: * Initializes the tape drives ****************************************************************************/ void init_tapes() { int i; for(i=0;i