English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 09 December 2020, 21:50   #21
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
could you try
__aligned struct StandardPacket con_standard_packet;

a lot of DOS things need to be aligned on 4 byte boundaries cause of BCPL pointers.
alkis is offline  
Old 10 December 2020, 08:48   #22
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,214
Quote:
Originally Posted by tygre View Post
So I went for allocating a StandardPacket every iteration without explicitly freeing it... Could it be because this StandardPacket is "consumed" somehow by the Console?

No. The dos.library functions do nothing else than that: Put the packet on the stack. Of course, you need to make sure that you don't leave your function before you received the packet back from the handler.
Thomas Richter is offline  
Old 10 December 2020, 23:00   #23
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi Alkis and Thomas!

I don't know how to "align" the struct with VBCC, it doesn't recognise __aligned, would you know how?

Best!
tygre is offline  
Old 11 December 2020, 07:10   #24
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by tygre View Post
Hi Alkis and Thomas!

I don't know how to "align" the struct with VBCC, it doesn't recognise __aligned, would you know how?

Best!

guess you'd have to use a static variable


Code:
#pragma pack(push,4)
static struct StandardPacket con_standard_packet;
#pragma pack(pop)

which is ok if the function is not invoked parallel

PS: and maybe you can omit the memset then, since it's initial zeroed.
bebbo is offline  
Old 11 December 2020, 09:12   #25
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,214
In this particular case, alignment is not necessary. The CON-Handler is in C, and all pointers between the packet and the message are C-style pointers.
Thomas Richter is offline  
Old 11 December 2020, 09:46   #26
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Quote:
Originally Posted by tygre View Post
Hi Alkis and Thomas!

I don't know how to "align" the struct with VBCC, it doesn't recognise __aligned, would you know how?

Best!
This should do it

Code:
char foo[sizeof(struct StandardPacket)+4];    // 68 + 4 = 72 bytes
struct StandardPacket  *_con_standard_packet = (struct StandardPacket  *)((ULONG) &foo[4] & ~3);
memset(_con_standard_packet, 0, sizeof(struct StandardPacket));

Well, after Thomas' feedback this is not necessary. I'll leave it here as a technique to align something with a compiler that doesn't support align.
alkis is offline  
Old 21 December 2020, 21:48   #27
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi all!

I'm still "stuck": my code works but from your comments, I'm not sure that it's doing what it should... Any memset or free of the struct StandardPacket * still causes a crash

You can see my current code here, am I missing something "obvious"?

Cheers!
tygre is offline  
Old 22 December 2020, 13:32   #28
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by tygre View Post
Hi all!

I'm still "stuck": my code works but from your comments, I'm not sure that it's doing what it should... Any memset or free of the struct StandardPacket * still causes a crash

You can see my current code here, am I missing something "obvious"?

Cheers!

this looks wrong:
Code:
do
        {
if(GetMsg(_con_reply_port))
            {
// Nothing to do
            }
else
            {
console_signal   = 1L << _con_reply_port->mp_SigBit;
received_signals = Wait(console_signal   |
SIGBREAKF_CTRL_C |
controls_signal_playing_stopped());
break;
            }
        }
while(TRUE);



consider the first GetMsg() returns NULL, then it waits for a signal and exits the loop without getting the message (if any).
So freeing/clearing the message will overwrite the node values of the still linked message.


Thus if a CTRL_C comes first you face the problem of having an unanswered message.


Maybe you can work around by using ACTION_WAIT_CHAR with a reasonable timeout.






bebbo is offline  
Old 01 February 2021, 15:13   #29
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hey!

Thank you all for your advice!
Finally, I got my code to work as expected, with a stack-allocated (and reused) StandardPacket and a reply port that can be safely deleted! Also, it fixes the problem found by Bebbo

Grabbing the Console

