90 lines
4.0 KiB
Markdown
90 lines
4.0 KiB
Markdown
# Sinclair Scientific Calculator Emulator alternative software written in Rust
|
|
|
|
Alternative implementation for [Sinclair Scientific calculator](https://wiki.hexadust.net/books/electronics/page/sinclair-scientific-calculator-emulator-1974) board.
|
|
|
|
## Build Instructions
|
|
|
|
1. Install prerequisites as described in the [`avr-hal` README] (`avr-gcc`, `avr-libc`, `avrdude`, [`ravedude`]).
|
|
2. Use `nightly-2024-03-22` toolchain.
|
|
2. Run `cargo build --release` to build the firmware (debug builds won't work for now).
|
|
3. Run `RAVEDUDE_PORT=/dev/ttyUSB0 cargo run --release` to flash the firmware to a connected board. If `ravedude` fails to detect your board, check its documentation at
|
|
<https://crates.io/crates/ravedude>.
|
|
4. `ravedude` will open a console session after flashing where you can interact with the UART console of your board.
|
|
|
|
[`avr-hal` README]: https://github.com/Rahix/avr-hal#readme
|
|
[`ravedude`]: https://crates.io/crates/ravedude
|
|
|
|
## License
|
|
|
|
- [LICENSE-APACHE](LICENSE-APACHE)
|
|
|
|
## Floating point support
|
|
|
|
### Error linking when using `f64`, `undefined reference to`:
|
|
|
|
```
|
|
__divdf3
|
|
__gedf2
|
|
__gtdf2
|
|
__ltdf2
|
|
__muldf3
|
|
__nedf2
|
|
__subdf3
|
|
|
|
```
|
|
|
|
Use `f32` as `f64` are not supported by `avr-libc`.
|
|
|
|
### Error linking `src/float/add.rs:161: more undefined references to 'core::panicking::panic' follow`
|
|
|
|
* Goes away when using `--release` builds
|
|
* https://github.com/rust-lang/compiler-builtins/issues/245
|
|
|
|
### Error `multiple definition of '__addsf3'`
|
|
|
|
```
|
|
(.text.avr-libc.fplib+0x2): multiple definition of `__addsf3';
|
|
avr-calc/target/avr-atmega328p/release/deps/libcompiler_builtins-ff74a4526ccb7313.rlib(compiler_builtins-ff74a4526ccb7313.compiler_builtins.63915e056af5b1f3-cgu.0.rcgu.o):
|
|
.cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.108/src/macros.rs:500: first defined here
|
|
```
|
|
|
|
```
|
|
objdump -t target/avr-atmega328p/release/deps/libcompiler_builtins-ff74a4526ccb7313.rlib | grep __addsf3
|
|
00000000 l d .text._ZN17compiler_builtins5float3add8__addsf317h33c25ff7dd1591e8E 00000000 .text._ZN17compiler_builtins5float3add8__addsf317h33c25ff7dd1591e8E
|
|
00000000 l d .text.__addsf3 00000000 .text.__addsf3
|
|
00000000 g F .text._ZN17compiler_builtins5float3add8__addsf317h33c25ff7dd1591e8E 0000085c .hidden _ZN17compiler_builtins5float3add8__addsf317h33c25ff7dd1591e8E
|
|
00000000 g F .text.__addsf3 00000006 .hidden __addsf3
|
|
```
|
|
|
|
* https://github.com/rust-lang/compiler-builtins/tree/master/compiler-builtins
|
|
* `compiler-builtins` also implements software floats and this collides with `libm` from `avr-lib`.
|
|
* It provides `__adddf3` and `__addsf3` but not `__divdf3` and others listed above?
|
|
* The `__addsf3` is provided by both libs, `avr-lib` does not provide `f64` variants and `builtins` some operations are missing?
|
|
* Compiling with no default libraries and just `libc` (for `mem*` functions) still does not work as it imports `__addsff3`:
|
|
```
|
|
= note: /usr/bin/avr-ld:
|
|
/usr/lib/gcc/avr/9.3.0/../../../../avr/lib/avr5/libc.a(addsf3.o): in function `__addsf3':
|
|
(.text.avr-libc.fplib+0x2): multiple definition of `__addsf3';
|
|
target/avr-atmega328p/release/deps/libcompiler_builtins-0dbc77ea0d873946.rlib(compiler_builtins-0dbc77ea0d873946.compiler_builtins.88514279ac67cc58-cgu.0.rcgu.o):index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.108/src/macros.rs:500: first defined here
|
|
```
|
|
|
|
### avr-libc
|
|
|
|
* https://github.com/avrdudes/avr-libc
|
|
* Only `f32` are implemented: https://github.com/avrdudes/avr-libc/tree/main/libm/fplib
|
|
|
|
The `atmega328p` uses libraries from `/usr/avr/lib/avr5/` and it contains `libm`.
|
|
|
|
`libm.a` contains all the missing symbols but with `sf` instead of `df`.
|
|
|
|
* `objdump -t /usr/avr/lib/avr5/libm.a | grep fp`
|
|
* `sf3` single (`f32`) float
|
|
* `df3` double (`f64`) float
|
|
* https://gcc.gnu.org/onlinedocs/gcc-3.4.0/gccint/Soft-float-library-routines.html
|
|
```
|
|
float __divsf3 (float a, float b)
|
|
double __divdf3 (double a, double b)
|
|
```
|
|
|
|
Setting `"no-default-libraries": true,` in `avr-specs/avr-atmega328p.json` excludes `libm`, adding `-lm` and `-lc` works.
|