Revision: 1447 Author: robhamerling Date: Sun Nov 1 02:12:55 2009 Log: Fixed 'numeric' keyword with fuse_def CP in 16f873/4 device files. Added device file for 12F617 Updated devicefiles documentation
http://code.google.com/p/jallib/source/detail?r=1447 Added: /trunk/include/device/12f617.jal Modified: /trunk/CHANGELOG /trunk/doc/html/devicefiles.html /trunk/include/device/16f873.jal /trunk/include/device/16f874.jal ======================================= --- /dev/null +++ /trunk/include/device/12f617.jal Sun Nov 1 02:12:55 2009 @@ -0,0 +1,458 @@ +-- =================================================== +-- Title: JalV2 device include file for PIC 12F617 +-- +-- Author: Rob Hamerling, Copyright (c) 2008..2009, all rights reserved. +-- +-- Adapted-by: +-- +-- Compiler: 2.4l +-- +-- This file is part of jallib (http://jallib.googlecode.com) +-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html) +-- +-- Description: +-- Device include file for pic12f617, containing: +-- - Declaration of ports and pins of the chip. +-- - Procedures for shadowing of ports and pins +-- to circumvent the read-modify-write problem. +-- - Symbolic definitions for configuration bits (fuses) +-- - Some device dependent procedures for common +-- operations, like: +-- . enable_digital_io() +-- +-- Sources: +-- - "x:/mplab840/mplab ide/device/pic12f617.dev" +-- - "x:/mplab840/mpasm suite/lkr/12f617_g.lkr" +-- +-- Notes: +-- - Created with Dev2Jal Rexx script version 0.0.84 +-- - File creation date/time: 29 Oct 2009 17:20 +-- +-- =================================================== +-- +const word DEVICE_ID = 0x1360 +const byte PICTYPE[] = "12F617" +const byte DATASHEET[] = "41302" +const byte PGMSPEC[] = "41396" +-- +-- Vdd Range: 2.000-5.500 Nominal: 5.000 +-- Vpp Range: 10.000-12.000 Default: 12.000 +-- +-- --------------------------------------------------- +-- +include chipdef_jallib -- common constants +-- +pragma target cpu PIC_14 -- (banks = 2) +pragma target chip 12f617 +pragma target bank 0x0080 +pragma target page 0x0800 +pragma stack 8 +pragma code 2048 -- (words) +pragma data 0x20-0x6F,0xA0-0xBF +pragma shared 0x70-0x7F +-- +var volatile byte _pic_accum shared at { 0x7E } -- (compiler) +var volatile byte _pic_isr_w shared at { 0x7F } -- (compiler) +-- +const word _FUSES_CT = 1 +const word _FUSE_BASE = 0x2007 +const word _FUSES = 0b_0011_1111_1111_1111 +-- +const word _ID_CT = 4 +const word _ID_BASE[_ID_CT] = { 0x2000,0x2001,0x2002,0x2003 } +const word _ID[_ID_CT] = { 0x0000,0x0000,0x0000,0x0000 } +-- +-- ------------------------------------------------ +var volatile byte INDF at { 0x0,0x80 } +var volatile byte _ind at { 0x0,0x80 } -- (compiler) +-- ------------------------------------------------ +var volatile byte TMR0 at { 0x1 } +-- ------------------------------------------------ +var volatile byte PCL at { 0x2,0x82 } +var volatile byte _pcl at { 0x2,0x82 } -- (compiler) +-- ------------------------------------------------ +var volatile byte STATUS at { 0x3,0x83 } +var volatile bit STATUS_IRP at STATUS : 7 +var volatile bit*2 STATUS_RP at STATUS : 5 +var volatile bit STATUS_NTO at STATUS : 4 +var volatile bit STATUS_NPD at STATUS : 3 +var volatile bit STATUS_Z at STATUS : 2 +var volatile bit STATUS_DC at STATUS : 1 +var volatile bit STATUS_C at STATUS : 0 +var volatile byte _status at { 0x3,0x83 } -- (compiler) +const byte _irp = 7 -- (compiler) +const byte _RP1 = 6 -- (compiler) +const byte _RP0 = 5 -- (compiler) +const byte _not_to = 4 -- (compiler) +const byte _not_pd = 3 -- (compiler) +const byte _z = 2 -- (compiler) +const byte _dc = 1 -- (compiler) +const byte _c = 0 -- (compiler) +-- ------------------------------------------------ +var volatile byte FSR at { 0x4,0x84 } +var volatile byte _fsr at { 0x4,0x84 } -- (compiler) +-- ------------------------------------------------ +var volatile byte GPIO at { 0x5 } +var volatile byte PORTA at GPIO +-- +var byte _PORTA_shadow = PORTA +-- +procedure _PORTA_flush() is + pragma inline + PORTA = _PORTA_shadow +end procedure +procedure PORTA'put(byte in x) is + pragma inline + _PORTA_shadow = x + _PORTA_flush() +end procedure +-- +procedure PORTA_low'put(byte in x) is + _PORTA_shadow = (_PORTA_shadow & 0xF0) | (x & 0x0F) + _PORTA_flush() +end procedure +function PORTA_low'get() return byte is + return (PORTA & 0x0F) +end function +-- +procedure PORTA_high'put(byte in x) is + _PORTA_shadow = (_PORTA_shadow & 0x0F) | (x << 4) + _PORTA_flush() +end procedure +function PORTA_high'get() return byte is + return (PORTA >> 4) +end function +-- +var volatile bit GPIO_GP5 at GPIO : 5 +var volatile bit pin_A5 at GPIO : 5 +-- +procedure pin_A5'put(bit in x at _PORTA_shadow : 5) is + pragma inline + _PORTA_flush() +end procedure +-- +var volatile bit GPIO_GP4 at GPIO : 4 +var volatile bit pin_A4 at GPIO : 4 +-- +procedure pin_A4'put(bit in x at _PORTA_shadow : 4) is + pragma inline + _PORTA_flush() +end procedure +-- +var volatile bit GPIO_GP3 at GPIO : 3 +var volatile bit pin_A3 at GPIO : 3 +-- +procedure pin_A3'put(bit in x at _PORTA_shadow : 3) is + pragma inline + _PORTA_flush() +end procedure +-- +var volatile bit GPIO_GP2 at GPIO : 2 +var volatile bit pin_A2 at GPIO : 2 +-- +procedure pin_A2'put(bit in x at _PORTA_shadow : 2) is + pragma inline + _PORTA_flush() +end procedure +-- +var volatile bit GPIO_GP1 at GPIO : 1 +var volatile bit pin_A1 at GPIO : 1 +-- +procedure pin_A1'put(bit in x at _PORTA_shadow : 1) is + pragma inline + _PORTA_flush() +end procedure +-- +var volatile bit GPIO_GP0 at GPIO : 0 +var volatile bit pin_A0 at GPIO : 0 +-- +procedure pin_A0'put(bit in x at _PORTA_shadow : 0) is + pragma inline + _PORTA_flush() +end procedure +-- +-- ------------------------------------------------ +var volatile byte PCLATH at { 0xA,0x8A } +var volatile bit*5 PCLATH_PCLATH at PCLATH : 0 +var volatile byte _pclath at { 0xA,0x8A } -- (compiler) +-- ------------------------------------------------ +var volatile byte INTCON at { 0xB,0x8B } +var volatile bit INTCON_GIE at INTCON : 7 +var volatile bit INTCON_PEIE at INTCON : 6 +var volatile bit INTCON_TMR0IE at INTCON : 5 +var volatile bit INTCON_INTE at INTCON : 4 +var volatile bit INTCON_GPIE at INTCON : 3 +var volatile bit INTCON_TMR0IF at INTCON : 2 +var volatile bit INTCON_INTF at INTCON : 1 +var volatile bit INTCON_GPIF at INTCON : 0 +-- ------------------------------------------------ +var volatile byte PIR1 at { 0xC } +var volatile bit PIR1_ADIF at PIR1 : 6 +var volatile bit PIR1_ECCPIF at PIR1 : 5 +var volatile bit PIR1_C1IF at PIR1 : 3 +var volatile bit PIR1_TMR2IF at PIR1 : 1 +var volatile bit PIR1_TMR1IF at PIR1 : 0 +-- ------------------------------------------------ +var volatile word TMR1 at { 0xE } +-- ------------------------------------------------ +var volatile byte TMR1L at { 0xE } +-- ------------------------------------------------ +var volatile byte TMR1H at { 0xF } +-- ------------------------------------------------ +var volatile byte T1CON at { 0x10 } +var volatile bit T1CON_T1GINV at T1CON : 7 +var volatile bit T1CON_TMR1GE at T1CON : 6 +var volatile bit*2 T1CON_T1CKPS at T1CON : 4 +var volatile bit T1CON_T1OSCEN at T1CON : 3 +var volatile bit T1CON_NT1SYNC at T1CON : 2 +var volatile bit T1CON_TMR1CS at T1CON : 1 +var volatile bit T1CON_TMR1ON at T1CON : 0 +-- ------------------------------------------------ +var volatile byte TMR2 at { 0x11 } +-- ------------------------------------------------ +var volatile byte T2CON at { 0x12 } +var volatile bit*4 T2CON_TOUTPS at T2CON : 3 +var volatile bit T2CON_TMR2ON at T2CON : 2 +var volatile bit*2 T2CON_T2CKPS at T2CON : 0 +-- ------------------------------------------------ +var volatile word CCPR1 at { 0x13 } +-- ------------------------------------------------ +var volatile byte CCPR1L at { 0x13 } +-- ------------------------------------------------ +var volatile byte CCPR1H at { 0x14 } +-- ------------------------------------------------ +var volatile byte CCP1CON at { 0x15 } +var volatile bit CCP1CON_P1M at CCP1CON : 7 +var volatile bit*2 CCP1CON_DCB at CCP1CON : 4 +var volatile bit*4 CCP1CON_CCP1M at CCP1CON : 0 +-- ------------------------------------------------ +var volatile byte PWM1CON at { 0x16 } +var volatile bit PWM1CON_PRSEN at PWM1CON : 7 +var volatile bit*7 PWM1CON_PDC at PWM1CON : 0 +-- ------------------------------------------------ +var volatile byte ECCPAS at { 0x17 } +var volatile bit ECCPAS_ECCPASE at ECCPAS : 7 +var volatile bit*3 ECCPAS_ECCPAS at ECCPAS : 4 +var volatile bit*2 ECCPAS_PSSAC at ECCPAS : 2 +var volatile bit*2 ECCPAS_PSSBD at ECCPAS : 0 +-- ------------------------------------------------ +var volatile byte VRCON at { 0x19 } +var volatile bit VRCON_C1VREN at VRCON : 7 +var volatile bit VRCON_VRR at VRCON : 5 +var volatile bit VRCON_FBREN at VRCON : 4 +var volatile bit*4 VRCON_VR at VRCON : 0 +-- ------------------------------------------------ +var volatile byte CMCON0 at { 0x1A } +var volatile bit CMCON0_C1ON at CMCON0 : 7 +var volatile bit CMCON0_C1OUT at CMCON0 : 6 +var volatile bit CMCON0_C1OE at CMCON0 : 5 +var volatile bit CMCON0_C1POL at CMCON0 : 4 +var volatile bit CMCON0_C1R at CMCON0 : 2 +var volatile bit CMCON0_C1CH at CMCON0 : 0 +-- ------------------------------------------------ +var volatile byte CMCON1 at { 0x1C } +var volatile bit CMCON1_T1ACS at CMCON1 : 4 +var volatile bit CMCON1_C1HYS at CMCON1 : 3 +var volatile bit CMCON1_T1GSS at CMCON1 : 1 +var volatile bit CMCON1_C1SYNC at CMCON1 : 0 +-- ------------------------------------------------ +var volatile byte ADRESH at { 0x1E } +-- ------------------------------------------------ +var volatile byte ADCON0 at { 0x1F } +var volatile bit ADCON0_ADFM at ADCON0 : 7 +var volatile bit ADCON0_VCFG at ADCON0 : 6 +var volatile bit*3 ADCON0_CHS at ADCON0 : 2 +var volatile bit ADCON0_GO at ADCON0 : 1 +var volatile bit ADCON0_NDONE at ADCON0 : 1 +var volatile bit ADCON0_ADON at ADCON0 : 0 +-- ------------------------------------------------ +var volatile byte OPTION_REG at { 0x81 } +var volatile bit OPTION_REG_NGPPU at OPTION_REG : 7 +var volatile bit OPTION_REG_INTEDG at OPTION_REG : 6 +var volatile bit OPTION_REG_T0CS at OPTION_REG : 5 +var volatile bit OPTION_REG_T0SE at OPTION_REG : 4 +var volatile bit OPTION_REG_PSA at OPTION_REG : 3 +var volatile bit*3 OPTION_REG_PS at OPTION_REG : 0 +-- ------------------------------------------------ +var volatile byte TRISIO at { 0x85 } +var volatile byte TRISA at TRISIO +var volatile byte PORTA_direction at TRISIO +-- +procedure PORTA_low_direction'put(byte in x) is + TRISA = (TRISA & 0xF0) | (x & 0x0F) +end procedure +function PORTA_low_direction'get() return byte is + return (TRISA & 0x0F) +end function +-- +procedure PORTA_high_direction'put(byte in x) is + TRISA = (TRISA & 0x0F) | (x << 4) +end procedure +function PORTA_high_direction'get() return byte is + return (TRISA >> 4) +end function +-- +var volatile bit TRISIO_TRISIO5 at TRISIO : 5 +var volatile bit pin_A5_direction at TRISIO : 5 +-- +var volatile bit TRISIO_TRISIO4 at TRISIO : 4 +var volatile bit pin_A4_direction at TRISIO : 4 +-- +var volatile bit TRISIO_TRISIO3 at TRISIO : 3 +var volatile bit pin_A3_direction at TRISIO : 3 +-- +var volatile bit TRISIO_TRISIO2 at TRISIO : 2 +var volatile bit pin_A2_direction at TRISIO : 2 +-- +var volatile bit TRISIO_TRISIO1 at TRISIO : 1 +var volatile bit pin_A1_direction at TRISIO : 1 +-- +var volatile bit TRISIO_TRISIO0 at TRISIO : 0 +var volatile bit pin_A0_direction at TRISIO : 0 +-- +-- ------------------------------------------------ +var volatile byte PIE1 at { 0x8C } +var volatile bit PIE1_ADIE at PIE1 : 6 +var volatile bit PIE1_ECCPIE at PIE1 : 5 +var volatile bit PIE1_C1IE at PIE1 : 3 +var volatile bit PIE1_TMR2IE at PIE1 : 1 +var volatile bit PIE1_TMR1IE at PIE1 : 0 +-- ------------------------------------------------ +var volatile byte PCON at { 0x8E } +var volatile bit PCON_NPOR at PCON : 1 +var volatile bit PCON_NBOR at PCON : 0 +-- ------------------------------------------------ +var volatile byte OSCTUNE at { 0x90 } +var volatile bit*5 OSCTUNE_TUN at OSCTUNE : 0 +-- ------------------------------------------------ +var volatile byte PR2 at { 0x92 } +-- ------------------------------------------------ +var volatile byte APFCON at { 0x93 } +var volatile bit APFCON_T1GSEL at APFCON : 4 +var volatile bit APFCON_P1BSEL at APFCON : 1 +var volatile bit APFCON_P1ASEL at APFCON : 0 +-- ------------------------------------------------ +var volatile byte WPU at { 0x95 } +var volatile bit WPU_WPUA5 at WPU : 5 +var volatile bit WPU_WPUA4 at WPU : 4 +var volatile bit WPU_WPUA2 at WPU : 2 +var volatile bit WPU_WPUA1 at WPU : 1 +var volatile bit WPU_WPUA0 at WPU : 0 +-- ------------------------------------------------ +var volatile byte IOC at { 0x96 } +var volatile bit IOC_IOC5 at IOC : 5 +var volatile bit IOC_IOC4 at IOC : 4 +var volatile bit IOC_IOC3 at IOC : 3 +var volatile bit IOC_IOC2 at IOC : 2 +var volatile bit IOC_IOC1 at IOC : 1 +var volatile bit IOC_IOC0 at IOC : 0 +-- ------------------------------------------------ +var volatile byte PMCON1 at { 0x98 } +var volatile bit PMCON1_WREN at PMCON1 : 2 +var volatile bit PMCON1_WR at PMCON1 : 1 +var volatile bit PMCON1_RD at PMCON1 : 0 +-- ------------------------------------------------ +var volatile byte PMCON2 at { 0x99 } +-- ------------------------------------------------ +var volatile byte PMADRL at { 0x9A } +-- ------------------------------------------------ +var volatile byte PMADRH at { 0x9B } +var volatile bit PMADRH_PMADRH2 at PMADRH : 2 +var volatile bit PMADRH_PMADRH1 at PMADRH : 1 +var volatile bit PMADRH_PMADRH0 at PMADRH : 0 +-- ------------------------------------------------ +var volatile byte PMDATL at { 0x9C } +-- ------------------------------------------------ +var volatile byte PMDATH at { 0x9D } +var volatile bit*6 PMDATH_PMDATH at PMDATH : 0 +-- ------------------------------------------------ +var volatile byte ADRESL at { 0x9E } +-- ------------------------------------------------ +var volatile byte ANSEL at { 0x9F } +var volatile bit*3 ANSEL_ADCS at ANSEL : 4 +var volatile bit JANSEL_ANS3 at ANSEL : 3 +var volatile bit JANSEL_ANS2 at ANSEL : 2 +var volatile bit JANSEL_ANS1 at ANSEL : 1 +var volatile bit JANSEL_ANS0 at ANSEL : 0 +-- +-- =================================================== +-- +-- Special (device specific) constants and procedures +-- +const ADC_GROUP = ADC_V0 +const byte ADC_NTOTAL_CHANNEL = 0 +-- +-- - - - - - - - - - - - - - - - - - - - - - - - - - - +-- Change analog I/O pins into digital I/O pins. +procedure analog_off() is + pragma inline + ANSEL = 0b0000_0000 -- all digital +end procedure +-- +-- - - - - - - - - - - - - - - - - - - - - - - - - - - +-- Disable ADC module +procedure adc_off() is + pragma inline + ADCON0 = 0b0000_0000 -- disable ADC +end procedure +-- +-- - - - - - - - - - - - - - - - - - - - - - - - - - - +-- Disable comparator module +procedure comparator_off() is + pragma inline + CMCON0 = 0b0000_0111 -- disable comparator +end procedure +-- +-- - - - - - - - - - - - - - - - - - - - - - - - - - - +-- Switch analog ports to digital mode (if analog module present). +procedure enable_digital_io() is + pragma inline + analog_off() + adc_off() + comparator_off() +end procedure +-- +-- ================================================== +-- +-- Symbolic Fuse definitions +-- ------------------------- +-- +-- addr 0x2007 +-- +pragma fuse_def OSC 0x7 { + RC_CLKOUT = 0x7 + RC_NOCLKOUT = 0x6 + INTOSC_CLKOUT = 0x5 + INTOSC_NOCLKOUT = 0x4 + EC_NOCLKOUT = 0x3 + HS = 0x2 + XT = 0x1 + LP = 0x0 + } +pragma fuse_def WDT 0x8 { + ENABLED = 0x8 + DISABLED = 0x0 + } +pragma fuse_def PWRTE 0x10 { + DISABLED = 0x10 + ENABLED = 0x0 + } +pragma fuse_def MCLR 0x20 { + EXTERNAL = 0x20 + INTERNAL = 0x0 + } +pragma fuse_def CP 0x40 { + DISABLED = 0x40 + ENABLED = 0x0 + } +pragma fuse_def IOSCFS 0x80 { + F8MHZ = 0x80 + F4MHZ = 0x0 + } +pragma fuse_def BROWNOUT 0x300 { + DISABLED = 0x0 + DISABLED = 0x100 + RUNONLY = 0x200 + ENABLED = 0x300 + } +-- ======================================= --- /trunk/CHANGELOG Sat Oct 31 15:34:12 2009 +++ /trunk/CHANGELOG Sun Nov 1 02:12:55 2009 @@ -7,11 +7,14 @@ device files: - device files created with MPLAB 8.40 - - over 50 new device files + - over 50 new device files released - alias declarations added for access of Enhanced CCP modules as 'legacy' CCP modules - - alias declarations added for access of SSP modules of 18Fs with midrange register names + - alias declarations added for access of SSP modules of 18Fs with midrange register names. - added declarations of pseudo variables for shared memory SFRs and their subfields for several high-end 18Fs. + - Changes of fuse_def declarations which may affect existing programs: + - 'CCPxMX' normalized to 'CCPxMUX' and its values normalized to 'pin_xy' + - Removed leading, trailing and multiple consecutive underscores from keywords externals: - sd_card - library to drive a SD Card storage media @@ -30,7 +33,7 @@ - added delay_1s to delay library - provisional fix to make rtc_int_tmr0 library independent of ocsillator frequency - profiler library to measure execution time of a procedure - - sqrt library + - sqrt library samples: - seven_segment samples ======================================= --- /trunk/doc/html/devicefiles.html Fri Oct 30 01:39:56 2009 +++ /trunk/doc/html/devicefiles.html Sun Nov 1 02:12:55 2009 @@ -647,7 +647,7 @@ Portx_high is read from or written to bits 7..4 of Portx. -<h2>Naming convention for configuration bits (fuses)</h2> +<h2>Naming convention for configuration bit fields (fuses)</h2> <p>The configuration bits or groups of bits is such a large variety that it is almost impossible to obtain a uniform naming convention. @@ -803,12 +803,29 @@ <p><b>Notes:</b> <ol> +<li>The terms 'Enabled' and 'Disabled' may have to be specified where +usually 'On' and 'Off' are used. <li>In addition to these 'standard' fuse_defs above there may be others, depending on the features of the specific PICmicro. -Please read the device file to see which fuse-defs are available for your +Please read the device file to see which fuse_defs are available for your target PICmicro. -<li>The terms 'Enabled' and 'Disabled' may have to be specified where -usually 'On' and 'Off' are used. +<li>Since the compiler requires names to start with a letter or underscore +and may not contain special characters the descriptions found in the MPLAB +.dev files (other than those mentioned above) have been manipulated as +follows in this sequence: +<ul> +<li>special characters and spaces are translated to underscores +<li>leading and trailing underscores are removed +<li>multiple consecutive underscores are reduced to a single underscore +<li>when the first character is numeric a prefix 'R' is added. +</ul> +Because the MPLAB .dev files contain sometimes extensive descriptions of +configuration bits some fuse_defs have rather complex keywords! +<li>An example of an address range specification for PICs with the +possibility to protect specific code memory areas you may have to specify: +<pre> +pragma target CP R0F00_0FFF +</pre) </ol> <p>When a fuse_def statement causes compile-time error messages you ======================================= --- /trunk/include/device/16f873.jal Thu Oct 29 09:30:19 2009 +++ /trunk/include/device/16f873.jal Sun Nov 1 02:12:55 2009 @@ -25,8 +25,8 @@ -- - "x:/mplab840/mpasm suite/lkr/16f873_g.lkr" -- -- Notes: --- - Created with Dev2Jal Rexx script version 0.0.84 --- - File creation date/time: 29 Oct 2009 17:20 +-- - Created with Dev2Jal Rexx script version 0.0.85 +-- - File creation date/time: 1 Nov 2009 09:37 -- -- =================================================== -- @@ -768,8 +768,8 @@ } pragma fuse_def CP 0x3030 { DISABLED = 0x3030 - 0F00_0FFF = 0x2020 - 0800_0FFF = 0x1010 + R0F00_0FFF = 0x2020 + R0800_0FFF = 0x1010 ENABLED = 0x0 } pragma fuse_def BROWNOUT 0x40 { ======================================= --- /trunk/include/device/16f874.jal Thu Oct 29 09:30:19 2009 +++ /trunk/include/device/16f874.jal Sun Nov 1 02:12:55 2009 @@ -25,8 +25,8 @@ -- - "x:/mplab840/mpasm suite/lkr/16f874_g.lkr" -- -- Notes: --- - Created with Dev2Jal Rexx script version 0.0.84 --- - File creation date/time: 29 Oct 2009 17:20 +-- - Created with Dev2Jal Rexx script version 0.0.85 +-- - File creation date/time: 1 Nov 2009 09:38 -- -- =================================================== -- @@ -1021,8 +1021,8 @@ } pragma fuse_def CP 0x3030 { DISABLED = 0x3030 - 0F00_0FFF = 0x2020 - 0800_0FFF = 0x1010 + R0F00_0FFF = 0x2020 + R0800_0FFF = 0x1010 ENABLED = 0x0 } pragma fuse_def BROWNOUT 0x40 { --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "jallib" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/jallib?hl=en -~----------~----~----~----~------~----~------~--~---
