__sdcc_banked_call and __sdcc_banked_ret were assembled into GSFINAL, which
sits in the startup path: GSINIT ends exactly where GSFINAL begins, so the
processor falls into it rather than being sent there. It works today only
because this object comes after every C object on the link line, so the
LJMP to __sdcc_program_startup is laid down first and the helpers land
behind it. Reordering that line, or moving main() into another module,
would put the helper body at the fallthrough address instead, and the board
would not come up out of a build that reports nothing wrong.
SDCC's own crtbank.asm declares the area order and then puts both symbols
in HOME, so the file takes that name and that preamble as well.
GSFINAL now holds the three byte jump and nothing else. Of 401 symbols 17
change address, every one in the startup region, and between the reset
vector and 0x0094 not a byte differs, so no interrupt vector is disturbed.
Run on a SWTGW218AS: it came back after about 42 seconds reporting the new
build, with its stored configuration byte identical and every link at the
speed it had before.
Mark create_build_dir as PHONY so directory creation is never skipped.
Also add html_data.h as order-only prerequisite to the .c pattern rule,
fixing another the race where httpd/httpd.c and httpd/page_impl.c are
compiled before the generated header exists.
Replace file-path prerequisite tools/output/fileadder with order-only
dependency on the tools PHONY target.
Also add tools as order-only dependency to the final .bin target which
invokes all of the tools.
Honor SOURCE_DATE_EPOCH, falling back to the HEAD commit date and then
to wall-clock when git is absent. Same-commit builds become
byte-identical (BUILD_DATE is baked into the image and covered by the
trailing CRC), which makes it possible to verify that a binary matches
a source tree.
Make defines defaults for commonly used variables, therefore
we need to check first how the variable was defined. If `default`
value was used, override it with our own default.
The presence of the main function is a hardcoded trigger in sdcc that causes
the interrupt vectors and atomic rollback helpers to be generated as part of
compilation of the file containing the main function.
This makes sure the runtime library is correctly initialized and reduces
crtstart.asm to contain only the banked call helpers.
To ensure that the __interrupt_vect in area HOME is located at the beginning
of the firmware, the linker flags are updated to set the HOME start to
0x00000 and the linker object order is modified to have rtlplayground.rel
first.
Generated code in rtlplayground.asm:
```
;--------------------------------------------------------
; interrupt vector
;--------------------------------------------------------
.area HOME (CODE)
__interrupt_vect:
ljmp __sdcc_gsinit_startup
ljmp _isr_ext0
.ds 5
ljmp _isr_timer0
.ds 5
ljmp _isr_ext1
.ds 5
reti
.ds 7
ljmp _isr_serial
.ds 5
ljmp _isr_timer2
.ds 5
reti
.ds 7
reti
.ds 7
ljmp _isr_ext2
.ds 5
ljmp _isr_ext3
; restartable atomic support routines
.ds 2
sdcc_atomic_exchange_rollback_start::
nop
nop
sdcc_atomic_exchange_pdata_impl:
movx a, @r0
mov r3, a
mov a, r2
movx @r0, a
sjmp sdcc_atomic_exchange_exit
nop
nop
sdcc_atomic_exchange_xdata_impl:
movx a, @dptr
mov r3, a
mov a, r2
movx @dptr, a
sjmp sdcc_atomic_exchange_exit
sdcc_atomic_compare_exchange_idata_impl:
mov a, @r0
cjne a, ar2, .+#5
mov a, r3
mov @r0, a
ret
nop
sdcc_atomic_compare_exchange_pdata_impl:
movx a, @r0
cjne a, ar2, .+#5
mov a, r3
movx @r0, a
ret
nop
sdcc_atomic_compare_exchange_xdata_impl:
movx a, @dptr
cjne a, ar2, .+#5
mov a, r3
movx @dptr, a
ret
sdcc_atomic_exchange_rollback_end::
sdcc_atomic_exchange_gptr_impl::
jnb b.6, sdcc_atomic_exchange_xdata_impl
mov r0, dpl
jb b.5, sdcc_atomic_exchange_pdata_impl
sdcc_atomic_exchange_idata_impl:
mov a, r2
xch a, @r0
mov dpl, a
ret
sdcc_atomic_exchange_exit:
mov dpl, r3
ret
sdcc_atomic_compare_exchange_gptr_impl::
jnb b.6, sdcc_atomic_compare_exchange_xdata_impl
mov r0, dpl
jb b.5, sdcc_atomic_compare_exchange_pdata_impl
sjmp sdcc_atomic_compare_exchange_idata_impl
```
The current code for entering commands via the serial CLI is completely
refactored and moved out of rtlplayground.c into a separate file cmd_edit.c
putting code into BANK2.
The serial ring buffer sbuf[] is now exclusively used for receiving
keys, including escape sequences (DEL will generate a 4-byte escape
sequence). The command is now held in cmd_buffer. This reduces
XMEM use, because the serial buffer can be much smaller.
Supported is only editing the current command line via backspace, del,
cursor left and right.
Because the code cannot distinguish escape sequences which are not yet
complete (because the serial isr has not yet put all characters into
the serial buffer) from the dozens of unsupported ones (F-keys/home,
Page up/down, cursor up/down...) they are ignored and remain in the
serial buffer until the ring-pointer overwrites them. This is standard
behaviour for consoles, which will print out garbage for unsupported
characters. In this implementation, the command line buffer and the
visible command line in the terminal are always synced, so garbage
can be removed again by ediing the line.
The code makes several redundant checks in order to prevent race-conditions
between the serial ISR and the comand-editing code.
The Makefile has the version number and generates a version.h which
has VERSION_SW define that looks like "v<VERSION>-g<GIT_SHORT_HASH>".
Software version shows at boot in the serial console.
And shown with command: `version`.
It can also be requested via `information.json`.
```
{
"ip_address": "192.168.10.247",
"ip_gateway": "192.168.10.1",
"ip_netmask": "255.255.255.0",
"mac_address": "1c:2a:a3:23:00:02",
"sw_ver": "v0.1.0-gd48235f",
"hw_ver": "SWGT024-V2.0"
}
```