Browse Source

Initial support for ZMODEM receive

master
Alec Murphy 4 years ago
parent
commit
9f0ba2775f
  1. 94
      Bookmarks.HC
  2. 518
      Load.HC
  3. 2
      README.md
  4. 2
      Run.HC
  5. 303
      ZModem.HC

94
Bookmarks.HC

@ -0,0 +1,94 @@
#define TT_MAX_ENTRIES 64
class TTConnEntryForm
{
U8 name[STR_LEN] format "$$DA-P,A=\"Name:%s\"$$\n";
U8 host[STR_LEN] format "$$DA-P,A=\"Host:%s\"$$\n";
I64 port format "$$DA,A=\"Port:%d\"$$\n";
U8 user[STR_LEN] format "$$DA-P,A=\"Username:%s\"$$\n";
U8 pass[STR_LEN] format "$$DA-P,A=\"Password:%s\"$$\n";
};
class TTConnEntry {
U8 name[STR_LEN];
U8 host[STR_LEN];
I64 port;
U8 user[STR_LEN];
U8 pass[STR_LEN];
};
TTConnEntry *conn_entries;
TTConnEntry *conn_rc_entries;
TTConnEntryForm *add_form;
TTConnEntryForm *edit_form;
I64 conn_len=0;
I64 conn_idx=0;

U8 *conn_list;
U8 *conn_edlist;
U0 ConnEntriesRecalc()
{
I64 oi=0;
I64 ri=0;
I64 p=0;
while (p<sizeof(TTConnEntry)*TT_MAX_ENTRIES)
{
conn_list[p]=0;
conn_edlist[p]=0;
conn_rc_entries(U8*)[p]=0;
p++;
};
while (oi<TT_MAX_ENTRIES)
{
if (conn_entries[oi].port>0)
{
StrPrint(conn_rc_entries[ri].name,conn_entries[oi].name);
StrPrint(conn_rc_entries[ri].host,conn_entries[oi].host);
conn_rc_entries[ri].port=conn_entries[oi].port;
StrPrint(conn_rc_entries[ri].user,conn_entries[oi].user);
StrPrint(conn_rc_entries[ri].pass,conn_entries[oi].pass);
ri++;
};
oi++;
};
MemCpy(conn_entries, conn_rc_entries, sizeof(TTConnEntry)*TT_MAX_ENTRIES);
conn_idx=0;
conn_len=0;
while (conn_idx<TT_MAX_ENTRIES)
{
if (conn_entries[conn_idx].port>0)
{
StrPrint(conn_list+conn_len,conn_entries[conn_idx].name);
StrPrint(conn_edlist+conn_len,conn_entries[conn_idx].name);
conn_len+=StrLen(conn_entries[conn_idx].name)+1;
conn_idx++;
}
else
{
break;
};
}
StrPrint(conn_list+conn_len,"Add Entry");
conn_len+=StrLen("Add Entry")+1;
conn_idx++;
StrPrint(conn_list+conn_len,"Delete Entry");
conn_len+=StrLen("Delete Entry")+1;
conn_idx++;
StrPrint(conn_list+conn_len,"Edit Entry");
conn_len+=StrLen("Edit Entry")+1;
conn_idx++;
}

518
TempleTerm.HC → Load.HC