Code:
static int _grab_console(void)
{
	if((_con_file = Open("*", MODE_OLDFILE)) == 0)
	{
		log_print_error("_grab_console(), could not open Consolet\n");
		goto _RETURN_ERROR;
	}

	if((_con_file_handle = BADDR(_con_file))->fh_Type == NULL)
	{
		log_print_error("_grab_console(), could not get Console file handle\n");
		goto _RETURN_ERROR;
	}
	_enable_RAW_mode(TRUE);

	_con_message_port = (struct MsgPort *)_con_file_handle->fh_Type;

	if((_con_reply_port = CreatePort(NULL, 0)) == NULL)
	{
		log_print_error( GetString( MSG_CONTROLSCLI_CONTROLSCLICOULDNOTCREATEMESSAGEPORT ) );
		goto _RETURN_ERROR;
	}

	_open_result = 1;

	goto _RETURN_OK;
	_RETURN_OK:
		return RETURN_OK;

	goto _RETURN_ERROR;
	_RETURN_ERROR:
		return RETURN_ERROR;
}
Waiting for a char or CTRL+C or some other signals

Code:
static char _get_char(void)
{
	struct StandardPacket  con_standard_packet = { 0 };
	char		       received_char       = '\0';
	ULONG                  console_signal      = 0L;
	ULONG                  received_signals    = 0L;
	struct Message        *message             = NULL;
	struct InputEvent     *input_event         = NULL;

	while(TRUE)
	{
		received_char = '\0';
		
		memset(&con_standard_packet, 0, sizeof(struct StandardPacket));
		con_standard_packet.sp_Msg.mn_Node.ln_Name = (char *)&con_standard_packet.sp_Pkt;
		con_standard_packet.sp_Pkt.dp_Link         = &con_standard_packet.sp_Msg;
		con_standard_packet.sp_Pkt.dp_Port         = _con_reply_port;
		con_standard_packet.sp_Pkt.dp_Type         = ACTION_READ;
		con_standard_packet.sp_Pkt.dp_Arg1         = _con_file_handle->fh_Arg1;
		con_standard_packet.sp_Pkt.dp_Arg2         = (LONG)&_con_answer;
		con_standard_packet.sp_Pkt.dp_Arg3         = (LONG)ANSWER_LENGTH;
		PutMsg(_con_message_port, &con_standard_packet.sp_Msg);

		console_signal   = 1L << _con_reply_port->mp_SigBit;
		received_signals = Wait(console_signal   |
								SIGBREAKF_CTRL_C |
								controls_signal_playing_stopped());

		if(received_signals & console_signal)
		{
			while(message = GetMsg(_con_reply_port))
			{
				ReplyMsg(message);
			}
			if(_convert_CSI_to_InputEvent((char *)&_con_answer[1], &input_event) == RETURN_OK)
			{
				if(input_event->ie_Class == IECLASS_RAWKEY)
				{
					received_char = _convert_InputEvent_to_ANSI(input_event);
				}
				else if(input_event->ie_Class = IECLASS_CLOSEWINDOW)
				{
					received_char = '0';
				}
				free(input_event);
			}
		}
		else if(received_signals & SIGBREAKF_CTRL_C)
		{
			received_char = '0';
		}
		else if(received_signals & controls_signal_playing_stopped())
		{
			controls_acknowledge_playing_stopped();
			received_char = '6';
		}

		// We stop listening only when we received an interesting char
		if(isprint(received_char) ||
		   received_char == '\n'  ||
		   received_char == '\r')
		{
			break;
		}
	}

	printf("%c", received_char);
	fflush(stdout);

	return received_char;
}
Releasing the Console

Code:
static void _release_console(void)
{
	_enable_RAW_mode(FALSE);

	// Any of these will cause Enforcer hits, memory corruption, Gurus...
	if(_con_reply_port)	     DeletePort(_con_reply_port);
	// if(_con_message_port)    ; // Nothing to do, depends on _con_file
	// if(_con_file_handle)	    ; // Nothing to do, depends on _con_file
	if(_con_file)		        Close(_con_file);

	_open_result = -1;
}
(The whole code is available in this Git repo.)

