From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!feeder.eternal-september.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.lang.ada Subject: Re: Forth and others (Was Re: How to get Ada to ?cross the chasm??) Date: Sun, 13 May 2018 15:43:42 +0300 Organization: Tidorum Ltd Message-ID: References: <1c73f159-eae4-4ae7-a348-03964b007197@googlegroups.com> <87k1sg2qux.fsf@nightsong.com> <87h8njmk4r.fsf@nightsong.com> <87po27fbv9.fsf@nightsong.com> <87in7x62vw.fsf@nightsong.com> <878t8szdtk.fsf@nightsong.com> <87tvrdhl5v.fsf@nightsong.com> <87sh6w7mac.fsf@nightsong.com> <874ljcthwk.fsf@nightsong.com> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net VzmQXxwqa40YbhXszpuaqgefH0yXzU1VEg/pdtppKarjfG8Ezf Cancel-Lock: sha1:MqmPuoKzLthLoOQdq6rHbd7cQW8= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 In-Reply-To: <874ljcthwk.fsf@nightsong.com> Xref: reader02.eternal-september.org comp.lang.ada:52335 Date: 2018-05-13T15:43:42+03:00 List-Id: On 18-05-13 05:21 , Paul Rubin wrote: > Niklas Holsti writes: >> As I wrote, BASIC was used previously at this sit... It was not fast >> enough, it did not do multi-tasking, and -- hold on to your hat -- the >> programs were running out of variable identifiers! > > Heh, but BASIC had arrays?!! So A(1), A(2) etc could be used for > different purposes ;). I don't recall if that trick was already in use for the BASIC programs; it may have been. > It looks like you can still run HP-2100 ALGOL under emulation: > > http://simh.trailing-edge.com/pdf/hp2100_doc.pdf > http://simh.trailing-edge.com/docs/hp2100_algol_howto_doc.txt Oh boy, what a thorough simulation, even all the I/O devices. >> The HP2100 had instructions which could more easily access the "base >> page" of RAM,... >> I made a post-compiler program (in Algol) that ... punched out a >> relocatable object-code tape that was altered to eliminate or reduce >> base-page use > > Interesting that the HP compiler didn't deal with this issue itself. It is a trade-off: variables in the base page were faster to access directly. IIRC, arrays were not put in the base page. Our programs were control-oriented, collecting and processing relatively small amounts of data, so perhaps we had a larger proportion of scalar (non-array) variables than usual for this machine. I did not think of it at the time, but perhaps we could have used the same trick you suggested for BASIC: define our variables as arrays instead of scalars, thus moving them away from the base page. > Machines like that were mostly before my time so I wonder what the usual > strategies were. I think the 8051 MCU (still used in embedded systems > today) has the same design and there are lots of C compilers for it > so they must handle it somehow. The base page is 128 or 256 bytes iirc. Ah, the 8051. The first microcontroller project I worked on used an 80C32 (same thing, really) to control a satellite-born detector of micro-meteoroids and small space debris. We used the Keil C compiler and Keil RTX-51 real-time kernel. One of these detectors was mounted on the International Space Station; still may be for all I know. It's called "internal memory" and is a separate address space (8-bit address). In the basic 8051 architecture, one can access the first 128 octets of internal memory using either direct or indirect addressing (but a goodish part of these 128 octets consists of working registers) and another 128 octets only with indirect addressing (because direct addressing of that part of the internal memory space accesses the memory-mapped I/O and control registers, the so-called Special Function Registers). The C compilers for the 8051 defined new keywords for use in variable declarations to say if the variable should be in the internal memory or in some of the other two memory areas (external memory or "paged" memory). Possibly the current compilers support the newly standardised C concept of named memory areas. Since the memory area could be chosen by the programmer, there was a work-around for overfilling the internal memory: move variables to the paged or external memory (assuming the particular 8051 system implemented those areas). So variables could be declared in the internal memory (possibly for indirect addressing only), in the paged memory, and in the external memory. Constants could also reside in the code memory (Harvard architecture). Pointers could also be declared as pointing to a specific memory area, or to any memory area (defined at run-time by the value of the pointer); the latter was called a general pointer, IIRC. Of course a pointer variable itself could reside in internal memory, paged memory, or external memory, so the declaration of a pointer variable could have _two_ of the new memory-area keywords, one to say in which memory area the pointer should be, and another to say into which memory area the pointer could point. The memcpy operation for general pointer variables was *complex*, the more so because different instructions must be used to access each different memory area. The 8051 call and return instructions use a stack in the internal memory, but always indirectly (thru the Stack Pointer register, SP), so this "native" stack is usually placed in the indirectly addressable upper 128 octets of the internal memory. Because this stack is so small, and hard to access with base+offset addressing, C compilers tend to use it only for the return addresses. Local variables are usually statically allocated, although some C compilers for the 8051 let one specify that a certain C function should be reentrant and have its local variables on some stack, perhaps a SW-managed stack in external memory. The SP register can point only into the internal memory. How to do multi-tasking, if the internal memory is too small to hold the stacks of all tasks? The Keil RTK would keep a copy of each task's stack in the external memory, and swap the _whole_ stack content between the external memory and the internal memory on each task switch. When it was allowed to make non-reentrant code, the Keil C compiler would allocate local variables statically, including variables placed in the internal memory, but it did it in a smart way by reusing the same memory locations for the local variables of different C functions that could never be active (in the call stack) at the same time -- even considering the call trees of all tasks. In other words, the compiler created an "overlay tree" for the local variables in internal memory. This was a main reason why largish C programs could be made to fit in the 8051 with the Keil compiler, but not with the free "sdcc" compiler. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .