goto not working? return(1) not working?

Post Reply
reifsnyderb
New member
Posts: 9
Joined: Tue May 07, 2024 2:59 pm

goto not working? return(1) not working?

Post by reifsnyderb »

I am trying to get this program to exit early. i.e. At line 121 after the //DEBUG CODE comment, to test it.

goto isn't working and is commented out.
exit() gives a screwy warning
return(0) isn't working

I've never seen these problems in a C compiler before. Any thoughts?

Code: Select all


/*	FORMAT.C */
/*	Written by Brian E. Reifsnyder */ 


/*  Usage:  FORMAT <drive letter> */


/*  
	Use Z88dk to compile.
	Compile with:  zcc +cpm format.c -create-app -mz80
	Output file as A.OUT
*/


#include <cpm.h>
//#include <stdio.h>

#define BIOS 0xFA00
#define CONOUT 0xFA0C
#define SELDSK 0xFA1B
#define SETTRK 0xFA1E
#define SETSEC 0xFA21
#define SETDMA 0xFA24
#define WRITE 0xFA2A

#define IOSTRUCTUREADDR 0xFF80
#define SVTMAXDISKADDR 0xFFA0

unsigned char *io = (unsigned char *)IOSTRUCTUREADDR;
unsigned char *io_disk = (unsigned char *)IOSTRUCTUREADDR+0x03;
unsigned char *io_track = (unsigned char *)IOSTRUCTUREADDR+0x04;
unsigned char *io_sector = (unsigned char *)IOSTRUCTUREADDR+0x06;
unsigned char *io_dma = (unsigned char *)IOSTRUCTUREADDR+0x08;

unsigned char *svt_max_disk = (unsigned char *)SVTMAXDISKADDR;


void printb_asm(unsigned char byte)
{
#asm
	ld hl,2
	add hl,sp              	; skip over return address on stack
	ld c,(hl)              	; c = byte
	call CONOUT
#endasm
}


//  Print via CP/M BIOS
//  strOutput must end with \n or the length will default to 80 characters.
//  \r is carriage return for a new line
unsigned int printb(const char * StrOutput)
{
	//unsigned char CharOutput[1];
	
	// Print the string
	unsigned int i = 0;
	while(i < 80)
	{
		if(StrOutput[i] == "\n") break;
		printb_asm(StrOutput[i]);
		i++;
	}
	
	return(0);
}


//  Write to disk
unsigned int writeb(unsigned char drive[1], unsigned char track[2], unsigned char sector[2], unsigned char * write_sector_buffer)
{
	unsigned int i;
	
	io_disk[0]=drive[0];
	
	io_track[0]=track[0];
	io_track[1]=track[1];
	
	io_sector[0]=sector[0];
	io_sector[1]=sector[1];
	
	io_dma = &write_sector_buffer[0];
	
#asm
	call WRITE
#endasm
	
	return(0);
}	


int main(int argc, char *argv[])
{
	unsigned char bPreviousDrive[1];
	unsigned char sector_buffer[128];

	//  Ensure valid input
	if(argc !=2)
	{
		//  Exit if number of arguments is wrong.
		printb("Usage:  format <drive letter>\r\r");
		return (1);
		//exit(1);
		//goto end_program;
	}

	if(argv[1][0] >= 0x61) argv[1] [0] = argv[1] [0] - 0x20;		// Assuming lower case characters, convert lower case to upper case
	
	argv[1][0] = argv[1][0] - 0x61;		// convert to zero-based number

	if(argv[1][0] > svt_max_disk[0])
	{
		// Exit if disk number is invalid.
		printb("Invalid drive letter.\r\r");
		return(1);
		//goto end_program;
		//exit(1);
	}


//  DEBUG CODE
printb("DEBUG AB\r\n");
return(0);

//printb("DEBUG END 123\r");
//goto end_program;
//exit(2);

	//  Store previous drive letter
	bPreviousDrive[0] = io_disk[0];

	//  Set drive + 128 to instruct AtarioIO to format this disk.
	argv[1][0] = argv[1][0] + 128;	// Add bit 7 to the disk number

	//  Format the disk
	printb("Formatting disk\r");
	writeb(argv[1][0],0,0,sector_buffer[0]);		// Note:  sector_buffer is undefined....but not used to format.

	//  Load sector buffer with 0xe5
	argv[1][0] = argv[1][0] - 128;	// Remove bit 7 from the disk number
	
	unsigned int i = 0;
	while(i < 128)
	{
		sector_buffer[i] = 0xe5;
		i++;
	}

	//  Write directory sectors with 0xe5
	//  Directory sectors are located at Track/Sector 3/1 - 3/16
	printb("Writing directory\r\n");
	i=1;
	while(i<=16)
	{
		writeb(argv[1][0],3,i,sector_buffer[0]);	
		i++;
	}

	// Restore previous drive letter
	io_disk[0] = bPreviousDrive[0];
  
	printb("Format Complete\r\r");
	
	
//end_program:
	
	//return(0);
	//exit(0);
}


