CC65 and Commodore specific characters

Started by Stephane Richard, October 04, 2006, 05:00 AM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

Stephane Richard

again, the title says all, as we all know C=[Character] and CTRL-[Characterrs]  how does that work in CC65?  say i wanna draw a boxed frame for example. :-).
When God created light, so too was born, the first Shadow!

MystikShadows

Guest

You can represent any PETSCII character in C and Assembler as the byte code, but CC65 can also read ASCII files and translate them to PETSCII.  I've not tried to create a text file with special characters for use with CC65, so I don't know how you do that, but it's probably in the documentation.

Stephane Richard

oh...well that's good to know...i'll definitaly be looking into that...I'm one of those TUI/GUI coders, I hate to just throw my programs at the screen without some sort of "intelligent" layout and yes, boxed characterrs, among other things, come in very hanby for this kind of stuff. :-)

So all I need is a commodore ascii chart and I'm in business...cool, shouldn't be too hard to find one of those ;-).

Thank you very much.
When God created light, so too was born, the first Shadow!

MystikShadows

BillBuckels

A Utility for Doing Text Screen Layout for the C64 and C128

I find it interesting (but not surprising) that CC65 does not come with utilities for this purpose. Nor it seems with much knowledge equity of the flavour that I prefer in this (and other) areas from what I have been noticing both on the C64 and Apple II sides.

You might consider using a compiler package that has been functional from that time to this and provides a complete programming environment including the tools to do the job:

Aztec C65 Version 1.06e Cross Compiler

http://www.clipshop.ca/Aztec/index.htm#commodore

Manx Aztec C65
Version 1.06e
Target: Commodore 64 6502 Native Code
Target OS: Commodore 64 (C64) BASIC 2 operating system
Compiler: C II Vers. 1.05h 6502 (C) 1982, 1983 by Manx Software Systems

MS-DOS cross-development environment for 8086 and compatible computers
Preconfigured for Windows XP

With several samples, projects, and a production example
With an additional link library for sound and graphics etc.
With many original related custom tools for MS-DOS including source code

This is a complete Aztec C build environment for Windows XP (MS-DOS) which will enable you to produce efficient 6502 machine-language programs which will, when properly built, load and run from BASIC on a Commodore 64 or in the Vice C64 emulator, and which will exit cleanly to BASIC when done.

http://www.clipshop.ca/Aztec/Aztec64.zip

For example, below is a listing for a converter that I provide that bsaves a text screen c/w color attributes. If you have ever used TheDRAW to BSave a text screen on the IBM-PC then you know just how good these editors are. It is trivial to design your program screens with color attributes and all the rest of it then save them for use on the C64 or C128.

Example of BSAVED Text Screen for the C64



The text screen above was created using the utility listed below. The program that uses the text screen itself was written in Aztec C64 which comes with many utilities similar to the one below to make programming in C on the C64 a snap.  There just isn't a better C64 C programming environment available with ease of installation and better utilities and examples. This hasn't changed in the more than 25 years that this compiler has been around. It worked then and still works.

Before I list the utility I am listing a loader from my cross-compiler distribution examples to show how easy it is. No need to reinvent the wheel. You will also notice that you have the option of embedding these screens in a character array as well. Your choice and my example shows how to use these. Actually my library also has a number of functions that provide support for colored text and so forth using the extended character set in a disciplined manner similar to what is done on the IBM-PC rather than as a bunch bits and pieces that draw little boogers. I have drawn my fair share of boogers as well but that's a listing for another day.

Download the compiler and give a try and you will see what you have been missing and the way it was really done.

An Aztec C64 demo using a converted text screen from the IBM created by bsv2x64


/* btest.c (C) Copyright Bill Buckels 2008 */

/* an Aztec C64 demo using a converted text screen from
   the IBM created by bsv2x64.

   KISS 101 (Keep it Simple Simon)

   all the programmer needs to do is draw the
   screen on the IBM remembering to keep it 40 columns
   wide x 25 rows.

   It's just like baking a cake. Recipe below.

   See bsv2x64.c for details or use bsv2x64.exe
   without details. See MAKEFILE and makedisk.bat
   for usual build directions.

   Runs on a C64 or in an C64 emulator.

   */



