A86: Re: External Strings


[Prev][Next][Index][Thread]

A86: Re: External Strings




Dux taught me how to do strings, they're really easy.  You should read his
tutorial on the VAT and ABS addressing, as it will come in handy when trying
to figure out how the code works.  Map is defined as an address somewhere on
ram page 1 to load the data into (according Dux, the range is $800b [one OP,
11 bytes, is there when your program is run...after all, ram page 1 IS the
FPS (floating point stack)] to $bfea, giving you 16352 bytes of continuous,
temporary ram to work with).  The code returns "RET C" if the string isn't
found (presumably to the TI-OS or a shell), but you could have it jump "JR
C,error" to an error message if you so choose.

[see below code for more info on strings]

loaddata:
 ld hl,mapvar-1        ; point to var name (first byte is irrelevant)
 rst 20h               ; load name into OP1
 rst 10h               ; call _FINDSYM
 ret c                 ; if it doesn't exist, return
 ld a,b                ; copy high byte
 ex de,hl              ; swap low bytes
 call $4c3f            ; skip length word (ahl += 2)
 call _SET_ABS_SRC_ADDR  ; set the source address as the var
 ld a,1                ; copy to ram page 1
 ld hl,Map-$8000       ; start at $8000 on page 1 (page 1 is at $10000 ABS)
 call _SET_ABS_DEST_ADDR ; set the destination as ram page 1
 xor a                 ; clear high byte
 ld hl,4096            ; size of string var
 call _SET_MM_NUM_BYTES  ; set the number of bytes to copy
 call _mm_ldir         ; copy the map
 call _RAM_PAGE_1      ; make sure ram page 1 is still loaded
 jr dataloaded
mapvar:
 .db 8,"cnc86map"

To load your data into strings, the easiest way is to use Jimmy Mardell's
great BIN2STR utility, which comes in the Sqrxz level editor zip file.  It
will convert a binary file directly to a string variable, ready to be sent
to the 86 (actually it defaults to 85 files, you have to tell it to make 86
strings...).  If you need code or something sprites that are stored as
.db's, then you will need to assemble it first.  The easiest way to do this
is with TASM (something like TASM -t80 -b -s -g0 might work).  The .obj file
will be in the correct format for BIN2STR.  The .sym file is the symbol
table, which will be all of the equates and labels used in the code.  You
will need to paste this into your program if you are going to be calling and
jumping to stuff on ram page 1 as if it was part of your program.  Make sure
you use the .org directive at the top of the code and set it to the location
in ram page 1 where your code will be so the lables produced will be
correct.

If you are using a level editor and want to save the data as a string, you
can use these C routines I wrote for mine.  You call save_map_str() with the
name of the map to save without the extension.  .86s will be appended to it,
and the name will be the variable that is sent to the 86.  This is designed
to save a character array that is [64][64], hence the 4096 bytes used
throughout it, but this is easily changed to whatever you need.  Last thing,
you can change the text in header.comment to whatever you want.  It is a max
of 42 bytes (zero terminated?  don't remember...might be good to stick with
41 or less) and padded with zero bytes.  So I just fill it full of zero's
and copy the actual text to it later after that, which makes it a little
easier.  If you have any questions about this code, please email me and not
the list, as it's not a C list.  If there's enough demand, I'll write up my
own BIN2STR and post the source.

typedef struct
{
  char  sig[8],         // "**TI86**"
        ext_sig[3],     // EOF, CR, NULL byte (1a, 0a, 00)
        comment[42];    // padded with NULL bytes to len of 42
  short file_len;       // file length minus 0x39
} FileHeader;

typedef struct
{
  short data_ptr,       // points to var_len2 at end of entry
        var_len;        // length of variable
  char  type,           // variable type
        name_len,       // variable name length
        name[8];        // variable name
  short var_len2;       // exactly the same as var_len
} FileEntry;

typedef struct
{
  short len;            // length of the program
  char  token[2];       // for a compiled asm prgm, (8e, 28)
} VarPrgm;

typedef struct
{
  short len;            // length of the string
} VarString;

void save_map_str(char *name)
{
  FILE  *fp;
  short x, y;
  unsigned short checksum;
  char *p;
  FileHeader header;
  char fname[16];

  strcpy(fname, name);
  strcat(fname, ".86s");

  memcpy(header.sig, "**TI86**", 8);
  header.ext_sig[0] = 0x1a;
  header.ext_sig[1] = 0x0a;
  header.ext_sig[2] = 0x00;
  memset(header.comment, 0, 42);
  memcpy(header.comment, "cnc86map", 8); //CnCEdit map for CnC86
  header.file_len = 10 + strlen(name) + 4096;

  printf("Saving map as %s...", fname);
  fp = fopen(fname, "wb");
  if (fp == NULL)
    printf("\nError opening %s.  Map not saved!\n", fname);
  else
  {
    fwrite(&header, sizeof(header), 1, fp);

    checksum = 0;
    fputc_sum(4 + strlen(name), fp, &checksum);
    fputc_sum(0, fp, &checksum);
    fputc_sum((4096 + 2) % 256, fp, &checksum);
    fputc_sum((4096 + 2) >> 8, fp, &checksum);
    fputc_sum(0x0c, fp, &checksum);
    fputc_sum(strlen(name), fp, &checksum);
    for(x = 0; x < strlen(name); x++)
      fputc_sum(name[x], fp, &checksum);
    fputc_sum((4096 + 2) % 256, fp, &checksum);
    fputc_sum((4096 + 2) >> 8, fp, &checksum);
    fputc_sum(4096 % 256, fp, &checksum);
    fputc_sum(4096 >> 8, fp, &checksum);

    for(y = 0; y < 64; y++)
      for(x = 0; x < 64; x++)
        fputc_sum(map[x][y], fp, &checksum);
    fwrite(&checksum, 2, 1, fp);

    fclose(fp);
    if (errno != 0)
    {
      printf("\nError writting %s.  Map not saved!\n", fname);
      return;
    }
    printf("done!\n");
  }
}

fputc_sum(char c, FILE *fp, unsigned short *sum)
{
  *sum += c;
  fputc(c, fp);
}

-----Original Message-----
From: Dave VanEe <dvanee@dowco.com>
To: assembly-86@lists.ticalc.org <assembly-86@lists.ticalc.org>
Date: Wednesday, November 11, 1998 11:49 PM
Subject: A86: External Strings


>
>Right now I have a lot of data for my program stored all under one label,
ie:
>
>DATA:
> .db -stuff-
> .db -more stuff-
> ...etc...
>
>A while ago someone posted how to load 4k into ram page 1. How can I put
>all of this info into an external string that could be copied to ram page
>1? Right now it totals 792 bytes, but will get larger later.
>
>Thanx,
>Dave