Browse Source

Better ZMODEM compatibility (tested w/ lrzsz, SEXYZ)

master
Alec Murphy 4 years ago
parent
commit
c7c826159c
  1. 164
      Load.HC
  2. 51
      ZModem.HC

164
Load.HC

@ -24,6 +24,8 @@ U8 *rz_fbuf;
U8 *rz_filename;
U8 *rz_shortfn;
I64 rz_xctr=0;
I64 rz_bufpos=0;
I64 rzp_type=0;
@ -89,9 +91,14 @@ U0 TempleTermSession(I64 sock)
I64 rz_totalleft=0;
I64 rz_filetime=0;
I64 rz_filemode=0;
I64 rz_pktctr=0;
I64 rz_pos=0;
I64 rz_serial=0;
U32 crc=0;
U32 crc_len=0;
I64 seq_type=0;
DCFill(tt_buf,tt_cur_bg);
tt_buf->color=tt_cur_fg;
@ -109,6 +116,7 @@ U0 TempleTermSession(I64 sock)
I64 bold;
U32 rz_dpos;
U32 rz_opos;
U8 *rx_buf=CAlloc(1024);
U8 *ad_seq=CAlloc(6);
@ -146,6 +154,18 @@ U0 TempleTermSession(I64 sock)
while (pos<got)
{
// Quick and dirty way to eat XON? yummm
if (IN_ZDLE==3)
{
IN_ZDLE--;
};
if (in_rz>0){
if (rx_buf[pos]==XON)
{
IN_ZDLE=3;
};
};
if (IN_ZDLE==1)
{
rx_buf[pos] ^= 0x40;
@ -173,8 +193,6 @@ U0 TempleTermSession(I64 sock)
tt_buf->color=tt_cur_fg;
};
// send(sock, zmr_abort, 5, 0);
if (abort_rz==1)
{
send(sock, zmr_abort, 5, 0);
@ -189,12 +207,13 @@ U0 TempleTermSession(I64 sock)
if (in_rz==20)
{
// EOF
progress1=rz_dpos;
StrPrint(progress1_desc, "Saving File: %s", rz_shortfn);
FileWrite(rz_filename, rz_fbuf, rz_filesize);
Free(rz_fbuf);
Snd(62);Sleep(50);Snd(74);Sleep(50);SndRst;
ProgressBarsRst;
sendHexHeader(sock, ZRINIT, (CANFC32|CANFDX|CANOVIO) );
sendHexHeader(sock, ZRINIT, 0, 0, 0, (CANFDX|CANOVIO) );
in_rz=2;
rzb_state=0;
};
@ -203,7 +222,70 @@ U0 TempleTermSession(I64 sock)
if (in_rz==7)
{
// ZDATA, cont...:
if (rz_ibpos==0)
{
// Get ZDLE sequence
seq_type = rx_buf[pos]^0x40;
// Calculate CRC16
crc = getCRC16(rz_ibuf, crc_len);
crc = crc16Update(crc, seq_type);
};
if (rz_ibpos==1)
{
if (rx_buf[pos]!=((crc >> 8) & 0xFF))
{
rz_dpos = rz_opos;
sendHexHeader(sock, ZRPOS, rz_dpos.u8[3], rz_dpos.u8[2], rz_dpos.u8[1], rz_dpos.u8[0]);
in_rz=2;
rzb_state=0;
rz_bufpos=0;
rz_ibpos=0;
break;
//AdamLog("Pkt %d: \dRED\dBad CRC\dBLUE\d MSB %02X Got: %02X\n", rz_pktctr,((crc >> 8) & 0xFF),rx_buf[pos]);
}
else
{
};
};
if (rz_ibpos==2)
{
if (rx_buf[pos]!=(crc & 0xFF))
{
rz_dpos = rz_opos;
sendHexHeader(sock, ZRPOS, rz_dpos.u8[3], rz_dpos.u8[2], rz_dpos.u8[1], rz_dpos.u8[0]);
in_rz=2;
rzb_state=0;
rz_bufpos=0;
rz_ibpos=0;
break;
//AdamLog("Pkt %d: \dRED\dBad CRC\dBLUE\d MSB %02X Got: %02X\n", rz_pktctr,((crc >> 8) & 0xFF),rx_buf[pos]);
}
else
{
};
// If ZCRCQ or ZCRCW, need to ack.
if (seq_type==ZCRCQ || seq_type==ZCRCW)
{
sendHexHeader(sock, ZACK, rz_dpos.u8[0], rz_dpos.u8[1], rz_dpos.u8[2], rz_dpos.u8[3]);
in_rz=2;
rzb_state=0;
break;
};
};
if (rz_ibpos==3)
{
progress1=rz_dpos;
};
// get length of subpacket
if (rz_fileleft<1024)
{
rz_dfmax=rz_fileleft;
@ -213,14 +295,13 @@ U0 TempleTermSession(I64 sock)
rz_dfmax=1024;
};
// copy bytestream to tha buffah
if (rz_ibpos>2) {
rz_ibuf[rz_bufpos] = rx_buf[pos];
if (rz_bufpos<(rz_dfmax))
{
rz_bufpos++;
progress1++;
};
};
rz_ibpos++;
@ -229,17 +310,21 @@ U0 TempleTermSession(I64 sock)
{
rz_fileleft -= rz_dfmax;
MemCpy(rz_fbuf+rz_dpos, rz_ibuf,rz_dfmax);
MemCpy(rz_fbuf+rz_dpos, rz_ibuf, rz_dfmax);
rz_opos = rz_dpos;
rz_dpos += rz_dfmax;
if (rz_fileleft<=0)
{
in_rz=20;
in_rz=2;
}
else
{
crc_len=rz_dfmax;
rz_ibpos=0;
rz_bufpos=0;
rz_pktctr++;
};
};
@ -248,8 +333,9 @@ U0 TempleTermSession(I64 sock)
if (in_rz==6)
{
// ZDATA:
// ZDATA, begin:
// get length of subpacket
if (rz_fileleft<1024)
{
rz_dfmax=rz_fileleft;
@ -259,12 +345,12 @@ U0 TempleTermSession(I64 sock)
rz_dfmax=1024;
};
// copy bytestream to tha buffah
if (rz_ibpos>5) {
rz_ibuf[rz_bufpos] = rx_buf[pos];
if (rz_bufpos<(rz_dfmax))
{
rz_bufpos++;
progress1++;
};
};
@ -276,17 +362,21 @@ U0 TempleTermSession(I64 sock)
rz_fileleft -= rz_dfmax;
MemCpy(rz_fbuf+rz_dpos, rz_ibuf,rz_dfmax);
rz_opos = rz_dpos;
rz_dpos += rz_dfmax;
if (rz_fileleft<=0)
{
rz_remainfiles--;
in_rz=20;
in_rz=2;
}
else
{
crc_len=rz_dfmax;
rz_ibpos=0;
rz_bufpos=0;
rz_pktctr++;
in_rz++;
};
@ -333,8 +423,10 @@ U0 TempleTermSession(I64 sock)
progress4_max=0;
progress1_t0=0;
progress1_tf=0;
rz_pktctr=0;
rz_pos=0;
rz_dpos=0;
rz_opos=0;
sendHexHeader(sock, ZRPOS, rz_pos.u8[3], rz_pos.u8[2], rz_pos.u8[1], rz_pos.u8[0]);
in_rz=2;
rzb_state=0;
@ -381,15 +473,32 @@ U0 TempleTermSession(I64 sock)
case 0x30:
// wait next pass...
break;
case 0x30 + ZFIN:
sendHexHeader(sock, ZFIN);
in_rz=0;
DETECT_ZDLE=0;
IN_ZDLE=0;
break;
// sexyz?! you slag
case 'b': // ZEOF?
rz_ibpos=0;
rzb_state=0;
if (rz_fileleft<=0)
{
in_rz=20;
}
else
{
in_rz=2;
};
break;
default:
AdamLog("\n%02X",rx_buf[pos]);
PopUpOk("ERROR: Unknown type, aborting...");
PopUpOk("ERROR: Unknown HEX type, aborting...");
progress1=0;progress1_max=0;
send(sock, zmr_abort, 5, 0);
in_rz=0;
@ -397,6 +506,7 @@ U0 TempleTermSession(I64 sock)
IN_ZDLE=0;
break;
};
}
if (rzp_type==ZBIN)
@ -418,16 +528,22 @@ U0 TempleTermSession(I64 sock)
break;
case ZEOF:
// ignore ZEOF, we will send ZRINIT when
// file transfer is complete.
rz_ibpos=0;
in_rz=2;
rz_ibpos=0;
rzb_state=0;
if (rz_fileleft<=0)
{
in_rz=20;
}
else
{
in_rz=2;
};
break;
default:
AdamLog("\n%02X",rx_buf[pos]);
PopUpOk("ERROR: Unknown type, aborting...");
PopUpOk("ERROR: Unknown BIN type, aborting...");
progress1=0;progress1_max=0;
send(sock, zmr_abort, 5, 0);
in_rz=0;
@ -444,15 +560,13 @@ U0 TempleTermSession(I64 sock)
{
DETECT_ZDLE=0;
IN_ZDLE=0;
// Hang around and wait for a packet...
};
if (in_rz==1)
{
// ZModem Receive detect: Got ZRQINIT, send ZRINIT
sendHexHeader(sock, ZRINIT, (CANFC32|CANFDX|CANOVIO) );
sendHexHeader(sock, ZRINIT, 0, 0, 0, (CANFDX|CANOVIO) );
in_rz=2;
rzb_state=0;
};
@ -729,6 +843,7 @@ U0 TempleTermSession(I64 sock)
{
rzp_type=ZHEX;
in_esc=0;
rz_xctr=0;
in_rz++;
};
rzh_state=0;
@ -755,8 +870,8 @@ U0 TempleTermSession(I64 sock)
{
if (in_rz>1 && in_rz<3)
{
DETECT_ZDLE=1;
rzp_type=ZBIN;
DETECT_ZDLE=1;
in_esc=0;
in_rz++;
};
@ -821,7 +936,6 @@ I64 TempleTermConnect(U8 *host, I64 port=23)
Fs->draw_it=&TDrawIt;
CTask *session = Spawn(&TempleTermSession,sock,"TempleTermSession",,Fs);
while (TRUE)
{
sx_u8[0]=0;
@ -830,12 +944,12 @@ I64 TempleTermConnect(U8 *host, I64 port=23)
if (in_rz>0)
{
if (key==27)
 {
{
abort_rz=1;
};
};
if (in_rz==0)
if (in_rz==0 || abort_rz==1)
{
// Send username
if ((kbd.scan_code & 0xFFFF) == 2070)

51
ZModem.HC

@ -2,6 +2,10 @@
// Defines
#define RZ_TIMEOUT 1000000
#define XON 0x11
#define ZPAD '*'
#define ZBIN 'A'
#define ZHEX 'B'
@ -130,11 +134,6 @@ U32 crc32Update(U32 crc, U32 ch)
return a ^ b;
}
U32 crc32Vale(U32 crc)
{
return crc;
}
U8 crc32Byte1(U32 crc)
{
return ((((crc)) >> 24) & 0xff);
@ -155,9 +154,9 @@ U8 crc32Byte4(U32 crc)
return (((crc)) & 0xff);
}
// CRCXM
// CRC16
U16 crcxm_tab[256] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
U16 crc16_tab[256] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
@ -190,30 +189,25 @@ U16 crcxm_tab[256] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0};
U16 crcxmInit()
U16 crc16Init()
{
return 0;
}
U16 crcxmUpdate(U16 crc, U16 ch)
U16 crc16Update(U16 crc, U8 ch)
{
U16 a = (((crc) & 0xff) << 8);
U16 i = ch ^ (crc >> 8);
U16 b = crcxm_tab[i];
U16 b = crc16_tab[i];
return a ^ b;
}
U16 crcxmVale(U16 crc)
{
return crc;
}
U8 crcxmLowbyte(U16 crc)
U8 crc16Lowbyte(U16 crc)
{
return crc & 0xff;
}
U8 crcxmHighbyte(U16 crc)
U8 crc16Highbyte(U16 crc)
{
return (crc >> 8) & 0xff;
}
@ -225,18 +219,16 @@ U16 getHexChar(I64 idx)
return (256*(hexdigit[((idx) >> 4) & 0x0F])) + hexdigit[idx & 0x0F];
}
U16 getCRCXM(U8 *buf, I64 len)
I64 getCRC16(U8 *buf, I64 len)
{
U16 crc=crcxmInit;
I64 crc=crc16Init;
I64 pos=0;
while (pos<len)
{
crc = crcxmUpdate(crc, buf[pos]);
crc = crc16Update(crc, buf[pos]);
pos++;
};
I64 high=crcxmHighbyte(crc);
I64 low=crcxmHighbyte(crc);
return (256*getHexChar(high)) +getHexChar(low);
return crc;
}
I64 PutHex(U8 *data, I64 index, U8 b)
@ -262,9 +254,8 @@ I64 PutHex(U8 *data, I64 index, U8 b)
return (index);
}
//U0 sendHexHeader(I64 sock, U8 hdr_type, U32 num=0, U8 ZP0=0, U8 ZP1=0, U8 ZP2=0, U8 ZP3=0)
U0 sendHexHeader(I64 sock, U8 hdr_type, U8 ZP0=0, U8 ZP1=0, U8 ZP2=0, U8 ZP3=0)
{
{
U8 *hdr=CAlloc(32);
hdr[0] = ZPAD;
@ -274,15 +265,15 @@ U0 sendHexHeader(I64 sock, U8 hdr_type, U8 ZP0=0, U8 ZP1=0, U8 ZP2=0, U8 ZP3=0)
I64 index = 4;
index = PutHex(hdr, index, hdr_type);
U16 crc = crcxmUpdate(crcxmInit, hdr_type);
U16 crc = crc16Update(crc16Init, hdr_type);
index = PutHex(hdr, index, ZP0);
crc = crcxmUpdate(crc, ZP0);
crc = crc16Update(crc, ZP0);
index = PutHex(hdr, index, ZP1);
crc = crcxmUpdate(crc, ZP1);
crc = crc16Update(crc, ZP1);
index = PutHex(hdr, index, ZP2);
crc = crcxmUpdate(crc, ZP2);
crc = crc16Update(crc, ZP2);
index = PutHex(hdr, index, ZP3);
crc = crcxmUpdate(crc, ZP3);
crc = crc16Update(crc, ZP3);
index = PutHex(hdr, index, (crc >> 8)(U8));
index = PutHex(hdr, index, (crc)(U8));

Loading…
Cancel
Save