/* the CMAIN define must always be the first line
   in your main program when
   using poke.h and B64NAT.LIB and nowhere else.

   B64NAT.LIB makes extensive use of the memory variables
   in poke.h which are included in your main program
   and nowhere else.

   They are referenced as externals by B64NAT.LIB and any
   overlay modules that you may create.

   when linking with B64NAT.LIB the aztec C linker requires
   B64NAT.LIB on the link line before C64NAT.LIB to
   resolve B64NAT.LIB calls to C64NAT.LIB
*/

#define CMAIN 1

#include <poke.h>
#include <colors.h>


/* character array created from IBM text screen btest.bsv */
/* array structure is C64 screen value, C64  color value */
/* char btest[2000]; */

#include "btest.h"

char *prompt = "Press 0-9 and A-F for Color.";

main()
{

   int row, col1, col2, color, reverse=1, normal=0;
   int ch, color, len;
   int prow = 12, pcol = 5;
   char buf[10];


   /* first a simple example */
   /* this one gets the C64 Aztec C good houskeeping seal of approval */

   scr_mixed(); /* put the C64 in mixed case mode */
   scr_clear(); /* clear screen */

   memscr(btest); /* load the text screen array */

   outtext("Press A Key To See Colors...",prow,pcol,C64_BWHITE,normal);

   /* clear all keypressess */
   kbflush();

   /* wait until a key is pressed */
   while(!kbhit());

   scr_back(0, -1); /* set background to black */
   scr_clear(); /* clear screen */


   row = 0;
   col1 = 0;   /* normal column */
   col2 = 10;  /* reverse column */
   for (color = 1; color < 16; color++) {
     sprintf(buf,"Color %2d", color);
     outtext(buf,row,col1,color,normal);
     outtext(buf,row,col2,color,reverse);
     row++;
   }
   len = strlen(buf); /* save the string length */

   prow = 16;
   pcol = 0;
   outtext("Press Any Key to Reverse...",prow,pcol,C64_BWHITE,normal);

    /* wait until a key is pressed */

    while (kbhit()); /* wait for key release */
    kbflush();
    getch();  /* wait for another key press */

   row = 0;
   for (color = 1; color < 16; color++) {
     revtext(row,col1,len,reverse);
     revtext(row,col2,len,normal);
     row++;
   }


outtext(prompt,prow,pcol,C64_BWHITE,normal);
outtext("Press 'X' To Load Screen...",prow+1,pcol,C64_BWHITE,normal);
    len = strlen(prompt);

TOP:;


    ch = toupper(getch());

    /* characters 0-9 and A-F */
    if ((ch > 47 && ch < 58) || (ch > 64 && ch < 71)) {
if (ch < 65) color = ch - 48;
else color = ch - 55;
attext(prow,pcol,len,color);
/* border color,background color */
        scr_back(-1,color); /* set border only */
}

if (ch != 'X') goto TOP;

    scr_back(-1,C64_LBLUE); /* reset border only */
    scr_clear(); /* clear screen */

   /* load a binary screen - use default load addresses */
   /* second arg is set to 0 - otherwise override addr */
   bload("BTEST.BXC",0);
   bload("BTEST.BXD",0);


   prow = 12;
   pcol = 9;
   outtext("Press A Key To Exit...",prow,pcol,C64_BWHITE,normal);
   kbflush();
   while(!kbhit());

   /* eat the last key pressed */
   getchar();
   scr_clear(); /* clear screen to hide getchar */
   scr_reset(); /* clear again and reset to default and UPPER case */

   exit(0);

}




BillBuckels

bsv2x64 converts IBM BSaved text screens to Commodore 64 compatible BSaved text screens

The listing for this program is split into two parts. The comments below are verbose for sure but terribly important since they explain what we are really doing here.

Part 1 of 2


