aboutsummaryrefslogtreecommitdiff
path: root/arrayutils.s
diff options
context:
space:
mode:
authorB. Watson <yalhcru@gmail.com>2021-05-10 16:47:37 -0400
committerB. Watson <yalhcru@gmail.com>2021-05-10 16:47:37 -0400
commit9d59ca053dbfddb34a2a4eac8ebb0252460c0137 (patch)
treed7bd40834b73b5b6115ff0293cf6c22145b88245 /arrayutils.s
parent2ff01881f4b7f0842a10e3c5ab7991c81f60861d (diff)
downloadtaipan-9d59ca053dbfddb34a2a4eac8ebb0252460c0137.tar.gz
Rewrite array handling, save 175 bytes
Diffstat (limited to 'arrayutils.s')
-rw-r--r--arrayutils.s106
1 files changed, 77 insertions, 29 deletions
diff --git a/arrayutils.s b/arrayutils.s
index 188ace4..4e3babf 100644
--- a/arrayutils.s
+++ b/arrayutils.s
@@ -14,47 +14,95 @@
; the function, or around 1/3 the size of the for loop, or under 1/4
; the size of bzero() plus its function call.
- .import _ships_on_screen
- .export _have_ships_on_screen, _clear_ships_on_screen
+; we also have clear_hkw() and clear_hold().
+
+ .import _ships_on_screen, _hkw_, _hold_
+ .export _no_ships_on_screen
+ .export _hold_is_empty, _hkw_is_empty, _have_no_cargo
+ .export _clear_hkw, _clear_hold, _clear_ships_on_screen
.include "atari.inc"
- .proc _clear_ships_on_screen
- ldx #$14
+ .code
+_clear_ships_on_screen:
+ lda #<(_ships_on_screen-1)
+ ldx #>(_ships_on_screen-1)
+ ldy #$14
+ ; fall thru
+
+clr_array:
+ ; AX is array address minus one!
+ ; Y is sizeof(array)
+ sta FR0
+ stx FR0+1
lda #0
@l:
- sta _ships_on_screen-1,x
- dex
+ sta (FR0),y
+ dey
bne @l
rts
- .endproc
-; extern char have_ships_on_screen(void);
+_clear_hkw:
+ lda #<(_hkw_-1)
+ ldx #>(_hkw_-1)
+ ldy #$08
+ bne clr_array
+
+_clear_hold:
+ lda #<(_hold_-1)
+ ldx #>(_hold_-1)
+ ldy #$10
+ bne clr_array
-; optimized (both size and speed) replacement for:
+;;;;;
-; if ((ships_on_screen[0] == 0) && (ships_on_screen[1] == 0) &&
-; (ships_on_screen[2] == 0) && (ships_on_screen[3] == 0) &&
-; (ships_on_screen[4] == 0) && (ships_on_screen[5] == 0) &&
-; (ships_on_screen[6] == 0) && (ships_on_screen[7] == 0) &&
-; (ships_on_screen[8] == 0) && (ships_on_screen[9] == 0))
+; Several places in the Taipan C code we have to check whether an
+; array is all zero. A for loop in C takes up quite a bit of space,
+; so write an array-checker in asm.
-; ...which compiles to ~100 bytes of code. a for loop would be
-; around 64 bytes (like the clearing loop above). this is 3 bytes
-; for the function call plus 11 bytes for the function, plus a
-; couple more bytes for the ! in front of the function call (since
-; the result is opposite what the original code did).
-; I could save the 3 bytes by inlining this as asm() in the C code,
-; but it would be more fragile than making a separate function.
+; Wrappers for array_is_empty():
+; no_ships_on_screen()
+; hold_is_empty()
+; hkw_is_empty()
+; have_no_cargo();
- .proc _have_ships_on_screen
- ldx #$14 ; sizeof(ships_on_screen)
+_no_ships_on_screen:
+ lda #<(_ships_on_screen-1)
+ ldx #>(_ships_on_screen-1)
+ ldy #$14
+ ; fall thru
+
+array_is_empty:
+ ; AX is array address minus one!
+ ; Y is sizeof(array)
+ sta FR0
+ stx FR0+1
@l:
- lda _ships_on_screen-1,x
- bne @done ; found a non-0 byte, A and X are both non-zero
- dex
+ lda (FR0),y
+ bne ret0
+ dey
bne @l
- ; end of loop. if we get here, A and X are both zero
-@done:
+@ret1:
+ lda #1
rts
- .endproc
+ret0:
+ lda #0
+ tax ; need this or not?
+ rts
+
+_hkw_is_empty:
+ lda #<(_hkw_-1)
+ ldx #>(_hkw_-1)
+ ldy #$08
+ bne array_is_empty
+
+_hold_is_empty:
+ lda #<(_hold_-1)
+ ldx #>(_hold_-1)
+ ldy #$10
+ bne array_is_empty
+
+_have_no_cargo:
+ jsr _hkw_is_empty
+ beq ret0
+ bne _hold_is_empty