Cheers!
tygre is offline  
Old 31 December 2022, 00:09   #30
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi all!

I'm bringing this thread back from the dead because my code doesn't work anymore with AmigaOS v3.1.4.1 and, presumably, v3.2... I never noticed because I'm using v3.1

What happens is that Open() now fails:

Code:
	if((_con_file = Open("*", MODE_OLDFILE)) == 0)
	{
		log_print_error("_grab_console(), could not open Consolet\n");
		goto _RETURN_ERROR;
	}
Does the CLI/Shell works differently in v3.1.4 when compared to v3.1?

Thanks in advance!
tygre is offline  
Old 31 December 2022, 00:47   #31
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,214
Sorry, the CON:-Handler did not change in 3.1.4, and up to a minor bug fix, the console.device did not change either. "*" still opens the console, and the shell does not work differently.

So, I am not quite clear about the question. You can verify from the shell that "*" still works as expected:

Code:
echo "hi" >*
This also just opens "*". Thus, quite likely, something else is wrong.
Thomas Richter is offline  
Old 31 December 2022, 04:13   #32
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
It's what I thought too

But I don't know what else could be wrong: Open("*", MODE_OLDFILE) returns 0 instead of some handle and SnoopDOS reports a "Fail"

Code:
...
31    [13] AmiModRadio   OpenLib    locale.library                                                                                      Ver 38                    OK  
32    [13] AmiModRadio   OpenLib    intuition.library                                                                                   Ver 36                    OK  
33    [13] AmiModRadio   OpenLib    utility.library                                                                                     Ver 37                    OK  
34    [13] AmiModRadio   Lock       HD2:Programmation/C/VBCC/AmiModRadio/bin/vbcc-classic/debug/data/Players                            Read                      OK  
35    [13] AmiModRadio   OpenLib    rexxsyslib.library                                                                                  Ver 0                     OK  
36    [13] AmiModRadio   Lock       ENVARC:AmiModRadio                                                                                  Read                      OK  
37    [13] AmiModRadio   Lock       HD2:Programmation/C/VBCC/AmiModRadio/bin/vbcc-classic/debug/images/                                 Read                      Fail
38    [13] AmiModRadio   OpenLib    xadmaster.library                                                                                   Ver 11                    OK  
39    [13] AmiModRadio   OpenLib    keymap.library                                                                                      Ver 36                    OK  
40    [13] AmiModRadio   Open       *                                                                                                   Read                      Fail
41    [13] AmiModRadio   Lock       ENVARC:AmiModRadio                                                                                  Read                      OK
What else could be wrong with that line?

Thanks!
tygre is offline  
Old 31 December 2022, 12:23   #33
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,214
The only reason could be that the process does not have a console task. For example, if it is run from workbench, it would not.
Thomas Richter is offline  
Old 31 December 2022, 20:54   #34
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi Thomas!

But I'm sure that AmiModRadio is run from the CLI... If it helps, this problem happens with v3.1.4.1 and also seem to happen with AmigaOS v4.1 (not tested myself)

PS. I attached a screenshot of the Shell (v3.1.4.1), showing the problem...

Thanks in advance!
Attached Thumbnails
Click image for larger version

Name:	AMRandConsole.png
Views:	59
Size:	53.7 KB
ID:	77604  
tygre is offline  
Old 07 January 2023, 06:17   #35
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi!

I did some digging and already found one difference between what's happening in my code running in 3.1 and 3.2. I get the "answer" from the console in response to an event, with:

Code:
con_standard_packet.sp_Pkt.dp_Arg2         = (LONG)&_con_answer;
and decode it with:

Code:
_convert_CSI_to_InputEvent((char *)&_con_answer[1], &input_event)
In 3.1, the control sequence starts with 0x9B, followed by the class of the raw input event, for example 1 for a key or 11 for the close gadget, followed by a semi-colon, etc. I use &_con_answer[1] to "skip" over 0x9B and start decoding at the class. In 3.2, this same control sequence seems to "miss" the 0x9B so my skipping over "eats" the first char of the class, throwing off everything.

