Skip to content

Commit 3a38805

Browse files
committed
Add network_init and fix json reading correct number of bytes
1 parent 897d238 commit 3a38805

File tree

10 files changed

+94
-25
lines changed

10 files changed

+94
-25
lines changed

Changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22

33
## [Unreleased]
44

5+
## [2.1.3] - 2024-01-03
6+
57
### Changed
68

79
- [apple2] sp_init looks from slot 7 down to 1 instead of up from 1 to 7
810
- [apple2] sp_init now additionally looks for an SP card WITH the network adapter on it, which should skip other installed SP devices
911
- [apple2] sp_init only runs once and stores network id, close no longer resets it.
1012
- lots of tests fixed (cycle count errors mostly)
13+
- add network_init to detect network errors early. Implemented on APPLE2, nop on atari.
14+
Note: network_open still checks if appropriate init has happened on apple, but network_init will do same thing first, and then open will use the results from init.
1115

1216
## [2.1.2] - 2024-01-03
1317

apple2/src/fn_fuji/sp_init.s

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,17 @@
1414
.include "macros.inc"
1515
.include "zp.inc"
1616

17-
; uint8_t sp_init();
17+
; int8_t sp_init();
1818
;
1919
; returns network slot if Smart Port initialised and has a NETWORK adapter
20-
; otherwise 0.
20+
; otherwise 0 if there were no errors but no SP device, else the -ve value of the device error from SP, as returned by sp_find_device.
2121
.proc _sp_init
22-
mva #$01, _sp_is_init
22+
mva #$01, _sp_is_init ; we assume you can only call init once. No devices are mounted after powerup
2323
mva #$00, _sp_network
24+
sta last_sp_error
2425

2526
; find a device slot that has Smart Port with a NETWORK adapter
26-
; going from 7 down to 1, which is more likely to hit a FN device before some other RAM Card etc.
27+
; going from 7 down to 1, which is more likely to hit a FN device before some other RAM Card etc (thanks @ShunKita)
2728
mwa #$c700, ptr1
2829
ldx #$01
2930

@@ -52,12 +53,12 @@
5253
cpx #$08
5354
bne @all_slots
5455

55-
; not found, return 0 in A/X
56+
; not found, return value of last_sp_error, which will be -ve or 0 for the caller to know there was a device error or not
5657
; first, clear the dispatch function in case it was set when testing for a network device
5758
ldx #$00
5859
stx _sp_dispatch_fn
5960
stx _sp_dispatch_fn+1
60-
txa
61+
lda last_sp_error
6162
rts
6263

6364
@found_sp:
@@ -79,10 +80,15 @@
7980

8081
jsr _sp_find_network
8182
bpl @found_network
83+
beq :+
84+
85+
; we had a -ve value, which indicates a real SP error of some kind, capture it
86+
; so we can indicate the issue at the end if we didn't find a SP with network
87+
sta last_sp_error
8288

83-
; didn't find network, keep trying more slots
89+
; as we didn't find network, keep trying more slots
8490
; restore ptr1
85-
popax ptr1
91+
: popax ptr1
8692
; restore the id we last tried into X
8793
pla
8894
tax
@@ -94,6 +100,9 @@
94100
; a contains the found slot id of the network device
95101
sta _sp_network ; save the value for other functions to use
96102

103+
; if one of the potentially other SP devices was in error, we will ignore it, as we found the right one with network.
104+
mva #$00, last_sp_error
105+
97106
; fix the stack
98107
jsr incsp2 ; remove the ptr1 we saved for looping
99108
pla ; remove the old X index we saved for looping
@@ -102,4 +111,9 @@
102111
ldx #$00 ; high byte of return
103112
lda _sp_network ; low byte of return (and sets Z)
104113
rts
105-
.endproc
114+
.endproc
115+
116+
.data
117+
; store the last SP error we got.
118+
; we want to ensure any error from the last SP device detected that we discard is captured.
119+
last_sp_error: .byte 0

apple2/src/fn_network/network_json_query.s

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ not_empty:
126126

127127
; nul terminate the string
128128
adw tmp5, ptr4 ; set tmp5 to end of string
129+
sbw1 tmp5, #$01 ; remove 1 for the 0x9b char at the end of the result
129130
ldy #$00
130131
tya
131132
sta (tmp5), y

apple2/src/fn_network/network_status.s

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@
2323
;
2424
_network_status:
2525
; save A/X so we can restore them after clearing payload
26-
pha
27-
txa
28-
pha
29-
jsr _sp_clr_payload ; calls bzero, so trashes p1/2/3
30-
pla
31-
tax
32-
pla
26+
27+
; pha
28+
; txa
29+
; pha
30+
; jsr _sp_clr_payload ; calls bzero, so trashes p1/2/3
31+
; pla
32+
; tax
33+
; pla
34+
3335
; drop into no_clr version
3436

3537
_network_status_no_clr:

atari/src/fn_network/network_json_query.s

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323

2424
; uint8_t network_json_query(char *devicespec, char *query, char *s);
2525
;
26+
; TODO: how do we deal with very large json results? Maybe interface with network_read, which can handle them.
27+
; Or does sio_read work with any max size?
28+
2629
.proc _network_json_query
2730
axinto tmp6 ; save target string location
2831

@@ -65,9 +68,9 @@
6568
beq no_data
6669