/* bsv2x64.c (C) Copyright Bill Buckels 2008 */

/*
converts IBM BSaved text screens like those created in TheDRAW to
Commodore 64 compatible BSaved text screens suitable for use as C64
program screens.

also produces a character array suitable for embedding in an Aztec C C64
application.

compiled under Microsoft (R) C/C++ Version 8.00c as a 16 bit MS-DOS
application. Should probably be ok for other compilers with minor
adjustments like headers and constants and storage considerations.
But since this is abslutely trivial compared to what is going on here
in an absolutely trivial application I have left this part as is
for readability purposes.

In this program I translate 144 IBM characters accurately to their
respective 128 commodore 64 equivalents. I will leave it to you to
decide for yourself how this is possible.

for more information on the bsaved text format see my wikipedia article
at:

http://en.wikipedia.org/wiki/BSAVE_(graphics_image_format)

*/


/*

C64 SCREEN MEMORY MAP

                                 COLUMN                             1063
      0             10             20             30            39 /
     +------------------------------------------------------------/
1024 |                                                            |  0
1064 |                                                            |
1104 |                                                            |
1144 |                                                            |
1184 |                                                            |
1224 |                                                            |
1264 |                                                            |
1304 |                                                            |
1344 |                                                            |
1384 |                                                            |
1424 |                                                            | 10
1464 |                                                            |
1504 |                                                            | ROW
1544 |                                                            |
1584 |                                                            |
1624 |                                                            |
1664 |                                                            |
1704 |                                                            |
1744 |                                                            |
1784 |                                                            |
1824 |                                                            | 20
1864 |                                                            |
1904 |                                                            |
1944 |                                                            |
1984 |                                                            | 24
     +------------------------------------------------------------\
                                                                   \
                                                                    2023
The actual values to POKE into a color memory location to change a
character's color are:

0  BLACK   4  PURPLE     8  ORANGE     12  GRAY 2
1  WHITE   5  GREEN      9  BROWN      13  Light GREEN
2  RED     6  BLUE      10  Light RED  14  Light BLUE
3  CYAN    7  YELLOW    11  GRAY 1     15  GRAY 3

For example, to change the color of a character located at the upper
left-hand corner of the screen to red, type: POKE 55296,2.

C64 COLOR MEMORY MAP
                                 COLUMN                             55335
      0             10             20             30            39 /
     +------------------------------------------------------------/
55296|                                                            |  0
55336|                                                            |
55376|                                                            |
55416|                                                            |
55456|                                                            |
55496|                                                            |
55536|                                                            |
55576|                                                            |
55616|                                                            |
55656|                                                            |
55696|                                                            | 10
55736|                                                            |
55776|                                                            | ROW
55816|                                                            |
55856|                                                            |
55896|                                                            |
55936|                                                            |
55976|                                                            |
56016|                                                            |
56056|                                                            |
56096|                                                            | 20
56136|                                                            |
56176|                                                            |
56216|                                                            |
56256|                                                            | 24
     +------------------------------------------------------------\
                                                                   56295

*/


#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define TRUE 1
#define FALSE 0

#define SUCCESS 0
#define FAILURE 1

/* 16 color indices for the VIC II C64 */
enum {  C64_BLACK=0,
        C64_BWHITE,
        C64_RED,
        C64_CYAN,
        C64_PURPLE,
        C64_GREEN,
        C64_BLUE,
        C64_YELLOW,
        C64_ORANGE,
        C64_BROWN,
        C64_LRED,
        C64_DGRAY,
        C64_MGRAY,
        C64_LGREEN,
        C64_LBLUE,
        C64_LGRAY};

/* IBM 16 color remapping for C64 conversion using the IBM indices to
   the C64 indices

C64_BROWN is never used (no IBM equivalent)
C64_DGRAY is never used (too dark)
C64_PURPLE is used for both MAGENTA and LMAGENTA
C64_CYAN is used for both CYAN and LCYAN
C64_LGRAY is used for WHITE

*/
unsigned char Vga2C64[16] = {
C64_BLACK,
        C64_BLUE,
        C64_GREEN,
        C64_CYAN,
        C64_RED,
        C64_PURPLE,
        C64_ORANGE,
        C64_LGRAY,
        C64_MGRAY,
        C64_LBLUE,
        C64_LGREEN,
        C64_CYAN,
        C64_LRED,
        C64_PURPLE,
        C64_YELLOW,
        C64_BWHITE};


