home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <string.h>
- #include <alloc.h>
-
- void read_image(char * s);
- void write_image(char * s);
- void read_jpp(char * s);
- void write_jpp(char * s);
- void read_vgaspec_header(char * s);
- void read_vgaspec(char * s);
- void write_vgaspec(char * s);
- void read_old_vgaspec(char * s);
- void write_old_vgaspec(char * s);
- void read_raw(char * s);
- void read_z80(char * s);
- void write_z80(char * s);
- void read_prg(char * s);
- void write_prg(char * s);
- void jpp_to_vgaspec();
- void vgaspec_to_jpp();
- void raw_to_jpp();
- void jpp_to_z80();
- void z80_to_jpp();
- void jpp_to_prg();
- void prg_to_jpp();
- void z80_uncompress();
- void z80_uncompress();
- int z80_compress();
-
- union header_u {
- char in[9];
- struct {
- char type;
- unsigned int length;
- unsigned int start;
- char var;
- char res1;
- int line;
- } header;
- } h;
-
- char expect[]={
- 0x03, /* type CODE */
- 0x00,0xc0, /* image size */
- 0x00,0x40, /* image start */
- 0xff, /* var */
- 0xff, /* res1 */
- 0xff,0xff /* line */
- };
-
- struct jpp_s {
- unsigned char i;
- unsigned char lax;
- unsigned char hax;
- unsigned char eax;
- unsigned char dax;
- unsigned char cax;
- unsigned char bax;
- unsigned char fax;
- unsigned char aax;
- unsigned char l;
- unsigned char h;
- unsigned char e;
- unsigned char d;
- unsigned char c;
- unsigned char b;
- unsigned char iyl;
- unsigned char iyh;
- unsigned char ixl;
- unsigned char ixh;
- unsigned char iff2;
- unsigned char r;
- unsigned char f;
- unsigned char a;
- unsigned char spl;
- unsigned char sph;
- unsigned char im;
- unsigned char border;
- } jpp;
-
- struct vga_s {
- /*00*/ unsigned char S;
- /*01*/ unsigned char P;
- /*02*/ unsigned int len;
- /*04*/ unsigned int start;
- /*06*/ unsigned char c;
- /*07*/ unsigned char b;
- /*08*/ unsigned char e;
- /*09*/ unsigned char d;
- /*0A*/ unsigned char l;
- /*0B*/ unsigned char h;
- /*0C*/ unsigned char f;
- /*0D*/ unsigned char a;
- /*0E*/ unsigned char ixl;
- /*0F*/ unsigned char ixh;
- /*10*/ unsigned char iyl;
- /*11*/ unsigned char iyh;
- /*12*/ unsigned char cax;
- /*13*/ unsigned char bax;
- /*14*/ unsigned char eax;
- /*15*/ unsigned char dax;
- /*16*/ unsigned char lax;
- /*17*/ unsigned char hax;
- /*18*/ unsigned char fax;
- /*19*/ unsigned char aax;
- /*1A*/ unsigned char r;
- /*1B*/ unsigned char i;
- /*1C*/ unsigned char spl;
- /*1D*/ unsigned char sph;
- /*1E*/ unsigned char pcl;
- /*1F*/ unsigned char pch;
- /*20*/ unsigned char res2;
- /*21*/ unsigned char res3;
- /*22*/ unsigned char border;
- /*23*/ unsigned char res4;
- /*24*/ unsigned char im;
- /*25*/ unsigned char res5;
- } vga;
-
- struct z80_s {
- /*00*/ unsigned char a;
- /*01*/ unsigned char f;
- /*02*/ unsigned char c;
- /*03*/ unsigned char b;
- /*04*/ unsigned char l;
- /*05*/ unsigned char h;
- /*06*/ unsigned char pcl;
- /*07*/ unsigned char pch;
- /*08*/ unsigned char spl;
- /*09*/ unsigned char sph;
- /*0A*/ unsigned char i;
- /*0B*/ unsigned char r;
- /*0C*/ unsigned char data;
- /*0D*/ unsigned char e;
- /*0E*/ unsigned char d;
- /*0F*/ unsigned char cax;
- /*10*/ unsigned char bax;
- /*11*/ unsigned char eax;
- /*12*/ unsigned char dax;
- /*13*/ unsigned char lax;
- /*14*/ unsigned char hax;
- /*15*/ unsigned char aax;
- /*16*/ unsigned char fax;
- /*17*/ unsigned char iyl;
- /*18*/ unsigned char iyh;
- /*19*/ unsigned char ixl;
- /*1A*/ unsigned char ixh;
- /*1B*/ unsigned char iff1;
- /*1C*/ unsigned char iff2;
- /*1D*/ unsigned char im;
- } z80;
-
- struct prg_s {
- /*00*/ char name[10];
- /*0A*/ char nullbyte;
- /*0B*/ unsigned char contains_0x61;
- /*0C*/ unsigned char contains_0x35;
- /*0D*/ unsigned char contains_0x03;
- /*0E*/ unsigned char contains_0x00[0xdc-0x0e];
- /*DC*/ unsigned char iyl;
- /*DD*/ unsigned char iyh;
- /*DE*/ unsigned char ixl;
- /*DF*/ unsigned char ixh;
- /*E0*/ unsigned char eax;
- /*E1*/ unsigned char dax;
- /*E2*/ unsigned char cax;
- /*E3*/ unsigned char bax;
- /*E4*/ unsigned char lax;
- /*E5*/ unsigned char hax;
- /*E6*/ unsigned char fax;
- /*E7*/ unsigned char aax;
- /*E8*/ unsigned char e;
- /*E9*/ unsigned char d;
- /*EA*/ unsigned char c;
- /*EB*/ unsigned char b;
- /*EC*/ unsigned char l;
- /*ED*/ unsigned char h;
- /*EE*/ unsigned char iff2;
- /*EF*/ unsigned char i;
- /*F0*/ unsigned char spl;
- /*F1*/ unsigned char sph;
- /*F2*/ unsigned char filler[0x0e];
- } prg;
-
- #define IMSIZE 49152
-
- unsigned char image[IMSIZE];
-
- unsigned int z80_size;
-
- int intype;
- int outtype;
-
- #define RAW 1
- #define JPP 2
- #define SPECTRUM 3
- #define Z80 4
- #define PRG 5
- #define UNKNOWN 6
-
- unsigned int addr;
- unsigned int sp;
- unsigned int pc;
- int fd;
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int i;
- char *p;
- struct stat status;
- char * fromstring;
- char * tostring;
- char * outfile;
-
- if(argc != 3)
- {
- fprintf(stderr,"SPCONV version 1.02 - %s\n\n",__DATE__);
- fprintf(stderr,"Usage: spconv <source> <target>\n\n");
- fprintf(stderr,"Source must be a valid .SNA, .SP, .Z80, .PRG or RAW file.\n");
- fprintf(stderr,"Target must be a .SNA, .SP, .Z80 or .PRG file.\n\n");
- fprintf(stderr,"If the second parameter contains only a suffix, the prefix\n");
- fprintf(stderr,"of the input file will be used (i.e. 'spconv file.sna .z80')\n\n");
- fprintf(stderr,"Output .SP files are in the new format, .Z80 files are compressed.\n\n");
- fprintf(stderr,"If <source> and <target> are .SP files, convertion from old\n");
- fprintf(stderr,"to new format or from new to old format will be performed.\n");
- fprintf(stderr,"If <source> and <target> are of the same type an error message\n");
- fprintf(stderr,"will be generated (unless they are both .SP files)\n");
- fprintf(stderr,"\n\nPublic Domain, H. de Groot 1992\n\n");
-
- return 1;
- }
-
- if((strchr(argv[1],'*')!=NULL) || (strrchr(argv[1],'?')!=NULL) ||
- (strchr(argv[2],'*')!=NULL) || (strrchr(argv[2],'?')!=NULL))
- {
- fprintf(stderr,"This program can't handle wildcards, sorry!\n");
- return 1;
- }
-
- if(stat(argv[1],&status)<0)
- {
- perror(argv[1]);
- return 1;
- }
-
- /*
- * recognize input type on filename:
- *
- * .SNA -> JPP file
- * .SP -> SPECTRUM file (was VGASPEC)
- * .Z80 -> Z80 file
- * .PRG -> PRG file
- * other -> if exact 48+header -> raw file
- * otherwise unknown
- */
-
- intype=UNKNOWN;
- p=strrchr(argv[1],'.');
- if(p==NULL) p=argv[1]; /* not found, set at begin of string */
- if((strcmp(p,".SNA")==0) || (strcmp(p,".sna")==0))
- {
- fromstring="from .SNA";
- intype=JPP;
- }
- if((strcmp(p,".Z80")==0) || (strcmp(p,".z80")==0))
- {
- fromstring="from .Z80";
- intype=Z80;
- }
- if((strcmp(p,".SP")==0) || (strcmp(p,".sp")==0))
- {
- fromstring="from .SP";
- intype=SPECTRUM;
- }
- if((strcmp(p,".PRG")==0) || (strcmp(p,".prg")==0))
- {
- fromstring="from .PRG";
- intype=PRG;
- }
-
- if(intype==UNKNOWN)
- if (status.st_size == (sizeof(h)+IMSIZE))
- {
- fromstring="from RAW";
- intype=RAW;
- }
-
- /*
- * recognize output type on filename:
- *
- * .SNA -> JPP file
- * .SP -> SPECTRUM file (was VGASPEC)
- * .Z80 -> Z80 file
- * .PRG -> PRG file
- * otherwise unknown
- */
- outtype=UNKNOWN;
-
- p=strrchr(argv[2],'.');
- if(p==NULL) p=argv[2]; /* not found, set at begin of string */
- if((strcmp(p,".SNA")==0) || (strcmp(p,".sna")==0))
- {
- tostring="to .SNA";
- outtype=JPP;
- }
- if((strcmp(p,".Z80")==0) || (strcmp(p,".z80")==0))
- {
- tostring="to .Z80";
- outtype=Z80;
- }
- if((strcmp(p,".SP")==0) || (strcmp(p,".sp")==0))
- {
- tostring="to .SP";
- outtype=SPECTRUM;
- }
- if((strcmp(p,".PRG")==0) || (strcmp(p,".prg")==0))
- {
- tostring="to .PRG";
- outtype=PRG;
- }
-
- if(intype==UNKNOWN)
- {
- fprintf(stderr,"Unknown input file format. Must be a valid .SNA, .SP, .Z80 or .PRG file,\r");
- fprintf(stderr,"or a Raw file\n");
- return 3;
- }
-
- if(outtype==UNKNOWN)
- {
- fprintf(stderr,"Unknown output file format. Must be a .SNA, .SP or .Z80 or .PRG file\n");
- return 4;
- }
-
- /*
- if argv[2] only contains the suffix then use the prefix of
- argv[1];
- */
- if(argv[2][0]=='.')
- {
- outfile=malloc(strlen(argv[1])+strlen(argv[2])+1);
- strcpy(outfile,argv[1]); /* copy prefix */
-
- p=strrchr(outfile,'.');
- if(p!=NULL) *p='\0'; /* put end of string at position of '.' */
-
- strcat(outfile,argv[2]); /* append suffix */
- }
- else
- {
- outfile=malloc(strlen(argv[2]));
-
- strcpy(outfile,argv[2]);
- }
-
- if(intype==outtype)
- {
- if(intype!=SPECTRUM)
- {
- fprintf(stderr,"Input and output file format are the same. ");
- fprintf(stderr,"What you try to do\n");
- fprintf(stderr,"is handled much better by the MSDOS \"COPY\" ");
- fprintf(stderr,"command!\n");
- return 3;
- }
- else
- {
- if((status.st_size == (sizeof(vga)+IMSIZE)))
- {
- printf("Converting %s from new .SP format to old .SP format.\n",argv[1]);
- read_vgaspec(argv[1]);
-
- write_old_vgaspec(outfile);
- return 0;
- }
- else if((status.st_size == (sizeof(vga)+IMSIZE-6)))
- {
- read_vgaspec_header(argv[1]);
- if((vga.S=='S')&&(vga.P=='P'))
- {
- fprintf(stderr,"Invalid input file format. This could be a new syle .SP file with\n");
- fprintf(stderr,"an image of another length than 48Kb. This kind of .SP files cannot\n");
- fprintf(stderr,"be converted. All other file formats (including the old .SP format)\n");
- fprintf(stderr,"contain images of 48Kb length.\n");
- return 3;
- }
-
- printf("Converting %s from old .SP format to new .SP format.\n",argv[1]);
- read_old_vgaspec(argv[1]);
- vga.S='S';
- vga.P='P';
- vga.len=0xC000;
- vga.start=0x4000;
- write_vgaspec(outfile);
- return 0;
- }
- else
- {
- read_vgaspec_header(argv[1]);
- if((vga.S=='S')&&(vga.P=='P'))
- {
- fprintf(stderr,"Invalid input file format. This could be a new syle .SP file with\n");
- fprintf(stderr,"an image of another length than 48Kb. This kind of .SP files cannot\n");
- fprintf(stderr,"be converted. All other file formats (including the old .SP format)\n");
- fprintf(stderr,"contain images of 48Kb length.\n");
- return 3;
- }
- else
- {
- fprintf(stderr,"Unknown input file format. Must be a valid .SNA, .SP, .Z80 or .PRG file\n");
- return 3;
- }
- }
- }
- }
-
- printf("Converting %s %s %s\n",argv[1],fromstring,tostring);
-
- /*
- * convert input_file to JPP
- */
- if((intype==JPP) && (status.st_size == (sizeof(jpp)+IMSIZE)))
- {
- read_jpp(argv[1]);
- }
- else if ((intype==SPECTRUM)&&((status.st_size == (sizeof(vga)+IMSIZE))))
- {
- read_vgaspec(argv[1]);
-
- vgaspec_to_jpp();
- }
- else if ((intype==SPECTRUM)&&((status.st_size == (sizeof(vga)+IMSIZE-6))))
- {
- read_old_vgaspec(argv[1]);
-
- vgaspec_to_jpp();
- }
- else if (intype==RAW)
- {
- read_raw(argv[1]);
-
- raw_to_jpp();
- }
- else if (intype==Z80)
- {
- read_z80(argv[1]);
-
- z80_to_jpp();
- }
- else if (intype==PRG)
- {
- if(status.st_size != (sizeof(prg)+IMSIZE))
- {
- printf("Warning: the image part of %s is not exactly 48k!\n",argv[1]);
- printf(" Converting anyway, the converted file may not work\n");
- }
- read_prg(argv[1]);
-
- prg_to_jpp();
- }
- else
- {
- printf("Unrecognized input file type, can't convert\n");
- return 3;
- }
-
- /*
- * convert internal JPP format to output file
- */
- if(outtype==JPP)
- {
- write_jpp(outfile);
- }
- else if (outtype==SPECTRUM)
- {
- jpp_to_vgaspec();
-
- write_vgaspec(outfile);
- }
- else if (outtype==Z80)
- {
- jpp_to_z80();
-
- write_z80(outfile);
- }
- else if (outtype==PRG)
- {
- jpp_to_prg(outfile);
-
- write_prg(outfile);
- }
- else
- {
- printf("Unrecognized output file type, can't convert\n");
- return 4;
- }
- return 0;
- }
-
- void read_image(char * s)
- {
- if(read(fd,image,IMSIZE)==-1)
- {
- perror(s);
- exit(1);
- }
- }
-
- void write_image(char * s)
- {
- if(write(fd,image,IMSIZE)==-1)
- {
- perror(s);
- exit(2);
- }
- }
-
- void read_jpp(char * s)
- {
- fd=open(s,O_RDONLY|O_BINARY);
- if(fd < 0)
- {
- perror(s);
- exit(1);
- }
- if(read(fd,&jpp,sizeof(jpp))==-1)
- {
- perror(s);
- exit(1);
- }
- read_image(s);
- close(fd);
- }
-
- void write_jpp(char * s)
- {
- unlink(s);
-
- fd=open(s,O_WRONLY|O_CREAT|O_BINARY,0666);
- if(fd<0)
- {
- perror(s);
- exit(2);
- }
-
- if(write(fd,&jpp,sizeof(jpp))==-1)
- {
- perror(s);
- exit(2);
- }
- write_image(s);
- close(fd);
- }
-
- void read_vgaspec_header(char * s)
- {
- fd=open(s,O_RDONLY|O_BINARY);
- if(fd < 0)
- {
- perror(s);
- exit(1);
- }
- if(read(fd,&vga,sizeof(vga))==-1)
- {
- perror(s);
- exit(1);
- }
- close(fd);
- }
-
- void read_vgaspec(char * s)
- {
- fd=open(s,O_RDONLY|O_BINARY);
- if(fd < 0)
- {
- perror(s);
- exit(1);
- }
- if(read(fd,&vga,sizeof(vga))==-1)
- {
- perror(s);
- exit(1);
- }
- read_image(s);
- close(fd);
- }
-
- void write_vgaspec(char * s)
- {
- unlink(s);
-
- fd=open(s,O_WRONLY|O_CREAT|O_BINARY,0666);
- if(fd<0)
- {
- perror(s);
- exit(2);
- }
-
- if(write(fd,&vga,sizeof(vga))==-1)
- {
- perror(s);
- exit(2);
- }
- write_image(s);
- close(fd);
- }
-
- void read_old_vgaspec(char * s)
- {
- fd=open(s,O_RDONLY|O_BINARY);
- if(fd < 0)
- {
- perror(s);
- exit(1);
- }
- if(read(fd,((char *)&vga)+6,sizeof(vga)-6)==-1)
- {
- perror(s);
- exit(1);
- }
- read_image(s);
- close(fd);
- }
-
- void write_old_vgaspec(char * s)
- {
- unlink(s);
-
- fd=open(s,O_WRONLY|O_CREAT|O_BINARY,0666);
- if(fd<0)
- {
- perror(s);
- exit(2);
- }
-
- if(write(fd,((char *)&vga)+6,sizeof(vga)-6)==-1)
- {
- perror(s);
- exit(2);
- }
- write_image(s);
- close(fd);
- }
-
- void read_raw(char * s)
- {
- int i;
-
- fd=open(s,O_RDONLY|O_BINARY);
- if(fd < 0)
- {
- perror(s);
- exit(1);
- }
- if(read(fd,&h,sizeof(h))==-1)
- {
- perror(s);
- exit(1);
- }
- for(i=0;i<9;i++)
- {
- if(h.in[i]!=expect[i])
- {
- fprintf(stderr,"Header of spectum image not ok, ");
- fprintf(stderr,"Spectrum image should be saved with:\n");
- fprintf(stderr,"SAVE *\"b\"CODE 16384,49152");
- exit(1);
- }
- }
- read_image(s);
- close(fd);
- }
-
- void read_z80(char * s)
- {
- fd=open(s,O_RDONLY|O_BINARY);
- if(fd < 0)
- {
- perror(s);
- exit(1);
- }
- if(read(fd,&z80,sizeof(z80))==-1)
- {
- perror(s);
- exit(1);
- }
- read_image(s);
- close(fd);
- }
-
- void write_z80(char * s)
- {
- unlink(s);
-
- fd=open(s,O_WRONLY|O_CREAT|O_BINARY,0666);
- if(fd<0)
- {
- perror(s);
- exit(2);
- }
-
- if(write(fd,&z80,sizeof(z80))==-1)
- {
- perror(s);
- exit(2);
- }
- if(write(fd,image,z80_size)==-1)
- {
- perror(s);
- exit(2);
- }
- close(fd);
- }
-
- void jpp_to_vgaspec()
- {
- sp=256*jpp.sph+jpp.spl;
- addr=sp-0x4000;
- pc=image[addr]+256*image[addr+1];
- sp=sp+2;
-
- vga.S='S';
- vga.P='P';
- vga.len=0xC000;
- vga.start=0x4000;
- vga.f=jpp.f;
- vga.a=jpp.a;
- vga.b=jpp.b;
- vga.c=jpp.c;
- vga.d=jpp.d;
- vga.e=jpp.e;
- vga.h=jpp.h;
- vga.l=jpp.l;
-
- vga.fax=jpp.fax;
- vga.aax=jpp.aax;
- vga.bax=jpp.bax;
- vga.cax=jpp.cax;
- vga.dax=jpp.dax;
- vga.eax=jpp.eax;
- vga.hax=jpp.hax;
- vga.lax=jpp.lax;
-
- vga.ixh=jpp.ixh;
- vga.ixl=jpp.ixl;
- vga.iyh=jpp.iyh;
- vga.iyl=jpp.iyl;
-
- vga.i=jpp.i;
- vga.r=jpp.r;
-
- vga.im=jpp.im & 0x02; /* 0 for IM1, 2 for IM2 */
-
- /* works? how does it know it was IM1 ? */
- if((jpp.iff2 & 0x04) != 0)
- vga.im=vga.im | 0x01;
-
- vga.sph=sp/256;
- vga.spl=sp%256;
-
- vga.pch=pc/256;
- vga.pcl=pc%256;
-
- vga.border=jpp.border;
-
- vga.res2=0;
- vga.res3=0;
- vga.res4=0;
- vga.res5=0;
- }
-
- void vgaspec_to_jpp()
- {
- pc=256*vga.pch+vga.pcl;
-
- jpp.f=vga.f;
- jpp.a=vga.a;
- jpp.b=vga.b;
- jpp.c=vga.c;
- jpp.d=vga.d;
- jpp.e=vga.e;
- jpp.h=vga.h;
- jpp.l=vga.l;
-
- jpp.fax=vga.fax;
- jpp.aax=vga.aax;
- jpp.bax=vga.bax;
- jpp.cax=vga.cax;
- jpp.dax=vga.dax;
- jpp.eax=vga.eax;
- jpp.hax=vga.hax;
- jpp.lax=vga.lax;
-
- jpp.ixh=vga.ixh;
- jpp.ixl=vga.ixl;
- jpp.iyh=vga.iyh;
- jpp.iyl=vga.iyl;
-
- jpp.border=vga.border;
-
- jpp.i=vga.i;
- jpp.r=vga.r;
-
- /* If register I has changed, chances are good that it runs in
- IM2 mode */
- if(jpp.i==0x3f)
- jpp.im=0x01;
- else
- jpp.im=0x02;
-
- if((vga.im & 0x01) == 0)
- jpp.iff2=0x00;
- else
- jpp.iff2=0xff;
-
- sp=256*vga.sph+vga.spl;
- sp=sp-2;
- addr=sp-0x4000;
- image[addr]=vga.pcl;
- image[addr+1]=vga.pch;
-
- jpp.sph=sp/256;
- jpp.spl=sp%256;
- }
-
- void raw_to_jpp()
- {
- pc=0x1bf4; /* entry of "next statement" */
-
- jpp.f=0x99;
- jpp.a=0x5f;
- jpp.b=0x1f;
- jpp.c=0xf0;
- jpp.d=0x5d;
- jpp.e=0x0c;
- jpp.h=0x5d;
- jpp.l=0x0e;
-
- jpp.fax=0x44;
- jpp.aax=0x00;
- jpp.bax=0x18;
- jpp.cax=0x20;
- jpp.dax=0x00;
- jpp.eax=0x07;
- jpp.hax=0x5c;
- jpp.lax=0xf1;
-
- jpp.ixh=0x03;
- jpp.ixl=0xd4;
- jpp.iyh=0x5c;
- jpp.iyl=0x3a;
-
- jpp.i=0x3f;
- jpp.r=0x00;
- jpp.im=0x01;
- jpp.iff2=0xFF;
-
- /* set sp by means of RAMTOP in the image */
- addr=0x5cb2-0x4000;
- sp=256*image[addr+1]+image[addr]-1;
-
- /* Reset ERR NR to no error */
- image[0x5c3a-0x4000]=0xff;
-
- /* Set border by means of BORDCR */
- jpp.border=(image[0x5c48-0x4000] & 0x38)>>3;
-
- /* put return address to MAIN-4 (0x1303) on stack */
- sp=sp-2;
- addr=sp-0x4000;
- image[addr]=0x03;
- image[addr+1]=0x13;
-
- sp=sp-2;
- addr=sp-0x4000;
- image[addr]=pc%256;
- image[addr+1]=pc/256;
-
- jpp.sph=sp/256;
- jpp.spl=sp%256;
- }
-
- void jpp_to_z80()
- {
- sp=256*jpp.sph+jpp.spl;
- addr=sp-0x4000;
- pc=image[addr]+256*image[addr+1];
- sp=sp+2;
-
- z80.f=jpp.f;
- z80.a=jpp.a;
- z80.b=jpp.b;
- z80.c=jpp.c;
- z80.d=jpp.d;
- z80.e=jpp.e;
- z80.h=jpp.h;
- z80.l=jpp.l;
-
- z80.fax=jpp.fax;
- z80.aax=jpp.aax;
- z80.bax=jpp.bax;
- z80.cax=jpp.cax;
- z80.dax=jpp.dax;
- z80.eax=jpp.eax;
- z80.hax=jpp.hax;
- z80.lax=jpp.lax;
-
- z80.ixh=jpp.ixh;
- z80.ixl=jpp.ixl;
- z80.iyh=jpp.iyh;
- z80.iyl=jpp.iyl;
-
- z80.i=jpp.i;
- z80.r=jpp.r | 0x080; /* bit 7 is stored somewhere else, always set */
- z80.im=jpp.im & 0x03;
- z80.im=z80.im + 0x60; /* fixed normal video/kempston joystick */
-
- z80.sph=sp/256;
- z80.spl=sp%256;
-
- z80.pch=pc/256;
- z80.pcl=pc%256;
-
- /* all kinds of stuff put in "data" */
- z80.data=(jpp.border & 0x07)*2;
- if((jpp.r & 0x80)!=0) z80.data=z80.data+1; /* here is bit 7 of r */
- z80.data=z80.data | z80_compress();
-
- if((jpp.iff2 & 0x04) != 0)
- {
- z80.iff1=0xff;
- z80.iff2=0xff;
- }
- else
- {
- z80.iff1=0;
- z80.iff2=0;
- }
- }
-
- void z80_to_jpp()
- {
- pc=256*z80.pch+z80.pcl;
-
- jpp.f=z80.f;
- jpp.a=z80.a;
- jpp.b=z80.b;
- jpp.c=z80.c;
- jpp.d=z80.d;
- jpp.e=z80.e;
- jpp.h=z80.h;
- jpp.l=z80.l;
-
- jpp.fax=z80.fax;
- jpp.aax=z80.aax;
- jpp.bax=z80.bax;
- jpp.cax=z80.cax;
- jpp.dax=z80.dax;
- jpp.eax=z80.eax;
- jpp.hax=z80.hax;
- jpp.lax=z80.lax;
-
- jpp.ixh=z80.ixh;
- jpp.ixl=z80.ixl;
- jpp.iyh=z80.iyh;
- jpp.iyl=z80.iyl;
-
- jpp.border=(z80.data/2) & 0x07;
-
- jpp.i=z80.i;
-
- if(z80.data==0xff) z80.data=0;
-
- if((z80.data & 0x01)==1)
- jpp.r=(z80.r & 0x7f)+0x80;
- else
- jpp.r=z80.r & 0x7f;
-
- jpp.im=z80.im & 0x03;
-
- if(z80.iff2 != 0)
- jpp.iff2=0xff;
- else
- jpp.iff2=0x00;
-
- sp=256*z80.sph+z80.spl;
- sp=sp-2;
- addr=sp-0x4000;
-
- jpp.sph=sp/256;
- jpp.spl=sp%256;
-
- if((z80.data & 0x20)!=0)
- z80_uncompress();
-
- /* PC can only be stored in the image after decompression!! */
- image[addr]=z80.pcl;
- image[addr+1]=z80.pch;
- }
-
- void z80_uncompress()
- {
- unsigned char far * uc;
- unsigned int i,j,k;
- unsigned char l;
-
- uc=farmalloc(IMSIZE+0x0100);
-
- if(uc==NULL)
- {
- fprintf(stderr,"Not enough memory to uncompress z80 image\n");
- exit(7);
- }
-
- j=0;
- i=0;
- while(i<IMSIZE)
- {
- if(image[j]!=0xed)
- uc[i]=image[j];
- else if(image[j+1]!=0xed)
- uc[i]=image[j];
- else
- {
- /* fetch count */
- k=(int) image[j+2];
- /* fetch character */
- l=image[j+3];
- while(k!=0)
- {
- uc[i]=l;
- i++;
- k--;
- }
- j=j+3;
- i--;
- }
- i++;
- j++;
- }
-
- if(i!=IMSIZE)
- {
- fprintf(stderr,"Z80 image corrupted, can't decompress\n");
- fprintf(stderr,"i=%u, should be %u\n",i,IMSIZE);
- exit(6);
- }
-
- /* copy back */
- j=0;
- i=0;
- while(i<IMSIZE)
- image[j++]=uc[i++];
-
- farfree(uc);
- }
-
- #define NOTCOMPRESSED 0
- #define COMPRESSED 0x20
- #define NO 0
- #define YES 1
-
- int z80_compress()
- {
- unsigned char far * comp;
- unsigned int i,j;
- unsigned int num;
- unsigned char c,n;
- unsigned int ed;
-
- z80_size=IMSIZE;
-
- comp=farmalloc(IMSIZE+0x0100);
- if(comp==NULL)
- {
- printf("Warning: Not enough memory to compress the image, using uncopressed image\n");
- return NOTCOMPRESSED;
- }
-
- i=0;
- j=0;
- /* ensure 'ed' is not set */
- ed=NO;
- while(i<IMSIZE)
- {
- c=image[i];
- i++;
- if(i<IMSIZE)
- {
- n=image[i];
- }
- else
- {
- /* force 'n' to be unequal to 'c' */
- n=c;
- n++;
- }
-
- if(c!=n)
- {
- comp[j]=c;
- j++;
- if(c==0xed)
- ed=YES;
- else
- ed=NO;
- }
- else
- {
- if(c==0xed)
- {
- /* two times 0xed - special care */
- comp[j]=0xed;
- j++;
- comp[j]=0xed;
- j++;
- comp[j]=0x02;
- j++;
- comp[j]=0xed;
- j++;
- i++; /* skip second ED */
-
- /* because 0xed is valid compressed we don't
- have to watch it! */
- ed=NO;
- }
- else if(ed==YES)
- {
- /* can't compress now, skip this double pair */
- comp[j]=c;
- j++;
- ed=NO; /* 'c' can't be 0xed */
- }
- else
- {
- num=1;
- while(i<IMSIZE)
- {
- if(c!=image[i])
- break;
- num++;
- i++;
- if(num==255)
- break;
- }
- if(num <= 4)
- {
- /* no use to compress */
- while(num!=0)
- {
- comp[j]=c;
- j++;
- num--;
- }
- }
- else
- {
- comp[j]=0xed;
- j++;
- comp[j]=0xed;
- j++;
- comp[j]=(unsigned char) num;
- j++;
- comp[j]=c;
- j++;
- }
- }
- }
-
- if(j >= (IMSIZE-4))
- {
- /* compressed image bigger or same than original */
- farfree(comp);
- return NOTCOMPRESSED;
- }
- }
- /* append "end of compressed area" mark */
- comp[j]=0;
- j++;
- comp[j]=0xed;
- j++;
- comp[j]=0xed;
- j++;
- comp[j]=0;
- j++;
-
- z80_size = j;
-
- /* copy back */
- i=0;
- j=0;
- while(i<IMSIZE)
- image[i++]=comp[j++];
- farfree(comp);
-
- return COMPRESSED;
- }
-
- void read_prg(char * s)
- {
- fd=open(s,O_RDONLY|O_BINARY);
- if(fd < 0)
- {
- perror(s);
- exit(1);
- }
- if(read(fd,&prg,sizeof(prg))==-1)
- {
- perror(s);
- exit(1);
- }
- read_image(s);
- close(fd);
- }
-
- void write_prg(char * s)
- {
- unlink(s);
-
- fd=open(s,O_WRONLY|O_CREAT|O_BINARY,0666);
- if(fd<0)
- {
- perror(s);
- exit(2);
- }
-
- if(write(fd,&prg,sizeof(prg))==-1)
- {
- perror(s);
- exit(2);
- }
- write_image(s);
- close(fd);
- }
-
- void prg_to_jpp()
- {
- jpp.b=prg.b;
- jpp.c=prg.c;
- jpp.d=prg.d;
- jpp.e=prg.e;
- jpp.h=prg.h;
- jpp.l=prg.l;
- jpp.fax=prg.fax;
- jpp.aax=prg.aax;
- jpp.bax=prg.bax;
- jpp.cax=prg.cax;
- jpp.dax=prg.dax;
- jpp.eax=prg.eax;
- jpp.hax=prg.hax;
- jpp.lax=prg.lax;
-
- jpp.ixh=prg.ixh;
- jpp.ixl=prg.ixl;
- jpp.iyh=prg.iyh;
- jpp.iyl=prg.iyl;
-
- /* Set border by means of BORDCR */
- jpp.border=(image[0x5c48-0x4000] & 0x38)>>3;
-
- jpp.i=prg.i;
-
- if(prg.i==0x3f)
- jpp.im=0x01;
- else
- jpp.im=0x02;
-
- sp=256*prg.sph+prg.spl;
- sp=sp+4; /* there are two more words on the stack besides PC */
- addr=sp-0x4000;
-
- jpp.r=image[addr-3];
- /* the af combo is on the stack */
- jpp.f=image[addr-2];
- jpp.a=image[addr-1];
-
- jpp.sph=sp/256;
- jpp.spl=sp%256;
-
- /* interrupts always on ??? */
- jpp.iff2=prg.iff2;
- }
-
- void jpp_to_prg(char * n)
- {
- int i;
- unsigned char * p;
-
- /* clean header structure first */
- p=(unsigned char *) &prg;
- for(i=0; i < 256; i++)
- p[i]='\0';
-
- prg.contains_0x61=0x61; /* size of image in sectors */
- prg.contains_0x35=0x35; /* don't know yet */
- prg.contains_0x03=0x03; /* don't know yet */
-
- sp=256*jpp.sph+jpp.spl;
- addr=sp-0x4000;
-
- /* these are on the stack */
- image[addr-1]=jpp.a;
- image[addr-2]=jpp.f;
- image[addr-3]=jpp.r;
- image[addr-4]=jpp.iff2;
-
- sp=sp-4;
-
- prg.name[0]='\0';
- strncpy(prg.name,n,10);
- prg.name[10]='\0';
-
- prg.b=jpp.b;
- prg.c=jpp.c;
- prg.d=jpp.d;
- prg.e=jpp.e;
- prg.h=jpp.h;
- prg.l=jpp.l;
-
- prg.fax=jpp.fax;
- prg.aax=jpp.aax;
- prg.bax=jpp.bax;
- prg.cax=jpp.cax;
- prg.dax=jpp.dax;
- prg.eax=jpp.eax;
- prg.hax=jpp.hax;
- prg.lax=jpp.lax;
-
- prg.ixh=jpp.ixh;
- prg.ixl=jpp.ixl;
- prg.iyh=jpp.iyh;
- prg.iyl=jpp.iyl;
-
- prg.i=jpp.i;
- prg.iff2=jpp.iff2;
-
- prg.sph=sp/256;
- prg.spl=sp%256;
-
- /* prg.border=jpp.border; */
- }
-