Shop OBEX P1 Docs P2 Docs Learn Events
TAQOZ Reloaded v2.8 - Word Glossary - Page 3 — Parallax Forums

TAQOZ Reloaded v2.8 - Word Glossary

13

Comments

  • Hi Bob:

    Regarding variable space, Christof's limiting value $200 (512 bytes) is not correct. It is much larger. See the number of data bytes used after rebooting. Using large arrays may cause problems. They should be defined in hub memory > 128k.

    I also note that LOG and EXP are not natural logs but log base 2 as described in Chip's documentation.

    Nick

  • Hi @nchlor Nick,
    I've made changes to 'DEFINING VARIABLES' and 'MATHS' sections inline with your comments. Many thanks for that.
    Bob

  • Christof Eb.Christof Eb. Posts: 1,195
    edited 2022-03-16 10:04

    @nchlor said:
    Hi Bob:

    Regarding variable space, Christof's limiting value $200 (512 bytes) is not correct. It is much larger. See the number of data bytes used after rebooting. Using large arrays may cause problems. They should be defined in hub memory > 128k.

    I also note that LOG and EXP are not natural logs but log base 2 as described in Chip's documentation.

    Nick

    Hi Nick, which version of Taqoz do you use exactly?

    My statement was related to the binary version, as described in the first post here: https://forums.parallax.com/discussion/173767/p2-taqoz-v2-8-for-25mhz-crystal-of-kiss-with-sd-card-921600-baud#latest
    (( I have perceived your saying: "Christof's ... IS NOT CORRECT" as "impertinence", as I had experienced the limit the hard way by crashing code. So if you don't intend such feelings, you might want to use different words in future.... ))

    I have seen, that memory layout and pins assignment for vga vary between versions even if they have the same version number.
    Christof

  • Hi Bob,
    perhaps it would be good, if you could include the exact origin of your version of Taqoz 2.8 into your Glossary to avoid misunderstandings.
    Christof

  • Hi Christof

    Sorry for my   wording.   I am using the most current version of TAQOZ as described in the glossary with a substantial addition of variables in my program.  I believe that using VGA would require significant free memory
    

    which is only available in the hub >128000 k.

    Nick

  • bob_g4bbybob_g4bby Posts: 411
    edited 2022-03-16 19:50

    Hi @"Christof Eb."
    That would be useful. In version 52 of the glossary I've described my particular set up of Taqoz v2.8 in section 'Installing TAQOZ RELOADED - Method 2' towards the back of the glossary, together with the boot message I receive on switch-on. The system reports 1368 bytes free for data - although I haven't tested that to be true. I use this set-up because I have no interest in onboard VGA or multimedia support at the moment, I'd rather have the space for my application. Whether you have $200 bytes or 1568 bytes, neither is really enough for a large application - so exploring the space above the first 128K is a useful thing to do - especially as I'm interested in software defined radio which needs multiple data buffers.
    Cheers, Bob

  • @bob_g4bby said:
    Hi @"Christof Eb."
    That would be useful. In version 52 of the glossary I've described my particular set up of Taqoz v2.8 in section 'Installing TAQOZ RELOADED - Method 2' towards the back of the glossary, together with the boot message I receive on switch-on. The system reports 1368 bytes free for data - although I haven't tested that to be true. I use this set-up because I have no interest in onboard VGA or multimedia support at the moment, I'd rather have the space for my application. Whether you have $200 bytes or 1568 bytes, neither is really enough for a large application - so exploring the space above the first 128K is a useful thing to do - especially as I'm interested in software defined radio which needs multiple data buffers.
    Cheers, Bob

    Ah, good,
    I have now dug out my Kiss board, it says:
    KERNEL Parallax P2 TAQOZ RELOADED sIDE V2.8 'CHIP' Prop_Ver G 200MHz 210401-1230
    Christof

  • Perhaps this is something for the glossary too.
    Something very special did hamper me for several hours:

    This works:
    TAQOZ# : .1 1 . ; --- ok
    TAQOZ# .1 --- 1 ok

    Does not work:
    TAQOZ# : .1_ 1 . ; --- ok
    TAQOZ# .1_ --- ok No error but no action!

    TAQOZ# see .1_

    1B686: pub .1_
    0BB30: 1801 1
    0BB32: 2B6F . ;

    So if you chose an underscore as last char of a word, it will be compiled ok but it will not work when compiled or interpreted.

  • That's been added to version 53.

  • Hi Bob,
    There doesn't seem to be a link I can find to download the latest Taqoz Reloaded v2.8 glossary?
    I've tried the forum search function, but the returned posts don't seem to have a reference to the latest glossary link.
    Can you advise please?
    Pete

  • @Peter_F said:
    Hi Bob,
    There doesn't seem to be a link I can find to download the latest Taqoz Reloaded v2.8 glossary?
    I've tried the forum search function, but the returned posts don't seem to have a reference to the latest glossary link.
    Can you advise please?
    Pete

    The first post has the updated document.

  • Hi Publison, found it. Sorry! - senior moment! Many thanks.
    https://forums.parallax.com/discussion/173302/taqoz-reloaded-v2-8-word-glossary/p1

  • bob_g4bbybob_g4bby Posts: 411
    edited 2022-04-17 13:41

    I've added some words about memory requirements and limitations in the STACK section of version 58. Taqoz actually uses 5 stacks, although the programmer is only aware of 3 of them. They are mostly located in LUT memory, but the top values of the data and loop stacks are in COG memory.

  • bob_g4bbybob_g4bby Posts: 411
    edited 2022-04-20 10:35

    I've just worked out how TIMEOUT, TIMEOUT? and UNTIL? work and included that information in version 59.

    6 bytes TIME1                           --- storage for a timeout - (a double variable would do as well, but 6 bytes only are actually required)
    1000 TIME1 TIMEOUT                      --- start a timeout of 1000 ms, stored at TIME1
    TIME1 TIMEOUT? .                        --- we check whether TIME1 has timed out yet - would return 0 (false) if no time out yet
    2000 ms TIME1 TIMEOUT? .                --- we check again, after a delay of 2s - TIMEOUT? returns -1 (true) if timeout has passed
    
    3000 TIME1 TIMEOUT                      --- somewhere in a program we start a 3000 ms timeout and elsewhere we can program ...
    TIME1 ?UNTIL                            --- ?UNTIL will only finish executing once timeout has occurred
    
  • @bob_g4bby said:
    I've added some words about memory requirements and limitations in the STACK section of version 58. Taqoz actually uses 5 stacks, although the programmer is only aware of 3 of them. They are mostly located in LUT memory, but the top values of the data and loop stacks are in COG memory.

    Thanks, Bob, for this!

    I think I will try, if LUT! can make my value-type variables (and then locals?) faster. I would need 2 "cog" variables. I have not yet found a position regarding LUT memory. Is it worth to save it for ??? or should I just use it for the locals frame stack?

  • RossHRossH Posts: 5,459

    Like others here, I have had many problems with SD cards on the P2. The P2 Evaluation boards I have are all finicky. Also, there are differences between the RevA boards and the RevB boards. I do not have a RevC board, so I don't know if this version works better.

    As others have reported, successfully booting the P2 from an SD Card seems to depend on both the brand and the size of card. SanDisk cards seem to work most reliably, Verbatim cards often won't boot at all, or will boot once but then require a power cycle or physical removal and re-insertion before they will boot again. I have some cards that will boot reliably from either a hardware or a software reset, some cards that will boot from a hardware reset but not from a software reset, and some cards that will not boot at all. All the cards seem to work perfectly well in other devices.

    If anyone has any PASM code that can reliably reboot the P2 from the SD card, and which works for a variety of SD card brands and sizes, please post it.

    Ross.

  • @bob_g4bby
    Hi,
    if you can verify that, it might save others a lot of time. At least I needed it to find this:
    ALIAS NOT invert does not work. Heavy crash.
    : invert NOT ; does work.
    At the moment I believe, that ALIAS cannot be used for words, which execute from cog.
    Christof

  • @"Christof Eb."

    So, I'm still using Parallax P2 TAQOZ RELOADED sIDE V2.8 'CHIP' Prop_Ver G 200MHz 210401-1230
    I don't get a crash with this:-

    1. TAQOZ# ALIAS NOT invert ---  ok
    2. TAQOZ# 0 invert . --- -1  ok
    3. TAQOZ# -1 invert . --- 0  ok
    4. TAQOZ# 5555 invert . --- -5556  ok
    5. TAQOZ# -5556 invert . --- 5555  ok
    

    : invert NOT ; works the same. What's going on I wonder - are you using the same build? Maybe it has become corrupted? Does it crash only with certain values?
    Cheers, Bob

  • @bob_g4bby said:
    @"Christof Eb."

    So, I'm still using Parallax P2 TAQOZ RELOADED sIDE V2.8 'CHIP' Prop_Ver G 200MHz 210401-1230
    I don't get a crash with this:-

    1. TAQOZ# ALIAS NOT invert ---  ok
    2. TAQOZ# 0 invert . --- -1  ok
    3. TAQOZ# -1 invert . --- 0  ok
    4. TAQOZ# 5555 invert . --- -5556  ok
    5. TAQOZ# -5556 invert . --- 5555  ok
    

    : invert NOT ; works the same. What's going on I wonder - are you using the same build? Maybe it has become corrupted? Does it crash only with certain values?
    Cheers, Bob

    Sorry Bob, very strange.
    Yes, it is the same version. When I retried a few minutes ago, I could reproduce the problem at first. But not now any more.
    ??? Christof ???

  • @bob_g4bby

    Hi Bob,
    at the moment I will use "alias" with caution. I don't know what has happened.

    If you want to, you could improve the docu about:
    2/ ( u1 -- u2) It is unsigned in Taqoz, so perhaps u instead of n.

    dm* ( d1 u -- d2 ) As far as I found out here, the double argument is signed, but not the second single argument. If this is negative then there is a problem.

    Christof

  • @"Christof Eb." I've corrected 2/ and dm* and upissued the glossary. Thank you.

  • bob_g4bbybob_g4bby Posts: 411
    edited 2023-03-07 13:50

    @"Christof Eb." today I can't get this to work (although the very same code has worked in the past!)
    ALIAS >L WITH ( obj -- )
    but
    pub WITH >L ; (obj -- )
    works
    Does that prove or disprove "At the moment I believe, that ALIAS cannot be used for words, which execute from cog" . How do you tell when a word is located in COG, by the way?

  • @bob_g4bby said:
    @"Christof Eb." today I can't get this to work (although the very same code has worked in the past!)
    ALIAS >L WITH ( obj -- )
    but
    pub WITH >L ; (obj -- )
    works
    Does that prove or disprove "At the moment I believe, that ALIAS cannot be used for words, which execute from cog" . How do you tell when a word is located in COG, by the way?

    Hi Bob,
    had a look into the file taqoz.lst, which is in the ZIP. There you can search for ">L" and then LPUSH. The label LPUSH is at 0ac in cog memory.

    1f7ec     4c3e02           byte 2,  ">L"
    1f7ef     00ac             word PUSHL
    

    This is the dictionary entry.

                       ' >L ( n -- ) 33*
    008dc 0ac fc304615 PUSHL                wrlut   a,auxptr
    008e0 0ad fb8c2bdf              ijnz    auxptr,#DROP
    

    This is the assembler code.

    At the moment, I assume, that the problem has something to do with "C@ $E0 AND @WORDS C+!" in

    pre ALIAS   [C] NFA' [G] DUP CFA [C] CREATE$ @WORDS CPA!   C@ $E0 AND @WORDS C+! ;
    

    Christof

  • bob_g4bbybob_g4bby Posts: 411
    edited 2023-03-08 12:04

    I did a simple test this morning with ALIAS. I created 18 aliases of the word >L and dumped the header to check the CFA which should be 0ac every time:-

    ALIAS >L NO1
    NFA' NO1 20 DUMP
    ALIAS >L NO2
    NFA' NO2 20 DUMP
    ALIAS >L NO3
    NFA' NO3 20 DUMP
    ALIAS >L NO4
    NFA' NO4 20 DUMP
    ALIAS >L NO5
    NFA' NO5 20 DUMP
    ALIAS >L NO6
    NFA' NO6 20 DUMP
    ALIAS >L NO7
    NFA' NO7 20 DUMP
    ALIAS >L NO8
    NFA' NO8 20 DUMP
    ALIAS >L NO9
    NFA' NO9 20 DUMP
    ALIAS >L NO10
    NFA' NO10 20 DUMP
    ALIAS >L NO11
    NFA' NO11 20 DUMP
    ALIAS >L NO12
    NFA' NO12 20 DUMP
    ALIAS >L NO13
    NFA' NO13 20 DUMP
    ALIAS >L NO14
    NFA' NO14 20 DUMP
    ALIAS >L NO15
    NFA' NO15 20 DUMP
    ALIAS >L NO16
    NFA' NO16 20 DUMP
    ALIAS >L NO17
    NFA' NO17 20 DUMP
    ALIAS >L NO18
    NFA' NO18 20 DUMP
    

    This produced the following terminal output:-

    TAQOZ# ALIAS >L NO1 ---  ok
    TAQOZ# NFA' NO1 20 DUMP ---
    1C74C: 03 4E 4F 31  AC 00 07 4C  49 53 54 49  4E 47 D0 8C     '.NO1...LISTING..'
    1C75C: 84 41 53 4D  3A CC 8C 84  53 55 42 3A  C8 8C 06 46     '.ASM:...SUB:...F' ok
    TAQOZ# ALIAS >L NO2 ---  ok
    TAQOZ# NFA' NO2 20 DUMP ---
    1C746: 03 4E 4F 32  AC 00 03 4E  4F 31 AC 00  07 4C 49 53     '.NO2...NO1...LIS'
    1C756: 54 49 4E 47  D0 8C 84 41  53 4D 3A CC  8C 84 53 55     'TING...ASM:...SU' ok
    TAQOZ# ALIAS >L NO3 ---  ok
    TAQOZ# NFA' NO3 20 DUMP ---
    1C740: 03 4E 4F 33  AC 00 03 4E  4F 32 AC 00  03 4E 4F 31     '.NO3...NO2...NO1'
    1C750: AC 00 07 4C  49 53 54 49  4E 47 D0 8C  84 41 53 4D     '...LISTING...ASM' ok
    TAQOZ# ALIAS >L NO4 ---  ok
    TAQOZ# NFA' NO4 20 DUMP ---
    1C73A: 03 4E 4F 34  AC 8C 03 4E  4F 33 AC 00  03 4E 4F 32     '.NO4...NO3...NO2'
    1C74A: AC 00 03 4E  4F 31 AC 00  07 4C 49 53  54 49 4E 47     '...NO1...LISTING' ok
    TAQOZ# ALIAS >L NO5 ---  ok
    TAQOZ# NFA' NO5 20 DUMP ---
    1C734: 03 4E 4F 35  AC 8C 03 4E  4F 34 AC 8C  03 4E 4F 33     '.NO5...NO4...NO3'
    1C744: AC 00 03 4E  4F 32 AC 00  03 4E 4F 31  AC 00 07 4C     '...NO2...NO1...L' ok
    TAQOZ# ALIAS >L NO6 ---  ok
    TAQOZ# NFA' NO6 20 DUMP ---
    1C72E: 03 4E 4F 36  AC 8C 03 4E  4F 35 AC 8C  03 4E 4F 34     '.NO6...NO5...NO4'
    1C73E: AC 8C 03 4E  4F 33 AC 00  03 4E 4F 32  AC 00 03 4E     '...NO3...NO2...N' ok
    TAQOZ# ALIAS >L NO7 ---  ok
    TAQOZ# NFA' NO7 20 DUMP ---
    1C728: 03 4E 4F 37  AC 8C 03 4E  4F 36 AC 8C  03 4E 4F 35     '.NO7...NO6...NO5'
    1C738: AC 8C 03 4E  4F 34 AC 8C  03 4E 4F 33  AC 00 03 4E     '...NO4...NO3...N' ok
    TAQOZ# ALIAS >L NO8 ---  ok
    TAQOZ# NFA' NO8 20 DUMP ---
    1C722: 03 4E 4F 38  AC 8C 03 4E  4F 37 AC 8C  03 4E 4F 36     '.NO8...NO7...NO6'
    1C732: AC 8C 03 4E  4F 35 AC 8C  03 4E 4F 34  AC 8C 03 4E     '...NO5...NO4...N' ok
    TAQOZ# ALIAS >L NO9 ---  ok
    TAQOZ# NFA' NO9 20 DUMP ---
    1C71C: 03 4E 4F 39  AC 00 03 4E  4F 38 AC 8C  03 4E 4F 37     '.NO9...NO8...NO7'
    1C72C: AC 8C 03 4E  4F 36 AC 8C  03 4E 4F 35  AC 8C 03 4E     '...NO6...NO5...N' ok
    TAQOZ# ALIAS >L NO10 ---  ok
    TAQOZ# NFA' NO10 20 DUMP ---
    1C715: 04 4E 4F 31  30 AC 00 03  4E 4F 39 AC  00 03 4E 4F     '.NO10...NO9...NO'
    1C725: 38 AC 8C 03  4E 4F 37 AC  8C 03 4E 4F  36 AC 8C 03     '8...NO7...NO6...' ok
    TAQOZ# ALIAS >L NO11 ---  ok
    TAQOZ# NFA' NO11 20 DUMP ---
    1C70E: 04 4E 4F 31  31 AC 00 04  4E 4F 31 30  AC 00 03 4E     '.NO11...NO10...N'
    1C71E: 4F 39 AC 00  03 4E 4F 38  AC 8C 03 4E  4F 37 AC 8C     'O9...NO8...NO7..' ok
    TAQOZ# ALIAS >L NO12 ---  ok
    TAQOZ# NFA' NO12 20 DUMP ---
    1C707: 04 4E 4F 31  32 AC 00 04  4E 4F 31 31  AC 00 04 4E     '.NO12...NO11...N'
    1C717: 4F 31 30 AC  00 03 4E 4F  39 AC 00 03  4E 4F 38 AC     'O10...NO9...NO8.' ok
    TAQOZ# ALIAS >L NO13 ---  ok
    TAQOZ# NFA' NO13 20 DUMP ---
    1C700: 04 4E 4F 31  33 AC 00 04  4E 4F 31 32  AC 00 04 4E     '.NO13...NO12...N'
    1C710: 4F 31 31 AC  00 04 4E 4F  31 30 AC 00  03 4E 4F 39     'O11...NO10...NO9' ok
    TAQOZ# ALIAS >L NO14 ---  ok
    TAQOZ# NFA' NO14 20 DUMP ---
    1C6F9: 04 4E 4F 31  34 AC 8C 04  4E 4F 31 33  AC 00 04 4E     '.NO14...NO13...N'
    1C709: 4F 31 32 AC  00 04 4E 4F  31 31 AC 00  04 4E 4F 31     'O12...NO11...NO1' ok
    TAQOZ# ALIAS >L NO15 ---  ok
    TAQOZ# NFA' NO15 20 DUMP ---
    1C6F2: 04 4E 4F 31  35 AC 8C 04  4E 4F 31 34  AC 8C 04 4E     '.NO15...NO14...N'
    1C702: 4F 31 33 AC  00 04 4E 4F  31 32 AC 00  04 4E 4F 31     'O13...NO12...NO1' ok
    TAQOZ# ALIAS >L NO16 ---  ok
    TAQOZ# NFA' NO16 20 DUMP ---
    1C6EB: 04 4E 4F 31  36 AC 8C 04  4E 4F 31 35  AC 8C 04 4E     '.NO16...NO15...N'
    1C6FB: 4F 31 34 AC  8C 04 4E 4F  31 33 AC 00  04 4E 4F 31     'O14...NO13...NO1' ok
    TAQOZ# ALIAS >L NO17 ---  ok
    TAQOZ# NFA' NO17 20 DUMP ---
    1C6E4: 04 4E 4F 31  37 AC 8C 04  4E 4F 31 36  AC 8C 04 4E     '.NO17...NO16...N'
    1C6F4: 4F 31 35 AC  8C 04 4E 4F  31 34 AC 8C  04 4E 4F 31     'O15...NO14...NO1' ok
    TAQOZ# ALIAS >L NO18 ---  ok
    TAQOZ# NFA' NO18 20 DUMP ---
    1C6DD: 04 4E 4F 31  38 AC 00 04  4E 4F 31 37  AC 8C 04 4E     '.NO18...NO17...N'
    1C6ED: 4F 31 36 AC  8C 04 4E 4F  31 35 AC 8C  04 4E 4F 31     'O16...NO15...NO1' ok
    TAQOZ#
    

    showing that the alias NO4, NO5, NO6, NO7, NO8, NO14, NO15, NO16, NO17 are incorrect with a CFA of 18AC. It may be that ALIAS is buggy with certain memory addresses

    I'm suspicious of CPA! as all that C@ $E0 AND @WORDS C+! does is transfer the top 3 bits of the old name count to the new name count. These bits are used to signal the word is pub, pre or pri etc. The new word needs to match the old word, so it will behave the same.

  • bob_g4bbybob_g4bby Posts: 411
    edited 2023-03-08 13:33

    The word CPA! is to blame for ALIAS failing depending on where in memory the new word's name is. CPA! does the following, with no comments in the source as to why:-

    pub CPA! ( n nfa -- )   
    DUP                                     ( NFAold CFAold NFAnew NFAnew -- )
    $20 AND IF                              ( NFAold CFAold NFAnew -- )
        CPA M!                             --- finds CPAnew and stores only the bottom nonzero byte of CFAold
                                           --- and this produces an illegal CFA for the new word - as shown in the '18 ALIAS' tests
    ELSE
        CPA W!                             --- or finds CPAnew and stores both bytes of CFAold
    THEN ;
    

    Why is there a test on bit 5 of the new word's name field address? I'm going to ask Peter that one!

  • @"Christof Eb." There were bugs in the words ALIAS and CPA!. This code seems to work fine. I've tested it by making 20 aliases of the same word and checking that the cfa the word header contains were all the same and that the aliases run the same as the original word. Here's the replacement source code for ALIAS in file Extend.fth:-

    pre ALIAS
            [C] NFA' [G] ?DUP
            IF ( nfa )
    ---     read cfa then create new header & store cfa in its cpa
              DUP C@ $E0 AND SWAP CFA ( atrs cfa )
              [C] CREATE$
    ---      blend old atrs in with new count (also patch 230309)
              OVER @WORDS C@ OR @WORDS C!
    ---      then store the CFA into the new CPA as 2 or 3 bytes (atr.5)
              @WORDS CPA  ROT $20 AND IF M! ELSE W! THEN
            ELSE ERROR
            THEN
    ;
    

    Delete word PFA! in file Extend.fth, as it is no longer used. See if this works for you. You can either compile the new ALIAS over the old one, or reload your modified Extend.fth and then any other modules you use. Cheers, Bob

  • Hi @bob_g4bby
    thank you!
    As far as I understand M! does not overwrite any bytes in a long, which would be zero after write. I am not sure, if it's secure to leave some bytes whatever they are before???

  • bob_g4bbybob_g4bby Posts: 411
    edited 2023-03-09 18:31

    If you have a variable VAR1, which contains $12345678, and you execute $AB VAR1 M!, VAR1 now contains $123456AB
    If you have a variable VAR1, which contains $12345678, and you execute $ABC VAR1 M!, VAR1 now contains $12345ABC and so on ... the bottom n bits only get overwritten.

    So Peter uses it to alter the bottom bits of a 24-bit extended CPA field.

    I've upissued the glossary to include the ALIAS bug fix and a description of the dictionary. Feel free to comment.

  • Hi @bob_g4bby ,
    what gives me a "bad feeling" is this:

    TAQOZ#  ---  ok
    TAQOZ# long alpha ---  ok
    TAQOZ# $12345678 alpha ! ---  ok
    TAQOZ# $9900 alpha M! ---  ok
    TAQOZ# alpha @ .long --- 1234_9978 ok
    TAQOZ#
    

    I do not see, that a zero low byte of a code address is impossible?

    (((I don't understand, why Forth people don't use named local variables. This ALIAS word would be so much clearer....)))

    Thumbs up for your description of the dictionary! Great!

  • Christof Eb.Christof Eb. Posts: 1,195
    edited 2023-03-10 08:47

    @bob_g4bby
    "New word headers extend downwards in memory, usually located within the lowest 64k of RAM,
    although the dictionary can be relocated."
    In my system I have
    Code: $0000_0000 to $0000_B2FC
    Words: $0001_B8DB to $0001_FF97
    Do you really have this dictionary in the lowest 64k in your system? At least in the taqoz.lst, that I have, this in the second 64k. Otherwise it would be likely to be overwritten by code.
    I have had some look into the question, how these paged 24bit CFAs are handled. At the moment, I have some doubts if this feature was mature and tested very well. As far as I understand the compiler would need to compile "PAGE1" into a word that calls a word, which has got a 24bit code address.
    Did check it. At least as long the code does not overwrite the dictionary, the compiler seems to work for PAGE1.

Sign In or Register to comment.