Skip to content

Commit

Permalink
Add network_init and fix json reading correct number of bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
markjfisher committed Jan 4, 2024
1 parent 897d238 commit 3a38805
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 25 deletions.
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

## [Unreleased]

## [2.1.3] - 2024-01-03

### Changed

- [apple2] sp_init looks from slot 7 down to 1 instead of up from 1 to 7
- [apple2] sp_init now additionally looks for an SP card WITH the network adapter on it, which should skip other installed SP devices
- [apple2] sp_init only runs once and stores network id, close no longer resets it.
- lots of tests fixed (cycle count errors mostly)
- add network_init to detect network errors early. Implemented on APPLE2, nop on atari.
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.

## [2.1.2] - 2024-01-03

Expand Down
32 changes: 23 additions & 9 deletions apple2/src/fn_fuji/sp_init.s
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@
.include "macros.inc"
.include "zp.inc"

; uint8_t sp_init();
; int8_t sp_init();
;
; returns network slot if Smart Port initialised and has a NETWORK adapter
; otherwise 0.
; 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.
.proc _sp_init
mva #$01, _sp_is_init
mva #$01, _sp_is_init ; we assume you can only call init once. No devices are mounted after powerup
mva #$00, _sp_network
sta last_sp_error

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

Expand Down Expand Up @@ -52,12 +53,12 @@
cpx #$08
bne @all_slots

; not found, return 0 in A/X
; 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
; first, clear the dispatch function in case it was set when testing for a network device
ldx #$00
stx _sp_dispatch_fn
stx _sp_dispatch_fn+1
txa
lda last_sp_error
rts

@found_sp:
Expand All @@ -79,10 +80,15 @@

jsr _sp_find_network
bpl @found_network
beq :+

; we had a -ve value, which indicates a real SP error of some kind, capture it
; so we can indicate the issue at the end if we didn't find a SP with network
sta last_sp_error

; didn't find network, keep trying more slots
; as we didn't find network, keep trying more slots
; restore ptr1
popax ptr1
: popax ptr1
; restore the id we last tried into X
pla
tax
Expand All @@ -94,6 +100,9 @@
; a contains the found slot id of the network device
sta _sp_network ; save the value for other functions to use

; if one of the potentially other SP devices was in error, we will ignore it, as we found the right one with network.
mva #$00, last_sp_error

; fix the stack
jsr incsp2 ; remove the ptr1 we saved for looping
pla ; remove the old X index we saved for looping
Expand All @@ -102,4 +111,9 @@
ldx #$00 ; high byte of return
lda _sp_network ; low byte of return (and sets Z)
rts
.endproc
.endproc

.data
; store the last SP error we got.
; we want to ensure any error from the last SP device detected that we discard is captured.
last_sp_error: .byte 0
1 change: 1 addition & 0 deletions apple2/src/fn_network/network_json_query.s
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ not_empty:

; nul terminate the string
adw tmp5, ptr4 ; set tmp5 to end of string
sbw1 tmp5, #$01 ; remove 1 for the 0x9b char at the end of the result
ldy #$00
tya
sta (tmp5), y
Expand Down
16 changes: 9 additions & 7 deletions apple2/src/fn_network/network_status.s
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
;
_network_status:
; save A/X so we can restore them after clearing payload
pha
txa
pha
jsr _sp_clr_payload ; calls bzero, so trashes p1/2/3
pla
tax
pla

; pha
; txa
; pha
; jsr _sp_clr_payload ; calls bzero, so trashes p1/2/3
; pla
; tax
; pla

; drop into no_clr version

_network_status_no_clr:
Expand Down
9 changes: 6 additions & 3 deletions atari/src/fn_network/network_json_query.s
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@

; uint8_t network_json_query(char *devicespec, char *query, char *s);
;
; TODO: how do we deal with very large json results? Maybe interface with network_read, which can handle them.
; Or does sio_read work with any max size?

.proc _network_json_query
axinto tmp6 ; save target string location

Expand Down Expand Up @@ -65,9 +68,9 @@
beq no_data

; read data, this sets _fn_bytes_read
pusha tmp5
pushax tmp6
setax DVSTAT
pusha tmp5 ; unit
pushax tmp6 ; buffer
setax DVSTAT ; length
jsr _sio_read
bne error

Expand Down
3 changes: 1 addition & 2 deletions atari/src/fn_network/sio_read.s
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
_sio_read:
axinto ptr1 ; length

; 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
; axinto _fn_bytes_read
axinto _fn_bytes_read

setax #t_network_read
jsr copy_nw_cmd_data ; setup DCB
Expand Down
29 changes: 29 additions & 0 deletions common/src/network_init.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <stdint.h>
#include <ctype.h>

#include "../../fujinet-network.h"

#ifdef BUILD_APPLE2
#include "../../fujinet-network-apple2.h"
#include "../../apple2/src/fn_fuji/inc/sp.h"
#endif

uint8_t network_init()
{
int8_t err = 0;

#ifdef BUILD_APPLE2
err = sp_init();
if (err == 0) {
return FN_ERR_NO_DEVICE;
} else if (err > 0) {
// The device was initialised correctly, and we found a network device
return FN_ERR_OK;
} else {
// -ve value is the inverse of the SP error from sp_find_device
return fn_error(-err);
}
#endif

return err;
}
11 changes: 9 additions & 2 deletions common/src/network_read.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ uint8_t network_read(char *devicespec, uint8_t *buf, uint16_t len)
uint8_t r = 0;
uint16_t fetch_size = 0;
uint16_t amount_left = len;
uint16_t total_read = 0;
#ifdef BUILD_ATARI
uint8_t unit = 0;
#endif
Expand Down Expand Up @@ -75,7 +76,11 @@ uint8_t network_read(char *devicespec, uint8_t *buf, uint16_t len)
}

fetch_size = MIN(amount_left, fn_network_bw);
fetch_size = MIN(fetch_size, MAX_READ_SIZE); // should we always limit to MAX_READ_SIZE on all devices?

#ifdef BUILD_APPLE2
// need to validate this is only required for apple
fetch_size = MIN(fetch_size, MAX_READ_SIZE);
#endif

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

buf += fetch_size;
amount_left -= fetch_size;
fn_bytes_read += fetch_size;
total_read += fetch_size;
}

// 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.
fn_bytes_read = total_read;
return 0;
}
2 changes: 2 additions & 0 deletions fujinet-network-apple2.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ void sp_clr_payload();
int8_t sp_status(uint8_t dest, uint8_t statcode);
int8_t sp_control(uint8_t dest, uint8_t ctrlcode);
int8_t sp_read(uint8_t dest, uint16_t len);
uint8_t sp_init();

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


#endif
12 changes: 10 additions & 2 deletions fujinet-network.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ extern uint16_t fn_bytes_read;
extern uint8_t fn_device_error;

uint8_t fn_error(uint8_t code);

/*
* Network status values. These are set during network_read. You can capture your own using network_status.
* bw : bytes waiting
Expand All @@ -35,7 +34,15 @@ extern uint8_t fn_network_conn;
extern uint8_t fn_network_error;

/**
* @brief Get Network Device Status byte
* @brief Initialise network device
* Allows initialisation of network to perform any platform dependent checks, and allow applications to
* exit early if there is a network issue.
* @return fujinet-network status/error code (See FN_ERR_* values) and set device specific error if there is any
*/
uint8_t network_init();

/**
* @brief Get Network Device Status byte
* @param devicespec pointer to device specification of form: N:PROTO://[HOSTNAME]:PORT/PATH/.../
* @param bw pointer to where to put bytes waiting
* @param c pointer to where to put connection status
Expand Down Expand Up @@ -184,6 +191,7 @@ uint8_t network_http_delete(char *devicespec, uint8_t trans);
#define FN_ERR_BAD_CMD (0x02) /* Function called with bad arguments */
#define FN_ERR_OFFLINE (0x03) /* The device is offline */
#define FN_ERR_WARNING (0x04) /* Device specific non-fatal warning issued */
#define FN_ERR_NO_DEVICE (0x05) /* There is no network device */

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

Expand Down

0 comments on commit 3a38805

Please sign in to comment.