FILE *fp = NULL, *fp2 = NULL,*fp3 = NULL;

/* a microsoft compatible bsaved text image format descriptor */
unsigned char BSV_header[7]={

'\xfd',          /* ID Flag = file descriptor identifier bsaved file */

'\x00', '\xb8',  /* base address     = LSB | MSB original segment    */
'\x00', '\x00',  /* offset from base = LSB | MSB original offset     */

'\xA0', '\x0F'   /* file size = LSB | MSB of bytes to be loaded +    */
/* size of descriptors in bytes (8)                 */
};


/* buffers for the ibm character-attribute pairs */
unsigned char bsvbuffer[4000], ptxbuffer[4000];


/*

Remap ibm screen characters to commodore 64 screen character
equivalents. All IBM DOS OEM characters that do not have a PETSCII
equivalent are taken as spaces (32).

The following table translates IBM oem ASCII into commodore 64
shifted (mixed case) PETSCII for writing directly to the C64 screen in
standard text mode (not multicolor).

This means that you can only use one background color.

The mapping to do this is different from printing the same ascii values
since when printing ascii on the C64 many of the values are screen
control codes mixed-in with characters. The indices in the table below
cannot be used for printing. For example the C64 petscii value is 1 for
the lowercase 'a' when writing to screen memory.

By adding 128 to the values in the table, a reverse character is
displayed.

This means that the background color is used to print the text, and the
text color is used to print the background. In other words adding 128
to the translated table value reverses the video.

It can also be used to translate into unshifted petscii provided the
ascii value is converted tolower() before being used as an indices into
the table. Your choice, keeping in mind that the upper case only
translation of these will be displayed in lower case if mixed case
screen mode is used and the lower case version will display upper case
characters as "garbage" if vice versa.

Prior to loading these on the C64 the screen the first step would be
putchar(14) to switch to mixed case. or if upper case only to
putchar(142) then to clear the screen and home the cursor by
putchar(147).

All the Alpha-Numeric characters can be directly translated, and almost
all the punctuation characters can be directly translated with the
notable exceptions of a dos style slash, an opening single quote, an
underscore, and a caret. I am able to provide a C64 substitution for
the underscore, and subsitute the closed single quote for the open
single quote.

You'll have to do without the dos slash and the caret.

The standard IBM box drawing characters are translated as well. Keeping
in mind that both the IBM and commodore have their own unique graphics
characters, it is only the IBM box characters that can be translated to
a single line equivalent on the C64.

The commodore's block graphics are not the same as the IBM's and a
right half and top half are not available on the C64, so I substitute a
right third and top third. A left half and bottom half are available but
if all are to be used together to create a block-pixel image a slight gap
will show rightwise and topwise which may degrade the result.

Stay away from block graphics if you can and stick to boxes and
standard characters if you are preparing screens for conversion to C64.

The idea here is not to translate all the ibm characters into commodore
64 characters but rather to provide a slightly compromised character set
mostly on the IBM hi-ascii side that will fit into the C64's standard
128 positions. 144 IBM characters are translated accurately in the
table with the exceptions that I have noted.

The scientific notation and multi-lingual characters from the IBM have
no PETSCII equivalent and are not translated. I was lazy when
translating the IBM multilingual characters allowing that it is better
for the user to make whatever substitution they wish from the upper
and lower case alphabets themselves. As an english speaking western
Canadian what I have done here suits my purposes just fine thanks.

If a commodore 64 equivalent is not possible a blank character is
printed.

Despite the caveats noted above, a thoughfully constructed 40 column x
25 row area saved as an 80 column x 25 row BSaved Text Screen with a
single background color (preferably black) will translate intact to a
commodore 64 equivalent, allowing you to use a utility like TheDraw on
the IBM to do your C64 screen layouts.

*/

