aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cart.txt85
-rw-r--r--console.s22
-rw-r--r--taipan.c72
3 files changed, 118 insertions, 61 deletions
diff --git a/cart.txt b/cart.txt
index f897de9..6b81727 100644
--- a/cart.txt
+++ b/cart.txt
@@ -31,44 +31,64 @@ the 1200XL.
...so:
-Bank 7 has the startup code, uncompressed title screen, title code,
-and code to copy from the other banks to RAM.
-
-That gives me banks 0-6 to store code in. The code is 27174 bytes, so I
-have plenty of space: it'll occupy 4 banks, leaving 2 empty ones. The
-last code bank will only be 1/3 full of code... but 1K of it will be
-used for the font, so 4.5K free there.
+Bank 7 has the startup code, uncompressed title screen, title code, and
+code to copy stuff from the other banks to RAM. The main portion of the
+code gets split up into bank-sized chunks... but the last bank of code
+doesn't need to be copied to RAM: I use a custom linker script to have
+cl65 org the RODATA segment there, plus a new segment called HIGHCODE,
+which is executable code that will run directly from the cartridge. This
+bank stays selected while the game is running, so it also has the font
+in it.
+
+There are currently 3 banks of code (numbers 0, 1, 2) that need to be
+copied to RAM. The bank with RODATA and HIGHCODE is bank 3. Banks 4, 5,
+6 are unused. As I optimize the code, bank 2 will contain less and less
+code, and hopefully will disappear one day (at which point, I only need
+a 32K cart instead of a 64K one).
Code in bank 7 will copy all the chunks to correct place in RAM... and
I don't need to leave room for DOS or anything else, so the code can be
ORGed at $0400 (romable_taimain.raw target in the Makefile does this).
-$0400 + 27174 means the code ends at $6e26. The BSS is right after that,
-and is less than a page. The OS will place the GR.0 display list at $7c20,
-and the stack will grow down from there to $7a20 (except it never grows
-that much).
+Currently, romable_taimain.raw is 18739 bytes. $0400 + 18739 means the
+code ends at $4d33. The BSS is right after that, and is less than a
+page. The OS will place the GR.0 display list at $7c20, and the stack
+will grow down from there to $7a20 (except it never grows that much).
-Copying the game code to RAM causes a short delay at boot (0.43 seconds).
+Copying the game code to RAM causes a short delay at boot (about 1/3 sec).
It's barely noticeable, and lots of cartridge games have similar delays.
The copying code could maybe be optimized to speed it up a little,
but it's probably not even worth the effort.
Amusingly, the Taipan cart will work on a 32K 800. Not a 16K Atari though.
+24K might become possible, but currently isn't (AFAIK there never were
+any stock 24K Ataris anyway, they'd be 8K or 16K machines with a 3rd-party
+RAM upgrade, and exceedingly rare these days).
bank 7: fixed bank
$a000-$bxxx - title screen data, dl, menu code,
memory size checker, code to
- copy romable_taimain to RAM
+ copy romable_taimain to RAM.
+ currently 1441 bytes free in this bank.
$bffa-$bfff - cart trailer
-banks 0, 1, 2: full banks of romable_taimain code
+banks 0, 1: full banks of romable_taimain code
$8000-$9dff - 31 pages (7936 bytes, 7.75K) of code
-$9f00-$9fff - unused
-
-bank 3: last (partial) bank of romable_taimain, plus the font.
-This bank stays enabled after copying is done.
-$8000-$9bff - up to 7K of code (28 pages)
-$9c00-$9fff - font (1K)
+$9f00-$9fff - unused, filled with $ff
+
+bank 2: last (partial) bank of romable_taimain
+$8000-$9f00 - up to 31 pages (7936 bytes, 7.75K) of code.
+ currently only 2809 bytes (11 pages) are used,
+ and the number's getting smaller all the time.
+$9f00-$9fff - unused, filled with $ff
+
+bank 3: RODATA and HIGHCODE segments.
+ This bank stays enabled after copying is done.
+ currently all but 7 bytes are used.
+$8000-$9bff - up to 7K of code/data (28 pages)
+$9c00-$9fff - font (1K). The font has a nonzero byte at $9ffc,
+ so the OS doesn't think there's a cartridge here
+ if this bank happens to come up at boot.
Unused areas are filled with $ff (this is the default state for both
flash and EPROM). For the banks that map at $8000, this includes the
@@ -91,6 +111,11 @@ Changes the game needed for a cart version: Not many.
as low as possible allows room for bugfixes or new features (if I ever
add any).
+the RODATA segment is org'ed to $8000 (see cartbank3.cfg).
+
+all of the game's asm code, and a small amount of the C code, goes in
+a new segment called HIGHCODE (see cartbank3.cfg).
+
checkmem.s isn't needed any longer... though there is a new memory checker
(in bank 7) that says "32K required" if someone tries it on a 16K machine.
@@ -105,11 +130,10 @@ The title decompression is gone: it just displays the title screen DL
and data straight from ROM. The menu help text and the tail end of the
display list are in RAM though, so the menu can change them. Moving the
end of the DL to RAM means one extra black (border-colored) scanline
-appears due to the DL jump instruction. I may make the border the same
-color as the text bg, to make this less noticeable.
+appears due to the DL jump instruction.
The font is located in ROM, on a 1K boundary, so CHBAS can point
-to it, rather that $2000 like the xex version.
+to it, rather than $2000 like the xex version.
num_buf and firm are located in the BSS rather than page 6 as they
are in the .xex version.
@@ -129,6 +153,21 @@ in asm? Probably. Do I want to? Not really.
--
+A 5200 version should be possible. At the moment, the .xex version is
+just under 32K (excluding the memory-checker segment). The 5200 would
+need its own conio, since cc65's conio for 5200 uses a 20x24 GR.1 screen
+and doesn't support input at all.
+
+The 5200 cart window is 32K, so no bankswitching would be
+required. There's only 16K of RAM, but that'll be plenty.
+
+The numeric keys on the controller would be used for all input. When
+entering a firm name, it'll work like texting on a regular phone keypad,
+press 2 for A, press it again for B, etc. The * and # keys will be
+backspace and enter. Not sure what to use for A-for-all and delete.
+
+--
+
The cartridge label should look like a classic brown 1st-gen 400/800 cart,
even if the cart shell itself doesn't.
diff --git a/console.s b/console.s
index 7c7e18e..04524ab 100644
--- a/console.s
+++ b/console.s
@@ -2,9 +2,11 @@
.include "atari.inc"
.export _clrtobot, _clrtoeol, _clrtoline, _cspaces, _cblank, _backspace
+ .export _rvs_on, _rvs_off
.import mul40 ; from cc65's runtime
.importzp tmp3 ; ditto
+ .import _revflag ; conio/revers.s
.import bump_destptr ; these two are
.importzp destptr ; from draw_lorcha.s
.import _cspace
@@ -26,7 +28,9 @@
_clrtobot: ; same as clrtoline(24);
lda #24
- bne _clrtoline
+ ;bne _clrtoline
+ .byte $2c ; BIT absolute opcode
+ ; fall through to _clrtoeol
_clrtoeol:
lda ROWCRS
@@ -81,6 +85,11 @@ _cspaces:
bne @lp
rts
+_backspace:
+ dec COLCRS
+ lda #1
+ ; fall through to _cblank
+
_cblank:
tax
lda COLCRS
@@ -95,7 +104,10 @@ _cblank:
sta COLCRS
rts
-_backspace:
- dec COLCRS
- lda #1
- bne _cblank
+_rvs_on:
+ lda #$80
+ .byte $2c ; BIT absolute opcode
+_rvs_off:
+ lda #0
+ sta _revflag
+ rts
diff --git a/taipan.c b/taipan.c
index 7f1c206..31fcf3e 100644
--- a/taipan.c
+++ b/taipan.c
@@ -117,6 +117,12 @@ extern void clrtoeol(void);
/* print 'count' spaces: */
extern void __fastcall__ cspaces(unsigned char count);
+/* avoid calling/linking conio's revers() function. This saves us
+ 49 bytes (2 per call to revers(), plus these functions are smaller
+ than conio's revers() because they return void) */
+extern void rvs_on(void);
+extern void rvs_off(void);
+
/* asm funcs from draw_lorcha.s for drawing/animating enemy ships.
used by sea_battle() */
extern void __fastcall__ draw_lorcha(int which);
@@ -578,9 +584,9 @@ void cprintulong(unsigned long ul) {
void at_sea(void) {
gotoxy(30, 6);
cspace();
- revers(1);
+ rvs_on();
cputs(location[0]);
- revers(0);
+ rvs_off();
cspaces(3);
}
@@ -694,13 +700,13 @@ void cprintfancy_centered(unsigned long num) {
cspaces(3);
if(num < 100L) cspace();
if(num < 10000L) cspace();
- revers(1);
+ rvs_on();
cprintulong(num);
} else {
- revers(1);
+ rvs_on();
cprintfancy(num);
}
- revers(0);
+ rvs_off();
}
/* if BIGNUM, cprintfancy() just converts to bignum and uses
@@ -787,10 +793,10 @@ void hide_cursor() {
*/
void update_guns() {
- revers(1);
+ rvs_on();
gotoxy(31, 1);
justify_int(guns);
- revers(0);
+ rvs_off();
// hide_cursor();
}
@@ -885,13 +891,13 @@ int sea_battle(int id, int num_ships) {
/* the static part of "we have N guns" display, gets printed
only once per battle. Bloats the code by 30-odd bytes, but
updates are smoother-looking. Maybe. */
- revers(1);
+ rvs_on();
gotoxy(30, 0);
cputs(" We have");
gotoxy(30, 1);
cspaces(6);
cputs("guns");
- revers(0);
+ rvs_off();
update_guns();
fight_stats(num_ships, orders);
@@ -1610,18 +1616,18 @@ void port_stats(void)
*/
gotoxy(32, 3);
- // revers(1);
+ // rvs_on();
cputs(months + 4 * (month - 1));
- // revers(0);
+ // rvs_off();
cspace();
cprintulong(year);
gotoxy(30, 6);
cblank(10);
- revers(1);
+ rvs_on();
if(port == 4 || port == 5) cspace();
cputs(location[port]);
- revers(0);
+ rvs_off();
gotoxy(28, 9);
clrtoeol();
@@ -1630,11 +1636,11 @@ void port_stats(void)
gotoxy(29, 12);
clrtoeol();
i = status / 20;
- // if(i < 2) revers(1);
+ // if(i < 2) rvs_on();
cputs(st[i]);
cputc(':');
cprintulong(status);
- // revers(0);
+ // rvs_off();
gotoxy(6, 14);
cblank(14);
@@ -1748,7 +1754,7 @@ void aire(void) {
void retire(void) {
compradores_report();
- revers(1);
+ rvs_on();
// cspaces(29);
// crlf();
retire_blanks();
@@ -1769,7 +1775,7 @@ void retire(void) {
// cspaces(29);
// crlf();
retire_blanks();
- revers(0);
+ rvs_off();
timed_getch();
final_stats();
@@ -1842,7 +1848,7 @@ void final_stats(void)
cputc_s();
}
cputs("\r\n\n");
- revers(1);
+ rvs_on();
cputs("Your score is ");
#ifdef BIGNUM
cprintfancy_big(bigscore);
@@ -1850,7 +1856,7 @@ void final_stats(void)
cprintulong(score);
#endif
cputs(".\r\n");
- revers(0);
+ rvs_off();
if ((score < 100) && (score >= 0))
{
cputs("Have you considered a land based job?\r\n\n\n");
@@ -1871,10 +1877,10 @@ void final_stats(void)
if (score > 49999L)
{
- revers(1);
+ rvs_on();
}
cputs("Ma Tsu");
- revers(0);
+ rvs_off();
cspaces(9);
cputs("50,000 and over |\r\n");
cprint_pipe();
@@ -1882,21 +1888,21 @@ void final_stats(void)
if ((score < 50000L) && (score > 7999L))
{
- revers(1);
+ rvs_on();
}
cputs("Master Taipan");
- revers(0);
+ rvs_off();
cputs(" 8,000 to 49,999|\r\n");
cprint_pipe();
// cputc('|');
if ((score < 8000L) && (score > 999L))
{
- revers(1);
+ rvs_on();
}
// cputs("Taipan");
cprint_taipan();
- revers(0);
+ rvs_off();
cspaces(10);
cputs("1,000 to 7,999|\r\n");
cprint_pipe();
@@ -1904,10 +1910,10 @@ void final_stats(void)
if ((score < 1000) && (score > 499))
{
- revers(1);
+ rvs_on();
}
cputs("Compradore");
- revers(0);
+ rvs_off();
cspaces(8);
cputs("500 to 999|\r\n");
cprint_pipe();
@@ -1915,10 +1921,10 @@ void final_stats(void)
if (score < 500)
{
- revers(1);
+ rvs_on();
}
cputs("Galley Hand");
- revers(0);
+ rvs_off();
cspaces(7);
cputs("less than 500|\r\n");
@@ -2921,15 +2927,15 @@ void buy(void) {
clrtobot();
afford = cash / price[choice];
- revers(1);
+ rvs_on();
cputs(" You can ");
- revers(0);
+ rvs_off();
gotoxy(0, 22);
how_much();
cputs(item[choice]);
cputs(" shall");
gotoxy(31, 22);
- revers(1);
+ rvs_on();
cputs(" afford ");
gotoxy(31, 23);
// cspaces(9);
@@ -2942,7 +2948,7 @@ void buy(void) {
if(afford < 100000000) cspace();
cprintulong(afford);
- revers(0);
+ rvs_off();
gotoxy(0, 23);
cputs("I buy, ");