diff --git a/64tass.c b/64tass.c index 00c9eb5..39ae6e9 100644 --- a/64tass.c +++ b/64tass.c @@ -1,6 +1,6 @@ /* Turbo Assembler 6502/65C02/65816/DTV - $Id: 64tass.c 2153 2020-02-01 14:21:10Z soci $ + $Id: 64tass.c 2156 2020-03-08 12:44:05Z soci $ 6502/65C02 Turbo Assembler Version 1.3 (c) 1996 Taboo Productions, Marek Matula @@ -4073,17 +4073,11 @@ MUST_CHECK Obj *compile(void) case CMD_CPU: if ((waitfor->skip & 1) != 0) { /* .cpu */ struct values_s *vs; - const struct cpu_list_s { - const char *name; - const struct cpu_s *def; - } *cpui; - static const struct cpu_list_s cpus[] = { - {"6502", &c6502}, {"65c02", &c65c02}, - {"65ce02", &c65ce02}, {"6502i", &c6502i}, - {"65816", &w65816}, {"65dtv02", &c65dtv02}, - {"65el02", &c65el02}, {"r65c02", &r65c02}, - {"w65c02", &w65c02}, {"4510", &c4510}, - {"default", NULL}, {NULL, NULL}, + const struct cpu_s **cpui; + static const struct cpu_s default_cpu = {"default", NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}; + static const struct cpu_s *cpus[] = { + &c6502, &c65c02, &c65ce02, &c6502i, &w65816, &c65dtv02, + &c65el02, &r65c02, &w65c02, &c4510, &default_cpu, NULL }; str_t cpuname; @@ -4092,9 +4086,9 @@ MUST_CHECK Obj *compile(void) if (!get_exp(0, 1, 1, &epoint)) goto breakerr; vs = get_val(); if (tostr(vs, &cpuname)) break; - for (cpui = cpus; cpui->name != NULL; cpui++) { - if (cpuname.len == strlen(cpui->name) && memcmp(cpui->name, cpuname.data, cpuname.len) == 0) { - const struct cpu_s *cpumode = (cpui->def != NULL) ? cpui->def : arguments.cpumode; + for (cpui = cpus; *cpui != NULL; cpui++) { + if (cpuname.len == strlen((*cpui)->name) && memcmp((*cpui)->name, cpuname.data, cpuname.len) == 0) { + const struct cpu_s *cpumode = (*cpui != &default_cpu) ? *cpui : arguments.cpumode; if (current_address->l_address.bank > cpumode->max_address) { err_msg_big_address(&epoint); current_address->l_address.bank &= cpumode->max_address; @@ -4103,7 +4097,7 @@ MUST_CHECK Obj *compile(void) break; } } - if (cpui->name == NULL) err_msg2(ERROR___UNKNOWN_CPU, &cpuname, &vs->epoint); + if (*cpui == NULL) err_msg2(ERROR___UNKNOWN_CPU, &cpuname, &vs->epoint); } break; case CMD_PRON: /* .pron */ diff --git a/README b/README index 4c88026..9789b10 100644 --- a/README +++ b/README @@ -424,10 +424,11 @@ Byte string constants Byte strings are like character strings, but hold bytes instead of characters. -Quoted character strings prefixing by `b', `l', `n', `p', `s' or `x' characters -can be used to create byte strings. The resulting byte string contains what -.text, .shiftl, .null, .ptext and .shift would create. Direct hexadecimal entry -can be done using the `x' prefix which. +Quoted character strings prefixing by `b', `l', `n', `p', `s', `x' or `z' +characters can be used to create byte strings. The resulting byte string +contains what .text, .shiftl, .null, .ptext and .shift would create. Direct +hexadecimal entry can be done using the `x' prefix and `z' denotes a z85 +encoded byte string. Byte string operators and functions y .. x concatenate strings x"12" .. x"34" is x"1234" @@ -454,8 +455,25 @@ mystr = b"oeU" ;convert text to bytes, like .text .text l"p2" ;convert to bytes like .shiftl .text n"p3" ;convert to bytes like .null .text p"p4" ;convert to bytes like .ptext + +Binary data may be embedded in source code by using hexadecimal byte strings. +This is more compact than using .byte followed by a lot of numbers. As expected +1 byte becomes 2 characters. + .text x"fce2" ;2 bytes: $fc and $e2 (big endian) +If readability is not a concern then the more compact z85 encoding may be used +which encodes 4 bytes into 5 characters. Data lengths not a multiple of 4 are +handled by omitting leading zeros in the last group. + + .text z"FiUj*2M$hf";8 bytes: 80 40 20 10 08 04 02 01 + +For data lengths of multiple of 4 bytes any z85 encoder will do. Otherwise the +simplest way to encode a binary file into a z85 string is to create a source +file which reads it using the line `label = binary('filename')'. Now if the +labels are listed to a file then there will be a z85 encoded definition for +this label. + Lists and tuples Lists and tuples can hold a collection of values. Lists are defined from values @@ -2991,6 +3009,15 @@ Operation options This is useful for automatic dependency generation to avoid missing target errors on file rename. + The following Makefile uses the rules generated by 64tass (in `.dep') to + achieve automatic dependency tracking: + + demo: demo.asm .dep + 64tass --make-phony -M.dep $< -o $@ + + .dep: + -include .dep + -E , --error Specify error output file diff --git a/README.html b/README.html index 997a461..55a4c7f 100644 --- a/README.html +++ b/README.html @@ -583,11 +583,11 @@

Character string constants

Byte strings are like character strings, but hold bytes instead of characters.

-

Quoted character strings prefixing by b, l, n, p, s -or x characters can be used to create byte strings. The resulting byte +

Quoted character strings prefixing by b, l, n, p, s, x +or z characters can be used to create byte strings. The resulting byte string contains what .text, .shiftl, .null, .ptext and .shift would -create. Direct hexadecimal entry can be done using the x prefix which.

+create. Direct hexadecimal entry can be done using the x prefix and z denotes a z85 encoded byte string.

@@ -619,9 +619,30 @@

Byte string constants

.textl"p2";convert to bytes like .shiftl.textn"p3";convert to bytes like .null.textp"p4";convert to bytes like .ptext + + +

Binary data may be embedded in source code by using hexadecimal byte +strings. This is more compact than using .byte followed by a lot +of numbers. As expected 1 byte becomes 2 characters.

+ +
         .text x"fce2"   ;2 bytes: $fc and $e2 (big endian)
 
+

If readability is not a concern then the more compact z85 encoding may be used +which encodes 4 bytes into 5 characters. Data lengths not a multiple of 4 are +handled by omitting leading zeros in the last group.

+ +
+        .text z"FiUj*2M$hf";8 bytes: 80 40 20 10 08 04 02 01
+
+ +

For data lengths of multiple of 4 bytes any z85 encoder will do. Otherwise the +simplest way to encode a binary file into a z85 string is to create a source file +which reads it using the line label = binary('filename'). Now if the labels +are listed to a file then there will be a z85 encoded definition for this +label.

+

Lists and tuples

Lists and tuples can hold a collection of values. Lists are defined from @@ -3422,6 +3443,17 @@

Operation options +demo: demo.asm .dep + 64tass --make-phony -M.dep $< -o $@ + +.dep: +-include .dep + +
-E <file>, --error <file>
Specify error output file

Normally compilation errors a written to the standard error output. diff --git a/boolobj.c b/boolobj.c index c65ccc7..facb4ae 100644 --- a/boolobj.c +++ b/boolobj.c @@ -1,5 +1,5 @@ /* - $Id: boolobj.c 2122 2019-12-21 06:27:50Z soci $ + $Id: boolobj.c 2155 2020-03-08 09:33:08Z soci $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -89,14 +89,14 @@ static MUST_CHECK Obj *repr(Obj *o1, linepos_t UNUSED(epoint), size_t maxsize) { return val_reference(&v->v); } -static MUST_CHECK Error *ival(Obj *o1, ival_t *iv, unsigned int bits, linepos_t epoint) { - if (diagnostics.strict_bool) err_msg_bool_val(ERROR_____CANT_IVAL, bits, o1, epoint); +static MUST_CHECK Error *ival(Obj *o1, ival_t *iv, unsigned int UNUSED(bits), linepos_t epoint) { + if (diagnostics.strict_bool) err_msg_bool(ERROR______CANT_INT, o1, epoint); *iv = (Bool *)o1 == true_value ? 1 : 0; return NULL; } -static MUST_CHECK Error *uval(Obj *o1, uval_t *uv, unsigned int bits, linepos_t epoint) { - if (diagnostics.strict_bool) err_msg_bool_val(ERROR_____CANT_UVAL, bits, o1, epoint); +static MUST_CHECK Error *uval(Obj *o1, uval_t *uv, unsigned int UNUSED(bits), linepos_t epoint) { + if (diagnostics.strict_bool) err_msg_bool(ERROR______CANT_INT, o1, epoint); *uv = (Bool *)o1 == true_value ? 1 : 0; return NULL; } diff --git a/error.c b/error.c index d9eec28..9bfdc77 100644 --- a/error.c +++ b/error.c @@ -1,5 +1,5 @@ /* - $Id: error.c 2098 2019-11-24 05:07:52Z soci $ + $Id: error.c 2155 2020-03-08 09:33:08Z soci $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1176,12 +1176,6 @@ void err_msg_bool(Error_types no, Obj *o, linepos_t epoint) { adderror(" [-Wstrict-bool]"); } -void err_msg_bool_val(Error_types no, unsigned int bits, Obj *o, linepos_t epoint) { - new_error_msg2(diagnostic_errors.strict_bool, epoint); - err_msg_big_integer(terr_error[no - 0x40], bits, o); - adderror(" [-Wstrict-bool]"); -} - void err_msg_bool_oper(oper_t op) { new_error_msg2(diagnostic_errors.strict_bool, op->epoint3); err_msg_invalid_oper2(op->op, op->v1, op->v2); diff --git a/error.h b/error.h index b119eb6..a98b4e7 100644 --- a/error.h +++ b/error.h @@ -1,5 +1,5 @@ /* - $Id: error.h 2043 2019-10-27 19:43:15Z soci $ + $Id: error.h 2155 2020-03-08 09:33:08Z soci $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -86,7 +86,6 @@ extern void err_msg_output_and_destroy(struct Error *); extern void err_msg_argnum(size_t, size_t, size_t, linepos_t); extern void err_msg_bool(Error_types, struct Obj *, linepos_t); extern void err_msg_bool_oper(struct oper_s *); -extern void err_msg_bool_val(Error_types, unsigned int, struct Obj *, linepos_t); extern void err_msg_implied_reg(linepos_t, uint32_t); extern void err_msg_jmp_bug(linepos_t); extern void err_msg_pc_wrap(linepos_t); diff --git a/opcodes.c b/opcodes.c index 7021b45..a57dc41 100644 --- a/opcodes.c +++ b/opcodes.c @@ -1,5 +1,5 @@ /* - $Id: opcodes.c 2098 2019-11-24 05:07:52Z soci $ + $Id: opcodes.c 2156 2020-03-08 12:44:05Z soci $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -94,6 +94,7 @@ static const uint8_t alias_w65816[] = { }; const struct cpu_s w65816 = { + "65816", mnemonic_w65816, opcode_w65816, disasm_w65816, @@ -169,6 +170,7 @@ static const uint8_t alias_c6502[] = { }; const struct cpu_s c6502 = { + "6502", mnemonic_c6502, opcode_c6502, disasm_c6502, @@ -248,6 +250,7 @@ static const uint8_t alias_c65c02[] = { }; const struct cpu_s c65c02 = { + "65c02", mnemonic_c65c02, opcode_c65c02, disasm_c65c02, @@ -331,6 +334,7 @@ static const uint8_t alias_c6502i[] = { }; const struct cpu_s c6502i = { + "6502i", mnemonic_c6502i, opcode_c6502i, disasm_c6502i, @@ -411,6 +415,7 @@ static const uint8_t alias_c65dtv02[] = { }; const struct cpu_s c65dtv02 = { + "65dtv02", mnemonic_c65dtv02, opcode_c65dtv02, disasm_c65dtv02, @@ -499,6 +504,7 @@ static const uint8_t alias_c65el02[] = { }; const struct cpu_s c65el02 = { + "65el02", mnemonic_c65el02, opcode_c65el02, disasm_c65el02, @@ -578,6 +584,7 @@ static const uint8_t alias_r65c02[] = { }; const struct cpu_s r65c02 = { + "r65c02", mnemonic_r65c02, opcode_r65c02, disasm_r65c02, @@ -658,6 +665,7 @@ static const uint8_t alias_w65c02[] = { }; const struct cpu_s w65c02 = { + "w65c02", mnemonic_w65c02, opcode_w65c02, disasm_w65c02, @@ -742,6 +750,7 @@ static const uint8_t alias_c65ce02[] = { }; const struct cpu_s c65ce02 = { + "65ce02", mnemonic_c65ce02, opcode_c65ce02, disasm_c65ce02, @@ -826,6 +835,7 @@ static const uint8_t alias_c4510[] = { }; const struct cpu_s c4510 = { + "4510", mnemonic_c4510, opcode_c4510, disasm_c4510, diff --git a/opcodes.h b/opcodes.h index 3c30eef..d840939 100644 --- a/opcodes.h +++ b/opcodes.h @@ -1,5 +1,5 @@ /* - $Id: opcodes.h 2098 2019-11-24 05:07:52Z soci $ + $Id: opcodes.h 2156 2020-03-08 12:44:05Z soci $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -34,6 +34,7 @@ typedef enum Reg_types { } Reg_types; struct cpu_s { + const char *name; const uint32_t *mnemonic; const uint8_t *opcode; const uint16_t *disasm;

Byte string operators and functions