It has been many years since I seriously programmed in C so I needed to reacquaint myself with some of the language mechanics. I was particular concerned with ensuring I understood pointers, arrays, and passing these between functions. I started out with exploring pointer handling.
I created a program that created an integer, a char, and a char array, and pointers to each one. It then manipulates the char via the variable and the pointer, and prints the values to verify the values are changing as expected. For the integer, it just displays the value and the address. For the char array I just print the array then the array address using the address operator and without it. Then I have the program pass the char array to a function several times to manipulate a portion of it each time (inversing 5 to 10 characters – 5 chars, then 10, then 5, then 10), while the main calling routine prints the char array out to confirm the changes were as expected.
Here is my source:
// ------------------------------------------------------------
// Program: pointers.c
// Desc...: Pointer demonstration
// Author.: Wade Ripkowski
// Date...: 20220809
// Notes..: cl65 -v -O -t atari pointers.c -o pointers.xex
// ------------------------------------------------------------
// Pull in include files
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <atari.h>
// ------------------------------------------------------------
// Func...: void invstr(char *pcs, unsigned char bs)
// Desc...: Inverses bs chars of a string
// Param..: pcs = pointer to string to inverse
// bs = size (number) of chars in string to inverse
// ------------------------------------------------------------
void invstr(char *pcs, unsigned char bs)
{
unsigned char bL;
// Loop through number of requested chars
for (bL=0; bL<bs; bL++)
{
// Dereference, change char value by 128, increment pointer
*(pcs++) ^= 128;
}
}
// ------------------------------------------------------------
// Func...: void main(void)
// Desc...: Main routine
// ------------------------------------------------------------
void main(void)
{
// Declare int and set value
int i = 5;
// Declare char and char array
char c, ca[11];
// Declare char pointer and set to address of defined char
char *pc = &c;
// Setup screen
clrscr();
printf("-[CC65 Pointer Tests]-------------------");
// Show integer value and address of variable i
printf("\nINTEGER\n");
printf(" i (int): %d\n", i);
printf(" i address: %p\n", &i);
// Show char value and pointer value
printf("\nCHAR\n");
c = 65;
printf(" orig c (char): c=%d, *pc=%d\n", c, *pc);
// Change the char value, reshow values
c = 66;
printf(" mod c: c=%d, *pc=%d\n", c, *pc);
// Change the char value thru the pointer, reshow values
*pc = 67;
printf(" mod *pc: c=%d, *pc=%d\n", c, *pc);
// Show char array and address
printf("\nCHAR ARRAY\n");
strcpy(ca, "1234567890");
printf(" ca (array): %s\n", ca);
printf(" &ca address: %p\n", &ca);
printf(" ca address: %p : %s\n", ca, ca);
printf(" ca address+2: %p : %s\n", ca+2, ca+2);
// Manipulate string thru function
printf("\nFUNCTION MANIPULATION\n");
// Flip 1st 5 chars of string
// first half inverted
invstr(ca, 5);
printf(" ca inv 5: %s\n", ca);
// Flip all 10 chars of string
// first half now normal, second half now inverted
invstr(ca, 10);
printf(" ca inv 10: %s\n", ca);
// Flip 1st 5 chars of string again
// all 10 inverted now
invstr(ca, 5);
printf(" ca inv 5: %s\n", ca);
// Flip all 10 chars of string agian
// all 10 back to normal now
invstr(ca, 10);
printf(" ca inv 10: %s\n", ca);
// Wait for a keypress
while (! kbhit()) { };
// Exit
return;
}
I used this command to build it. I won’t repeat what each of the parameters are, as I explained that in the last post:
cl65 -v -O -t atarixl pointers.c -o pointers.xex
Output of the build process:
$ cl65 -v -t atarixl pointers.c -o pointers.xex
Opened include file '/usr/local/share/cc65/include/stdio.h'
Opened include file '/usr/local/share/cc65/include/stddef.h'
Opened include file '/usr/local/share/cc65/include/stdarg.h'
Opened include file '/usr/local/share/cc65/include/conio.h'
Opened include file '/usr/local/share/cc65/include/atari.h'
Opened include file '/usr/local/share/cc65/include/_gtia.h'
Opened include file '/usr/local/share/cc65/include/_pbi.h'
Opened include file '/usr/local/share/cc65/include/_pokey.h'
Opened include file '/usr/local/share/cc65/include/_pia.h'
Opened include file '/usr/local/share/cc65/include/_antic.h'
Opened include file '/usr/local/share/cc65/include/string.h'
Opened include file '/usr/local/share/cc65/include/stddef.h'
Opened include file '/usr/local/share/cc65/include/atari.h'
0 errors, 0 warnings
Opened output file 'pointers.s'
Wrote output to 'pointers.s'
Closed output file 'pointers.s'
Opened 'pointers.xex'...
Dumping 'HEADER'
Writing 'EXEHDR'
Dumping 'SYSCHKHDR'
Writing 'SYSCHKHDR'
Dumping 'SYSCHKCHNK'
Writing 'SYSCHK'
Dumping 'SYSCHKTRL'
Writing 'SYSCHKTRL'
Dumping 'SRPREPHDR'
Writing 'SRPREPHDR'
Dumping 'SRPREPCHNK'
Writing 'LOWBSS'
Writing 'SRPREP'
Writing 'SHADOW_RAM'
Writing 'SHADOW_RAM2'
Dumping 'SRPREPTRL'
Writing 'SRPREPTRL'
Dumping 'MAINHDR'
Writing 'MAINHDR'
Dumping 'MAIN'
Writing 'STARTUP'
Writing 'LOWCODE'
Writing 'ONCE'
Writing 'CODE'
Writing 'RODATA'
Writing 'DATA'
Writing 'BSS'
Dumping 'TRAILER'
Writing 'AUTOSTRT'
And, here is a screenshot of the program run:
