Skip to content

Commit df98441

Browse files
committed
4.7.0 add fn_clock interface and atari/apple2 cc65 implementations
1 parent 0cbbc3c commit df98441

File tree

15 files changed

+421
-28
lines changed

15 files changed

+421
-28
lines changed

Changelog.md

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

33
## [Unreleased]
44

5+
## [4.7.0] - 2024-09-20
6+
7+
- [clock] a simple clock library to interface with FujiNet clock device with atari/apple2 (cc65) implementations
8+
59
## [4.6.2] - 2024-09-15
610

711
- [apple2 bus] refactor all sp_get_xxx functions, moving common code into sp_find_device

apple2/src/bus/cc65/sp_find_device.s

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
.export device_type_id
44
.export device_count
5-
.export device_id_idx
5+
.export _device_id_idx
66
.export tmp_orig_type
77

88
.import _sp_cmdlist
@@ -15,12 +15,11 @@
1515
.import pusha
1616
.import negax
1717
.import return0
18-
.import return1
1918

2019
.include "sp.inc"
2120
.include "zp.inc"
2221

23-
; bool sp_find_device();
22+
; uint8_t sp_find_device();
2423
; device_type_id contains the type id to search for
2524
; where type_id is the internal fujinet device type_id:
2625
; $10 = fujinet
@@ -69,7 +68,7 @@ have_count:
6968
sta device_count
7069

7170
lda #$01
72-
sta device_id_idx
71+
sta _device_id_idx
7372
device_loop:
7473
jsr pusha ; the current Device ID
7574
lda #$03
@@ -84,12 +83,12 @@ device_loop:
8483

8584
; found it, so return the current index
8685
ldx #$00
87-
lda device_id_idx
86+
lda _device_id_idx
8887
rts
8988

9089
not_found_yet:
91-
inc device_id_idx
92-
lda device_id_idx
90+
inc _device_id_idx
91+
lda _device_id_idx
9392
cmp device_count
9493
bcc device_loop
9594
beq device_loop
@@ -123,9 +122,11 @@ id_loc1 = *-2
123122

124123
beq not_found
125124

126-
; found it from searching, so return success after setting the id
125+
; found it from searching, so return the id after setting it
127126
jsr set_id
128-
jmp return1
127+
ldx #$00
128+
cmp #$00 ; set status registers for the return based on A's id value
129+
rts
129130

130131
not_found:
131132
tax ; set x to 0
@@ -136,9 +137,8 @@ id_loc2 = *-2
136137

137138
rts
138139

139-
140140
.bss
141141
device_type_id: .res 1
142142
device_count: .res 1
143-
device_id_idx: .res 1
143+
_device_id_idx: .res 1
144144
tmp_orig_type: .res 1

apple2/src/bus/cc65/sp_find_fuji.s

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,10 @@
66
.import _sp_payload
77
.import _sp_status
88

9-
.import device_id_idx
9+
.import _device_id_idx
1010
.import device_count
1111

1212
.import pusha
13-
.import return0
14-
.import return1
15-
16-
.macpack cpu
1713

1814
; uint8_t sp_get_fuji_id()
1915
_sp_get_fuji_id:
@@ -35,7 +31,7 @@ not_found_by_id:
3531
; assumes device_count is set from previous search by ID
3632
try_fallback:
3733
lda #$01
38-
sta device_id_idx
34+
sta _device_id_idx
3935

4036
device_loop:
4137
jsr pusha ; the current Device ID
@@ -63,12 +59,12 @@ device_loop:
6359

6460
; found it, so return the current index
6561
ldx #$00
66-
lda device_id_idx
62+
lda _device_id_idx
6763
bne :+
6864

6965
not_found_yet:
70-
inc device_id_idx
71-
lda device_id_idx
66+
inc _device_id_idx
67+
lda _device_id_idx
7268
cmp device_count
7369
bcc device_loop
7470
beq device_loop

apple2/src/bus/cc65/sp_read.s

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
.import _sp_cmdlist
44
.import sp_dispatch
5-
.import _sp_nw_unit
6-
.import _sp_payload
75

8-
.import popa
96
.import sp_rw_common
107

