English Amiga Board


Go Back   English Amiga Board > Coders > Coders. System

 
 
Thread Tools
Old 10 October 2023, 10:02   #1
Mafi
Registered User
 
Join Date: Jul 2022
Location: Australia
Posts: 49
Kprintf serial output and Sashimi

Hello all,

I’m trying to use kprintf to output debugging details to the serial port. I have Sashimi running yet nothing is being intercepted. However, Patchwork output is, so I’m certain it’s something I’m doing wrong. I have CR/LF in my output string too. I’ve tried using kprintf from debug.lib; as well as writing two different implementations myself (one using serial.device and the other just banging the hw directly) - but nothing results in output. Any hints?

Cheers,
-Matt
Mafi is offline  
Old 10 October 2023, 11:15   #2
thomas
Registered User
 
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 7,024
This one works:

Code:
LVORawDoFmt	EQU	-522
LVORawPutChar	EQU	-516

	move.l	4.w,a6
	move.l	a6,sysbase

	lea	string,a0
	lea	putchproc,a2
	jsr	LVORawDoFmt(a6)

	moveq.l	#0,d0
	rts

putchproc:
	move.l	sysbase(pc),a6
	jsr	LVORawPutChar(a6)
	rts

sysbase:	dc.l	0

string:	dc.b	"Hello Sashimi!",$a,0
thomas is offline  
Old 10 October 2023, 11:33   #3
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Originally Posted by thomas View Post
This one works:

Code:
LVORawDoFmt	EQU	-522
LVORawPutChar	EQU	-516

	move.l	4.w,a6
	move.l	a6,sysbase

	lea	string,a0
	lea	putchproc,a2
	jsr	LVORawDoFmt(a6)

	moveq.l	#0,d0
	rts

putchproc:
	move.l	sysbase(pc),a6
	jsr	LVORawPutChar(a6)
	rts

sysbase:	dc.l	0

string:	dc.b	"Hello Sashimi!",$a,0
In case anybody wonders: exec.library/RawPutChar() will filter out any NUL byte which is part of the data stream. This is not normally an issue, but should your code depend upon being able to send NUL bytes, you may have to resort to different measures. Also, be aware that a line feed character (ASCII code 10) will always be translated into a carriage return character followed by a line feed character.

Tools such as Sashimi or its precursor Sushi will not perform any such translations, though. Only the exec.library/RawPutChar() does.
Olaf Barthel is offline  
Old 11 October 2023, 03:01   #4
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,300
Also note that RawDoFmt() is patched over by the locale.library once loaded, so you get some extra functonality from there as well, such as argument reordering. Whle in most cases this patch does only good, it may not be what you want in critical situations.
Thomas Richter is offline  
Old 11 October 2023, 04:17   #5
Mafi
Registered User
 
Join Date: Jul 2022
Location: Australia
Posts: 49
Quote:
Originally Posted by Thomas Richter View Post
Also note that RawDoFmt() is patched over by the locale.library once loaded, so you get some extra functonality from there as well, such as argument reordering. Whle in most cases this patch does only good, it may not be what you want in critical situations.
Thanks both! Is there a reason why RawPutChar is not in the assembler includes? It isn’t at least in the 3.2 NDK. I’ll give this a go later and see how it goes. Appreciate the replies.

-Matt
Mafi is offline  
Old 11 October 2023, 08:12   #6
thomas
Registered User
 
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 7,024
Quote:
Originally Posted by Olaf Barthel View Post
should your code depend upon being able to send NUL bytes, you may have to resort to different measures.
Which other measures to send debug output to the serial port are there so that Sushi and Sashimi are still able to intercept it? My understanding is that these programs hook into RawPutChar and thus this is the only way to get output to them.

Using RawDoFmt is just a convenient way to send a string through RawPutChar and get substitution/formatting options as add on. Otherwise you would have to write your own code which calls RawPutChar in a loop.
thomas is offline  
Old 11 October 2023, 09:52   #7
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Originally Posted by Thomas Richter View Post
Also note that RawDoFmt() is patched over by the locale.library once loaded, so you get some extra functonality from there as well, such as argument reordering. Whle in most cases this patch does only good, it may not be what you want in critical situations.
If you are using AmigaOS 3.2, then the locale.library RawDoFmt() patch will do its best to check quickly if argument reordering is called for and skip the necessary most monumental preparations which can only be compared to the construction of the Great Pyramid of Giza if this feature is not needed. It also uses a lot less stack space by default

Word to the wise: if your code uses kprintf(), etc. make sure that you have significantly more than 4K of stack space at hand.

Last edited by Olaf Barthel; 11 October 2023 at 10:02.
Olaf Barthel is offline  
Old 11 October 2023, 10:02   #8
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Originally Posted by Mafi View Post
Thanks both! Is there a reason why RawPutChar is not in the assembler includes?
Because the Commodore engineers wanted you to make use of the linker libraries which encapsulated everything you really needed to know, I suppose.

