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.
This commit is contained in:
Virgil Dupras 2019-11-14 09:55:31 -05:00
parent 0e79035d9c
commit 7cf3ed38da
28 changed files with 212 additions and 300 deletions

View File

@ -1,5 +1,4 @@
; *** Requirements ***
; addHL
; printstr
; printcrlf
; stdioReadLine
@ -12,6 +11,7 @@
jp basStart
.inc "core.asm"
.inc "lib/util.asm"
.inc "lib/parse.asm"
.equ BAS_RAMSTART USER_RAMSTART

View File

@ -1,3 +1,20 @@
; *** Requirements ***
; BLOCKDEV_SIZE
; FS_HANDLE_SIZE
; _blkGetB
; _blkPutB
; _blkSeek
; _blkTell
; fsFindFN
; fsOpen
; fsGetB
; fsPutB
; fsSetSize
; printstr
; printcrlf
; stdioReadLine
; stdioPutC
;
.inc "user.h"
; *** Overridable consts ***
@ -13,6 +30,7 @@
jp edMain
.inc "core.asm"
.inc "lib/util.asm"
.inc "lib/parse.asm"
.equ IO_RAMSTART USER_RAMSTART

View File

@ -22,27 +22,6 @@
; around whenever we add or delete lines. Hopefully, "LDIR" will be our friend
; here...
;
; *** Requirements ***
; BLOCKDEV_SIZE
; FS_HANDLE_SIZE
; _blkGetB
; _blkPutB
; _blkSeek
; _blkTell
; addHL
; cpHLDE
; fsFindFN
; fsOpen
; fsGetB
; fsPutB
; fsSetSize
; intoHL
; printstr
; printcrlf
; stdioReadLine
; stdioPutC
; unsetZ
;
; *** Variables ***
;
.equ ED_CURLINE ED_RAMSTART

View File

@ -19,12 +19,7 @@
;
; *** Requirements ***
; strncmp
; addDE
; upcase
; unsetZ
; intoDE
; intoHL
; writeHLinDE
; findchar
; parseHex
; parseHexPair
@ -73,6 +68,7 @@
jp zasmMain
.inc "core.asm"
.inc "zasm/const.asm"
.inc "lib/util.asm"
.inc "zasm/util.asm"

View File

@ -21,6 +21,7 @@ look like:
.inc "err.h"
.inc "ascii.h"
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.equ ACIA_RAMSTART RAMSTART
.inc "acia.asm"

View File

@ -1,9 +1,13 @@
; core
;
; Routines used by pretty much all parts. You will want to include it first
; in your glue file.
; *** REGISTER FIDDLING ***
; 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:
@ -17,6 +21,17 @@ addDE:
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:
@ -42,28 +57,6 @@ intoIX:
pop ix
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
; subtract the value of A from HL
; affects flags according to the 16-bit subtraction.
subHL:
push de
ld d, 0
ld e, a
or a ;reset carry flag
sbc hl, de ;There is no 'sub hl, de', so we must use sbc
pop de
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:
@ -110,133 +103,3 @@ unsetZ:
ret nz
cp 1 ;if a is zero, Z reset
ret
; *** STRINGS ***
; Fill B bytes at (HL) with A
fill:
push bc
push hl
.loop:
ld (hl), a
inc hl
djnz .loop
pop hl
pop bc
ret
; Increase HL until the memory address it points to is equal to A for a maximum
; of 0xff bytes. Returns the new HL value as well as the number of bytes
; iterated in A.
; If a null char is encountered before we find A, processing is stopped in the
; same way as if we found our char (so, we look for A *or* 0)
; Set Z if the character is found. Unsets it if not
findchar:
push bc
ld c, a ; let's use C as our cp target
ld a, 0xff
ld b, a
.loop: ld a, (hl)
cp c
jr z, .match
or a ; cp 0
jr z, .nomatch
inc hl
djnz .loop
.nomatch:
call unsetZ
jr .end
.match:
; We ran 0xff-B loops. That's the result that goes in A.
ld a, 0xff
sub b
cp a ; ensure Z
.end:
pop bc
ret
; Format the lower nibble of A into a hex char and stores the result in A.
fmtHex:
; The idea here is that there's 7 characters between '9' and 'A'
; in the ASCII table, and so we add 7 if the digit is >9.
; daa is designed for using Binary Coded Decimal format, where each
; nibble represents a single base 10 digit. If a nibble has a value >9,
; it adds 6 to that nibble, carrying to the next nibble and bringing the
; value back between 0-9. This gives us 6 of that 7 we needed to add, so
; then we just condtionally set the carry and add that carry, along with
; a number that maps 0 to '0'. We also need the upper nibble to be a
; set value, and have the N, C and H flags clear.
or 0xf0
daa ; now a =0x50 + the original value + 0x06 if >= 0xfa
add a, 0xa0 ; cause a carry for the values that were >=0x0a
adc a, 0x40
ret
; Formats value in A into a string hex pair. Stores it in the memory location
; that HL points to. Does *not* add a null char at the end.
fmtHexPair:
push af
; let's start with the rightmost char
inc hl
call fmtHex
ld (hl), a
; and now with the leftmost
dec hl
pop af
push af
rra \ rra \ rra \ rra
call fmtHex
ld (hl), a
pop af
ret
; Compares strings pointed to by HL and DE up to A count of characters. If
; equal, Z is set. If not equal, Z is reset.
strncmp:
push bc
push hl
push de
ld b, a
.loop:
ld a, (de)
cp (hl)
jr nz, .end ; not equal? break early. NZ is carried out
; to the called
cp 0 ; If our chars are null, stop the cmp
jr z, .end ; The positive result will be carried to the
; caller
inc hl
inc de
djnz .loop
; We went through all chars with success, but our current Z flag is
; unset because of the cp 0. Let's do a dummy CP to set the Z flag.
cp a
.end:
pop de
pop hl
pop bc
; Because we don't call anything else than CP that modify the Z flag,
; our Z value will be that of the last cp (reset if we broke the loop
; early, set otherwise)
ret
; Transforms the character in A, if it's in the a-z range, into its upcase
; version.
upcase:
cp 'a'
ret c ; A < 'a'. nothing to do
cp 'z'+1
ret nc ; A >= 'z'+1. nothing to do
; 'a' - 'A' == 0x20
sub 0x20
ret