118
.include "sp.inc"
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
.export _clock_get_time
2+
3+
.import _sp_count
4+
.import _sp_get_clock_id
5+
.import _sp_payload
6+
.import _sp_status
7+
8+
.import incsp2
9+
.import popax
10+
.import pusha
11+
.import return0
12+
.import return1
13+
14+
.include "macros.inc"
15+
.include "zp.inc"
16+
17+
; uint8_t clock_get_time(uint8_t* time_data, TimeFormat format);
18+
19+
_clock_get_time:
20+
sta time_format ; format, save it where we need it! saves a BSS byte
21+
22+
; get the device id of the clock, this is stored in _sp_clock_id, but also returned so we can check if it failed (0 is error)
23+
jsr _sp_get_clock_id
24+
bne got_id
25+
26+
; no clock found, return 1 as an error (FN_ERR_IO_ERROR)
27+
; but first adjust the stack to remove the data pointer
28+
error:
29+
jsr incsp2
30+
jmp return1
31+
32+
got_id:
33+
; call sp_status(uint8_t dest, uint8_t statcode)
34+
sta tmp1 ; save the clock device id
35+
36+
; convert the time format to the appropriate device specific code.
37+
; SIMPLE_BINARY (0) -> 'T'
38+
; PRODOS_BINARY (1) -> 'P'
39+
; APETIME_TZ_BINARY (2) -> 'A'
40+
; APETIME_BINARY (3) -> 'B'
41+
; TZ_ISO_STRING (4) -> 'S'
42+
; UTC_ISO_STRING (5) -> 'Z'
43+
44+
ldx #$00
45+
time_format = *-1
46+
; ensure the value is valid
47+
cpx #$06
48+
bcs error
49+
pusha tmp1
50+
lda code_table, x
51+
52+
jsr _sp_status
53+
bne error
54+
55+
; results are in sp_payload, the clock data returned is small (4 to 26 bytes)
56+
; _sp_count holds the number of bytes to copy from sp_payload, will always contain at least 1 byte (null terminator)
57+
popax ptr1 ; read the time_data location into ptr1
58+
ldy #$00
59+
: lda _sp_payload, y
60+
sta (ptr1), y
61+
iny
62+
cpy _sp_count
63+
bne :-
64+
65+
jmp return0
66+
67+
.data
68+
code_table:
69+
.byte 'T', 'P', 'A', 'B', 'S', 'Z'
70+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
.export _clock_get_tz
2+
3+
.import _sp_count
4+
.import _sp_get_clock_id
5+
.import _sp_payload
6+
.import _sp_status
7+
8+
.import pusha
9+
.import return0
10+
.import return1
11+
12+
.include "macros.inc"
13+
.include "zp.inc"
14+
15+
; uint8_t clock_get_tz(uint8_t* tz);
16+
17+
_clock_get_tz:
18+
axinto tmp_tz_loc
19+
jsr _sp_get_clock_id
20+
bne got_id
21+
22+
error:
23+
jmp return1
24+
25+
got_id:
26+
; sp_status(clock_id, 'G')
27+
jsr pusha
28+
lda #'G'
29+
jsr _sp_status
30+
bne error
31+
32+
; copy sp_count bytes from payload into buffer, there's always at least 1 byte (null terminator)
33+
mwa tmp_tz_loc, ptr1
34+
ldy #$00
35+
: lda _sp_payload, y
36+
sta (ptr1), y
37+
iny
38+
cpy _sp_count
39+
bne :-
40+
41+
jmp return0
42+
43+
44+
.bss
45+
tmp_tz_loc: .res 2
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
.export _clock_set_tz
2+
3+
.import _fn_error
4+
.import _memcpy
5+
.import _sp_control
6+
.import _sp_get_clock_id
7+
.import _sp_payload
8+
.import _strlen
9+
10+
.import incsp2
11+
.import pusha
12+
.import pushax
13+
.import return1
14+
15+
.include "macros.inc"
16+
.include "zp.inc"
17+
18+
; uint8_t clock_set_tz(char *tz);
19+
_clock_set_tz:
20+
axinto tmp_tz_ptr ; save the tz
21+
22+
; get the device id of the clock, this is stored in _sp_clock_id, but also returned so we can check if it failed (0 is error)
23+
jsr _sp_get_clock_id
24+
bne got_id
25+
26+
; no clock found, return 1 as an error (FN_ERR_IO_ERROR)
27+
jmp return1
28+
29+
got_id:
30+
jsr pusha ; store the destination device for call to sp_control
31+
32+
; copy timezone string into sp_payload, including the null terminator
33+
pushax #(_sp_payload + 2)
34+
pushax tmp_tz_ptr
35+
jsr _strlen
36+
37+
clc
38+
adc #$01
39+
bcc :+
40+
inx
41+
42+
: sta _sp_payload + 0
43+
stx _sp_payload + 1
44+
jsr _memcpy
45+
46+
; destination was stored on s/w stack already
47+
lda #'T' ; set 'T'imezone
48+
jsr _sp_control
49+
50+
; convert to fujinet error
51+
jmp _fn_error
52+
53+
54+
.bss
55+
tmp_tz_ptr: .res 2
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
.export _clock_get_time
2+
3+
.import _bus
4+
.import _fuji_success
5+
6+
.import popax
7+
.import return0
8+
9+
.include "device.inc"
10+
.include "fujinet-clock.inc"
11+
.include "macros.inc"
12+
.include "zp.inc"
13+
14+
; uint8_t clock_get_time(uint8_t* time_data, TimeFormat format);
15+
_clock_get_time:
16+
tay
17+
cpy #$06 ; was the format value in range?
18+
bcc ok
19+
20+
; return an error status
21+
jmp return0
22+
23+
ok:
24+
lda t_clock_get_time_cmd, y
25+
sta IO_DCB::dcomnd
26+
lda t_clock_get_time_len, y
27+
sta IO_DCB::dbytlo
28+
popax IO_DCB::dbuflo
29+
30+
; the SIO clock device follows the APETIME device ID:
31+
; #define SIO_DEVICEID_APETIME 0x45
32+
mva #SIO_CLOCK_DEVICE_ID, IO_DCB::ddevic
33+
mva #$40, IO_DCB::dstats
34+
ldx #$00
35+
stx IO_DCB::dunuse
36+
stx IO_DCB::daux1
37+
stx IO_DCB::daux2
38+
stx IO_DCB::dbythi
39+
inx ; x = 1
40+
stx IO_DCB::dunit
41+
inx ; x = 2 - as this is a FN non network call, we can keep this low
42+
stx IO_DCB::dtimlo
43+
jsr _bus
44+
jmp _fuji_success
45+
46+
.rodata
47+
48+
; tables for the commands that have to be sent for the different types of time command
49+
; see fuji_clock.h
50+
t_clock_get_time_cmd:
51+
.byte 'T', 'P', SIO_APETIMECMD_GETTZTIME, SIO_APETIMECMD_GETTIME, 'S', 'Z'
52+
53+
t_clock_get_time_len:
54+
.byte 7, 4, 6, 6, 25, 25

0 commit comments

Comments
 (0)