Program Genesis_SMS;
uses crt;

type tilefacil=array[0..63] of byte;
     tiledificil=array[0..255]of byte;
     archivoentrada=record entbyte:byte;end;
     archivosalida=record salbyte:byte;end;

var
 tilefa:tilefacil;
 tiledi:tiledificil;
 entarch:file of archivoentrada;
 salarch:file of archivosalida;
 archent:archivoentrada;
 archsal:archivosalida;
 nomarchent,nomarchsal:string[100];
 largo1,largo2:longint;
 byte1,byte2:byte;
 comoquiere:char;
 aux1,aux2:integer;


Begin
 clrscr;
 writeln('What do you want to do:');
 write('[E]xtract gfx from a .bin rom or [I]nsert them back: ');
 repeat
  comoquiere:=upcase(readkey);
  write(comoquiere);
 until (comoquiere='E')or(comoquiere='I');

 if comoquiere='E' then
 begin
  writeln;
  writeln;
  writeln;
  writeln('(all values must be in decimal)');
  writeln;
  write('Genesis .bin rom image: ');
  readln(nomarchent);
  write('Output new SMS file: ');
  readln(nomarchsal);
  write('Address: ');
  readln(largo1);
  write('Ending address: ');
  readln(largo2);
  writeln;

  assign(entarch,nomarchent);
  reset(entarch);
  assign(salarch,nomarchsal);
  rewrite(salarch);
  seek(entarch,largo1);


  repeat    {extraer}
   for aux1:=0 to 31 do
   begin
    if not eof(entarch) then read(entarch,archent);
    byte1:=archent.entbyte;
    byte2:=byte1;
    asm shr byte1,1; shr byte1,1; shr byte1,1; shr byte1,1; and byte2,15;end;
    tilefa[aux1*2]:=byte1;
    tilefa[(aux1*2)+1]:=byte2;
   end;

   for aux1:=0 to 7 do    {tilefa a tiledi}
   begin
    for aux2:=0 to 7 do
    begin
     byte1:=tilefa[(aux1*8)+aux2];
     byte2:=byte1;
     asm and byte2,1; end;
     tiledi[(aux1*32)+aux2]:=byte2;
     byte2:=byte1;
     asm shr byte2,1; and byte2,1; end;
     tiledi[(aux1*32)+8+aux2]:=byte2;
     byte2:=byte1;
     asm shr byte2,1; shr byte2,1; and byte2,1; end;
     tiledi[(aux1*32)+16+aux2]:=byte2;
     byte2:=byte1;
     asm shr byte2,1; shr byte2,1; shr byte2,1; and byte2,1; end;
     tiledi[(aux1*32)+24+aux2]:=byte2;
    end;
   end;

   for aux1:=0 to 31 do {dizque comprime y escribe}
   begin
    byte2:=0;
    for aux2:=0 to 7 do
    begin
     byte1:=tiledi[(aux1*8)+aux2];
     asm shl byte2,1; mov al,byte2; or al,byte1; mov byte2,al; end;
    end;
    archsal.salbyte:=byte2;
    write(salarch,archsal);
   end;

   largo1:=largo1+32;
  until largo1>=largo2;
 end






 else         {insertar}
 begin
  writeln;
  writeln;
  writeln;
  writeln('(all values must be in decimal)');
  writeln;
  write('Input SMS file: ');
  readln(nomarchent);
  write('Insert in Genesis rom: ');
  readln(nomarchsal);
  write('Address: ');
  readln(largo1);
  writeln;

  assign(entarch,nomarchent);
  reset(entarch);
  assign(salarch,nomarchsal);
  reset(salarch);
  seek(salarch,largo1);

  repeat
  for aux1:=0 to 31 do      {llenar tiledi}
  begin
   if eof(entarch) then comoquiere:='F'
    else read(entarch,archent);
   byte1:=archent.entbyte;
   byte2:=byte1;
   asm and byte2,1; end;
   tiledi[(aux1*8)+7]:=byte2;
   byte2:=byte1;
   asm shr byte2,1; and byte2,1; end;
   tiledi[(aux1*8)+6]:=byte2;
   byte2:=byte1;
   asm shr byte2,1; shr byte2,1; and byte2,1; end;
   tiledi[(aux1*8)+5]:=byte2;
   byte2:=byte1;
   asm shr byte2,1; shr byte2,1; shr byte2,1; and byte2,1; end;
   tiledi[(aux1*8)+4]:=byte2;
   byte2:=byte1;
   asm shr byte2,1; shr byte2,1;
    shr byte2,1; shr byte2,1; and byte2,1; end;
   tiledi[(aux1*8)+3]:=byte2;
   byte2:=byte1;
   asm shr byte2,1; shr byte2,1; shr byte2,1;
    shr byte2,1;shr byte2,1; and byte2,1; end;
   tiledi[(aux1*8)+2]:=byte2;
   byte2:=byte1;
   asm shr byte2,1; shr byte2,1; shr byte2,1;
    shr byte2,1; shr byte2,1; shr byte2,1; and byte2,1; end;
   tiledi[(aux1*8)+1]:=byte2;
   byte2:=byte1;
   asm shr byte2,1; shr byte2,1; shr byte2,1;
    shr byte2,1; shr byte2,1; shr byte2,1; shr byte2,1; and byte2,1; end;
   tiledi[aux1*8]:=byte2;
  end;


  for aux1:=0 to 7 do   {tiledi a tilefa}
  begin
   for aux2:=0 to 7 do
   begin
    byte1:=tiledi[(aux1*32)+aux2];
    byte2:=byte1;
    byte1:=tiledi[(aux1*32)+8+aux2];
    asm mov al,byte1; shl al,1; or byte2,al; end;
    byte1:=tiledi[(aux1*32)+16+aux2];
    asm mov al,byte1; shl al,1; shl al,1; or byte2,al; end;
    byte1:=tiledi[(aux1*32)+24+aux2];
    asm mov al,byte1; shl al,1; shl al,1; shl al,1; or byte2,al; end;
    tilefa[(aux1*8)+aux2]:=byte2;
   end;
  end;

  for aux1:=0 to 31 do
  begin
   byte1:=tilefa[aux1*2];
   byte2:=tilefa[(aux1*2)+1];
   asm mov al,byte1; shl al,1; shl al,1; shl al,1; shl al,1; or byte2,al; end;
   archsal.salbyte:=byte2;
   if comoquiere<>'F' then write(salarch,archsal);
  end;
  until comoquiere='F';
 end;


 close(entarch);
 close(salarch);
 writeln;
 writeln;
 writeln('Done');

End.
