Exemple #1
0
/*
        XMODEM termination processing
*/
LOCAL	void	xmodemEnd(W er)
{
        // finish XMODEM protocol
	while (er >= 0) er = xmodemRead();

	if (er != E_END && er != E_CANCEL) {
		purgeInput();		// wait until there is no more data
		outputByte(CAN);	// transmite two (or more) consecutive CANs
		outputByte(CAN);
		outputByte(CAN);
	}
}
Exemple #2
0
int handleStateChange(BFState * interp,char command){
	switch(command){
		case '>':
			incrementDataPointer(interp);
			break;
		case '<':
			decrementDataPointer(interp);
			break;
		case '+':
			incrementCurrentByte(interp);
			break;
		case '-':
			decrementCurrentByte(interp);
			break;
		case '.':
			outputByte(interp);
			break;
		case ',':
			inputByte(interp);
			break;
		case '[':
		case ']':
			return 1;
		default:
			return 2;
	}
	return 0;
}
Exemple #3
0
void
outputAlignedDataList(FILE *f, int size, AST *ast)
{
    if (size > 1) {
        while ((datacount % size) != 0) {
            outputByte(f, 0);
        }
    }
    outputDataList(f, size, ast);
}
Exemple #4
0
void
outputDataList(FILE *f, int size, AST *ast)
{
    unsigned val, origval;
    int i, reps;
    AST *sub;

    while (ast) {
        sub = ast->left;
        if (sub->kind == AST_ARRAYDECL || sub->kind == AST_ARRAYREF) {
            origval = EvalPasmExpr(ast->left->left);
            reps = EvalPasmExpr(ast->left->right);
        } else if (sub->kind == AST_STRING) {
            const char *ptr = sub->d.string;
            while (*ptr) {
                val = (*ptr++) & 0xff;
                outputByte(f, val);
                for (i = 1; i < size; i++) {
                    outputByte(f, 0);
                }
            }
            reps = 0;
        } else {
            origval = EvalPasmExpr(ast->left);
            reps = 1;
        }
        while (reps > 0) {
            val = origval;
            for (i = 0; i < size; i++) {
                outputByte(f, val & 0xff);
                val = val >> 8;
            }
            --reps;
        }
        ast = ast->right;
    }
}
Exemple #5
0
/*
 * output bytes for a file
 */