The RawPutChar() function also has two companion functions in the form of RawMayGetChar() and RawIOInit() which are undocumented. RawIOInit() will set up the serial port to use 9,600 bits/second and RawMayGetChar() will, as the name says, try to pick up any input from the serial port and return it (or just -1 if there's nothing to be picked up in the first place).

You are not missing much here, unless you intend to give the old-fashion null-modem cable a workout, debugging low level system code on actual vintage hardware like it's 1986
Olaf Barthel is offline  
Old 11 October 2023, 10:14   #9
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Originally Posted by thomas View Post
Which other measures to send debug output to the serial port are there so that Sushi and Sashimi are still able to intercept it? My understanding is that these programs hook into RawPutChar and thus this is the only way to get output to them.
Yes, there is is only RawPutChar().

However, CATS created a counterpart to the debug.lib, which was limited to output and input on the serial port, in the form of ddebug.lib.

Unlike the functions in debug.lib, ddebug.lib does not use any operating system functions but tickles the parallel port hardware instead.

Because you can't have both input and output on the built-in parallel port active at the same time, ddebug.lib is limited to output. ddebug.lib was handy for sending debug output straight to a device known as a "printer" back in the day. I'm not sure many people remember these things
Olaf Barthel is offline  
Old 11 October 2023, 12:45   #10
patrik
Registered User
 
patrik's Avatar
 
Join Date: Jan 2005
Location: Umeå
Age: 43
Posts: 930
Quote:
Originally Posted by Olaf Barthel View Post
Yes, there is is only RawPutChar().

However, CATS created a counterpart to the debug.lib, which was limited to output and input on the serial port, in the form of ddebug.lib.

Unlike the functions in debug.lib, ddebug.lib does not use any operating system functions but tickles the parallel port hardware instead.

Because you can't have both input and output on the built-in parallel port active at the same time, ddebug.lib is limited to output. ddebug.lib was handy for sending debug output straight to a device known as a "printer" back in the day. I'm not sure many people remember these things
I actually needed to use ddebug.lib just a couple of years ago, when I was unable to use the serial port for debug output, as I was doing a project that utilized the serial port.

However, when the computer was wired like that with the serial port unavailable for debug output, I found it highly inconvenient that:
1. Many debugging tools don't have support for parallel output
2. For other projects I was also working on, I had to change the code to output to parallel as the output functions kprintf, kputstr etc of debug.lib are called dprintf, dputstr in ddebug.lib.

Especially 2. might perhaps sound like an minor problem, but it is an unnecessary inconvenience and it got me thinking: why even have separate debug libraries and functions when you could just patch exec.library/RawPutChar(), like Sashimi does, but to instead output to the parallel port? This would also solve 1..

So created a tool/patch that does exactly that. It uses ddebug.lib for output, but then nothing else has to use ddebug.lib, so if you want your debug output to the serial port again, it is a simple as not loading it:
https://aminet.net/package/dev/debug/RawIO2Parallel

Btw, I don't use a printer, but a parallel to serial converter.
patrik is offline  
Old 11 October 2023, 14:20   #11
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,300
Quote:
Originally Posted by patrik View Post
1. Many debugging tools don't have support for parallel output
2. For other projects I was also working on, I had to change the code to output to parallel as the output functions kprintf, kputstr etc of debug.lib are called dprintf, dputstr in ddebug.lib.
There is no really good answer except "it has always been like that". Most debugging tools go acutally over RawPutChar, and it is relatively easy to replace this function, as you propose, with something that logs into whatever you prefer to log to, including parallel and the console.


Actually, if you enable in Os 3.2 the "debug log", it will do exactly that and log debug output into the RAM-Disk. As by-product of this boot option, it will also redirect any output from debugging tools to this very same file.
Thomas Richter is offline  
Old 11 October 2023, 19:23   #12
Bruce Abbott
Registered User
 
Bruce Abbott's Avatar
 
Join Date: Mar 2018
Location: Hastings, New Zealand
Posts: 2,708
Quote:
Originally Posted by Thomas Richter View Post
Also note that RawDoFmt() is patched over by the locale.library once loaded, so you get some extra functonality from there as well, such as argument reordering.
What do you mean by 'argument reordering', and what other 'functionality' does it add?
Bruce Abbott is offline  
Old 11 October 2023, 20:29   #13
patrik
Registered User
 
patrik's Avatar
 
Join Date: Jan 2005
Location: Umeå
Age: 43
Posts: 930
Quote:
Originally Posted by Bruce Abbott View Post
What do you mean by 'argument reordering', and what other 'functionality' does it add?
There is some example in the locale.library/FormatString() autodoc:
http://amigadev.elowar.com/read/ADCD.../node0457.html
patrik is offline  
Old 12 October 2023, 06:26   #14
Bruce Abbott
Registered User
 
Bruce Abbott's Avatar
 
Join Date: Mar 2018
Location: Hastings, New Zealand
Posts: 2,708
Quote:
Originally Posted by patrik View Post
There is some example in the locale.library/FormatString() autodoc:
http://amigadev.elowar.com/read/ADCD.../node0457.html
Thanks for that. So it adds '$' to specify the argument order, 'X' for lower case hex, and 'D' and 'U' for localized number formats.

If you stick to the documented RawDoFmt formats it should have no effect.

More disturbing is I found out that my code using RawDoFmt had a serious bug in it that was being masked by this patch. When I ran it without locale active, it crashed!

The documentation for RawDoFmt says:-
Code:
	PutChProc(Char,  PutChData);
		  D0-0:8 A3

		the procedure is called with a NULL Char at the end of
		the format string.

	PutChData - a value that is passed through to the PutChProc
		procedure.  This is untouched by RawDoFmt, and may be
		modified by the PutChProc.
What it doesn't say is that all registers other than D0 and A3 must be preserved!
Bruce Abbott is offline  
Old 12 October 2023, 09:50   #15
hooverphonique
ex. demoscener "Bigmama"
 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,635
Quote:
Originally Posted by Bruce Abbott View Post
all registers other than D0 and A3 must be preserved!
What does that mean? That calling RawDoFmt may scratch all other registers than D0 and A3?


Also, the documentation for PutChProc is wrong I think - D0 likely doesn't supply a 9 bit char
hooverphonique is offline  
Old 12 October 2023, 12:29   #16
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Originally Posted by Bruce Abbott View Post
Thanks for that. So it adds '$' to specify the argument order, 'X' for lower case hex, and 'D' and 'U' for localized number formats.

If you stick to the documented RawDoFmt formats it should have no effect.

More disturbing is I found out that my code using RawDoFmt had a serious bug in it that was being masked by this patch. When I ran it without locale active, it crashed!

The documentation for RawDoFmt says:-
Code:
	PutChProc(Char,  PutChData);
		  D0-0:8 A3

		the procedure is called with a NULL Char at the end of
		the format string.

	PutChData - a value that is passed through to the PutChProc
		procedure.  This is untouched by RawDoFmt, and may be
		modified by the PutChProc.
What it doesn't say is that all registers other than D0 and A3 must be preserved!
Thank you, I'll add a note to the Autodocs. Probably too late by some 37 years but every little bit helps.

I looked up the original implementation and it does not seem to have changed much post Kickstart 1.0 until 2.0 came around. PutChProc() is supposed to adhere to the scratch register specs, which means that register A3 should not be changed, but registers D0/D1/A0/A1 are not expected to retain their respective initial values when PutChProc() returns.

Last edited by Olaf Barthel; 12 October 2023 at 12:49.
Olaf Barthel is offline  
Old 12 October 2023, 16:00   #17
thomas
Registered User
 
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 7,024
A3 is owned by PutChProc. It can be changed and should be left at the value you expect to receive next time.

The documented default PutChProc is

move.b d0,(a3)+
rts
thomas is offline  
Old 12 October 2023, 16:19   #18
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Originally Posted by thomas View Post
A3 is owned by PutChProc. It can be changed and should be left at the value you expect to receive next time.

The documented default PutChProc is

move.b d0,(a3)+
rts
Yikes, me and my bad memory... I haven't used the PutChProc procedure in this way for more than 20 years now. Thank you! Autodocs are updated to mention that D2-D7/A2/A4-A6 should not be clobbered.

In addition to the register usage, I had already added a new "warning" section which covers the increased stack size requirements if the locale.library patch is active.

The patch reserves space for up to 128 parameters which might need to be reordered, plus some 200 characters for numbers with grouping characters/strings inserted. That accounts for some 850+ bytes of stack space which is bound to be filled with data even if you merely call it with an empty string as the format specification.

I generously rounded this up to a minimum of 1000 bytes of stack space you should have available to safely call RawDoFmt(). Also included in the warning is a caution that functions which indirectly invoke RawDoFmt(), such as dos.library/VPrintf, also expect to draw that much stack space.

RawDoFmt() is full of surprises
Olaf Barthel is offline  
Old 12 October 2023, 19:36   #19
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,300
So much that MuForce aka Enforcer does not use it to format its output for the reasons mentioned.
Thomas Richter is offline  
Old 13 October 2023, 14:10   #20
Bruce Abbott
Registered User
 
Bruce Abbott's Avatar
 
Join Date: Mar 2018
Location: Hastings, New Zealand
Posts: 2,708
Quote:
Originally Posted by Olaf Barthel View Post
The patch reserves space for up to 128 parameters which might need to be reordered, plus some 200 characters for numbers with grouping characters/strings inserted.
Wow, that's way more than I will ever need.

I might go back to using my own RawDoFmt code that I wrote 30 years ago to avoid calling the ROM function.
Bruce Abbott 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
Diagrom Serial Output garbled avinitlarge support.Hardware 6 29 December 2021 13:24
Two different serial numbers TCH support.Hardware 6 10 July 2021 19:00
Serial output in WinUAE 3.3 - how to? DarrenHD support.WinUAE 3 16 June 2016 21:41
PC Serial to Amiga Serial lesta_smsc support.Hardware 48 02 December 2015 10:14
Sending debug output to the serial port OS3.x NovaCoder Coders. C/C++ 0 18 February 2013 06:56

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 00:50.

Top

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