diff --git a/README.md b/README.md index b1e85fb6..c118f538 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,9 @@ Usage: customasm [options] ... Options: -f, --format FORMAT The format of the output file. Possible formats: - binary, binstr, hexstr, bindump, hexdump, mif + binary, binstr, hexstr, bindump, hexdump, + mif, intelhex + -o, --output FILE The name of the output file. -p, --print Print output to stdout instead of writing to a file. -q, --quiet Suppress progress reports. diff --git a/src/asm/binary_output.rs b/src/asm/binary_output.rs index 3d8f001e..8b0b574d 100644 --- a/src/asm/binary_output.rs +++ b/src/asm/binary_output.rs @@ -235,4 +235,49 @@ impl BinaryOutput result.push_str("END;"); result } + + + pub fn generate_intelhex(&self, start_bit: usize, end_bit: usize) -> String + { + let mut result = String::new(); + + let mut bytes_left = (end_bit - start_bit) / 8 + if (end_bit - start_bit) % 8 != 0 { 1 } else { 0 }; + + let mut index = start_bit; + while index < end_bit + { + let bytes_in_row = if bytes_left > 32 { 32 } else { bytes_left }; + + result.push(':'); + result.push_str(&format!("{:02X}", bytes_in_row)); + result.push_str(&format!("{:04X}", index / 8)); + result.push_str("00"); + + let mut checksum = 0_u8; + checksum = checksum.wrapping_add(bytes_in_row as u8); + checksum = checksum.wrapping_add(((index / 8) >> 8) as u8); + checksum = checksum.wrapping_add((index / 8) as u8); + + for _ in 0..bytes_in_row + { + let mut byte: u8 = 0; + for _ in 0..8 + { + byte <<= 1; + byte |= if self.read(index) { 1 } else { 0 }; + index += 1; + } + + result.push_str(&format!("{:02X}", byte)); + checksum = checksum.wrapping_add(byte); + } + + bytes_left -= bytes_in_row; + result.push_str(&format!("{:02X}", (!checksum).wrapping_add(1))); + result.push('\n'); + } + + result.push_str(":00000001FF"); + result + } } \ No newline at end of file diff --git a/src/driver.rs b/src/driver.rs index d0ad5a0d..101f9c73 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -15,6 +15,7 @@ enum OutputFormat BinDump, HexDump, Mif, + IntelHex, } @@ -63,12 +64,13 @@ fn drive_inner(report: RcReport, opts: &getopts::Options, args: &Vec, fi let out_format = match matches.opt_str("f").as_ref().map(|s| s.as_ref()) { - Some("binstr") => OutputFormat::BinStr, - Some("bindump") => OutputFormat::BinDump, - Some("hexstr") => OutputFormat::HexStr, - Some("hexdump") => OutputFormat::HexDump, - Some("binary") => OutputFormat::Binary, - Some("mif") => OutputFormat::Mif, + Some("binstr") => OutputFormat::BinStr, + Some("bindump") => OutputFormat::BinDump, + Some("hexstr") => OutputFormat::HexStr, + Some("hexdump") => OutputFormat::HexDump, + Some("binary") => OutputFormat::Binary, + Some("mif") => OutputFormat::Mif, + Some("intelhex") => OutputFormat::IntelHex, None => if out_stdout { OutputFormat::HexDump } @@ -108,12 +110,13 @@ fn drive_inner(report: RcReport, opts: &getopts::Options, args: &Vec, fi let output_data = match out_format { - OutputFormat::Binary => assembled.generate_binary (0, assembled.len()), - OutputFormat::BinStr => assembled.generate_binstr (0, assembled.len()).bytes().collect::>(), - OutputFormat::BinDump => assembled.generate_bindump(0, assembled.len()).bytes().collect::>(), - OutputFormat::HexStr => assembled.generate_hexstr (0, assembled.len()).bytes().collect::>(), - OutputFormat::HexDump => assembled.generate_hexdump(0, assembled.len()).bytes().collect::>(), - OutputFormat::Mif => assembled.generate_mif (0, assembled.len()).bytes().collect::>(), + OutputFormat::Binary => assembled.generate_binary (0, assembled.len()), + OutputFormat::BinStr => assembled.generate_binstr (0, assembled.len()).bytes().collect::>(), + OutputFormat::BinDump => assembled.generate_bindump (0, assembled.len()).bytes().collect::>(), + OutputFormat::HexStr => assembled.generate_hexstr (0, assembled.len()).bytes().collect::>(), + OutputFormat::HexDump => assembled.generate_hexdump (0, assembled.len()).bytes().collect::>(), + OutputFormat::Mif => assembled.generate_mif (0, assembled.len()).bytes().collect::>(), + OutputFormat::IntelHex => assembled.generate_intelhex(0, assembled.len()).bytes().collect::>(), }; if out_stdout @@ -142,7 +145,7 @@ fn drive_inner(report: RcReport, opts: &getopts::Options, args: &Vec, fi fn make_opts() -> getopts::Options { let mut opts = getopts::Options::new(); - opts.optopt("f", "format", "The format of the output file. Possible formats: binary, binstr, hexstr, bindump, hexdump, mif", "FORMAT"); + opts.optopt("f", "format", "The format of the output file. Possible formats: binary, binstr, hexstr, bindump, hexdump, mif, intelhex", "FORMAT"); opts.optmulti("i", "include", "Specifies an additional file for processing before the given . [deprecated]", "FILE"); opts.optopt("o", "output", "The name of the output file.", "FILE"); opts.optflag("p", "print", "Print output to stdout instead of writing to a file."); diff --git a/src/webasm/mod.rs b/src/webasm/mod.rs index 56af9ea7..806bb7af 100644 --- a/src/webasm/mod.rs +++ b/src/webasm/mod.rs @@ -22,11 +22,12 @@ pub unsafe extern fn wasm_assemble(format: u32, src: *mut String) -> *mut String let output = asm.get_binary_output(); match format { - 0 => Ok(output.generate_hexdump(0, output.len())), - 1 => Ok(output.generate_bindump(0, output.len())), - 2 => Ok(output.generate_hexstr (0, output.len())), - 3 => Ok(output.generate_binstr (0, output.len())), - 4 => Ok(output.generate_mif (0, output.len())), + 0 => Ok(output.generate_hexdump (0, output.len())), + 1 => Ok(output.generate_bindump (0, output.len())), + 2 => Ok(output.generate_hexstr (0, output.len())), + 3 => Ok(output.generate_binstr (0, output.len())), + 4 => Ok(output.generate_mif (0, output.len())), + 5 => Ok(output.generate_intelhex(0, output.len())), _ => unreachable!() } }; diff --git a/web/index.html b/web/index.html index 6b004cfd..53152c30 100644 --- a/web/index.html +++ b/web/index.html @@ -95,6 +95,7 @@ +