IIRC *.sna
fileformat originated from FDC/FDD peripherials I have this one:
which was a FDC+FDD for 48K ZXS using MDOS ... there was no 16K or 128K support. The 128K support was added years later but I never heard of 16K...
If it helps here are save/load routines (C++/VCL) from my emulator (I wrote years ago):
//---------------------------------------------------------------------------
void ZXSpectrum::load_sna(AnsiString name)
{
BYTE dat[27];
int hnd,siz;
reset();
hnd=FileOpen(name,fmOpenRead);
if (hnd<0) return;
siz=FileSeek(hnd,0,2);
FileSeek(hnd,0,0);
if (siz== 49179) set_model(_ZXSpectrum_model_48K);
if (siz==131103) set_model(_ZXSpectrum_model_128K);
if (siz<27) { FileClose(hnd); return; }
FileRead(hnd,dat,27);
int adr=0;
cpu.reg.r8.i=dat[adr]; adr++;
cpu.reg.r8._l=dat[adr]; adr++;
cpu.reg.r8._h=dat[adr]; adr++;
cpu.reg.r8._e=dat[adr]; adr++;
cpu.reg.r8._d=dat[adr]; adr++;
cpu.reg.r8._c=dat[adr]; adr++;
cpu.reg.r8._b=dat[adr]; adr++;
cpu.reg.r8._f=dat[adr]; adr++;
cpu.reg.r8._a=dat[adr]; adr++;
cpu.reg.r8.l=dat[adr]; adr++;
cpu.reg.r8.h=dat[adr]; adr++;
cpu.reg.r8.e=dat[adr]; adr++;
cpu.reg.r8.d=dat[adr]; adr++;
cpu.reg.r8.c=dat[adr]; adr++;
cpu.reg.r8.b=dat[adr]; adr++;
cpu.reg.r8.iyl=dat[adr]; adr++;
cpu.reg.r8.iyh=dat[adr]; adr++;
cpu.reg.r8.ixl=dat[adr]; adr++;
cpu.reg.r8.ixh=dat[adr]; adr++;
cpu.iff2=0; if (BYTE(dat[adr]&4)!=0) cpu.iff2=1; adr++;
cpu.reg.r8.r=dat[adr]; adr++;
cpu.reg.r8.f=dat[adr]; adr++;
cpu.reg.r8.a=dat[adr]; adr++;
cpu.reg.r8.spl=dat[adr]; adr++;
cpu.reg.r8.sph=dat[adr]; adr++;
cpu.im=dat[adr]; adr++;
port_wr(254,dat[adr]); adr++;
if (siz== 49179)
{
load_48k(hnd,16384, 48*1024);
union { BYTE db[2]; WORD dw; } ubw; //retn
ubw.db[0]=mem_rd(cpu.reg.r16.sp);
cpu.reg.r16.sp++;
ubw.db[1]=mem_rd(cpu.reg.r16.sp);
cpu.reg.r16.sp++;
cpu.reg.r16.pc=ubw.dw;
cpu.iff1=cpu.iff2;
enable_bank_switching=false;
}
if (siz==131103)
{
int i,n;
BYTE q;
load_128k(hnd,5,16384);
load_128k(hnd,2,16384);
FileSeek(hnd,49179,0);
FileRead(hnd,&cpu.reg.r16.pc,2);
FileRead(hnd,&q,1); port_wr(0x7FFD,q); n=rambank;
FileRead(hnd,&q,1); // if (q) rom=TRDOS
FileSeek(hnd,32795,0);
load_128k(hnd,n,16384);
FileSeek(hnd,49183,0);
for (i=0;i<8;i++)
{
if (i==n) continue;
if (i==5) continue;
if (i==2) continue;
load_128k(hnd,i,16384);
}
cpu.iff1=cpu.iff2;
}
FileClose(hnd);
}
//---------------------------------------------------------------------------
void ZXSpectrum::save_sna(AnsiString name)
{
BYTE origstackL,origstackH;
BYTE dat[27];
int hnd,siz;
hnd=FileCreate(name);
if (hnd<0) return;
if ((model==_ZXSpectrum_model_48K)
||(model==_ZXSpectrum_model_RAM64K)
||(model==_ZXSpectrum_model_GAMA_87)
||(model==_ZXSpectrum_model_GAMA_88)
||(model==_ZXSpectrum_model_GAMA_89)
||(model==_ZXSpectrum_model_M)
||(model==_ZXSpectrum_model_KOMPAKT))
{
siz= 49179;
union { BYTE db[2]; WORD dw; } ubw; //(retn)^-1
ubw.dw=cpu.reg.r16.pc; // change stack to return from interrupt to start adress (PC)
cpu.reg.r16.sp--;
origstackH=mem_rd(cpu.reg.r16.sp);
mem_wr(cpu.reg.r16.sp,ubw.db[1]);
cpu.reg.r16.sp--;
origstackL=mem_rd(cpu.reg.r16.sp);
mem_wr(cpu.reg.r16.sp,ubw.db[0]);
}
if ((model==_ZXSpectrum_model_128K)
||(model==_ZXSpectrum_model_128K_2)
||(model==_ZXSpectrum_model_128K_2A)
||(model==_ZXSpectrum_model_128K_3))
{
siz=131103;
}
int adr=0;
dat[adr]=cpu.reg.r8.i ; adr++;
dat[adr]=cpu.reg.r8._l ; adr++;
dat[adr]=cpu.reg.r8._h ; adr++;
dat[adr]=cpu.reg.r8._e ; adr++;
dat[adr]=cpu.reg.r8._d ; adr++;
dat[adr]=cpu.reg.r8._c ; adr++;
dat[adr]=cpu.reg.r8._b ; adr++;
dat[adr]=cpu.reg.r8._f ; adr++;
dat[adr]=cpu.reg.r8._a ; adr++;
dat[adr]=cpu.reg.r8.l ; adr++;
dat[adr]=cpu.reg.r8.h ; adr++;
dat[adr]=cpu.reg.r8.e ; adr++;
dat[adr]=cpu.reg.r8.d ; adr++;
dat[adr]=cpu.reg.r8.c ; adr++;
dat[adr]=cpu.reg.r8.b ; adr++;
dat[adr]=cpu.reg.r8.iyl ; adr++;
dat[adr]=cpu.reg.r8.iyh ; adr++;
dat[adr]=cpu.reg.r8.ixl ; adr++;
dat[adr]=cpu.reg.r8.ixh ; adr++;
if (cpu.iff2) dat[adr]|=4; adr++;
dat[adr]=cpu.reg.r8.r ; adr++;
dat[adr]=cpu.reg.r8.f ; adr++;
dat[adr]=cpu.reg.r8.a ; adr++;
dat[adr]=cpu.reg.r8.spl ; adr++;
dat[adr]=cpu.reg.r8.sph ; adr++;
dat[adr]=cpu.im ; adr++;
dat[adr]=port00FE ; adr++;
FileWrite(hnd,dat,27);
if (siz== 49179)
{
save_48k(hnd,16384, 48*1024);
mem_wr(cpu.reg.r16.sp,origstackL); // restore stack to original state
cpu.reg.r16.sp++;
mem_wr(cpu.reg.r16.sp,origstackH);
cpu.reg.r16.sp++;
}
if (siz==131103)
{
int i,n;
BYTE q;
save_128k(hnd,5,16384);
save_128k(hnd,2,16384);
save_128k(hnd,rambank,16384);
FileWrite(hnd,&cpu.reg.r16.pc,2);
FileWrite(hnd,&port7FFD,1);
q=0; // if (q) rom=TRDOS
FileWrite(hnd,&q,1);
for (i=0;i<8;i++)
{
if (i==rambank) continue;
if (i==5) continue;
if (i==2) continue;
save_128k(hnd,i,16384);
}
}
FileClose(hnd);
}
//---------------------------------------------------------------------------