diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/kdata.asm | 3 | ||||
| -rw-r--r-- | src/syscall.asm | 41 |
2 files changed, 44 insertions, 0 deletions
diff --git a/src/kdata.asm b/src/kdata.asm index 6333f38..eece708 100644 --- a/src/kdata.asm +++ b/src/kdata.asm @@ -57,6 +57,9 @@ wFsSlashPtr::DS 2 ; last '/' seen while splitting a path wListDir:: DS 1 ; directory sys_list enumerates wKChar:: DS 1 ; scratch for KPutc wConInSkip:: DS 1 ; console input: mid-SLIP-frame? (skip net packets) +wSleepTarget::DS 1 ; sys_sleep: target in 1/64-second units +wSleepAcc:: DS 2 ; sys_sleep: accumulated DIV ticks +wSleepLastDiv::DS 1 ; sys_sleep: previous DIV reading wKillParent::DS 1 ; scratch for sys_kill wPsBuf:: DS 2 ; scratch for sys_ps wPnStart:: DS 2 ; scratch for sys_progname diff --git a/src/syscall.asm b/src/syscall.asm index 04e9661..1051a4d 100644 --- a/src/syscall.asm +++ b/src/syscall.asm @@ -68,6 +68,7 @@ SyscallTable: dw sys_srecv_nb ; 31 SRECVNB dw sys_pollin ; 32 POLLIN dw sys_net ; 33 NET + dw sys_sleep ; 34 SLEEP ; ----------------------------------------------------------------------------- sys_nosys: @@ -279,6 +280,46 @@ sys_yield: ret ; ----------------------------------------------------------------------------- +; sys_sleep(B = 1/64-second units) - cooperative delay driven by the DIV timer. +; DIV (FF04) free-runs at 16384 Hz, so 256 ticks = 1/64 s. We accumulate DIV +; deltas across SchedYields (other procs run) until enough units have elapsed. +; ----------------------------------------------------------------------------- +sys_sleep: + ld a, b + or a + ret z ; sleep 0 = no-op + ld [wSleepTarget], a + xor a + ld [wSleepAcc], a + ld [wSleepAcc+1], a + ld a, [rDIV] + ld [wSleepLastDiv], a +.loop + call SchedYield + ld a, [rDIV] + ld c, a ; current DIV + ld a, [wSleepLastDiv] + ld b, a ; previous DIV + ld a, c + ld [wSleepLastDiv], a + sub b ; A = DIV delta (mod 256) + ld e, a + ld a, [wSleepAcc] ; acc += delta + add e + ld [wSleepAcc], a + ld a, [wSleepAcc+1] + adc 0 + ld [wSleepAcc+1], a ; acc high byte = elapsed 1/64-second units + ld b, a + ld a, [wSleepTarget] + cp b + jr z, .done ; elapsed == target + jr c, .done ; elapsed > target + jr .loop +.done + ret + +; ----------------------------------------------------------------------------- ; sys_exit(code=B) -- become a zombie awaiting reap; never returns. ; - store exit code, set PS_ZOMBIE ; - reparent any children to init (so they can still be waited on) |