I must do something wrong to "miss" this 0x9B but what is it?
(I'm using printf("\33[1;11{"); to listen to raw keys and the close gadget.)

Thanks in advance!

Last edited by tygre; 07 January 2023 at 06:30. Reason: More details
tygre is offline  
Old 07 January 2023, 13:31   #36
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,214
Without complete source, it is hard to reproduce this. Just note that CSI is equivalent to ESC [, so you may want to check for both sequences.
Thomas Richter is offline  
Old 07 January 2023, 17:07   #37
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Thanks Thomas!

Actually, I was wrong: on AmigaOS 3.1 the CSI sequence seems to always start with a char with decimal value -101 (corresponding to 0x9b?) while on 3.2 some sequence do and others don't. Would that make sense?

If you wouldn't mind, the code is available on BitBucket: here I get the CSI sequence and there I process it.

Thank you in advance!

PS. And I also have this problem that, when I quit and release the console, on 3.1 everything gets back to normal while on 3.2 the console is "frozen": I cannot type anything and I must click the close gadget to close the window. Maybe something with the way I release the console?

(I already changed my code by moving _enable_RAW_mode(FALSE); inside the if(_con_file). I also fixed the if(input_event->ie_Class = IECLASS_CLOSEWINDOW), should have been == of course...)

Last edited by tygre; 07 January 2023 at 21:10. Reason: More details
tygre is offline  
Old 09 January 2023, 22:16   #38
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,214
You have a couple of construction problems here, let me go through them:

*) You seem to assume that you always get an entire CSI message, starting with the CSI. However, the console does not guarantee that. Thus, it could very well be that you received only parts of the message, and the rest of the message is delivered with the next ACTION_READ, or it could be that there is more data in the output buffer of the console, and you receive that other part of the message first.

Thus, you really need to parse the message character by character, and isolate the CSI control sequence from it, and re-fill your buffer once you run out of bytes.

*) You also re-use the same buffer with each ACTION_READ, but do you completely empty the previous buffer?

*) You do not seem to look at the size of the returned buffer. Thus, you do not know how many characters are in there.

Thus, you need to restructure your code here. There are two possibilities here. Either, you write your main loop around the CSI parser, such that the CSI parser reads characters from the console byte per byte (potentially from a buffer, refilling the buffer when it runs dry), and then performing actions as you get data.

Or you write your code around the buffer-receiver, and write the CSI parser as a state machine that updates its state from each byte that it fed into it from the outside, as soon as a new buffer of data arrives.

As said earlier, your main assumption here seems to be that the CSI sequences are somehow aligned to the ACTION_READs, but that's not given.
Thomas Richter is offline  
Old 10 January 2023, 02:22   #39
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi Thomas and thank you so much!

Quote:
Originally Posted by Thomas Richter View Post
As said earlier, your main assumption here seems to be that the CSI sequences are somehow aligned to the ACTION_READs, but that's not given.
I had no idea of all these "details" I'm going to rework my code one way or the other that you suggested!

Would you also see why my code release the console well on v3.1 but "freezes" the Shell on v3.2?

Best!
tygre is offline  
Old 10 January 2023, 05:38   #40
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,214
You should also disable the raw-key events again when leaving the program, or you cut off the con-handler from its input. It listens to the same console device that serves your program, and if raw events are enabled, cooked keyboard events are disabled.
Thomas Richter is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
NewsTek Episode 9 is now available for your listening pleasure. Pyromania Amiga scene 4 26 June 2010 16:42
Listening to Amiga music does this moriez Nostalgia & memories 4 02 April 2010 22:00
listening suggestions Marcuz request.Modules 48 06 August 2008 11:02
NewsTek Episode 2 is now availabe for your listening pleasure. Pyromania Amiga scene 0 21 April 2008 05:44
Amiga Round Table Podcast #17 is available for your listening pleasure! Pyromania Amiga scene 1 18 December 2007 21:22

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 14:55.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.10268 seconds with 16 queries