1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-07-23 06:50:19 +10:00
collapseos/kernel/core.asm
Virgil Dupras 7cf3ed38da Extract str.asm from core.asm and make core included by userspace
Most of register fiddling routines (which is now the only thing contained
in care.asm) are used by almost all userspace apps, often in inner loops.

That makes the penalty of using jump tables for those a bit too high.
Moreover, it burdens jump tables needlessly.

Because this unit is very small (now that string routines are out), it makes
sense to always include it in binaries.
2019-11-14 10:14:15 -05:00

106 lines
2.3 KiB
NASM

; core
;
; Routines used pretty much all everywhere. Unlike all other kernel units,
; this unit is designed to be included directly by userspace apps, not accessed
; through jump tables. The reason for this is that jump tables are a little
; costly in terms of machine cycles and that these routines are not very costly
; in terms of binary space.
; Therefore, this unit has to stay small and tight because it's repeated both
; in the kernel and in userspace. It should also be exclusively for routines
; used in the kernel.
; add the value of A into DE
addDE:
push af
add a, e
jr nc, .end ; no carry? skip inc
inc d
.end:
ld e, a
pop af
noop: ; piggy backing on the first "ret" we have
ret
; add the value of A into HL
; affects carry flag according to the 16-bit addition, Z, S and P untouched.
addHL:
push de
ld d, 0
ld e, a
add hl, de
pop de
ret
; copy (HL) into DE, then exchange the two, utilising the optimised HL instructions.
; ld must be done little endian, so least significant byte first.
intoHL:
push de
ld e, (hl)
inc hl
ld d, (hl)
ex de, hl
pop de
ret
intoDE:
ex de, hl
call intoHL
ex de, hl ; de preserved by intoHL, so no push/pop needed
ret
intoIX:
push ix
ex (sp), hl ;swap hl with ix, on the stack
call intoHL
ex (sp), hl ;restore hl from stack
pop ix
ret
; Compare HL with DE and sets Z and C in the same way as a regular cp X where
; HL is A and DE is X.
cpHLDE:
push hl
or a ;reset carry flag
sbc hl, de ;There is no 'sub hl, de', so we must use sbc
pop hl
ret
; Write the contents of HL in (DE)
; de and hl are preserved, so no pushing/popping necessary
writeHLinDE:
ex de, hl
ld (hl), e
inc hl
ld (hl), d
dec hl
ex de, hl
ret
; Call the method (IX) is a pointer to. In other words, call intoIX before
; callIX
callIXI:
push ix
call intoIX
call callIX
pop ix
ret
; jump to the location pointed to by IX. This allows us to call IX instead of
; just jumping it. We use IX because we seldom use this for arguments.
callIX:
jp (ix)
callIY:
jp (iy)
; Ensures that Z is unset (more complicated than it sounds...)
; There are often better inline alternatives, either replacing rets with
; appropriate jmps, or if an 8 bit register is known to not be 0, an inc
; then a dec. If a is nonzero, 'or a' is optimal.
unsetZ:
or a ;if a nonzero, Z reset
ret nz
cp 1 ;if a is zero, Z reset
ret