/* if you have qedit or some other DOS editor with an oem ascii chart
you can refer to that and compare it to a petscii chart to see why
I have done what I did. Note that most if not all petscii charts
will give you the C64 screen control characters as well. this is
not the way the C64 works at the screen memory level although much
of the ordering is the same. If you fail to see the corelation
then trust me on this one... the values below are correct.

The key to the table below is to remember that the "at" sign is at
subscript zero, followed by the lowercase 'a' to 'z' hence the
numbers 1-26 at the IBM position for these.

The next key to the table is to remember that beginning at position
32 the IBM values and commodore values are exactly the same right
through to 'Z' with the exception of the "at" sign as noted above.

The third key to the table is to remember that the high ascii
box drawing characters on the IBM (you can see these clustered
towards the end of the array below) map to common values on the
C64 whether you use the mixed-case or the upper-case character
set on the C64. You can also see the IBM pound (currency) sign
hanging-out by itself.

You will also note that if I had translated the non-english IBM
characters into my choice for mapping the english alphabet the
table would not be as clear to read nor for me to construct
since it is hand-built. Hence, I am adamantly lazy prefering
readability over busy-work.

If you want more detail study this a little closer. If you
want multi-lingual characters to map to english characters
add them yourself.

The C64 provides for custom fontsets to be used to solve that
problem which we will get to in a different sample program
than this one. When you use a custom fontset on the C64 even
your keys remap, so you'd better get that one right for the
country and keyboard you're programming for.

'nuff said.

*/
unsigned char ibm2petscii[256] = {
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
30, ' ',  31, ' ', ' ', ' ', ' ', ' ',
' ', '!',  34, '#', '$',  37, '&',  39,
'(', ')', '*', '+', ',', '-', '.',  47,
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ':', ';', '<', '=', '>', '?',
  0, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z',  27, ' ',  29, ' ', 111,
39,   1,   2,   3,   4,   5,   6,   7,
  8,   9,  10,  11,  12,  13,  14,  15,
16,  17,  18,  19,  20,  21,  22,  23,
24,  25,  26, '(',   93, ')', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ',  28, ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
102, 102, 102,  93, 115, 115, 115, 110,
110, 115,  93, 110, 125, 125, 125, 110,
109, 113, 114, 235,  64,  91, 235, 235,
109, 112, 113, 114, 235,  64,  91, 113,
113, 114, 114, 109, 109, 112, 112,  91,
91, 125, 112, 102,  98,  97, 118, 120,
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};

/* derivative background color count */
int bgcnt[16];

/* file and output names */
char c64array[128];
char c64screen[128];
char c64colors[128];
char arrayname[128];

char ErrorMessage[128];



Continued In Part 2 of 2

BillBuckels

bsv2x64 converts IBM BSaved text screens to Commodore 64 compatible BSaved text screens

The listing for this program is split into two parts. This is part two. The comments in the previous part are terribly important since they explain what we are really doing here. It should be noted that we are producing two types of files here in order to offer the C64 programmer the option of using these as a C character array or as a BLoadable text screen. BASIC 7 programmers can just as easily use BLoadable text screens in their programs as well.

Part 2 of 2


