From 9d59ca053dbfddb34a2a4eac8ebb0252460c0137 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Mon, 10 May 2021 16:47:37 -0400 Subject: Rewrite array handling, save 175 bytes --- arrayutils.s | 106 +++++++++++++++++++++++++++++++++++++++++++---------------- taipan.c | 43 ++++++++++++------------ 2 files changed, 99 insertions(+), 50 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 diff --git a/taipan.c b/taipan.c index 367c7be..8221cc1 100644 --- a/taipan.c +++ b/taipan.c @@ -378,6 +378,17 @@ unsigned long __fastcall__ strtonum(const char* nptr); unsigned char firmpos; +int ships_on_screen[10]; + +/* arrayutils.s */ +extern char no_ships_on_screen(void); +extern void clear_ships_on_screen(void); +extern char have_no_cargo(void); +extern char hold_is_empty(void); +extern char hkw_is_empty(void); +extern void clear_hold(void); +extern void clear_hkw(void); + /* use page 6 for these buffers, for .xex build. Otherwise they're BSS. */ #ifdef CART_TARGET char firm[23]; @@ -637,14 +648,8 @@ void init_game(void) { #else bank = 0; #endif - hkw_[0] = 0; - hkw_[1] = 0; - hkw_[3] = 0; - hkw_[4] = 0; - hold_[0] = 0; - hold_[1] = 0; - hold_[2] = 0; - hold_[3] = 0; + clear_hkw(); + clear_hold(); hold = 0; damage = 0; wu_warn = 0; @@ -1091,12 +1096,6 @@ void plus_or_space(unsigned char b) { #endif */ -int ships_on_screen[10]; -extern char have_ships_on_screen(void); -extern void clear_ships_on_screen(void); - -char have_no_cargo(void); - /* sea_battle only ever returns 1 to 4. making the return type a char saved 61 bytes! */ char sea_battle(char id, int num_ships) { @@ -1212,7 +1211,7 @@ char sea_battle(char id, int num_ships) { set_orders(); for(i = 1; i <= guns; i++) { - if(!have_ships_on_screen()) { + if(no_ships_on_screen()) { static int j; for (j = 0; j <= 9; j++) { @@ -1332,7 +1331,7 @@ char sea_battle(char id, int num_ships) { total = 0; turbo = 0; - if(have_no_cargo()) { + if(hold_is_empty()) { print_combat_msg(M_you_have_no_cargo); cprint_taipan_bangbang(); bad_joss_sound(); @@ -1407,10 +1406,7 @@ char sea_battle(char id, int num_ships) { hold += amount; ok += (amount / 10); } else { - hold_[0] = 0; - hold_[1] = 0; - hold_[2] = 0; - hold_[3] = 0; + clear_hold(); hold += total; ok += (total / 10); } @@ -2179,12 +2175,15 @@ void final_stats(void) #endif } +/* + // rewritten in asm (arrayutils.s) char have_no_cargo(void) { char i; for(i = 0; i < 4; ++i) if(hkw_[i] || hold_[i]) return 0; return 1; } +*/ /* #ifdef CART_TARGET @@ -3550,9 +3549,11 @@ int main(void) { under_attack_timed_getch(); } + /* if ((one_chance_in(50)) && ((hkw_[0] + hkw_[1] + hkw_[2] + hkw_[3]) > 0)) - { + */ + if(one_chance_in(50) && !hkw_is_empty()) { int i; for (i = 0; i < 4; i++) -- cgit v1.2.3