Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Jr = \
f256/audio.asm \
f256/clock.asm \
f256/console.asm \
f256/cpu.asm \
f256/dips.asm \
f256/fat32.asm \
f256/flash.asm \
Expand Down
84 changes: 2 additions & 82 deletions f256/audio.asm
Original file line number Diff line number Diff line change
Expand Up @@ -288,47 +288,6 @@ playnote: sec ; Convert the note character to an index
bra loop

;
; Wait for about 1ms
;
wait_1ms: phx

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and below, delete local copies of the wait routines, replace calls to local wait_100ms with cpu.wait_100ms.

phy

; Inner loop is 6 clocks per iteration or 1us
; Run the inner loop ~1000 times for 1ms

ldx #3
wait_outr: ldy #$ff
wait_inner: nop
dey
bne wait_inner
dex
bne wait_outr

ply
plx
rts

;
; Wait for 100ms
;
wait_100ms: phx
ldx #100
wait100l: jsr wait_1ms
dex
bne wait100l
plx
rts

;
; Wait for some 10ths of seconds
;
; X = number of 10ths of a second to wait
;
wait_tens: jsr wait_100ms
dex
bne wait_tens
rts
;
; Assignment of notes to frequency
; NOTE: in general, this table should support 10-bit values
; we're using just one octave here, so we can get away with bytes
Expand Down Expand Up @@ -511,59 +470,20 @@ clr_loop: sta SID_LEFT,x

stz SID_LEFT+4
stz SID_RIGHT+4
rts
;
; Wait forever
;

loop: nop
bra loop


;
; Wait for about 1ms
;
wait_1ms: phx
phy

; Inner loop is 6 clocks per iteration or 1us
; Run the inner loop ~1000 times for 1ms

ldx #3
wait_outr: ldy #$ff
wait_inner: nop
dey
bne wait_inner
dex
bne wait_outr

ply
plx
rts

;
; Wait for 100ms
;
wait_100ms: phx
ldx #100
wait100l: jsr wait_1ms
dex
bne wait100l
plx
rts
.endn

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the wait_tens implementation below out of the nested namespace so it can be cleanly accessed by all routines in this module.


;
; Wait for some 10ths of seconds
;
; X = number of 10ths of a second to wait
;
wait_tens: jsr wait_100ms
wait_tens: jsr cpu.wait_100ms
dex
bne wait_tens
rts

.endn

.send
.endn
.endn
Expand Down
135 changes: 135 additions & 0 deletions f256/cpu.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
; This file is part of the TinyCore MicroKernel for the Foenix F256.
; Copyright 2022, 2023 Jessie Oberreuter <Gadget@HackwrenchLabs.com>.
; Copyright 2026 Wildbits Computing Company
; SPDX-License-Identifier: GPL-3.0-only

.cpu "w65c02"

.namespace platform
cpu .namespace


.section dp
self .namespace
wait_count .byte ?
.endn
.send

; See comment blocks for `wait_20us` and below
WAIT_COUNT_6_3MHz = 21
WAIT_COUNT_12_6MHz = 47

@agurtovoy agurtovoy Jul 17, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted 2x-core-aware timed sleep* implementations from iec.asm, renamed to wait*, double-checked & tightened up the timings.


.section global

init
; Initialize the `wait_count`
lda #WAIT_COUNT_6_3MHz
jsr is_2x
bcc +
lda #WAIT_COUNT_12_6MHz
+ sta self.wait_count

clc
rts

is_2x
; The 7th bit of the machine ID indicates a 2x core; shift it into
; carry and return
lda $d6a7
asl a
rts


; Wait for approximately but no less than 20 microseconds (including the caller's `jsr`)
wait_20us ; [jsr] 6 cycles
phx ; 3 cycles
ldx self.wait_count ; 3 cycles
- dex ; 2 cycles
bne - ; 2 + 1 if branch is taken
plx ; 4 cycles
rts ; 6 cycles
; = (21 + 5 * wait_count) cycles
;
; At 6.3 MHz: 1 cycle = 0.15873us
; 20us = 126 cycles
; 21 + 5 * wait_count = 126
; 5 * wait_count = 105
; wait_count = 21

;
; At 12.6 MHz: 1 cycle = 0.07937us
; 20us = 252 cycles
; 21 + 5 * wait_count = 252
; 5 * wait_count = 231
; wait_count = 46.2
; use 47 to uphold the "no less than 20us" contract


wait_x_20us .macro x
phx
ldx #\x
- jsr platform.cpu.wait_20us
dex
bne -
plx
.endmacro

; Wait for approximately but no less than 100 microseconds
wait_100us
.wait_x_20us 5
rts

; Wait for approximately but no less than 1 ms
wait_1ms
.wait_x_20us 50
rts

; Wait for approximately but no less than `X` ms
wait_x_ms
- jsr wait_1ms
dex
bne -
rts

.namespace self
; Wait for approximately but no less than `YX` ms; `Y` is a biased page count,
; not the raw high byte; see `wait_ms` for the encoding
wait_yx_ms
- jsr wait_1ms
dex
bne -
dey
bne -
rts
.endn


; Wait for approximately but no less than the specified number of ms
wait_ms .macro ms

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Primary API for arbitrary ms waits

.cerror \ms <= 0, "Expected a positive number"
.cerror \ms > $FF00, "Can't wait for longer than ", $FF00, " ms at a time"
.if \ms > 255
phx
phy
ldx #<\ms
ldy #(>\ms) + ((<\ms) != 0 ? 1 : 0)
jsr platform.cpu.self.wait_yx_ms
ply
plx
.else
phx
ldx #\ms
jsr platform.cpu.wait_x_ms
plx
.endif
.endmacro

; Wait for approximately but no less than 100 ms
wait_100ms
.wait_ms 100
rts

.send

.endn
.endn
Loading