Hi there,
It looks like it's not possible to declare a pointer to char and initialise it to the video memory, e.g.
type VideoMemory: ^char;
var VideoMemory := 0x80000;
Excuse the syntax if its wrong, I'm new to Pascal. :-)
I'd like to know if it's not possible to get a pointer to the video memory region on PCs will I need to modify the compiler to allow it? Or would it be easier to just write a helper routine in C or assembler and link to it instead? Also what is the calling convention used and what does the procedure activation record look like?
Is it fairly easy to use an alternative standalone runtime library with GNU Pascal? I'd like to use GCC's -fstandalone and -nostdinc -nostdlib (IIRC) options to link to my own standalone runtime so I can use Pascal for low level system programming.
Thanks very much. James
[ Charset ISO-8859-1 unsupported, converting... ]
Hi there,
It looks like it's not possible to declare a pointer to char and initialise it to the video memory, e.g.
type VideoMemory: ^char;
var VideoMemory := 0x80000;
Excuse the syntax if its wrong, I'm new to Pascal. :-)
The following shows how to store a character at address 0x80000:
program VideoMemory; type VideoMemory = ^char;
var VideoMemoryVar : VideoMemory value VideoMemory($80000); begin VideoMemoryVar^ := 'a'; end .
Note that it depends on your OS what will be at the address 0x80000. If you try to access video memory after entering protected mode, but before you initialize memory management your OS will crash.
Also variables and pointer types used to access hardware should be marked `volatile', but I just noticed that currently GPC does not allow this...
I'd like to know if it's not possible to get a pointer to the video memory region on PCs will I need to modify the compiler to allow it? Or would it be easier to just write a helper routine in C or assembler and link to it instead? Also what is the calling convention used and what does the procedure activation record look like?
You can use inline asm -- typically things which are impossible to do in Pascal (or another HLL) reduce to a small number of instructions.
In general GPC uses the same calling convention as C. However, Pascal has much more possibilities for parameter passing then C (variable parameters, conformal arrays) and extra types. Also, GPC adds some extensions to standard Pascal. Things which are not present in C are mapped to C-like constructs -- for example variable parameters are implemented by passing pointers (addreses of the parameters).
Is it fairly easy to use an alternative standalone runtime library with GNU Pascal? I'd like to use GCC's -fstandalone and -nostdinc -nostdlib (IIRC) options to link to my own standalone runtime so I can use Pascal for low level system programming.
It is fairly easy to link-in alternative runtime library (or no runtime library at all), just use gcc as a linker. OTOH GPC assumes presence of runtime support and generates calls to support routines when needed. So you have to provide support routines for all constructs that you use. As first approximation operations on strings, sets and files and memory (de)allocation are implemented by runtime calls.
Note that most of GPC runtime is written in Pascal -- if you avoid some high-level constructs you can use no runtime at all.
Waldek Hebisch wrote:
Note that it depends on your OS what will be at the address 0x80000. If you try to access video memory after entering protected mode, but before you initialize memory management your OS will crash.
I think I will just leave out the first 1MB altogether and consider it off-limits. Then I can safely use the video buffer there, identity mapped, as the buffer for kprintf() or KWrite/KWriteLn as the case would be in Pascal.
Also variables and pointer types used to access hardware should be marked `volatile', but I just noticed that currently GPC does not allow this...
So perhaps I will have to compile without any optimisations so that no optimisations are performed that might mess things up.
In general GPC uses the same calling convention as C. However, Pascal has much more possibilities for parameter passing then C (variable parameters, conformal arrays) and extra types. Also, GPC adds some extensions to standard Pascal. Things which are not present in C are mapped to C-like constructs -- for example variable parameters are implemented by passing pointers (addreses of the parameters).
That's good. So to implement a printf-like function I am not looking at pass by value, I just need to remember I am dealing with pass by reference in all cases for varargs functions.
It is fairly easy to link-in alternative runtime library (or no runtime library at all), just use gcc as a linker. OTOH GPC assumes presence of runtime support and generates calls to support routines when needed. So you have to provide support routines for all constructs that you use. As first approximation operations on strings, sets and files and memory (de)allocation are implemented by runtime calls.
Thanks very much, that's been very useful information.
I will implement my own string functions, memory allocation, file handling and basic I/O and leave out the rest, being careful not to use it. I will probably not use sets or anything like that, or any object orientation. The closest I will get is using the C equivalent of struct, i.e. the record type.
Thanks, :) JD
James Buchanan wrote:
Waldek Hebisch wrote:
In general GPC uses the same calling convention as C. However, Pascal has much more possibilities for parameter passing then C (variable parameters, conformal arrays) and extra types. Also, GPC adds some extensions to standard Pascal. Things which are not present in C are mapped to C-like constructs -- for example variable parameters are implemented by passing pointers (addreses of the parameters).
That's good. So to implement a printf-like function I am not looking at pass by value, I just need to remember I am dealing with pass by reference in all cases for varargs functions.
Variable parameters (Pascal term) are quite different than varargs (C term). For compatibility with C GPC supports calling varargs functions. GPC does not support writing varargs functions (you can write a trivial one, but there is no way to get the parameters). Note that Writeln is _not_ a varargs function. Writeln is converted by the compiler into calls for separate arguments -- no user defined function can behave the same as Writeln.
Waldek Hebisch wrote:
Variable parameters (Pascal term) are quite different than varargs (C term). For compatibility with C GPC supports calling varargs functions. GPC does not support writing varargs functions (you can write a trivial one, but there is no way to get the parameters). Note that Writeln is _not_ a varargs function. Writeln is converted by the compiler into calls for separate arguments -- no user defined function can behave the same as Writeln.
Oh well, it's not as if it's absolutely essential. It's not a great hassle to have to break up the output into separate calls. Less than elegant, but not too bad. Then again I could call a C function that does it, so the I/O routines are written in C rather than Pascal. I'll try both and then think on it before putting anything in.
It would certainly be nice to have a Pascal-like language especially for systems programming. No thousand page specs that nobody understands or the compiler being tied down to any particular platform or making use of a runtime library that's a major job to port to a different system. Just a Pascal that's more like C, with the ability to use Pascal extensions whether that is object orientation or whatever. A nice middle ground between C and C++ (almost impossible for kernel level work).
Thanks again, JD
James Buchanan wrote:
Waldek Hebisch wrote:
Variable parameters (Pascal term) are quite different than varargs (C term). For compatibility with C GPC supports calling varargs functions. GPC does not support writing varargs functions (you can write a trivial one, but there is no way to get the parameters). Note that Writeln is _not_ a varargs function. Writeln is converted by the compiler into calls for separate arguments -- no user defined function can behave the same as Writeln.
Oh well, it's not as if it's absolutely essential. It's not a great hassle to have to break up the output into separate calls. Less than elegant, but not too bad.
In Pascal you might prefer not to rewrite the "print"/"write" function (which is common practice in C, such as "printk"), but to use the existing Write[Ln] and redirect its output. This way, you leave the breaking up of the output and the formatting ("i : 42" etc.) to the compiler as usual, and basically only need to provide routines to output a raw sequence of characters (cf. roughly snprintf() / write() in C).
For this purpose, GPC supports "text file device drivers" (look for "AssignTFDD" in gpc.pas). Of course, you'll need to use some parts of the GPC RTS (or equivalent subsitutes) for it to work.
Then you can assign a "Text" file to your output routine and do a normal "WriteLn (MyFile, whatever)". In fact you can even assign "Output" and do just "WriteLn (whatever)", if you don't need "Output" otherwise.
Then again I could call a C function that does it, so the I/O routines are written in C rather than Pascal. I'll try both and then think on it before putting anything in.
Since GPC allows calling varargs, that's an option. Just be careful of integer sizes etc. (e.g., integer expressions may be of type LongInt unexpectedly).
Frank
Waldek Hebisch wrote:
[ Charset ISO-8859-1 unsupported, converting... ]
Hi there,
It looks like it's not possible to declare a pointer to char and initialise it to the video memory, e.g.
type VideoMemory: ^char;
var VideoMemory := 0x80000;
Excuse the syntax if its wrong, I'm new to Pascal. :-)
The following shows how to store a character at address 0x80000:
program VideoMemory; type VideoMemory = ^char;
var VideoMemoryVar : VideoMemory value VideoMemory($80000); begin VideoMemoryVar^ := 'a'; end .
Note that it depends on your OS what will be at the address 0x80000. If you try to access video memory after entering protected mode, but before you initialize memory management your OS will crash.
Also variables and pointer types used to access hardware should be marked `volatile', but I just noticed that currently GPC does not allow this...
It does, but as an "attribute" (in order to reduce syntax pollution for a very rarely used feature).
program VideoMemory; type VolatileChar = char attribute (volatile); VideoMemory = ^VolatileChar;
procedure p; var VideoMemoryVar : VideoMemory value VideoMemory($80000); c: Char; begin c := VideoMemoryVar^; c := VideoMemoryVar^; c := VideoMemoryVar^; c := VideoMemoryVar^; c := VideoMemoryVar^; c := VideoMemoryVar^; c := VideoMemoryVar^; c := VideoMemoryVar^; c := VideoMemoryVar^; end;
begin p end.
(The procedure body is there to look at the generated assmebler code and see the multiple accesses, which vanish without the attribute when compiling with optimization.)
Frank
Frank Heckenbach wrote:
Waldek Hebisch wrote:
Also variables and pointer types used to access hardware should be marked `volatile', but I just noticed that currently GPC does not allow this...
It does, but as an "attribute" (in order to reduce syntax pollution for a very rarely used feature).
program VideoMemory; type VolatileChar = char attribute (volatile); VideoMemory = ^VolatileChar;
<rest of the program snipped>
Hmm, when I compile this program I see:
vol.pas:3: warning: 'volatile' attribute directive ignored
also, looking at the gpc source I had impression that we should add proper handling of 'volatile' attribute.
Waldek Hebisch wrote:
Frank Heckenbach wrote:
It does, but as an "attribute" (in order to reduce syntax pollution for a very rarely used feature).
program VideoMemory; type VolatileChar = char attribute (volatile); VideoMemory = ^VolatileChar;
<rest of the program snipped>
Hmm, when I compile this program I see:
vol.pas:3: warning: 'volatile' attribute directive ignored
also, looking at the gpc source I had impression that we should add proper handling of 'volatile' attribute.
I see. I had made this change in my copy only.
Frank