static void
assembleFile(FILE *f, AST *ast)
{
    FILE *inf;
    const char *name = ast->d.string;
    int c;

    inf = fopen(name, "rb");
    if (!inf) {
        ERROR(ast, "file %s: %s", name, strerror(errno));
        return;
    }
    while ((c = fgetc(inf)) >= 0) {
        outputByte(f, c);
    }
    fclose(inf);
}
Exemple #6
0
void
assembleInstruction(FILE *f, AST *ast)
{
    uint32_t val, mask, src, dst;
    Instruction *instr;
    int i, numoperands, expectops;
    AST *operand[MAX_OPERANDS];
    AST *line = ast;
    char *callname;
    AST *retast;

    instr = (Instruction *)ast->d.ptr;
    val = instr->binary;
    if (instr->ops != NOP_OPERANDS) {
        /* for anything except NOP set the condition to "always" */
        val |= 0xf << 18;
    }
    /* check for modifiers and operands */
    numoperands = 0;
    ast = ast->right;
    while (ast != NULL) {
        if (ast->kind == AST_EXPRLIST) {
            if (numoperands >= MAX_OPERANDS) {
                ERROR(line, "Too many operands to instruction");
                return;
            }
            operand[numoperands++] = ast->left;
        } else if (ast->kind == AST_INSTRMODIFIER) {
            InstrModifier *mod = (InstrModifier *)ast->d.ptr;
            mask = mod->modifier;
            if (mask & 0x80000000) {
                val = val & mask;
            } else {
                val = val | mask;
            }
        } else {
            ERROR(line, "Internal error: expected instruction modifier found %d", ast->kind);
            return;
        }
        ast = ast->right;
    }

    /* parse operands and put them in place */
    switch (instr->ops) {
    case NO_OPERANDS:
    case NOP_OPERANDS:
        expectops = 0;
        break;
    case TWO_OPERANDS:
    case JMPRET_OPERANDS:
        expectops = 2;
        break;
    default:
        expectops = 1;
        break;
    }
    if (expectops != numoperands) {
        ERROR(line, "Expected %d operands for %s, found %d", expectops, instr->name, numoperands);
        return;
    }
    src = dst = 0;
    switch (instr->ops) {
    case NO_OPERANDS:
    case NOP_OPERANDS:
        break;
    case TWO_OPERANDS:
    case JMPRET_OPERANDS:
        dst = EvalPasmExpr(operand[0]);
        src = EvalPasmExpr(operand[1]);
        break;
    case SRC_OPERAND_ONLY:
        dst = 0;
        src = EvalPasmExpr(operand[0]);
        break;
    case DST_OPERAND_ONLY:
        dst = EvalPasmExpr(operand[0]);
        src = 0;
        break;
    case CALL_OPERAND:
        if (operand[0]->kind != AST_IDENTIFIER) {
            ERROR(operand[0], "call operand must be an identifier");
            return;
        }
        src = EvalPasmExpr(operand[0]);
        callname = malloc(strlen(operand[0]->d.string) + 8);
        strcpy(callname, operand[0]->d.string);
        strcat(callname, "_ret");
        retast = NewAST(AST_IDENTIFIER, NULL, NULL);
        retast->d.string = callname;
        dst = EvalPasmExpr(retast);
        break;
    default:
        ERROR(line, "Unsupported instruction `%s'", instr->name);
        return;
    }
    if (src > 511) {
        ERROR(line, "Source operand too big for %s", instr->name);
        return;
    }
    if (dst > 511) {
        ERROR(line, "Destination operand too big for %s", instr->name);
        return;
    }
    val = val | (dst << 9) | src;
    /* output the instruction */
    /* make sure it is aligned */
    while ((datacount % 4) != 0) {
        outputByte(f, 0);
    }
    for (i = 0; i < 4; i++) {
        outputByte(f, val & 0xff);
        val = val >> 8;
    }
}
Exemple #7
0
/*
        XMODEM read processing
*/
LOCAL	W	xmodemRead(void)
{
	W	i, c, ctlch;
	UB	cksum;

	if (blkptr < blksz) return blkbuf[blkptr++];

	c = 0;
	ctlch = ACK;
	if (blkno++ == 0) {
                /* only for the initial packet transfer */
		outputByte(NAK);
		c = inputByte(SOH1_TMO);
		ctlch = -1;
	}

	for (;;) {
                // receiving block
		for (i = 0;;) {
			if (ctlch >= 0) {
                                // ack/beginning character is transmitted
				outputByte(ctlch);

                                // leading letter in the ack is extracted
				c = inputByte(SOH_TMO);
			}
			ctlch = NAK;
			if (c == SOH) {blksz = BLK_SZ;	break;}
			if (c == STX) {blksz = XBLK_SZ; break;}
			if (c == CAN || c == CTLC) {	// cancel transfer
                                // Is CAN followed by another CAN?
				c = inputByte(IDLE_TMO);
				if (c < 0 || c == CAN || c == CTLC)
							return E_CANCEL;
			} else if (c == EOT) {	// end of transmission
				outputByte(ACK);
				return E_END;
			}
			purgeInput();	// skip data
			if (++i >= MAX_RETRY) return E_XMODEM;
		}

                // read a block number & check
		if ((i = inputByte(RECV_TMO)) < 0) continue;
		if ((c = inputByte(RECV_TMO)) < 0) continue;
		if (i + c != 0xff) continue;

		if (i != (blkno & 0xff)) {
			if (i != ((blkno - 1) & 0xff)) return E_XMODEM;
                        // skip if the previous block is read
			ctlch = ACK;
		}

                // read the block itself
		for (cksum = 0, i = 0; i < blksz; i++) {
			if ((c = inputByte(RECV_TMO)) < 0) break;
			cksum += (blkbuf[i] = c);
		}
		if (c < 0) continue;

                // validate checksum
		if (inputByte(RECV_TMO) == cksum && ctlch != ACK) break;
	}
	blkptr = 0;
	return blkbuf[blkptr++];
}