[Oberon] Negative integer literals in Oberon
joerg.straube at iaeth.ch
Sat May 2 13:23:36 CEST 2020
Yes and no.
Addresses (as integers) do not exist in Oberon.
Oberon uses POINTER. You can‘t do arithmetic on pointers. only = and # are allowed on pointers/adresses, no < or >
If you use SYSTEM.GET/PUT/VAL you hopefully know what you are doing.
With 32bit INTEGERs and max 24bit address bus of the RISC5 (max 16 MB) you don‘t run into this overflow problem.
SYSTEM.GET/PUT can handle „negative“ values (=large positive values) correctly.
> Am 01.05.2020 um 20:22 schrieb Oleg N. Cher <allot at bk.ru>:
> Dear Joerg,
> If we talk about addresses, addresses are usually positive numbers. And working in Oberon, we have an inconvenient moment when the maximum positive number denoting the address goes to the minimum negative: 7FFFFFFFH+1. Therefore, strictly speaking, integers do not map well on the address type. This is bad when addresses are compared and so on. It's just a compromise.
> Joerg пишет:
>> I agree that addresses are INTEGERs.
>> They start at 0 and increment up to max memory. Low level function SYSTEM.GET(a, v) defines address “a“ as INTEGER. Whether you have to work with hex notation though is another story. But be it.
>>>> Am 28.04.2020 um 16:04 schrieb Skulski, Wojciech <skulski at pas.rochester.edu>:
>>>> There is no question, that hex notation is convenient and needed.
>>> I am glad that you are retracting your suggestion that hex could be removed ;-)
>>>> But are we really talking about INTEGERs here? Whenever I saw hex notation in my career, it had something to do with HW registers and silly register constants for low level programming.
>>> There are a few use cases.
>>> Case 1. We are talking of memory locations. The RAM memory chip is organized as an array. An array starts at 0 and goes on with consecutive numbers, which are integers. Moreover, addresses are often calculated. Therefore, an address is not only an integer, but it is also an integer with math. So yes, an address is a first class integer.
>>> Case 2. We can dig further and note that the DRAM is organized as a vector composed on the row, column, and bank. So DRAM address is a triple. But practical DRAM memory controllers strive to map the triple to an ascending array of integers. So there is no reason to deny the integer status in case of DRAM.
>>> Case 3. Hardware registers and special purpose memories: arrays of registers, video memories, or network chip buffers (e.g., Wiznet W5300 or ASIX AX8180). These are as good memory arrays as any memory, and their addresses are as good addresses as any. So these addresses are good integers.
>>> Case 3. The content of these special registers or video memories. We already know that the addresses are registers, but how about the content? Here we can recall that the colors can be calculated using integer math. Another example: imagine that the memory buffer contains an arbitrary signal to be synthesized, which is often the case with signal processing. This also needs calculation. The conclusion: the register content is a good integer and it needs math.
>>>> - INTEGERs and REALs are abstractions to do calculations with undefined precision.
>>> Yes, if you are implementing an abstract algorithm. Not quite so if you are serving some hardware.
>>>> - POINTER is an abstraction to address memory
>>> Ditto. A POINTER is allocated by the run time at any memory location. Good for algorithms. Not good for serving hardware. In the latter case I would advocate a minor language extension, or something equivalent. Presently the same is somehow achieved with SYSTEM syntax.
>>> myReg := NEW (INTEGER32 at 01234H); (* 32-bit register *)
>>>> - SET is an abstraction for bit operations.
>>> Good for abstract algorithms, but in practice we also need hardware mapped bits. How about the following:
>>> myBits := NEW (SET27 at 01234H); (* 27-bit register *)
>>>> To what Oberon type should the hex notation apply?
>>> Integers and sets.
>>>> In my point of view to INTEGERs the least. SET the most, but this is not foreseen today.
>>>> And POINTERs have no explicit value at all, as all is abstracted away (hidden) by NEW()
>>> Not sufficient for serving hardware. If the pointer is used to reach a concrete register or video memory, then its target location must be provided by the programmer rather than the run time.
>>> Am 28.04.20, 06:51 schrieb "Oberon im Auftrag von Skulski, Wojciech" <oberon-bounces at lists.inf.ethz.ch im Auftrag von skulski at pas.rochester.edu>:
>>>> It‘s a good point but a little bit a corner case. Principally,
>>>> Oberon does not know addresses, as addresses are abstracted
>>>> away by the type construct POINTER TO
>>> Yes, POINTER TO needs to be used eventually. But we are facing the question
>>> how to assign the hard coded address to the POINTER. The VRAMORG is
>>> the case in point. This address is connected to the firmware video controller.
>>> The value has to be used as provided below, or there will be no video.
>>> VRAMORG does not have to be coded in hex in Oberon. The FW developer can use
>>> 0E7F00H, while the Oberon programmer can write 950016 in decimal. But it is
>>> much easier and less error prone if both developers can use the same notation.
>>> So we need the hex in this case because firmware developers are likely to use hex.
>>> Another example is perhaps all these protocols like Ethernet where the documentation
>>> will provide hex constants. Imagine the Oberon developer not being able to use these,
>>> but rather using a Windows calculator to translate to decimal because hex notation
>>> was removed from the language.
>>> br, Jörg
>>>>> Am 27.04.2020 um 22:40 schrieb Skulski, Wojciech <skulski at pas.rochester.edu>:
>>>>> Could somebody give me a good example, where INTEGERs need a hex notation?
>>>> How about this? These INTEGERS represent addresses. Are addresses integers? I believe they are. The memory is a collection of addresses with consecutive numbers expressed with integers. So it is a relevant example.
>>>> (* Memory map; PO.System page 104 *)
>>>> STACKSIZE* = 8000H; (* 32 kB. Was hardwired in Kernel.Init *)
>>>> STACKORG* = 80000H; (* stackOrg = 524,288; half a megabyte. *)
>>>> HEAPORG* = STACKORG; (* heapOrg = stackOrg *)
>>>> FSoffset* = STACKORG; (* Not clear what it is *)
>>>> MEMLIM* = 0E7EF0H; (* 1 MB minus 98,575 bytes of VRAM at the end*)
>>>> VRAMORG* = 0E7F00H; (* start of memory-mapped display frame*)
>>>> VRAMSIZE* = 1024*768 DIV 8; (* 1024 x 768 pixel, monocolor display frame*)
>>> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
>> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
More information about the Oberon