diff options
-rw-r--r-- | bigfloat.s | 18 | ||||
-rw-r--r-- | rand.s | 44 | ||||
-rw-r--r-- | taipan.c | 164 | ||||
-rw-r--r-- | timed_getch.s | 10 |
4 files changed, 171 insertions, 65 deletions
@@ -228,11 +228,15 @@ _ulong_to_big: ; high value needs to be multiplied by 65536 - lda #<BIG_64K - sta FLPTR - lda #>BIG_64K - sta FLPTR+1 - jsr FLD1P + ldx #<BIG_64K ; FR1 = 65536 + ldy #>BIG_64K + jsr FLD1R + + ;lda #<BIG_64K + ;sta FLPTR + ;lda #>BIG_64K + ;sta FLPTR+1 + ;jsr FLD1P ; old version: ; lda #<BIG_64K @@ -346,9 +350,7 @@ _bank_maxed_out: _big_cmp: sta FLPTR stx FLPTR+1 - jsr FLD0P - - jsr FMOVE ; move to FR1 (since it's the 2nd arg) + jsr FLD1P jsr popax ; get a arg @@ -1,13 +1,48 @@ .export _randb, _randi, _randl +; .export _rand1in5 +; .export _randbit .importzp sreg, tmp3 .include "atari.inc" -; RANDOM is the POKEY LFSR read address. -; unfortunately, a read from this address will never -; return 0, since LFSR's can't do that. So there's -; extra code in here to (try to) compensate. +; RANDOM is the POKEY LFSR read address. This appears to be the low 8 +; bits of a 17-bit LFSR (Atari calls it a poly counter). Unfortunately, +; a read from this address will never return 0, since LFSR's can't do +; that. If Atari had made the RANDOM register read the higher order bits +; of the LFSR, rather than the bottom 8, this wouldn't be a problem... but +; they didn't, so there's extra code in here to (try to) compensate. + +; Might use this at some point: +;_randbit: +; lda RANDOM +; asl +; lda #0 +; adc #0 +; rts + +; unsigned char __fastcall__ randbit(void); +;_randbit: +; ldx #0 +;randbit: +; lda RANDOM +; lsr +; and #$01 +; rts + +; This doesn't give evenly distributed results, it's twice as +; likely to return 2 or 3 than 0, 1, or 4. +; unsigned char __fastcall__ rand1in5(void); +;_rand1in5: +; ldx #0 +;rand1in5: +; lda RANDOM +; lsr +; lsr +; and #$03 +; adc #0 +; rts + ; unsigned char __fastcall__ randb(void); _randb: ; C-callable entry point @@ -42,6 +77,7 @@ _randi: rts ; unsigned long __fastcall__ randl(void); +; this returns the full range of an unsigned long, 0 to 2**32-1 _randl: jsr randb sta sreg @@ -44,9 +44,10 @@ /**** atari-specific stuff */ -/* values returned by cgetc() for backspace & enter keys */ +/* values returned by cgetc() for backspace/enter/delete keys */ #define BKSP 0x7e #define ENTER 0x9b +#define DEL 0x9c /* timed_getch() args for seconds, based on jiffy clock of target system. No adjustment made for PAL, sorry. */ @@ -238,8 +239,8 @@ void final_stats(void); void you_only_have(unsigned char in_bank); void cprintulong(unsigned long ul); -void cprintfancy_ctr(unsigned long num, unsigned char center); -#define cprintfancy(num) cprintfancy_ctr(num, 0) +void cprintfancy(unsigned long num); +void cprintfancy_centered(unsigned long num); void too_much_cash(void); char would_overflow(unsigned long a, unsigned long b); int get_time(void); @@ -248,7 +249,7 @@ unsigned char firmpos; /* use page 6 for these buffers */ char *firm = (char *) 0x680; -char *fancy_buf = (char *) 0x600; +char *num_buf = (char *) 0x600; char *item[] = { "Opium", "Silk", "Arms", "General Cargo" }; @@ -282,10 +283,27 @@ int base_price[4][8] = { {1000, 11, 16, 15, 14, 12, 10, 13}, {10, 12, 16, 10, 11, 13, 14, 15}, {1, 10, 11, 12, 13, 14, 15, 16} }; +/* hkw_ is the warehouse, hold_ is how much of each item is + in your hold. both need to be unsigned (makes no sense to + have negative amounts in warehouse or hold). hold_ needs + to be a long because it's entirely possible to buy e.g. over + 32768 of some item later in the game. You won't be able to + leave port, so you'll have to get rid of it on the same turn, + but we still have to stop it overflowing a 16-bit int. + I'm not convinced hkw_ needs to be long, since it's + limited to 10000 of each item. */ unsigned long hkw_[4], hold_[4]; -/* this really can go negative */ -int hold = 0; +/* this really can go negative (meaning, your ship is + overloaded). It needs to be a long though. At some + point, it *still* might overflow, e.g. if general cargo + drops to 1, you have over 2**31-1 in cash, and you + buy that many general cargo... Probably should limit the + amount of cargo the player can buy per transaction, but + even then, they can do multiple transactions on the same + turn. Need a signed version of would_overflow() to do + this right. */ +long hold = 0; /* these being negative would be a Bad Thing */ unsigned int guns = 0, @@ -389,7 +407,7 @@ int get_time(void) { /* print an int or long as a string, conio-style */ void cprintulong(unsigned long ul) { - cputs(ultoa(ul, fancy_buf, 10)); + cputs(ultoa(ul, num_buf, 10)); } void at_sea() { @@ -521,41 +539,61 @@ void new_gun(void) return; } +void cprintfancy_centered(unsigned long num) { + if(num < 1000000L) { + /* 0 to 999999: + | 999999 | + | 99999 | + | 9999 | + | 999 | + | 99 | + | 9 | */ + cputs(" "); + if(num < 100L) cputc(' '); + if(num < 10000L) cputc(' '); + revers(1); + cprintulong(num); + } else { + if(num < 10000000L) cputc(' '); + revers(1); + cprintfancy(num); + } + revers(0); +} + +/* if BIGNUM, cprintfancy() just converts to bignum and uses + cprintfancy_big() to do the work. A bit slower, but fast + enough, and avoids duplicate logic. */ +#ifdef BIGNUM +void cprintfancy(unsigned long num) { + bignum(b); + ulong_to_big(num, b); + cprintfancy_big(b); +} +#else /* replaces old fancy_numbers. same logic, but stuff is just printed on the screen rather than being kept in a buffer. - center is a boolean. - Since we no longer return a string, port_stats() can't use - strlen() to position the debt amount... so we have to do - it here. Complicates the logic. One minor difference between this and fancy_numbers() is that we print "1.10 Million" rather than "1.1 Million" (extra zero). I don't think anyone's going to complain. - - BUG here, 2.09 million is printed as 2.9 million (leading 0 - digit is dropped) */ -void cprintfancy_ctr(unsigned long num, unsigned char center) { - char mil = 1; - char *fancy_buf = (char*)0x600; - unsigned long tmp; +void cprintfancy(unsigned long num) { + unsigned char tmp; if(num >= 100000000L) { /* 100 million and up: |1000 Million| |100 Million | */ - if(center) revers(1); - cputs(ultoa(num / 1000000L, fancy_buf, 10)); + cprintulong(num / 1000000L); } else if (num >= 10000000L) { /* 10 million to 99 million: | 10 Million | |10.1 Million|*/ tmp = (num % 1000000L) / 100000L; - if(center && !tmp) cputc(' '); - if(center) revers(1); - cputs(ultoa(num / 1000000L, fancy_buf, 10)); + cprintulong(num / 1000000L); if(tmp) { cputc('.'); - cputs(ultoa(tmp, fancy_buf, 10)); + cprintulong(tmp); } } else if (num >= 1000000L) { /* 1 million to 9 million: @@ -563,12 +601,11 @@ void cprintfancy_ctr(unsigned long num, unsigned char center) { |1.10 Million| // always has 0, never 1.1 |1.23 Million| */ tmp = (num % 1000000L) / 10000L; - if(center && !tmp) cputc(' '); - if(center) revers(1); - cputs(ultoa(num / 1000000L, fancy_buf, 10)); + cprintulong(num / 1000000L); if(tmp) { cputc('.'); - cputs(ultoa(tmp, fancy_buf, 10)); + if(tmp < 10L) cputc('0'); + cprintulong(tmp); } } else { /* 0 to 999999: @@ -578,26 +615,14 @@ void cprintfancy_ctr(unsigned long num, unsigned char center) { | 999 | | 99 | | 9 | */ - mil = 0; - if(center) { - cputs(" "); - /* - cputc(' '); - cputc(' '); - cputc(' '); - */ - tmp = 0; - for(tmp = 100L; tmp < 1000000L; tmp *= 100L) - if(num < tmp) cputc(' '); - } - if(center) revers(1); - cputs(ultoa(num, fancy_buf, 10)); + cprintulong(num); + return; } - if(mil) cputs(" Million"); - revers(0); + cputs(" Million"); } +#endif /* void fancy_numbers(unsigned long num, char *fancy) { @@ -1242,7 +1267,6 @@ int sea_battle(int id, int num_ships) { /* TODO: rewrite in asm. Maybe. */ long get_num(void) { - static char number[20]; unsigned char count = 0; char input; @@ -1250,21 +1274,35 @@ long get_num(void) { cblank(1); while((input = numgetc()) != '\n') { + if(count >= 10) continue; if(input == BKSP) { if(!count) continue; backspace(); - number[count] = '\0'; + num_buf[count] = '\0'; count--; } else if(input == 'a') { if(!count) return -1; + } else if(input == 'k' || input == 'm') { + char i; + for(i = 0; i < (input == 'k' ? 3 : 6); i++) { + cputc('0'); + num_buf[count++] = '0'; + if(count >= 10) break; + } + } else if(input == DEL) { + while(count) { + backspace(); + count--; + } + POKEW(1024, count); } else { cputc(input); - number[count++] = input; + num_buf[count++] = input; } } cursor(0); - number[count] = '\0'; - return strtol(number, (char **)NULL, 10); + num_buf[count] = '\0'; + return strtol(num_buf, (char **)NULL, 10); } /* TODO: rewrite in asm */ @@ -1302,8 +1340,8 @@ void cash_or_guns(void) } else { #ifdef TIMEWARP year = 1869; - // cash = 1000000000L; - cash = 4294000000L; + cash = 1000000000L; + // cash = 4294000000L; // cash = 3500000L; #ifdef BIGNUM big_copy(bank, big1M); @@ -1489,7 +1527,7 @@ void port_stats(void) // gotox(34 - strlen(fancy_num) / 2); clrtoeol(); // revers(1); - cprintfancy_ctr(debt, 1); + cprintfancy_centered(debt); // cputs(fancy_num); // revers(0); @@ -2210,6 +2248,21 @@ void li_yuen_extortion(void) { // amount = ((cash / i) * ((float) randi() / RAND_MAX)) + j; amount = randclamp((cash >> (i - 1))) + j; + + /* + clear_msg_window(); + cputs("DEBUG li_yuen_extortion()\r\n"); + cputs("amount time i j\r\n"); + cprintulong(amount); + cputc(' '); + cprintulong(time); + cputc(' '); + cprintulong(i); + cputc(' '); + cprintulong(j); + agetc(); + */ + if(!amount) return; /* asking for 0 is dumb */ compradores_report(); @@ -2961,6 +3014,13 @@ int main(void) { port_stats(); + /* + clear_msg_window(); + cputs("li "); + cprintulong(li); + agetc(); + */ + if(wu_assassin) { wu_assassin = 0; compradores_report(); diff --git a/timed_getch.s b/timed_getch.s index f52f50c..ba3b0a9 100644 --- a/timed_getch.s +++ b/timed_getch.s @@ -53,6 +53,8 @@ _agetc: ; special cases cmp #$9b ; enter key, return as-is beq ok + cmp #$9c ; delete key, return as-is + beq ok cmp #$7e ; backspace beq ok @@ -92,10 +94,16 @@ _numgetc: jsr _agetc cmp #$9b beq ok - cmp #$7e + cmp #$7e ; backspace beq ok cmp #$61 ; allow 'a' for "all" beq ok + cmp #$6b ; allow 'k' for 1000 + beq ok + cmp #$6d ; allow 'm' for 1 million + beq ok + cmp #$9c ; shift-del + beq ok cmp #'0' bcc _numgetc cmp #'9'+1 |