125
kernel/str.asm Normal file
View File

@ -0,0 +1,125 @@
; Fill B bytes at (HL) with A
fill:
push bc
push hl
.loop:
ld (hl), a
inc hl
djnz .loop
pop hl
pop bc
ret
; Increase HL until the memory address it points to is equal to A for a maximum
; of 0xff bytes. Returns the new HL value as well as the number of bytes
; iterated in A.
; If a null char is encountered before we find A, processing is stopped in the
; same way as if we found our char (so, we look for A *or* 0)
; Set Z if the character is found. Unsets it if not
findchar:
push bc
ld c, a ; let's use C as our cp target
ld a, 0xff
ld b, a
.loop: ld a, (hl)
cp c
jr z, .match
or a ; cp 0
jr z, .nomatch
inc hl
djnz .loop
.nomatch:
call unsetZ
jr .end
.match:
; We ran 0xff-B loops. That's the result that goes in A.
ld a, 0xff
sub b
cp a ; ensure Z
.end:
pop bc
ret
; Format the lower nibble of A into a hex char and stores the result in A.
fmtHex:
; The idea here is that there's 7 characters between '9' and 'A'
; in the ASCII table, and so we add 7 if the digit is >9.
; daa is designed for using Binary Coded Decimal format, where each
; nibble represents a single base 10 digit. If a nibble has a value >9,
; it adds 6 to that nibble, carrying to the next nibble and bringing the
; value back between 0-9. This gives us 6 of that 7 we needed to add, so
; then we just condtionally set the carry and add that carry, along with
; a number that maps 0 to '0'. We also need the upper nibble to be a
; set value, and have the N, C and H flags clear.
or 0xf0
daa ; now a =0x50 + the original value + 0x06 if >= 0xfa
add a, 0xa0 ; cause a carry for the values that were >=0x0a
adc a, 0x40
ret
; Formats value in A into a string hex pair. Stores it in the memory location
; that HL points to. Does *not* add a null char at the end.
fmtHexPair:
push af
; let's start with the rightmost char
inc hl
call fmtHex
ld (hl), a
; and now with the leftmost
dec hl
pop af
push af
rra \ rra \ rra \ rra
call fmtHex
ld (hl), a
pop af
ret
; Compares strings pointed to by HL and DE up to A count of characters. If
; equal, Z is set. If not equal, Z is reset.
strncmp:
push bc
push hl
push de
ld b, a
.loop:
ld a, (de)
cp (hl)
jr nz, .end ; not equal? break early. NZ is carried out
; to the called
cp 0 ; If our chars are null, stop the cmp
jr z, .end ; The positive result will be carried to the
; caller
inc hl
inc de
djnz .loop
; We went through all chars with success, but our current Z flag is
; unset because of the cp 0. Let's do a dummy CP to set the Z flag.
cp a
.end:
pop de
pop hl
pop bc
; Because we don't call anything else than CP that modify the Z flag,
; our Z value will be that of the last cp (reset if we broke the loop
; early, set otherwise)
ret
; Transforms the character in A, if it's in the a-z range, into its upcase
; version.
upcase:
cp 'a'
ret c ; A < 'a'. nothing to do
cp 'z'+1
ret nc ; A >= 'z'+1. nothing to do
; 'a' - 'A' == 0x20
sub 0x20
ret

