📄 plc.c
字号:
in_queue_tail = (in_queue_tail + 1) & (QUEUE_SIZE-1); /* it's a power of 2 */
}
if (answerptr == 5) /* size of ACK */
break;
if (t != (next = get_timer()))
{
t = next;
tickcount++;
}
}
if ((answerptr != 5)
|| (answer[0] != MSG_BYTE0)
|| (answer[1] != MSG_BYTE1)
|| (answer[2] != MSG_ACK)
|| (answer[3] != 0)
|| (answer[4] != 0))
{
draw_popbox(NULL);
cstrout(POPBOX_ROW + 2 * TEXTHEIGHT, POPBOX_COL + 3 * TEXTWIDTH,msg,POPBOX_FOREGROUND,POPBOX_BACKGROUND);
cstrout(POPBOX_ROW + 4 * TEXTHEIGHT, POPBOX_COL + 3 * TEXTWIDTH,"Press <enter> to continue",POPBOX_FOREGROUND,POPBOX_BACKGROUND);
getstr(POPBOX_ROW + 4 * TEXTHEIGHT, POPBOX_COL + (3 + 25) * TEXTWIDTH, answer, 1,POPBOX_FOREGROUND,POPBOX_BACKGROUND);
show_ladder();
}
}
WORD compile_rung(rung,level,find_label_addresses) /* recursive function! */
WORD rung, level, find_label_addresses;
{
WORD i, error, len, index, branch;
BYTE objbuf[8]; /* should only need 4 bytes */
if (level == 0)
{
if (program_len < MAX_PROGRAM)
program[program_len++] = SETLINETRUE;
else
return(COMPILE_PROG_TOO_BIG);
}
error = COMPILE_OK;
for (index = 0; (error == COMPILE_OK) && (index < rungs[rung].num_elements); index++)
{
if (rungs[rung].node[index].or_branch != OR_NULL)
{
branch = rungs[rung].node[index].or_branch;
if (program_len < MAX_PROGRAM)
program[program_len++] = PUSHLINETRUE;
else
return(COMPILE_PROG_TOO_BIG);
}
if (rungs[rung].node[index].objindex == NULL_OBJ)
{
error = COMPILE_OK;
len = 0; /* blank node, ignore it */
}
else
{
if ((error = (*objs[rungs[rung].node[index].objindex].compilefn)(&rungs[rung].node[index],&len,objbuf)) != COMPILE_OK)
{
if ((error == COMPILE_UNKNOWN_ADDR) && (find_label_addresses))
error = COMPILE_OK; /* ignore this error first pass */
else
{
(*objs[rungs[rung].node[index].objindex].drawfn)(rungs[rung].info.u_row-scroll_baserow,rungs[rung].info.l_col+TEXTWIDTH+index*LADDER_ELEMENT_WIDTH,&rungs[rung].node[index],BLACK,RED);
return(error);
}
}
}
if ((program_len + len) >= MAX_PROGRAM)
return(COMPILE_PROG_TOO_BIG);
for (i = 0; i < len; i++, program_len++)
{
program[program_len] = objbuf[i];
}
if (rungs[rung].node[index].linkstatus == ENDLINK)
{
if (program_len < MAX_PROGRAM)
program[program_len++] = ORBRANCH;
else
return(COMPILE_PROG_TOO_BIG);
if ((error = compile_rung(branch,level+1,find_label_addresses)) != COMPILE_OK)
{
if ((error == COMPILE_UNKNOWN_ADDR) && (find_label_addresses))
error = COMPILE_OK; /* ignore this error first pass */
else
return(error);
}
} /* if (... == ENDLINK) */
} /* for (index = 0; ...) */
if (level)
{
if (program_len < MAX_PROGRAM)
program[program_len++] = ORPOPLINETRUE;
else
return(COMPILE_PROG_TOO_BIG);
}
return(COMPILE_OK);
}
void compile_error(error)
WORD error;
{
BYTE answer[8];
draw_popbox("Ladder program error:");
switch (error)
{
case COMPILE_UNKNOWN_PARAMS:
cstrout(POPBOX_ROW + 4 * TEXTHEIGHT, POPBOX_COL + 3 * TEXTWIDTH,"Node parameters not set",POPBOX_FOREGROUND,POPBOX_BACKGROUND);
break;
case COMPILE_DUP_ADDR:
cstrout(POPBOX_ROW + 4 * TEXTHEIGHT, POPBOX_COL + 3 * TEXTWIDTH,"Duplicate label",POPBOX_FOREGROUND,POPBOX_BACKGROUND);
break;
case COMPILE_PROG_TOO_BIG:
sprintf(tempstr,"Program too big %d ",program_len);
cstrout(POPBOX_ROW + 4 * TEXTHEIGHT, POPBOX_COL + 3 * TEXTWIDTH,tempstr,POPBOX_FOREGROUND,POPBOX_BACKGROUND);
break;
}
cstrout(POPBOX_ROW + 6 * TEXTHEIGHT, POPBOX_COL + 3 * TEXTWIDTH,"Press <enter> to continue",POPBOX_FOREGROUND,POPBOX_BACKGROUND);
getstr(POPBOX_ROW + 6 * TEXTHEIGHT, POPBOX_COL + (3 + 25) * TEXTWIDTH, answer, 1,POPBOX_FOREGROUND,POPBOX_BACKGROUND);
show_ladder();
}
void download(menuindex)
WORD menuindex;
{
WORD i;
WORD chksum;
WORD root;
WORD error;
BYTE answer[8];
null_mouse_object();
for (i = 0; i < NUM_LABELS; i++)
label_addresses[i] = NULL_LABEL;
/* Pass 1: find label addresses */
program_len = 0;
error = COMPILE_OK;
for (root = 0; (error == COMPILE_OK) && (root < ladder_size); root++)
{
error = compile_rung(rung_list[root],0,TRUE); /* TRUE = find label addreses */
}
if (error != COMPILE_OK)
return(compile_error(error));
/* Pass 2: generate final code */
program_len = 0;
error = COMPILE_OK;
for (root = 0; (error == COMPILE_OK) && (root < ladder_size); root++)
{
error = compile_rung(rung_list[root],0,FALSE); /* FALSE = label addreses should be known */
}
if (error != COMPILE_OK)
return(compile_error(error));
for (chksum = 0, i = 0; i < program_len; i++)
chksum += program[i];
tempstr[0] = MSG_BYTE0;
tempstr[1] = MSG_BYTE1;
tempstr[2] = MSG_PROGRAM;
tempstr[3] = (program_len + 2) & 0xff;
tempstr[4] = (program_len + 2) >> 8;
xmit_buf(tempstr,5);
xmit_buf(program,program_len);
tempstr[0] = chksum & 0xff;
tempstr[1] = chksum >> 8;
xmit_buf(tempstr,2);
get_ack("Download failure (comm error?)");
}
void onestep(menuindex)
WORD menuindex;
{
null_mouse_object();
beep();
}
void linestep(menuindex)
WORD menuindex;
{
null_mouse_object();
beep();
}
void run(menuindex)
WORD menuindex;
{
BYTE answer[8];
null_mouse_object();
tempstr[0] = MSG_BYTE0;
tempstr[1] = MSG_BYTE1;
tempstr[2] = MSG_RUN;
tempstr[3] = 0;
tempstr[4] = 0;
xmit_buf(tempstr,5);
get_ack("RUN failure (comm error?)");
}
void stop(menuindex)
WORD menuindex;
{
BYTE answer[8];
null_mouse_object();
tempstr[0] = MSG_BYTE0;
tempstr[1] = MSG_BYTE1;
tempstr[2] = MSG_STOP;
tempstr[3] = 0;
tempstr[4] = 0;
xmit_buf(tempstr,5);
get_ack("STOP failure (comm error?)");
}
#ifdef SIMPLE_ADDROW
void addrow(menuindex)
WORD menuindex;
{
WORD maxr;
WORD nextrung;
null_mouse_object();
for (nextrung = 0; nextrung < MAX_RUNGS; nextrung++)
if (!used_rungs[nextrung])
break;
if ((nextrung == MAX_RUNGS) /* full, can't do anything */
|| (ladder_size == MAX_LADDER))
return;
new_rung(nextrung,maxr + LADDER_ROW_INCREMENT);
rung_list[ladder_size++] = nextrung;
show_ladder();
}
void delrow(menuindex)
WORD menuindex;
{
null_mouse_object();
beep();
}
#else /* SIMPLE_ADDROW */
void appendrow(menuindex)
WORD menuindex;
{
WORD maxr;
WORD nextrung;
null_mouse_object();
for (nextrung = 0; nextrung < MAX_RUNGS; nextrung++)
if (!used_rungs[nextrung])
break;
if ((nextrung == MAX_RUNGS) /* full, can't do anything */
|| (ladder_size == MAX_LADDER))
return;
maxr = get_ladder_maxrow();
new_rung(nextrung,maxr + LADDER_ROW_INCREMENT);
rung_list[ladder_size++] = nextrung;
show_ladder();
}
void addrow_spacing(rung,size) /* recursive! */
{
WORD i;
for (i = 0; i < rungs[rung].num_elements; i++)
if (rungs[rung].node[i].or_branch != OR_NULL)
addrow_spacing(rungs[rung].node[i].or_branch,size);
rungs[rung].info.u_row += size;
rungs[rung].info.l_row += size;
}
void addrow(index) /* index into rung_list[] */
WORD index;
{
WORD maxr, nextrung, i;
for (nextrung = 0; nextrung < MAX_RUNGS; nextrung++)
if (!used_rungs[nextrung])
break;
if ((nextrung == MAX_RUNGS) /* full, can't do anything */
|| (ladder_size == MAX_LADDER))
return;
maxr = get_ladder_maxrow() + LADDER_ROW_INCREMENT;
if (index != ladder_size) /* if not end-of-list */
maxr = rungs[rung_list[index]].info.u_row; /* get row we're going to replace */
for (i = index; i < ladder_size; i++)
addrow_spacing(rung_list[i],LADDER_ROW_INCREMENT+LADDER_ROW_HEIGHT);
for (i = ladder_size; i > index; i--)
rung_list[i] = rung_list[i-1]; /* move rungs logically "down" to make space */
rung_list[i] = nextrung;
new_rung(nextrung,maxr);
ladder_size++;
}
void delrow_spacing(rung,size) /* recursive! */
{
WORD i;
for (i = 0; i < rungs[rung].num_elements; i++)
if (rungs[rung].node[i].or_branch != OR_NULL)
delrow_spacing(rungs[rung].node[i].or_branch,size);
rungs[rung].info.u_row -= size;
rungs[rung].info.l_row -= size;
}
void delrow_rungs(rung) /* recursive! */
{
WORD i;
for (i = 0; i < rungs[rung].num_elements; i++)
if (rungs[rung].node[i].or_branch != OR_NULL)
delrow_rungs(rungs[rung].node[i].or_branch);
used_rungs[rung] = FALSE;
}
void delrow(index)
WORD index;
{
WORD spacing, i;
if (ladder_size == 1)
return; /* can't completely empty the ladder! */
spacing = 0;
if (index < ladder_size - 1)
{
spacing = rungs[rung_list[index+1]].info.l_row - rungs[rung_list[index]].info.l_row;
/* get "moveup" size */
}
delrow_rungs(rung_list[index]);
for (i = index; i < ladder_size - 1; i++)
{
rung_list[i] = rung_list[i+1];
delrow_spacing(rung_list[i],spacing);
}
ladder_size--;
}
#endif /* SIMPLE_ADDROW */
void pickup(menuindex)
WORD menuindex;
{
null_mouse_object();
mouse_object = screen_list[menuindex].objindex;
strcat(mouse_cursor,objs[mouse_object].label);
strcpy(mouse_overlay," ");
strcat(mouse_overlay,objs[mouse_object].overlay);
}
void quit(menuindex)
WORD menuindex;
{
BYTE answer[8];
if (!quickexit)
cleanup_dirty();
exitflag = TRUE;
}
show_menu()
{
WORD i;
for (i = 0; i < NUM_MENU_ELEMENTS; i++)
{
strout(screen_list[i].u_row,screen_list[i].l_col,objs[screen_list[i].objindex].label);
overlay(screen_list[i].u_row,screen_list[i].l_col,objs[screen_list[i].objindex].overlay);
}
}
void show_rung(rung,level) /* RECURSIVE! */
WORD rung, level;
{
WORD j, r, c;
WORD i;
r = rungs[rung].info.u_row;
if (r < (scroll_baserow + LADDER_ROW_HEIGHT))
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -