#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <libraries/asl.h>
#include <libraries/locale.h>
#include <graphics/gfx.h>
#include <dos/dostags.h>
#include <devices/parallel.h>
#include <devices/audio.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define  CATCOMP_NUMBERS
#define  CATCOMP_CODE
#define  CATCOMP_BLOCK
#include "ti92_link_strings.h"

#define GADGET_SCREENSHOT       1
#define GADGET_FARGOSCREENSHOT  2
#define GADGET_SAVESCREENSHOT   3
#define GADGET_GETROMDUMP       4
#define GADGET_RECEIVE          5
#define GADGET_A_LIST           6
#define GADGET_T_LIST           7
#define GADGET_CHK_READY        8
#define GADGET_UPD_LIST         9
#define GADGET_REQ_BACKUP      10
#define GADGET_SEND_BACKUP     11
#define GADGET_REMOTE          12
#define GADGET_PREFS           13
#define GADGET_SOUND           14
#define GADGET_LOAD_FILE       15
#define GADGET_SEND_ONE_TO_TI  16
#define GADGET_SEND_ALL_TO_TI  17
#define GADGET_SEND_ONE_TO_AM  18
#define GADGET_SEND_ALL_TO_AM  19
#define GADGET_SAVE_FILE       20
#define GADGET_VIEW            21

void Init_lib_stuff(void);
BOOL create_window(struct Window **Window1,int left,int top,int width,int height,char *title,int flags,int type,int IDCMPFlag,struct Gadget *FirstGad);
void CreateMes(struct IntuiText *x,SHORT left,SHORT top,UBYTE *mesg);
void StatusString(char *text);
void send_byte(unsigned char data);
unsigned char get_byte(void);
void get_var(void);
void send_ack(void);
void send_datareq(void);
void get_data(unsigned char *data);
void get_ack(void);
void send_reqscrdump(void);
void get_romdump(void);
void drawprogbar(void);
void SetBarPos(char wert);
void get_fcam(void);
void get_vars(void);
void send_chk_ready(void);
void send_sim_ti(void);
void send_get_dirlist(void);
BOOL get_varh(void);
void send_req_backup(void);
void send_remote_char(unsigned char zeichen,unsigned char zeichenh);
void do_remote(void);
void send_var(unsigned int varlang,unsigned char vartyp,unsigned char *varname,unsigned char *data);
void type_string(unsigned char *s,unsigned char typ);
void recmode(BOOL nstat);
BOOL ask_for_comment(unsigned char *comment);
void send_backup(void);
void save_as_iff(void);
void do_prefs(void);
void do_sound(void);
void load_ti92_file(void);
void free_a_list(void);
void printvarinfo(unsigned char *varinfo,BOOL right);
void view_var(void);
void do_locale(void);
void erequest(char *text);
void req_var(unsigned char *varname,unsigned char vartyp,unsigned int varlen);
void save_92g_file(void);
void save_prefs(unsigned char *filename);
void load_prefs(void);
void showcomment(unsigned char *comment);

BOOL calc_ready=FALSE,at_homescreen;
BOOL check_ok;
unsigned int old_chk;

BOOL recmode_stat=FALSE;
FILE *recmode_fileh;

char barpos=0;
char bartext[60];

struct IntuitionBase   *IntuitionBase;
struct Library         *GadToolsBase;
struct Library         *GfxBase;
struct Library         *DosBase;
struct Library         *LocaleBase;

struct IOExtPar *ParallelIO;
struct MsgPort  *ParallelMP;

struct Gadget          *ToolGadgets[25];
struct Gadget          *ToolGadgetList=NULL;
struct Gadget          *CommentGadgets[5];
struct Gadget          *CommentGadgetList=NULL;
struct Gadget          *PrefsGadgets[10];
struct Gadget          *PrefsGadgetList=NULL;

struct Window          *Tool_Window;
struct Window          *Remote_Window;
struct Window          *Comment_Window;
struct Window          *Prefs_Window;
struct Window          *Sound_Window;

long                    upd_scrdump_on_remote=TRUE;
long                    timeout=4;

APTR                    VisualInfo;

struct List             a_list;
unsigned int            a_listsel;
struct Node             a_nodes[50];
unsigned char           a_inuse[50];
unsigned char           *a_data[50];
unsigned char           a_typ[50];
unsigned int            a_lang[50];
unsigned char           a_names[50][30];

struct List             t_list;
unsigned int            t_listsel;
struct Node             t_nodes[50];
unsigned char           t_inuse[50];
unsigned char           t_typ[50];
unsigned int            t_lang[50];
unsigned char           t_names[50][30];

ULONG romsize=1024;
int timeout_error=0;
time_t                  zeit;
unsigned char pic[3][3840];
int picd=0;

unsigned char *PORTREG_B_CIAA = (unsigned char*) 0xBFE101;
unsigned char *PORTREG_A_CIAB = (unsigned char*) 0xBFD000;
unsigned char *DIRREG_B_CIAA  = (unsigned char*) 0xBFE301;
unsigned char *DIRREG_A_CIAB  = (unsigned char*) 0xBFD200;

char *str_prog_exit;
char *str_yes;
char *str_no;
char *str_send_byte_timeout_text;
char *str_get_byte_timeout_text;
char *str_par_err_text;
char *str_butt_get_scrs;
char *str_butt_get_farscrs;
char *str_butt_save_as_iff;
char *str_butt_get_romdump;
char *str_butt_receive;
char *str_a_vars;
char *str_t_vars;
char *str_butt_chk_ready;
char *str_butt_upd_list;
char *str_butt_req_backup;
char *str_butt_send_backup;
char *str_butt_remote;
char *str_butt_prefs;
char *str_butt_sound;
char *str_butt_load_file;
char *str_butt_save_file;
char *str_butt_view;
char *str_romsize;
char *str_textviewer;
char *str_picviewer;
char *str_label_short;
char *str_label_middle;
char *str_label_long;
char *str_ready;
char *str_not_at_homescr;
char *str_not_resp;
char *str_req_scrshot;
char *str_wait_for_data;
char *str_remotecontrolling;
char *str_ti_remotecont;
char *str_getting_var;
char *str_getting_scrshot;
char *str_drawing_scrshot;
char *str_select_file_romdump;
char *str_waiting_for_romdump;
char *str_getting_romdump;
char *str_wait_for_fcam;
char *str_getting_fcam;
char *str_chk_for_calc;
char *str_select_file_save_backup;
char *str_req_backup;
char *str_getting_backup;
char *str_getting_backup_info;
char *str_special_keys;
char *str_waiting_for_input;
char *str_send_var_info;
char *str_enter_comment;
char *str_no_comment;
char *str_ok;
char *str_cancel;
char *str_select_file_send_backup;
char *str_loading_backupfile;
char *str_sending_backup;
char *str_sending_backup_info;
char *str_select_file_save_iff;
char *str_edit_prefs;
char *str_get_scrdump_after_pressing_key;
char *str_timeout;
char *str_prefs;
char *str_select_file_92g;
char *str_err_opening_gfx;
char *str_err_opening_dos;
char *str_err_opening_gadtools;
char *str_err_opening_mainwin;
char *str_err_opening_file;
char *str_err_no_fcam;
char *str_err_no_backupfile;
char *str_err_no_ti92file;
char *str_err_use_send_backup;
char *str_select_file_save_92g;
char *str_err_wrong_chksum;
char *str_save_prefs;
char *str_use_prefs;
char *str_cancel_prefs;
char *str_req_var_info;
char *str_getting_dirlist;
char *str_comment_in_file;

char text_viewer[80]="SYS:Utilities/MultiView";
char pic_viewer[80]="SYS:Utilities/MultiView";

struct IntuiText     send_byte_timeout_text,send_byte_timeout_ok;
struct IntuiText     get_byte_timeout_text,get_byte_timeout_ok;

struct LocaleInfo LocaleInf;

char Versionstr[]="$VER: Ti92-Link v1.00";

unsigned char gcolors[8];