reifsnyderb
New member
Posts: 9
Joined: Tue May 07, 2024 2:59 pm

Re: goto not working? return(1) not working?

Post by reifsnyderb »

No ideas?

I started investigating the possibility that the while loop in printb() wasn't exiting when StrOutput encountered \n.

Some additional questions:
Is there a problem with break exiting from a while loop? (i.e. printb() function)
Is there a problem with the following statement:
if(StrOutput == "\n") break;

In other compilers, I don't recall having this sort of problem. I am thinking about trying another compiler.
reifsnyderb
New member
Posts: 9
Joined: Tue May 07, 2024 2:59 pm

Re: goto not working? return(1) not working?

Post by reifsnyderb »

I just realized my last post had an error. Since I can't edit or delete my last post, here it goes again....

No ideas?

I started investigating the possibility that the while loop in printb() wasn't exiting when StrOutput encountered \n.

Some additional questions:
Is there a problem with break exiting from a while loop? (i.e. printb() function)
Is there a problem with the following statement:

Code: Select all

if(StrOutput[i] == "\n") break;
In other compilers, I don't recall having this sort of problem. I am thinking about trying another compiler.


(Update, it wasn't an error, square brackets were used for StrOutput and the index (i) wasn't being displayed.)
stefano
Well known member
Posts: 2183
Joined: Mon Jul 16, 2007 7:39 pm

Re: goto not working? return(1) not working?

Post by stefano »

You obviously can't use C statements between #asm / #endasm delimiters.

The sample code you are trying to debug is rather extreme, I wonder if some of the issues are just consequences of the BDOS or BIOS interference.
reifsnyderb
New member
Posts: 9
Joined: Tue May 07, 2024 2:59 pm

Re: goto not working? return(1) not working?

Post by reifsnyderb »

stefano wrote: Thu May 30, 2024 2:08 pm You obviously can't use C statements between #asm / #endasm delimiters.

The sample code you are trying to debug is rather extreme, I wonder if some of the issues are just consequences of the BDOS or BIOS interference.
I don't have any C statements between #asm / #endasm.

