Because `cmd` is guaranteed by the compiler to be NULL-terminated, we can make use of that to ensure the loop always ends.
So we don't need to know when the next words starts.
Fix declaration of tx_buf_empty bit var
__sbit is for SFRs, for regular data __bit should be used. Otherwise the variables is not correctly declared in the BSEG section, leading to bit temporaries being allocated in the same location.
When this causes the tx_buf_empty to be overwritten to 0, then the next write_char will hang forever.
With this change the bit is properly declared in BSEG for the linker, which in my testing resolves the overlap issue:
```
;--------------------------------------------------------
; bit data
;--------------------------------------------------------
.area BSEG (BIT)
_tx_buf_empty::
.ds 1
```
Only the vlan and mtu commands call atoi_short, which has a local bit _atoi_short_sloc0_1_0 which is the first bit in the BSEG, and assigning to that one corrupted the tx_buf_empty bit.
Though this is also a compiler optimization-failure, the _atoi_short_sloc0_1_0 value isn't even used after assignment, AFAICS it is a dead store.
Its from the isnumber inline:
```
[...]
;--------------------------------------------------------
; bit data
;--------------------------------------------------------
.area BSEG (BIT)
_atoi_short_sloc0_1_0:
.ds 1
_parse_ip_sloc0_1_0:
.ds 1
[...]
; cmd_parser.c:85: l -= '0';
mov r3,a
add a,#0xd0
; cmd_parser.c:86: return (l <= ('9'-'0'));
add a,#0xff - 0x09
cpl c
; cmd_parser.c:172: while (isnumber(cmd_buffer[idx])) {
mov _atoi_short_sloc0_1_0,c
jnc 00103$
[...]
```
__sbit is for SFRs, for regular data __bit should be used.
Otherwise the variables is not correctly declared in the BSEG
section, leading to bit temporaries being allocated in the same
location.
When this causes the tx_buf_empty to be overwritten to 0, then
the next write_char will hang forever.
This splits the current MACHINE_KP_9000_9XHML_X definition into "V2_2"
and "V3_1" versions for the two known versions of this hardware.
Confirmed to work:
- LED configuration matches stock firmware
- Port ordering matches label
- A SFP can be detected and EEPROM read (I don't have a fiber cable to test link)
- Reset button presses are detected
While the current implementation works for what it is actually used, it
is broken when trying to do larger transfers.
The length field in the control register has a size of 4 bits. In every
transfer, length+1 bytes are read. Thus, each transfer is limited to a
maximum of 16 bytes. Add a check for the length, and write the correct
value to the register.
Also update the loop in "sfp_send_data" to properly increment the output
register. Remove the unused special case for a length of 128 bytes.