int bsv2x64(char *bsvname)
{
FILE *bsvfile;
    unsigned char *ptr, a, c, ch, fg, bg;
    unsigned idx, jdx, row, cnt, adder;

    unsigned char background,color;

    // PTX support added to ClipShop
    // also added here for the funnery of it
    int bPTX = FALSE;

    unsigned int byteoff=0,secondoff=1,packet;
    unsigned char byte,bytecount;
    int wordcount,target;


    /* use pessimistic approach for error */
    sprintf(ErrorMessage,"Can't open %s",bsvname);
    if((bsvfile=fopen(bsvname,"rb"))==NULL)return FAILURE;
    sprintf(ErrorMessage,"%s is an unrecognized format.",bsvname);

    /* be optimistic that file is supported */
    strcpy(arrayname, bsvname);
    jdx = 999;
    for (idx = 0; arrayname[idx] != 0; idx++) {
   c= tolower(arrayname[idx]);
   arrayname[idx] = c;
   if (c=='.')jdx = idx;
}
if (jdx != 999)arrayname[jdx] = 0;

    strcpy(c64array,arrayname);
    strcpy(c64screen,arrayname);
    strcpy(c64colors,arrayname);

    strcat(c64array,".h");
    strcat(c64screen,".bxd");      /* screen data */
    strcat(c64colors,".bxc");      /* screen colors */

    fread(ptxbuffer,7,1,bsvfile);
    for(idx=0;idx<5;idx++)
    {
        if(ptxbuffer[idx]!=BSV_header[idx])
        {

          rewind(bsvfile);
          fread(ptxbuffer,128,1,bsvfile);
          if (ptxbuffer[0]==0 && ptxbuffer[1]==3 &&
              ptxbuffer[2]==1 && ptxbuffer[3]==16) {
            bPTX = TRUE;
            break;
          }

          fclose(bsvfile);
      return FAILURE;
        }
    }

    /* support for PTX files
       these use the ZSoft PCX run length encoding
       and encode the characters first and the attributes
       second which provides for good compression
       on most text screens */
    if (bPTX == TRUE) {
      target = fread(ptxbuffer,1,4000,bsvfile);
      wordcount=0;
      do{ bytecount=1;  /* start with a seed count */
          byte=ptxbuffer[wordcount];
          wordcount++;
          /* check to see if its raw */
           /* if its not, run encoded */
          if(0xC0 == (0xC0 &byte)){

            bytecount= 0x3f &byte;
            byte=ptxbuffer[wordcount];
            wordcount++;
          }
          for(packet=0;packet<bytecount;packet++){
            if(byteoff<4000){
              bsvbuffer[byteoff]=byte;
              byteoff+=2;
            }
            else{
              if (secondoff<4000) {
                bsvbuffer[secondoff]=byte;
                secondoff+=2;
              }
            }
          }

        }while(wordcount<target);
    }
    else {
      fread((char *)&bsvbuffer[0],4000,1,bsvfile);
    }
    fclose(bsvfile);


strcpy(ErrorMessage,"Unable to open output file(s).");

    /* remember to rename these to lowercase
       if using c1541 to create disk images.
       if we had compiled this as a 32 bit application
       XP would have done that for us since I use lowercase
       output filenames. */
fp  = fopen(c64array,"w");
fp2 = fopen(c64screen,"wb");
fp3 = fopen(c64colors,"wb");

if (NULL == fp || NULL == fp2 || NULL == fp3) {
if(NULL != fp)fclose(fp);
if(NULL != fp2)fclose(fp2);
if(NULL != fp3)fclose(fp3);
return FAILURE;
}

    sprintf(ErrorMessage, "Output files %s[.h, .bxd, .bxc] created!",
             arrayname); /* good enough */

    /* set count to zero */
    for (idx = 0; idx < 16; idx++)bgcnt[idx] = 0;

    /* loop 25 rows - one for each character line in the text screen */
    /* first we do a background color prevalence test */
    /* generally what we want is a screen that has been prepared
       with primarily a black background */
    for(row=0;row<25;row++)
    {

        /* offset 80 - columns each row */
        ptr = (unsigned char *)&bsvbuffer[row*160];
        for(jdx=0;jdx<40;jdx++)
        {
            c=*ptr++;                 /* character */
            a=*ptr++;                 /* attribute pair */
            /* fg = (a&0x0f);*/
            bg = (a>>4);
            bgcnt[bg]+=1;
    }
}

     /* we need to establish a global background */
     /* the test below will determine the most prevalent */
     /* background in the source image and use it */
cnt = bgcnt[0];
background = 0;

for (idx = 1; idx < 16; idx++) {
if (bgcnt[idx] > cnt) {
         background = idx;
         cnt = bgcnt[idx];
}
}

fprintf(fp,"/* character array created from IBM text screen %s */\n", bsvname);
fprintf(fp,"/* array structure is C64 screen value, C64  color value */\n");
fprintf(fp,"char %s[2000] = {\n",arrayname);

/* load screen to default address of 1024 */
/* screen datafile size is 1000 bytes */
/* screen colorfile size is 1000 bytes */

/* C64 bsaved headers with load address */
/* you should be able to bload these in basic 7
    on a c128 although I haven't tried it.
    basic 2 doesn't have a bload and you will need
    to test these from the command line using the
    load binary command on a c64.
    in aztec C we have the bload command available
    (I have written a system level load but not run)
    or we can just read the thing from disk, or embed
    it as an array. Aztec C Rules!

*/

fputc(0,fp2);
fputc(4,fp2); /* 0x400 */

  fputc(0,fp3);
fputc(0xd8,fp3); /* 0xd800 */

cnt = 0;
     for(row=0;row<25;row++)
     {

        /* offset 80 - columns each row */
        /* but we will only use 40 of them */
        ptr = (unsigned char *)&bsvbuffer[row*160];
        for(jdx=0;jdx<40;jdx++)
        {
            c=*ptr++;                 /* character */
            a=*ptr++;                 /* attribute pair */

            fg = (a&0x0f);
            bg = (a>>4);

            adder = 0;
            /* if the foreground matches the global background
               swap-in the color and reverse the character.
               this will give us the proper value for the
               the ibm color that is being used for the real background
               color.. for example if the global background is black
               and black text is printed on a CYAN background...
               otherwise plot the text color on the global background */
            if (fg == background) {
    adder = 128; /* reverse character */
    fg = bg;
}

color = Vga2C64[fg];
ch = ibm2petscii[c] + adder;

fputc(ch, fp2);       /* screen */
fputc(color,fp3);     /* color */

fprintf(fp," %3d, %3d", ch, color);
cnt += 1;

if (cnt == 8) {
   /* newline every 8 pairs */
   /* terminate the array properly */
   if (row == 24 && jdx == 39) fprintf(fp,"};\n");
   else fprintf(fp,",\n");
   cnt = 0;
}
else {
   fprintf(fp,",");
}


    }
  }


    fclose(fp);
    fclose(fp2);
    fclose(fp3);
    return SUCCESS;
}


