Sometimes I have to explain myself
-
Rick Cortese
- Posts: 17
- Joined: 28 Sep 2009
Sometimes I have to explain myself
I think I have been on both sides of cc65 i.e. giving credit where credit is due and lamenting the state of the art with respect to C programming.
I'm not bashing the cc65 crew as the would be inappropriate from a programming standpoint. They are very talented and well versed beyond my ability in both C and assembly language.
Recently someone on the mailing list asked about aligning fields for some quirks in the Atari hardware like display list location, character sets, et cetera and said they were short of space.
I replied something to the effect that you could chain programs on the Atari such that PROGA.EXE runs and terminates so you can do the memory reservations and fixed data locations then PROGB.EXE will be run automatically.
The procedure is pretty simple, menu driven DOS/DUP so you just hit 'C for COPY file and give it
PORGB.EXE,PROGA.EXE /A
The 'or you could do this' pointed me to the help file where you find
*******************************************************
Low code and high data example
Goal: Create an executable with 2 load chunks which doesn't use the memory area from $4000 to $7FFF. The CODE segment of the program should go below $4000 and the DATA and RODATA segments should go above $7FFF.
The main problem is that the EXE header generated by the cc65 runtime lib is wrong. It defines a single load chunk with the sizes/addresses of the LOWCODE, INIT, CODE, RODATA, and DATA segments (the whole user program).
The contents of the EXE header come from the EXEHDR segment, which is defined in crt0.s. This cannot be changed w/o modifying and recompiling the cc65 atari runtime lib. Therefore the original EXE header must be discarded. It will be replaced by a user created one.
The user needs to create a customized linker config file which adds new memory areas and segments to hold the new EXE header and the header data for the second load chunk. Also an assembly source file needs to be created which defines the contents of the new EXE header and the second load chunk header.
This is a modified cc65 Atari linker configuration file (split.cfg):
MEMORY {
ZP: start = $82, size = $7E, type = rw, define = yes;
HEADER: start = $0000, size = $6, file = %O; # first load chunk
RAMLO: start = $2E00, size = $1200, file = %O;
BANK: start = $4000, size = $4000, file = "";
SECHDR: start = $0000, size = $4, file = %O; # second load chunk
RAM: start = $8000, size = $3C20, file = %O; # $3C20: matches upper bound $BC1F
TRAILER: start = $0000, size = $0006, file = %O;
}
SEGMENTS {
EXEHDR: load = BANK, type = ro;
NEXEHDR: load = HEADER, type = ro; # first load chunk
LOWCODE: load = RAMLO, type = ro, define = yes, optional = yes;
INIT: load = RAMLO, type = ro, optional = yes;
CODE: load = RAMLO, type = ro, define = yes;
CHKHDR: load = SECHDR, type = ro; # second load chunk
RODATA: load = RAM, type = ro, define = yes;
DATA: load = RAM, type = rw, define = yes;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
AUTOSTRT: load = TRAILER, type = ro; # defines program entry point
}
FEATURES {
CONDES: segment = RODATA,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = RODATA,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
__STACKSIZE__ = $800; # 2K stack
__RESERVED_MEMORY__: value = $0, weak = yes;
}
A new memory area BANK was added which describes the reserved area. It gets loaded with the contents of the old EXEHDR segment. But the memory area isn't written to the output file. This way the contents of the EXEHDR segment get discarded.
The added NEXEHDR segment defines the correct EXE header. It puts only the CODE segment into load chunk #1 (RAMLO memory area).
The header for the second load chunk comes from the new CHKHDR segment. It puts the RODATA and DATA segments into load chunk #2 (RAM memory area).
The contents of the new NEXEHDR and CHKHDR segments come from this file (split.s):
.import __LOWCODE_LOAD__, __BSS_LOAD__, __CODE_SIZE__
.import __CODE_LOAD__, __DATA_LOAD__, __RODATA_LOAD__
.segment "NEXEHDR"
.word $FFFF ; EXE file magic number
; 1st load chunk
.word __LOWCODE_LOAD__
.word __CODE_LOAD__ + __CODE_SIZE__ - 1
.segment "CHKHDR"
; 2nd load chunk (contains with AUTOSTRT in fact a 3rd load chunk)
.word __RODATA_LOAD__
.word __BSS_LOAD__ - 1
Compile with
cl65 -t atari -C split.cfg -o prog.com prog.c split.s
Low data and high code example
Goal: Put RODATA and DATA into low memory and LOWCODE, INIT, CODE, BSS into high memory (split2.cfg):
MEMORY {
ZP: start = $82, size = $7E, type = rw, define = yes;
HEADER: start = $0000, size = $6, file = %O; # first load chunk
RAMLO: start = $2E00, size = $1200, file = %O;
BANK: start = $4000, size = $4000, file = "";
SECHDR: start = $0000, size = $4, file = %O; # second load chunk
RAM: start = $8000, size = $3C20, file = %O; # $3C20: matches upper bound $BC1F
TRAILER: start = $0000, size = $0006, file = %O;
}
SEGMENTS {
EXEHDR: load = BANK, type = ro; # discarded old EXE header
NEXEHDR: load = HEADER, type = ro; # first load chunk
RODATA: load = RAMLO, type = ro, define = yes;
DATA: load = RAMLO, type = rw, define = yes;
CHKHDR: load = SECHDR, type = ro; # second load chunk
LOWCODE: load = RAM, type = ro, define = yes, optional = yes;
INIT: load = RAM, type = ro, optional = yes;
CODE: load = RAM, type = ro, define = yes;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
AUTOSTRT: load = TRAILER, type = ro; # defines program entry point
}
FEATURES {
CONDES: segment = RODATA,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = RODATA,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
__STACKSIZE__ = $800; # 2K stack
__RESERVED_MEMORY__: value = $0, weak = yes;
}
New contents for NEXEHDR and CHKHDR are needed (split2.s):
.import __LOWCODE_LOAD__, __BSS_LOAD__, __DATA_SIZE__
.import __DATA_LOAD__, __RODATA_LOAD__
.segment "NEXEHDR"
.word $FFFF
.word __RODATA_LOAD__
.word __DATA_LOAD__ + __DATA_SIZE__ - 1
.segment "CHKHDR"
.word __LOWCODE_LOAD__
.word __BSS_LOAD__ - 1
Compile with
cl65 -t atari -C split2.cfg -o prog.com prog.c split2.s
***************************************************
Understand that this is just jerking the linker around so it does what is already there in the Atari OS. The command line to *LINK* it is longer then using the COPY with append command! You have to learn 'C, develop your program, then learn linker! One of the advantages of C was it was black box in that you didn't need to know how something was accomplished in order to get something done. There was no POKE in C, it was almost Pascal like in keeping you away from the hardware. Then it evolved into something meant to bang on hardware. From there it has evolved into integrated development environment that have a longer learning curve then the language.
As a final note, someone pointed out that the linker scripts were no longer valid after updates and had to be rewritten.<sigh>
Rick
I'm not bashing the cc65 crew as the would be inappropriate from a programming standpoint. They are very talented and well versed beyond my ability in both C and assembly language.
Recently someone on the mailing list asked about aligning fields for some quirks in the Atari hardware like display list location, character sets, et cetera and said they were short of space.
I replied something to the effect that you could chain programs on the Atari such that PROGA.EXE runs and terminates so you can do the memory reservations and fixed data locations then PROGB.EXE will be run automatically.
The procedure is pretty simple, menu driven DOS/DUP so you just hit 'C for COPY file and give it
PORGB.EXE,PROGA.EXE /A
The 'or you could do this' pointed me to the help file where you find
*******************************************************
Low code and high data example
Goal: Create an executable with 2 load chunks which doesn't use the memory area from $4000 to $7FFF. The CODE segment of the program should go below $4000 and the DATA and RODATA segments should go above $7FFF.
The main problem is that the EXE header generated by the cc65 runtime lib is wrong. It defines a single load chunk with the sizes/addresses of the LOWCODE, INIT, CODE, RODATA, and DATA segments (the whole user program).
The contents of the EXE header come from the EXEHDR segment, which is defined in crt0.s. This cannot be changed w/o modifying and recompiling the cc65 atari runtime lib. Therefore the original EXE header must be discarded. It will be replaced by a user created one.
The user needs to create a customized linker config file which adds new memory areas and segments to hold the new EXE header and the header data for the second load chunk. Also an assembly source file needs to be created which defines the contents of the new EXE header and the second load chunk header.
This is a modified cc65 Atari linker configuration file (split.cfg):
MEMORY {
ZP: start = $82, size = $7E, type = rw, define = yes;
HEADER: start = $0000, size = $6, file = %O; # first load chunk
RAMLO: start = $2E00, size = $1200, file = %O;
BANK: start = $4000, size = $4000, file = "";
SECHDR: start = $0000, size = $4, file = %O; # second load chunk
RAM: start = $8000, size = $3C20, file = %O; # $3C20: matches upper bound $BC1F
TRAILER: start = $0000, size = $0006, file = %O;
}
SEGMENTS {
EXEHDR: load = BANK, type = ro;
NEXEHDR: load = HEADER, type = ro; # first load chunk
LOWCODE: load = RAMLO, type = ro, define = yes, optional = yes;
INIT: load = RAMLO, type = ro, optional = yes;
CODE: load = RAMLO, type = ro, define = yes;
CHKHDR: load = SECHDR, type = ro; # second load chunk
RODATA: load = RAM, type = ro, define = yes;
DATA: load = RAM, type = rw, define = yes;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
AUTOSTRT: load = TRAILER, type = ro; # defines program entry point
}
FEATURES {
CONDES: segment = RODATA,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = RODATA,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
__STACKSIZE__ = $800; # 2K stack
__RESERVED_MEMORY__: value = $0, weak = yes;
}
A new memory area BANK was added which describes the reserved area. It gets loaded with the contents of the old EXEHDR segment. But the memory area isn't written to the output file. This way the contents of the EXEHDR segment get discarded.
The added NEXEHDR segment defines the correct EXE header. It puts only the CODE segment into load chunk #1 (RAMLO memory area).
The header for the second load chunk comes from the new CHKHDR segment. It puts the RODATA and DATA segments into load chunk #2 (RAM memory area).
The contents of the new NEXEHDR and CHKHDR segments come from this file (split.s):
.import __LOWCODE_LOAD__, __BSS_LOAD__, __CODE_SIZE__
.import __CODE_LOAD__, __DATA_LOAD__, __RODATA_LOAD__
.segment "NEXEHDR"
.word $FFFF ; EXE file magic number
; 1st load chunk
.word __LOWCODE_LOAD__
.word __CODE_LOAD__ + __CODE_SIZE__ - 1
.segment "CHKHDR"
; 2nd load chunk (contains with AUTOSTRT in fact a 3rd load chunk)
.word __RODATA_LOAD__
.word __BSS_LOAD__ - 1
Compile with
cl65 -t atari -C split.cfg -o prog.com prog.c split.s
Low data and high code example
Goal: Put RODATA and DATA into low memory and LOWCODE, INIT, CODE, BSS into high memory (split2.cfg):
MEMORY {
ZP: start = $82, size = $7E, type = rw, define = yes;
HEADER: start = $0000, size = $6, file = %O; # first load chunk
RAMLO: start = $2E00, size = $1200, file = %O;
BANK: start = $4000, size = $4000, file = "";
SECHDR: start = $0000, size = $4, file = %O; # second load chunk
RAM: start = $8000, size = $3C20, file = %O; # $3C20: matches upper bound $BC1F
TRAILER: start = $0000, size = $0006, file = %O;
}
SEGMENTS {
EXEHDR: load = BANK, type = ro; # discarded old EXE header
NEXEHDR: load = HEADER, type = ro; # first load chunk
RODATA: load = RAMLO, type = ro, define = yes;
DATA: load = RAMLO, type = rw, define = yes;
CHKHDR: load = SECHDR, type = ro; # second load chunk
LOWCODE: load = RAM, type = ro, define = yes, optional = yes;
INIT: load = RAM, type = ro, optional = yes;
CODE: load = RAM, type = ro, define = yes;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
AUTOSTRT: load = TRAILER, type = ro; # defines program entry point
}
FEATURES {
CONDES: segment = RODATA,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = RODATA,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
__STACKSIZE__ = $800; # 2K stack
__RESERVED_MEMORY__: value = $0, weak = yes;
}
New contents for NEXEHDR and CHKHDR are needed (split2.s):
.import __LOWCODE_LOAD__, __BSS_LOAD__, __DATA_SIZE__
.import __DATA_LOAD__, __RODATA_LOAD__
.segment "NEXEHDR"
.word $FFFF
.word __RODATA_LOAD__
.word __DATA_LOAD__ + __DATA_SIZE__ - 1
.segment "CHKHDR"
.word __LOWCODE_LOAD__
.word __BSS_LOAD__ - 1
Compile with
cl65 -t atari -C split2.cfg -o prog.com prog.c split2.s
***************************************************
Understand that this is just jerking the linker around so it does what is already there in the Atari OS. The command line to *LINK* it is longer then using the COPY with append command! You have to learn 'C, develop your program, then learn linker! One of the advantages of C was it was black box in that you didn't need to know how something was accomplished in order to get something done. There was no POKE in C, it was almost Pascal like in keeping you away from the hardware. Then it evolved into something meant to bang on hardware. From there it has evolved into integrated development environment that have a longer learning curve then the language.
As a final note, someone pointed out that the linker scripts were no longer valid after updates and had to be rewritten.<sigh>
Rick
Re: Sometimes I have to explain myself
This post is loaded with so many factual errors about C that I feel compelled to respond.
Actually, that was never an overt design requirement of C. C's intent was nothing more than to port Unix from the PDP/7 to the multifarious PDP/11 environments using a language with a consistent syntax. C, in and of itself, was originally written as a high-level PDP assembler (C's post- and pre-increment operators, for example, come directly from the PDP's equivalent addressing modes, for example) with only the most basic forms of type checking -- just enough to catch some common errors, but not all.
I actively encourage you to compare early C code against contemporary C code. You'll be shocked at how little abstraction it encouraged back in the 60s and 70s.
Sorry, but C is fundamentally predicated on its ability to poke into arbitrary memory, from day one. It was designed to port operating systems, after all.
(1) Arrays are just syntactic sugar for memory (de)references. A [ i ] is the exact same thing as *(A+I). Don't believe me? Go ahead and compile a program referencing p[0] instead of *p, or even p[-10].
(2) You can use the unary * operator anywhere you want, albeit with some optional casting.
The fragment:
is precisely equivalent to the following BASIC excerpt:
Not even close. K&R designed C explicitly because Pascal suffered so badly from its inability to touch hardware (and it still suffers today; if you want to do systems programming with a Wirth language, use Modula-2 or Oberon instead).
Pascal has sets; C (still) doesn't. Pascal has well-defined pointer semantics (which get even more defined in Modula-2 and Oberon!). C (still) doesn't. Pascal, back when C came out, lacked separate compilation and support for modularity; however, it now offers this using mechanisms not entirely unlike what you'll find in languages like Modula-2 or Ruby. C , meanwhile, still doesn't offer anything remotely close to this. I could go on, but I'd just be parroting what Google can easily turn up.
If you study the revision history of the C specification, especially after becoming standardized through ANSI, you'll find repeated changes to the language to increase, not decrease, its level of abstraction. Typing, while still optional, has gotten stronger over the years. Enumerations are supported now. You no longer have to cast function pointers using (*)() notation, thanks to "typedef" (you can now use typedef char foo(int, ...);, and declare function pointers to be foo *). You can now mix pointers and array notation to arbitrary depths. And, you no longer have to use * to invoke through a function pointer. Many C compilers have the option to support C++-style "demand instantiation" of variables (e.g., for(int i=0; i < ...; i++)...).
Are you aware that C didn't get an official boolean data type until 1999?
Rick Cortese wrote:
One of the advantages of C was it was black box in that you didn't need to know how something was accomplished in order to get something done.
I actively encourage you to compare early C code against contemporary C code. You'll be shocked at how little abstraction it encouraged back in the 60s and 70s.
Quote:
There was no POKE in C,
(1) Arrays are just syntactic sugar for memory (de)references. A [ i ] is the exact same thing as *(A+I). Don't believe me? Go ahead and compile a program referencing p[0] instead of *p, or even p[-10].
(2) You can use the unary * operator anywhere you want, albeit with some optional casting.
The fragment:
Code: Select all
unsigned long p;
*((char *)p++) = 0x00;
Code: Select all
POKE p,0:p=p+1
Quote:
it was almost Pascal like in keeping you away from the hardware.
Pascal has sets; C (still) doesn't. Pascal has well-defined pointer semantics (which get even more defined in Modula-2 and Oberon!). C (still) doesn't. Pascal, back when C came out, lacked separate compilation and support for modularity; however, it now offers this using mechanisms not entirely unlike what you'll find in languages like Modula-2 or Ruby. C , meanwhile, still doesn't offer anything remotely close to this. I could go on, but I'd just be parroting what Google can easily turn up.
If you study the revision history of the C specification, especially after becoming standardized through ANSI, you'll find repeated changes to the language to increase, not decrease, its level of abstraction. Typing, while still optional, has gotten stronger over the years. Enumerations are supported now. You no longer have to cast function pointers using (*)() notation, thanks to "typedef" (you can now use typedef char foo(int, ...);, and declare function pointers to be foo *). You can now mix pointers and array notation to arbitrary depths. And, you no longer have to use * to invoke through a function pointer. Many C compilers have the option to support C++-style "demand instantiation" of variables (e.g., for(int i=0; i < ...; i++)...).
Are you aware that C didn't get an official boolean data type until 1999?
-
Rick Cortese
- Posts: 17
- Joined: 28 Sep 2009
Re: Sometimes I have to explain myself
kc5tja wrote:
This post is loaded with so many factual errors about C that I feel compelled to respond.
The example I posted where people seriously consider it as a viable alternative to a simple file copy tells me you must have been living under a rock for the last 20 years.
If you don't know what is going on now, what makes you think you knew what was going on when you were still in grade school?
Specifically have you ever heard the term portability used? I don't know what else to tell you other then instructors told you not to bang on hardware and the techniques to do it were just given a single cursitory example with the caveat that we should never use it as it would make our code non portable.
I am pretty happy with my statement and stand by it. There is nothing you can say in your goofy brow beating style that would convince me to subscribe to your alternate view of reality.
Rick
Re: Sometimes I have to explain myself
Rick Cortese wrote:
The example I posted where people seriously consider it as a viable alternative to a simple file copy tells me you must have been living under a rock for the last 20 years.
Quote:
If you don't know what is going on now, what makes you think you knew what was going on when you were still in grade school?
Related to this is an activity called research, which is the act of studying these primary (and sometimes secondary) sources of information. Collecting and collating the data learned therefrom, I am able to draw conclusions which are in large part in agreement with the understanding of others, including the authors of C itself.
Quote:
Specifically have you ever heard the term portability used?
Quote:
I am pretty happy with my statement and stand by it.
Quote:
There is nothing you can say in your goofy brow beating style that would convince me to subscribe to your alternate view of reality. 
Quote:
C was developed on and for mainframes
Quote:
and nobody wanted to put a language in the hands of a rookie programmers that let them accidentally bang the hard drive and screw up the payroll records.
The language isn't the issue here. The operating system determines the availability of this power. This is why Unix, OS/360, VM, VMS, and so many others all implement ACL-driven security systems.
Hint -- I work with this stuff every single day.
Quote:
It wasn't until personal computers came out, maybe 10 years after C first came out, that it was tailored to directly access the hardware. I guess your history begins in the 80's.
http://www.cs.bell-labs.com/who/dmr/
To whit:
Quote:
The version of the C Reference Manual Postscript (250KB) or PDF, (79K) that came with 6th Edition Unix (May 1975), in the second volume entitled ``Documents for Use With the Unix Time-sharing System''. For completeness, there are also versions of Kernighan's tutorial on C, in Postscript or PDF format.
I encourage you to read page 10, wherein he describes the evolution of C to port Unix.
Look, everyone in this country has a right to free speech. But not everyone has a right to be listened to. If you spew misinformation, or manifest deliberate attempts to distort information to persue some agenda, I absolutely will call you on it..
Yes, with the specific context of getting my microcontroller development environment running, I have major complaints about overall system complexity. But, this is not the fault of C, the language. It's the fault of the tool manufacturers. C does have its own faults, but they're very orthogonal to the problems I was having at the time.
I encourage you to get over and educate yourself on what actually happened in history and stop slandering other people. Continued ad hominem and patently unjustified attacks on me will result in me petitioning the site administrator to have you removed from the board for abusive behavior.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Chill guys... We like you both. Maybe the forum needs a new section where you "call someone out" on a topic. I've seen it much meaner than this on other forums, as I'm sure we all have. Just sorta surprising when someone (1 or both of you) reads a thread and then BAM! you've been "called out" to explain yourself, and then threats.
No problem with it IMO. But the "surprise" of being "called out" should be put in a separate thread, that way there is no surprise, and also there is more room for constructive arguments without the fear of being banned.
Just saying, not all arguments are destructive, especially here. We all have above average intelligence...
No problem with it IMO. But the "surprise" of being "called out" should be put in a separate thread, that way there is no surprise, and also there is more room for constructive arguments without the fear of being banned.
Just saying, not all arguments are destructive, especially here. We all have above average intelligence...
-
Rick Cortese
- Posts: 17
- Joined: 28 Sep 2009
Re: Sometimes I have to explain myself
kc5tja wrote:
Rick Cortese wrote:
The example I posted where people seriously consider it as a viable alternative to a simple file copy tells me you must have been living under a rock for the last 20 years.
Quote:
If you don't know what is going on now, what makes you think you knew what was going on when you were still in grade school?
I pulled out my copy of "Turbo C The Complete Reference" by Schildt. This was about the time of version 1.5 with the forward written by Philipe Kann no less. Understand too that this was written after my 'things changed' time of the introduction of micros. In 908 pages there is one reference to direct video that covers 3 pages and ends with warning
"However, for computers that are not hardware compatible direct video RAM output can not be used."
That same type of warning is put in for most of the non standard language extensions that were put in for speed over compatibility.
I can also give you a Bill Wilkinson quote
"Unlike Forth, however, C requires the user to declare that he/she
is going beyond the scope of the language structures in order to
"cheat" and access the machine level directly."
I don't know about you but words like "cheat" and phrases like "going beyond the scope of the language structures" are not exactly an endorsement of your position.
These quotes are consistant with my recollections of that time and my post here. I could easily find a dozen more but I have the feeling they would be wasted on you. If you used C back then it was probably on a time sharing mainframe. I recall the company I worked for at that time spent something like $750,000 for a DEC and you can be sure they didn't want a bunch of yahoos with direct access to hardware. You should know this kind of stuff if you are Linux fan. You don't give that kind of hardware access to a user.
You are taking my post out of context by changing the time frame to suit your purpose of being argumentative. If I can't tell you that you are taking my post out of context who can? I mean sheesh! All I said was ~there was a time before hardware specific implementations of C became common place and a time after. How can anybody argue with that?
I would prefer you don't follow up with another one of your tirades. If you want to argue stick with the point I made, i.e. "there was a time before hardware specific implementations of C became common place and a time after" and/or <one of>my conclusion that this has made C non standard. I mean to me your argument is a non sequitur. I am reminded of the Monty Python bit where Michael Palin tries to buy an argument with John Cleese.
Rick
C is designed to make access to the hardware easy. Why? C was written for writing Unix. Unix is an operating system. An operating system spends it's time accessing hardware!
Operating system restrictions have no bearing on the restrictions a language poses on the user; that under Linux, Unix, or any other modern operating system you cannot access the hardware directly has no bearing that the ability to access it directly (when allowed to do so) and how to do so is explicitly documented in the standard. Yes, it's non-portable - the general assumption is that if you're accessing hardware directly, you know what you're doing.
Your interpretation of history does not match the facts. I'm sorry, but please, before claiming such things, do the research. C's development explicitly mirrored the features that Unix needed; one of those was the ability to manage hardware. This is not bad form in and of itself; it is a very important feature for a driver writer.
C is very close to the least abstracted usable language you can create; it is simple in definition by design, with the result that it can do very complex things.
C is a language for writing anything from an operating system & it's drivers, to a complex application. While it's use for the later is deservedly being eroded by more high level languages, in the former application it, along with C++, is holding strong.
Operating system restrictions have no bearing on the restrictions a language poses on the user; that under Linux, Unix, or any other modern operating system you cannot access the hardware directly has no bearing that the ability to access it directly (when allowed to do so) and how to do so is explicitly documented in the standard. Yes, it's non-portable - the general assumption is that if you're accessing hardware directly, you know what you're doing.
Your interpretation of history does not match the facts. I'm sorry, but please, before claiming such things, do the research. C's development explicitly mirrored the features that Unix needed; one of those was the ability to manage hardware. This is not bad form in and of itself; it is a very important feature for a driver writer.
C is very close to the least abstracted usable language you can create; it is simple in definition by design, with the result that it can do very complex things.
C is a language for writing anything from an operating system & it's drivers, to a complex application. While it's use for the later is deservedly being eroded by more high level languages, in the former application it, along with C++, is holding strong.
Please, let's refrain from taking offense, as well as from insulting each other.
I wonder if the technical and historical point here is the difference between machines with memory-mapped i/o and machines with a separate i/o space? C's pointers would give complete access to the former type of machine. Or perhaps it's the difference which comes when there are different protection rings, or a supervisor mode.
As we're on 6502.org, we're presumably fond of the simplest model, which is more like the early minicomputers than the PC model.
I wonder if the technical and historical point here is the difference between machines with memory-mapped i/o and machines with a separate i/o space? C's pointers would give complete access to the former type of machine. Or perhaps it's the difference which comes when there are different protection rings, or a supervisor mode.
As we're on 6502.org, we're presumably fond of the simplest model, which is more like the early minicomputers than the PC model.
-
Rick Cortese
- Posts: 17
- Joined: 28 Sep 2009
BigEd wrote:
Please, let's refrain from taking offense, as well as from insulting each other.
I wonder if the technical and historical point here is the difference between machines with memory-mapped i/o and machines with a separate i/o space? C's pointers would give complete access to the former type of machine. Or perhaps it's the difference which comes when there are different protection rings, or a supervisor mode.
As we're on 6502.org, we're presumably fond of the simplest model, which is more like the early minicomputers than the PC model.
I wonder if the technical and historical point here is the difference between machines with memory-mapped i/o and machines with a separate i/o space? C's pointers would give complete access to the former type of machine. Or perhaps it's the difference which comes when there are different protection rings, or a supervisor mode.
As we're on 6502.org, we're presumably fond of the simplest model, which is more like the early minicomputers than the PC model.
Likewise there there was a time when portability was an issue. You were taught, cajoled, and encouraged to keep it standard. It is kind of like trying to remind people there were text based browsers before Windows. Heck, they lost the fight but that doesn't mean they weren't there.
The only OS in a widely distributed product I can recall from that time period that was written in C was for the Atari ST which made it an object of ridicule in some circles. I have the BIOS listing for the IBM in that period, 100% assembler. Ditto for CP/M, there were a few C compilers for it but they were used to write programs like squeeze. Yes, I know Linux is written in written in C, but that was later. It also depends on where you draw the line in OS i.e. BIOS, kernal, or VI. I can probably name a dozen OS prior to 1985 that were written in asm. I don't think I can name 3 written in C. I do have an oddball Forth computer where you could call Forth an OS which probably ties it with UNIX and BSD. I'm pretty sure ones like QNX started out on a '286 in assembler. Sheesh! If someone could give me a list of a dozen computers prior to 1985 in wide distribution with their OS/kernal written in C and I will happily admit I am wrong. Twelve PDP-10s does not count. C was probably used at least 100000:1 for writing applications on these systems vs. replacing the existing OS or writing a new OS for a new computer. That you could write an OS in C, and be laughed at as a feeb, sure. I could write an OS in BASIC. That doesn't make it a good idea, desirable, or what the proliferation of the language was about. That every microwave oven and DVD player probably has an OS written in C now, well that is now.
There was no compatibility issue when there was only one version and one copy of C. Somewhere between that one and the thousands we have now it became an issue.
Rick
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Sometimes I have to explain myself
Rick Cortese wrote:
The example I posted where people seriously consider it as a viable alternative to a simple file copy tells me you must have been living under a rock for the last 20 years.
Such insults are unnecessary and merely detract from the usefulness of this forum.
Quote:
Specifically have you ever heard the term portability used?
Quote:
I don't know what else to tell you other then instructors told you not to bang on hardware and the techniques to do it were just given a single cursitory example with the caveat that we should never use it as it would make our code non portable.
Quote:
C was developed on and for mainframes...
Quote:
...and nobody wanted to put a language in the hands of a rookie programmers that let them accidentally bang the hard drive and screw up the payroll records.
Quote:
It wasn't until personal computers came out, maybe 10 years after C first came out, that it was tailored to directly access the hardware. I guess your history begins in the 80's.
BTW, the ability to directly access the hardware was an innate characteristic of C from the beginning. As I said above, C is an abstraction of PDP/11 assembly language, which, of course, would have been able to do anything to the machine, including crashing it.
BTW, the only thing worse than putting one's foot into one's mouth is biting off more than one can chew, if you get my drift.
x86? We ain't got no x86. We don't NEED no stinking x86!
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Well guys, I'm not going to kick anyone out (so far I only do that to spammers-- thousands of 'em), but I can't say I haven't thought about just deleting this whole topic. I can usually get along with abrasive people, and I hope I can encourage you all to do the same. This is about our common interest; and, while we want correct info disseminated, it's for the benefit of all, not for winning arguments per se. Fair enough?
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
One Last Post
GARTHWILSON wrote:
Well guys, I'm not going to kick anyone out...
Speaking of forum control, what happens when someone tries to submit code to Mike for posting here and no hint is given that it was received/reviewed/tossed in the garbage, etc.?
x86? We ain't got no x86. We don't NEED no stinking x86!
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
GARTHWILSON wrote:
BDD, I've tried Emailing you but your service apparently rejects my address as a spam source. Can you please put my address on the "white list."
x86? We ain't got no x86. We don't NEED no stinking x86!