Compare commits
No commits in common. "b6e9d5ae86418b0dae400087bd1a26da82a0d893" and "2fe2f0a1a7e85bded6948304e7790128bc7e7d77" have entirely different histories.
b6e9d5ae86
...
2fe2f0a1a7
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,6 +1,4 @@
|
||||
main
|
||||
scu-dsp-asm
|
||||
*.o
|
||||
*.gch
|
||||
*.d
|
||||
test/*.s
|
11
Makefile
11
Makefile
@ -1,9 +1,8 @@
|
||||
STATIC = -static -static-libgcc -static-libstdc++
|
||||
CXXFLAGS = -Og -g -Wall -Wextra -Werror -Wfatal-errors -Wno-c99-designator -std=c++20
|
||||
CXXFLAGS = -Og -g -Wall -Wextra -Werror -Wfatal-errors -Wpedantic -Wno-c99-designator -std=c++20
|
||||
LDFLAGS =
|
||||
|
||||
TARGET =
|
||||
CXX = $(TARGET)g++
|
||||
CXX = $(TARGET)clang++
|
||||
|
||||
SRC = main.cpp
|
||||
SRC += lexer.cpp
|
||||
@ -15,15 +14,15 @@ SRC += stmt_string.cpp
|
||||
OBJ = $(patsubst %.cpp,%.o,$(SRC))
|
||||
DEP = $(patsubst %.cpp,%.d,$(SRC))
|
||||
|
||||
all: scu-dsp-asm
|
||||
all: main
|
||||
|
||||
-include $(DEP)
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) -MMD -MF $(basename $<).d -c $< -o $@
|
||||
|
||||
scu-dsp-asm: $(OBJ)
|
||||
$(CXX) $(STATIC) $(LDFLAGS) $^ -o $@
|
||||
main: $(OBJ)
|
||||
$(CXX) $(LDFLAGS) $^ -o $@
|
||||
|
||||
clean:
|
||||
rm -f *.o *.d *.gch main
|
||||
|
@ -131,7 +131,7 @@ uint32_t emitter_t::visit(const op::mov_ram_a_t * mov_ram_a) const
|
||||
|
||||
uint32_t emitter_t::visit(const op::mov_imm_d1_t * mov_imm_d1) const
|
||||
{
|
||||
num_t value = mov_imm_d1->imm.normalize(mov_imm_d1->imm.expr->accept(this));
|
||||
num_t value = mov_imm_d1->imm.expr->accept(this);
|
||||
if (mov_imm_d1->imm.in_range(value))
|
||||
return mov_imm_d1->code() | mov_imm_d1->bits() | value;
|
||||
else
|
||||
@ -152,7 +152,7 @@ uint32_t emitter_t::visit(const op::control_word_t * control_word) const
|
||||
|
||||
uint32_t emitter_t::visit(const load::mvi_t * mvi) const
|
||||
{
|
||||
num_t value = mvi->imm.normalize(mvi->imm.expr->accept(this));
|
||||
num_t value = mvi->imm.expr->accept(this);
|
||||
if (mvi->imm.in_range(value))
|
||||
return mvi->code() | mvi->bits() | value;
|
||||
else
|
||||
@ -161,7 +161,7 @@ uint32_t emitter_t::visit(const load::mvi_t * mvi) const
|
||||
|
||||
uint32_t emitter_t::visit(const load::mvi_cond_t * mvi_cond) const
|
||||
{
|
||||
num_t value = mvi_cond->imm.normalize(mvi_cond->imm.expr->accept(this));
|
||||
num_t value = mvi_cond->imm.expr->accept(this);
|
||||
if (mvi_cond->imm.in_range(value))
|
||||
return mvi_cond->code() | mvi_cond->bits() | value;
|
||||
else
|
||||
@ -170,7 +170,7 @@ uint32_t emitter_t::visit(const load::mvi_cond_t * mvi_cond) const
|
||||
|
||||
uint32_t emitter_t::visit(const dma::src_d0_imm_t * src_d0_imm) const
|
||||
{
|
||||
num_t value = src_d0_imm->imm.normalize(src_d0_imm->imm.expr->accept(this));
|
||||
num_t value = src_d0_imm->imm.expr->accept(this);
|
||||
if (src_d0_imm->imm.in_range(value))
|
||||
return src_d0_imm->code() | src_d0_imm->bits() | value;
|
||||
else
|
||||
@ -179,7 +179,7 @@ uint32_t emitter_t::visit(const dma::src_d0_imm_t * src_d0_imm) const
|
||||
|
||||
uint32_t emitter_t::visit(const dma::d0_dst_imm_t * d0_dst_imm) const
|
||||
{
|
||||
num_t value = d0_dst_imm->imm.normalize(d0_dst_imm->imm.expr->accept(this));
|
||||
num_t value = d0_dst_imm->imm.expr->accept(this);
|
||||
if (d0_dst_imm->imm.in_range(value))
|
||||
return d0_dst_imm->code() | d0_dst_imm->bits() | value;
|
||||
else
|
||||
@ -198,7 +198,7 @@ uint32_t emitter_t::visit(const dma::d0_dst_ram_t * d0_dst_ram) const
|
||||
|
||||
uint32_t emitter_t::visit(const jump::jmp_t * jmp) const
|
||||
{
|
||||
num_t value = jmp->imm.normalize(jmp->imm.expr->accept(this));
|
||||
num_t value = jmp->imm.expr->accept(this);
|
||||
if (jmp->imm.in_range(value))
|
||||
return jmp->code() | jmp->bits() | value;
|
||||
else
|
||||
@ -207,7 +207,7 @@ uint32_t emitter_t::visit(const jump::jmp_t * jmp) const
|
||||
|
||||
uint32_t emitter_t::visit(const jump::jmp_cond_t * jmp_cond) const
|
||||
{
|
||||
num_t value = jmp_cond->imm.normalize(jmp_cond->imm.expr->accept(this));
|
||||
num_t value = jmp_cond->imm.expr->accept(this);
|
||||
if (jmp_cond->imm.in_range(value))
|
||||
return jmp_cond->code() | jmp_cond->bits() | value;
|
||||
else
|
||||
|
@ -22,10 +22,11 @@ struct emitter_error_t : std::runtime_error
|
||||
|
||||
struct emitter_t : visitor_t<uint32_t>
|
||||
{
|
||||
emitter_t(variables_t& variables)
|
||||
: variables(variables) {}
|
||||
emitter_t(variables_t& variables, const addresses_t& addresses)
|
||||
: variables(variables), addresses(addresses) {}
|
||||
|
||||
variables_t& variables;
|
||||
const addresses_t& addresses;
|
||||
|
||||
uint32_t visit(const binary_t * binary) const;
|
||||
uint32_t visit(const grouping_t * grouping) const;
|
||||
|
@ -174,10 +174,10 @@ void resolver_t::visit(const assign_t * assign) const
|
||||
|
||||
void resolver_t::visit(const label_t * label) const
|
||||
{
|
||||
if (variables.contains(label->name.lexeme)) {
|
||||
if (addresses.contains(label->name.lexeme)) {
|
||||
throw std::runtime_error("label redefinition is not allowed");
|
||||
} else {
|
||||
variables.insert({label->name.lexeme, pc.value});
|
||||
addresses.insert({label->name.lexeme, pc.value});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,11 +25,11 @@ struct pc_t
|
||||
|
||||
struct resolver_t : visitor_t<void>
|
||||
{
|
||||
resolver_t(pc_t& pc, variables_t& variables)
|
||||
: pc(pc), variables(variables) {}
|
||||
resolver_t(pc_t& pc, addresses_t& addresses)
|
||||
: pc(pc), addresses(addresses) {}
|
||||
|
||||
pc_t& pc;
|
||||
variables_t& variables;
|
||||
addresses_t& addresses;
|
||||
|
||||
void visit(const binary_t * binary) const;
|
||||
void visit(const grouping_t * grouping) const;
|
||||
|
36
grammar.txt
36
grammar.txt
@ -1,25 +1,3 @@
|
||||
expression → term
|
||||
term → factor ( ( "-" | "+" ) factor )*
|
||||
factor → unary ( ( "/" | "*" | "%" ) unary )*
|
||||
unary → ( "~" | "+" | "-" ) unary
|
||||
| shift
|
||||
shift → andl ( ( "<<" | ">>" ) andl )*
|
||||
andl → orl ( "&" orl )*
|
||||
orl → andl ( ( "|" | "^" ) andl )*
|
||||
primary → number
|
||||
| "(" expression ")"
|
||||
|
||||
number → "%" base2-number
|
||||
| "$" base16-number
|
||||
| "0b" base2-number
|
||||
| "0x" base16-number
|
||||
| base10-number
|
||||
|
||||
imm → ("#")? expression
|
||||
uimm8 → imm
|
||||
uimm19 → imm
|
||||
uimm25 → imm
|
||||
|
||||
alu → and | or | xor | add | sub | ad2 | sr | rr | sl | rl | rl8
|
||||
|
||||
xy_src → "mc0" | "mc1" | "mc2" | "mc3"
|
||||
@ -47,14 +25,12 @@ d1_src → "mc0" | "mc1" | "mc2" | "mc3"
|
||||
| "m0" | "m1" | "m2" | "m3"
|
||||
| "alh" | "all"
|
||||
|
||||
mov_imm_d1 → "mov" uimm8 "," d1_dest
|
||||
mov_imm_d1 → "mov" simm8 "," d1_dest
|
||||
mov_ram_d1 → "mov" d1_src "," d1_dest
|
||||
|
||||
d1_bus → mov_imm_d1 → mov_ram_d1
|
||||
|
||||
nop → "nop"
|
||||
|
||||
op → ( nop | alu | x_bus | y_bus | d1_bus ) +
|
||||
op → ( alu | x_bus | y_bus | d1_bus ) +
|
||||
|
||||
load_dest → "mc0" | "mc1" | "mc2" | "mc3"
|
||||
| "rx" | "pl"
|
||||
@ -84,8 +60,8 @@ dma_dmah → ("dma" | "dmah") add_mode?
|
||||
dma_length_ram → "m0" | "m1" | "m2" | "m3"
|
||||
| "mc0" | "mc1" | "mc2" | "mc3"
|
||||
|
||||
dma_ingress_imm → dma_dmah "d0" "," dma_ingress "," uimm8
|
||||
dma_egress_imm → dma_dmah dma_egress "," "d0" "," uimm8
|
||||
dma_ingress_imm → dma_dmah "d0" "," dma_ingress "," simm8
|
||||
dma_egress_imm → dma_dmah dma_egress "," "d0" "," simm8
|
||||
dma_ingress_ram → dma_dmah "d0" "," dma_ingress "," dma_length_ram
|
||||
dma_egress_ram → dma_dmah dma_egress "," "d0" "," dma_length_ram
|
||||
|
||||
@ -106,7 +82,8 @@ loop → "btm" | "lps"
|
||||
|
||||
end → "end" | "endi"
|
||||
|
||||
instruction → op
|
||||
instruction → "nop"
|
||||
| op
|
||||
| load
|
||||
| dma
|
||||
| jump
|
||||
@ -121,3 +98,4 @@ instruction_statement → label? instruction? "\n"
|
||||
|
||||
statement → assignment_statement
|
||||
| instruction_statement
|
||||
|
||||
|
41
lexer.cpp
41
lexer.cpp
@ -53,19 +53,6 @@ constexpr static N parse_number(const std::string_view s)
|
||||
return n;
|
||||
}
|
||||
|
||||
struct bin_t {
|
||||
constexpr static bool pred(const char c)
|
||||
{
|
||||
return c >= '0' && c <= '1';
|
||||
}
|
||||
|
||||
template <typename N>
|
||||
constexpr static N parse(const std::string_view s)
|
||||
{
|
||||
return parse_number<N, 2>(s);
|
||||
}
|
||||
};
|
||||
|
||||
struct dec_t {
|
||||
constexpr static bool pred(const char c)
|
||||
{
|
||||
@ -172,13 +159,13 @@ std::optional<token_t> lexer_t::lex_token()
|
||||
case '-': return {{pos, minus, lexeme()}};
|
||||
case '*': return {{pos, star, lexeme()}};
|
||||
case '/': return {{pos, slash, lexeme()}};
|
||||
case '%': return {{pos, percent, lexeme()}};
|
||||
case '~': return {{pos, tilde, lexeme()}};
|
||||
case '&': return {{pos, ampersand, lexeme()}};
|
||||
case '|': return {{pos, bar, lexeme()}};
|
||||
case '^': return {{pos, carot, lexeme()}};
|
||||
case '=': return {{pos, equal, lexeme()}};
|
||||
case ':': return {{pos, colon, lexeme()}};
|
||||
case '#': return {{pos, hash, lexeme()}};
|
||||
case '<':
|
||||
if (match('<')) return {{pos, left_shift, lexeme()}};
|
||||
break;
|
||||
@ -188,12 +175,8 @@ std::optional<token_t> lexer_t::lex_token()
|
||||
case ';':
|
||||
while (!at_end_p() && peek() != '\n') advance();
|
||||
break;
|
||||
case '\\':
|
||||
if (match('\n')) { continue; }
|
||||
else if (match('\r')) { if (match('\n')) continue; }
|
||||
break;
|
||||
case '\r':
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\t':
|
||||
break;
|
||||
case '\n':
|
||||
@ -204,13 +187,6 @@ std::optional<token_t> lexer_t::lex_token()
|
||||
return {{tmp, eol, lexeme()}};
|
||||
}
|
||||
break;
|
||||
case '%':
|
||||
if (bin_t::pred(peek())) {
|
||||
start_ix += 1;
|
||||
return {_number<bin_t>()};
|
||||
} else {
|
||||
return {{pos, percent, lexeme()}};
|
||||
}
|
||||
case '$':
|
||||
if (hex_t::pred(peek())) {
|
||||
start_ix += 1;
|
||||
@ -222,18 +198,7 @@ std::optional<token_t> lexer_t::lex_token()
|
||||
if (hex_t::pred(peek())) {
|
||||
start_ix += 2;
|
||||
return {_number<hex_t>()};
|
||||
} else {
|
||||
error(pos.line, pos.col, "expected hexadecimal literal");
|
||||
return {};
|
||||
}
|
||||
} else if (match('b')) {
|
||||
if (bin_t::pred(peek())) {
|
||||
start_ix += 2;
|
||||
return {_number<bin_t>()};
|
||||
} else {
|
||||
error(pos.line, pos.col, "expected binary literal");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
[[fallthrough]];
|
||||
default:
|
||||
|
7
main.cpp
7
main.cpp
@ -40,14 +40,15 @@ static void run(std::ostream& os, std::string source)
|
||||
parser_t pass2(tokens);
|
||||
ast::printer_t printer(std::cout);
|
||||
ast::pc_t pc;
|
||||
ast::variables_t variables;
|
||||
ast::resolver_t resolver(pc, variables);
|
||||
ast::addresses_t addresses;
|
||||
ast::resolver_t resolver(pc, addresses);
|
||||
while (auto stmt_o = pass1.statement()) {
|
||||
(*stmt_o)->accept(&printer);
|
||||
std::cout << std::endl << std::flush;
|
||||
(*stmt_o)->accept(&resolver);
|
||||
}
|
||||
ast::emitter_t emitter(variables);
|
||||
ast::variables_t variables;
|
||||
ast::emitter_t emitter(variables, addresses);
|
||||
while (auto stmt_o = pass2.statement()) {
|
||||
uint32_t output = (*stmt_o)->accept(&emitter);
|
||||
if (output != 0xffff'ffff) {
|
||||
|
33
parser.cpp
33
parser.cpp
@ -1,3 +1,16 @@
|
||||
/*
|
||||
expression → term ;
|
||||
term → factor ( ( "-" | "+" ) factor )* ;
|
||||
factor → unary ( ( "/" | "*" | "%" ) unary )* ;
|
||||
unary → ( "~" | "+" | "-" ) unary
|
||||
| shift ;
|
||||
shift → andl ( ( "<<" | ">>" ) andl )*
|
||||
andl → orl ( "&" orl )*
|
||||
orl → andl ( ( "|" | "^" ) andl )*
|
||||
primary → NUMBER
|
||||
| "(" expression ")" ;
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <cassert>
|
||||
@ -31,11 +44,6 @@ const token_t& parser_t::peek()
|
||||
return tokens[current_ix];
|
||||
}
|
||||
|
||||
const token_t& parser_t::peek(int n)
|
||||
{
|
||||
return tokens[current_ix + n];
|
||||
}
|
||||
|
||||
const token_t& parser_t::advance()
|
||||
{
|
||||
if (!at_end_p()) current_ix++;
|
||||
@ -272,7 +280,6 @@ std::optional<op::op_t *> parser_t::xyd1_bus()
|
||||
else
|
||||
throw error(peek(), "expected x-bus, y-bus, or d-bus destination operand");
|
||||
} else {
|
||||
match(hash); // optionally consume a hash
|
||||
uimm_t<8> imm = uimm_t<8>(peek(), expression());
|
||||
consume(comma, "expected `,`");
|
||||
if (auto dest_o = d1_dest())
|
||||
@ -290,7 +297,6 @@ std::optional<op::op_t *> parser_t::xyd1_bus()
|
||||
|
||||
std::optional<stmt_t *> parser_t::op()
|
||||
{
|
||||
bool saw_nop = false;
|
||||
std::vector<const op::op_t *> ops;
|
||||
std::vector<const token_t *> tokens;
|
||||
|
||||
@ -309,12 +315,11 @@ std::optional<stmt_t *> parser_t::op()
|
||||
while (true) {
|
||||
// fixme: check for emplacement here
|
||||
const token_t& token = peek();
|
||||
if (match(_nop)) saw_nop = 1;
|
||||
else if (auto op_o = alu() ) emplace_op(token, *op_o);
|
||||
if (auto op_o = alu() ) emplace_op(token, *op_o);
|
||||
else if (auto op_o = xyd1_bus()) emplace_op(token, *op_o);
|
||||
else break;
|
||||
}
|
||||
if (ops.size() != 0 || saw_nop)
|
||||
if (ops.size() != 0)
|
||||
return {new op::control_word_t(ops)};
|
||||
else
|
||||
return {};
|
||||
@ -362,7 +367,6 @@ std::optional<stmt_t *> parser_t::load()
|
||||
{
|
||||
if (match(_mvi)) {
|
||||
const token_t& expr_token = peek();
|
||||
match(hash); // optionally consume a hash
|
||||
expr_t * expr = expression();
|
||||
consume(comma, "expected `,`");
|
||||
load::dest_t dest = parser_t::load_dest();
|
||||
@ -508,7 +512,6 @@ std::optional<stmt_t *> parser_t::dma()
|
||||
if (auto length_ram_o = dma_length_ram()) {
|
||||
return {new dma::d0_dst_ram_t(hold, add, dst, *length_ram_o)};
|
||||
} else {
|
||||
match(hash); // optionally consume a hash
|
||||
uimm_t<8> imm = uimm_t<8>(peek(), expression());
|
||||
return {new dma::d0_dst_imm_t(hold, add, dst, imm)};
|
||||
}
|
||||
@ -520,7 +523,6 @@ std::optional<stmt_t *> parser_t::dma()
|
||||
if (auto length_ram_o = dma_length_ram()) {
|
||||
return {new dma::src_d0_ram_t(hold, add, src, *length_ram_o)};
|
||||
} else {
|
||||
match(hash); // optionally consume a hash
|
||||
uimm_t<8> imm = uimm_t<8>(peek(), expression());
|
||||
return {new dma::src_d0_imm_t(hold, add, src, imm)};
|
||||
}
|
||||
@ -551,11 +553,9 @@ std::optional<stmt_t *> parser_t::jump()
|
||||
if (match(_jmp)) {
|
||||
if (auto cond_o = jump_cond()) {
|
||||
consume(comma, "expected `,` after jump condition");
|
||||
match(hash); // optionally consume a hash
|
||||
uimm_t<8> imm = uimm_t<8>(peek(), expression());
|
||||
return {new jump::jmp_cond_t(*cond_o, imm)};
|
||||
} else {
|
||||
match(hash); // optionally consume a hash
|
||||
uimm_t<8> imm = uimm_t<8>(peek(), expression());
|
||||
return {new jump::jmp_t(imm)};
|
||||
}
|
||||
@ -579,7 +579,8 @@ std::optional<stmt_t *> parser_t::end()
|
||||
|
||||
std::optional<stmt_t *> parser_t::instruction()
|
||||
{
|
||||
if (auto op_o = op()) return op_o;
|
||||
if (match(_nop)) return {new nop::nop_t()};
|
||||
else if (auto op_o = op()) return op_o;
|
||||
else if (auto load_o = load()) return load_o;
|
||||
else if (auto dma_o = dma()) return dma_o;
|
||||
else if (auto jump_o = jump()) return jump_o;
|
||||
|
@ -31,7 +31,6 @@ struct parser_t
|
||||
|
||||
const token_t& previous();
|
||||
const token_t& peek();
|
||||
const token_t& peek(int n);
|
||||
const token_t& advance();
|
||||
bool check(enum token_t::type_t token_type);
|
||||
bool match(enum token_t::type_t token_type);
|
||||
|
10
stmt.hpp
10
stmt.hpp
@ -40,15 +40,6 @@ struct imm_t {
|
||||
static constexpr num_t max = (1L << (bits - static_cast<num_t>(sign))) - 1;
|
||||
static constexpr num_t min = sign ? -(max + 1) : 0;
|
||||
|
||||
num_t normalize(num_t value) const
|
||||
{
|
||||
if (!S && value > 2147483648) { // fixme: hack
|
||||
return value & max;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
bool in_range(num_t value) const
|
||||
{
|
||||
return value <= max && value >= min;
|
||||
@ -266,6 +257,7 @@ struct control_word_t : stmt_accept_t<control_word_t>
|
||||
control_word_t(std::vector<const op::op_t *> ops)
|
||||
: ops(ops)
|
||||
{
|
||||
if (ops.size() == 0) throw std::runtime_error("zero-length ops");
|
||||
}
|
||||
|
||||
const std::vector<const op_t *> ops;
|
||||
|
@ -22,21 +22,17 @@ const std::string alu_type_string[] = {
|
||||
};
|
||||
|
||||
const std::string xy_src_string[] = {
|
||||
[i(xy_src_t::m0 )] = "m0" ,
|
||||
[i(xy_src_t::m1 )] = "m1" ,
|
||||
[i(xy_src_t::m2 )] = "m2" ,
|
||||
[i(xy_src_t::m3 )] = "m3" ,
|
||||
[i(xy_src_t::mc0)] = "mc0",
|
||||
[i(xy_src_t::mc1)] = "mc1",
|
||||
[i(xy_src_t::mc2)] = "mc2",
|
||||
[i(xy_src_t::mc3)] = "mc3",
|
||||
[i(xy_src_t::m0 )] = "m0" ,
|
||||
[i(xy_src_t::m1 )] = "m1" ,
|
||||
[i(xy_src_t::m2 )] = "m2" ,
|
||||
[i(xy_src_t::m3 )] = "m3" ,
|
||||
};
|
||||
|
||||
const std::string d1_dest_string[] = {
|
||||
[i(d1_dest_t::mc0)] = "mc0",
|
||||
[i(d1_dest_t::mc1)] = "mc1",
|
||||
[i(d1_dest_t::mc2)] = "mc2",
|
||||
[i(d1_dest_t::mc3)] = "mc3",
|
||||
[i(d1_dest_t::rx )] = "rx" ,
|
||||
[i(d1_dest_t::pl )] = "pl" ,
|
||||
[i(d1_dest_t::ra0)] = "ra0",
|
||||
@ -50,16 +46,14 @@ const std::string d1_dest_string[] = {
|
||||
};
|
||||
|
||||
const std::string d1_src_string[] = {
|
||||
[i(d1_src_t::m0 )] = "m0" ,
|
||||
[i(d1_src_t::m1 )] = "m1" ,
|
||||
[i(d1_src_t::m2 )] = "m2" ,
|
||||
[i(d1_src_t::m3 )] = "m3" ,
|
||||
[i(d1_src_t::mc0)] = "mc0",
|
||||
[i(d1_src_t::mc1)] = "mc1",
|
||||
[i(d1_src_t::mc2)] = "mc2",
|
||||
[i(d1_src_t::mc3)] = "mc3",
|
||||
[i(d1_src_t::all)] = "all",
|
||||
[i(d1_src_t::alh)] = "alh",
|
||||
[i(d1_src_t::m0 )] = "m0" ,
|
||||
[i(d1_src_t::m1 )] = "m1" ,
|
||||
[i(d1_src_t::m2 )] = "m2" ,
|
||||
[i(d1_src_t::m3 )] = "m3" ,
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,52 +0,0 @@
|
||||
DSPASM = dspasm.exe
|
||||
|
||||
SRC = sample1.asm sample2a.asm sample2b.asm sample3.asm
|
||||
SRC += cmpnm.asm fbtrans.asm loop_pr.asm udiv.asm
|
||||
EXPECT = $(patsubst %.asm,expect/%.bin,$(SRC))
|
||||
ACTUAL = $(patsubst %.asm,actual/%.bin,$(SRC))
|
||||
ALL = $(EXPECT) $(ACTUAL)
|
||||
ALL_TXT = $(patsubst %.bin,%.txt,$(ALL))
|
||||
|
||||
all: $(ALL)
|
||||
all-txt: $(ALL_TXT)
|
||||
|
||||
%.s: %.asm
|
||||
@test -f $(DSPASM) || (echo $(DSPASM) does not exist--set the DSPASM make variable; exit 1)
|
||||
@rm -f $@
|
||||
echo '[autoexec]' > $@.conf
|
||||
echo 'mount C $(dir $(DSPASM))' >> $@.conf
|
||||
echo 'mount D $(dir $<)' >> $@.conf
|
||||
echo 'D:' >> $@.conf
|
||||
echo 'C:\$(notdir $(DSPASM)) $(notdir $<) $(notdir $@)' >> $@.conf
|
||||
echo 'exit' >> $@.conf
|
||||
dosbox -conf $@.conf
|
||||
@rm $@.conf
|
||||
mv $(shell echo '$@' | tr '[:lower:]' '[:upper:]') $@
|
||||
|
||||
%.txt: %.bin
|
||||
python bin-dump.py $< > $@
|
||||
|
||||
%.txt: %.bin
|
||||
python bin-dump.py $< > $@
|
||||
|
||||
expect/%.bin: %.s
|
||||
@mkdir -p $(dir $@)
|
||||
srec_cat -Output $@ -Binary $<
|
||||
|
||||
actual/%.bin: %.asm
|
||||
@mkdir -p $(dir $@)
|
||||
../main $< $@
|
||||
|
||||
clean:
|
||||
rm -f expect/*.{bin,txt} actual/*.{bin,txt} *.s
|
||||
|
||||
.SUFFIXES:
|
||||
.INTERMEDIATE:
|
||||
.SECONDARY:
|
||||
.PHONY: all clean
|
||||
|
||||
%: RCS/%,v
|
||||
%: RCS/%
|
||||
%: %,v
|
||||
%: s.%
|
||||
%: SCCS/s.%
|
@ -1,12 +0,0 @@
|
||||
import sys
|
||||
import struct
|
||||
|
||||
with open(sys.argv[1], 'rb') as f:
|
||||
b = f.read()
|
||||
|
||||
assert len(b) % 4 == 0, len(b)
|
||||
|
||||
for i in range(len(b) // 4):
|
||||
word = b[i*4:i*4+4]
|
||||
n, = struct.unpack('>I', word)
|
||||
print(f'{n:>032b}')
|
Loading…
x
Reference in New Issue
Block a user