int main()
{
  int                  i;
  ULONG                mclass,mcode,mqualifier;
  struct IntuiMessage  *mesg;
  struct IntuiText     prog_ende_text,prog_ende_y,prog_ende_n;
  struct Screen        *Screenptr;
  struct NewGadget     NewGadgetInfo;
  APTR                 maddress;
/*  struct TextAttr      topazAttr = {"topaz.font",8,FS_NORMAL,FPF_ROMFONT,FPF_DESIGNED}; */
  struct ColorMap *cmap;
  unsigned char varinfo[50],vartyp[10];
  
  Init_lib_stuff();
     
  for (i=0;i<50;i++)
  {
    a_inuse[i]=FALSE;
    t_inuse[i]=FALSE;
  }
  
  *DIRREG_B_CIAA=0xFF;  
  *DIRREG_A_CIAB&=0xF9;
   
  *PORTREG_B_CIAA=0x03; 
  
  NewList(&a_list);
  NewList(&t_list);
            
  CreateMes(&prog_ende_text,45,25,str_prog_exit);
  CreateMes(&prog_ende_y,3,3,str_yes);
  CreateMes(&prog_ende_n,3,3,str_no);
  CreateMes(&send_byte_timeout_text,45,25,str_send_byte_timeout_text);
  CreateMes(&send_byte_timeout_ok,3,3,str_ok);
  CreateMes(&get_byte_timeout_text,45,25,str_get_byte_timeout_text);
  CreateMes(&get_byte_timeout_ok,3,3,str_ok);
  
  Screenptr=(struct Screen *)LockPubScreen(NULL);
  VisualInfo=(APTR)GetVisualInfoA(Screenptr,NULL);
  
  cmap=Screenptr->ViewPort.ColorMap;
  gcolors[7]=FindColor(cmap,0x00000000,0x00000000,0x00000000,-1);
  gcolors[6]=FindColor(cmap,0x24924924,0x24924924,0x24924924,-1);
  gcolors[5]=FindColor(cmap,0x49249248,0x49249248,0x49249248,-1);
  gcolors[4]=FindColor(cmap,0x6DB6DB6C,0x6DB6DB6C,0x6DB6DB6C,-1);
  gcolors[3]=FindColor(cmap,0x92492490,0x92492490,0x92492490,-1);
  gcolors[2]=FindColor(cmap,0xB6DB6DB4,0xB6DB6DB4,0xB6DB6DB4,-1);
  gcolors[1]=FindColor(cmap,0xDB6DB6D8,0xDB6DB6D8,0xDB6DB6D8,-1);
  gcolors[0]=FindColor(cmap,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,-1);
  
  if (gcolors[2]==gcolors[0]) gcolors[2]=gcolors[3];
  if (gcolors[5]==gcolors[7]) gcolors[5]=gcolors[4];
  
  ToolGadgets[0]=(struct Gadget *)CreateContext(&ToolGadgetList);

  NewGadgetInfo.ng_LeftEdge=14;
  NewGadgetInfo.ng_TopEdge=26;
  NewGadgetInfo.ng_Width=120;
  NewGadgetInfo.ng_Height=20;
  NewGadgetInfo.ng_GadgetText=str_butt_get_scrs;
  NewGadgetInfo.ng_TextAttr=/*&topazAttr*/NULL;
  NewGadgetInfo.ng_GadgetID=GADGET_SCREENSHOT;
  NewGadgetInfo.ng_Flags=0;
  NewGadgetInfo.ng_VisualInfo=VisualInfo;
  ToolGadgets[1]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,ToolGadgets[0],&NewGadgetInfo,NULL);

  NewGadgetInfo.ng_TopEdge=52;
  NewGadgetInfo.ng_GadgetText=str_butt_get_farscrs;
  NewGadgetInfo.ng_GadgetID=GADGET_FARGOSCREENSHOT;
  ToolGadgets[2]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,ToolGadgets[1],&NewGadgetInfo,NULL);  

  NewGadgetInfo.ng_TopEdge=78;
  NewGadgetInfo.ng_GadgetText=str_butt_save_as_iff;
  NewGadgetInfo.ng_GadgetID=GADGET_SAVESCREENSHOT;
  ToolGadgets[3]=(struct Gadget *)CreateGadget(BUTTON_KIND,ToolGadgets[2],&NewGadgetInfo,GA_Disabled,TRUE,TAG_DONE);  

  NewGadgetInfo.ng_TopEdge=104;
  NewGadgetInfo.ng_GadgetText=str_butt_get_romdump;
  NewGadgetInfo.ng_GadgetID=GADGET_GETROMDUMP;
  ToolGadgets[4]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,ToolGadgets[3],&NewGadgetInfo,NULL);  

  NewGadgetInfo.ng_TopEdge=130;
  NewGadgetInfo.ng_GadgetText=str_butt_receive;
  NewGadgetInfo.ng_GadgetID=GADGET_RECEIVE;
  ToolGadgets[5]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,ToolGadgets[4],&NewGadgetInfo,NULL);  

  NewGadgetInfo.ng_TopEdge=180;
  NewGadgetInfo.ng_Width=140;
  NewGadgetInfo.ng_Height=130;
  NewGadgetInfo.ng_GadgetText=str_a_vars;
  NewGadgetInfo.ng_GadgetID=GADGET_A_LIST;
  ToolGadgets[6]=(struct Gadget *)CreateGadget(LISTVIEW_KIND,ToolGadgets[5],&NewGadgetInfo,
                                               GTLV_Labels,       &a_list,
                                               GTLV_ShowSelected, NULL,
                                               TAG_DONE);  

  NewGadgetInfo.ng_LeftEdge=385;
  NewGadgetInfo.ng_GadgetText=str_t_vars;
  NewGadgetInfo.ng_GadgetID=GADGET_T_LIST;
  ToolGadgets[7]=(struct Gadget *)CreateGadget(LISTVIEW_KIND,ToolGadgets[6],&NewGadgetInfo,
                                               GTLV_Labels,       &t_list,
                                               GTLV_ShowSelected, NULL,
                                               TAG_DONE);  

  NewGadgetInfo.ng_LeftEdge=407;
  NewGadgetInfo.ng_TopEdge=26;
  NewGadgetInfo.ng_Width=120;
  NewGadgetInfo.ng_Height=20;
  NewGadgetInfo.ng_GadgetText=str_butt_chk_ready;
  NewGadgetInfo.ng_GadgetID=GADGET_CHK_READY;
  ToolGadgets[8]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,ToolGadgets[7],&NewGadgetInfo,NULL);

  NewGadgetInfo.ng_TopEdge=130;
  NewGadgetInfo.ng_GadgetText=str_butt_sound;
  NewGadgetInfo.ng_GadgetID=GADGET_SOUND;
  ToolGadgets[9]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,ToolGadgets[8],&NewGadgetInfo,NULL);

  NewGadgetInfo.ng_TopEdge=52;
  NewGadgetInfo.ng_Height=20;
  NewGadgetInfo.ng_GadgetText=str_butt_req_backup;
  NewGadgetInfo.ng_GadgetID=GADGET_REQ_BACKUP;
  ToolGadgets[10]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,ToolGadgets[9],&NewGadgetInfo,NULL);

  NewGadgetInfo.ng_TopEdge=78;
  NewGadgetInfo.ng_GadgetText=str_butt_send_backup;
  NewGadgetInfo.ng_GadgetID=GADGET_SEND_BACKUP;
  ToolGadgets[11]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,ToolGadgets[10],&NewGadgetInfo,NULL);

  NewGadgetInfo.ng_TopEdge=104;
  NewGadgetInfo.ng_GadgetText=str_butt_remote;
  NewGadgetInfo.ng_GadgetID=GADGET_REMOTE;
  ToolGadgets[12]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,ToolGadgets[11],&NewGadgetInfo,NULL);

  NewGadgetInfo.ng_LeftEdge=405;
  NewGadgetInfo.ng_TopEdge=321;
  NewGadgetInfo.ng_Height=19;
  NewGadgetInfo.ng_GadgetText=str_butt_prefs;
  NewGadgetInfo.ng_GadgetID=GADGET_PREFS;
  ToolGadgets[13]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,ToolGadgets[12],&NewGadgetInfo,NULL);

  NewGadgetInfo.ng_Height=20;
  NewGadgetInfo.ng_LeftEdge=272;
  NewGadgetInfo.ng_TopEdge=180;
  NewGadgetInfo.ng_Width=110;
  NewGadgetInfo.ng_GadgetText=str_butt_upd_list;
  NewGadgetInfo.ng_GadgetID=GADGET_UPD_LIST;
  ToolGadgets[14]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,ToolGadgets[13],&NewGadgetInfo,NULL);

  NewGadgetInfo.ng_LeftEdge=157;
  NewGadgetInfo.ng_GadgetText=str_butt_load_file;
  NewGadgetInfo.ng_GadgetID=GADGET_LOAD_FILE;
  ToolGadgets[15]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,ToolGadgets[14],&NewGadgetInfo,NULL);

  NewGadgetInfo.ng_TopEdge=205;
  NewGadgetInfo.ng_GadgetText="<--";
  NewGadgetInfo.ng_GadgetID=GADGET_SEND_ONE_TO_AM;
  ToolGadgets[16]=(struct Gadget *)CreateGadget(BUTTON_KIND,ToolGadgets[15],&NewGadgetInfo,GA_Disabled,TRUE,TAG_DONE);

  NewGadgetInfo.ng_LeftEdge=272;
  NewGadgetInfo.ng_GadgetText="-->";
  NewGadgetInfo.ng_GadgetID=GADGET_SEND_ONE_TO_TI;
  ToolGadgets[17]=(struct Gadget *)CreateGadget(BUTTON_KIND,ToolGadgets[16],&NewGadgetInfo,GA_Disabled,TRUE,TAG_DONE);

  NewGadgetInfo.ng_TopEdge=230;
  NewGadgetInfo.ng_GadgetText="==>";
  NewGadgetInfo.ng_GadgetID=GADGET_SEND_ALL_TO_TI;
  ToolGadgets[18]=(struct Gadget *)CreateGadget(BUTTON_KIND,ToolGadgets[17],&NewGadgetInfo,GA_Disabled,TRUE,TAG_DONE);

  NewGadgetInfo.ng_LeftEdge=157;
  NewGadgetInfo.ng_GadgetText="<==";
  NewGadgetInfo.ng_GadgetID=GADGET_SEND_ALL_TO_AM;
  ToolGadgets[19]=(struct Gadget *)CreateGadget(BUTTON_KIND,ToolGadgets[18],&NewGadgetInfo,GA_Disabled,TRUE,TAG_DONE);

  NewGadgetInfo.ng_TopEdge=255;
  NewGadgetInfo.ng_GadgetText=str_butt_save_file;
  NewGadgetInfo.ng_GadgetID=GADGET_SAVE_FILE;
  ToolGadgets[20]=(struct Gadget *)CreateGadget(BUTTON_KIND,ToolGadgets[19],&NewGadgetInfo,GA_Disabled,TRUE,TAG_DONE);

  NewGadgetInfo.ng_TopEdge=280;
  NewGadgetInfo.ng_GadgetText=str_butt_view;
  NewGadgetInfo.ng_GadgetID=GADGET_VIEW;
  ToolGadgets[21]=(struct Gadget *)CreateGadget(BUTTON_KIND,ToolGadgets[20],&NewGadgetInfo,GA_Disabled,TRUE,TAG_DONE);

  if (!create_window(&Tool_Window,20,20,540,350,"Ti92-Link",SMART_REFRESH|ACTIVATE|WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH,WBENCHSCREEN,IDCMP_CLOSEWINDOW|IDCMP_GADGETUP|IDCMP_GADGETDOWN|IDCMP_MOUSEMOVE,ToolGadgetList))
  {
    erequest(str_err_opening_mainwin);
    FreeVisualInfo(VisualInfo);
    FreeGadgets(ToolGadgetList);
    UnlockPubScreen(NULL,Screenptr);
    CloseLibrary(GfxBase);
    CloseLibrary(DosBase);
    CloseLibrary(GadToolsBase);
    CloseLibrary(IntuitionBase);
    CloseCatalog(LocaleInf);
    CloseLibrary(LocaleBase);
    CloseDevice((struct IORequest *)ParallelIO);
    DeleteExtIO(ParallelIO);
    DeletePort(ParallelMP);
    exit(0);
  }

  load_prefs();

  SetAPen(Tool_Window->RPort,1);
  Move(Tool_Window->RPort,147,155);
  Draw(Tool_Window->RPort,147,22);
  Draw(Tool_Window->RPort,392,22);
  SetAPen(Tool_Window->RPort,2);
  Draw(Tool_Window->RPort,392,155);
  Draw(Tool_Window->RPort,147,155);

  SetAPen(Tool_Window->RPort,1);
  Move(Tool_Window->RPort,10,340);
  Draw(Tool_Window->RPort,10,320);
  Draw(Tool_Window->RPort,395,320);
  SetAPen(Tool_Window->RPort,2);
  Draw(Tool_Window->RPort,395,340);
  Draw(Tool_Window->RPort,10,340);

  send_chk_ready();
  send_get_dirlist();

  *PORTREG_B_CIAA=0x03; 
      
  SetDrMd(Tool_Window->RPort,JAM1);
  if (calc_ready)
  {
    if (at_homescreen) StatusString(str_ready);
    else StatusString(str_not_at_homescr);
  }
  else StatusString(str_not_resp);
  timeout_error=FALSE;
 
  for(;;)
  {
    WaitPort(Tool_Window->UserPort);
    while((mesg=(struct IntuiMessage*)GT_GetIMsg(Tool_Window->UserPort))!=NULL)
    {
      mclass=mesg->Class;
      maddress=mesg->IAddress;
      mcode=mesg->Code;
      mqualifier=mesg->Qualifier;
      GT_ReplyIMsg(mesg);
      timeout_error=0;
      switch(mclass)
      {
        case IDCMP_CLOSEWINDOW: if (AutoRequest(Tool_Window,&prog_ende_text,&prog_ende_y,&prog_ende_n,NULL,NULL,250,100))
                                {
                                  for (i=0;i<50;i++) if (a_inuse[i]) free(a_data[i]);
                                  CloseWindow(Tool_Window);
                                  FreeVisualInfo(VisualInfo);
                                  FreeGadgets(ToolGadgetList);
                                  UnlockPubScreen(NULL,Screenptr);
                                  CloseLibrary(GfxBase);
                                  CloseLibrary(DosBase);
                                  CloseLibrary(GadToolsBase);
                                  CloseLibrary(IntuitionBase);
                                  CloseCatalog(LocaleInf);
                                  CloseLibrary(LocaleBase);
                                  CloseDevice((struct IORequest *)ParallelIO);
                                  DeleteExtIO(ParallelIO);
                                  DeletePort(ParallelMP);
                                  exit(0);
                                }
                                break;
        case BUTTONIDCMP:       switch(((struct Gadget *)maddress)->GadgetID)
                                {
                                  case GADGET_SCREENSHOT:        SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 StatusString(str_req_scrshot);
                                                                 send_chk_ready();
                                                                 send_reqscrdump();
                                                                 break;
                                  case GADGET_FARGOSCREENSHOT:   SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 get_fcam();
                                                                 break;
                                  case GADGET_SAVESCREENSHOT:    SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 save_as_iff();
                                                                 break;
                                  case GADGET_GETROMDUMP:        SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 get_romdump();
                                                                 break;
                                  case GADGET_RECEIVE:           SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 StatusString(str_wait_for_data);
                                                                 get_vars();
                                                                 send_chk_ready();
                                                                 break;
                                  case GADGET_CHK_READY:         SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 send_chk_ready();
                                                                 break;
                                  case GADGET_UPD_LIST:          SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 send_chk_ready();
                                                                 send_get_dirlist();
                                                                 break;
                                  case GADGET_REQ_BACKUP:        SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 send_chk_ready();
                                                                 if (timeout_error) break;
                                                                 send_req_backup();
                                                                 break;
                                  case GADGET_SEND_BACKUP:       SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 send_chk_ready();
                                                                 if (timeout_error) break;
                                                                 send_backup();
                                                                 SetBarPos(0);
                                                                 Delay(100);
                                                                 send_chk_ready();
                                                                 send_get_dirlist();
                                                                 break;
                                  case GADGET_REMOTE:            SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 StatusString(str_remotecontrolling);
                                                                 create_window(&Remote_Window,190,200,200,100,str_ti_remotecont,SMART_REFRESH|ACTIVATE|WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH,WBENCHSCREEN,IDCMP_CLOSEWINDOW|IDCMP_VANILLAKEY|IDCMP_RAWKEY,NULL);
                                                                 do_remote();
                                                                 send_chk_ready();
                                                                 CloseWindow(Remote_Window);
                                                                 break;
                                  case GADGET_PREFS:             SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 do_prefs();
                                                                 break;
                                  case GADGET_SOUND:             SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 do_sound();
                                                                 break;
                                  case GADGET_LOAD_FILE:         SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 load_ti92_file();
                                                                 break;
                                  case GADGET_A_LIST:            GT_SetGadgetAttrs(ToolGadgets[17],Tool_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
                                                                 a_listsel=mcode;
                                                                 if (a_typ[a_listsel]==0x0B||a_typ[a_listsel]==0x10) GT_SetGadgetAttrs(ToolGadgets[21],Tool_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
                                                                 else GT_SetGadgetAttrs(ToolGadgets[21],Tool_Window,NULL,GA_Disabled,TRUE,TAG_DONE);
                                                                 type_string(vartyp,a_typ[a_listsel]);
                                                                 sprintf(varinfo,"\"%s\" - %s - %i bytes",a_names[a_listsel],vartyp,a_lang[a_listsel]+1);
                                                                 printvarinfo(varinfo,FALSE);
                                                                 break;
                                  case GADGET_T_LIST:            GT_SetGadgetAttrs(ToolGadgets[16],Tool_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
                                                                 t_listsel=mcode;
                                                                 type_string(vartyp,t_typ[t_listsel]);
                                                                 sprintf(varinfo,"\"%s\" - %s - %i bytes",t_names[t_listsel],vartyp,t_lang[t_listsel]+1);
                                                                 printvarinfo(varinfo,TRUE);
                                                                 break;
                                  case GADGET_SEND_ONE_TO_AM:    SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 req_var(t_names[t_listsel],t_typ[t_listsel],t_lang[t_listsel]);
                                                                 send_chk_ready();
                                                                 break;
                                  case GADGET_SEND_ALL_TO_AM:    free_a_list();
                                                                 SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 for(i=0;i<50;i++)
                                                                 {
                                                                   if (t_inuse[i]) req_var(t_names[i],t_typ[i],t_lang[i]);
                                                                   if (timeout_error) break;
                                                                 }
                                                                 send_chk_ready();
                                                                 break;
                                  case GADGET_SEND_ONE_TO_TI:    SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 send_var(a_lang[a_listsel],a_typ[a_listsel],a_names[a_listsel],a_data[a_listsel]);
                                                                 send_byte(0x09);
                                                                 send_byte(0x92);
                                                                 send_byte(0x00);
                                                                 send_byte(0x00);
                                                                 get_ack();
                                                                 send_chk_ready();
                                                                 send_get_dirlist();
                                                                 break;
                                  case GADGET_SEND_ALL_TO_TI:    SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 for(i=0;i<50;i++)
                                                                 { 
                                                                   if (a_inuse[i])
                                                                   {
                                                                     send_var(a_lang[i],a_typ[i],a_names[i],a_data[i]);
                                                                     send_byte(0x09);
                                                                     send_byte(0x92);
                                                                     send_byte(0x00);
                                                                     send_byte(0x00);
                                                                     get_ack();
                                                                   }
                                                                 }
                                                                 send_chk_ready();
                                                                 send_get_dirlist();
                                                                 break;
                                  case GADGET_SAVE_FILE:         SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 save_92g_file();
                                                                 break;
                                  case GADGET_VIEW:              SetWindowPointer(Tool_Window,WA_BusyPointer,TRUE,TAG_DONE);
                                                                 view_var();
                                                                 break;
                                  default:                       printf("IDCMP:??? code=%i qualifier=%i\n",mcode,mqualifier);


                                }
      }
      if (calc_ready)
      {
        if (at_homescreen) StatusString(str_ready);
        else StatusString(str_not_at_homescr);
      }
      else StatusString(str_not_resp);
      SetBarPos(0);
      SetWindowPointer(Tool_Window,WA_BusyPointer,FALSE,TAG_DONE);
      *PORTREG_B_CIAA=0x03; 
    }
  }
}

BOOL create_window(struct Window **Window1,int left,int top,int width,int height,char *title,int flags,int type,int IDCMPFlags,struct Gadget *FirstGad)
{
  struct NewWindow NewWindow1;
  
  NewWindow1.LeftEdge=left;
  NewWindow1.TopEdge=top;
  NewWindow1.Width=width;
  NewWindow1.Height=height;
  NewWindow1.Title=title;
  NewWindow1.DetailPen=0;
  NewWindow1.BlockPen=1;
  NewWindow1.Flags=flags;
  NewWindow1.IDCMPFlags=IDCMPFlags;
  NewWindow1.Type=type;
  NewWindow1.FirstGadget=FirstGad;
  NewWindow1.CheckMark=NULL;
  NewWindow1.Screen=NULL;
  NewWindow1.BitMap=NULL;
  NewWindow1.MinWidth=30;
  NewWindow1.MinHeight=30;
  NewWindow1.MaxWidth=1024;
  NewWindow1.MaxHeight=1024;
  
  Window1[0]=(struct Window *) OpenWindow(&NewWindow1);
  if (Window1[0]==NULL) return FALSE;
  return TRUE;
}

void Init_lib_stuff(void)
{
  struct EasyStruct par_req;
  unsigned char req_title[]="Ti92-Link";
  
  IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",39);
  if (IntuitionBase==NULL)
  {
    printf("Error opening \"intuition.library\"\nHave you got AmigaOS 3.x? (needed)\n");
    exit(FALSE);
  }
  LocaleBase=(struct Library *) OpenLibrary("locale.library",38);
  LocaleInf.li_Catalog=NULL;
  if (LocaleBase)
  {
    LocaleInf.li_LocaleBase=LocaleBase;
    LocaleInf.li_Catalog=(APTR)OpenCatalogA(NULL,"Ti92-Link.catalog",NULL);
  } 
  do_locale(); 
  GfxBase=(struct Library *) OpenLibrary("graphics.library",0);
  if (GfxBase==NULL)
  {
    erequest(str_err_opening_gfx);
    exit(FALSE);
  }  
  DosBase=(struct Library *) OpenLibrary("dos.library",0);
  if (DosBase==NULL)
  {
    erequest(str_err_opening_dos);
    exit(FALSE);
  }  
  GadToolsBase=(struct Library *) OpenLibrary("gadtools.library",0);
  if (GadToolsBase==NULL)
  {
    erequest(str_err_opening_gadtools);
    exit(FALSE);
  }

  par_req.es_StructSize=sizeof(struct EasyStruct);
  par_req.es_Flags=0;
  par_req.es_Title=req_title;
  par_req.es_TextFormat=str_par_err_text;
  par_req.es_GadgetFormat=str_ok;

  if (ParallelMP=(struct MsgPort *)CreatePort(0,0) ) 
  {
   if (ParallelIO=(struct IOExtPar *)CreateExtIO(ParallelMP,sizeof(struct IOExtPar)) )
   {
    if (OpenDevice(PARALLELNAME,0L,(struct IORequest *)ParallelIO,0) )
    {
      EasyRequestArgs(NULL,&par_req,NULL,NULL);
      exit(FALSE);
    }
   }
   else
   {
    EasyRequestArgs(NULL,&par_req,NULL,NULL);
    exit(FALSE);
   }
  }
  else
  {
    EasyRequestArgs(NULL,&par_req,NULL,NULL);
    exit(FALSE);
  }
}

void CreateMes(struct IntuiText *x,SHORT left,SHORT top,UBYTE *mesg)
{
  x->FrontPen=0;
  x->BackPen=1;
  x->DrawMode=JAM1;
  x->LeftEdge=top;
  x->ITextFont=NULL;
  x->IText=mesg;
  x->NextText=NULL;
}

void send_byte(unsigned char data)
{
  unsigned char bit;
  time_t zeitb;
  int tdiff=timeout;
  unsigned int cnt=0;

  if (timeout_error) return;

  if (recmode_stat) fputc(data,recmode_fileh);

  
  for(bit=0;bit<8;bit++)
  {
    if(data&1)
    {
      *PORTREG_B_CIAA=2;
      while(*PORTREG_A_CIAB&0x04)
      {
        cnt++;
        if (!(cnt%1000)) 
        {
         zeitb=time(NULL);
         if (difftime(zeitb,zeit))
         {
          zeit=time(NULL);
          tdiff--;
          if (!tdiff)
          {
            AutoRequest(Tool_Window,&send_byte_timeout_text,NULL,&send_byte_timeout_ok,NULL,NULL,250,100);
            timeout_error=1;
            return;
          }
         }
        }
      }
      *PORTREG_B_CIAA=3;
      while(!(*PORTREG_A_CIAB&0x04))
      {
        cnt++;
        if (!(cnt%1000)) 
        {
         zeitb=time(NULL);
         if (difftime(zeitb,zeit))
         {
          zeit=time(NULL);
          tdiff--;
          if (!tdiff)
          {
            AutoRequest(Tool_Window,&send_byte_timeout_text,NULL,&send_byte_timeout_ok,NULL,NULL,250,100);
            timeout_error=1;
            return;
          }
         }
        }
      }
    }
    else
    { 
      *PORTREG_B_CIAA=1;
      while(*PORTREG_A_CIAB&0x02)
      {
        cnt++;
        if (!(cnt%1000)) 
        {
         zeitb=time(NULL);
         if (difftime(zeitb,zeit))
         {
          zeit=time(NULL);
          tdiff--;
          if (!tdiff)
          {
            AutoRequest(Tool_Window,&send_byte_timeout_text,NULL,&send_byte_timeout_ok,NULL,NULL,250,100);
            timeout_error=1;
            return;
          }
         }
        }
      }      
      *PORTREG_B_CIAA=3;
      while(!(*PORTREG_A_CIAB&0x02))
      {
        cnt++;
        if (!(cnt%1000)) 
        {
         zeitb=time(NULL);
         if (difftime(zeitb,zeit))
         {
          zeit=time(NULL);
          tdiff--;
          if (!tdiff)
          {
            AutoRequest(Tool_Window,&send_byte_timeout_text,NULL,&send_byte_timeout_ok,NULL,NULL,250,100);
            timeout_error=1;
            return;
          }
         }
        }
      }
    }
    data>>=1;
  }
}

unsigned char get_byte(void)
{
  unsigned char bit;
  unsigned char data=0,v;
  time_t zeitb;
  int tdiff=timeout;
  unsigned int cnt=1;
  
  if (timeout_error) return;
  
  for(bit=0;bit<8;bit++)
  {
    while((v=*PORTREG_A_CIAB&0x06)==6)
    {
      cnt++;
      if (!(cnt%1000)) 
      {
       zeitb=time(NULL);
       if (difftime(zeitb,zeit))
       {
        zeit=time(NULL);
        tdiff--;
        if (!tdiff)
        {
          AutoRequest(Tool_Window,&get_byte_timeout_text,NULL,&get_byte_timeout_ok,NULL,NULL,250,100);
          timeout_error=1;
          return;
        }
       }
      }
    }
    if(v==4)
    {
      data>>=1;
      data|=128;
      *PORTREG_B_CIAA=1;
      while(!(*PORTREG_A_CIAB&0x02))
      { 
        cnt++;
        if (!(cnt%1000)) 
        {
         zeitb=time(NULL);
         if (difftime(zeitb,zeit))
         {
          tdiff--;
          zeit=time(NULL);
          if (!tdiff)
          {
            AutoRequest(Tool_Window,&get_byte_timeout_text,NULL,&get_byte_timeout_ok,NULL,NULL,250,100);
            timeout_error=1;
            return;
          }
         }
        }
      }
      *PORTREG_B_CIAA=3;
    }
    else
    {
      data>>=1;
      *PORTREG_B_CIAA=2;
      while(!(*PORTREG_A_CIAB&0x04))
      { 
        cnt++;
        if (!(cnt%1000)) 
        {
         zeitb=time(NULL);
         if (difftime(zeitb,zeit))
         {
          tdiff--;
          zeit=time(NULL);
          if (!tdiff)
          {
            AutoRequest(Tool_Window,&get_byte_timeout_text,NULL,&get_byte_timeout_ok,NULL,NULL,250,100);
            timeout_error=1;
            return;
          }
         }
        }
      }  
      *PORTREG_B_CIAA=3;      
    }
  }
  
  if (recmode_stat) fputc(data,recmode_fileh);

/*  printf("%i\n",(int)data); */
  return data;
}

void get_var(void)
{
  unsigned long cnt,lang,n;
  unsigned char typ;
  unsigned char *vardata;
  unsigned char namelen;
  unsigned char name[20];
  unsigned char infotext[50];
  unsigned char typtext[10];
    
  vardata=(unsigned char *)malloc(65535);
  name[0]=0;
  get_byte();
  get_byte();
  lang=get_byte();
  lang+=get_byte()<<8;
  get_byte();
  get_byte();
  typ=get_byte();
  type_string(typtext,typ);
  namelen=get_byte();
  for(n=0;n<namelen;n++)
  {
    name[n]=get_byte();
    name[n+1]=0;
  }
  sprintf(infotext,str_getting_var,name,typtext,lang);
  StatusString(infotext);
  get_byte();
  get_byte();
  send_ack();
  send_datareq();
  get_ack();
  get_data(vardata);  
  if (!check_ok) 
  {
    erequest(str_err_wrong_chksum);
  } 
  else
  {
    GT_SetGadgetAttrs(ToolGadgets[6],Tool_Window,NULL,GTLV_Labels,NULL,TAG_DONE);
    lang--;
    for(n=0;n<50;n++)
    {
      if (!a_inuse[n])
      {
        a_inuse[n]=TRUE;
        a_data[n]=(unsigned char *)malloc(lang);
        for(cnt=5;cnt<(lang+5);cnt++) a_data[n][cnt-5]=vardata[cnt];
        a_typ[n]=typ;
        a_lang[n]=lang;
        strcpy(a_names[n],name);
        a_nodes[n].ln_Name=a_names[n];
        AddTail(&a_list,&a_nodes[n]);
        break;
      }
    }
    GT_SetGadgetAttrs(ToolGadgets[6],Tool_Window,NULL,GTLV_Labels,&a_list,TAG_DONE);
    GT_SetGadgetAttrs(ToolGadgets[20],Tool_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
    GT_SetGadgetAttrs(ToolGadgets[18],Tool_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
  }
  free(vardata);
}           

void get_vars(void)
{
  unsigned char cont;

  free_a_list();
  
  for(;;)
  {
   if(get_byte()!=0x89)
   {
    if (timeout_error) return;
    printf("packet not from Ti92\n");
    return;
   }
   cont=get_byte();
   if (timeout_error) return;
   switch(cont)
   {
    case 0x92: get_byte();
               get_byte();
               send_ack();
               return;
    case 0x06: get_var();
               break; 
    default:   printf("no varheader or eot\n");
               return;
   }
  }
}

void send_ack(void)
{
  send_byte(9);
  send_byte(0x56);
  send_byte(0);
  send_byte(0);
}

void send_datareq(void)
{
  send_byte(9);
  send_byte(9);
  send_byte(0);
  send_byte(0);
}

void get_data(unsigned char *data)
{
  unsigned char databyte,datatype;
  unsigned int  lang,n;
  unsigned long chk=0;
  unsigned int  pckchk; 
  
  SetBarPos(0);
  datatype=get_byte();
  if (datatype!=0x89) 
  {
    if (timeout_error) return;

/*    printf("packet nicht von Ti92?\nexiting...\n");
    exit(0);*/
  }
  databyte=get_byte();
  if (databyte!=0x15)
  {
    if (timeout_error) return;
/*    printf("kein Datenpacket...\nexiting...\n");
    exit(0);  */
  }
  lang=get_byte();
  lang+=get_byte()<<8;
/*  printf("Länge: %i bytes\n",lang); */
  for(n=0;n<lang;n++)
  {
    data[n]=get_byte();
    chk+=data[n]; 
    if (!(n%100)) SetBarPos((100*n)/lang);
  }

  chk&=0xFFFF;
  pckchk=get_byte();
  pckchk+=get_byte()<<8;
  if (pckchk==chk) check_ok=TRUE;
  else check_ok=FALSE;
  old_chk=chk;
/*  if (pckchk==chk) printf("Checksum ok!\n");
  else printf("Checksum falsch!(errechnet:%i, von TI: %i)\n",(int)chk,(int)pckchk); */

  send_ack();
}

void get_ack(void)
{
  unsigned char databyte,datatype;
  
  datatype=get_byte();
  if (datatype!=0x89) 
  {
    if (timeout_error) return;
/*    printf("packet nicht von Ti92?\nexiting...\n");
    exit(0);*/
  }
  databyte=get_byte();
  if (databyte!=0x56)
  {
    if (timeout_error) return;
 /*   printf("kein ACK...\nexiting...\n");
    exit(0); */
  }
  get_byte();
  get_byte();
}

void send_reqscrdump(void)
{
  int x,y;
  
  send_byte(9);
  send_byte(0x6D);
  send_byte(0);
  send_byte(0);
  get_ack();
  if (timeout_error) return;
  StatusString(str_getting_scrshot);
  get_data(pic[0]);
  SetBarPos(0);
  StatusString(str_drawing_scrshot);  
  for(y=0;y<128;y++)
  {
    for(x=0;x<240;x++)
    {
      if (pic[0][y*30+x/8]&(0x80>>(x%8))) SetAPen(Tool_Window->RPort,gcolors[7]);
      else SetAPen(Tool_Window->RPort,gcolors[0]);
      WritePixel(Tool_Window->RPort,150+x,25+y);
    }
  }
  picd=1;
  GT_SetGadgetAttrs(ToolGadgets[3],Tool_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
}

void StatusString(char *text)
{
  strcpy(bartext,text);
  drawprogbar();
}

void SetBarPos(char wert)
{
  barpos=wert;
  drawprogbar();
}

void drawprogbar(void)
{
  float pos=3.83*barpos+11;
  SetAPen(Tool_Window->RPort,3);
  RectFill(Tool_Window->RPort,11,321,(SHORT)pos,339);
  SetAPen(Tool_Window->RPort,0);
  RectFill(Tool_Window->RPort,(SHORT)pos,321,394,339);
  SetAPen(Tool_Window->RPort,1);
  Move(Tool_Window->RPort,15,334);
  Text(Tool_Window->RPort,bartext,strlen(bartext));
}

void get_romdump(void)
{
  APTR aslreq;
  BOOL aslres;
  char filename[200];
  struct FileRequester *filereq;
  FILE *fileh;
  long cnt,pos;
  unsigned char data[1024];
  unsigned char stat[30];
  unsigned char info[60];
  unsigned int x;

  StatusString(str_select_file_romdump);  
  aslreq=(APTR)AllocAslRequestTags(ASL_FileRequest,ASLFR_DoSaveMode,TRUE,ASLFR_TitleText,str_select_file_romdump,ASLFR_Window,Tool_Window,TAG_DONE);
  aslres=AslRequest(aslreq,NULL);
  filereq=(struct FileRequester *)aslreq;
  if (aslres) 
  {
    if (!filereq->fr_Drawer[0]) strcpy(filename,filereq->fr_File);
    else
    {
      if (filereq->fr_Drawer[strlen(filereq->fr_Drawer)-1]==':') sprintf(filename,"%s%s",filereq->fr_Drawer,filereq->fr_File);
      else sprintf(filename,"%s/%s",filereq->fr_Drawer,filereq->fr_File);
    }
  }
  FreeAslRequest(aslreq);
  if (!aslres) return;
  
  fileh=fopen(filename,"wb");
  if (!fileh)
  {
    sprintf(info,str_err_opening_file,filename);
    erequest(info);
    return;
  }
  StatusString(str_waiting_for_romdump);  
  
  for(cnt=0;cnt<romsize*1024;cnt++)
  {
/*fputc(get_byte(),fileh);*/
    data[cnt%1024]=get_byte();    
    if (cnt%1024==1023) fwrite(data,1,1024,fileh);
    if (!(cnt%1024))
    {
      sprintf(stat,str_getting_romdump,cnt/1024,romsize);
      StatusString(stat);   
      if (!(cnt%11264))
      {
        pos=(100*cnt)/(romsize*1024);
        SetBarPos(pos);
      } 
    }  
    if (timeout_error) 
    {
      fclose(fileh);
      return;
    }
  }
  fclose(fileh);
}

void get_fcam(void)
{
  int err=0;
  int layers,lnum,cnt;
  int p1,p2,p3,x,y;
    
  for(lnum=0;lnum<3;lnum++)
  {
    for(cnt=0;cnt<3840;cnt++) pic[lnum][cnt]=0;
  }
  
  StatusString(str_wait_for_fcam);
  
  if (get_byte()!='F') err=1;
  if (get_byte()!='C') err=1;
  if (get_byte()!='a') err=1;
  if (get_byte()!='m') err=1;

  StatusString(str_getting_fcam);
  
  if (timeout_error) return;
  if (err)
  {
    erequest(str_err_no_fcam);
    return;
  }
  
  layers=get_byte();
  
  for (lnum=0;lnum<layers;lnum++)
  { 
    for (cnt=0;cnt<3840;cnt++)
    {    
      pic[lnum][cnt]=get_byte();
      if (timeout_error) return;
      if (!(cnt%200)) SetBarPos((100*lnum)/layers+((100*cnt/3840))/layers);
    }
  }
  
  SetBarPos(0);
  StatusString(str_drawing_scrshot);
  
  for(y=0;y<128;y++)
  {
    for(x=0;x<240;x++)
    {
      if (layers==1)
      {
        p1=pic[0][y*30+x/8]&(0x80>>(x%8));
        if (p1) SetAPen(Tool_Window->RPort,gcolors[7]);
        else SetAPen(Tool_Window->RPort,gcolors[0]);
      }
      if (layers==2) 
      {
        p1=pic[0][y*30+x/8]&(0x80>>(x%8));
        p2=pic[1][y*30+x/8]&(0x80>>(x%8));
        if (!p1&&!p2) SetAPen(Tool_Window->RPort,gcolors[0]);
        if (!p1&&p2) SetAPen(Tool_Window->RPort,gcolors[2]);
        if (p1&&!p2) SetAPen(Tool_Window->RPort,gcolors[5]);
        if (p1&&p2) SetAPen(Tool_Window->RPort,gcolors[7]);
      }
      WritePixel(Tool_Window->RPort,150+x,25+y);
    }
  } 
  picd=layers;
  GT_SetGadgetAttrs(ToolGadgets[3],Tool_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
}

void send_chk_ready(void)
{
  int err=0;
   
  calc_ready=FALSE; 
  
  StatusString(str_chk_for_calc);
   
  send_byte(0x09);
  send_byte(0x68);
  send_byte(0x00);
  send_byte(0x00); 
    
  if (get_byte()!=137) err=1;
  if (get_byte()!=86) err=1;
  if (get_byte()!=0) err=1;
  if (get_byte()==0) at_homescreen=TRUE;
  else at_homescreen=FALSE;
  
  if (timeout_error||err) return;

  calc_ready=TRUE;
}

void send_sim_ti(void)
{
  int x;

  get_byte();
  get_byte();
  get_byte();
  get_byte();


  send_byte(137);
  send_byte(86);
  send_byte(0);
  send_byte(0);
}

void send_get_dirlist(void)
{
  unsigned int x;  
  unsigned char name[10];
  unsigned int  data,jmplen;
  unsigned char n,typ;
  unsigned char folder[10],varname[20];

  name[8]=0;
  GT_SetGadgetAttrs(ToolGadgets[7],Tool_Window,NULL,GTLV_Labels,NULL,TAG_DONE);
  NewList(&t_list);
  for(x=0;x<50;x++) t_inuse[x]=FALSE;
  GT_SetGadgetAttrs(ToolGadgets[7],Tool_Window,NULL,GTLV_Labels,&t_list,TAG_DONE);
  GT_SetGadgetAttrs(ToolGadgets[19],Tool_Window,NULL,GA_Disabled,TRUE,TAG_DONE);

  StatusString(str_getting_dirlist);
  printvarinfo("",FALSE);

  send_byte(0x09);
  send_byte(0xA2);
  send_byte(0x06);
  send_byte(0x00);
  send_byte(0x00);
  send_byte(0x00);
  send_byte(0x00);
  send_byte(0x00);
  send_byte(0x19);
  send_byte(0x00);
  send_byte(0x19);
  send_byte(0x00);
  get_ack();

  if (timeout_error) return;

  get_byte();
  get_byte();
  jmplen=get_byte();
  jmplen+=get_byte()<<8;
  for(x=0;x<jmplen+2;x++) get_byte();

  for(;;)
  {
    send_ack();
    send_byte(0x09);
    send_byte(0x09);
    send_byte(0xFF);
    send_byte(0xFF);
    get_ack();

    if (timeout_error)
    {
      GT_SetGadgetAttrs(ToolGadgets[7],Tool_Window,NULL,GTLV_Labels,NULL,TAG_DONE);
      NewList(&t_list);
      for(x=0;x<50;x++) t_inuse[x]=FALSE;
      GT_SetGadgetAttrs(ToolGadgets[7],Tool_Window,NULL,GTLV_Labels,&t_list,TAG_DONE);
      return;
    }
    get_byte();  
    get_byte();  
    get_byte();
    get_byte();
    get_byte();
    get_byte();
    get_byte();
    get_byte();
    for(n=0;n<8;n++) name[n]=get_byte();
    typ=get_byte();
    get_byte();
    data=get_byte();  
    data+=get_byte()<<8;
    get_byte();
    get_byte();
    get_byte();  /* chk */
    get_byte();  /* chk */
    
    if (typ==0x1F) strcpy(folder,name);
    else
    {
      sprintf(varname,"%s\\%s",folder,name);
      GT_SetGadgetAttrs(ToolGadgets[7],Tool_Window,NULL,GTLV_Labels,NULL,TAG_DONE);
      for(x=0;x<50;x++)
      {
        if (!t_inuse[x])
        {
          t_inuse[x]=TRUE;
          t_typ[x]=typ;
          t_lang[x]=data-1;
          strcpy(t_names[x],varname);
          t_nodes[x].ln_Name=t_names[x];
          AddTail(&t_list,&t_nodes[x]);
          break;
        }
      }
      GT_SetGadgetAttrs(ToolGadgets[7],Tool_Window,NULL,GTLV_Labels,&t_list,TAG_DONE);
    } 
    send_ack();

    get_byte();
    if (get_byte()==0x92) break;
    get_byte();
    get_byte();
  }
  get_byte();
  get_byte();
  send_ack();
  if (t_inuse[0]) GT_SetGadgetAttrs(ToolGadgets[19],Tool_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
}

void send_req_backup(void)
{
  unsigned int x,jmpcnt,blkcnt=0,x1;
  unsigned int lang,namelen,n;
  long gchk=0,filepos;
  char verstring[6];
  unsigned char vardata[1200];
  APTR aslreq;
  BOOL aslres;
  char filename[200];
  char comment[40];
  struct FileRequester *filereq;
  FILE *fileh;
  char infostr[60];

  StatusString(str_select_file_save_backup);  
  aslreq=(APTR)AllocAslRequestTags(ASL_FileRequest,ASLFR_DoSaveMode,TRUE,ASLFR_TitleText,str_select_file_save_backup,ASLFR_Window,Tool_Window,TAG_DONE);
  aslres=AslRequest(aslreq,NULL);
  filereq=(struct FileRequester *)aslreq;
  if (aslres) 
  {
    if (!filereq->fr_Drawer[0]) strcpy(filename,filereq->fr_File);
    else
    {
      if (filereq->fr_Drawer[strlen(filereq->fr_Drawer)-1]==':') sprintf(filename,"%s%s",filereq->fr_Drawer,filereq->fr_File);
      else sprintf(filename,"%s/%s",filereq->fr_Drawer,filereq->fr_File);
    }
  }
  FreeAslRequest(aslreq);
  if (!aslres) return;
  
  if (!ask_for_comment(comment)) return;

  fileh=fopen(filename,"wb");
  if (!fileh)
  {
    printf(str_err_opening_file,filename);
    return;
  }
  StatusString(str_req_backup);  

  send_byte(0x09);
  send_byte(0xA2);
  send_byte(0x11);
  send_byte(0x00);
  send_byte(0x00);
  send_byte(0x00);
  send_byte(0x00);
  send_byte(0x00);
  send_byte(0x1D);
  send_byte(0x0B);
  send_byte(0x6D);
  send_byte(0x61);
  send_byte(0x69);
  send_byte(0x6E);
  send_byte(0x5C);
  send_byte(0x62);
  send_byte(0x61);
  send_byte(0x63);
  send_byte(0x6B);
  send_byte(0x75);
  send_byte(0x70);
  send_byte(0x9F);
  send_byte(0x04);

  get_ack();
  
  if(timeout_error)
  {
    fclose(fileh);
    return;
  }
  StatusString(str_getting_backup);  
   
  if (get_byte()!=137)
  {
    printf("packet not from Ti92\n");
    fclose(fileh);
    return;
  }
  if (get_byte()!=6)
  {
    printf("no varheader\n");
    fclose(fileh);
    return;
  }
  
  get_byte();
  get_byte();
  lang=get_byte();
  lang+=get_byte()<<8;
  get_byte();
  get_byte();
  get_byte();
  namelen=get_byte();
  for(x=0;x<namelen;x++)
  {
    verstring[x]=get_byte();
    verstring[x+1]=0;
  }
  get_byte();
  get_byte();
   
  send_ack();

  fputc('*',fileh);
  fputc('*',fileh);
  fputc('T',fileh);
  fputc('I',fileh);
  fputc('9',fileh);
  fputc('2',fileh);
  fputc('*',fileh);
  fputc('*',fileh);
  fputc(1,fileh);
  for (x=0;x<9;x++) fputc(0,fileh);
  for (x1=0;x1<strlen(comment);x1++) fputc(comment[x1],fileh); 
  for (x=x1;x<40;x++) fputc(0,fileh);
  fputc(1,fileh);
  fputc(0,fileh);
  fputc(0x52,fileh);
  fputc(0,fileh);
  fputc(0,fileh);
  fputc(0,fileh);
  for (x1=0;x1<strlen(verstring);x1++) fputc(verstring[x1],fileh); 
  for (x=x1;x<8;x++) fputc(0,fileh);
  fputc(0x1D,fileh);
  fputc(0,fileh);
  fputc(0,fileh);
  fputc(0,fileh);

  fputc(0,fileh);   /* filesize */
  fputc(0,fileh);

  fputc(0,fileh);
  fputc(0,fileh);
  fputc(0xA5,fileh);
  fputc(0x5A,fileh);
 
  for(;;)
  {
    blkcnt++;
    sprintf(infostr,str_getting_backup_info,verstring,blkcnt);
    StatusString(infostr);
    send_datareq();
    get_ack();
    get_data(vardata); 
    for(n=4;n<(lang+4);n++) gchk+=vardata[n];
    if (!check_ok)
    {
      printf("checksum wrong\n");
      fclose(fileh);
      return;
    } 
    if (timeout_error)
    {
      fclose(fileh);
      return;
    }
    fwrite(vardata+4,1,lang,fileh);
    if (get_byte()!=0x89)
    {
      printf("packet not from Ti92\n");
      fclose(fileh);
      return;
    } 
    if (get_byte()!=6)
    {
      get_byte();
      get_byte();
      send_ack();
      gchk&=0xFFFF;
      fputc(gchk%256,fileh);
      fputc(gchk/256,fileh);
      filepos=ftell(fileh);
      fseek(fileh,76,SEEK_SET);
      fputc(filepos%256,fileh);
      fputc(filepos/256,fileh);
      fclose(fileh);
      return;
    }
    get_byte();
    get_byte();
    lang=get_byte();
    lang+=get_byte()<<8;
    for(x=0;x<3;x++) get_byte();
    jmpcnt=get_byte();
    for(x=0;x<jmpcnt+2;x++) get_byte();
    send_ack();
  }
}

void send_remote_char(unsigned char zeichen,unsigned char zeichenh)
{
  send_byte(0x09);
  send_byte(0x87);
  send_byte(zeichen);
  send_byte(zeichenh);

  get_ack();
}

void do_remote(void)
{
  ULONG                mclass;
  ULONG                mcode;
  struct IntuiMessage  *mesg;
  APTR                 maddress;
  BOOL                 still_msg=FALSE;
  unsigned char rem_info1[]="F9   =  MODE";
  unsigned char rem_info2[]="F10  =  APPS";

  SetAPen(Remote_Window->RPort,1);
  Move(Remote_Window->RPort,15,35);
  Text(Remote_Window->RPort,str_special_keys,strlen(str_special_keys));
  Move(Remote_Window->RPort,15,55);
  Text(Remote_Window->RPort,rem_info1,strlen(rem_info1));
  Move(Remote_Window->RPort,15,70);
  Text(Remote_Window->RPort,rem_info2,strlen(rem_info2));

  if (upd_scrdump_on_remote) send_reqscrdump();
  for(;;)
  {
    StatusString(str_waiting_for_input);
    if (!still_msg) WaitPort(Remote_Window->UserPort);
    for(;;)
    {
      if (!still_msg)
      {
        mesg=(struct IntuiMessage*)GT_GetIMsg(Remote_Window->UserPort);
        if (!mesg) break;
      }
      still_msg=FALSE;
      mclass=mesg->Class;
      mcode=mesg->Code;
      maddress=mesg->IAddress;
      GT_ReplyIMsg(mesg);
      timeout_error=FALSE;
      switch(mclass)
      {
        case IDCMP_CLOSEWINDOW:     return;
        case IDCMP_VANILLAKEY:    /*  printf("vk:%i\n",mcode); */
                                    switch(mcode)
                                    {
                                      case 27:  send_remote_char(8,1);
                                                break; 
                                      case 8:   send_remote_char(1,1);
                                                break; 
                                      case 127: send_remote_char(1,33);
                                                break; 
                                      default:  send_remote_char(mcode,0);
                                                break;
                                    }
                                    mesg=(struct IntuiMessage*)GT_GetIMsg(Remote_Window->UserPort);
                                    if (mesg) still_msg=TRUE;
                                    else if (upd_scrdump_on_remote) send_reqscrdump();
                                    break;
        case IDCMP_RAWKEY:        /*  printf("rk:%i\n",mcode); */
                                    switch(mcode)
                                    {
                                      case 80:  send_remote_char(12,1);
                                                break; 
                                      case 81:  send_remote_char(13,1);
                                                break; 
                                      case 82:  send_remote_char(14,1);
                                                break; 
                                      case 83:  send_remote_char(15,1);
                                                break; 
                                      case 84:  send_remote_char(16,1);
                                                break; 
                                      case 85:  send_remote_char(17,1);
                                                break; 
                                      case 86:  send_remote_char(18,1);
                                                break; 
                                      case 87:  send_remote_char(19,1);
                                                break; 
                                      case 76:  send_remote_char(82,1);
                                                break; 
                                      case 79:  send_remote_char(81,1);
                                                break; 
                                      case 77:  send_remote_char(88,1);
                                                break; 
                                      case 78:  send_remote_char(84,1);
                                                break; 
                                      case 88:  send_remote_char(10,1);
                                                break; 
                                      case 89:  send_remote_char(9,1);
                                                break; 
                                      default:  break;
                                    }
                                    mesg=(struct IntuiMessage*)GT_GetIMsg(Remote_Window->UserPort);
                                    if (mesg) still_msg=TRUE;
                                    else if (upd_scrdump_on_remote) send_reqscrdump();
                                    break;
      }
    }
  }
}

void send_var(unsigned int varlang,unsigned char vartyp,unsigned char *varname,unsigned char *data)
{
  int n;
  unsigned long chk;
  unsigned char infostr[50],vartypstr[10];
  
  type_string(vartypstr,vartyp);
  sprintf(infostr,str_send_var_info,varname,vartypstr,varlang+1);
  StatusString(infostr);

  send_byte(0x09);
  send_byte(0x06);
  send_byte(6+strlen(varname));
  send_byte(0x00);
  send_byte((varlang+1)%256);         chk=(varlang+1)%256;
  send_byte((varlang+1)/256);         chk+=(varlang+1)/256;
  send_byte(0x00);
  send_byte(0x00);
  send_byte(vartyp);              chk+=vartyp;
  send_byte(strlen(varname));     chk+=strlen(varname);
  for(n=0;n<strlen(varname);n++)
  {
    send_byte(varname[n]);
    chk+=varname[n];
  }
  send_byte(chk%256);
  send_byte(chk/256);

  get_ack();
  
  if(timeout_error) return;
  
  get_byte();
  if (get_byte()!=0x09)
  {
    printf("didn`t get req for data\n");
    return;
  }
  get_byte();
  get_byte();
  
  send_ack();
   
  send_byte(0x09);
  send_byte(0x15);
  send_byte((varlang+5)%256);
  send_byte((varlang+5)/256);
  send_byte(0x00);
  send_byte(0x00);
  send_byte(0x00);
  send_byte(0x00);
  send_byte(varlang/256);    chk=varlang/256; 
  for(n=0;n<varlang;n++) 
  {
    if (!(n%150)) SetBarPos((100*n)/varlang);
    send_byte(data[n]);
    chk+=data[n];
  }
  chk&=0xFFFF;
  send_byte(chk%256);
  send_byte(chk/256);

  get_ack();
}

void type_string(unsigned char *s,unsigned char typ)
{
  switch(typ)
  {
    case 0x1D: sprintf(s,"BACKUP");
               break;
    case 0x0A: sprintf(s,"DATA");
               break;
    case 0x00: sprintf(s,"EXPR");
               break;
    case 0x0E: sprintf(s,"FIG");
               break;
    case 0x13: sprintf(s,"FUNC");
               break;
    case 0x0D: sprintf(s,"GDB");
               break;
    case 0x04: sprintf(s,"LIST");
               break;
    case 0x14: sprintf(s,"MAC");
               break;
    case 0x06: sprintf(s,"MAT");
               break;
    case 0x10: sprintf(s,"PIC");
               break;
    case 0x12: sprintf(s,"PRGM");
               break;
    case 0x0C: sprintf(s,"STR");
               break;
    case 0x0B: sprintf(s,"TEXT");
               break;
    default:   sprintf(s,"???");
  }
}

void recmode(BOOL nstat)
{
  
  if (nstat&&!recmode_stat)
  {
    recmode_fileh=fopen("ram:Ti92-Link_log","wb");
    if (recmode_fileh) recmode_stat=TRUE;
    return;
  }
  if (!nstat&&recmode_stat)
  {
    fclose(recmode_fileh);
    recmode_stat=FALSE;
    return;
  }
}

BOOL ask_for_comment(unsigned char *comment)
{
  ULONG                mclass;
  struct IntuiMessage  *mesg;
  APTR                 maddress;
  struct NewGadget     NewGadgetInfo;
  unsigned char        *tempptr;
  BOOL                 ok_disabled=FALSE;

  StatusString(str_enter_comment);

  CommentGadgets[0]=(struct Gadget *)CreateContext(&CommentGadgetList);

  NewGadgetInfo.ng_LeftEdge=14;
  NewGadgetInfo.ng_TopEdge=26;
  NewGadgetInfo.ng_Width=350;
  NewGadgetInfo.ng_Height=20;
  NewGadgetInfo.ng_GadgetText="";
  NewGadgetInfo.ng_TextAttr=/*&topazAttr*/NULL;
  NewGadgetInfo.ng_GadgetID=1;
  NewGadgetInfo.ng_Flags=0;
  NewGadgetInfo.ng_VisualInfo=VisualInfo;
  CommentGadgets[1]=(struct Gadget *)CreateGadget(STRING_KIND,CommentGadgets[0],&NewGadgetInfo,GTST_String,str_no_comment,GTST_MaxChars,38,TAG_DONE);

  NewGadgetInfo.ng_TopEdge=52;
  NewGadgetInfo.ng_GadgetText=str_ok;
  NewGadgetInfo.ng_GadgetID=2;
  NewGadgetInfo.ng_Width=100;
  CommentGadgets[2]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,CommentGadgets[1],&NewGadgetInfo,NULL);  

  NewGadgetInfo.ng_TopEdge=52;
  NewGadgetInfo.ng_LeftEdge=264;
  NewGadgetInfo.ng_GadgetText=str_cancel;
  NewGadgetInfo.ng_GadgetID=3;
  NewGadgetInfo.ng_Width=100;
  CommentGadgets[3]=(struct Gadget *)CreateGadgetA(BUTTON_KIND,CommentGadgets[2],&NewGadgetInfo,NULL);  

  create_window(&Comment_Window,100,100,378,85,str_enter_comment,SMART_REFRESH|ACTIVATE|WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH,WBENCHSCREEN,IDCMP_CLOSEWINDOW|IDCMP_GADGETUP|IDCMP_INTUITICKS,CommentGadgetList);

  for(;;)
  {
    WaitPort(Comment_Window->UserPort);
    while((mesg=(struct IntuiMessage*)GT_GetIMsg(Comment_Window->UserPort))!=NULL)
    {
      mclass=mesg->Class;
      maddress=mesg->IAddress;
      GT_ReplyIMsg(mesg);
      switch(mclass)
      {
        case IDCMP_CLOSEWINDOW:     CloseWindow(Comment_Window);
                                    FreeGadgets(CommentGadgetList);
                                    return FALSE;
        case BUTTONIDCMP:           switch(((struct Gadget *)maddress)->GadgetID)
                                    {
                                      case 2:  GT_GetGadgetAttrs(CommentGadgets[1],Comment_Window,NULL,GTST_String,&tempptr,TAG_DONE);
                                               strcpy(comment,tempptr);
                                               CloseWindow(Comment_Window);
                                               FreeGadgets(CommentGadgetList);
                                               return TRUE;    
                                      case 3:  CloseWindow(Comment_Window);
                                               FreeGadgets(CommentGadgetList);
                                               return FALSE;
                                    }
                                    break;
        case IDCMP_INTUITICKS:      GT_GetGadgetAttrs(CommentGadgets[1],Comment_Window,NULL,GTST_String,&tempptr,TAG_DONE);
                                    if (tempptr[0]&&ok_disabled)
                                    {
                                      GT_SetGadgetAttrs(CommentGadgets[2],Comment_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
                                      ok_disabled=FALSE;
                                    }
                                    if (!tempptr[0]&&!ok_disabled)
                                    {
                                      GT_SetGadgetAttrs(CommentGadgets[2],Comment_Window,NULL,GA_Disabled,TRUE,TAG_DONE);
                                      ok_disabled=TRUE;
                                    }
                                    break;
      }
    }
  }
}

void send_backup(void)
{
  unsigned int lang,namelen,n,blkcnt=0,fchk,cnt;
  long gchk=0,filepos,backlang,filechk=0,sended=0;
  char verstring[6];
  unsigned char *vardata;
  APTR aslreq;
  BOOL aslres;
  char filename[200];
  char comment[43];
  struct FileRequester *filereq;
  FILE *fileh;
  char infostr[60];
  BOOL err=FALSE;

  StatusString(str_select_file_send_backup);  
  aslreq=(APTR)AllocAslRequestTags(ASL_FileRequest,ASLFR_TitleText,str_select_file_send_backup,ASLFR_Window,Tool_Window,TAG_DONE);
  aslres=AslRequest(aslreq,NULL);
  filereq=(struct FileRequester *)aslreq;
  if (aslres) 
  {
    if (!filereq->fr_Drawer[0]) strcpy(filename,filereq->fr_File);
    else
    {
      if (filereq->fr_Drawer[strlen(filereq->fr_Drawer)-1]==':') sprintf(filename,"%s%s",filereq->fr_Drawer,filereq->fr_File);
      else sprintf(filename,"%s/%s",filereq->fr_Drawer,filereq->fr_File);
    }
  }
  FreeAslRequest(aslreq);
  if (!aslres) return;
  
  fileh=fopen(filename,"rb");
  if (!fileh)
  {
    printf(str_err_opening_file,filename);
    return;
  }
  
  if (fgetc(fileh)!='*') err=TRUE;
  if (fgetc(fileh)!='*') err=TRUE;
  if (fgetc(fileh)!='T') err=TRUE;
  if (fgetc(fileh)!='I') err=TRUE;
  if (fgetc(fileh)!='9') err=TRUE;
  if (fgetc(fileh)!='2') err=TRUE;
  if (fgetc(fileh)!='*') err=TRUE;
  if (fgetc(fileh)!='*') err=TRUE;
  
  for(n=0;n<10;n++) fgetc(fileh);
  
  comment[40]=0;
  for(n=0;n<40;n++) comment[n]=fgetc(fileh);
  
  showcomment(comment);
  
  for(n=0;n<6;n++) fgetc(fileh);
  verstring[8]=0;
  for(n=0;n<8;n++) verstring[n]=fgetc(fileh);
  
  if (fgetc(fileh)!=0x1D)
  {
    erequest(str_err_no_backupfile);
    fclose(fileh);
    return;
  }
  
  for(n=0;n<3;n++) fgetc(fileh);
  
  backlang=fgetc(fileh);
  backlang+=fgetc(fileh)<<8;
  backlang-=84;

  for(n=0;n<4;n++) fgetc(fileh);

  vardata=(unsigned char*)malloc(65536);
  StatusString(str_loading_backupfile);  
  for(n=0;n<backlang;n++)
  { 
    vardata[n]=fgetc(fileh);
    filechk+=vardata[n];
  }
  filechk&=0xFFFF;
  
  fchk=fgetc(fileh);
  fchk+=fgetc(fileh)<<8;
 
  if (filechk!=fchk)
  {
    printf("chksum in file wrong! filechk=%i fchk=%i\n",filechk,fchk);
    free(vardata);
    fclose(fileh);
    return;
  }
  fclose(fileh);
  
  StatusString(str_sending_backup);  
  
  send_byte(0x09);
  send_byte(0x68);
  send_byte(0x00);
  send_byte(0x00);
  
  get_ack();
   
  send_byte(9);
  send_byte(6);
  send_byte(5);
  send_byte(0);
  send_byte(242);
  send_byte(233);
  send_byte(0);
  send_byte(0);
  send_byte(29);
  send_byte(248);
  send_byte(1);
 
  for(;;)
  {
   get_ack();

   send_byte(9);
   send_byte(6);
   send_byte(5);
   send_byte(0);
   send_byte(0);
   send_byte(0);
   send_byte(0);
   send_byte(0);
   send_byte(29);
   send_byte(29);
   send_byte(0);

   get_ack();

   if (get_byte()!=137)
   {
    printf("packet not from Ti92\n");
    free(vardata);
    return;
   }
   if (get_byte()!=0x09)
   {
    printf("no req for data\n");
    free(vardata);
    return;
   }
   get_byte();
   get_byte();

   send_ack();

   blkcnt++;
   sprintf(infostr,str_sending_backup_info,verstring,blkcnt);
   StatusString(infostr);
   if((backlang-sended)>=1024)
   {
    send_byte(0x09);
    send_byte(0x15);
    send_byte(0x00);
    send_byte(0x04);
    gchk=0;
    for(cnt=0;cnt<1024;cnt++)
    {
      send_byte(vardata[sended+cnt]);
      gchk+=vardata[sended+cnt];
      if(timeout_error)
      {    
        free(vardata);
        return;
      }
      if (!(cnt%150)) SetBarPos((100*cnt)/1024);
    }
    gchk&=0xFFFF;
    send_byte(gchk%256);
    send_byte(gchk/256);
    sended+=1024;
   }
   else
   {
    send_byte(0x09);
    send_byte(0x15);
    send_byte((backlang-sended)%256);
    send_byte((backlang-sended)/256);
    gchk=0;
    for(cnt=0;cnt<(backlang-sended);cnt++)
    {
      send_byte(vardata[sended+cnt]);
      gchk+=vardata[sended+cnt];
      if(timeout_error)
      {    
        free(vardata);
        return;
      }
      if (!(cnt%150)) SetBarPos((100*cnt)/(backlang-sended));
    }
    gchk&=0xFFFF;
    send_byte(gchk%256);
    send_byte(gchk/256);
    free(vardata);
    get_ack();
    send_byte(0x09);
    send_byte(0x92);
    send_byte(0x00);
    send_byte(0x00);
    return;
   }
  }
}  

void save_as_iff(void)
{
  unsigned int n,filepos,n1;
  unsigned char *vardata;
  APTR aslreq;
  BOOL aslres;
  char filename[200];
  struct FileRequester *filereq;
  FILE *fileh;

  StatusString(str_select_file_save_iff);  
  aslreq=(APTR)AllocAslRequestTags(ASL_FileRequest,ASLFR_DoSaveMode,TRUE,ASLFR_TitleText,str_select_file_save_iff,ASLFR_Window,Tool_Window,TAG_DONE);
  aslres=AslRequest(aslreq,NULL);
  filereq=(struct FileRequester *)aslreq;
  if (aslres) 
  {
    if (!filereq->fr_Drawer[0]) strcpy(filename,filereq->fr_File);
    else
    {
      if (filereq->fr_Drawer[strlen(filereq->fr_Drawer)-1]==':') sprintf(filename,"%s%s",filereq->fr_Drawer,filereq->fr_File);
      else sprintf(filename,"%s/%s",filereq->fr_Drawer,filereq->fr_File);
    }
  }
  FreeAslRequest(aslreq);
  if (!aslres) return;
  
  fileh=fopen(filename,"wb");
  if (!fileh)
  {
    printf(str_err_opening_file,filename);
    return;
  }

  fputc('F',fileh);
  fputc('O',fileh);
  fputc('R',fileh);
  fputc('M',fileh);

  fputc(0,fileh);  /* Länge der Daten */
  fputc(0,fileh);
  fputc(0,fileh);
  fputc(0,fileh);

  fputc('I',fileh);
  fputc('L',fileh);
  fputc('B',fileh);
  fputc('M',fileh);
  
  fputc('B',fileh);
  fputc('M',fileh);
  fputc('H',fileh);
  fputc('D',fileh);

  fputc(0,fileh);  /* Länge der Daten */
  fputc(0,fileh);
  fputc(0,fileh);
  fputc(20,fileh);
  
  fputc(0,fileh);
  fputc(240,fileh);
  
  fputc(0,fileh);
  fputc(128,fileh);
  
  fputc(0,fileh);
  fputc(0,fileh);

  fputc(0,fileh);
  fputc(0,fileh);

  fputc(picd,fileh);

  fputc(0,fileh);

  fputc(0,fileh);

  fputc(0,fileh);
  fputc(0,fileh);
  fputc(0,fileh);

  fputc(1,fileh);
  fputc(1,fileh);

  fputc(0,fileh);
  fputc(240,fileh);

  fputc(0,fileh);
  fputc(128,fileh);

  fputc('C',fileh);
  fputc('M',fileh);
  fputc('A',fileh);
  fputc('P',fileh);

  fputc(0,fileh);
  fputc(0,fileh);
  fputc(0,fileh);
  if (picd==1)
  {
    fputc(6,fileh);
    fputc(255,fileh);
    fputc(255,fileh);
    fputc(255,fileh);
    fputc(0,fileh);
    fputc(0,fileh);
    fputc(0,fileh);
  }
  if (picd==2)
  {
    fputc(12,fileh);
    fputc(255,fileh);
    fputc(255,fileh);
    fputc(255,fileh);
    fputc(170,fileh);
    fputc(170,fileh);
    fputc(170,fileh);
    fputc(85,fileh);
    fputc(85,fileh);
    fputc(85,fileh);
    fputc(0,fileh);
    fputc(0,fileh);
    fputc(0,fileh);
  }
  if (picd==3)
  {
    fputc(24,fileh);
    fputc(255,fileh);
    fputc(255,fileh);
    fputc(255,fileh);
    fputc(219,fileh);
    fputc(219,fileh);
    fputc(219,fileh);
    fputc(182,fileh);
    fputc(182,fileh);
    fputc(182,fileh);
    fputc(146,fileh);
    fputc(146,fileh);
    fputc(146,fileh);
    fputc(109,fileh);
    fputc(109,fileh);
    fputc(109,fileh);
    fputc(73,fileh);
    fputc(73,fileh);
    fputc(73,fileh);
    fputc(36,fileh);
    fputc(36,fileh);
    fputc(36,fileh);
    fputc(0,fileh);
    fputc(0,fileh);
    fputc(0,fileh);
  }
  
  fputc('B',fileh);
  fputc('O',fileh);
  fputc('D',fileh);
  fputc('Y',fileh);
  
  fputc(0,fileh);
  fputc(0,fileh);
  
  if (picd==1) fputc(15,fileh);
  if (picd==2) fputc(30,fileh);
  if (picd==3) fputc(45,fileh);
  fputc(0,fileh);  
 
  for(n1=0;n1<128;n1++)
  {
    if (picd>2) for(n=0;n<30;n++) fputc(pic[2][n+30*n1],fileh);
    if (picd>1) for(n=0;n<30;n++) fputc(pic[1][n+30*n1],fileh);
    for(n=0;n<30;n++) fputc(pic[0][n+30*n1],fileh);
  }
  
  filepos=ftell(fileh);
  fseek(fileh,6,SEEK_SET);
  fputc((filepos-8)/256,fileh);  
  fputc((filepos-8)%256,fileh); 
  fclose(fileh); 
}

void do_prefs(void)
{
  ULONG                mclass;
  struct IntuiMessage  *mesg;
  APTR                 maddress;
  struct NewGadget     NewGadgetInfo;
  unsigned char *tempptr;

  unsigned char *timeout_labels[4];

  timeout_labels[0]=str_label_short;
  timeout_labels[1]=str_label_middle;
  timeout_labels[2]=str_label_long;
  timeout_labels[3]=NULL;

  StatusString(str_edit_prefs);

  PrefsGadgets[0]=(struct Gadget *)CreateContext(&PrefsGadgetList);

  NewGadgetInfo.ng_LeftEdge=400;
  NewGadgetInfo.ng_TopEdge=26;
  NewGadgetInfo.ng_Width=20;
  NewGadgetInfo.ng_Height=20;
  NewGadgetInfo.ng_GadgetText=str_get_scrdump_after_pressing_key;
  NewGadgetInfo.ng_TextAttr=NULL;
  NewGadgetInfo.ng_GadgetID=1;
  NewGadgetInfo.ng_Flags=0;
  NewGadgetInfo.ng_VisualInfo=VisualInfo;
  PrefsGadgets[1]=(struct Gadget *)CreateGadget(CHECKBOX_KIND,PrefsGadgets[0],&NewGadgetInfo,GTCB_Checked,upd_scrdump_on_remote,GTCB_Scaled,TRUE,TAG_DONE);

  NewGadgetInfo.ng_TopEdge=52;
  NewGadgetInfo.ng_LeftEdge=320;
  NewGadgetInfo.ng_GadgetText=str_timeout;
  NewGadgetInfo.ng_GadgetID=2;
  NewGadgetInfo.ng_Width=100;
  if (timeout==2) PrefsGadgets[2]=(struct Gadget *)CreateGadget(CYCLE_KIND,PrefsGadgets[1],&NewGadgetInfo,GTCY_Labels,timeout_labels,TAG_DONE);  
  if (timeout==4) PrefsGadgets[2]=(struct Gadget *)CreateGadget(CYCLE_KIND,PrefsGadgets[1],&NewGadgetInfo,GTCY_Labels,timeout_labels,GTCY_Active,1,TAG_DONE);  
  if (timeout==6) PrefsGadgets[2]=(struct Gadget *)CreateGadget(CYCLE_KIND,PrefsGadgets[1],&NewGadgetInfo,GTCY_Labels,timeout_labels,GTCY_Active,2,TAG_DONE);  

  NewGadgetInfo.ng_TopEdge=52;
  NewGadgetInfo.ng_LeftEdge=175;
  NewGadgetInfo.ng_GadgetText=str_romsize;
  NewGadgetInfo.ng_GadgetID=3;
  NewGadgetInfo.ng_Width=50;
  PrefsGadgets[3]=(struct Gadget *)CreateGadget(INTEGER_KIND,PrefsGadgets[2],&NewGadgetInfo,GTIN_MaxChars,4,GTIN_Number,romsize,TAG_DONE);  

  NewGadgetInfo.ng_TopEdge=78;
  NewGadgetInfo.ng_GadgetText=str_textviewer;
  NewGadgetInfo.ng_GadgetID=4;
  NewGadgetInfo.ng_Width=245;
  PrefsGadgets[4]=(struct Gadget *)CreateGadget(STRING_KIND,PrefsGadgets[3],&NewGadgetInfo,GTST_MaxChars,78,GTST_String,text_viewer,TAG_DONE);  

  NewGadgetInfo.ng_TopEdge=104;
  NewGadgetInfo.ng_GadgetText=str_picviewer;
  NewGadgetInfo.ng_GadgetID=5;
  PrefsGadgets[5]=(struct Gadget *)CreateGadget(STRING_KIND,PrefsGadgets[4],&NewGadgetInfo,GTST_MaxChars,78,GTST_String,pic_viewer,TAG_DONE);  

  NewGadgetInfo.ng_LeftEdge=10;
  NewGadgetInfo.ng_TopEdge=134;
  NewGadgetInfo.ng_GadgetText=str_save_prefs;
  NewGadgetInfo.ng_GadgetID=6;
  NewGadgetInfo.ng_Width=133;
  PrefsGadgets[6]=(struct Gadget *)CreateGadget(BUTTON_KIND,PrefsGadgets[5],&NewGadgetInfo,TAG_DONE);  

  NewGadgetInfo.ng_LeftEdge=153;
  NewGadgetInfo.ng_GadgetText=str_use_prefs;
  NewGadgetInfo.ng_GadgetID=7;
  PrefsGadgets[7]=(struct Gadget *)CreateGadget(BUTTON_KIND,PrefsGadgets[6],&NewGadgetInfo,TAG_DONE);  

  NewGadgetInfo.ng_LeftEdge=296;
  NewGadgetInfo.ng_GadgetText=str_cancel_prefs;
  NewGadgetInfo.ng_GadgetID=8;
  PrefsGadgets[8]=(struct Gadget *)CreateGadget(BUTTON_KIND,PrefsGadgets[7],&NewGadgetInfo,TAG_DONE);  
 
  create_window(&Prefs_Window,70,100,438,162,str_prefs,SMART_REFRESH|ACTIVATE|WINDOWDRAG|WINDOWDEPTH,WBENCHSCREEN,IDCMP_GADGETUP,PrefsGadgetList);

  for(;;)
  {
    WaitPort(Prefs_Window->UserPort);
    while((mesg=(struct IntuiMessage*)GT_GetIMsg(Prefs_Window->UserPort))!=NULL)
    {
      mclass=mesg->Class;
      maddress=mesg->IAddress;
      GT_ReplyIMsg(mesg);
      switch(mclass)
      {
        case BUTTONIDCMP:           switch(((struct Gadget *)maddress)->GadgetID)
                                    {
                                      case 6:  GT_GetGadgetAttrs(PrefsGadgets[1],Prefs_Window,NULL,GTCB_Checked,&upd_scrdump_on_remote,TAG_DONE);
                                               GT_GetGadgetAttrs(PrefsGadgets[2],Prefs_Window,NULL,GTCY_Active,&timeout,TAG_DONE);
                                               timeout++;
                                               timeout*=2;
                                               GT_GetGadgetAttrs(PrefsGadgets[3],Prefs_Window,NULL,GTIN_Number,&romsize,TAG_DONE);
                                               GT_GetGadgetAttrs(PrefsGadgets[4],Prefs_Window,NULL,GTST_String,&tempptr,TAG_DONE);
                                               strcpy(text_viewer,tempptr);
                                               GT_GetGadgetAttrs(PrefsGadgets[5],Prefs_Window,NULL,GTST_String,&tempptr,TAG_DONE);
                                               strcpy(pic_viewer,tempptr);
                                               CloseWindow(Prefs_Window);
                                               FreeGadgets(PrefsGadgetList);
                                               save_prefs("ENVARC:Ti92-Link.prefs");
                                               save_prefs("ENV:Ti92-Link.prefs");
                                               return;
                                      case 7:  GT_GetGadgetAttrs(PrefsGadgets[1],Prefs_Window,NULL,GTCB_Checked,&upd_scrdump_on_remote,TAG_DONE);
                                               GT_GetGadgetAttrs(PrefsGadgets[2],Prefs_Window,NULL,GTCY_Active,&timeout,TAG_DONE);
                                               timeout++;
                                               timeout*=2;
                                               GT_GetGadgetAttrs(PrefsGadgets[3],Prefs_Window,NULL,GTIN_Number,&romsize,TAG_DONE);
                                               GT_GetGadgetAttrs(PrefsGadgets[4],Prefs_Window,NULL,GTST_String,&tempptr,TAG_DONE);
                                               strcpy(text_viewer,tempptr);
                                               GT_GetGadgetAttrs(PrefsGadgets[5],Prefs_Window,NULL,GTST_String,&tempptr,TAG_DONE);
                                               strcpy(pic_viewer,tempptr);
                                               CloseWindow(Prefs_Window);
                                               FreeGadgets(PrefsGadgetList);
                                               save_prefs("ENV:Ti92-Link.prefs");
                                               return;
                                      case 8:  CloseWindow(Prefs_Window);
                                               FreeGadgets(PrefsGadgetList);
                                               return;


                                    }
      }
    }
  }
}

void do_sound(void)
{
  ULONG                mclass;
  struct IntuiMessage  *mesg;
  APTR                 maddress;
  struct IOAudio       *AudioIO1;
  struct IOAudio       *AudioIO2;
  struct MsgPort       *AudioMP1;
  struct MsgPort       *AudioMP2;
  UBYTE  whichannel1[]={1,2};
  UBYTE  whichannel2[]={4,8};
  BYTE                 *waveptr1;
  BYTE                 *waveptr2;
  ULONG                device;
  BYTE                 ch1,ch2;
  ULONG                cnt;

  AudioIO1=(struct IOAudio *) AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC|MEMF_CLEAR);
  if (!AudioIO1)
  {
    printf("Error getting mem for IOAudio struct!\n");
    return;
  }
  AudioIO2=(struct IOAudio *) AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC|MEMF_CLEAR);
  if (!AudioIO2)
  {
    FreeMem(AudioIO1,sizeof(struct IOAudio));
    printf("Error getting mem for IOAudio struct!\n");
    return;
  }

  AudioMP1=(struct MsgPort *)CreatePort(0,0);
  if(!AudioMP1)
  {
    FreeMem(AudioIO1,sizeof(struct IOAudio));
    FreeMem(AudioIO2,sizeof(struct IOAudio));
    printf("Error creating messageport!\n");
    return;
  }

  AudioMP2=(struct MsgPort *)CreatePort(0,0);
  if(!AudioMP2)
  {
    FreeMem(AudioIO1,sizeof(struct IOAudio));
    FreeMem(AudioIO2,sizeof(struct IOAudio));
    DeletePort(AudioMP1);
    printf("Error creating messageport!\n");
    return;
  }

  AudioIO1->ioa_Request.io_Message.mn_ReplyPort     = AudioMP1;
  AudioIO1->ioa_Request.io_Message.mn_Node.ln_Pri   = 0;
  AudioIO1->ioa_Request.io_Command                  = ADCMD_ALLOCATE;
  AudioIO1->ioa_Request.io_Flags                    = ADIOF_NOWAIT;
  AudioIO1->ioa_AllocKey                            = 0;
  AudioIO1->ioa_Data                                = whichannel1;
  AudioIO1->ioa_Length                              = sizeof(whichannel1);

  AudioIO1->ioa_Request.io_Message.mn_ReplyPort     = AudioMP2;
  AudioIO1->ioa_Request.io_Message.mn_Node.ln_Pri   = 0;
  AudioIO1->ioa_Request.io_Command                  = ADCMD_ALLOCATE;
  AudioIO1->ioa_Request.io_Flags                    = ADIOF_NOWAIT;
  AudioIO1->ioa_AllocKey                            = 0;
  AudioIO1->ioa_Data                                = whichannel1;
  AudioIO1->ioa_Length                              = sizeof(whichannel2);

  device=OpenDevice(AUDIONAME,0L,(struct IORequest *) AudioIO1,0L);
  if (device)
  {
    printf("Error opening %s / allocing channels\n");
    FreeMem(AudioIO1,sizeof(struct IOAudio));
    FreeMem(AudioIO2,sizeof(struct IOAudio));
    DeletePort(AudioMP1);
    DeletePort(AudioMP2);
    return;
  }

  device=OpenDevice(AUDIONAME,0L,(struct IORequest *) AudioIO2,0L);
  if (device)
  {
    printf("Error opening %s / allocing channels\n");
    CloseDevice((struct IORequest *) AudioIO1);
    FreeMem(AudioIO1,sizeof(struct IOAudio));
    FreeMem(AudioIO2,sizeof(struct IOAudio));
    DeletePort(AudioMP1);
    DeletePort(AudioMP2);
    return;
  }

  waveptr1=(BYTE *) AllocMem(2,MEMF_CHIP|MEMF_PUBLIC);
  if(!waveptr1)
  {
    printf("Error opening %s / allocing channels\n");
    CloseDevice((struct IORequest *) AudioIO1);
    CloseDevice((struct IORequest *) AudioIO2);
    FreeMem(AudioIO1,sizeof(struct IOAudio));
    FreeMem(AudioIO2,sizeof(struct IOAudio));
    DeletePort(AudioMP1);
    DeletePort(AudioMP2);
  }

  waveptr2=(BYTE *) AllocMem(2,MEMF_CHIP|MEMF_PUBLIC);
  if(!waveptr2)
  {
    printf("Error opening %s / allocing channels\n");
    FreeMem(waveptr1,2);
    CloseDevice((struct IORequest *) AudioIO1);
    CloseDevice((struct IORequest *) AudioIO2);
    FreeMem(AudioIO1,sizeof(struct IOAudio));
    FreeMem(AudioIO2,sizeof(struct IOAudio));
    DeletePort(AudioMP1);
    DeletePort(AudioMP2);
  }
  
  AudioIO1->ioa_Request.io_Message.mn_ReplyPort     =AudioMP1;
  AudioIO1->ioa_Request.io_Command                  =CMD_WRITE;
  AudioIO1->ioa_Request.io_Flags                    =ADIOF_PERVOL;
  AudioIO1->ioa_Data                                =(BYTE *)waveptr1;
  AudioIO1->ioa_Length                              =2;
  AudioIO1->ioa_Period                              =324;
  AudioIO1->ioa_Volume                              =64;
  AudioIO1->ioa_Cycles                              =0;
  
  AudioIO2->ioa_Request.io_Message.mn_ReplyPort     =AudioMP2;
  AudioIO2->ioa_Request.io_Command                  =CMD_WRITE;
  AudioIO2->ioa_Request.io_Flags                    =ADIOF_PERVOL;
  AudioIO2->ioa_Data                                =(BYTE *)waveptr2;
  AudioIO2->ioa_Length                              =2;
  AudioIO2->ioa_Period                              =324;
  AudioIO2->ioa_Volume                              =64;
  AudioIO2->ioa_Cycles                              =0;
  
  BeginIO((struct IORequest *)AudioIO1);
  BeginIO((struct IORequest *)AudioIO2);

/*  *DIRREG_B_CIAA=0x00;
  *DIRREG_A_CIAB|=0x06;

  *PORTREG_A_CIAB|=0x06;  */

  create_window(&Sound_Window,70,100,438,170,str_butt_sound,SMART_REFRESH|ACTIVATE|WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH,WBENCHSCREEN,IDCMP_CLOSEWINDOW,NULL);

  for(;;)
  {
    if ((mesg=(struct IntuiMessage*)GT_GetIMsg(Sound_Window->UserPort))!=NULL)
    {
      mclass=mesg->Class;
      maddress=mesg->IAddress;
      GT_ReplyIMsg(mesg);
      switch(mclass)
      {
        case IDCMP_CLOSEWINDOW:     AbortIO((struct IORequest *)AudioIO1);
                                    AbortIO((struct IORequest *)AudioIO2);
                                    CloseDevice((struct IORequest *) AudioIO1);
                                    CloseDevice((struct IORequest *) AudioIO2);
                                    FreeMem(waveptr1,2);
                                    FreeMem(waveptr2,2);
                                    FreeMem(AudioIO1,sizeof(struct IOAudio));
                                    FreeMem(AudioIO2,sizeof(struct IOAudio));
                                    DeletePort(AudioMP1);
                                    DeletePort(AudioMP2);
                                    CloseWindow(Sound_Window);
                               /*     *DIRREG_B_CIAA=0xFF;  
                                    *DIRREG_A_CIAB&=0xF9;  */
                                    return;
      }
    }
/*    ch1=(*PORTREG_B_CIAA&0x01);
    ch2=(*PORTREG_B_CIAA&0x02);  */
    ch1=(*PORTREG_A_CIAB&0x02);
    ch2=(*PORTREG_A_CIAB&0x04);
    if (ch1) waveptr1[0]=127;
    else waveptr1[0]=-127;
    if (ch2) waveptr2[0]=127;
    else waveptr2[0]=-127;
    waveptr1[1]=waveptr1[0];
    waveptr2[1]=waveptr2[0];
    printf("%i %i\n",ch1,ch2);
  }
}

void load_ti92_file(void)
{
  unsigned int n,filepos,n1;
  APTR aslreq;
  BOOL aslres;
  char filename[200];
  struct FileRequester *filereq;
  FILE *fileh;
  unsigned long cnt;
  unsigned char typ,err=FALSE;
  unsigned int lang;
  unsigned char namelen;
  unsigned char name[20];
  unsigned char *vardata=(unsigned char *)malloc(65536);
  unsigned char infotext[40];
  unsigned char typtext[10];
  unsigned char folder[10]="";
  unsigned long startpos,endpos,cfilepos,rchk,fchk;
  unsigned char comment[45];

  StatusString(str_select_file_92g);  
  aslreq=(APTR)AllocAslRequestTags(ASL_FileRequest,ASLFR_TitleText,str_select_file_92g,ASLFR_Window,Tool_Window,TAG_DONE);
  aslres=AslRequest(aslreq,NULL);
  filereq=(struct FileRequester *)aslreq;
  if (aslres) 
  {
    if (!filereq->fr_Drawer[0]) strcpy(filename,filereq->fr_File);
    else
    {
      if (filereq->fr_Drawer[strlen(filereq->fr_Drawer)-1]==':') sprintf(filename,"%s%s",filereq->fr_Drawer,filereq->fr_File);
      else sprintf(filename,"%s/%s",filereq->fr_Drawer,filereq->fr_File);
    }
  }
  FreeAslRequest(aslreq);
  if (!aslres) return;
  
  fileh=fopen(filename,"rb");
  if (!fileh)
  {
    printf(str_err_opening_file,filename);
    return;
  }

  if (fgetc(fileh)!='*') err=TRUE;
  if (fgetc(fileh)!='*') err=TRUE;
  if (fgetc(fileh)!='T') err=TRUE;
  if (fgetc(fileh)!='I') err=TRUE;
  if (fgetc(fileh)!='9') err=TRUE;
  if (fgetc(fileh)!='2') err=TRUE;
  if (fgetc(fileh)!='*') err=TRUE;
  if (fgetc(fileh)!='*') err=TRUE;

  if (err)
  {
    fclose(fileh);
    erequest(str_err_no_ti92file);
    free(vardata);
    return;
  }

  free_a_list();

  for(n=0;n<10;n++) fgetc(fileh);

  for(n=0;n<38;n++) comment[n]=fgetc(fileh);

  showcomment(comment);

  for(n=0;n<4;n++) fgetc(fileh);

  endpos=fgetc(fileh);
  endpos+=fgetc(fileh)<<8;
  
  for(;;)
  {
    startpos=endpos;
    fgetc(fileh);
    fgetc(fileh);
    for(n=0;n<8;n++)name[n]=fgetc(fileh);
    if (name[0]==0xA5&&name[1]==0x5A)
    {
      fclose(fileh);
      free(vardata);
      return;
    }
    name[8]=0;
    typ=fgetc(fileh);
    for(n=0;n<3;n++) fgetc(fileh);
    endpos=fgetc(fileh);
    endpos+=fgetc(fileh)<<8;
    switch(typ)
    {
      case 0x1D: erequest(str_err_use_send_backup);
                 fclose(fileh);
                 free(vardata);
                 return;
      case 0x1F: strcpy(folder,name);
                 break;
      default:   cfilepos=ftell(fileh);
                 fseek(fileh,startpos,SEEK_SET);
                 rchk=0;
                 for(n=0;n<5;n++) rchk+=fgetc(fileh);
                 for(n=0;n<(endpos-startpos-7);n++)
                 {
                   vardata[n]=fgetc(fileh);
                   rchk+=vardata[n];
                 }
                 rchk&=0xFFFF;
                 fchk=fgetc(fileh);
                 fchk+=fgetc(fileh)<<8;
                 if (rchk!=fchk&&(rchk+256)!=fchk)
                 {
                   printf("checksum of \"%s\" wrong rchk=%i fchk=%i\n",name,rchk,fchk);
                 }
                 fseek(fileh,cfilepos,SEEK_SET);
                 GT_SetGadgetAttrs(ToolGadgets[6],Tool_Window,NULL,GTLV_Labels,NULL,TAG_DONE);
                 for(n=0;n<50;n++)
                 {
                   if (!a_inuse[n])
                   {
                     a_inuse[n]=TRUE;
                     a_data[n]=(unsigned char *)malloc(endpos-startpos-7);
                     for(cnt=0;cnt<endpos-startpos-7;cnt++) a_data[n][cnt]=vardata[cnt];
                     a_typ[n]=typ;
                     a_lang[n]=endpos-startpos-7;
                     if (folder[0]) sprintf(a_names[n],"%s\\%s",folder,name);
                     else strcpy(a_names[n],name);
                     a_nodes[n].ln_Name=a_names[n];
                     AddTail(&a_list,&a_nodes[n]);
                     break;
                   }
                 }
                 GT_SetGadgetAttrs(ToolGadgets[6],Tool_Window,NULL,GTLV_Labels,&a_list,TAG_DONE);
                 GT_SetGadgetAttrs(ToolGadgets[18],Tool_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
                 GT_SetGadgetAttrs(ToolGadgets[20],Tool_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
                 break;

    }
  }
}

void free_a_list(void)
{
  int i;

  GT_SetGadgetAttrs(ToolGadgets[6],Tool_Window,NULL,GTLV_Labels,NULL,TAG_DONE);
  NewList(&a_list);
  GT_SetGadgetAttrs(ToolGadgets[6],Tool_Window,NULL,GTLV_Labels,&a_list,TAG_DONE);
  GT_SetGadgetAttrs(ToolGadgets[20],Tool_Window,NULL,GA_Disabled,TRUE,TAG_DONE);
  GT_SetGadgetAttrs(ToolGadgets[17],Tool_Window,NULL,GA_Disabled,TRUE,TAG_DONE);
  GT_SetGadgetAttrs(ToolGadgets[21],Tool_Window,NULL,GA_Disabled,TRUE,TAG_DONE);
  printvarinfo("",FALSE);

  for (i=0;i<50;i++) if (a_inuse[i])
  {
    a_inuse[i]=FALSE;
    free(a_data[i]);
  }
}

void printvarinfo(unsigned char *varinfo,BOOL right)
{
  SetAPen(Tool_Window->RPort,0);
  RectFill(Tool_Window->RPort,5,302,535,318);
  SetAPen(Tool_Window->RPort,1);
  if(!right) Move(Tool_Window->RPort,15,314);
  else Move(Tool_Window->RPort,525-TextLength(Tool_Window->RPort,varinfo,strlen(varinfo)),314);
  Text(Tool_Window->RPort,varinfo,strlen(varinfo));
}

void view_var(void)
{
  unsigned char filename[80],command[80];
  FILE *fileh;
  BPTR icon,ocon;
  unsigned int n,n1,rlen,filepos;
  
  sprintf(filename,"T:Ti92-Link_tmp_%s",a_names[a_listsel]);
  fileh=fopen(filename,"wb");
  if (!fileh)
  {
    printf(str_err_opening_file,filename);
    return;
  }
  switch(a_typ[a_listsel])
  {
    case 0x10:  fputc('F',fileh);
                fputc('O',fileh);
                fputc('R',fileh);
                fputc('M',fileh);

                fputc(0,fileh);  
                fputc(0,fileh);
                fputc(0,fileh);
                fputc(0,fileh);

                fputc('I',fileh);
                fputc('L',fileh);
                fputc('B',fileh);
                fputc('M',fileh);
  
                fputc('B',fileh);
                fputc('M',fileh);
                fputc('H',fileh);
                fputc('D',fileh);

                fputc(0,fileh);  
                fputc(0,fileh);
                fputc(0,fileh);
                fputc(20,fileh);
  
                fputc(0,fileh);
                fputc(a_data[a_listsel][4]+1,fileh);
  
                fputc(0,fileh);
                fputc(a_data[a_listsel][2],fileh);
  
                rlen=(a_data[a_listsel][4]+1)/8;
                if ((a_data[a_listsel][4]+1)%8) rlen++;
  
                fputc(0,fileh);
                fputc(0,fileh);

                fputc(0,fileh);
                fputc(0,fileh);

                fputc(1,fileh);

                fputc(0,fileh);

                fputc(0,fileh);

                fputc(0,fileh);
                fputc(0,fileh);
                fputc(0,fileh);

                fputc(1,fileh);
                fputc(1,fileh);

                fputc(0,fileh);
                fputc(a_data[a_listsel][4]+1,fileh);

                fputc(0,fileh);
                fputc(a_data[a_listsel][2],fileh);

                fputc('C',fileh);
                fputc('M',fileh);
                fputc('A',fileh);
                fputc('P',fileh);

                fputc(0,fileh);
                fputc(0,fileh);
                fputc(0,fileh);

                fputc(6,fileh);
                fputc(255,fileh);
                fputc(255,fileh);
                fputc(255,fileh);
                fputc(0,fileh);
                fputc(0,fileh);
                fputc(0,fileh);
  
                fputc('B',fileh);
                fputc('O',fileh);
                fputc('D',fileh);
                fputc('Y',fileh);
  
                fputc(0,fileh);
                fputc(0,fileh);
  
                fputc((rlen*(a_data[a_listsel][2]))/256,fileh);
                fputc((rlen*(a_data[a_listsel][2]))%256,fileh);  
 
                for(n1=0;n1<a_data[a_listsel][2];n1++)
                {
                  for(n=0;n<rlen;n++) fputc(a_data[a_listsel][5+n+rlen*n1],fileh);
                }
  
                filepos=ftell(fileh);
                fseek(fileh,6,SEEK_SET);
                fputc((filepos-8)/256,fileh);  
                fputc((filepos-8)%256,fileh); 

                sprintf(command,"%s %s",pic_viewer,filename);
                break; 
    case 0x0B:  for (n=2;n<a_lang[a_listsel]-2;n++)
                {
                  if (a_data[a_listsel][n]!=13) fputc(a_data[a_listsel][n],fileh);
                  else
                  {
                    fputc(10,fileh);
                    n++;   
                  }
                }
                sprintf(command,"%s %s",text_viewer,filename);
                break;
    default:    for(n=0;n<a_lang[a_listsel];n++) fputc(a_data[a_listsel][n],fileh);
                sprintf(command,"%s %s",text_viewer,filename);
                break;
  }
  fclose(fileh);
  icon=Open("CON:////Ti92-Link_Viewer_Input_CON/AUTO/CLOSE",MODE_READWRITE);
  ocon=Open("CON:////Ti92-Link_Viewer_Output_CON/AUTO/CLOSE",MODE_READWRITE);
  SystemTags(command,SYS_Input,icon,SYS_Output,ocon,SYS_Asynch,TRUE,TAG_DONE);
}

void do_locale(void)
{
  str_prog_exit=(char *)GetString(&LocaleInf,MSG_PROG_EXIT);
  str_yes=(char *)GetString(&LocaleInf,MSG_YES);
  str_no=(char *)GetString(&LocaleInf,MSG_NO);
  str_send_byte_timeout_text=(char *)GetString(&LocaleInf,MSG_SEND_BYTE_TIMEOUT_TEXT);
  str_get_byte_timeout_text=(char *)GetString(&LocaleInf,MSG_GET_BYTE_TIMEOUT_TEXT);
  str_par_err_text=(char *)GetString(&LocaleInf,MSG_PAR_ERR_TEXT);
  str_butt_get_scrs=(char *)GetString(&LocaleInf,MSG_BUTT_GET_SCRS);
  str_butt_get_farscrs=(char *)GetString(&LocaleInf,MSG_BUTT_GET_FARSCRS);
  str_butt_save_as_iff=(char *)GetString(&LocaleInf,MSG_BUTT_SAVE_AS_IFF);
  str_butt_get_romdump=(char *)GetString(&LocaleInf,MSG_BUTT_GET_ROMDUMP);
  str_butt_receive=(char *)GetString(&LocaleInf,MSG_BUTT_RECEIVE);
  str_a_vars=(char *)GetString(&LocaleInf,MSG_A_VARS);
  str_t_vars=(char *)GetString(&LocaleInf,MSG_T_VARS);
  str_butt_chk_ready=(char *)GetString(&LocaleInf,MSG_BUTT_CHK_READY);
  str_butt_upd_list=(char *)GetString(&LocaleInf,MSG_BUTT_UPD_LIST);
  str_butt_req_backup=(char *)GetString(&LocaleInf,MSG_BUTT_REQ_BACKUP);
  str_butt_send_backup=(char *)GetString(&LocaleInf,MSG_BUTT_SEND_BACKUP);
  str_butt_remote=(char *)GetString(&LocaleInf,MSG_BUTT_REMOTE);
  str_butt_prefs=(char *)GetString(&LocaleInf,MSG_BUTT_PREFS);
  str_butt_sound=(char *)GetString(&LocaleInf,MSG_BUTT_SOUND);
  str_butt_load_file=(char *)GetString(&LocaleInf,MSG_BUTT_LOAD_FILE);
  str_butt_save_file=(char *)GetString(&LocaleInf,MSG_BUTT_SAVE_FILE);
  str_butt_view=(char *)GetString(&LocaleInf,MSG_BUTT_VIEW);
  str_romsize=(char *)GetString(&LocaleInf,MSG_ROMSIZE);
  str_textviewer=(char *)GetString(&LocaleInf,MSG_TEXTVIEWER);
  str_picviewer=(char *)GetString(&LocaleInf,MSG_PICVIEWER);
  str_label_short=(char *)GetString(&LocaleInf,MSG_LABEL_SHORT);
  str_label_middle=(char *)GetString(&LocaleInf,MSG_LABEL_MIDDLE);
  str_label_long=(char *)GetString(&LocaleInf,MSG_LABEL_LONG);
  str_ready=(char *)GetString(&LocaleInf,MSG_READY);
  str_not_at_homescr=(char *)GetString(&LocaleInf,MSG_NOT_AT_HOMESCR);
  str_not_resp=(char *)GetString(&LocaleInf,MSG_NOT_RESP);
  str_req_scrshot=(char *)GetString(&LocaleInf,MSG_REQ_SCRSHOT);
  str_wait_for_data=(char *)GetString(&LocaleInf,MSG_WAIT_FOR_DATA);
  str_remotecontrolling=(char *)GetString(&LocaleInf,MSG_REMOTECONTROLLING);
  str_ti_remotecont=(char *)GetString(&LocaleInf,MSG_TI_REMOTECONT);
  str_getting_var=(char *)GetString(&LocaleInf,MSG_GETTING_VAR);
  str_getting_scrshot=(char *)GetString(&LocaleInf,MSG_GETTING_SCRSHOT);
  str_drawing_scrshot=(char *)GetString(&LocaleInf,MSG_DRAWING_SCRSHOT);
  str_select_file_romdump=(char *)GetString(&LocaleInf,MSG_SELECT_FILE_ROMDUMP);
  str_waiting_for_romdump=(char *)GetString(&LocaleInf,MSG_WAITING_FOR_ROMDUMP);
  str_getting_romdump=(char *)GetString(&LocaleInf,MSG_GETTING_ROMDUMP);
  str_wait_for_fcam=(char *)GetString(&LocaleInf,MSG_WAIT_FOR_FCAM);
  str_getting_fcam=(char *)GetString(&LocaleInf,MSG_GETTING_FCAM);
  str_chk_for_calc=(char *)GetString(&LocaleInf,MSG_CHK_FOR_CALC);
  str_select_file_save_backup=(char *)GetString(&LocaleInf,MSG_SELECT_FILE_SAVE_BACKUP);
  str_req_backup=(char *)GetString(&LocaleInf,MSG_REQ_BACKUP);
  str_getting_backup=(char *)GetString(&LocaleInf,MSG_GETTING_BACKUP);
  str_getting_backup_info=(char *)GetString(&LocaleInf,MSG_GETTING_BACKUP_INFO);
  str_special_keys=(char *)GetString(&LocaleInf,MSG_SPECIAL_KEYS);
  str_waiting_for_input=(char *)GetString(&LocaleInf,MSG_WAITING_FOR_INPUT);
  str_send_var_info=(char *)GetString(&LocaleInf,MSG_SEND_VAR_INFO);
  str_enter_comment=(char *)GetString(&LocaleInf,MSG_ENTER_COMMENT);
  str_no_comment=(char *)GetString(&LocaleInf,MSG_NO_COMMENT);
  str_ok=(char *)GetString(&LocaleInf,MSG_OK);
  str_cancel=(char *)GetString(&LocaleInf,MSG_CANCEL);
  str_select_file_send_backup=(char *)GetString(&LocaleInf,MSG_SELECT_FILE_SEND_BACKUP);
  str_loading_backupfile=(char *)GetString(&LocaleInf,MSG_LOADING_BACKUPFILE);
  str_sending_backup=(char *)GetString(&LocaleInf,MSG_SENDING_BACKUP);
  str_sending_backup_info=(char *)GetString(&LocaleInf,MSG_SENDING_BACKUP_INFO);
  str_select_file_save_iff=(char *)GetString(&LocaleInf,MSG_SELECT_FILE_SAVE_IFF);
  str_edit_prefs=(char *)GetString(&LocaleInf,MSG_EDIT_PREFS);
  str_get_scrdump_after_pressing_key=(char *)GetString(&LocaleInf,MSG_GET_SCRDUMP_AFTER_PRESSING_KEY);
  str_timeout=(char *)GetString(&LocaleInf,MSG_TIMEOUT);
  str_prefs=(char *)GetString(&LocaleInf,MSG_PREFS);
  str_select_file_92g=(char *)GetString(&LocaleInf,MSG_SELECT_FILE_92G);
  str_err_opening_gfx=(char *)GetString(&LocaleInf,MSG_ERR_OPENING_GFX);
  str_err_opening_dos=(char *)GetString(&LocaleInf,MSG_ERR_OPENING_DOS);
  str_err_opening_gadtools=(char *)GetString(&LocaleInf,MSG_ERR_OPENING_GADTOOLS);
  str_err_opening_mainwin=(char *)GetString(&LocaleInf,MSG_ERR_OPENING_MAINWIN);
  str_err_opening_file=(char *)GetString(&LocaleInf,MSG_ERR_OPENING_FILE);
  str_err_no_fcam=(char *)GetString(&LocaleInf,MSG_ERR_NO_FCAM);
  str_err_no_backupfile=(char *)GetString(&LocaleInf,MSG_ERR_NO_BACKUPFILE);
  str_err_no_ti92file=(char *)GetString(&LocaleInf,MSG_ERR_NO_TI92FILE);
  str_err_use_send_backup=(char *)GetString(&LocaleInf,MSG_ERR_USE_SEND_BACKUP);
  str_select_file_save_92g=(char *)GetString(&LocaleInf,MSG_SELECT_FILE_SAVE_92G);
  str_err_wrong_chksum=(char *)GetString(&LocaleInf,MSG_ERR_WRONG_CHKSUM);
  str_save_prefs=(char *)GetString(&LocaleInf,MSG_SAVE_PREFS);
  str_use_prefs=(char *)GetString(&LocaleInf,MSG_USE_PREFS);
  str_cancel_prefs=(char *)GetString(&LocaleInf,MSG_CANCEL_PREFS);
  str_req_var_info=(char *)GetString(&LocaleInf,MSG_REQ_VAR_INFO);
  str_getting_dirlist=(char *)GetString(&LocaleInf,MSG_GETTING_DIRLIST);
  str_comment_in_file=(char *)GetString(&LocaleInf,MSG_COMMENT_IN_FILE);
}

void erequest(char *text)
{
  struct EasyStruct req;
  unsigned char req_title[]="Ti92-Link";
  
  req.es_StructSize=sizeof(struct EasyStruct);
  req.es_Flags=0;
  req.es_Title=req_title;
  req.es_TextFormat=text;
  req.es_GadgetFormat=str_ok;

  EasyRequestArgs(NULL,&req,NULL,NULL);
}

void req_var(unsigned char *varname,unsigned char vartyp,unsigned int varlen)
{
  unsigned int chk,jmplen,cnt,n;
  unsigned char *vardata;
  unsigned char infostr[60],vartypstr[10];

  type_string(vartypstr,vartyp);
  sprintf(infostr,str_req_var_info,varname,vartypstr,varlen+1);
  StatusString(infostr);

  send_byte(0x09);
  send_byte(0xA2);
  send_byte(6+strlen(varname));
  send_byte(0x00);

  for(n=0;n<5;n++) send_byte(0x00);
  send_byte(strlen(varname));      chk=strlen(varname);
  for(n=0;n<strlen(varname);n++)
  {
    send_byte(varname[n]);
    chk+=varname[n];
  }
  send_byte(chk%256);
  send_byte(chk/256);

  for(n=0;n<6;n++) get_byte();
  jmplen=get_byte();
  jmplen+=get_byte()<<8;
  jmplen+=2;

  for(n=0;n<jmplen;n++) get_byte();

  send_ack();
  sprintf(infostr,str_getting_var,varname,vartypstr,varlen+1);
  StatusString(infostr);
  send_datareq();
  get_ack();

  vardata=(unsigned char *)malloc(65536);
  get_data(vardata);
  send_ack();
  get_byte();
  get_byte();
  get_byte();
  get_byte();
  send_ack(); 
  if (!check_ok) 
  {
    erequest(str_err_wrong_chksum);
  } 
  else
  {
    GT_SetGadgetAttrs(ToolGadgets[6],Tool_Window,NULL,GTLV_Labels,NULL,TAG_DONE);
    for(n=0;n<50;n++)
    {
      if (!a_inuse[n])
      {
        a_inuse[n]=TRUE;
        a_data[n]=(unsigned char *)malloc(varlen);
        for(cnt=5;cnt<(varlen+5);cnt++) a_data[n][cnt-5]=vardata[cnt];
        a_typ[n]=vartyp;
        a_lang[n]=varlen;
        strcpy(a_names[n],varname);
        a_nodes[n].ln_Name=a_names[n];
        AddTail(&a_list,&a_nodes[n]);
        break;
      }
    }
    GT_SetGadgetAttrs(ToolGadgets[6],Tool_Window,NULL,GTLV_Labels,&a_list,TAG_DONE);
    GT_SetGadgetAttrs(ToolGadgets[20],Tool_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
    GT_SetGadgetAttrs(ToolGadgets[18],Tool_Window,NULL,GA_Disabled,FALSE,TAG_DONE);
  }
  free(vardata);
  Delay(2);
}

void save_92g_file(void)
{
  unsigned int n,filepos,n1,x,x1,vars=0,varcnt=0;
  unsigned char *vardata;
  APTR aslreq;
  BOOL aslres;
  char filename[200],comment[50],folder[10]="",ftemp[20],*tempptr,sname[10];
  struct FileRequester *filereq;
  FILE *fileh;
  unsigned long varcntpos=0,curpos,varchk;
  unsigned long vardatasize=0;

  StatusString(str_select_file_save_92g);  
  aslreq=(APTR)AllocAslRequestTags(ASL_FileRequest,ASLFR_DoSaveMode,TRUE,ASLFR_TitleText,str_select_file_save_92g,ASLFR_Window,Tool_Window,TAG_DONE);
  aslres=AslRequest(aslreq,NULL);
  filereq=(struct FileRequester *)aslreq;
  if (aslres) 
  {
    if (!filereq->fr_Drawer[0]) strcpy(filename,filereq->fr_File);
    else
    {
      if (filereq->fr_Drawer[strlen(filereq->fr_Drawer)-1]==':') sprintf(filename,"%s%s",filereq->fr_Drawer,filereq->fr_File);
      else sprintf(filename,"%s/%s",filereq->fr_Drawer,filereq->fr_File);
    }
  }
  FreeAslRequest(aslreq);
  if (!aslres) return;
  
  fileh=fopen(filename,"wb");
  if (!fileh)
  {
    printf(str_err_opening_file,filename);
    return;
  }
  if (ask_for_comment(comment))
  {
    for (n=0;n<50;n++)
    {
      if (a_inuse[n])
      {
        vars++;
        strcpy(ftemp,a_names[n]);
        tempptr=strchr(ftemp,'\\');
        if (tempptr) tempptr[0]=0;
        if (strcmp(ftemp,folder)&&tempptr)
        {
          vars++;
          strcpy(folder,ftemp);
        }
      }
    }
    folder[0]=0;
    
    fputc('*',fileh);
    fputc('*',fileh);
    fputc('T',fileh);
    fputc('I',fileh);
    fputc('9',fileh);
    fputc('2',fileh);
    fputc('*',fileh);
    fputc('*',fileh);
    fputc(1,fileh);

    for (x=0;x<9;x++) fputc(0,fileh);
    for (x1=0;x1<strlen(comment);x1++) fputc(comment[x1],fileh); 
    for (x=x1;x<40;x++) fputc(0,fileh);

    fputc(vars,fileh);
    fputc(0,fileh);
 
    for (n=0;n<50;n++)
    {
      if (a_inuse[n])
      {
        strcpy(ftemp,a_names[n]);
        tempptr=strchr(ftemp,'\\');
        if (tempptr)
        {
          tempptr[0]=0;
          strcpy(sname,tempptr+1);
        }
        else strcpy(sname,ftemp);
        if (strcmp(ftemp,folder)&&tempptr)
        {
          if (varcntpos)
          {
            curpos=ftell(fileh);
            fseek(fileh,varcntpos,SEEK_SET);
            fputc(varcnt,fileh);
            fseek(fileh,curpos,SEEK_SET);
            varcnt=0;
          }
          fputc((0x42+16*vars+vardatasize)%256,fileh);
          fputc((0x42+16*vars+vardatasize)/256,fileh);    
          fputc(0,fileh);
          fputc(0,fileh);
          for (x1=0;x1<strlen(ftemp);x1++) fputc(ftemp[x1],fileh); 
          for (x=x1;x<8;x++) fputc(0,fileh);
          fputc(0x1F,fileh);
          fputc(0,fileh);
          varcntpos=ftell(fileh);
          fputc(0,fileh);
          fputc(0,fileh);
          strcpy(folder,ftemp);
        }
        varcnt++;
        fputc((0x42+16*vars+vardatasize)%256,fileh);
        fputc((0x42+16*vars+vardatasize)/256,fileh);    
        fputc(0,fileh);
        fputc(0,fileh);
        for (x1=0;x1<strlen(sname);x1++) fputc(sname[x1],fileh); 
        for (x=x1;x<8;x++) fputc(0,fileh);
        fputc(a_typ[n],fileh);
        fputc(0,fileh);
        fputc(0,fileh);
        fputc(0,fileh);
        vardatasize+=a_lang[n]+7;
      }
    }
    if (varcntpos)
    {
      curpos=ftell(fileh);
      fseek(fileh,varcntpos,SEEK_SET);
      fputc(varcnt,fileh);
      fseek(fileh,curpos,SEEK_SET);
    }

    folder[0]=0;

    fputc((0x42+16*vars+vardatasize)%256,fileh);
    fputc((0x42+16*vars+vardatasize)/256,fileh);    
    fputc(0,fileh);
    fputc(0,fileh);
    fputc(0xA5,fileh);
    fputc(0x5A,fileh);
  }
  for (n=0;n<50;n++)
  {
    if (a_inuse[n])
    {
      varchk=0;
      fputc(0,fileh);
      fputc(0,fileh);
      fputc(0,fileh);
      fputc(0,fileh);
      fputc(a_lang[n]/256,fileh); varchk+=a_lang[n]/256;
      for(x=0;x<a_lang[n];x++)
      {
        fputc(a_data[n][x],fileh);
        varchk+=a_data[n][x];
      }
      fputc(varchk%256,fileh);
      fputc(varchk/256,fileh);
    }
  }
  fclose(fileh);
}

void save_prefs(unsigned char *filename)
{
  FILE *fileh;
  unsigned char infotext[50],n;
  
  fileh=fopen(filename,"wb");
  if (!fileh)
  {
    sprintf(infotext,str_err_opening_file,filename);
    erequest(infotext);
    return;
  }

  fputc(upd_scrdump_on_remote,fileh);
  fputc(timeout,fileh);
  for(n=0;;n++)
  {
    fputc(text_viewer[n],fileh);
    if (!text_viewer[n]) break;
  }
  for(n=0;;n++)
  {
    fputc(pic_viewer[n],fileh);
    if (!pic_viewer[n]) break;
  }
  fclose(fileh);
}

void load_prefs(void)
{
  FILE *fileh;
  unsigned char n;
  
  fileh=fopen("ENV:Ti92-Link.prefs","rb");
  if (!fileh) return;

  upd_scrdump_on_remote=fgetc(fileh);
  timeout=fgetc(fileh);
  for(n=0;;n++)
  {
    text_viewer[n]=fgetc(fileh);
    if (!text_viewer[n]) break;
  }
  for(n=0;;n++)
  {
    pic_viewer[n]=fgetc(fileh);
    if (!pic_viewer[n]) break;
  }
  fclose(fileh);
}

void showcomment(unsigned char *comment)
{
  unsigned char infotext[100];

  sprintf(infotext,"%s: %s",str_comment_in_file,comment);
  printvarinfo(infotext,FALSE);
}