6770
; read data, this sets _fn_bytes_read
68-
pusha tmp5
69-
pushax tmp6
70-
setax DVSTAT
71+
pusha tmp5 ; unit
72+
pushax tmp6 ; buffer
73+
setax DVSTAT ; length
7174
jsr _sio_read
7275
bne error
7376

atari/src/fn_network/sio_read.s

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
_sio_read:
1717
axinto ptr1 ; length
1818

19-
; this is wrong, we must set this in the network_read code, not here, as we could do more than 1 read for any connection, and need to accumulate
20-
; axinto _fn_bytes_read
19+
axinto _fn_bytes_read
2120

2221
setax #t_network_read
2322
jsr copy_nw_cmd_data ; setup DCB

common/src/network_init.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <stdint.h>
2+
#include <ctype.h>
3+
4+
#include "../../fujinet-network.h"
5+
6+
#ifdef BUILD_APPLE2
7+
#include "../../fujinet-network-apple2.h"
8+
#include "../../apple2/src/fn_fuji/inc/sp.h"
9+
#endif
10+
11+
uint8_t network_init()
12+
{
13+
int8_t err = 0;
14+
15+
#ifdef BUILD_APPLE2
16+
err = sp_init();
17+
if (err == 0) {
18+
return FN_ERR_NO_DEVICE;
19+
} else if (err > 0) {
20+
// The device was initialised correctly, and we found a network device
21+
return FN_ERR_OK;
22+
} else {
23+
// -ve value is the inverse of the SP error from sp_find_device
24+
return fn_error(-err);
25+
}
26+
#endif
27+
28+
return err;
29+
}

common/src/network_read.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ uint8_t network_read(char *devicespec, uint8_t *buf, uint16_t len)
2525
uint8_t r = 0;
2626
uint16_t fetch_size = 0;
2727
uint16_t amount_left = len;
28+
uint16_t total_read = 0;
2829
#ifdef BUILD_ATARI
2930
uint8_t unit = 0;
3031
#endif
@@ -75,7 +76,11 @@ uint8_t network_read(char *devicespec, uint8_t *buf, uint16_t len)
7576
}
7677

7778
fetch_size = MIN(amount_left, fn_network_bw);
78-
fetch_size = MIN(fetch_size, MAX_READ_SIZE); // should we always limit to MAX_READ_SIZE on all devices?
79+
80+
#ifdef BUILD_APPLE2
81+
// need to validate this is only required for apple
82+
fetch_size = MIN(fetch_size, MAX_READ_SIZE);
83+
#endif
7984

8085
#ifdef BUILD_ATARI
8186
sio_read(unit, buf, fetch_size);
@@ -88,8 +93,10 @@ uint8_t network_read(char *devicespec, uint8_t *buf, uint16_t len)
8893

8994
buf += fetch_size;
9095
amount_left -= fetch_size;
91-
fn_bytes_read += fetch_size;
96+
total_read += fetch_size;
9297
}
9398

99+
// do this here at the end, not in the loop so sio_read for atari can continue to set fn_bytes_read for short reads.
100+
fn_bytes_read = total_read;
94101
return 0;
95102
}

fujinet-network-apple2.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ void sp_clr_payload();
2424
int8_t sp_status(uint8_t dest, uint8_t statcode);
2525
int8_t sp_control(uint8_t dest, uint8_t ctrlcode);
2626
int8_t sp_read(uint8_t dest, uint16_t len);
27+
uint8_t sp_init();
2728

2829
uint8_t network_status_no_clr(char *devicespec, uint16_t *bw, uint8_t *c, uint8_t *err);
2930
uint8_t network_unit(char *devicespec);
3031

32+
3133
#endif

fujinet-network.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ extern uint16_t fn_bytes_read;
2323
extern uint8_t fn_device_error;
2424

2525
uint8_t fn_error(uint8_t code);
26-
2726
/*
2827
* Network status values. These are set during network_read. You can capture your own using network_status.
2928
* bw : bytes waiting
@@ -35,7 +34,15 @@ extern uint8_t fn_network_conn;
3534
extern uint8_t fn_network_error;
3635

3736
/**
38-
* @brief Get Network Device Status byte
37+
* @brief Initialise network device
38+
* Allows initialisation of network to perform any platform dependent checks, and allow applications to
39+
* exit early if there is a network issue.
40+
* @return fujinet-network status/error code (See FN_ERR_* values) and set device specific error if there is any
41+
*/
42+
uint8_t network_init();
43+
44+
/**
45+
* @brief Get Network Device Status byte
3946
* @param devicespec pointer to device specification of form: N:PROTO://[HOSTNAME]:PORT/PATH/.../
4047
* @param bw pointer to where to put bytes waiting
4148
* @param c pointer to where to put connection status
@@ -184,6 +191,7 @@ uint8_t network_http_delete(char *devicespec, uint8_t trans);
184191
#define FN_ERR_BAD_CMD (0x02) /* Function called with bad arguments */
185192
#define FN_ERR_OFFLINE (0x03) /* The device is offline */
186193
#define FN_ERR_WARNING (0x04) /* Device specific non-fatal warning issued */
194+
#define FN_ERR_NO_DEVICE (0x05) /* There is no network device */
187195

188196
#define FN_ERR_UNKNOWN (0xff) /* Device specific error we didn't handle */
189197

0 commit comments

Comments
 (0)