void main(int argc, char *argv[])
{

   int xfile = 2;

   if(argc!=2)
   {
puts("Usage is \"bsv2x64 my.bsv\"");
    puts("BSV or PTX filename required...");
   }
   else {
    if ((xfile = bsv2x64(argv[1]))!= SUCCESS)
        printf("OOPS! %s\n",ErrorMessage);
        else
            puts(ErrorMessage);
   }
   exit(xfile);

}



http://www.clipshop.ca/Aztec/index.htm#commodore

BillBuckels

The Library Routines in Aztec C that Make It All Happen



My Aztec64 distribution for writing C language programs from the comfort of my Windows machine to run on a C64 includes a number of tools and indeed code examples that are neither limited to this environment nor are they limited to the C programming language.

Here's some of the library functionality revealed from my distribution for writing text with colors to the screen and related functionality with the sincere wish that this may prove helpful to those seeking the wisdom of the ages.

Before reading the code below you will want to review my example loader program (btest.c) and the code for the bsv2x64 utility. Better yet just download the compiler package and unzip it and run the examples in the Vice emulator or whatever you have handy.

Step 1 - First One Needs to Layout a Screen

After laying-out a screen, it can be bloaded from disk or included as a character array in a header. On something as simple as a text screen I have not bothered with run-length encoding for this go around. I certainly do on bitmapped graphics. 


#include <poke.h>

  /* walk through character, attribute pairs */
   /* and place them directly in the screen and color memory */
   /* keep in mind that I have stayed in HIRES text mode on all of this */
   /* this is because I want the mixed case characters and the box drawing characters */
   /* for my IBM screen conversions scheme. */

   /* I have built my library functions based on this common ground. */
   /* The foreground text color is reversible with a single background color. */


