Shop Learn
TAQOZ - Tachyon Forth for the P2 BOOT ROM - Page 36 — Parallax Forums

TAQOZ - Tachyon Forth for the P2 BOOT ROM

13132333436

Comments

  • Sorry chaps, it's my fault, I had the terminal set to send CR+LF instead of CR. SEE works fine now.

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2021-03-24 03:49

    I thought I'd share this post with you that I posted on a Forth group.

    Forth is a very productive "tool", and I say tool as I hate to say "language" because most people envisage a huge compiler and libraries hosted on a PC that spits out a binary blob for a target processor whereas embedded Forth is a living interactive language and runtime environment that is on and in the target processor. Even $1 chips these days have the resources to host a Forth dev environment.

    Now, here's the problem. I have tiny 8-pin PIC chips embedded in designs that are very useful for all kinds of little things and the chips are "cheap as chips". But I am very very tired of Microchip's tools growing ever more ginormous just to program an itty-bitty PIC in assembler. They also stop supporting older ICSP tools such as some of the PICkits etc but either way, those things are still awkward and tethered to a PC.
    Well, not no more. Forth to the rescue! Yesterday I wrote an ICSP and exerciser and today in between life I wrote an assembler that uses standard Microchip syntax etc. The day before I built the ICSP with a ZIF socket etc and mounted and wired it into one of my Propeller boards.

    I still need to add some finishing touches to it so that it is completely standalone in a production environment with a keyboard and VGA monitor but total code and dictionary is not worthy of Wiggins (Thinking Forth p66).
    Code bytes used = 614
    Name bytes used = 718
    Most of the dictionary usage is simply for the assembler mnemonics though.

    I plan to add a menu so production chips can just be programmed, verified and exercised with a touch of button and even timestamped and logged as well as burn a serial number etc. The files are stored on the SD card and in addition there are other programs too, some using the RS232 and RS422/485 ports for testing datacomms products and displaying the analysis on the monitor.

    Oh, I mentioned an assembler and source code will be on this standalone Forth PC with a 2k block editor for the assembly source code files so no longer will I need to download hundreds of megabytes and wrestle with it to make it work.
    Remember ----- Use the Forth
    I will be away for the next few days but I want to have it finished for Monday so I will post photos by then!

    In the meantime here's a photo of what I am currently using, just a really old prototype that I removed my LAN module from and added in this little stick out burner on instead. I can slot it back into the metal case when I'm done but I will add a small IDC cable to the top right for the VGA and PS/2 signals.

  • You made my day !
    Just yesterday I was looking at these newer pic18 chips and thought how nice would it be to have Forth running on them. So many cool things could be done with them cheaply and very conveniently with Forth. Lots of these chips are still available in DIP packages so it could attract some old style hobby audience. And many of these pic18's are 5V and very capable too.

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2021-03-24 07:59

    @Maciek said:
    You made my day !
    Just yesterday I was looking at these newer pic18 chips and thought how nice would it be to have Forth running on them. So many cool things could be done with them cheaply and very conveniently with Forth. Lots of these chips are still available in DIP packages so it could attract some old style hobby audience. And many of these pic18's are 5V and very capable too.

    No, it's not Forth on the PIC chip, it's Forth to assemble PIC source code and burn it into a chip. The PIC ISA is ugly but the chips are cheap and reliable. Who cares if about the instruction set. The PIC18 may be more capable perhaps but for the same price I can pick 100MHz+ RISC-V chips and the distributor TME is right there in Poland too. Now, that is a chip I would have Tachyon running on.

    That PCB has a P1 on it.

  • MaciekMaciek Posts: 314
    edited 2021-03-24 08:27

    @"Peter Jakacki" said:
    ...
    No, it's not Forth on the PIC chip, it's Forth to assemble PIC source code and burn it into a chip.The PIC ISA is ugly but the chips are cheap and reliable. Who cares if about the instruction set. The PIC18 may be more capable perhaps but for the same price I can pick 100MHz+ RISC-V chips and the distributor TME is right there in Poland too. Now, that is a chip I would have Tachyon running on.

    I stand corrected then. Thanks, but honestly, having been freed from that Microchip compiler/IDE/programmer nuisances and a real PC dependency is a huge step forward.

    As a side note, I have an account at TME and have bought from them a few times in recent years but somehow I keep ordering from Mouser (for parts selection) and for the delivery (times and prices) nobody could ever beat Farnell, if I wanted something urgently.

  • Nice one Peter. Being Australian and using Forth go hand in glove. Resourceful engineer sees a need and creates tool to meet an immediate problem with minimum of fuss, effort and memory.

  • bob_g4bbybob_g4bby Posts: 222
    edited 2021-03-24 10:01

    Maciek,

    On the topic of forth on a shoestring, I went to the trouble of etching my own pcb for a 16F84 programmer for this forth system. This chip had 1k of 14 bit instructions in flash, 64 bytes of EEPROM and 68 bytes of RAM, so no room for a conventional forth tool, but there was room for an umbilical forth, where 99% of the tool is PC based and 1% is on the microcontroller, linked by a 1 wire interface. Notable features:-
    1. The PIC had to be preprogrammed with a permanent tiny bootloader - it had 3 forth 'words' in it - program a byte sent to the micro, read a programmed byte and execute from an address
    2. If a word was typed that wasn't in the micro, then it was programmed in, along with any word that was needed by that word, recursively - then it executed
    3. Small words were loaded in-line, larger words were called, so it executed fast
    4. There was a multitasker module which I tried - you could write code for as many 'independent' tasks as you wanted a bit like the propeller.
    5. You could write interrupt routines in forth - I read a rotary encoder with it, for radio tuning purposes
    6. It had an #include function for libraries. However, only the words you actually had used in your application got loaded
    7. The programmer was gentle. If the byte to be programmed was already the right value, it was not reprogrammed, thus prolonging the life of the flash memory.
    8. In use, it felt like writing code on a normal forth system. Underneath, it was incrementally writing assembler subroutines to the 16F84 with much communication to and fro the PC and 16F84.
    9. The system supported many different PIC and some Atmel chips
    This has been up for sale for years, but i doubt it will get sold now. It's a shame, as it was a very neat solution, just like Peter's minimalist assembler.

    As well as starting to learn Taqoz, I've been constructing a 100W chinese linear amplifier, cheap from ebay. At the moment it doesn't think it's an amplifier - it's oscillating away at some vhf or uhf frequency my 'scope couldn't see, but a schottky diode detector could. So over the next few days (when the garage workshop is warmed enough by the sun) I'll be trying to calm the little chap down.

  • Bob,

    When it comes to Forth on a lowly micro I'm a big fan and admirer of this guy's superb work. Also this might interest you as well.
    The problem with small micros is that they get more and more expensive when compared with much more capable ones and, save for the smallest ones, it almost makes no sense to use them any more. The low power advantage is gone, the 5V capability is gone, the small pin count is gone too. I mean, the more capable ones have these features as well and much more for only slightly increased price (and that is not always true).

    Taqoz is a league for itself and I am learning it as well these days albeit with slower than I would like progress (too many things on my hands professionally and so little quality hobby time). It, combined with the P2, is such a powerful tool I'm really surprised it struggles to gain the user base it deserves. But as long as it server me and Peter, its author, and maybe a few others too, I don't really care.

    I think the hardest part for the newcomers is to drop their current habits and start thinking differently, with the full control over the given micro at their disposal right on that very chip and not to be tied to the libraries, IDEs and compilers.
    Maybe I am an old prune not following the latest trends and technologies but I much prefer to actually know and understand how things work than be left at the mercy of some library author that I'm supposed to trust (really, it's not about the authors, it's about the libraries that depend on other libraries that in turn make use of other libraries too that makes it almost impossible to follow and analyze).

  • Interesting two forths, those , one standalone, one tethered. OK, the Spring sunshine has warmed up the garage enough to be tolerable, so I'm off amplifier-taming.

  • bob_g4bbybob_g4bby Posts: 222
    edited 2021-04-02 16:38

    Installing Taqoz Reloaded v2.8 on the SD card of a P2-EVAL from a Windows computer - I found this worked reliably:-

    1. Download the Tachyon Forth from the Cloud dropbox
    2. Unzip it to a folder
    3. Set the 'Flash' dip switch on the P2-EVAL, reset P59^ and P59v. USB RES stays set.
    4. Download the flexprop tool and unzip it to a folder
    5. Run flexprop and in Ports set 921600 baud and the com port your P2 is connected on
    6. Using flexprop, send file taqoz.bin from folder Tachyon dropbox April 2021\P2\TAQOZ to the P2 with Flash binary file found in the Commands menu - it only takes a second or so as shown by just three lines on the Propeller Output window.
    7. Shut down flexprop
    8. Start tera term and set Serial port to the port your P2 is connected to, 921600 baud, 8 bits, no parity, 1 stop bit, no flow control. Set Terminal to CR for New-line on Receive and Transmit, no local echo, terminal VT-100
    9. Press the reset on the P2-EVAL, you should get this start up message from Taqoz v2.8:-
    þxQOZ#
      *Cold start*
    -------------------------------------------------------------------------------
      Parallax P2  *TAQOZ RELOADED sIDE*  V2.8 'CHIP' Prop_Ver G 200MHz 210401-1230
    -------------------------------------------------------------------------------
    TAQOZ#
    
    1. Using tera term, upload to Taqoz files EXTEND.FTH and FILES.FTH from folder Tachyon dropbox April 2021\P2\TAQOZ\Forth Check they compile with no errors. You might decide to upload others, such as P2ASM.FTH for writing new Taqoz words in assembly code
    2. Format a Sandisk SD card on Windows using SD Card Formatter with Overwrite format set. (Other makes have been found to work) Insert newly formatted SD card into the P2-EVAL
    3. At the Taqoz prompt, type BU enter to backup the tool set to the SD card - this takes around 2 s
    4. Reset the FLASH dip switch, so that the P2 will boot from SD card next time
    5. Reset the P2, the following start up message should then appear in tera term:-
    þBOOTING....  CARD: SANDISK   SD SD32G REV$85 #3200344782 DATE:2021/1
    KERNEL            Parallax P2  *TAQOZ RELOADED sIDE*  V2.8 'CHIP' Prop_Ver G 200MHz 210401-1230
       MODULES:
       4890 *P2ASM*         TAQOZ INTERACTIVE ASSEMBLER for the PARALLAX P2 - 210124-1200
       2726 *DISK*          SD DISK REPORTING & FORMATTING TOOLS 190800-0000
       5042 *FILE*          TAQOZ FAT32 FILE SYSTEM for SD CARD plus VIRTUAL MEMORY  210128-0830
       1644 *SPIRAM*        LY68L6400 8MB SPI RAM ACCESS 191020-0000
       1766 *DECOMPILER*    A decompiler for TAQOZ 190825-0000
        822 *UBI2C*         EFM8UB3 I2C COMMANDS 210118-0000
        614 *RTC*           RV-3028 RTC DATE and TIME 190800-0000
        882 *SMARTPINS*     SMARTPIN FUNCTIONS and drive modes 190800-0000
        382 *P2CLOCK*       P2 CLOCK CONTROL 190800-0000
       2572 *ANSI*          ANSI TERMINAL SUPPORT 200410-0000
        434 *EXTEND*        Primary kernel extensions for TAQOZ 210128-0830
       5990 *SPIFLASH*
    MEMORY MAP
      CODE:         08CD6  36,054 bytes
      WORDS:        1C752  14,405 bytes
      DATA:         01EF2  1,368 bytes
      ROOM:                80,508 bytes
    HARDWARE
      PCB           P2
      CLOCK IN      20.000000MHZ
    DEVICES
      SD CARD       31 GB  SANDISK   SD SD32G REV$85 #3200344782 DATE:2021/1
    I2C DEVICES
    STATS           cpufreq: 200MHz  systicks: 1,444
    -------------------------------------------------------------------------------
    TAQOZ#
    
    1. Taqoz is now installed on SD card, although it won't appear in the directory as a filename
    2. Other files can be loaded onto the SD card - and they will be listed with the Taqoz DIR or DIRW command
    3. Although written for the Taqoz ROM toolset, this glossary might be useful to start programming in Taqoz v2.8
    4. These links are useful
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2021-04-01 15:12

    Or you can load _BOOT_P2.BIX onto the SD CARD which is the easiest way. Alternatively load it serially into the P2 and backup from there.

    Backup options are:
    BACKUP filename
    BACKUP BIX which will backup to the _BOOT_P2.BIX file. If it does not exist then it will create one.
    BACKUP MBR (BU or ^B) which will backup to sector 1 and set the boot signature in the MBR (Assumes you have a properly formatted SD card with unassigned storage before the first partition.
    BACKUP FLASH (or ^F) will write a bootloader to Flash page 0 and then the 128k TAQOZ image
    BACKUP DISABLE will disable Flash and MBR booting only - if you want to disable the BIX file then RENAME it i.e. RENAME _BOOT_P2.BIX _BOOT_P2.BIN

  • Cluso99Cluso99 Posts: 17,772
    edited 2021-04-01 20:46

    IIRC TAQOZ can also reformat an SD card too.

    And yes, much easier to copy the binary to the SD as _BOOT_P2.BIX

  • bob_g4bbybob_g4bby Posts: 222
    edited 2021-04-01 22:13

    I agree _BOOT_P2.BIX is the simplest, but it comes with everything. Starting from the kernel alone allows the programmer to choose relevant modules. ( Just now I don't need RTC, serial RAM, VGA, Multimedia support etc)

  • @bob_g4bby - even with all those "extra" modules TAQOZ still takes up less than 64kB total including the full dictionary so I wouldn't have thought having these extras a load on the P2 resources. The P2 has 8 cogs that we rarely use yet they are there if and when we need them. So too likewise the extra software support.

    Now Bob, you have successfully coaxed the Si5351 into generating various frequencies and what I haven't done yet for the P2D2 is to be able to dial up a frequency from the clock input rather than via the internal PLL, which btw, I have still not implemented fully either. What do you reckon your chances are of being able to get this to work? Buckley's or Bob's?

  • @bob_g4bby said:
    I agree _BOOT_P2.BIX is the simplest, but it comes with everything. Starting from the kernel alone allows the programmer to choose relevant modules. ( Just now I don't need RTC, serial RAM, VGA, Multimedia support etc)

    Yes, yes, yes, that should be the way to go.

  • @dnalor said:

    @bob_g4bby said:
    I agree _BOOT_P2.BIX is the simplest, but it comes with everything. Starting from the kernel alone allows the programmer to choose relevant modules. ( Just now I don't need RTC, serial RAM, VGA, Multimedia support etc)

    Yes, yes, yes, that should be the way to go.

    But why ?
    The resources are there and in excess. The features are there for you to decide if you like/need to use them or not. My approach would be to only shave off the excess feature if it gets in a way and surprisingly it doesn't in the case of the TAQOZ in any reasonable way I can imagine. It's like having that extra gear in your car that already is present at no extra cost - you may not use it at all but when you need it, you have it because it's there.

  • Just testing out some old routines and making sure the framebuffer grab was working correctly.

  • ErNaErNa Posts: 1,583

    @Maciek said:

    @dnalor said:

    @bob_g4bby said:
    I agree _BOOT_P2.BIX is the simplest, but it comes with everything. Starting from the kernel alone allows the programmer to choose relevant modules. ( Just now I don't need RTC, serial RAM, VGA, Multimedia support etc)

    Yes, yes, yes, that should be the way to go.

    But why ?
    The resources are there and in excess. The features are there for you to decide if you like/need to use them or not. My approach would be to only shave off the excess feature if it gets in a way and surprisingly it doesn't in the case of the TAQOZ in any reasonable way I can imagine. It's like having that extra gear in your car that already is present at no extra cost - you may not use it at all but when you need it, you have it because it's there.

    Is there a misunderstanding on the way: I interpret denalor: take the binary and use what you need whenever you need it, memory constrains are no longer an issue. And I interpret Maciek the same way?

    My believe is: we need uniform hardware as the war is lost because of minor reasons. And if I stumble over a changed pin number, I stumble any way and may give up. MS-Dos was successful because there were stringent rules as Gates gave a licence only to OEMs, while DR-Dos was modified by every single implementor. It's a pity, the P2D2 is not available to the public yet and I hope it will before much more simple, but less powerful designs are around! There's a company in Swiss that once made Swiss Army knives and only those knives.

  • MaciekMaciek Posts: 314
    edited 2021-04-02 09:34

    And I thought dnalor meant (same as bob-g4bby) to just start with the kernel and add to it as need arises. Nothing wrong with that and it has many advantages but having more instead of less, in this particular case, has even more advantages imho :).

    And when it comes to the universal hardware platform I think this topic deserves a separate thread as I see many people have different ideas of what exactly such a platform should be. For my needs the most universal hardware platform is obviously the P2D2 with the KISS board from @ManAtWork being a close second.

  • bob_g4bbybob_g4bby Posts: 222
    edited 2021-04-02 09:44

    Peter, good idea, I'll have a go converting the si5351 driver to Taqoz over the next week or so. 'Buckley's chance' - I had to look that one up - like 'vanishingly small chance' - nice one, just about sums up my programming ;-)

  • @bob_g4bby said:
    Peter, good idea, I'll have a go converting the si5351 driver to Taqoz over the next week or so. 'Buckley's chance' - I had to look that one up - like 'vanishingly small chance' - nice one, just about sums up my programming ;-)

    I think you've got Bob's chance there mate. You are a seasoned and resourceful man who gets the job done. Sometimes you might be up to armpits in it, but have no fear, Bob is here!

    @Maciek - yes, what dnalor said could be taken either way but what I know for sure is that I know nothing. But that's something, isn't it? :wink:

  • ErNaErNa Posts: 1,583

    @"Peter Jakacki" said:
    @Maciek - yes, what dnalor said could be taken either way but what I know for sure is that I know nothing. But that's something, isn't it? :wink:

    As you say it: as we gain more and more knowledge we have to "ZIP" old knowlegde. So the path to knowledge has some steps: I know something, I know everything, I know everything better, I know, I don't know everything better, .., I know I know nothing. The moment you reach the third level you are qualified to be a university professor.

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2021-04-07 07:33

    I had opportunity today to compare TAQOZ against a fast Forth I wrote back in 2005 for the ARM7TDMI-S ISA on the LPC2148. This Forth produced compact bytecode which was still fast. The test unit I used was an LPC2148 running at 66MHz and the P2D2 running at 340MHz but I also compared results when the P2 was scaled back down to 66MHz. First test was an empty loop and I kept the code identical on both. Since the ARM Forth didn't have the equivalent LAP timing tools but did have MS@ to read the current millisecond timer, I simply created an alias for GETMS and use this.
    First the ARM.

    .VER
    ARM7 IVOS - 1.0b Peter Jakacki  (Nov  2 2006-00:06:37)
    Copyright 2005 Peter Jakacki
     ok
    DECIMAL  ok
    : DEMO MS@ 1000000 0 DO LOOP MS@ SWAP - . ;  ok
    DEMO  2028 ok
    SEE DEMO                                      ....
    --------------------------------------------------
    4000.0800: LFA    0001.E869
    4000.0804: ATR    FF
    4000.0805: NFA    44 45 4D 4F 00 00 00
    4000.080C: CFA    E1A0E00F 0FE1A0E0
    --------------------------------------------------
    * LONG CALL TO FORTH INTERPRETER *
    
    4000.0814: FD 201B        MS@
    4000.0817: E2 000F.4240   LIT32
    4000.081C: 00             0
    4000.081D: 2B             (DO)
    4000.081E: F8 FF          (LOOP) <4000.081E
    
    4000.0820: FD 201B        MS@
    4000.0823: 59             SWAP
    4000.0824: 66             -
    4000.0825: C5             .
    4000.0826: FF             EXIT
    

    That took 2,028ms to run 1 million empty loops and 19 code bytes + 8 for the CFA = 27.

    Now the P2.

    TAQOZ# .VER ---   Parallax P2  *TAQOZ RELOADED sIDE*  V2.8 'CHIP' Prop_Ver G 340MHz 210401-1230
     ok
    TAQOZ# : DEMO MS@ 1000000 0 DO LOOP MS@ SWAP - . ; ---  ok
    TAQOZ# DEMO --- 95  ok
    TAQOZ# SEE DEMO
    1B834: pub DEMO
    0B42E: 0FF4     MS@
    0B430: 0083     := 131
    0B436: 1800     0
    0B438: 10BC     DO
    0B43A: 0143     LOOP
    0B43C: 0FF4     MS@
    0B43E: 00A4     SWAP
    0B440: 00BB     -
    0B442: 2B6F     . ;
          ( 22  bytes )
    

    This took 95ms and used 22 code bytes (TAQOZ has an implied CFA). So that's 21 times faster but scaled back down to 66MHz it is still 4 times faster than the ARM.

    I did the same test for the Fibonacci routine and had to run a loop of 10,000 times 46 fibo and ARM took 507us/loop while TAOQZ took 10us/loop.
    So the P2 is 50 times faster while TAQOZ itself is 10 times faster than the ARM Forth at the equivalent clock speed, and we still have 7 more cogs.

    This vindicates the ideas I incorporated into TAQOZ such as the use of wordcode rather than bytecode, and also many other things including the implied CFA as normally Forth has a code field address at the start of the "parameters" that has the address of code to execute the parameters, but I just assume that the parameters are already (and mostly) wordcode. If I want it to do something different then the first wordcode calls something to make it different.

    Even just the interactive "always compile" makes testing code a breeze on TAQOZ because I don't have to define a temporary word and then invoke it everytime etc.

    BTW, I loved the ARM before this Cortex stuff which seems to have been a response to C compilers always running out of memory. Before that I could use the full 32-bit instruction and any register etc and I/O was I/O, not bit-banding hardware etc. Now ARM initialization or even CMSIS is another complicated kludge itself.

  • Cluso99Cluso99 Posts: 17,772

    Very interesting results Peter!
    We knew the P2 was good, now we know how good :)

  • One thing worth mentioning is that these figures compare a 16 year old ARM7 micro with, say, a year old one core (out of eight custom cores), both running clever, custom FORTH.
    How about a P2 C/BASIC against P2 TAQOZ ?
    Or, maybe not :) .

  • @Maciek said:
    One thing worth mentioning is that these figures compare a 16 year old ARM7 micro with, say, a year old one core (out of eight custom cores), both running clever, custom FORTH.
    How about a P2 C/BASIC against P2 TAQOZ ?
    Or, maybe not :) .

    Well that's why I scaled the clock speed and 32-bit ARM vs a single 32-bit P2 core with both running an optimized Forth and yet the P2 with TAQOZ performs 4 to 10 times better.
    As for comparing other languages I reckon the only real test is running actual applications rather than benchmarks or demo code.

  • Is there a 2.8 SD card image released yet? Also is there a way to dial back the clock rate? retroprop2 gets a bit hot to the touch after a while.

  • MaciekMaciek Posts: 314
    edited 2021-04-08 07:17

    @"frank freedman" said:
    Is there a 2.8 SD card image released yet? Also is there a way to dial back the clock rate? retroprop2 gets a bit hot to the touch after a while.

    Yes to both. Take a look here.
    To change the clock frequency just type the desired frequency (in multiple of 20 MHz) at the TAQOZ command prompt like this:
    (hit ENTER after clkfreq!)

    That's it. Your P2 runs at 200 MHz now :)

  • @"Peter Jakacki" said:

    @Maciek said:
    One thing worth mentioning is that these figures compare a 16 year old ARM7 micro with, say, a year old one core (out of eight custom cores), both running clever, custom FORTH.
    How about a P2 C/BASIC against P2 TAQOZ ?
    Or, maybe not :) .

    Well that's why I scaled the clock speed and 32-bit ARM vs a single 32-bit P2 core with both running an optimized Forth and yet the P2 with TAQOZ performs 4 to 10 times better.
    As for comparing other languages I reckon the only real test is running actual applications rather than benchmarks or demo code.

    ((A recent controller ARM M0 @125MHz with ATLAST-Forth does need 110µs for one 46 fibonacci loop of 10000 (4µs with pure Arduino C). A recent M7 @600MHz needs 10usecs with ATLAST (0,2µs with pure Arduino C) .))

    I have made the experience, that these interactive languages indeed have a great benefit during development. You can always easily test small snippets of code and therefore you always make small steps of progress. This applies to Micropython too. Micropython is much more convenient than Forth indeed. But the penalty of speed of Micropython against Forth is heavy. Even a portable Forth, (ATLAST) written in C, is about >4 times faster than Micropython.

    Microcontrollers have these days just the right power for Forth I think. For larger acceptance portable libraries would be needed. And (we had discussed this already) for better readability local variables are necessary.

  • People will use whatever suits them best or they feel comfortable with or they are made to use for the client has a certain request. Having a choice is good. However, making the right choice is not always obvious at the beginning and sometimes not even at the end :) .

Sign In or Register to comment.