Shop OBEX P1 Docs P2 Docs Learn Events
Catalina 2.6 - a FREE C compiler for the Propeller - The Final Frontier! - Page 14 — Parallax Forums

Catalina 2.6 - a FREE C compiler for the Propeller - The Final Frontier!

1111214161720

Comments

  • RossHRossH Posts: 5,573
    edited 2010-11-09 09:12
    Hi Dr_Acula,

    You're not comparing the right versions of the files. The one I based the SIO plugin on is Chip's version (v1.2). I have attached it, and also removed some debugging code I had left in my version to make the comparison easier.

    You really have to compare the SPIN and PASM (DAT) parts separately. The SPIN stuff will always be significantly different. A plugin can only ever use SPIN during initialization, and the initialization code has to pass different parameters. Also, some drivers have significant functionality implemented in SPIN (not in this case, but true in some of the video drivers - and such functionality has to be compleletly re-written for Catalina).

    As to the PASM differences, in this particular case, I added some functionality to make it possible to enable/disable the driver. Discounting this, there is only one difference between my "plugin" version of driver and Chip's - i.e. the way the initialization is handled, and the fact that it uses the registry.

    But you're probably right that at this point only I could easily turn an OBEX driver into a plugin - there is no standard for the way Propeller drivers are written which means every case you look at has some peculiar quirks. At some point I probably should document the process (as well as the registry itself) a bit better.

    Ross.
  • RossHRossH Posts: 5,573
    edited 2010-11-09 14:29
    Paxi wrote: »
    Thnx for the quick reply Ross.

    I already took a look at the documentation and I know how to acces the special register itself. Probably there is still some kind of missunderstanding from my side but the problem is not to access the special registers itself but rather what address to load into the register (depending on what is needed)
    My understanding of embedded programming is not as good so it´s a bit hard for me to put a clear question but i will try to with an example:

    To access the DebugLed I also had to know the adress of itself.
    The adress is 0x00000001;
    so i set _dira(0x00000001, mask)
    and set it to output _outa(0x00000001, mask)
    while the mask specifies the bits i want to set.

    So i knew that the DebugLed uses the adress 0x0000001 because it was written in the Manuel i got with my Propeller.
    But where do i get the adress for other "registers" i need for the gamepad drivers, f.e. the DATA or CLK or LATCH. These are no special registers as i understood correctly and can be loaded into _dira(addressof(....), mask); but where do i know their adress?

    Thanks in advance

    Hi Paxi,

    0x00000001 is not an "address" as such - it's the bit number in the DIRA (and INA and OUTA) registers. Each bit in these registers corresponds to an I/O pin on the Propeller. In this case 0x00000001 = bit 0 = pin P0.

    The pin numbers used for a specific purpose will depend on the board you are using, and should be listed in your documentation. For example, you ae correct that a debug LED is sometimes connected to P0 (at least it is on the Hydra and Hybrid boards, and possibly on some others).

    Catalina only knows specifically about pin numbers where they are used in various drivers (e.g. video, keyboard). When using the other pins, you must be careful not to affect the pins dedicated to such purposes. This is the purpose of the "mask" parameter - it helps you avoid accidentally affecting other pins.

    What Propeller board are you using? I can probably point you to a list of what the I/O pins are used for on that particular board.

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-09 14:31
    Ah, yes it is complicated.

    Right now, the basic building blocks I need for the dracblade are keyboard, kyefat32 sd card, hi res vga, two serial ports in one cog, and hybrid ram access/LCD latch code. On a new board design coming out soon, I'll also be adding mouse and a parallel port.

    These all exist in CP/M, so the code is written, but it isn't compatable with Catalina.

    So without all these, C programming is somewhat limited.

    So right now I guess the best way is to send you the working code from CP/M and ask if it can be translated into the Catalina plugin format.

    But if the plugin format can be documented, maybe we can all pitch in and write some plugins. I know all this takes time, but I think there are distinct advantages in standardising the plugin code. Possibly even to the point that it can be added to the obex, either in the C category, or in a new plugin category?
  • RossHRossH Posts: 5,573
    edited 2010-11-09 16:24
    Dr_Acula wrote: »
    Ah, yes it is complicated.

    Right now, the basic building blocks I need for the dracblade are keyboard, kyefat32 sd card, hi res vga, two serial ports in one cog, and hybrid ram access/LCD latch code. On a new board design coming out soon, I'll also be adding mouse and a parallel port.

    These all exist in CP/M, so the code is written, but it isn't compatable with Catalina.

    Hi Dr_Acula,

    keyboard, sd card, hi res vga, ram access and mouse are already available.

    I will have a look at the serial port driver you want to use - I always intended to add more generic serial port access to Catalina (the SIO plugin you looked at was written mainly for internal use - the PC HMI plugin is how Catalina programs usually access a serial port, but this only supports one port accessed via stdin and stdout).

    Parallel port I'm not so sure about - who uses a parallel port these days? And think of how many pins it would consume on the Prop! You might be better off using a serial to parallel port adaptor - you can buy these off the shelf, or build your own. But send me some specs on how you want to use it and I'll have a look. If you could provide me an existing SPIN or PASM implementation then it would speed things up.

    There's nothing I can do about the code incompatibility issues - C does not specify how such devices should appear to application programs (other than files or devices that can be accessed by redirecting stdin/stdout) - so this is always going to be platform-specific and completely non-portable.

    However, if I provide a working example, you can always modify this to make your devices appear however you want.

    I will document (with examples) the Catalina registry and plugins as I get time.

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-09 19:22
    Hi Ross,

    You know, most kids, when they get a new toy, they play with it for a while and then put it on the shelf.

    I'm not like most kids! I pull the toy to bits to see how it works, and then I rebuild it to do something else. My parents once gave me a radio controlled car and I ripped out the receiver and gave it some new smarter brains. Then it roved around the house seeking noise and light (party mode) or seeking dark (cockroach mode).

    I tell this story so you understand when I want to get inside Catalina and find out how it works from the inside. And I do that partly so others will find it easier to use. The 'one click IDE' is part of that goal and ultimately I'd like to showcase Catalina on Instructables and Make.

    Ok, dual serial port in one cog - if you can do that it would be fantastic. I know it can be done with two cogs, but cogs are precious and if we can save one with code that is already done, I'm sure someone will think of something we can do with that cog.

    The LCD code. This is specific to the dracblade, and it is wrapped up with the memory access code and has to be run by the same cog. In my quest to pull Catalina to bits I tried to find the XMM memory access code but it is eluding me for the moment.

    Attached is some code. I've also attached a schematic so it makes sense. This is a board I'm having made at the moment, and when it is done I'll send you a freebie soldered up one. So - maybe hold off writing any code for the moment (except for the serial code, which I think you can do with hardware you already have??).

    The code is from Cluso's triblade code, and it was the first propeller code I ever saw that didn't rely excessively on spin glue code. He passed some very simple parameters to a cog, and the cog spent all its time waiting for those parameters. I think you use a similar concept with rendevous points. It is a brilliant concept, but rarely used in the Obex.

    You can see on the schematic I've added some more latches. So the raw pasm code is going to be toggling the 138 lines and toggling the data lines. I think it will be easier to test once the board is done, but it is going to be very similar to this code fragment:
    OutputHighLatch ' sends out HighLatch to the 374 that does A16-19, led and the 4 spare outputs
                            mov     dira,latchdirection     ' setup active pins 138 and bus
                            mov     outa,HighLatch          ' send out HighLatch
                            or      outa,HighAddress        ' or with the high address
                            andn    outa,GateHigh           ' set gate low
                            or      outa,GateHigh           ' set the gate high again
    OutputHighLatch_ret     jmp     #tristate               ' set pins tristate
    

    except that the variable "HighAddress" which is
    HighAddress             long    %00000000_00000000_00001001_00000000 ' high address latch = xxxx100x and gate high xxxxxxx1                                          
    

    will change to xxxx101x for the LCD, xxxx110x for the parallel port and there will be a read to xxxx111x for the HC244.

    One will need to talk to this cog and give it commands. Currently, Cluso's commands are things like
       long  command, hubaddrs, ramaddrs, blocklen, errx, cog ' rendezvous between spin and assembly (can be used cog to cog)
    '        command  = R, W, N, F H =0 when operation completed by cog
    

    and so if I understood your rendevous protocol, maybe I could have a go at changing this code?

    Where is this all heading?

    Well, I'd like to see a C platform for the propeller that is really easy for a beginner to use. I'd like to have the software as simple as possible, and I'd like the hardware to be something that can be soldered by people who can no longer focus on the end of their nose!

    As you quite rightly point out, sd routines take a lot of space in C, and so it probably is fair to say that for serious coding, if you want an sd card you need external memory.

    I've had a few versions of the dracblade that have been a bit flaky with external memory, so even though I've been up to version 8, I've gone back to the stable version 5 and left the layout of the ram and latch chips the same.

    I think there is demand for a mouse, so I added that with a jumper to select mouse or the second serial port.

    There are pads for three different types of regulators for each voltage, for those that don't want the hassle of switching regs.

    I put in TV and VGA resistors, and so in the IDE I intend putting in a radio button so you can easily compile with one or the other (Catalina command line switches are easy to build on the fly in vb.net)

    The parallel port is maybe a bit legacy, I agree. Perhaps consider it 16 lines of generic digital output, and 8 lines of generic digital input.

    I've also put in a large prototyping area. The board is a eurocard size 160x100mm. The board is laid out in sections, so you can build the minimal propeller/eeprom section, then add other parts as required.

    I'm sure it isn't the perfect solution, but it is version 9 and I've learn't a lot along the way. Subtle things, like keeping the VGA lines short to minimise flicker on the screen. And cunning things, like Pullmoll using a BC557 instead of a BC547 for the reset transistor.

    Thanks ++ for reading this. I'm where I am because I ran out of space in CP/M for sbasic, and then very quickly ran out of space for C as well (48k). I'm excited about a platform for C that has 512k of memory, can be built with parts you can buy and solder easily, and can drive a VGA and a keyboard and an SD card and a little LCD display and turn leds on and off. Dare I say it, but I think we might be close to something that might beat Arduino?
  • RossHRossH Posts: 5,573
    edited 2010-11-09 19:39
    Hi Dr_Acula,

    Happy to help all I can (and as time permits). I'll have a look at your code for the LCD. I share your goal of an easy to use C-based platform for both hobbyist and professional use.

    As to the XMM code, this is embedded in the kernel, and duplicated in many of the other target files (since there is no 'include' capability for PASM, the code has to be explicitly copied wherever it is needed).

    Primarily, it is in Catalina_XMM_Input.spin - which is the XMM kernel itself. Look in that file and search for DRACBLADE. You will find the following code, which is included when the DRACBLADE symbol is defined on the command line (you will also see similar code for all the other supported platforms):
    #elseifdef DRACBLADE
    '
    '------------------------- DRACBLADE XMM Support Routines -----------------------
    '
    ' XMM_Activate : Activate the XMM bus - set Pin directions, and latch for Read
    '
    XMM_Activate
                  mov     outa,ram_MUX              ' disable mux (latch is active low)
                  mov     dira,ram_dir_read         ' set direction bits for read
    XMM_Activate_ret
                  ret
    '
    'XMM_Tristate : Give up the XMM bus. To reactivate, call XMM_Activate
    '            
    XMM_Tristate
                  mov     dira,#0                   ' all inputs
                  mov     outa,#0                   ' and all zero
    XMM_Tristate_ret
                  ret
    '
    #ifdef NEED_XMM_READLONG              
    '
    '
    ' XMM_ReadLong : Read long from XMM at address in XMM_Addr into the destination register
    '                set up in XMM_Dest. XMM_Activate should be called at least once before
    '                this routine is used.
    ' On entry:
    '    XMM_Addr : address to read (up to 21 bits)
    '    XMM_Dst  : destination of this instruction set to destination register
    ' On exit:
    '    XMM_Addr and XMM_Page set up for fast access. XMM_Addr incremented by 4.
    '    Destination register contains long read from XMM.
    '
    '
    ' XMM_ReadMult : Read multiple bytes in source register to XMM at address XMM_Addr.
    '                XMM_Activate should be called at least once before this routine is used.
    ' On entry:
    '    XMM_Addr : address to read (up to 21 bits)
    '    XMM_Dst  : destination of this instruction set to destination register
    '    XMM_Len  : number of bytes to read (usually 1, 2 or 4)
    ' On exit:
    '    XMM_Addr and XMM_Page set up for fast access. XMM_Addr incremented by 4.
    '    Destination register contains long read from XMM.
    '
    ' NOTE:  Does not use XMM_IncAddr, but instead increments address directly -
    '        this means this routine will only work for longs entirely WITHIN a
    '        page - but this should be true for all properly aligned long values.
    '        
    XMM_ReadLong
                  mov     XMM_Len,#4                ' read 4 bytes
    XMM_ReadMult
                  call    #XMM_SetAddr              ' latch ram address
                  mov     XMM_Temp, #0
    :ReadLoop
                  andn    outa,ram_MUX              ' enable mux
                  nop                               ' sram delay              
                  nop                               ' sram delay              
                  mov     outx,ina                  ' read byte from sram
                  or      outa,ram_MUX              ' disable mux
                  and     outx,#$FF                 ' mask the data to 8-bits
                  or      XMM_Temp,outx             ' ... into ...
                  ror     XMM_Temp,#8               ' ... XMM_Temp
                  call    #XMM_IncAddr              ' inc sram address
                  djnz    XMM_Len,#:ReadLoop        ' repeat while XMM_len <> 0
    XMM_Dst       mov     0-0, XMM_Temp             ' save the result
    XMM_ReadLong_ret
    XMM_ReadMult_ret
                  ret
    '
    #endif          
    '
    #ifdef NEED_XMM_WRITELONG              
    '
    ' XMM_WriteLong : Write long in source register to XMM at address XMM_Addr.
    ' On entry:
    '    XMM_Addr : (32-bit) address to write (up to 21 bits)
    '    XMM_Src  : source of this instruction set to source register
    ' On exit:
    '    XMM_Addr and XMM_Page shifted into position for fast use. XMM_Addr incremented by 4.
    '
    '
    ' XMM_WriteMult : Write multiple bytes in source register to XMM at address XMM_Addr.
    '                 XMM_Activate should be called at least once before this routine is used.
    ' On entry:
    '    XMM_Addr : address to write (up to 21 bits)
    '    XMM_Src  : source of this instruction set to source register
    '    XMM_Len  : number of bytes to write (usually 1, 2 or 4)
    ' On exit:
    '    XMM_Addr and XMM_Page shifted into position for fast use. XMM_Addr incremented by 4.
    '
    ' NOTE:  Does not use XMM_IncAddr, but instead increments address directly -
    '        this means this routine will only work for longs entirely WITHIN a
    '        page - but this should be true for all properly aligned long values.
    '
    XMM_WriteLong
                  mov     XMM_Len,#4                ' write 4 bytes
    XMM_WriteMult
                  call    #XMM_SetAddr              ' latch ram address
    XMM_Src       mov     XMM_Temp,0-0              ' save the value
    :WriteLoop
                  mov     dira, ram_dir_write       ' set outputs for write (to sram)
                  mov     outx,XMM_Temp             ' get next ...
                  and     outx,#$FF                 ' .. byte to write
                  or      outx,ram_WR               ' set write and disable mux 
                  mov     outa,outx                 ' write to SRAM
                  andn    outa,ram_MUX              ' enable mux
    '             nop                               ' sram delay
                  or      outa,ram_MUX              ' disable mux
                  ror     XMM_Temp,#8               ' prepare to write next byte
                  call    #XMM_IncAddr              ' inc sram address (autoinc page)
                  djnz    XMM_Len,#:WriteLoop       ' repeat while XMM_len <> 0
                  mov     dira,ram_dir_read         ' set outputs for read again
    XMM_WriteLong_ret
    XMM_WriteMult_ret
                  ret
    '
    #endif          
    '
    #ifdef NEED_XMM_WRITEPAGE              
    '
    ' XMM_WritePage : Write bytes from Hub RAM to XMM RAM
    ' On entry:
    '    XMM_Addr  (32-bit): destination address in sram, 19-bits used
    '    Hub_Addr  (32-bit): source address in main memory, 16-bits used
    '    XMM_Len   (32-bit): number of bytes to write. 
    '
    ' NOTE:  Uses XMM_IncAddr, which is slower than incrementing the address directly,
    '        but it means pages can be correctly read across page boundaries.
    '
    XMM_WritePage
                  call    #XMM_SetAddr              ' latch ram address
    :WriteLoop
                  mov     dira,ram_dir_write        ' set outputs for write (to sram)
                  rdbyte  outx,Hub_Addr             ' get byte to write
                  or      outx,ram_WR               ' set write and disable mux 
                  mov     outa,outx                 ' write byte (to sram)
                  andn    outa,ram_MUX              ' enable mux
    '             nop                               ' sram delay
                  or      outa,ram_MUX              ' disable mux
                  add     Hub_Addr,#1               ' inc source address
                  call    #XMM_IncAddr              ' inc sram address (autoinc page)
                  djnz    XMM_Len,#:WriteLoop       ' repeat while XMM_len <> 0
                  mov     dira,ram_dir_read         ' set outputs for read again
    XMM_WritePage_ret
                  ret
    '
    #endif          
    '
    #ifdef NEED_XMM_READPAGE              
    '
    ' XMM_ReadPage : Read bytes from XMM RAM to Hub RAM.
    ' On Entry: 
    '    XMM_Addr  (32-bit): source address in sram, 19-bits used
    '    Hub_Addr  (32-bit): destination address in main memory, 16-bits used
    '    XMM_Len   (32-bit): number of bytes to read. 
    '
    ' NOTE:  Uses XMM_IncAddr, which is slower than incrementing the address directly,
    '        but it means pages can be correctly read across page boundaries.
    '
    XMM_ReadPage
                  call    #XMM_SetAddr              ' latch ram address
    :ReadLoop
                  andn    outa,ram_MUX              ' enable mux
                  nop                               ' sram delay              
                  nop                               ' sram delay              
                  mov     outx,ina                  ' read byte (from sram)
                  or      outa,ram_MUX              ' disable mux
                  wrbyte  outx,Hub_Addr             ' write byte to destination (Hub)
                  add     Hub_Addr,#1               ' inc dest address
                  call    #XMM_IncAddr              ' inc sram address (autoinc page)
                  djnz    XMM_Len,#:ReadLoop        ' repeat while XMM_len <> 0
    XMM_ReadPage_ret
                  ret
    '
    #endif              
    '
    'XMM_SetAddr : Setup initial XMM address. XMM_Activate should be called
    '              at least once before this routine is used.
    'On Entry:
    '   XMM_Addr      : address to set (19 bits)
    '   XMM_Last0_7   : Last address bits 0 to 7 (or -1 if no last addr) 
    '   XMM_Last8_15  : Last address bits 8 to 15 (in bits 0 .. 7, or -1)
    '   XMM_Last16_19 : LAst address bits 16 to 19 (in bits 0 .. 7, or -1)
    '
    'On Exit:
    '   latches set
    '   XMM_Last0_7, XMM_Last8_15, XMM_Last_16_19 : updated
    '
    XMM_SetAddr
                  mov     dira,ram_dir_write        ' set up for writing (to latch)
                  mov     outx,XMM_Addr             ' shift  ...
                  shr     outx,#16                  ' addr bits 16 - 19 ...
                  and     outx,#$FF                 ' ... into position
                  or      outx,ram_A16_A19          ' set mux for bits 16 - 19
                  mov     outa,outx                 ' output new bits and enable mux
                  andn    outa,ram_MUX              ' enable mux
    '             nop                               ' sram delay              
                  or      outa,ram_MUX              ' disable mux
    XMM_Check8_19
                  mov     outx,XMM_Addr             ' shift  ...
                  shr     outx,#8                   ' addr bits 8 - 15 ...
                  and     outx,#$FF                 ' ... into position
                  or      outx,ram_A8_A15           ' set mux for bits 8 - 15
                  mov     outa,outx                 ' output new bits and enable mux
                  andn    outa,ram_MUX              ' enable mux
    '             nop                               ' sram delay              
                  or      outa,ram_MUX              ' disable mux
    XMM_Check0_7
                  mov     outx,XMM_Addr             ' bits 0 - 7 ...
                  and     outx,#$FF                 ' ... are already in position
                  or      outx,ram_A0_A7            ' set mux for bits 0 - 7 
                  mov     outa,outx                 ' output new bits and enable mux
                  andn    outa,ram_MUX              ' enable mux
    '             nop                               ' sram delay              
                  or      outa,ram_MUX              ' set read and disable mux
    XMM_Check_Done
                  mov     outa,ram_MUX
                  mov     dira,ram_dir_read         ' set up for reading
    XMM_SetAddr_ret
                  ret
    '
    '#ifdef NEED_XMM_INCADDR
    ' DRACBLADE ALWAYSE NEEDS INCADDR              
    '
    '
    'XMM_IncAddr : Increment XMM address, setting latches as necessary. XMM_Activate
    '              must be called at least once before this routine is used.
    ' On Entry:
    '   XMM_Addr      : address to increment (19 bits)
    '   XMM_Last0_7   : Last address bits 0 to 7 (or -1 if no last addr) 
    '   XMM_Last8_15  : Last address bits 8 to 15 (in bits 0 .. 7, or -1)
    '   XMM_Last16_19 : LAst address bits 16 to 19 (in bits 0 .. 7, or -1)
    '
    'On Exit:
    '   latches set
    '   XMM_Last0_7, XMM_Last8_15, XMM_Last_16_19 : updated
    '
    XMM_IncAddr
                  add     XMM_Addr,#1               ' inc sram address
                  mov     outx,XMM_Addr             ' does result of incrementing ...
                  and     outx,#$FF                 ' ... require updating latch 8 - 15 or 16 - 19?
                  tjnz    outx,#XMM_Set0_7          ' if not, just set latch for addr bits 0 - 7
                  call    #XMM_SetAddr              ' otherwise we must set all latches
                  jmp     #XMM_IncAddr_ret          ' done 
    XMM_Set0_7
                  mov     dira,ram_dir_write        ' set up for writing (to latch)
                  or      outx,ram_A0_A7            ' set mux for bits 0 - 7 
                  mov     outa,outx                 ' output new bits and enable mux
                  andn    outa,ram_MUX              ' enable mux
    '             nop                               ' sram delay              
                  or      outa,ram_MUX              ' set read and disable mux
                  mov     outa,ram_MUX
                  mov     dira,ram_dir_read         ' set up for reading
    XMM_IncAddr_ret
                  ret
    '
    '#endif
    '
    ' DracBlade Hardware Access:
    '
    '   (P24) M_PORT2-------------+ +-------- VGA (P23)                                             
    '   (P25) M_PORT2------------+| |+------- VGA (P22)                          
    '   (P26) KB ---------------+|| ||+------ VGA (P21)                           
    '   (P27) KB --------------+||| |||+----- VGA (P20)                        
    '   (P28) SCL ------------+|||| ||||+---- VGA (P19)            
    '   (P29) SDA -----------+||||| |||||+--- VGA (P18)                                               
    '   (P30) SO -----------+|||||| ||||||+-- VGA (P17)                                                
    '   (P31) SI ----------+||||||| |||||||+- VGA (P16)                                                      
    '                      |||||||| ||||||||                                                       
    ram_MUX       long    %00000000_00000000_0000_0001_00000000 ' active low                                        
    'ram_RD        long    %00000000_00000000_0000_0001_00000000 ' same as ram_MUX
    ram_WR        long    %00000000_00000000_0000_0011_00000000
    ram_A0_A7     long    %00000000_00000000_0000_0101_00000000
    ram_A8_A15    long    %00000000_00000000_0000_0111_00000000
    ram_A16_A19   long    %00000000_00000000_0000_1001_00000000
    'ram_DATA      long    %00000000_00000000_0000_0000_11111111
    ram_dir_read  long    %00000000_00000000_0000_1111_00000000
    ram_dir_write long    %00000000_00000000_0000_1111_11111111
    '                                        |||| |||| ||||||||
    '                         SD CS ---(P15)-+||| |||| |-DATA-|
    '                         SD DI ---(P14)--+|| |||| 76543210
    '                         SD CLK --(P13)---+| ||||
    '                         SD DO ---(P12)----+ |||+--(P8) ---- /mux (active low) 
    '                                             ||+---(P9)---+                               
    '                                             |+---(P10)--+|                   
    '                                             +----(P11)-+|| 
    '                                                        |||               
    '                                                        |||
    '                                                        000 /RD_RAM
    '                                                        001 /WR_RAM
    '                                                        010 /CS_A0-A7
    '                                                        011 /CS_A8-A15
    '                                                        100 /CS_A16-A18
    '                                                        101 /CS_LCD
    '                                                        110 Not connected
    '                                                        111 Not connected
    '
    outx          long      0                       ' as a temp address
    '
    XMM_Addr      long      0
    XMM_Temp      long      0
    XMM_Len       long      0
    XMM_Test      long      0
    HUB_Addr      long      0
    '
    '----------------------- End of DRACBLADE XMM Support Routines ------------------
    
    Also, see the comments that lead into the whole XMM section:
    '================= START OF PLATFORM SPECIFIC XMM SUPPORT CODE =================
    '
    ' The folling #defines determine which XMM functions are included - comment out
    ' the appropriate lines to exclude the corresponding XMM function:
    '
    #define NEED_XMM_READLONG
    #define NEED_XMM_WRITELONG
    '#define NEED_XMM_READPAGE
    '#define NEED_XMM_WRITEPAGE
    '#define NEED_XMM_INCADDR        ' required for XMM_ReadPage and XMM_WritePage
    '#define ACTIVATE_INITS_XMM      ' the HX512 does not allow this in the Kernel
    '                                    
    '
    '===============================================================================
    ' Beyond these lines, the code is common to all programs that need XMM support.
    '
    ' If you modify any of this code, copy it to all the files that contains it:
    '
    '       Catalina_XMM_Input.spin
    '       Catalina_XMM_SD_Loader_Input.spin
    '       Catalina_XMM_EEPROM_Loader_Input.spin
    '       Catalina_HUB_XMM_Loader_Input.spin
    '       Catalina_XMM_SIO_Loader_Input.spin
    '       Catalina_XMM_RamTest_Input.spin
    '       Catalyst_XMM_SD_Loader_Input.spim
    '
    '===============================================================================
    

    P.S. I just noticed thet the comments in the DRACBLADE XMM code no longer match the code! But the code is right - it's the comments that need updating!
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-09 21:25
    Thanks for the XMM code - found it now.

    I thought I would write a little bit of code to test out the display and change the text color
    /* Traditional first C program */
    
    #include <stdio.h>
    
    void main () {
    clearscreen();
    printf("Hello, World!\n");
    while (1) ; /* Prop reboots on exit from main()! */
    }
    
    void clearscreen()
    {
    	int i;
    	for (i=0;i<10;i++)
    		{
    			t_setpos(0,0,i);
    			t_color(0,0x00FF);
    		}
    }
    

    This code runs and it correctly puts white on black text for the first 10 lines.

    However, it is giving a warning in the compiler. Is my C code not correct?
    Catalina Compiler 2.6
    SCREEN.C:12: warning: declaration of `clearscreen' does not match previous declaration at SCREEN.C:6
    
  • RossHRossH Posts: 5,573
    edited 2010-11-09 21:38
    Hi Dr_Acula,

    If you call a function before declaring it, C declares the function for you - but it always declares it to return an int even if the call doesnt make use of any return value.

    Your actual function returns a void - so C thinks you are re-declaring the function.

    Two solutions:

    1. Just declare the function before using it:
    /* Traditional first C program */
    
    #include <stdio.h>
    
    void clearscreen()
    {
        int i;
        for (i=0;i<10;i++)
            {
                t_setpos(0,0,i);
                t_color(0,0x00FF);
            }
    }
    
    void main () {
    clearscreen();
    printf("Hello, World!\n");
    while (1) ; /* Prop reboots on exit from main()! */
    }
    
    2. Use a forward declaration:
    /* Traditional first C program */
    
    #include <stdio.h>
    
    void clearscreen(); // forward declaration
    
    void main () {
    clearscreen();
    printf("Hello, World!\n");
    while (1) ; /* Prop reboots on exit from main()! */
    }
    
    void clearscreen()
    {
        int i;
        for (i=0;i<10;i++)
            {
                t_setpos(0,0,i);
                t_color(0,0x00FF);
            }
    }
    

    Ross.
  • Nick MuellerNick Mueller Posts: 815
    edited 2010-11-10 03:39
    Ross, I'd like to get your help. :)
    I'm enough confused with the platform, compiler and linker setting in Code::block with my platform.

    Own hardware with almost nothing except an RS232, a few LEDs and jumpers and 128k EEPROM.
    RS232 is at the default pins (to load code of course). There's also a RS485 (like RS232 but half duplex + requires to drive RTS) on different pins (not important at the moment, I think).

    Now, I think that's:
    platform= no clue! DEMO?
    memsize = 32k
    ALTERNATE
    NO_FP (I don't have floating point in my code)
    NO_HMI
    model=1 (EMM, I think that's the right LMM-substitute with that much EEPROM)

    As I like the code::blocks ide, I'd want to set the settings there.
    What goes where (compiler flags; compiler settings; custom variables; ...)

    Thanks for your help!
    Nick

    In the meantime, I'll solder in the missing parts I just got from Digi-Key ...
  • RossHRossH Posts: 5,573
    edited 2010-11-10 04:38
    Hi Nick,

    I made provision for adding a CUSTOM platform. If you go to the Catalina\demos folder and try the command:
    catalina -lc -D CUSTOM -D PC hello_world.c
    You should see output like:
    Catalina Compiler 2.8
    Homespun Spin Compiler 0.27
    parsing C:\Program Files\Catalina\target\lmm_default.spin
    parsing C:\Program Files\Catalina\target\Catalina.spin
    parsing C:\Program Files\Catalina\target\Catalina_Common.spin
    Error: Catalina_Common.spin (431, 7): Expected "(eol)", got :
    ERROR : CUSTOM PLATFORM HAS NOT BEEN CONFIGURED!
    ^
    This error is expected. You need to edit the file Catalina\target\input\Catalina_Common_Input.spin and check the definitions for the CUSTOM platform. That section will initially look like this:
    #elseifdef CUSTOM
    '
    ' Comment out the following line when you have configured the Custom platform:
    '
    ERROR : CUSTOM PLATFORM HAS NOT BEEN CONFIGURED!
    
    '===============================================================================
    '
    ' Custom platform General definitions:
    ' 
    '===============================================================================
    
    KBD_PIN    = -1                 ' BASE PIN  (Custom)
    MOUSE_PIN  = -1                 ' BASE PIN  (Custom)
    TV_PIN     = -1                 ' BASE PIN  (Custom)
    VGA_PIN    = -1                 ' BASE PIN  (Custom)
    SD_DO_PIN  = -1                 ' Custom has no SD Card
    SD_CLK_PIN = -1                 ' Custom has no SD Card 
    SD_DI_PIN  = -1                 ' Custom has no SD Card
    SD_CS_PIN  = -1                 ' Custom has no SD Card
    I2C_PIN    = 28                 ' I2C Boot EEPROM SCL Pin
    I2C_DEV    = $A0                ' I2C Boot EEPROM Device Address
    SI_PIN     = 31                 ' PIN (Custom)
    SO_PIN     = 30                 ' PIN (Custom)
    '
    ' Custom platform Clock definitions:
    ' 
    CLOCKMODE = xtal1 + pll16x      ' (Custom)
    XTALFREQ  = 5_000_000           ' (Custom)
    CLOCKFREQ = 80_000_000          ' (Custom) Nominal clock frequency (required by some drivers)
    '
    ' Demo platform Loader and InterProp Comms definitions:
    '
    SIO_BAUD      = 115200          ' Baud rate to use for all interprop comms                 
    SIO_LOAD_MODE = %0000           ' Custom has only one CPU - this is for serial loading
    SIO_COMM_MODE = %0000           ' Custom has only one CPU - this is for serial loading
    TX_PIN        = -1              ' Custom has only one CPU
    RX_PIN        = -1              ' Custom has only one CPU
    '
    ' Custom platform XMM Base Address:
    '
    XMM_BASE_ADDRESS = -1           ' Custom board has no XMM
    '
    ' Custom platform Payload pins (SI/SO pins)
    '
    PAYLOAD_RXPIN = SI_PIN          ' Rx pin to use for Payload comms
    PAYLOAD_TXPIN = SO_PIN          ' Tx pin to use for Payload comms
    '
    ' Custom platform BlackCat debug pins (SI/SO pins)
    '
    BLACKCAT_RXPIN = SI_PIN         ' Rx pin to use for BlackCat comms
    BLACKCAT_TXPIN = SO_PIN         ' Tx pin to use for BlackCat comms
    BLACKCAT_MODE  = %0000          ' SIO mode to use for BlackCat comms
    '
    
    In your case, the only thing you need to do is comment out the line that says "ERROR : CUSTOM PLATFORM HAS NOT BEEN CONFIGURED!" and then check the CLOCKMODE, XTALFREQ and CLOCKFREQ constants are correct (they may already be correct). Everything else should be correct.

    Save the modified file and then try the compilation again. This time you should see output like:
    Catalina Compiler 2.8
    Homespun Spin Compiler 0.27
    parsing C:\Program Files\Catalina\target\lmm_default.spin
    parsing C:\Program Files\Catalina\target\Catalina.spin
    parsing C:\Program Files\Catalina\target\Catalina_Common.spin
    parsing C:\Program Files\Catalina\target\Catalina_Cogstore.spin
    parsing C:\Program Files\Catalina\target\Catalina_LMM.spin
    parsing C:\Program Files\Catalina\target\Catalina_HMI_Plugin_PC.spin
    parsing C:\Program Files\Catalina\target\Catalina_PC_Keyboard.spin
    parsing C:\Program Files\Catalina\target\Catalina_PC_Text.spin
    compiling lmm_default.spin
    compiling Catalina.spin
    compiling Catalina_Cogstore.spin
    compiling Catalina_LMM.spin
    compiling Catalina_HMI_Plugin_PC.spin
    compiling Catalina_PC_Keyboard.spin
    compiling Catalina_PC_Text.spin
    compiling Catalina_Common.spin
    writing hello_world.binary
    Now program hello_world.binary into EEPROM. You can either use the Parallax tools, or use the command:
    payload -e hello_world.binary
    Then start the Propeller Serial Terminal (set it to 115200 baud), and rebooth the Propeller by toggling DTR. You should see "Hello, World!" appear in the terminal emulator.

    Now for some of the gory details ...
    • The -lc option specifies the standard C library be included.
    • The -D CUSTOM command line flag obviously selects the CUSTOM target.
    • The -D PC command line option specifies that the program use the PC HMI plugin - this plugin uses the serial port (which is about the only device you have) for all I/O. The resulting program should work (using a serial terminal emulator on the PC) on any Propeller with pins 31 and 30 wired up for serial I/O and with the correct clock speed.
    • You don't really need to specify -D NO_FP or -D ALTERNATE (although you can if you want)
    • LMM mode (-x0) is the default mode, so you don't need to specify that either.
    • Even though we are programming the result into EEPROM, this program is actually a normal Parallax binary.You don't use the special EMM mode (-x1) unless you have a 64kb EEPROM and want to use the special EEPROM two-phase loader.
    • The memory size defaults to 32k for LMM programs, so you don't need to specify anything there either.
    You can use similar command options for the other programs in the demo directory. For example, try:
    catalina -lc -D CUSTOM -D PC othello.c
    Then load the program into EEPROM and use the Parallax Serial Terminal to play othello.

    Get this far before you try tackling Code::Blocks. Let me know how you go.

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-10 05:37
    Oh boy is this fun!

    Thanks for the tip re the order of functions. I've been very used to sbasic putting the functions first and the main at the end. I wasn't sure if this was allowed in C, but it makes sense and works fine that way.

    The IDE is working brilliantly. Some little checkboxes for options and this is a little example of the vb.net code
            If RadioButton10.Checked = True Then
                VGAMode = "HIRES_VGA"
            Else
                VGAMode = "LORES_VGA"
            End If
            'PrintLine(1, "catalina -lcx -x5 -M 128k -D DRACBLADE -D HIRES_VGA " + CatalinaFile)
            If CheckBox17.Checked = False Then
                CommandLine = "catalina -lcx -x5 -M " + Memsize + "k -D DRACBLADE -D " + VGAMode + " " + CatalinaFile
            Else
                CommandLine = "catalina -lc -D DEMO -D " + VGAMode + " " + CatalinaFile
            End If
    

    it may be relevant for the other discussion thread you are running, as I am using the DEMO option for quicker downloads. Nice to know I just change a check box to use the external ram and suddenly have 512k of code space.

    See the attached screenshot. Hit the compile button and this is running on the propeller in under 20 seconds. So the compile/edit/recompile cycle is quite reasonable. And that makes Catalina a real programming language!

    For fun I did not look up the vga colors but tested them using windows calculator with simple binary to hex conversions. It was pretty easy to determine that the order was RRGGBBxx and that the nicest looking text was white on a darker blue background. But of course, green on black is possible as are lots of other color combos.

    So I hereby declare that programming in C on the propeller is not only fun, but is fast, easy and quite a practical alternative to Spin. And that comes from a diehard BASIC programmer!
    1024 x 768 - 86K
  • PaxiPaxi Posts: 10
    edited 2010-11-10 06:37
    RossH wrote: »
    Hi Paxi,

    0x00000001 is not an "address" as such - it's the bit number in the DIRA (and INA and OUTA) registers. Each bit in these registers corresponds to an I/O pin on the Propeller. In this case 0x00000001 = bit 0 = pin P0.

    The pin numbers used for a specific purpose will depend on the board you are using, and should be listed in your documentation. For example, you ae correct that a debug LED is sometimes connected to P0 (at least it is on the Hydra and Hybrid boards, and possibly on some others).

    Catalina only knows specifically about pin numbers where they are used in various drivers (e.g. video, keyboard). When using the other pins, you must be careful not to affect the pins dedicated to such purposes. This is the purpose of the "mask" parameter - it helps you avoid accidentally affecting other pins.

    What Propeller board are you using? I can probably point you to a list of what the I/O pins are used for on that particular board.

    Ross.

    Thank you for the quick reply again. Now i understood it! :)
    I am using the Hydra Version from Propeller. I think there are some more ports listed in the documentation but not all. So i would appreciate a list of all I/O pins and their usage.

    Regards Paxi
  • max72max72 Posts: 1,155
    edited 2010-11-10 09:17
    @Praxi: this is a nice starting point:

    http://propeller.wikispaces.com/Dev+Board+Differences

    Massimo
  • Nick MuellerNick Mueller Posts: 815
    edited 2010-11-10 12:30
    Get this far before you try tackling Code::Blocks. Let me know how you go.

    Roos, perfect job!

    Only thing:
    "You need to edit the file Catalina\target\Catalina_Common_Input.spin"
    is in Catalina/target/input/ But I found that out! Hahaha.


    It only took longer for me to answer, because I soldered in a 16 pin SMT the wrong way round. And exactly the one that is surrounded by 3 high parts (headers etc.). Not easy to reach, had to cut off the legs and thus ruining 3 traces. No Propellers got hurt. :lol:

    But back to EMM:
    Did I understand it right, that a SPIN-loader first loads the cogs (like serial etc.) and then starts the C-code? Thus saving precious HUB-RAM.
    I expect my program to be big. In a similar version, I had to implemented such a load-from-EEPROM-method that was to some extend like yours. But I used the RS232-buffer that wasn't used at that moment for reading from EEPROM.


    Nick
  • RossHRossH Posts: 5,573
    edited 2010-11-10 14:35
    Only thing:
    "You need to edit the file Catalina\target\Catalina_Common_Input.spin"
    is in Catalina/target/input/ But I found that out! Hahaha.

    Oops! sorry - I have corrected the original in case anyone else tries it.

    But back to EMM:
    Did I understand it right, that a SPIN-loader first loads the cogs (like serial etc.) and then starts the C-code? Thus saving precious HUB-RAM.
    I expect my program to be big. In a similar version, I had to implemented such a load-from-EEPROM-method that was to some extend like yours. But I used the RS232-buffer that wasn't used at that moment for reading from EEPROM.

    Correct - here is a brief overview of the load options you have with Catalina:

    In general, the load process on the Propeller can be either one-phase or two-phase. Parallax's loader is one-phase - i.e. it just loads 32k from a binary file (or EEPROM) into hub RAM and then starts the program. This is simple enough, but it means that the memory space occupied by drivers and other programs that get loaded into cogs cannot be re-used as code space (it can be re-used as data space).

    By default, Catalina compiles LMM programs into a 32k binary so they can use the one-phase load mechanism, and can therefore be loaded on any Propeller by any loader - support for the one phase loader is essentially "built into" the Propeller. Or (like any other binary) they can be programmed into a 32k EEPROM and automatically loaded at boot time.

    Catalina also offers various two-phase loaders. One of these is the EEM (EEPROM) loader. When using this loader, Catalina generates a 64kb eeprom file, which MUST be programmed into an EEPROM of 64kb or larger. The first 32k contains a SPIN program that can be loaded normally using the Parallax loader (the "first" phase load) - this program loads the cogs, kernel etc. This program also contains a "second phase loader" (I think this is what you mean by the "SPIN" loader, but it is in fact written in PASM). The second phase loader then loads the actual C program from the second 32k bank of the external EEPROM, overwriting Hub RAM. This allows more of the Hub RAM to be used for C code. Not quite the full 32kb - but this is not usually a problem since some of that space has to be available as data space anyway.

    Another of Catalina's two-phase loaders is the SD XMM card loader, which does a similar job, but loads from SD Card into XMM - this process is much more complicated, but allows programs to be loaded that are megabytes in size (provided you have enough external RAM).

    I have now added a new SD LMM two-phase loader (which I am calling SMM for short). This loader will be available in the next release. It is similar to the SD XMM Loader, but after loading the cogs etc, it loads up to 31kb of C code into Hub RAM - i.e. it does not require or use any external memory.

    Payload is Catalina's serial loader program - it can be used to load normal SPIN/PASM binaries, LMM programs or XMM programs. It will soon be extended to allow loading of SMM programs,. But it cannot load EMM programs - these always have to be programmed into an EEPROM.

    Ross.
  • RossHRossH Posts: 5,573
    edited 2010-11-10 14:36
    max72 wrote: »
    @Praxi: this is a nice starting point:

    http://propeller.wikispaces.com/Dev+Board+Differences

    Massimo

    Thanks Max72!

    Paxi - this is the link I would have directed you to. Very useful!

    Ross.
  • RossHRossH Posts: 5,573
    edited 2010-11-10 14:40
    Dr_Acula wrote: »
    Oh boy is this fun!
    So I hereby declare that programming in C on the propeller is not only fun, but is fast, easy and quite a practical alternative to Spin. And that comes from a diehard BASIC programmer!

    Thanks Dr_Acula - looks good.

    If we can convince BASIC programmers, there is hope yet that we may convert SPIN people as well!

    I'll try your program out this weekend. Is your latest version still the binary in post #377?

    Ross.
  • Nick MuellerNick Mueller Posts: 815
    edited 2010-11-10 14:49
    This program also contains a "second phase loader" (I think this is what you mean by the "SPIN" loader, but it is in fact written in PASM).

    Yes, I wrote "SPIN" without thinking.

    Later, I'll have a look at the first phase loader, because I'll have to load COG-code conditionally (configuration-dependant). But nothing to be done right now.

    I know, those questions mean a lot of work and time for you. But may I come back to ask how I get my configuration to compile and link in code::blocks?


    Thanks a lot for your great support!
    Nick
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-10 14:49
    Latest version of the IDE attached. Many timing tweaks - eg when you hit the compile button, it resets the propeller board and also starts compiling catalina. But catalina usually finishes before kyedos boots, so I added a 2 second delay. You need to manually shut down the catalina window - I added a 'pause' in the batch file so you can see any errors.

    Also new kyedos added - some timing changes to the xmodem download.

    Also you need catalyst compiled so it talks to the serial port. Attached are the two versions renamed as 8.3, one is compiled for the local keyboard and one is for the serial port. Put both on the sd card.
  • Nick MuellerNick Mueller Posts: 815
    edited 2010-11-10 14:53
    But it cannot load EMM programs - these always have to be programmed into an EEPROM.

    I overlooked that!
    Does that mean you don't have a program to do that?
    I do have one that can write any number of chunks of code anywhere into EEPROM. It's a bit crude, but I'd be glad to give you the code.


    Nick
  • RossHRossH Posts: 5,573
    edited 2010-11-10 16:01
    I overlooked that!
    Does that mean you don't have a program to do that?
    I do have one that can write any number of chunks of code anywhere into EEPROM. It's a bit crude, but I'd be glad to give you the code.

    Nick

    Hi Nick,

    No, I don't have a program that can program 64kb EEPROMS. I use the Hydra Asset Manager (available here). I believe this can also be used on other platforms (I've only ever used it on the Hydra) but you have to modify the code.

    If you have code to do the same job, by all means post it - I'll see about incorporating it into Payload one day.

    Ross.
  • RossHRossH Posts: 5,573
    edited 2010-11-10 16:05

    I know, those questions mean a lot of work and time for you. But may I come back to ask how I get my configuration to compile and link in code::blocks?

    Nick

    Of course - but read the document Getting Started with CodeBlocks (located in the main Catalina directory) - and maybe you won't need to!

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-10 16:43
    Hi Ross, please let me know if you have problems getting the IDE working. I tend to run it a lot from within vb.net rather than as the compiled version as I'm constantly changing things. So if you do that and there are errors then you should be able to find them.
  • RossHRossH Posts: 5,573
    edited 2010-11-10 17:44
    Dr_Acula wrote: »
    Hi Ross, please let me know if you have problems getting the IDE working. I tend to run it a lot from within vb.net rather than as the compiled version as I'm constantly changing things. So if you do that and there are errors then you should be able to find them.

    I'll try installing and running it tonight - but I probably won't get much time to actually play with it till the weekend.

    Ross.
  • RossHRossH Posts: 5,573
    edited 2010-11-10 23:39
    Hi Dr_Acula,

    I get an unhandled exception when I run (see image). I managed to get one program to compile (by saying "Continue") but mostly I just get more exceptions or the program just exits. This is on Windows XP SP3.

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-10 23:51
    You just have to love Microsoft!

    Well, at least lots of other people have had this error. It is a permissions problem http://forums.asp.net/t/1084643.aspx and a detailed fix http://blog.crowe.co.nz/archive/2006/03/02/589.aspx

    Can you compile a new "hello world" in vb.net?

    If so, maybe it is a problem with some of the extra DLLs I'm using. In the form load at startup, could you put in some breakpoints on these lines
     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ' startup
            SerialPort1.ReadTimeout = 100
            w3sock = New Socket.TCP
            w3sock2 = New Socket.TCP
            Timer1.Interval = 150 ' check for new characters every 150ms
            'TextBox3.ForeColor = Color.LawnGreen
            'TextBox3.BackColor = Color.Black
            'CaptureFlag = False
            Call StartScreen()
            Call LoadINI()
    

    If it is the w3sock dll for instance I can get rid of those as they are only needed for CP/M compilation. I may need to think about a greatly simplified version of code.

    Thanks for your help on this one.
  • RossHRossH Posts: 5,573
    edited 2010-11-11 00:01
    Hi Dr_Acula,

    No joy, I'm afraid - followed the instructions, but still got the same error.

    I'll try again on the weekend. Also, I don't have vb.net installed, so I can't insert breakpoints or recompile - I'm just running the existing executable.

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-11 00:11
    That is odd, I didn't think I included the executable. Hmm - looking at the zip, there are a few copies in there.

    I've never had much luck with compiling vb.net and distributing the executable. It seems more reliable to distribute the source as at least it is easier to debug. So I suppose that leads to a download of vb.net

    I suspect there is a problem with the w3sock dll. You could try downloading it and registering it
        'http://dimac.net/default3.asp?M=FreeDownloads/Menu.asp&P=FreeDownloads/FreeDownloadsstart.asp
        ' Get the free download called w3sockets half way down the page
        ' put the sockets.dll file in c:\windows\system32
        ' run the SocketReg program
        'Your application needs to be aware of the socket.dll file, I accomplished this as follows:
        '1. Click on the 'Project' menu and select 'Add reference...'
        '2. Click on the 'Browse' tab
        '3. Navigate to where you have socket.dll installed on the HD
        '4. Select this file and click 'OK'
    



    If that is the problem, that probably leads me to think about a simpler IDE version designed specifically for catalina.

    Yes, upon further reflection I think I need a much simpler catalina-only IDE. Ok - back to coding!
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-11 01:08
    @Ross, I'm thinking of building this up from basics.

    Attached is a skeleton of an IDE. The only buttons that work are New and Exit. Can you check this installs without any errors?
  • RossHRossH Posts: 5,573
    edited 2010-11-11 01:42
    Dr_Acula,

    Yes, it installs and runs ok.
Sign In or Register to comment.