memscr(txtscr)
char *txtscr;
{
int idx, jdx = 0;

    for (idx = 0; idx < 2000; idx ++) {

       txtaddr[jdx] = txtscr[idx];
       idx ++;
       coladdr[jdx] = txtscr[idx];
       jdx++;

    }
}



Step 2 - At the core of writing colored text is an outtext function.

No programming environment is complete without one. This is not console I/O. This is direct to screen memory manipulation by the way. When you do your screen layouts, you need to note your row and column coordinates, whether you write in BASIC or C. This probably goes without saying but consider it said.


/* Copyright (C) Bill Buckels 2008 */

#include <poke.h>

/* ascii to petscii screencode table */
char _a2p[256] = {
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
30, ' ',  31, ' ', ' ', ' ', ' ', ' ',
' ', '!',  34, '#', '$',  37, '&',  39,
'(', ')', '*', '+', ',', '-', '.',  47,
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ':', ';', '<', '=', '>', '?',
  0, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z',  27, ' ',  29, ' ', 111,
39,   1,   2,   3,   4,   5,   6,   7,
  8,   9,  10,  11,  12,  13,  14,  15,
16,  17,  18,  19,  20,  21,  22,  23,
24,  25,  26, '(',   93, ')', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ',  28, ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
102, 102, 102,  93, 115, 115, 115, 110,
110, 115,  93, 110, 125, 125, 125, 110,
109, 113, 114, 235,  64,  91, 235, 235,
109, 112, 113, 114, 235,  64,  91, 113,
113, 114, 114, 109, 109, 112, 112,  91,
91, 125, 112, 102,  98,  97, 118, 120,
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};

a2p(idx)
int idx;
{
if (idx < 0 || idx > 255)return 0;
return _a2p[idx];
}


/* output text direct to screen memory */
/* options are normal or reverse video,
   use current color or set new color */
outtext(str,row,col,attr,rev)
char *str;
int row, col,attr,rev;
{
int idx, ch, b;

row = (row * 40) + col;

for (idx = 0; str[idx] != 0; idx++) {

   ch = str[idx];
   b = _a2p[ch];

   if (rev!=0)b=b+128;
   txtaddr[row] = b;

   if (attr!=-1) {
   coladdr[row] = attr;
   }
   row++;
}
}



Step 3 - When the user presses an arrow key, the text must reverse.

Or it can change to some other color of course. The point is that reversing a selected row then reversing it back again is just the way we usually do it and this (like Aztec C) has worked pretty well for a long long time.


/* Copyright (C) Bill Buckels 2008 */

#include <poke.h>

revtext(row,col,len,rev)
int row, col,len,rev;
{
/* reverse characters at row, col */
int idx, ch;

row = (row * 40) + col;

for (idx = 0; idx < len; idx++) {

   ch = txtaddr[row];
   if (rev != 0) {
   if (ch < 128) txtaddr[row] = ch+128;
   }
   else {
   if (ch > 127) txtaddr[row] = ch-128;

   }
   row++;
}
}


Step 4 - You can also change text colors without changing the text.

Sometimes you will want to use a different method of displaying a selected chunk of text, or you may want to store color schemes as user preferences or whatever the case may be. The point here is that you can change the text color without changing the text. You probably knew this anyway from doing graphics palette changes in vram and cram but here it is again.


/* Copyright (C) Bill Buckels 2008 */

#include <poke.h>

attext(row,col,len,attr)
int row, col,len,attr;
{
/* change color at row,col */
int idx;

row = (row * 40) + col;

for (idx = 0; idx < len; idx++) {
   coladdr[row] = attr;
   row++;
}
}


Download a Copy Today

There is lots more to this included with Aztec64. It's a complete environment and actually comes with tools and you can really write programs with it without playing around and piecing together confusing puzzles that try and make everything look like a Unix box.

So forget that noise and follow the link below:

http://www.clipshop.ca/Aztec/index.htm#commodore