While my printb() function goes directly to the BIOS, I suppose BDOS interference is possible on exit. I have no idea as how to determine if that is the issue, though. (That theory would also imply that the C program isn't properly exiting.)
User avatar
dom
Well known member
Posts: 2148
Joined: Sun Jul 15, 2007 10:01 pm

Re: goto not working? return(1) not working?

Post by dom »

Code: Select all

unsigned int printb(const char * StrOutput)
{
	//unsigned char CharOutput[1];
	
	// Print the string
	unsigned int i = 0;
	while(i < 80)
	{
		if(StrOutput[i] == "\n") break;
		printb_asm(StrOutput[i]);
		i++;
	}
	
	return(0);
}
You should probably check for a null character as part of the while condition or you're just going to print 80 characters of the rodata section. This probably gives the impression that the flow control isn't working and execution is just carrying on. No doubt it only prints part of a string at the end and this gives the impression that even more might be broken.
reifsnyderb
New member
Posts: 9
Joined: Tue May 07, 2024 2:59 pm

Re: goto not working? return(1) not working?

Post by reifsnyderb »

dom wrote: Thu May 30, 2024 2:21 pm

Code: Select all

unsigned int printb(const char * StrOutput)
{
	//unsigned char CharOutput[1];
	
	// Print the string
	unsigned int i = 0;
	while(i < 80)
	{
		if(StrOutput[i] == "\n") break;
		printb_asm(StrOutput[i]);
		i++;
	}
	
	return(0);
}
You should probably check for a null character as part of the while condition or you're just going to print 80 characters of the rodata section. This probably gives the impression that the flow control isn't working and execution is just carrying on. No doubt it only prints part of a string at the end and this gives the impression that even more might be broken.

It does appear that it could be printing out 80 characters and not breaking out of the while loop. I've tried using 0 in place of \n to see if I could get the while loop to exit. I've also tried to set i=100 so as to get the while loop to exit instead of using break.
User avatar
dom
Well known member
Posts: 2148
Joined: Sun Jul 15, 2007 10:01 pm

Re: goto not working? return(1) not working?

Post by dom »

I'd normally recommend to just use printf or puts which use the BDOS entry points, but this would work:

Code: Select all

        while(StrOutput[i] && i < 80)
You should also note that your lines actually don't end with \n but instead end with \r which is why the loop isn't breaking out when you oriiginally expected.
reifsnyderb
New member
Posts: 9
Joined: Tue May 07, 2024 2:59 pm

Re: goto not working? return(1) not working?

Post by reifsnyderb »

dom wrote: Thu May 30, 2024 2:34 pm I'd normally recommend to just use printf or puts which use the BDOS entry points, but this would work:

Code: Select all

        while(StrOutput[i] && i < 80)
You should also note that your lines actually don't end with \n but instead end with \r which is why the loop isn't breaking out when you oriiginally expected.
I would have used printf but I don't want a huge file. Right now, the compiled file is over 5k. The goal of this program is, literally, to send a couple bytes to the disk drive so it initiates a format then to fill the directory sectors with 0xe5. (Since this is running in an Atari 1090XL environment, the Atari computer is acting as an I/O device.) I figured I would write the program in C so as to save time.


I added the \n back in and it didn't make any difference. I also tried ending the line with a tilde (~).

Here's the new code....

Code: Select all

/*	FORMAT.C */
/*	Written by Brian E. Reifsnyder */ 


/*  Usage:  FORMAT <drive letter> */


/*  
	Use Z88dk to compile.
	Compile with:  zcc +cpm format.c -create-app -mz80
	Output file as A.OUT
*/


#include <cpm.h>
//#include <stdio.h>

#define BIOS 0xFA00
#define CONOUT 0xFA0C
#define SELDSK 0xFA1B
#define SETTRK 0xFA1E
#define SETSEC 0xFA21
#define SETDMA 0xFA24
#define WRITE 0xFA2A

#define IOSTRUCTUREADDR 0xFF80
#define SVTMAXDISKADDR 0xFFA0

unsigned char *io = (unsigned char *)IOSTRUCTUREADDR;
unsigned char *io_disk = (unsigned char *)IOSTRUCTUREADDR+0x03;
unsigned char *io_track = (unsigned char *)IOSTRUCTUREADDR+0x04;
unsigned char *io_sector = (unsigned char *)IOSTRUCTUREADDR+0x06;
unsigned char *io_dma = (unsigned char *)IOSTRUCTUREADDR+0x08;

unsigned char *svt_max_disk = (unsigned char *)SVTMAXDISKADDR;


void printb_asm(unsigned char byte)
{
#asm
	ld hl,2
	add hl,sp              	; skip over return address on stack
	ld c,(hl)              	; c = byte
	call CONOUT
#endasm
}


//  Print via CP/M BIOS
//  strOutput must end with \n or the length will default to 80 characters.
//  \r is carriage return for a new line
unsigned int printb(const char * StrOutput)
{
	//unsigned char CharOutput[1];
	
	// Print the string
	unsigned int i = 0;
	while(i < 80)
		//if(StrOutput[i] == "\n")
	{
		if(StrOutput[i]=="\n") break;
		if(StrOutput[i]=="~") break;
		
		printb_asm(StrOutput[i]);

//		if(StrOutput[i]=="\n")
//		{
//			i=100;
//		}
		i++;
	};

	return(0);
}


//  Write to disk
unsigned int writeb(unsigned char drive[1], unsigned char track[2], unsigned char sector[2], unsigned char * write_sector_buffer)
{
	unsigned int i;
	
	io_disk[0]=drive[0];
	
	io_track[0]=track[0];
	io_track[1]=track[1];
	
	io_sector[0]=sector[0];
	io_sector[1]=sector[1];
	
	io_dma = &write_sector_buffer[0];
	
#asm
	call WRITE
#endasm
	
	return(0);
}	


int main(int argc, char *argv[])
{
	unsigned char bPreviousDrive[1];
	unsigned char sector_buffer[128];

	//  Ensure valid input
	if(argc !=2)
	{
		//  Exit if number of arguments is wrong.
		printb("Usage:  format <drive letter>\r\r\n~");
		return (1);
		//exit(1);
		goto end_program;
	}

	if(argv[1][0] >= 0x61) argv[1] [0] = argv[1] [0] - 0x20;		// Assuming lower case characters, convert lower case to upper case
	
	argv[1][0] = argv[1][0] - 0x61;		// convert to zero-based number

	if(argv[1][0] > svt_max_disk[0])
	{
		// Exit if disk number is invalid.
		printb("Invalid drive letter.\r\r\n~");
		return(1);
		//goto end_program;
		//exit(1);
	}


//  DEBUG CODE
printb("DEBUG AB\r\n~");
return(0);

//printb("DEBUG END 123\r");
//goto end_program;
//exit(2);

	//  Store previous drive letter
	bPreviousDrive[0] = io_disk[0];

	//  Set drive + 128 to instruct AtarioIO to format this disk.
	argv[1][0] = argv[1][0] + 128;	// Add bit 7 to the disk number

	//  Format the disk
	printb("Formatting disk\r\n~");
	writeb(argv[1][0],0,0,sector_buffer[0]);		// Note:  sector_buffer is undefined....but not used to format.

	//  Load sector buffer with 0xe5
	argv[1][0] = argv[1][0] - 128;	// Remove bit 7 from the disk number
	
	unsigned int i = 0;
	while(i < 128)
	{
		sector_buffer[i] = 0xe5;
		i++;
	}

	//  Write directory sectors with 0xe5
	//  Directory sectors are located at Track/Sector 3/1 - 3/16
	printb("Writing directory\r\n");
	i=1;
	while(i<=16)
	{
		writeb(argv[1][0],3,i,sector_buffer[0]);	
		i++;
	}

	// Restore previous drive letter
	io_disk[0] = bPreviousDrive[0];
  
	printb("Format Complete\r\r~");
	
	
end_program:
	
	//return(0);
	//exit(0);
}



User avatar
dom
Well known member
Posts: 2148
Joined: Sun Jul 15, 2007 10:01 pm

Re: goto not working? return(1) not working?

Post by dom »

I don't know why this:

Code: Select all

		if(StrOutput[i] == "\n") break;
Didn't report a diagnostic, but this should be:

Code: Select all

		if(StrOutput[i] == '\n') break;
i.e. compare a character with a character not a character with a pointer.
reifsnyderb
New member
Posts: 9
Joined: Tue May 07, 2024 2:59 pm

Re: goto not working? return(1) not working?

Post by reifsnyderb »

dom wrote: Thu May 30, 2024 2:55 pm I don't know why this:

Code: Select all

		if(StrOutput[i] == "\n") break;
Didn't report a diagnostic, but this should be:

Code: Select all

		if(StrOutput[i] == '\n') break;
i.e. compare a character with a character not a character with a pointer.

That was it! Thank you!

I guess it's been a long while since I did any serious C programming.
Post Reply