View File

@ -14,6 +14,7 @@ jp aciaInt
.inc "err.h"
.inc "ascii.h"
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.equ ACIA_RAMSTART RAMSTART
.inc "acia.asm"

View File

@ -14,6 +14,7 @@ jp aciaInt
.inc "err.h"
.inc "ascii.h"
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.equ ACIA_RAMSTART RAMSTART
.inc "acia.asm"

View File

@ -9,6 +9,7 @@ jp init
.inc "err.h"
.inc "ascii.h"
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.equ ACIA_RAMSTART RAMSTART
.inc "acia.asm"

View File

@ -23,6 +23,7 @@ jp aciaInt
.inc "err.h"
.inc "ascii.h"
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.equ ACIA_RAMSTART RAMSTART
.inc "acia.asm"

View File

@ -13,13 +13,7 @@
; *** Jump Table ***
jp strncmp
jp addDE
jp addHL
jp upcase
jp unsetZ
jp intoDE
jp intoHL
jp writeHLinDE
jp findchar
jp parseHex
jp parseHexPair
@ -28,20 +22,19 @@
jp fsFindFN
jp fsOpen
jp fsGetB
jp cpHLDE ; approaching 0x38...
; interrupt hook
.fill 0x38-$
jp aciaInt
; *** Jump Table (cont.) ***
jp parseArgs
jp printstr
jp _blkGetB
jp _blkPutB
jp _blkSeek
jp _blkTell
jp printHexPair
jp printHexPair ; approaching 0x38...
; interrupt hook
.fill 0x38-$
jp aciaInt
; *** Jump Table (cont.) ***
jp sdcGetB
jp sdcPutB
jp blkGetB
@ -49,6 +42,7 @@ jp aciaInt
.inc "err.h"
.inc "ascii.h"
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.equ ACIA_RAMSTART RAMSTART
.inc "acia.asm"

View File

@ -5,13 +5,7 @@
; *** JUMP TABLE ***
.equ strncmp 0x03
.equ addDE @+3
.equ addHL @+3
.equ upcase @+3
.equ unsetZ @+3
.equ intoDE @+3
.equ intoHL @+3
.equ writeHLinDE @+3
.equ findchar @+3
.equ parseHex @+3
.equ parseHexPair @+3
@ -20,16 +14,15 @@
.equ fsFindFN @+3
.equ fsOpen @+3
.equ fsGetB @+3
.equ cpHLDE @+3
; now at 0x36
.equ parseArgs 0x3b
.equ parseArgs @+3
.equ printstr @+3
.equ _blkGetB @+3
.equ _blkPutB @+3
.equ _blkSeek @+3
.equ _blkTell @+3
.equ printHexPair @+3
.equ sdcGetB @+3
; now at 0x36
.equ sdcGetB 0x3b
.equ sdcPutB @+3
.equ blkGetB @+3

View File

@ -11,6 +11,7 @@
.inc "err.h"
.inc "ascii.h"
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.equ PAD_RAMSTART RAMSTART

View File

@ -11,6 +11,7 @@
.inc "err.h"
.inc "ascii.h"
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.inc "sms/kbd.asm"

View File

@ -8,13 +8,7 @@
; *** JUMP TABLE ***
jp strncmp
jp addDE
jp addHL
jp upcase
jp unsetZ
jp intoDE
jp intoHL
jp writeHLinDE
jp findchar
jp parseHex
jp parseHexPair
@ -25,7 +19,6 @@
jp fsGetB
jp fsPutB
jp fsSetSize
jp cpHLDE
jp parseArgs
jp printstr
jp _blkGetB
@ -42,6 +35,7 @@
.inc "err.h"
.inc "ascii.h"
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.inc "sms/kbd.asm"

View File

