📄 plc.c
字号:
show_ladder();
return;
}
if (mouse_object == DELROW_OBJ)
{
null_mouse_object();
for (r = 0; r < ladder_size; r++)
if (rung_list[r] == rung)
break;
if (r != ladder_size) /* if a "root" rung */
delrow(r); /* delete current rung */
show_ladder();
return;
}
#endif
null_mouse_object();
if (rungs[rung].node[index].objindex == NULL_OBJ)
return;
(*objs[rungs[rung].node[index].objindex].delfn)(rungs[rung].info.u_row-scroll_baserow,rungs[rung].info.l_col+index*LADDER_ELEMENT_WIDTH,&rungs[rung].node[index]);
rungs[rung].node[index].objindex = NULL_OBJ;
dirty = TRUE;
show_ladder();
}
void clear_elements(rung)
WORD rung;
{
WORD index, i;
for (index = 0; index < ELEMENTS_PER_RUNG; index++)
{
rungs[rung].node[index].objindex = NULL_OBJ;
rungs[rung].node[index].or_branch = OR_NULL;
rungs[rung].node[index].or_parent = OR_NULL;
rungs[rung].node[index].or_parentnode = OR_NULL;
rungs[rung].node[index].linkstatus = AVAILABLE;
for (i = 0; i < OPCODE_MAX; i++)
rungs[rung].node[index].opflags[i] = UNUSED_TYPE;
}
rungs[rung].info.left_action = ladder_node_add;
rungs[rung].info.right_action = ladder_node_del;
rungs[rung].info.objindex = LADDER_OBJ;
dirty = TRUE;
}
void new_rung(rung,screenrow)
WORD rung,screenrow;
{
WORD index;
if (screen_index == SCREEN_MAX)
return;
screen_list[screen_index++] = (struct element_info *)&rungs[rung];
rungs[rung].info.u_row = screenrow;
rungs[rung].info.l_row = screenrow + LADDER_ROW_HEIGHT;
rungs[rung].info.l_col = LADDER_LEFT_COL;
rungs[rung].info.r_col = LADDER_RIGHT_COL;
rungs[rung].num_elements = ELEMENTS_PER_RUNG;
rungs[rung].max_elements = ELEMENTS_PER_RUNG;
clear_elements(rung);
used_rungs[rung] = TRUE;
}
WORD get_rung_maxrow(rung) /* recursive! */
WORD rung;
{
WORD j, r, maxrow;
maxrow = rungs[rung].info.l_row;
for (j = 0; j < rungs[rung].num_elements; j++)
{
if (rungs[rung].node[j].or_branch != OR_NULL)
if ((r = get_rung_maxrow(rungs[rung].node[j].or_branch)) > maxrow)
maxrow = r;
}
return(maxrow);
}
WORD get_ladder_maxrow()
{
return(get_rung_maxrow(rung_list[ladder_size-1]));
}
WORD find_root_rung(root,rung) /* recursive! */
WORD root, rung;
{
WORD i;
if (root == rung)
return(TRUE);
for (i = 0; i < rungs[root].num_elements; i++)
{
if (rungs[root].node[i].or_branch != OR_NULL)
if (find_root_rung(rungs[root].node[i].or_branch,rung))
return(TRUE);
}
return(FALSE);
}
#ifdef BROKEN_ADD_OR_BRANCH
move_rungs_down(rung,row) /* recursive! */
{
WORD i;
for (i = 0; i < rungs[rung].num_elements; i++)
if (rungs[rung].node[i].or_branch != OR_NULL)
move_rungs_down(rungs[rung].node[i].or_branch,row);
if (rungs[rung].info.l_row >= row)
{
rungs[rung].info.u_row += LADDER_ROW_INCREMENT;
rungs[rung].info.l_row += LADDER_ROW_INCREMENT;
}
}
WORD encloses(rung,br,row,lcol,rcol)
WORD rung, *br, row, lcol, rcol;
{
WORD i, branch;
for (i = 0; i < rungs[rung].num_elements; i++)
if ((branch = rungs[rung].node[i].or_branch) != OR_NULL)
if ((rungs[branch].info.l_row >= row)
&& (rungs[branch].info.l_col < lcol)
&& (rungs[branch].info.r_col > rcol))
{
*br = branch;
return(rungs[branch].info.l_row);
}
return(0);
}
update_branch_spacing(rung,row,lcol,rcol) /* recursive! */ /* update branch spacing, if needed */
WORD rung, row, lcol, rcol; /* rung is an index into rungs[] */
{
WORD i, nextr, parent, branch;
if (rungs[rung].node[0].or_parent != OR_NULL)
{
if (nextr = encloses(rung,&branch,row,lcol,rcol))
{
if (nextr <= row)
/* max current row on parent is too small */
{
move_rungs_down(branch,row);
}
}
if ((parent = rungs[rung].node[0].or_parent) != OR_NULL)
update_branch_spacing(parent,row,lcol,rcol);
}
else
{
nextr = get_rung_maxrow(rung);
if (nextr < row)
nextr = row;
for (i = 0; i < ladder_size; i++)
if (rung_list[i] == rung)
break;
for (i++; i < ladder_size; i++)
{
if (rungs[rung_list[i]].info.l_row <= nextr + LADDER_ROW_INCREMENT)
break;
}
for ( ; i < ladder_size; i++)
{
move_rungs_down(rung_list[i],0);
}
}
}
add_or_branch(rung,index)
WORD rung, index;
{
WORD i, j;
WORD root, maxr;
WORD nextrung;
if (rungs[rung].node[index].linkstatus != AVAILABLE)
return; /* already connected to an OR branch */
if (rungs[rung].node[index].or_branch != OR_NULL)
return;
for (nextrung = 0; nextrung < MAX_RUNGS; nextrung++)
if (!used_rungs[nextrung])
break;
if (nextrung == MAX_RUNGS) /* full, can't do anything */
return;
if (screen_index == SCREEN_MAX)
return;
#ifdef NEVERDEF
if (get_ladder_maxrow() - scroll_baserow > MAX_GRAPHICS_ROW - LADDER_ROW_INCREMENT)
return;
#endif
for (j = 0; j < ladder_size; j++)
{
root = rung_list[j];
if (find_root_rung(root,rung))
break;
}
rungs[nextrung].info.u_row = rungs[rung].info.u_row + LADDER_ROW_INCREMENT;
rungs[nextrung].info.l_row = rungs[rung].info.l_row + LADDER_ROW_INCREMENT;
rungs[nextrung].info.l_col = rungs[rung].info.l_col + index * LADDER_ELEMENT_WIDTH;
rungs[nextrung].info.r_col = rungs[nextrung].info.l_col + LADDER_ELEMENT_WIDTH;
rungs[nextrung].num_elements = 1;
rungs[nextrung].max_elements = ELEMENTS_PER_RUNG - index;
clear_elements(nextrung); /* setup new rung */
rungs[nextrung].node[0].or_parent = rung; /* set parent */
rungs[nextrung].node[0].or_parentnode = index;
update_branch_spacing(rung,
rungs[nextrung].info.l_row,
rungs[nextrung].info.l_col,
rungs[nextrung].info.r_col); /* update branch spacing, if needed */
rungs[rung].node[index].or_branch = nextrung; /* set rung link */
rungs[rung].node[index].linkstatus = ENDLINK; /* default: only 1 element, this must be the end */
/* DO NOT link rung into ladder until AFTER
* we scan rung/OR branches for position updates!
*/
#ifdef NEVERDEF
maxr = get_rung_maxrow(root); /* get max current row on root */
if (maxr < rungs[nextrung].info.l_row) /* if we need more space */
move_rungs_down(rungs[rung].info.l_row); /* make space for new branch */
#endif
screen_list[screen_index++] = (struct element_info *)&rungs[nextrung];
used_rungs[nextrung] = TRUE;
}
#else /* BROKEN_ADD_OR_BRANCH */
move_rungs_down(row) /* recursive! */
WORD row;
{
WORD rung;
for (rung = 0; rung < MAX_RUNGS; rung++)
{
if ((used_rungs[rung]) && (rungs[rung].info.u_row > row))
{
rungs[rung].info.u_row += LADDER_ROW_INCREMENT;
rungs[rung].info.l_row += LADDER_ROW_INCREMENT;
}
}
}
add_or_branch(rung,index)
WORD rung, index;
{
WORD i, j;
WORD root, maxr;
WORD nextrung;
if (rungs[rung].node[index].linkstatus != AVAILABLE)
return; /* already connected to an OR branch */
if (rungs[rung].node[index].or_branch != OR_NULL)
return;
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;
if (screen_index == SCREEN_MAX)
return;
if (get_ladder_maxrow() - scroll_baserow > MAX_GRAPHICS_ROW - LADDER_ROW_INCREMENT)
return;
for (j = 0; j < ladder_size; j++)
{
root = rung_list[j];
if (find_root_rung(root,rung))
break;
}
maxr = get_rung_maxrow(root); /* get max current row on root */
rungs[rung].node[index].or_branch = nextrung; /* set rung link */
rungs[rung].node[index].linkstatus = ENDLINK; /* default: only 1 element, this must be the end */
rungs[nextrung].info.u_row = rungs[rung].info.u_row + LADDER_ROW_INCREMENT;
rungs[nextrung].info.l_row = rungs[rung].info.l_row + LADDER_ROW_INCREMENT;
rungs[nextrung].info.l_col = rungs[rung].info.l_col + index * LADDER_ELEMENT_WIDTH;
rungs[nextrung].info.r_col = rungs[nextrung].info.l_col + LADDER_ELEMENT_WIDTH;
rungs[nextrung].num_elements = 1;
rungs[nextrung].max_elements = ELEMENTS_PER_RUNG - index;
clear_elements(nextrung); /* setup new rung */
rungs[nextrung].node[0].or_parent = rung; /* set parent */
rungs[nextrung].node[0].or_parentnode = index;
if (maxr < rungs[nextrung].info.l_row) /* if we need more space */
move_rungs_down(rungs[rung].info.l_row); /* make space for new branch */
screen_list[screen_index++] = (struct element_info *)&rungs[nextrung];
used_rungs[nextrung] = TRUE;
}
#endif /* BROKEN_ADD_OR_BRANCH */
void expand_or_branch(rung,index)
WORD rung, index;
{
WORD parent, parentnode;
WORD expandnode;
if (rungs[rung].num_elements == rungs[rung].max_elements) /* full, we can't expand */
return;
if ((parent = rungs[rung].node[0].or_parent) == OR_NULL)
return; /* root rung, can't expand that! */
parentnode = rungs[rung].node[0].or_parentnode;
if (parentnode == rungs[parent].max_elements - 1)
return; /* at EOL, can't expand */
expandnode = rungs[rung].node[0].or_parentnode + rungs[rung].num_elements - 1;
if (expandnode == rungs[parent].num_elements-1) /* branch runs to end of parent branch */
return;
if (rungs[parent].node[expandnode+1].linkstatus != AVAILABLE)
return;
#ifdef BROKEN_ADD_OR_BRANCH
rungs[parent].node[expandnode].linkstatus = AVAILABLE;
#else
rungs[parent].node[expandnode].linkstatus = TAKEN;
#endif
rungs[parent].node[expandnode+1].linkstatus = ENDLINK;
rungs[rung].num_elements++;
rungs[rung].info.r_col += LADDER_ELEMENT_WIDTH;
}
void newladder(menuindex)
WORD menuindex;
{
WORD rung;
cleanup_dirty();
erase_ladder();
for (screen_index = 0; screen_index < NUM_MENU_ELEMENTS; screen_index++)
screen_list[screen_index] = &menu[screen_index];
null_mouse_object();
ladder_size = 1;
for (rung = 1; rung < MAX_RUNGS; rung++)
used_rungs[rung] = FALSE;
show_menu();
new_rung(0,FIRST_LADDER_ROW);
rung_list[0] = 0; /* new rung list */
dirty = FALSE;
scroll_baserow = 0;
show_ladder();
}
void xmit_buf(buf,len)
BYTE *buf;
WORD len;
{
WORD tickcount, t, next;
tickcount = 0;
t = get_timer();
while (len)
{
if (ok_to_send())
{
send_byte(*buf++);
len--;
}
if (t != (next = get_timer()))
{
t = next;
if (++tickcount == 36) /* two seconds */
break;
}
}
}
void get_ack(msg)
BYTE *msg;
{
BYTE answer[8];
BYTE answerptr;
WORD tickcount, t, next;
answerptr = 0;
tickcount = 0;
t = get_timer();
while (tickcount < 9) /* 1/2 second */
{
while (in_queue_head != in_queue_tail)
{
if (answerptr < 8)
answer[answerptr++] = in_queue[in_queue_tail];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -