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 | 
