diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | README.txt | 48 | ||||
-rw-r--r-- | bignum.h | 3 | ||||
-rw-r--r-- | bignum.s | 16 | ||||
-rw-r--r-- | size.pl | 4 | ||||
-rw-r--r-- | taipan.c | 45 |
6 files changed, 63 insertions, 59 deletions
@@ -60,7 +60,9 @@ STACK_SIZE=0x200 # The meaning of the -l flag is different between cc65-2.13.3 # and the later github cc65, so it's been removed here. #CFLAGS=-t $(SYS) -T -I. -L. -Wl -D__SYSTEM_CHECK__=1 -Wl -D__RESERVED_MEMORY__=1056 $(COPT) + CFLAGS=-t $(SYS) -T -I. -L. -Wl -D__SYSTEM_CHECK__=1 -DFONT_ADDR=$(FONT_ADDR) --start-addr $(TAIMAIN_ADDR) -Wl -D__STACKSIZE__=$(STACK_SIZE) $(COPT) + AS=ca65 ASFLAGS= AR=ar65 @@ -117,7 +119,7 @@ taipan.atr: all # depends on all the pieces, and just concatenates them. $(XEX): taimain.xex taifont.xex newtitle.xex comptitle.xex cat comptitle.xex newtitle.xex taifont.xex taimain.xex > $(XEX) - perl size.pl $(STACK_SIZE) + perl size.pl $(TAIMAIN_ADDR) $(STACK_SIZE) # Bitmap data for the title screen, 256x184 = 47104 pixels, 8 bits # per pixel, or 5888 bytes. Displayed in ANTIC mode F (aka GR.8), @@ -229,7 +231,7 @@ push: sh push.sh size: clean all - perl size.pl $(STACK_SIZE) + perl size.pl $(TAIMAIN_ADDR) $(STACK_SIZE) # Cruft. Was used for testing the enemy ship animation. lorchatest: lorchatest.c draw_lorcha.s taifont.xex @@ -23,12 +23,9 @@ can be found here: http://www.taipangame.com/ What's missing: -- Large integer (or floating point) support. Cash, Bank, and Debt - amounts will roll over to 0 if they exceed the max value for a 32-bit - unsigned integer (around 4 billion). I'm not sure if this is a real - problem for anyone (it takes a *long* time to get over a billion - in this game). As a side effect of this, the "negative interest" - bug/feature is missing. +- Large integer (or floating point) support for Debt and Cash (the + Bank is floating point though). As a side effect of this, the "negative + interest" bug/feature is missing. Build Requirements: @@ -81,9 +78,6 @@ Atari++, or Altirra. For Atari800, you should be able to do this: atari800 -nobasic taipan.xex -Even though the title screen says to press Escape to start, you can -really press any key to start the game. - License: The legal status of this is quite murky. The original game is still @@ -94,9 +88,10 @@ This Atari port includes font and graphics data ripped straight from the original Apple game, plus more font data ripped from the Atari 800's OS ROM. -The Linux port of taipan, according to its .lsm file, is GPL. My C code is -definitely a derivative work, so it's GPL also. The assembly code and ship -graphics are my own work, and I release them under the GPL (version 2). +The Linux port of taipan, according to its .lsm file, is GPL (version +uspecified). My C code is definitely a derivative work, so it's GPL +also. The assembly code and ship graphics are my own work, and I release +them under the GPL (version 2). Notes: @@ -121,12 +116,6 @@ arcade game). Bugs! At least these: -- When Cash is e.g. 2.09 Million, the leading 0 after the decimal - point isn't printed (so you get 2.9 Million) - -- bignum bank doesn't print enough decimal places (1.1 Million - instead of 1.12 Million, etc) - - Exiting the game (Play again? N) needs to at minimum restore the original text/background colors. @@ -145,14 +134,12 @@ Bugs! At least these: I either start using big numbers (floats or 64-bit ints or whatever), or just decide to live with the limits of 32-bit ints. -- Retirement score calculations are a bit off, due to using integer math. - -- Not really a bug, but, the interest calculations for debt and the bank - are slightly different, due to using integer math. Very small bank or - debt amounts will grow much faster than they should, then stabilize - and converge towards the correct values over time. This only happens - when you have less than 10 in debt, or less than 200 in the bank, - which (at least for me) are pretty rare situations. +- Not really a bug, but, the interest calculation for debt + is slightly different, due to using integer math. Very small debt + amounts will grow much faster than they should, then stabilize and + converge towards the correct values over time. This only happens when + you have less than 10 in debt, which (at least for me) is a pretty + rare situation. - A few things in the screen layout are slightly off comapred to the Apple version. Would really like to get it exact. @@ -181,7 +168,7 @@ Bugs! At least these: Deliberate differences between the Apple II and Atari ports: -1. Atari: "Press ESC for help" rather than ESC to start. +1. "Press ESC for help" rather than ESC to start. 2. I made it possible to disable the sound, since it's kinda repetitive and annoying, plus the game "freezes" while sounds are playing (no @@ -220,13 +207,14 @@ Deliberate differences between the Apple II and Atari ports: starts the game. 10. Apple uses floating point, no practical limit on cash/bank/debt. - Atari currently uses 32-bit unsigned longs, though float support - is soon to be added (at least for the bank). + Atari currently uses 32-bit unsigned longs for cash and debt, + though the bank is now floating point. 11. On Apple, price of General Cargo isn't always an integer (e.g. 6.5). 12. On Apple, dead enemy ships sink one scanline at a time, and there are - at least 2 sinking speeds. On Atari, it's one character, 8 scanlines, at a time. + at least 2 sinking speeds. On Atari, it's one character (8 scanlines) + at a time, and the speed is always the same. Differences between the Apple II original and Linux port: @@ -92,6 +92,9 @@ extern char __cdecl__ big_sub(bignump dest, bignump minuend, bignump subtrahend) extern char __cdecl__ big_mul(bignump dest, bignump multiplicand, bignump multiplier); extern char __cdecl__ big_div(bignump dest, bignump dividend, bignump divisor); +/* dest = src * -1 */ +extern void __fastcall__ big_negate(bignump dest, bignump src); + /* returns true if the bank is maxed out. We do this by checking the exponent byte, so the "max" is tied to the bignum implementation, which is why its prototype is here rather than bank.h. For Atari floats, it's 1.0e+14, or @@ -3,7 +3,7 @@ .importzp ptr3, ptr4, sreg .import popeax, popax, pushax, _memcmp .export _ulong_to_big, _big_to_ulong, _big_add, _big_sub, _big_mul, _big_div - .export _bank_maxed_out, _big_cmp, _big_copy + .export _bank_maxed_out, _big_cmp, _big_copy, _big_negate .include "atari.inc" @@ -71,6 +71,20 @@ ptr4_to_fr1: rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; void __fastcall__ big_negate(bignump dest, bignump src); +_big_negate: + sta ptr3 + stx ptr3+1 + jsr popax + sta ptr4 + stx ptr4+1 + ldy #0 + lda (ptr3),y + eor #$80 + sta (ptr4),y + rts + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; truncate FR0 to integer (no rounding: 2.8 -> 2) trunc_fr0: lda FR0 @@ -1,5 +1,6 @@ #!/usr/bin/perl -w +my $code_start = oct(shift) || die "no code start addr"; my $stack_size = oct(shift) || die "no stack size"; open MAP, "<taipan.map" or die $!; @@ -12,8 +13,9 @@ while(<MAP>) { close MAP; $free = (0xbc20 - $stack_size) - $bss_end + 1; +$code_size = $bss_start - $code_start; -printf "===> code ends at \$%04x\n", ($bss_start - 1); +printf "===> code ends at \$%04x (%d, %.1fK)\n", ($bss_start - 1), $code_size, $code_size / 1024; printf "===> BSS ends at \$%04x\n", $bss_end; printf "===> stack starts at \$%04x\n", 0xbc20 - $stack_size; printf "===> free code space \$%04x (%d, %.1fK)\n", $free, $free, $free / 1024; @@ -333,7 +333,14 @@ void cprintfancy_big(bignump b) { unsigned long leftdigits = 0L; unsigned char rightdigits = 0, letter = 'M', leading0 = 0; - if(big_cmp(b, big1T) >= 0) { + big_copy(tmp, b); + + if(big_cmp(tmp, big0) < 0) { + cputc('-'); + big_negate(tmp, tmp); + } + + if(big_cmp(tmp, big1T) >= 0) { revers(1); cputs("1 Trillion+!"); revers(0); @@ -341,16 +348,14 @@ void cprintfancy_big(bignump b) { } /* for >= 1B, divide by 1M */ - if(big_cmp(b, big1B) >= 0) { - big_div(tmp, b, big1K); + if(big_cmp(tmp, big1B) >= 0) { + big_div(tmp, tmp, big1K); letter = 'B'; - } else { - big_copy(tmp, b); } big_to_ulong(tmp, &leftdigits); - if(big_cmp(b, big1M) < 0) { /* 0..999999 */ + if(big_cmp(tmp, big1M) < 0) { /* 0..999999 */ letter = 0; } else if(leftdigits < 10000000L) { /* 1M..10M-1 */ leftdigits /= 10000L; @@ -1707,10 +1712,14 @@ void final_stats(void) ulong_to_big((unsigned long)time, bigtmp); big_div(bigscore, bigscore, bigtmp); - if(big_cmp(bigscore, big1M) > 0) + if(big_cmp(bigscore, big1M) > 0) { score = 1000000L; - else + } else if(big_cmp(bigscore, big0) < 0) { + score = -1; + } else { big_to_ulong(bigscore, (unsigned long*)&score); + } + #else /* TODO: write cprintlong() to print signed value */ long finalcash = cash + bank - debt; @@ -2731,28 +2740,11 @@ void buy(void) { cputs(" "); gotoxy(31, 23); - /* TODO: is this really right? */ if(afford < 100) cputc(' '); if(afford < 10000) cputc(' '); if(afford < 1000000) cputc(' '); if(afford < 100000000) cputc(' '); - /* - if (afford < 100) - { - strcpy(space, " "); - } else if (afford < 10000) { - strcpy(space, " "); - } else if (afford < 1000000) { - strcpy(space, " "); - } else if (afford < 100000000) { - strcpy(space, " "); - } else { - strcpy(space, ""); - } - cputs(space); - */ - cprintulong(afford); revers(0); @@ -2962,6 +2954,9 @@ void bignum_test(void) { for(i = 0; i < 14; i++) { cprintfancy_big(n); + cputc(' '); + big_negate(n, n); + cprintfancy_big(n); cputs("\r\n"); big_mul(n, n, o); } |