@ -16,31 +16,24 @@
; *** JUMP TABLE ***
.equ strncmp 0x03
.equ addDE 0x06
.equ addHL 0x09
.equ upcase 0x0c
.equ unsetZ 0x0f
.equ intoDE 0x12
.equ intoHL 0x15
.equ writeHLinDE 0x18
.equ findchar 0x1b
.equ parseHex 0x1e
.equ parseHexPair 0x21
.equ blkSel 0x24
.equ blkSet 0x27
.equ fsFindFN 0x2a
.equ fsOpen 0x2d
.equ fsGetB 0x30
.equ fsPutB 0x33
.equ fsSetSize 0x36
.equ cpHLDE 0x39
.equ parseArgs 0x3c
.equ printstr 0x3f
.equ _blkGetB 0x42
.equ _blkPutB 0x45
.equ _blkSeek 0x48
.equ _blkTell 0x4b
.equ printcrlf 0x4e
.equ stdioPutC 0x51
.equ stdioReadLine 0x54
.equ upcase @+3
.equ findchar @+3
.equ parseHex @+3
.equ parseHexPair @+3
.equ blkSel @+3
.equ blkSet @+3
.equ fsFindFN @+3
.equ fsOpen @+3
.equ fsGetB @+3
.equ fsPutB @+3
.equ fsSetSize @+3
.equ parseArgs @+3
.equ printstr @+3
.equ _blkGetB @+3
.equ _blkPutB @+3
.equ _blkSeek @+3
.equ _blkTell @+3
.equ printcrlf @+3
.equ stdioPutC @+3
.equ stdioReadLine @+3

View File

@ -24,6 +24,7 @@
.inc "err.h"
.inc "ascii.h"
.inc "core.asm"
.inc "str.asm"
.equ FNT_WIDTH 3
.equ FNT_HEIGHT 5
.inc "fnt/mgm.asm"

View File

@ -12,13 +12,7 @@
; *** JUMP TABLE ***
jp strncmp
jp addDE
jp addHL
jp upcase
jp unsetZ
jp intoDE
jp intoHL
jp writeHLinDE
jp findchar
jp parseHex
jp parseHexPair
@ -29,7 +23,6 @@
jp fsGetB
jp fsPutB
jp fsSetSize
jp cpHLDE
jp parseArgs
jp printstr
jp _blkGetB
@ -41,6 +34,7 @@
jp stdioReadLine
.inc "core.asm"
.inc "str.asm"
.inc "err.h"
.inc "ascii.h"
.inc "parse.asm"

View File

@ -5,13 +5,7 @@
; *** JUMP TABLE ***
.equ strncmp 0x03
.equ addDE @+3
.equ addHL @+3
.equ upcase @+3
.equ unsetZ @+3
.equ intoDE @+3
.equ intoHL @+3
.equ writeHLinDE @+3
.equ findchar @+3
.equ parseHex @+3
.equ parseHexPair @+3
@ -22,7 +16,6 @@
.equ fsGetB @+3
.equ fsPutB @+3
.equ fsSetSize @+3
.equ cpHLDE @+3
.equ parseArgs @+3
.equ printstr @+3
.equ _blkGetB @+3

View File

@ -10,12 +10,7 @@
jp init ; 3 bytes
; *** JUMP TABLE ***
jp strncmp
jp addDE
jp upcase
jp unsetZ
jp intoDE
jp intoHL
jp writeHLinDE
jp findchar
jp parseHex
jp parseHexPair
@ -32,6 +27,7 @@ jp _blkTell
jp printstr
.inc "core.asm"
.inc "str.asm"
.inc "err.h"
.inc "ascii.h"
.inc "parse.asm"

View File

@ -5,12 +5,7 @@
; *** JUMP TABLE ***
.equ strncmp 0x03
.equ addDE @+3
.equ upcase @+3
.equ unsetZ @+3
.equ intoDE @+3
.equ intoHL @+3
.equ writeHLinDE @+3
.equ findchar @+3
.equ parseHex @+3
.equ parseHexPair @+3

View File

@ -30,40 +30,6 @@ test:
jp p, fail ; negative
call nexttest
; *** subHL ***
ld hl, 0x123
ld a, 0x25
call subHL
ld a, h
cp 0
jp nz, fail
ld a, l
cp 0xfe
jp nz, fail
call nexttest
ld hl, 0x125
ld a, 0x23
call subHL
ld a, h
cp 1
jp nz, fail
ld a, l
cp 0x02
jp nz, fail
call nexttest
ld hl, 0x125
ld a, 0x25
call subHL
ld a, h
cp 1
jp nz, fail
ld a, l
cp 0
jp nz, fail
call nexttest
; *** cpHLDE ***
ld hl, 0x42
ld de, 0x42

View File

@ -10,6 +10,7 @@
jp test
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.inc "lib/util.asm"
.inc "zasm/util.asm"

View File

@ -5,6 +5,7 @@
jp test
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.inc "lib/util.asm"
.inc "zasm/util.asm"

View File

@ -7,6 +7,7 @@
jp test
.inc "core.asm"
.inc "str.asm"
.inc "lib/util.asm"
.inc "zasm/util.asm"
.inc "zasm/const.asm"

View File

@ -1,6 +1,7 @@
jp test
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.inc "zasm/util.asm"

View File

@ -2,6 +2,7 @@ jp runTests
.inc "err.h"
.inc "core.asm"
.inc "str.asm"
.inc "parse.asm"
.inc "zasm/const.asm"
.inc "lib/util.asm"