@ -1,4 +1,8 @@
#define TT_MAX_ENTRIES 64
#include "::/Apps/TempleTerm/Bookmarks"
#include "::/Apps/TempleTerm/ZModem"
I64 in_rz=0;
I64 abort_rz=0;
#define TT_CFG_FILE "Bookmarks.DATA.Z"
#define TT_CFG_PATH "::/Home/TempleTerm"
@ -10,100 +14,23 @@ I64 tt_cur_bg=BLACK;
I64 tt_cur_fg=WHITE;
I64 tt_cur_int=0;
I64 conn_len=0;
I64 conn_idx=0;
I64 res=0;
class TTConnEntryForm
{
U8 name[STR_LEN] format "$$DA-P,A=\"Name:%s\"$$\n";
U8 host[STR_LEN] format "$$DA-P,A=\"Host:%s\"$$\n";
I64 port format "$$DA,A=\"Port:%d\"$$\n";
U8 user[STR_LEN] format "$$DA-P,A=\"Username:%s\"$$\n";
U8 pass[STR_LEN] format "$$DA-P,A=\"Password:%s\"$$\n";
};
class TTConnEntry {
U8 name[STR_LEN];
U8 host[STR_LEN];
I64 port;
U8 user[STR_LEN];
U8 pass[STR_LEN];
};
TTConnEntry *conn_entries;
TTConnEntry *conn_rc_entries;
TTConnEntryForm *add_form;
TTConnEntryForm *edit_form;
U8 *conn_list;
U8 *conn_edlist;
U0 ConnEntriesRecalc()
{
I64 oi=0;
I64 ri=0;
I64 p=0;
while (p<sizeof(TTConnEntry)*TT_MAX_ENTRIES)
{
conn_list[p]=0;
conn_edlist[p]=0;
conn_rc_entries(U8*)[p]=0;
p++;
};
while (oi<TT_MAX_ENTRIES)
{
if (conn_entries[oi].port>0)
{
StrPrint(conn_rc_entries[ri].name,conn_entries[oi].name);
StrPrint(conn_rc_entries[ri].host,conn_entries[oi].host);
conn_rc_entries[ri].port=conn_entries[oi].port;
StrPrint(conn_rc_entries[ri].user,conn_entries[oi].user);
StrPrint(conn_rc_entries[ri].pass,conn_entries[oi].pass);
ri++;
};
oi++;
 };
MemCpy(conn_entries, conn_rc_entries, sizeof(TTConnEntry)*TT_MAX_ENTRIES);
conn_idx=0;
conn_len=0;
while (conn_idx<TT_MAX_ENTRIES)
{
if (conn_entries[conn_idx].port>0)
{
StrPrint(conn_list+conn_len,conn_entries[conn_idx].name);
StrPrint(conn_edlist+conn_len,conn_entries[conn_idx].name);
conn_len+=StrLen(conn_entries[conn_idx].name)+1;
conn_idx++;
}
else
{
break;
};
}
I64 rzh_seq[4] = { ZPAD,ZPAD,ZDLE,ZHEX };
I64 rzb_seq[3] = { ZPAD,ZDLE,ZBIN };
StrPrint(conn_list+conn_len,"Add Entry");
conn_len+=StrLen("Add Entry")+1;
conn_idx++;
U8 *rz_ibuf;
U8 *rz_fbuf;
U8 *rz_filename;
U8 *rz_shortfn;
StrPrint(conn_list+conn_len,"Delete Entry");
conn_len+=StrLen("Delete Entry")+1;
conn_idx++;
I64 rz_bufpos=0;
I64 rzp_type=0;
StrPrint(conn_list+conn_len,"Edit Entry");
conn_len+=StrLen("Edit Entry")+1;
conn_idx++;
I64 rzh_state=0;
I64 rzb_state=0;
}
U8 zmr_abort[5] = { ZDLE,ZDLE,ZDLE,ZDLE,ZDLE };
I64 isArrow()
{
@ -146,6 +73,24 @@ U0 TDrawIt(CTask *,CDC *dc)
U0 TempleTermSession(I64 sock)
{
CDC *tt_buf2=DCNew(640,480);
rz_ibuf=CAlloc(2048);
rz_filename=CAlloc(1024);
rz_shortfn=CAlloc(1024);
I64 DETECT_ZDLE=0;
I64 IN_ZDLE=0;
I64 rz_ibpos=0;
I64 rz_dfmax=0;
I64 rz_filesize=0;
I64 rz_remainfiles=0;
I64 rz_fileleft=0;
I64 rz_totalleft=0;
I64 rz_filetime=0;
I64 rz_filemode=0;
I64 rz_pos=0;
I64 rz_serial=0;
DCFill(tt_buf,tt_cur_bg);
tt_buf->color=tt_cur_fg;
@ -159,9 +104,12 @@ U0 TempleTermSession(I64 sock)
I64 sp_bg=0;
I64 sp_fg=0;
I64 j,k,l;
I64 bold;
U32 rz_dpos;
U8 *rx_buf=CAlloc(1024);
U8 *ad_seq=CAlloc(6);
U8 cpos_buf[64];
@ -178,6 +126,9 @@ U0 TempleTermSession(I64 sock)
bold=0;
U8 ich[2];
ich[1]=0;
I64 got, pos;
while (TRUE)
{
@ -193,6 +144,25 @@ U0 TempleTermSession(I64 sock)
pos=0;
while (pos<got)
{
if (IN_ZDLE==1)
{
rx_buf[pos] ^= 0x40;
IN_ZDLE++;
};
if (DETECT_ZDLE==1 && IN_ZDLE<1)
{
if (rx_buf[pos]==ZDLE) { IN_ZDLE++; };
};
if (IN_ZDLE==2)
{
IN_ZDLE=0;
};
if (IN_ZDLE<1)
{
if(pos==0)
@ -203,6 +173,290 @@ 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);
ProgressBarsRst;
Snd(42);Sleep(100);Snd(32);Sleep(100);SndRst;
in_rz=0;
DETECT_ZDLE=0;
IN_ZDLE=0;
abort_rz=0;
};
if (in_rz==20)
{
// EOF
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) );
in_rz=2;
rzb_state=0;
};
if (in_rz==7)
{
// ZDATA, cont...:
if (rz_fileleft<1024)
{
rz_dfmax=rz_fileleft;
}
else
{
rz_dfmax=1024;
};
if (rz_ibpos>2) {
rz_ibuf[rz_bufpos] = rx_buf[pos];
if (rz_bufpos<(rz_dfmax))
{
rz_bufpos++;
progress1++;
};
};
rz_ibpos++;
if (rz_ibpos==rz_dfmax+3)
{
rz_fileleft -= rz_dfmax;
MemCpy(rz_fbuf+rz_dpos, rz_ibuf,rz_dfmax);
rz_dpos += rz_dfmax;
if (rz_fileleft<=0)
{
in_rz=20;
}
else
{
rz_ibpos=0;
rz_bufpos=0;
};
};
};
if (in_rz==6)
{
// ZDATA:
if (rz_fileleft<1024)
{
rz_dfmax=rz_fileleft;
}
else
{
rz_dfmax=1024;
};
if (rz_ibpos>5) {
rz_ibuf[rz_bufpos] = rx_buf[pos];
if (rz_bufpos<(rz_dfmax))
{
rz_bufpos++;
progress1++;
};
};
rz_ibpos++;
if (rz_ibpos==rz_dfmax+6)
{
rz_fileleft -= rz_dfmax;
MemCpy(rz_fbuf+rz_dpos, rz_ibuf,rz_dfmax);
rz_dpos += rz_dfmax;
if (rz_fileleft<=0)
{
rz_remainfiles--;
in_rz=20;
}
else
{
rz_ibpos=0;
rz_bufpos=0;
in_rz++;
};
};
};
if (in_rz==5)
{
// FILEINFO: get fileinfo
if (rx_buf[pos] == 32)
{
rz_ibuf[rz_ibpos]=0;
}
else
{
rz_ibuf[rz_ibpos]=rx_buf[pos];
};
if (rx_buf[pos] == 0)
{
rz_filesize = Str2I64(rz_ibuf);
rz_ibpos = StrLen(rz_ibuf)+1;
rz_filetime = Str2I64(rz_ibuf+rz_ibpos);
rz_ibpos += StrLen(rz_ibuf+rz_ibpos) + 1;
rz_filemode = Str2I64(rz_ibuf+rz_ibpos);
rz_ibpos += StrLen(rz_ibuf+rz_ibpos) + 1;
rz_serial = Str2I64(rz_ibuf+rz_ibpos);
rz_ibpos += StrLen(rz_ibuf+rz_ibpos) + 1;
rz_remainfiles = Str2I64(rz_ibuf+rz_ibpos);
rz_ibpos += StrLen(rz_ibuf+rz_ibpos) + 1;
rz_totalleft = Str2I64(rz_ibuf+rz_ibpos);
rz_ibpos += StrLen(rz_ibuf+rz_ibpos) + 1;
rz_fileleft = rz_filesize;
// allocate buffer, set pos to 0, and start receiving...
rz_fbuf=CAlloc(rz_filesize);
StrPrint(progress1_desc, "ZMODEM Receive: %s (%d files remaining)", rz_shortfn, rz_remainfiles-1);
progress1=0;
progress1_max=rz_filesize;
progress2_max=0;
progress3_max=0;
progress4_max=0;
progress1_t0=0;
progress1_tf=0;
rz_pos=0;
rz_dpos=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;
rz_ibpos=-1;
};
rz_ibpos++;
};
if (in_rz==4)
{
// FILEINFO: get filename
if (rx_buf[pos] == 0 && rz_ibpos>5)
{
rz_ibuf[rz_ibpos-6]=0;
StrPrint(rz_shortfn, rz_ibuf);
StrPrint(rz_filename, "::/Home/TempleTerm/Downloads/%s",rz_ibuf);
in_rz++;
rz_ibpos=-1;
};
if (rz_ibpos>5)
{
if (rx_buf[pos]=='/')
{
rz_ibuf[rz_ibpos-6]='.';
}
else
{
rz_ibuf[rz_ibpos-6]=rx_buf[pos];
};
};
rz_ibpos++;
};
if (in_rz==3)
{
// Process packet
if (rzp_type==ZHEX)
{
switch(rx_buf[pos])
{
case 0x30:
// wait next pass...
break;
case 0x30 + ZFIN:
sendHexHeader(sock, ZFIN);
in_rz=0;
DETECT_ZDLE=0;
IN_ZDLE=0;
break;
default:
AdamLog("\n%02X",rx_buf[pos]);
PopUpOk("ERROR: Unknown type, aborting...");
progress1=0;progress1_max=0;
send(sock, zmr_abort, 5, 0);
in_rz=0;
DETECT_ZDLE=0;
IN_ZDLE=0;
break;
};
}
if (rzp_type==ZBIN)
{
DETECT_ZDLE=1;
switch(rx_buf[pos])
{
case ZFILE:
StrPrint(rz_ibuf,"");
rz_ibpos=0;
in_rz++;
break;
case ZDATA:
rz_ibpos=0;
rz_bufpos=0;
in_rz=6;
break;
case ZEOF:
// ignore ZEOF, we will send ZRINIT when
// file transfer is complete.
rz_ibpos=0;
in_rz=2;
rzb_state=0;
break;
default:
AdamLog("\n%02X",rx_buf[pos]);
PopUpOk("ERROR: Unknown type, aborting...");
progress1=0;progress1_max=0;
send(sock, zmr_abort, 5, 0);
in_rz=0;
DETECT_ZDLE=0;
IN_ZDLE=0;
break;
};
};
};
if (in_rz==2)
{
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) );
in_rz=2;
rzb_state=0;
};
if (in_esc==2)
{
ansi_buf[ansi_pos]=0;
@ -409,7 +663,7 @@ U0 TempleTermSession(I64 sock)
ansi_pos++;
}
if (in_esc==0)
if (in_esc==0 && in_rz==0)
{
switch (rx_buf[pos])
{
@ -449,6 +703,64 @@ U0 TempleTermSession(I64 sock)
default:
break;
};
};
if (rzh_state>0)
{
if (rx_buf[pos] == rzh_seq[rzh_state])
{
rzh_state++;
}
else
{
rzh_state=0;
}
};
if (rx_buf[pos] == rzh_seq[rzh_state])
{
rzh_state++;
};
if (rzh_state>3)
{
if (in_rz<3)
{
rzp_type=ZHEX;
in_esc=0;
in_rz++;
};
rzh_state=0;
};
if (rzb_state>0)
{
if (rx_buf[pos] == rzb_seq[rzb_state])
{
rzb_state++;
}
else
{
rzb_state=0;
}
};
if (rx_buf[pos] == rzb_seq[rzb_state])
{
rzb_state++;
};
if (rzb_state>2)
{
if (in_rz>1 && in_rz<3)
{
DETECT_ZDLE=1;
rzp_type=ZBIN;
in_esc=0;
in_rz++;
};
rzb_state=0;
};
// Y-scroll the frame buffer
@ -460,21 +772,23 @@ U0 TempleTermSession(I64 sock)
GrBlot(tt_buf,0,0,tt_buf2);
tt_cur_y--;
};
};
pos++;
// Advance to next pos in rx_buffer
pos++;
};
};
Sleep(1);
};
//PostMsg(Fs->parent_task,MSG_KEY_DOWN_UP,CH_ESC,0);
PostMsg(Fs->parent_task,MSG_KEY_DOWN_UP,255,0);
}
I64 TempleTermConnect(U8 *host, I64 port=23)
{
rzh_state=0;
rzb_state=0;
tt_cur_x=0;
tt_cur_y=0;
tt_cur_bg=BLACK;
@ -513,6 +827,16 @@ I64 TempleTermConnect(U8 *host, I64 port=23)
sx_u8[0]=0;
key=GetChar2(,FALSE);
if (in_rz>0)
{
if (key==27)
 {
abort_rz=1;
};
};
if (in_rz==0)
{
// Send username
if ((kbd.scan_code & 0xFFFF) == 2070)
{
@ -571,7 +895,7 @@ I64 TempleTermConnect(U8 *host, I64 port=23)
{
key=kbd.scan_code & 0xFF;
if (key==SC_F12) { break; };
if (key==SC_F12) { ProgressBarsRst; break; };
if (key==72)
{
@ -605,9 +929,13 @@ I64 TempleTermConnect(U8 *host, I64 port=23)
{
send(sock, sx_u8, 1, 0);
};
};
};
Free(rz_shortfn);
Free(rz_filename);
Free(rz_ibuf);
Kill(session);
close(sock);
Fs->draw_it=NULL;
@ -742,5 +1070,3 @@ U0 Run()
Free(conn_list);
Free(conn_edlist);
}
Run;

2
README.md

@ -3,7 +3,7 @@ BBS ANSI "telnet" Client for TempleOS
![TempleTerm](https://raw.githubusercontent.com/tramplersheikhs/templeterm/master/example.png "TempleTerm")
`#include "TempleTerm";`
`#include "Run";`
`TempleTerm(host,port);`

2
Run.HC

@ -0,0 +1,2 @@
#include "::/Apps/TempleTerm/Load"
Run;

303
ZModem.HC

@ -0,0 +1,303 @@
// replace headertype['ZFILE'],etc. with ZFILE,etc.
// Defines
#define ZPAD '*'
#define ZBIN 'A'
#define ZHEX 'B'
#define ZBIN32 'C'
#define ZDLE 0x18
#define ZCNL 0x02
#define ZCBIN 0x01
// header types
#define ZRQINI 0
#define ZRINIT 1
#define ZSINIT 2
#define ZACK 3
#define ZFILE 4
#define ZSKIP 5
#define ZNAK 6
#define ZABORT 7
#define ZFIN 8
#define ZRPOS 9
#define ZDATA 10
#define ZEOF 11
#define ZFERR 12
#define ZCRC 13
#define ZCHALLENGE 14
#define ZCOMPL 15
#define ZCAN 16
#define ZFREECNT 17
#define ZCOMMAND 18
#define ZSTDERR 19
#define ZCRCE 'h'
#define ZCRCG 'i'
#define ZCRCQ 'j'
#define ZCRCW 'k'
#define ZRUB0 'l'
#define ZRUB1 'm'
#define CANFC32 0x20
#define CANFDX 0x01
#define CANOVIO 0x02
U8 hexdigit[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
//U32 crc;
// CRC32
U32 crc32_tab[256] = {0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
U32 crc32Init()
{
U32 crc;
crc = 0xFFFFFFFF;
return crc;
};
U32 crc32Update(U32 crc, U32 ch)
{
U32 a = ((crc) >> 8);
U32 b = crc32_tab[(((ch) ^ (crc)) & 0xff)];
return a ^ b;
}
U32 crc32Vale(U32 crc)
{
return crc;
}
U8 crc32Byte1(U32 crc)
{
return ((((crc)) >> 24) & 0xff);
}
U8 crc32Byte2(U32 crc)
{
return ((((crc)) >> 16) & 0xff);
}
U8 crc32Byte3(U32 crc)
{
return ((((crc)) >> 8) & 0xff);
}
U8 crc32Byte4(U32 crc)
{
return (((crc)) & 0xff);
}
// CRCXM
U16 crcxm_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,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0};
U16 crcxmInit()
{
return 0;
}
U16 crcxmUpdate(U16 crc, U16 ch)
{
U16 a = (((crc) & 0xff) << 8);
U16 i = ch ^ (crc >> 8);
U16 b = crcxm_tab[i];
return a ^ b;
}
U16 crcxmVale(U16 crc)
{
return crc;
}
U8 crcxmLowbyte(U16 crc)
{
return crc & 0xff;
}
U8 crcxmHighbyte(U16 crc)
{
return (crc >> 8) & 0xff;
}
// Common
U16 getHexChar(I64 idx)
{
return (256*(hexdigit[((idx) >> 4) & 0x0F])) + hexdigit[idx & 0x0F];
}
U16 getCRCXM(U8 *buf, I64 len)
{
U16 crc=crcxmInit;
I64 pos=0;
while (pos<len)
{
crc = crcxmUpdate(crc, buf[pos]);
pos++;
};
I64 high=crcxmHighbyte(crc);
I64 low=crcxmHighbyte(crc);
return (256*getHexChar(high)) +getHexChar(low);
}
I64 PutHex(U8 *data, I64 index, U8 b)
{
if (b <= 0x9F)
{
data[index] = ((b >> 4) + 0x30);
}
else {
data[index] = ((b >> 4) + 0x57);
};
index++;
if ((b & 0x0F) <= 0x09)
{
data[index] = ((b & 0x0F) + 0x30);
}
else {
data[index] = ((b & 0x0F) + 0x57);
};
index++;
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;
hdr[1] = ZPAD;
hdr[2] = ZDLE;
hdr[3] = ZHEX;
I64 index = 4;
index = PutHex(hdr, index, hdr_type);
U16 crc = crcxmUpdate(crcxmInit, hdr_type);
index = PutHex(hdr, index, ZP0);
crc = crcxmUpdate(crc, ZP0);
index = PutHex(hdr, index, ZP1);
crc = crcxmUpdate(crc, ZP1);
index = PutHex(hdr, index, ZP2);
crc = crcxmUpdate(crc, ZP2);
index = PutHex(hdr, index, ZP3);
crc = crcxmUpdate(crc, ZP3);
index = PutHex(hdr, index, (crc >> 8)(U8));
index = PutHex(hdr, index, (crc)(U8));
hdr[index] = 0x0D;
index++;
hdr[index] = 0x0A | 0x80;
index++;
if (!(hdr_type == ZFIN || hdr_type == ZACK))
{
hdr[index] = 0x11;
index++;
};
send(sock, hdr, 32, 0);
Free(hdr);
}
Loading…
Cancel
Save