Menu

program not working past 2k 16f1938

Help
Chris
2012-08-13
2013-05-30
  • Chris

    Chris - 2012-08-13

    im writing a slightly large program. the problem begins when the size of the program extends past 2k in size. im using proteus to simulate my program and when i run it i get errors like
    "PC=0x0055 Attempt to read unimplemented memory location 0x0411 ignored"
    and
    "PC=0x0055 Attempt to write unimplemented memory location 0x0411 with 0x00 ignored"

    my program works fine when the size is around 2kb, i increased the size of the program by setting the same variable, with the same value, about 20 times, which pushed the size of my program to around 2.3k in size, and i get these errors.

    i have tried the program with and without "#option lcall" and i get the same results either way.

    i dont think this is a problem with my code, because the only thing i change in the code is setting the variable multiple times with the same value.

    im using the pic micro 16f1938, which has (i think) around 16k of program space, i would like to be able to use (most) of it, its doubtful ill need more than 4k of space for the program i am writing but im sure to need more than 2k.

    any help would be appreciated

     
  • Nobody/Anonymous

    That looks more like the compiler is placing variables in unimplemented RAM.

    In the 16F1938 DAT file there does seem to be an error in the FreeRAM allocation - the last block is listed as 620:34F. It should be 620:64F so try changing that.

     
  • Nobody/Anonymous

    The same error appears in the dat files for -

    16F1829
    16F1847
    16F1939
    16F1947

    generated on 15/2/2012 for anyone using those chips.

     
  • Chris

    Chris - 2012-08-14

    I tried that, and theres no change. still getting errors when program goes over 2k.
    the specific error im getting right now is
    "PC=0x005a. Attempt to write unimplemented memory location 0x0412 with 0xF0 ignored."

    and the error repeats every .001 seconds, with the only difference between the errors being the "PC=_____" value, some other values are
    PC=0x005c PC=0x005E PC=0x0060

     
  • Hugh Considine

    Hugh Considine - 2012-08-14

    Good job spotting that error with the RAM bank definitions, I will update the chip data!

    I'm not sure what is causing that error. I'd guess that it's something to do with the bank selection code, but I can't say for sure. The PC = 0x55 is a good tip though. If you're using the assembler in GCBASIC, could you copy and paste the relevant section of the listing file? That will probably be called compiled.lst, and you can open it with Notepad. If you're using the assembler in GCBASIC, scroll down to the line that starts with "000055", then copy and paste it and the 10 lines before and after it.

     
  • Chris

    Chris - 2012-08-14

    ive changed my code since my last post, but the results are very similar, still works fine under 2k, but now when over 2k this is the error i get
    "PC=0x01D6 Attempt to read unimplemented memory location 0x0495 ignored"
    and
    "PC=0x01D6 Attempt to write unimplemented memory location 0x0495 with 0x01 ignored"

    and that message repeats every .00001s until i end the simulation

    here is my the section of my .lst file near the location of 01D6 (though there is no 01D6 in the .lst file anywhere"

    ENDIF81
    0001CC 3002 MOVLW 2
    000000 0020 BANKSEL HI2CCURRENTMODE
    0001CE 0225 SUBWF HI2CCURRENTMODE,W
    0001CF 1D03 BTFSS STATUS, Z
    0001D0 29D6 GOTO ENDIF82
    000000 0024 BANKSEL SSPCON1
    0001D2 1195 BCF SSPCON1,SSPM3
    0001D3 1515 BSF SSPCON1,SSPM2
    0001D4 1495 BSF SSPCON1,SSPM1
    0001D5 1415 BSF SSPCON1,SSPM0
    ENDIF82
    000000 0024 BANKSEL SSPCON1
    0001D7 1695 BSF SSPCON1,SSPEN
    000000 0020 BANKSEL STATUS
    0001D9 0008 RETURN

     
  • Hugh Considine

    Hugh Considine - 2012-08-14

    That code looks ok at first glance. I thought that a banksel command might be missing, but it looks like there are banksel commands everywhere that there should be. They also appear to be selecting the correct bank. "BANKSEL SSPCON1" is setting the bank select register to 4, which seems to be correct because SSPCON1 is in bank 4.

    As a quick test, I put this code into MPLAB SIM and ran it:

    LIST p=16F1938, r=DEC
    #include <P16F1938.inc>

    ORG 0
    banksel SSPCON1
    bsf SSPCON1, SSPEN
    goto $
    END

    It worked without any problems (selected bank 4, and then set SSPEN) and the hex code generated by MPASM matches that produced by GCBASIC's assembler. I'll have another look tomorrow and double check, but the problem may be in the simulator.

     
  • Chris

    Chris - 2012-08-14

    well if it helps ill post here my full code, it is a possibility that the problem is with the simulator, this is the first chip ive had that had more than 2k program space so ive never had the chance to test this all out. i guess i could put the program on the chip itself and see if it works as expected but its just a lot easier to run it through the simulator instead of reprogramming the chip over and over. anyway, heres the full code.

    ;Chip Settings
    #chip 16F1938,8
    #config OSC=INTOSC, CLKOUTEN=OFF
    ;Defines (Constants)
    #define I2C_MODE Master
    #define I2C_DATA portc.4
    #define I2C_CLOCK portc.3
    #define current_address 240
    #define slave_address 224
    #define serial_register 1
    #define ir_in portb.0
    #define LCD_IO 4
    #define LCD_RS PORTC.0
    #define LCD_Enable PORTA.7
    #define LCD_DB4 PORTA.3
    #define LCD_DB5 PORTA.2
    #define LCD_DB6 PORTA.1
    #define LCD_DB7 PORTA.0
    #define speaker portc.7
    #define power_sw portc.5
    #define reset_sw portb.1
    #define LCD_NO_RW 
    #define remote_power 200
    #define #option lcall
    ;Variables
    Dim counter As byte
    Dim temp As byte
    Dim mem_temp As byte
    Dim hold_counter As byte
    Dim timer_temp As byte
    Dim remote_temp As word
    Dim remote_code As byte
    Dim release_counter As byte
    Dim zero_fill_temp As word
    Dim i2c_register As byte
    Dim i2c_buffer As byte
    Dim serial_buffer As byte
    Dim pc_power_var As bit
    Dim timeout_counter As byte
    Dim timer_var As byte
    Dim menu_depth As byte
    Dim red_var As byte
    Dim green_var As byte
    Dim blue_var As byte
    Dim contrast_var As byte
    Dim timeout_var As byte
    Dim serial_passthru As byte
    Dim display_var As string
    Dim menu_selection(2)
    Dim in_menu As bit
    Dim temp_sensor(5)
    Dim write_not_read As bit
    Dim fan_mode(5)
    Dim pulse_duty(5)
    Dim temp_offset(5)
    ;Interrupt Handlers
    On Interrupt SSP1Ready Call i2c_interrupt
    'display_power_mode 0=timeout 1=always on
    Set INTEDG Off
    Set NOT_WPUEN Off
    Set WPUB0 On
    Set WPUB1 On
    Set ACKDT On
    Set SSPIF Off
    SSPADD = current_address
    Hi2cMode Slave
    i2c_address = slave_address
    remote_temp = 255
    remote_code = 0
    serial_buffer = 0
    Set INTEDG Off
    Set NOT_WPUEN Off
    'ccp5
    Dir porta.4 Out
    'ccp4
    'portb.0 out
    'ccp3
    Dir PORTC.6 Out
    'ccp2
    Dir PORTc.1 Out
    'ccp1
    Dir PORTC.2 Out
    display_var = "LCD"
    lcd_sub
    Print "LCD"
    Print "LCD"
    Print "LCD"
    Print "LCD"
    Print "LCD"
    Print "LCD"
    Print "LCD"
    Print "LCD"
    Print "LCD"
    Print "LCD"
    Print "LCD"
    Print "LCD"
    Print "LCD"
    Do Forever
        If release_counter<150 Then
            release_counter = release_counter+1
        End If
        If release_counter=>150 Then
            remote_temp = 255
        End If
        If remote_temp=255 Then
            Set power_sw Off
        End If
        If remote_temp=remote_power Then
            Set power_sw On
        End If
        If serial_buffer=109 Then
            menu_init
            currently_in_menu:
            menu_start
            menu_display
            menu_fan
            serial_buffer = 0
            If menu_depth<3 and in_menu=1 Then
                Goto currently_in_menu
            End If
            display_var = "LCD"
            lcd_sub
            serial_buffer = 0
        End If
    Loop
    Sub mem_write
        counter = 0
        Do Until counter=>6
            counter = counter+1
            If counter=1 Then
                mem_temp = red_var
            End If
            If counter=2 Then
                mem_temp = green_var
            End If
            If counter=3 Then
                mem_temp = blue_var
            End If
            If counter=4 Then
                mem_temp = contrast_var
            End If
            If counter=5 Then
                mem_temp = timeout_var
            End If
            If counter=6 Then
                mem_temp = serial_passthru
            End If
            EPWrite counter, mem_temp
        Loop
        counter = 0
    End Sub
    Sub zero_fill
        Wait 1 ms
        zero_fill_temp = 1000
        Do Until serial_buffer=>zero_fill_temp
            zero_fill_temp = zero_fill_temp/10
            If zero_fill_temp=1 Then
                zero_fill_temp = 0
            End If
            HSerPrint "0"
            Wait 1 ms
        Loop
    End Sub
    Sub i2c_interrupt
        If SSPSTAT.S=1 Then
            If D_NOT_A=0 Then
                Hi2cReceive i2c_address
            End If
        End If
        Wait Until SSPIF=1
        Set SSPIF Off
        If i2c_address= current_address Then
            Wait Until BF=1
            Set SSPIF Off
            Hi2cReceive i2c_register
            Wait Until SSPSTAT.BF=1 or SSPSTAT.R_NOT_W=1
            If BF=1 Then
                Hi2cReceive i2c_buffer
                Wait Until SSPSTAT.P=1
                slave_receive
                Exit Sub
            End If
            If R_NOT_W=1 Then
                slave_send
                Hi2cSend i2c_buffer
            End If
        End If
        Wait Until SSPSTAT.P=1
    End Sub
    Sub master_receive
        Set SSPEN Off
        i2c_address = slave_address
        I2CStart
        I2CSend i2c_address
        I2CSend i2c_register
        I2CStop
        Wait 1 ms
        I2CStart
        I2CSend (i2c_address+1)
        I2CReceive i2c_buffer, ACK
        I2CStop
        menu_temp = i2c_buffer
        Set SSPEN On
    End Sub
    Sub master_send
        Set SSPEN Off
        i2c_address = slave_address
        I2CStart
        I2CSend i2c_address
        I2CSend i2c_register
        I2CSend i2c_buffer
        I2CStop
        Set SSPEN On
    End Sub
    Sub slave_send
        If i2c_register>=2 and i2c_register<=6 Then
            'fan mode
        End If
        If i2c_register>=7 and i2c_register <=11 Then
            'pulse duty
        End If
        If i2c_register>=12 and i2c_register <=16 Then
            'temp offset
        End If
        If i2c_register>=18 and i2c_register <=22 Then
            'temp sensors
        End If
        If i2c_register=23 Then
            'error check
        End If
        If i2c_register=25 Then
            'remote button
        End If
    End Sub
    Sub slave_receive
        If i2c_register=serial_register Then
            'serial
            serial_buffer = i2c_buffer
        End If
        If i2c_register>=2 and i2c_register<=6 Then
            'fan mode
        End If
        If i2c_register>=7 and i2c_register <=11 Then
            'pulse duty
        End If
        If i2c_register>=12 and i2c_register <=16 Then
            'temp_offset
        End If
        If i2c_register=17 Then
            'pc power
            pc_power = i2c_buffer
        End If
        If i2c_register>=18 and i2c_register <=22 Then
            temp_sensor(i2c_register-13) = i2c
        End If
    End Sub
    Sub set_remote_bits
        If counter>=5 and counter<=12 Then
            Rotate remote_code Left simple
            If Timer1>pulse_middle or PIR1.TMR1IF=1 Then
                remote_code.0 = 0
                Exit Sub
            End If
            remote_code.0 = 1
        End If
        If counter >12 Then
            Rotate remote_temp Left simple
            If Timer1>pulse_middle or TMR1IF=1 Then
                remote_temp.0 = 0
                Exit Sub
            End If
            remote_temp.0 = 1
        End If
    End Sub
    Sub serial_sub
        serial_buffer = HSerReceive
    End Sub
    Sub remote_sub
        Set PIR1.TMR1IF Off
        StartTimer 1
        release_counter = 0
        remote_code = 0
        remote_temp = 0
        counter = 0
        Do Until counter>=22
            counter = counter+1
            Wait Until ir_in=1 or PIR1.TMR1IF=1
            StopTimer 1
            set_remote_bits
            ClearTimer 1
            StartTimer 1
            counter = counter+1
            Wait Until ir_in=0 or PIR1.TMR1IF=1
            StopTimer 1
            set_remote_bits
            ClearTimer 1
            StartTimer 1
        Loop
        StopTimer 1
        Set PIR1.TMR1IF Off
        If remote_code=144 or remote_code=16 Then
            Exit Sub
        End If
        remote_temp = 999
    End Sub
    Sub mem_read
        counter = 0
        Do Until counter=>15
            counter = counter+1
            EPRead counter, mem_temp
            If counter=1 Then
                red_var = mem_temp
            End If
            If counter=2 Then
                green_var = mem_temp
            End If
            If counter=3 Then
                blue_var = mem_temp
            End If
            If counter=4 Then
                contrast_var = mem_temp
            End If
            If counter=5 Then
                timeout_var = mem_temp
            End If
            If counter=6 Then
                serial_passthru = mem_temp
            End If
        Loop
        counter = 0
    End Sub
    Sub power_sub
        If pc_power_var=0 Then
            If timeout_var<255 Then
                timeout_counter = timeout_counter+1
                If timeout_counter=>timeout_var Then
                    timeout_counter = timeout_var
                    HPWM 1, 40, 0
                    HPWM 2, 40, 0
                    HPWM 3, 40, 0
                    HPWM 5, 40, lcd_contrast
                End If
            End If
        End If
        If pc_power_var=1 Then
            timeout_counter = 0
            HPWM 1, 40, r_value
            HPWM 2, 40, g_value
            HPWM 3, 40, b_value
            HPWM 5, 40, lcd_contrast
        End If
    End Sub
    Sub menu_start
        menu_top:
        Wait Until serial_buffer>0
        CLS
        If serial_buffer=102 Then
            menu_depth = menu_depth+1
        End If
        If serial_buffer=100 Then
            menu_selection(menu_depth) = menu_selection(menu_depth)+1
        End If
        If serial_buffer=97 Then
            menu_selection(menu_depth) = menu_selection(menu_depth)-1
        End If
        If menu_selection(1)>8 Then
            menu_selection(1) = 1
        End If
        If menu_selection(1)=0 Then
            menu_selection(1) = 8
        End If
        If menu_selection(1)=7 Then
            If menu_depth=1 Then
                Print "Save"
            End If
            If menu_depth=2 Then
                Print "Saved"
                Wait 1 s
                in_menu = 0
            End If
        End If
        If menu_selection(1)=8 Then
            If menu_depth=1 Then
                Print "Exit"
            End If
            If menu_depth=2 Then
                in_menu = 0
            End If
        End If
    End Sub
    Sub startup_sub
    End Sub
    Sub lcd_sub
        CLS
        Print display_var
        Locate 1, 0
    End Sub
    Sub menu_init
        menu_depth = 1
        in_menu = 1
        menu_selection(1) = 1
        menu_selection(2) = 1
        CLS
        Print "Menu"
        Wait 1 s
    End Sub
    Sub menu_display
        If menu_selection(1)=1 Then
            'Display
            If menu_depth=1 Then
                Print "Display"
            End If
            If menu_depth=2 Then
                If menu_selection(2)=0 Then
                    menu_selection(2) = 7
                End If
                If menu_selection(2)>7 Then
                    menu_selection(2) = 1
                End If
                If menu_selection(2)=1 Then
                    display_var = "Backlight Red"
                    lcd_sub
                    menu_temp = red_var
                    menu_up_down
                    red_var = menu_temp
                End If
                If menu_selection(2)=2 Then
                    display_var = "Backlight green"
                    lcd_sub
                    menu_temp = green_var
                    menu_up_down
                    green_var = menu_temp
                End If
                If menu_selection(2)=3 Then
                    display_var = "Backlight Blue"
                    lcd_sub
                    menu_temp = blue_var
                    menu_up_down
                    blue_var = menu_temp
                End If
                If menu_selection(2)=4 Then
                    display_var = "Contrast"
                    lcd_sub
                    menu_temp = contrast_var
                    menu_up_down
                    contrast_var = menu_temp
                End If
                If menu_selection(2)=5 Then
                    display_var = "Backlight Timeout"
                    lcd_sub
                    menu_temp = timeout_var
                    menu_up_down
                    timeout_var = menu_temp
                End If
                If menu_selection(2)=6 Then
                    display_var = "Serial Passthru"
                    lcd_sub
                    menu_temp = serial_passthru
                    If serial_buffer=119 or serial_buffer=115 Then
                        If menu_temp=0 Then
                            menu_temp = 1
                            Goto skip_passthru_0
                        End If
                        serial_passthru = 0
                        skip_passthru_0:
                    End If
                    serial_passthru = menu_temp
                End If
                If menu_selection(2)=7 Then
                    Print "Exit"
                    Goto skip_print_display
                End If
                Print menu_temp
                skip_print_display:
            End If
        End If
    End Sub
    Sub menu_fan
        If menu_selection(1)=>2 and menu_selection(1)<=6 Then
            If menu_depth=1 Then
                'fan1, fan2, fan3, fan4, fan5
                Print "Fan"
                Print menu_selection(1)-1
            End If
            If menu_depth=2 Then
                If menu_selection(2)=0 Then
                    menu_selection(2) = 4
                End If
                If menu_selection(2)>4 Then
                    menu_selection(2) = 1
                End If
                If menu_selection(2)=1 Then
                    'mode
                    display_var = "Mode"
                    lcd_sub
                    i2c_register = menu_selection(1)
                    master_receive
                    menu_up_down
                    If menu_temp>4 Then
                        menu_temp = 1
                    End If
                    If menu_temp=0 Then
                        menu_temp = 4
                    End If
                    If menu_temp=1 Then
                        Print "Off"
                    End If
                    If menu_temp=2 Then
                        Print "On"
                    End If
                    If menu_temp=3 Then
                        Print "Temp"
                    End If
                    If menu_temp=4 Then
                        Print "Manual"
                    End If
                    i2c_buffer = menu_temp
                End If
                If menu_selection(2)=2 Then
                    'duty
                    display_var = "Duty"
                    lcd_sub
                    i2c_register = menu_selection(1)+5
                    master_receive
                    menu_up_down
                    Print menu_temp
                    i2c_buffer = menu_temp
                End If
                If menu_selection(2)=3 Then
                    'offset
                    display_var = "Temp Offset"
                    lcd_sub
                    i2c_register = menu_selection(1)+10
                    master_receive
                    menu_up_down
                    Print menu_temp
                    i2c_buffer = menu_temp
                End If
                If menu_selection(2)=4 Then
                    Print "Exit"
                    Goto skip_print_fan
                End If
                master_send
                skip_print_fan:
            End If
        End If
    End Sub
    Sub menu_up_down
        If serial_buffer=119 Then
            menu_temp = menu_temp+1
        End If
        If serial_buffer=115 Then
            menu_temp = menu_temp-1
        End If
    End Sub
    Sub menu_stop
    End Sub
    

    the section of code repeating the lcd command are just to get it past the 2k size, without those repeated commands in the code i get no errors, but i will test the code on the hardware itself tonight and see if it works properly. ill post the results of my hardware tests here

     
  • Chris

    Chris - 2012-08-15

    Hugh, in case youre interested i have modified the LCD.C file to add support for lcd 8-bit mode, with all 8 pins customizable (in other words you dont have to use the bits of a port, you can use any pin for the lcds data pins).

    you just have to put #define LCD_CUSTOM in the basic code, and for each lcd data pin like this

    #define LCD_DB0 portX.X
    #define LCD_DB1 portX.X
    #define LCD_DB2 portX.X
    #define LCD_DB3 portX.X
    #define LCD_DB4 portX.X
    #define LCD_DB5 portX.X
    #define LCD_DB6 portX.X
    #define LCD_DB7 portX.X

    I modified this code because i couldnt use my entire portA (one of the pins was a HPWM which i wanted to use), and i didnt want to use portB (has the weak pull-ups so i wanna save that for inputs) and portC has the hardware I2C which i wanna use to talk to another pic micro.
    so my only options were to use 4-bit mode, or to remap the pins for 8-bit mode

    im not sure if anyone else will need to remap for 8-bit mode but in case anyone does here is the modified code. i also modified the HPWM code to add support for my additional PWM channels (my chip has 5 total but GCBASIC only had support for up to 3) if youd like that code too just ask. they are very simple modifications. just wanted to give something back to the community

    '    Liquid Crystal Display routines for Great Cow BASIC
    '    Copyright (C) 2006 - 2009 Hugh Considine, Stefano Bonomi
    '    This library is free software; you can redistribute it and/or
    '    modify it under the terms of the GNU Lesser General Public
    '    License as published by the Free Software Foundation; either
    '    version 2.1 of the License, or (at your option) any later version.
    '    This library is distributed in the hope that it will be useful,
    '    but WITHOUT ANY WARRANTY; without even the implied warranty of
    '    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    '    Lesser General Public License for more details.
    '    You should have received a copy of the GNU Lesser General Public
    '    License along with this library; if not, write to the Free Software
    '    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    '********************************************************************************
    'IMPORTANT:
    'THIS FILE IS ESSENTIAL FOR SOME OF THE COMMANDS IN GCBASIC. DO NOT ALTER THIS FILE
    'UNLESS YOU KNOW WHAT YOU ARE DOING. CHANGING THIS FILE COULD RENDER SOME GCBASIC
    'COMMANDS UNUSABLE!
    '********************************************************************************
    'Credits:
    ' 4 and 8 bit routines  Hugh Considine
    ' 2 bit routines    Stefano Bonomi
    ' Testing       Stefano Adami
    #startup InitLCD
    'I/O Ports
    #define LCD_IO 4 'Number of pins used for LCD data bus (2, 4 or 8)
    'Sub used to write to LCD. Can be altered to allow custom LCD interfaces.
    #define LCDWriteByte LCDNormalWriteByte
    #define LCDReadByte LCDNormalReadByte
    #define LCD_DB SysLCDTemp.0 'Data bit. Used in 2-bit mode
    #define LCD_CB SysLCDTemp.0 'Clock bit. Used in 2-bit mode
    #define LCD_DATA_PORT SysLCDTemp 'Port to connect to LCD data bus. Used in 8-bit mode
    #define LCD_DB0 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in Custom mode
    #define LCD_DB1 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in Custom mode
    #define LCD_DB2 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in Custom mode
    #define LCD_DB3 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in Custom mode
    #define LCD_DB4 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in 4-bit mode
    #define LCD_DB5 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in 4-bit mode
    #define LCD_DB6 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in 4-bit mode
    #define LCD_DB7 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in 4-bit mode
    #define LCD_RS SysLCDTemp.1 'Output bit to control LCD Register Select. Used as variable by 2-bit mode, and as a pin in 4 and 8 bit mode. DO NOT CHANGE FOR 2-BIT MODE.
    #define LCD_RW SysLCDTemp.0 'Output bit to select read/write
    #define LCD_Enable SysLCDTemp.0 'Output bit to enable/disable LCD
    #define LCD_RSTemp SysLCDTemp.2
    'Misc Settings
    #define LCD_Write_Delay 8 10us
    #define FLASH 2
    '#define LCD_NO_RW
    'Lines for bar graph
    #define LCD_BAR_EMPTY b'00010001'
    #define LCD_BAR_FULL 255
    Sub PUT (In LCDPutLine, In LCDPutColumn, In LCDChar)
        LOCATE LCDPutLine, LCDPutColumn
        Set LCD_RS on
        LCDWriteByte(LCDChar)
    End Sub
    'GET not available in 2-bit mode
    Function GET (LCDPutLine, LCDPutColumn)
        Locate LCDPutLine, LCDPutColumn
        Set LCD_RS on
        GET = LCDReadByte
    End Function
    'LCDColumn is 0 to screen width-1, LCDLine is 0 to screen height-1
    Sub LOCATE (In LCDLine, In LCDColumn)
        Set LCD_RS Off
        If LCDLine > 1 Then
            LCDLine = LCDLine - 2
            LCDColumn = LCDColumn + 20
        End If
    
        LCDWriteByte(0x80 or 0x40 * LCDLine + LCDColumn)
        Wait 5 10us
    End Sub
    Sub CLS
        SET LCD_RS OFF
    
        'Clear screen
        LCDWriteByte (b'00000001')
        Wait 2 ms
    
        'Move to start of visible DDRAM
        LCDWriteByte(0x80)
        Wait 10 10us
    End Sub
    'Compatibility with older programs
    #define LCDInt Print
    #define LCDWord Print
    'String output
    sub Print (PrintData As String)
        'PrintLen = LEN(PrintData$)
        PrintLen = PrintData(0)
    
        If PrintLen = 0 Then Exit Sub
        Set LCD_RS On
    
        'Write Data
        For SysPrintTemp = 1 To PrintLen
            LCDWriteByte PrintData(SysPrintTemp)
        Next
    
    End Sub
    Sub Print (In LCDValue)
    
        LCDValueTemp = 0
        Set LCD_RS On
    
        IF LCDValue >= 100 Then
            LCDValueTemp = LCDValue / 100
            LCDValue = SysCalcTempX
            LCDWriteByte(LCDValueTemp + 48)
        End If
        If LCDValueTemp > 0 Or LCDValue >= 10 Then
            LCDValueTemp = LCDValue / 10
            LCDValue = SysCalcTempX
            LCDWriteByte(LCDValueTemp + 48)
        End If
        LCDWriteByte (LCDValue + 48)
    End Sub
    Sub Print (In LCDValue As Word)
        Dim SysCalcTempX As Word
        Set LCD_RS On
        LCDValueTemp = 0
    
        If LCDValue >= 10000 then 
            LCDValueTemp = LCDValue / 10000 [word]
            LCDValue = SysCalcTempX
            LCDWriteByte(LCDValueTemp + 48)
            Goto LCDPrintWord1000
        End If
        If LCDValue >= 1000 then
            LCDPrintWord1000:
            LCDValueTemp = LCDValue / 1000 [word]
            LCDValue = SysCalcTempX
            LCDWriteByte(LCDValueTemp + 48)
            Goto LCDPrintWord100
        End If
        If LCDValue >= 100 then
            LCDPrintWord100:
            LCDValueTemp = LCDValue / 100 [word]
            LCDValue = SysCalcTempX
            LCDWriteByte(LCDValueTemp + 48)
            Goto LCDPrintWord10
        End If
        If LCDValue >= 10 then
            LCDPrintWord10:
            LCDValueTemp = LCDValue / 10 [word]
            LCDValue = SysCalcTempX
            LCDWriteByte(LCDValueTemp + 48)
        End If
        LCDWriteByte (LCDValue + 48)
    End Sub
    Sub Print (In LCDValueInt As Integer)
        Dim LCDValue As Word
    
        'If sign bit is on, print - sign and then negate
        If LCDValueInt.15 = On Then
            LCDWriteChar("-")
            LCDValue = -LCDValueInt
    
        'Sign bit off, so just copy value
        Else
            LCDValue = LCDValueInt
        End If
    
        'Use Print(word) to display value
        Print LCDValue
    End Sub
    sub LCDHex(In LCDValue)
        LCDValueTemp = 0
        Set LCD_RS On
    
        IF LCDValue >= 0x10 then
            LCDValueTemp = LCDValue / 0x10
            LCDValue = SysCalcTempX
            LCDHexValueTemp = LCDValueTemp
            if LCDHexValueTemp > 9 then LCDHexValueTemp = LCDHexValueTemp + 7
            LCDWriteByte(LCDHexValueTemp + 48)
        end if
    
        LCDHexValueTemp = LCDValue
        if LCDHexValueTemp > 9 then LCDHexValueTemp = LCDHexValueTemp + 7
        LCDWriteByte (LCDHexValueTemp + 48)
    
    end sub
    sub LCDWriteChar(In LCDChar)
        set LCD_RS on
        LCDWriteByte(LCDChar)
    end sub
    function LCDReady
        #IFDEF LCD_NO_RW
            Wait 10 ms
            LCDReady = TRUE
            exit function
        #ENDIF
    
        #IFNDEF LCD_NO_RW
            #IFNDEF LCD_CUSTOM          
                #IFDEF LCD_IO 2
                    LCDReady = TRUE
                    exit function
                #ENDIF
                #IFDEF LCD_IO 4,8
                    LCDReady = FALSE
                    LCD_RSTemp = LCD_RS
    
                    SET LCD_RW ON
                    SET LCD_RS OFF
                    Wait 5 10us
                    SET LCD_Enable ON
                    wait 5 10us
                    #IFDEF LCD_IO 4
                        dir LCD_DB7 IN
                        if LCD_DB7 OFF THEN LCDReady = TRUE
                    #ENDIF
                    #IFDEF LCD_IO 8
                        dir LCD_DATA_PORT In
                        if LCD_DATA_PORT.7 OFF THEN LCDReady = TRUE
                    #ENDIF
                    SET LCD_Enable OFF
                    wait 25 10us
                    LCD_RS = LCD_RSTemp
                #ENDIF
            #ENDIF
    
            #IFDEF LCD_CUSTOM
                LCDReady = FALSE
                LCD_RSTemp = LCD_RS
    
                SET LCD_RW ON
                SET LCD_RS OFF
                Wait 5 10us
                SET LCD_Enable ON
                wait 5 10us
    
                DIR LCD_DB0 OUT
                DIR LCD_DB1 OUT
                DIR LCD_DB2 OUT
                DIR LCD_DB3 OUT
                DIR LCD_DB4 OUT
                DIR LCD_DB5 OUT
                DIR LCD_DB6 OUT
                DIR LCD_DB7 OUT
                if LCD_DB7 OFF THEN LCDReady = TRUE
                SET LCD_Enable OFF
                wait 25 10us
                LCD_RS = LCD_RSTemp
            #ENDIF
        #ENDIF
    end function
    sub LCDNormalWriteByte(In LCDByte)
    
        #IFNDEF LCD_NO_RW
            #IFNDEF LCD_CUSTOM
                #IFDEF LCD_IO 4,8
                    wait until LCDReady
                    set LCD_RW OFF 'Write mode
                #ENDIF
            #ENDIF
            #IFDEF LCD_CUSTOM
                wait until LCDReady
                set LCD_RW OFF 'Write mode
            #ENDIF
        #ENDIF
    
        #IFNDEF LCD_CUSTOM
            #IFDEF LCD_IO 2
                LCD2_NIBBLEOUT Swap4(LCDByte)   'Swap byte; Most significant NIBBLE sent first 
                LCD2_NIBBLEOUT LCDByte          'Less Significant NIBBLE output
            #ENDIF
    
            #IFDEF LCD_IO 4
                'Set pins to output
                DIR LCD_DB4 OUT
                DIR LCD_DB5 OUT
                DIR LCD_DB6 OUT
                DIR LCD_DB7 OUT
    
                'Write upper nibble to output pins
                set LCD_DB4 OFF
                set LCD_DB5 OFF
                set LCD_DB6 OFF
                set LCD_DB7 OFF
                if LCDByte.7 ON THEN SET LCD_DB7 ON
                if LCDByte.6 ON THEN SET LCD_DB6 ON
                if LCDByte.5 ON THEN SET LCD_DB5 ON
                if LCDByte.4 ON THEN SET LCD_DB4 ON
    
                'Pulse enable pin
                Wait 5 10us
                PULSEOUT LCD_Enable, 5 10us
                Wait 5 10us
    
                'Write lower nibble to output pins
                set LCD_DB4 OFF
                set LCD_DB5 OFF
                set LCD_DB6 OFF
                set LCD_DB7 OFF
                if LCDByte.3 ON THEN SET LCD_DB7 ON
                if LCDByte.2 ON THEN SET LCD_DB6 ON
                if LCDByte.1 ON THEN SET LCD_DB5 ON
                if LCDByte.0 ON THEN SET LCD_DB4 ON
    
                'Pulse enable pin
                Wait 5 10us
                PULSEOUT LCD_Enable, 5 10us
                Wait 5 10us
    
                'Set data pins low again
                SET LCD_DB7 OFF
                SET LCD_DB6 OFF
                SET LCD_DB5 OFF
                SET LCD_DB4 OFF
            #ENDIF
    
            #IFDEF LCD_IO 8
                'Set data port to output, and write a value to it
                DIR LCD_DATA_PORT out
                LCD_DATA_PORT = LCDByte
    
                'Pulse enable pin
                Wait 5 10us
                PULSEOUT LCD_Enable, 5 10us
                Wait 5 10us
    
                'Clear port again, in case it is shared with something else
                LCD_DATA_PORT = 0
            #ENDIF
        #ENDIF
        #IFDEF LCD_CUSTOM
            DIR LCD_DB0 OUT
            DIR LCD_DB1 OUT
            DIR LCD_DB2 OUT
            DIR LCD_DB3 OUT
            DIR LCD_DB4 OUT
            DIR LCD_DB5 OUT
            DIR LCD_DB6 OUT
            DIR LCD_DB7 OUT
    
            set LCD_DB0 OFF
            set LCD_DB1 OFF
            set LCD_DB2 OFF
            set LCD_DB3 OFF
            set LCD_DB4 OFF
            set LCD_DB5 OFF
            set LCD_DB6 OFF
            set LCD_DB7 OFF
    
            if LCDByte.7 ON THEN SET LCD_DB7 ON
            if LCDByte.6 ON THEN SET LCD_DB6 ON
            if LCDByte.5 ON THEN SET LCD_DB5 ON
            if LCDByte.4 ON THEN SET LCD_DB4 ON      
            if LCDByte.3 ON THEN SET LCD_DB3 ON
            if LCDByte.2 ON THEN SET LCD_DB2 ON
            if LCDByte.1 ON THEN SET LCD_DB1 ON
            if LCDByte.0 ON THEN SET LCD_DB0 ON
    
            'Pulse enable pin
            Wait 5 10us
            PULSEOUT LCD_Enable, 5 10us
            Wait 5 10us
    
            set LCD_DB0 OFF
            set LCD_DB1 OFF
            set LCD_DB2 OFF
            set LCD_DB3 OFF
            set LCD_DB4 OFF
            set LCD_DB5 OFF
            set LCD_DB6 OFF
            set LCD_DB7 OFF
        #ENDIF
    
    end sub
    SUB LCD2_NIBBLEOUT (In LCD2BYTE)
     'Set Data and Clock bits off
     SET LCD_DB OFF
     SET LCD_CB OFF
     'Clear Shift Register With six 0s prior to loading
     FOR LCDTemp = 1 TO 6   
      SET LCD_CB ON  ' STROBE
      SET LCD_CB OFF ' ======
     NEXT
     SET LCD_DB ON  ' First bit out to Shift register, always 1 for E gate
     SET LCD_CB ON  ' STROBE
     SET LCD_CB OFF ' ======
     IF LCD_RS OFF THEN SET LCD_DB OFF ' Second bit out equal to R/S
     SET LCD_CB ON  ' STROBE
     SET LCD_CB OFF ' ======                                    
     '4 bits Data out to Shift register, starting from Nibble most significant bit
     FOR LCDTemp = 1 to 4
      SET LCD_DB OFF
      IF LCD2Byte.3 ON THEN SET LCD_DB ON
      SET LCD_CB ON
      SET LCD_CB OFF
      ROTATE LCD2Byte LEFT
     NEXT
    SET LCD_DB ON               ' Last pulse for Nibble output. Not for Shift register
    WAIT 1 MS               ' Put E pin on LCD to one through an AND operation 
    SET LCD_DB OFF              ' with the first bit outputted (E)
    END SUB
    function LCDNormalReadByte
        #IFDEF LCD_NO_RW
            LCDReadByte = 0
            Exit Function
        #ENDIF
    
        #IFNDEF LCD_NO_RW
    
            set LCD_RW ON 'Read mode
            LCDReadByte = 0
    
            #IFNDEF LCD_CUSTOM
                #IFDEF LCD_IO 4
                    'Set pins to input
                    DIR LCD_DB4 IN
                    DIR LCD_DB5 IN
                    DIR LCD_DB6 IN
                    DIR LCD_DB7 IN
    
                    'Read upper nibble from input pins
                    SET LCD_Enable ON
                    Wait LCD_Write_Delay
                    if LCD_DB7 ON then SET LCDReadByte.7 ON
                    if LCD_DB6 ON THEN SET LCDReadByte.6 ON
                    if LCD_DB5 ON then SET LCDReadByte.5 ON
                    if LCD_DB4 ON THEN SET LCDReadByte.4 ON
                    SET LCD_Enable OFF
                    Wait 2 10us
    
                    'Read lower nibble from input pins
                    SET LCD_Enable ON
                    Wait LCD_Write_Delay
                    if LCD_DB7 ON then SET LCDReadByte.3 ON
                    if LCD_DB6 ON THEN SET LCDReadByte.2 ON
                    if LCD_DB5 ON then SET LCDReadByte.1 ON
                    if LCD_DB4 ON THEN SET LCDReadByte.0 ON
                    SET LCD_Enable OFF
                    Wait 2 10us
                #ENDIF
    
                #IFDEF LCD_IO 8
                    DIR LCD_DATA_PORT 255
                    SET LCD_Enable ON
                    Wait LCD_Write_Delay
                    LCDReadByte = LCD_DATA_PORT
                    SET LCD_Enable OFF
                    Wait 2 10us
                #ENDIF
            #ENDIF
            IFDEF LCD_CUSTOM
                'Set pins to input
                DIR LCD_DB1 IN
                DIR LCD_DB2 IN
                DIR LCD_DB2 IN
                DIR LCD_DB3 IN
                DIR LCD_DB4 IN
                DIR LCD_DB5 IN
                DIR LCD_DB6 IN
                DIR LCD_DB7 IN
                SET LCD_Enable ON
                Wait LCD_Write_Delay
                if LCD_DB7 ON then SET LCDReadByte.7 ON
                if LCD_DB6 ON THEN SET LCDReadByte.6 ON
                if LCD_DB5 ON then SET LCDReadByte.5 ON
                if LCD_DB4 ON THEN SET LCDReadByte.4 ON
                if LCD_DB3 ON then SET LCDReadByte.3 ON
                if LCD_DB2 ON THEN SET LCDReadByte.2 ON
                if LCD_DB1 ON then SET LCDReadByte.1 ON
                if LCD_DB0 ON THEN SET LCDReadByte.0 ON
                SET LCD_Enable OFF
                Wait 2 10us
            #ENDIF
        #ENDIF
    end function
    sub InitLCD
    
        #IFNDEF LCD_CUSTOM
            #IFDEF LCD_IO 2
                SET LCD_DB OFF
                SET LCD_CB OFF
                DIR LCD_DB OUT
                DIR LCD_CB OUT
                WAIT 35 MS
                SET LCD_RS OFF
                LCD2_NIBBLEOUT 0X03
                Wait 5 ms
                LCD2_NIBBLEOUT 0X03
                WAIT 1 MS
                LCD2_NIBBLEOUT 0X03
                WAIT 1 MS
                LCD2_NIBBLEOUT 0X02
                WAIT 1 MS
                LCDWriteByte 0x28
                WAIT 1 MS
                LCDWriteByte 0x08
                WAIT 1 MS
                LCDWriteByte 0x01
                WAIT 5 MS
                LCDWriteByte 0x06
                WAIT 1 MS
                LCDWriteByte 0x0C
                WAIT 1 MS
            #ENDIF
    
            #IFDEF LCD_IO 4,8
                DIR LCD_RS OUT
                #IFNDEF LCD_NO_RW
                    DIR LCD_RW OUT
                #ENDIF
                DIR LCD_Enable OUT
                wait 10 ms
                Wait until LCDReady
    
                'Set data bus width
                SET LCD_RS OFF
            #ENDIF
            #IFDEF LCD_IO 8
                LCDWriteByte(b'00111000') 
            #ENDIF
            #IFDEF LCD_IO 4
                DIR LCD_DB4 OUT
                DIR LCD_DB5 OUT
                DIR LCD_DB6 OUT
                DIR LCD_DB7 OUT
                set LCD_RS OFF
                #IFNDEF LCD_NO_RW
                    set LCD_RW OFF
                #ENDIF
                set LCD_DB4 OFF
                set LCD_DB5 ON
                set LCD_DB6 OFF
                set LCD_DB7 OFF
                Wait 5 10us
                PulseOut LCD_Enable, 5 10us
                Wait 5 ms
    
                LCDWriteByte(b'00101000')
                wait 25 10us
            #ENDIF
            #IFDEF LCD_IO 4,8
    
                'Set Cursor movement
                SET LCD_RS OFF
                LCDWriteByte(b'00000110')
                wait 5 10us
                'Turn off cursor
                LCDWriteByte(b'00001100')
                wait 5 10us
    
                'Clear screen
                CLS
            #ENDIF
        #ENDIF
        #IFDEF LCD_CUSTOM
            DIR LCD_RS OUT
            #IFNDEF LCD_NO_RW
                DIR LCD_RW OUT
            #ENDIF
            DIR LCD_Enable OUT
            wait 10 ms
            Wait until LCDReady
    
            'Set data bus width
            SET LCD_RS OFF
            LCDWriteByte(b'00111000')
        #ENDIF
    end sub
    sub LCDCursor(In LCDCRSR)
        'Can be ON, FLASH or OFF
        Set LCD_RW OFF
        LCDTemp = 12 '0 or 12
        If LCDCRSR = ON Then LCDTemp = 14 '2 or 12
        If LCDCRSR = FLASH Then LCDTemp = 15 '3 or 12
        'If LCDCRSR = OFF Then LCDTemp = 0 or 12
        LCDWriteByte(LCDTemp) '(LCDTemp or 12)
        Wait 5 10us
    end sub
    'Create a custom character in CGRAM
    sub LCDCreateChar (In LCDCharLoc, LCDCharData())
    
        #IFNDEF LCD_CUSTOM
            'Store old location
            #IFDEF LCD_IO 4,8
                Set LCD_RS Off
                LCDLoc = LCDReadByte
                Set LCDLoc.7 On
            #ENDIF
    
            'Select location
            Set LCD_RS Off
            LCDWriteByte (64 + LCDCharLoc * 8)
            wait 5 10us
    
            'Write char
            Set LCD_RS On
            For LCDTemp = 1 to 8
                LCDWriteByte LCDCharData(LCDTemp)
                wait 5 10us
            Next
    
            'Restore location
            #IFDEF LCD_IO 2
                set LCD_RS off
                LCDWriteByte(0x80)
                wait 5 10us
            #ENDIF
            #IFDEF LCD_IO 4,8
                Set LCD_RS Off
                LCDWriteByte (LCDLoc)
                wait 5 10us
            #ENDIF
        #ENDIF
        #IFDEF LCD_CUSTOM
            'Store old location
            Set LCD_RS Off
            LCDLoc = LCDReadByte
            Set LCDLoc.7 On
            'Select location
            Set LCD_RS Off
            LCDWriteByte (64 + LCDCharLoc * 8)
            wait 5 10us
    
            'Write char
            Set LCD_RS On
            For LCDTemp = 1 to 8
                LCDWriteByte LCDCharData(LCDTemp)
                wait 5 10us
            Next
    
            'Restore location
            Set LCD_RS Off
            LCDWriteByte (LCDLoc)
            wait 5 10us
        #ENDIF
    end sub
    'Create a graph character in CGRAM
    Sub LCDCreateGraph(In LCDCharLoc, In LCDValue)
        #IFNDEF LCD_CUSTOM
            'Store old location
            #IFDEF LCD_IO 4,8
                Set LCD_RS Off
                LCDLoc = LCDReadByte
                Set LCDLoc.7 On
            #ENDIF
    
            'Select location
            Set LCD_RS Off
            LCDWriteByte (64 + LCDCharLoc * 8)
            wait 5 10us
    
            'Write char for graph
            Set LCD_RS On
            For LCDTemp = 8 to 1
                If LCDTemp > LCDValue Then
                    LCDWriteByte LCD_BAR_EMPTY
                Else
                    LCDWriteByte LCD_BAR_FULL
                End If
                wait 5 10us
            Next
    
            'Restore location
            #IFDEF LCD_IO 2
                set LCD_RS off
                LCDWriteByte(0x80)
                wait 5 10us
            #ENDIF
            #IFDEF LCD_IO 4,8
                Set LCD_RS Off
                LCDWriteByte (LCDLoc)
                wait 5 10us
            #ENDIF
        #ENDIF
    
        #IFDEF LCD_CUSTOM
            'Store old location
            Set LCD_RS Off
            LCDLoc = LCDReadByte
            Set LCDLoc.7 On
    
            'Select location
            Set LCD_RS Off
            LCDWriteByte (64 + LCDCharLoc * 8)
            wait 5 10us
    
            'Write char for graph
            Set LCD_RS On
            For LCDTemp = 8 to 1
                If LCDTemp > LCDValue Then
                    LCDWriteByte LCD_BAR_EMPTY
                Else
                    LCDWriteByte LCD_BAR_FULL
                End If
                wait 5 10us
            Next
    
            'Restore location
            Set LCD_RS Off
            LCDWriteByte (LCDLoc)
            wait 5 10us
        #ENDIF
    End Sub
    
     
  • Chris

    Chris - 2012-08-15

    i was missing some code in the init section to set the cursor movement, here is the corrected code which i have tested to work in a simulator

    '    Liquid Crystal Display routines for Great Cow BASIC
    '    Copyright (C) 2006 - 2009 Hugh Considine, Stefano Bonomi
    '    This library is free software; you can redistribute it and/or
    '    modify it under the terms of the GNU Lesser General Public
    '    License as published by the Free Software Foundation; either
    '    version 2.1 of the License, or (at your option) any later version.
    '    This library is distributed in the hope that it will be useful,
    '    but WITHOUT ANY WARRANTY; without even the implied warranty of
    '    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    '    Lesser General Public License for more details.
    '    You should have received a copy of the GNU Lesser General Public
    '    License along with this library; if not, write to the Free Software
    '    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    '********************************************************************************
    'IMPORTANT:
    'THIS FILE IS ESSENTIAL FOR SOME OF THE COMMANDS IN GCBASIC. DO NOT ALTER THIS FILE
    'UNLESS YOU KNOW WHAT YOU ARE DOING. CHANGING THIS FILE COULD RENDER SOME GCBASIC
    'COMMANDS UNUSABLE!
    '********************************************************************************
    'Credits:
    ' 4 and 8 bit routines  Hugh Considine
    ' 2 bit routines    Stefano Bonomi
    ' Testing       Stefano Adami
    #startup InitLCD
    'I/O Ports
    #define LCD_IO 4 'Number of pins used for LCD data bus (2, 4 or 8)
    'Sub used to write to LCD. Can be altered to allow custom LCD interfaces.
    #define LCDWriteByte LCDNormalWriteByte
    #define LCDReadByte LCDNormalReadByte
    #define LCD_DB SysLCDTemp.0 'Data bit. Used in 2-bit mode
    #define LCD_CB SysLCDTemp.0 'Clock bit. Used in 2-bit mode
    #define LCD_DATA_PORT SysLCDTemp 'Port to connect to LCD data bus. Used in 8-bit mode
    #define LCD_DB0 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in Custom mode
    #define LCD_DB1 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in Custom mode
    #define LCD_DB2 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in Custom mode
    #define LCD_DB3 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in Custom mode
    #define LCD_DB4 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in 4-bit mode
    #define LCD_DB5 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in 4-bit mode
    #define LCD_DB6 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in 4-bit mode
    #define LCD_DB7 SysLCDTemp.0 'Output bit to interface with LCD data bus. Used in 4-bit mode
    #define LCD_RS SysLCDTemp.1 'Output bit to control LCD Register Select. Used as variable by 2-bit mode, and as a pin in 4 and 8 bit mode. DO NOT CHANGE FOR 2-BIT MODE.
    #define LCD_RW SysLCDTemp.0 'Output bit to select read/write
    #define LCD_Enable SysLCDTemp.0 'Output bit to enable/disable LCD
    #define LCD_RSTemp SysLCDTemp.2
    'Misc Settings
    #define LCD_Write_Delay 8 10us
    #define FLASH 2
    '#define LCD_NO_RW
    'Lines for bar graph
    #define LCD_BAR_EMPTY b'00010001'
    #define LCD_BAR_FULL 255
    Sub PUT (In LCDPutLine, In LCDPutColumn, In LCDChar)
        LOCATE LCDPutLine, LCDPutColumn
        Set LCD_RS on
        LCDWriteByte(LCDChar)
    End Sub
    'GET not available in 2-bit mode
    Function GET (LCDPutLine, LCDPutColumn)
        Locate LCDPutLine, LCDPutColumn
        Set LCD_RS on
        GET = LCDReadByte
    End Function
    'LCDColumn is 0 to screen width-1, LCDLine is 0 to screen height-1
    Sub LOCATE (In LCDLine, In LCDColumn)
        Set LCD_RS Off
        If LCDLine > 1 Then
            LCDLine = LCDLine - 2
            LCDColumn = LCDColumn + 20
        End If
    
        LCDWriteByte(0x80 or 0x40 * LCDLine + LCDColumn)
        Wait 5 10us
    End Sub
    Sub CLS
        SET LCD_RS OFF
    
        'Clear screen
        LCDWriteByte (b'00000001')
        Wait 2 ms
    
        'Move to start of visible DDRAM
        LCDWriteByte(0x80)
        Wait 10 10us
    End Sub
    'Compatibility with older programs
    #define LCDInt Print
    #define LCDWord Print
    'String output
    sub Print (PrintData As String)
        'PrintLen = LEN(PrintData$)
        PrintLen = PrintData(0)
    
        If PrintLen = 0 Then Exit Sub
        Set LCD_RS On
    
        'Write Data
        For SysPrintTemp = 1 To PrintLen
            LCDWriteByte PrintData(SysPrintTemp)
        Next
    
    End Sub
    Sub Print (In LCDValue)
    
        LCDValueTemp = 0
        Set LCD_RS On
    
        IF LCDValue >= 100 Then
            LCDValueTemp = LCDValue / 100
            LCDValue = SysCalcTempX
            LCDWriteByte(LCDValueTemp + 48)
        End If
        If LCDValueTemp > 0 Or LCDValue >= 10 Then
            LCDValueTemp = LCDValue / 10
            LCDValue = SysCalcTempX
            LCDWriteByte(LCDValueTemp + 48)
        End If
        LCDWriteByte (LCDValue + 48)
    End Sub
    Sub Print (In LCDValue As Word)
        Dim SysCalcTempX As Word
        Set LCD_RS On
        LCDValueTemp = 0
    
        If LCDValue >= 10000 then 
            LCDValueTemp = LCDValue / 10000 [word]
            LCDValue = SysCalcTempX
            LCDWriteByte(LCDValueTemp + 48)
            Goto LCDPrintWord1000
        End If
        If LCDValue >= 1000 then
            LCDPrintWord1000:
            LCDValueTemp = LCDValue / 1000 [word]
            LCDValue = SysCalcTempX
            LCDWriteByte(LCDValueTemp + 48)
            Goto LCDPrintWord100
        End If
        If LCDValue >= 100 then
            LCDPrintWord100:
            LCDValueTemp = LCDValue / 100 [word]
            LCDValue = SysCalcTempX
            LCDWriteByte(LCDValueTemp + 48)
            Goto LCDPrintWord10
        End If
        If LCDValue >= 10 then
            LCDPrintWord10:
            LCDValueTemp = LCDValue / 10 [word]
            LCDValue = SysCalcTempX
            LCDWriteByte(LCDValueTemp + 48)
        End If
        LCDWriteByte (LCDValue + 48)
    End Sub
    Sub Print (In LCDValueInt As Integer)
        Dim LCDValue As Word
    
        'If sign bit is on, print - sign and then negate
        If LCDValueInt.15 = On Then
            LCDWriteChar("-")
            LCDValue = -LCDValueInt
    
        'Sign bit off, so just copy value
        Else
            LCDValue = LCDValueInt
        End If
    
        'Use Print(word) to display value
        Print LCDValue
    End Sub
    sub LCDHex(In LCDValue)
        LCDValueTemp = 0
        Set LCD_RS On
    
        IF LCDValue >= 0x10 then
            LCDValueTemp = LCDValue / 0x10
            LCDValue = SysCalcTempX
            LCDHexValueTemp = LCDValueTemp
            if LCDHexValueTemp > 9 then LCDHexValueTemp = LCDHexValueTemp + 7
            LCDWriteByte(LCDHexValueTemp + 48)
        end if
    
        LCDHexValueTemp = LCDValue
        if LCDHexValueTemp > 9 then LCDHexValueTemp = LCDHexValueTemp + 7
        LCDWriteByte (LCDHexValueTemp + 48)
    
    end sub
    sub LCDWriteChar(In LCDChar)
        set LCD_RS on
        LCDWriteByte(LCDChar)
    end sub
    function LCDReady
        #IFDEF LCD_NO_RW
            Wait 10 ms
            LCDReady = TRUE
            exit function
        #ENDIF
    
        #IFNDEF LCD_NO_RW
            #IFNDEF LCD_CUSTOM          
                #IFDEF LCD_IO 2
                    LCDReady = TRUE
                    exit function
                #ENDIF
                #IFDEF LCD_IO 4,8
                    LCDReady = FALSE
                    LCD_RSTemp = LCD_RS
    
                    SET LCD_RW ON
                    SET LCD_RS OFF
                    Wait 5 10us
                    SET LCD_Enable ON
                    wait 5 10us
                    #IFDEF LCD_IO 4
                        dir LCD_DB7 IN
                        if LCD_DB7 OFF THEN LCDReady = TRUE
                    #ENDIF
                    #IFDEF LCD_IO 8
                        dir LCD_DATA_PORT In
                        if LCD_DATA_PORT.7 OFF THEN LCDReady = TRUE
                    #ENDIF
                    SET LCD_Enable OFF
                    wait 25 10us
                    LCD_RS = LCD_RSTemp
                #ENDIF
            #ENDIF
    
            #IFDEF LCD_CUSTOM
                LCDReady = FALSE
                LCD_RSTemp = LCD_RS
    
                SET LCD_RW ON
                SET LCD_RS OFF
                Wait 5 10us
                SET LCD_Enable ON
                wait 5 10us
    
                DIR LCD_DB0 OUT
                DIR LCD_DB1 OUT
                DIR LCD_DB2 OUT
                DIR LCD_DB3 OUT
                DIR LCD_DB4 OUT
                DIR LCD_DB5 OUT
                DIR LCD_DB6 OUT
                DIR LCD_DB7 OUT
                if LCD_DB7 OFF THEN LCDReady = TRUE
                SET LCD_Enable OFF
                wait 25 10us
                LCD_RS = LCD_RSTemp
            #ENDIF
        #ENDIF
    end function
    sub LCDNormalWriteByte(In LCDByte)
    
        #IFNDEF LCD_NO_RW
            #IFNDEF LCD_CUSTOM
                #IFDEF LCD_IO 4,8
                    wait until LCDReady
                    set LCD_RW OFF 'Write mode
                #ENDIF
            #ENDIF
            #IFDEF LCD_CUSTOM
                wait until LCDReady
                set LCD_RW OFF 'Write mode
            #ENDIF
        #ENDIF
    
        #IFNDEF LCD_CUSTOM
            #IFDEF LCD_IO 2
                LCD2_NIBBLEOUT Swap4(LCDByte)   'Swap byte; Most significant NIBBLE sent first 
                LCD2_NIBBLEOUT LCDByte          'Less Significant NIBBLE output
            #ENDIF
    
            #IFDEF LCD_IO 4
                'Set pins to output
                DIR LCD_DB4 OUT
                DIR LCD_DB5 OUT
                DIR LCD_DB6 OUT
                DIR LCD_DB7 OUT
    
                'Write upper nibble to output pins
                set LCD_DB4 OFF
                set LCD_DB5 OFF
                set LCD_DB6 OFF
                set LCD_DB7 OFF
                if LCDByte.7 ON THEN SET LCD_DB7 ON
                if LCDByte.6 ON THEN SET LCD_DB6 ON
                if LCDByte.5 ON THEN SET LCD_DB5 ON
                if LCDByte.4 ON THEN SET LCD_DB4 ON
    
                'Pulse enable pin
                Wait 5 10us
                PULSEOUT LCD_Enable, 5 10us
                Wait 5 10us
    
                'Write lower nibble to output pins
                set LCD_DB4 OFF
                set LCD_DB5 OFF
                set LCD_DB6 OFF
                set LCD_DB7 OFF
                if LCDByte.3 ON THEN SET LCD_DB7 ON
                if LCDByte.2 ON THEN SET LCD_DB6 ON
                if LCDByte.1 ON THEN SET LCD_DB5 ON
                if LCDByte.0 ON THEN SET LCD_DB4 ON
    
                'Pulse enable pin
                Wait 5 10us
                PULSEOUT LCD_Enable, 5 10us
                Wait 5 10us
    
                'Set data pins low again
                SET LCD_DB7 OFF
                SET LCD_DB6 OFF
                SET LCD_DB5 OFF
                SET LCD_DB4 OFF
            #ENDIF
    
            #IFDEF LCD_IO 8
                'Set data port to output, and write a value to it
                DIR LCD_DATA_PORT out
                LCD_DATA_PORT = LCDByte
    
                'Pulse enable pin
                Wait 5 10us
                PULSEOUT LCD_Enable, 5 10us
                Wait 5 10us
    
                'Clear port again, in case it is shared with something else
                LCD_DATA_PORT = 0
            #ENDIF
        #ENDIF
        #IFDEF LCD_CUSTOM
            DIR LCD_DB0 OUT
            DIR LCD_DB1 OUT
            DIR LCD_DB2 OUT
            DIR LCD_DB3 OUT
            DIR LCD_DB4 OUT
            DIR LCD_DB5 OUT
            DIR LCD_DB6 OUT
            DIR LCD_DB7 OUT
    
            set LCD_DB0 OFF
            set LCD_DB1 OFF
            set LCD_DB2 OFF
            set LCD_DB3 OFF
            set LCD_DB4 OFF
            set LCD_DB5 OFF
            set LCD_DB6 OFF
            set LCD_DB7 OFF
    
            if LCDByte.7 ON THEN SET LCD_DB7 ON
            if LCDByte.6 ON THEN SET LCD_DB6 ON
            if LCDByte.5 ON THEN SET LCD_DB5 ON
            if LCDByte.4 ON THEN SET LCD_DB4 ON      
            if LCDByte.3 ON THEN SET LCD_DB3 ON
            if LCDByte.2 ON THEN SET LCD_DB2 ON
            if LCDByte.1 ON THEN SET LCD_DB1 ON
            if LCDByte.0 ON THEN SET LCD_DB0 ON
    
            'Pulse enable pin
            Wait 5 10us
            PULSEOUT LCD_Enable, 5 10us
            Wait 5 10us
    
            set LCD_DB0 OFF
            set LCD_DB1 OFF
            set LCD_DB2 OFF
            set LCD_DB3 OFF
            set LCD_DB4 OFF
            set LCD_DB5 OFF
            set LCD_DB6 OFF
            set LCD_DB7 OFF
        #ENDIF
    
    end sub
    SUB LCD2_NIBBLEOUT (In LCD2BYTE)
     'Set Data and Clock bits off
     SET LCD_DB OFF
     SET LCD_CB OFF
     'Clear Shift Register With six 0s prior to loading
     FOR LCDTemp = 1 TO 6   
      SET LCD_CB ON  ' STROBE
      SET LCD_CB OFF ' ======
     NEXT
     SET LCD_DB ON  ' First bit out to Shift register, always 1 for E gate
     SET LCD_CB ON  ' STROBE
     SET LCD_CB OFF ' ======
     IF LCD_RS OFF THEN SET LCD_DB OFF ' Second bit out equal to R/S
     SET LCD_CB ON  ' STROBE
     SET LCD_CB OFF ' ======                                    
     '4 bits Data out to Shift register, starting from Nibble most significant bit
     FOR LCDTemp = 1 to 4
      SET LCD_DB OFF
      IF LCD2Byte.3 ON THEN SET LCD_DB ON
      SET LCD_CB ON
      SET LCD_CB OFF
      ROTATE LCD2Byte LEFT
     NEXT
    SET LCD_DB ON               ' Last pulse for Nibble output. Not for Shift register
    WAIT 1 MS               ' Put E pin on LCD to one through an AND operation 
    SET LCD_DB OFF              ' with the first bit outputted (E)
    END SUB
    function LCDNormalReadByte
        #IFDEF LCD_NO_RW
            LCDReadByte = 0
            Exit Function
        #ENDIF
    
        #IFNDEF LCD_NO_RW
    
            set LCD_RW ON 'Read mode
            LCDReadByte = 0
    
            #IFNDEF LCD_CUSTOM
                #IFDEF LCD_IO 4
                    'Set pins to input
                    DIR LCD_DB4 IN
                    DIR LCD_DB5 IN
                    DIR LCD_DB6 IN
                    DIR LCD_DB7 IN
    
                    'Read upper nibble from input pins
                    SET LCD_Enable ON
                    Wait LCD_Write_Delay
                    if LCD_DB7 ON then SET LCDReadByte.7 ON
                    if LCD_DB6 ON THEN SET LCDReadByte.6 ON
                    if LCD_DB5 ON then SET LCDReadByte.5 ON
                    if LCD_DB4 ON THEN SET LCDReadByte.4 ON
                    SET LCD_Enable OFF
                    Wait 2 10us
    
                    'Read lower nibble from input pins
                    SET LCD_Enable ON
                    Wait LCD_Write_Delay
                    if LCD_DB7 ON then SET LCDReadByte.3 ON
                    if LCD_DB6 ON THEN SET LCDReadByte.2 ON
                    if LCD_DB5 ON then SET LCDReadByte.1 ON
                    if LCD_DB4 ON THEN SET LCDReadByte.0 ON
                    SET LCD_Enable OFF
                    Wait 2 10us
                #ENDIF
    
                #IFDEF LCD_IO 8
                    DIR LCD_DATA_PORT 255
                    SET LCD_Enable ON
                    Wait LCD_Write_Delay
                    LCDReadByte = LCD_DATA_PORT
                    SET LCD_Enable OFF
                    Wait 2 10us
                #ENDIF
            #ENDIF
            IFDEF LCD_CUSTOM
                'Set pins to input
                DIR LCD_DB1 IN
                DIR LCD_DB2 IN
                DIR LCD_DB2 IN
                DIR LCD_DB3 IN
                DIR LCD_DB4 IN
                DIR LCD_DB5 IN
                DIR LCD_DB6 IN
                DIR LCD_DB7 IN
                SET LCD_Enable ON
                Wait LCD_Write_Delay
                if LCD_DB7 ON then SET LCDReadByte.7 ON
                if LCD_DB6 ON THEN SET LCDReadByte.6 ON
                if LCD_DB5 ON then SET LCDReadByte.5 ON
                if LCD_DB4 ON THEN SET LCDReadByte.4 ON
                if LCD_DB3 ON then SET LCDReadByte.3 ON
                if LCD_DB2 ON THEN SET LCDReadByte.2 ON
                if LCD_DB1 ON then SET LCDReadByte.1 ON
                if LCD_DB0 ON THEN SET LCDReadByte.0 ON
                SET LCD_Enable OFF
                Wait 2 10us
            #ENDIF
        #ENDIF
    end function
    sub InitLCD
    
        #IFNDEF LCD_CUSTOM
            #IFDEF LCD_IO 2
                SET LCD_DB OFF
                SET LCD_CB OFF
                DIR LCD_DB OUT
                DIR LCD_CB OUT
                WAIT 35 MS
                SET LCD_RS OFF
                LCD2_NIBBLEOUT 0X03
                Wait 5 ms
                LCD2_NIBBLEOUT 0X03
                WAIT 1 MS
                LCD2_NIBBLEOUT 0X03
                WAIT 1 MS
                LCD2_NIBBLEOUT 0X02
                WAIT 1 MS
                LCDWriteByte 0x28
                WAIT 1 MS
                LCDWriteByte 0x08
                WAIT 1 MS
                LCDWriteByte 0x01
                WAIT 5 MS
                LCDWriteByte 0x06
                WAIT 1 MS
                LCDWriteByte 0x0C
                WAIT 1 MS
            #ENDIF
    
            #IFDEF LCD_IO 4,8
                DIR LCD_RS OUT
                #IFNDEF LCD_NO_RW
                    DIR LCD_RW OUT
                #ENDIF
                DIR LCD_Enable OUT
                wait 10 ms
                Wait until LCDReady
    
                'Set data bus width
                SET LCD_RS OFF
            #ENDIF
            #IFDEF LCD_IO 8
                LCDWriteByte(b'00111000') 
            #ENDIF
            #IFDEF LCD_IO 4
                DIR LCD_DB4 OUT
                DIR LCD_DB5 OUT
                DIR LCD_DB6 OUT
                DIR LCD_DB7 OUT
                set LCD_RS OFF
                #IFNDEF LCD_NO_RW
                    set LCD_RW OFF
                #ENDIF
                set LCD_DB4 OFF
                set LCD_DB5 ON
                set LCD_DB6 OFF
                set LCD_DB7 OFF
                Wait 5 10us
                PulseOut LCD_Enable, 5 10us
                Wait 5 ms
    
                LCDWriteByte(b'00101000')
                wait 25 10us
            #ENDIF
            #IFDEF LCD_IO 4,8
    
                'Set Cursor movement
                SET LCD_RS OFF
                LCDWriteByte(b'00000110')
                wait 5 10us
                'Turn off cursor
                LCDWriteByte(b'00001100')
                wait 5 10us
    
                'Clear screen
                CLS
            #ENDIF
        #ENDIF
        #IFDEF LCD_CUSTOM
            DIR LCD_RS OUT
            #IFNDEF LCD_NO_RW
                DIR LCD_RW OUT
            #ENDIF
            DIR LCD_Enable OUT
            wait 10 ms
            Wait until LCDReady
    
            'Set data bus width
            SET LCD_RS OFF
            LCDWriteByte(b'00111000')
            'Set Cursor movement
            SET LCD_RS OFF
            LCDWriteByte(b'00000110')
            wait 5 10us
            'Turn off cursor
            LCDWriteByte(b'00001100')
            wait 5 10us
    
            'Clear screen
            CLS
        #ENDIF
    end sub
    sub LCDCursor(In LCDCRSR)
        'Can be ON, FLASH or OFF
        Set LCD_RW OFF
        LCDTemp = 12 '0 or 12
        If LCDCRSR = ON Then LCDTemp = 14 '2 or 12
        If LCDCRSR = FLASH Then LCDTemp = 15 '3 or 12
        'If LCDCRSR = OFF Then LCDTemp = 0 or 12
        LCDWriteByte(LCDTemp) '(LCDTemp or 12)
        Wait 5 10us
    end sub
    'Create a custom character in CGRAM
    sub LCDCreateChar (In LCDCharLoc, LCDCharData())
    
        #IFNDEF LCD_CUSTOM
            'Store old location
            #IFDEF LCD_IO 4,8
                Set LCD_RS Off
                LCDLoc = LCDReadByte
                Set LCDLoc.7 On
            #ENDIF
    
            'Select location
            Set LCD_RS Off
            LCDWriteByte (64 + LCDCharLoc * 8)
            wait 5 10us
    
            'Write char
            Set LCD_RS On
            For LCDTemp = 1 to 8
                LCDWriteByte LCDCharData(LCDTemp)
                wait 5 10us
            Next
    
            'Restore location
            #IFDEF LCD_IO 2
                set LCD_RS off
                LCDWriteByte(0x80)
                wait 5 10us
            #ENDIF
            #IFDEF LCD_IO 4,8
                Set LCD_RS Off
                LCDWriteByte (LCDLoc)
                wait 5 10us
            #ENDIF
        #ENDIF
        #IFDEF LCD_CUSTOM
            'Store old location
            Set LCD_RS Off
            LCDLoc = LCDReadByte
            Set LCDLoc.7 On
            'Select location
            Set LCD_RS Off
            LCDWriteByte (64 + LCDCharLoc * 8)
            wait 5 10us
    
            'Write char
            Set LCD_RS On
            For LCDTemp = 1 to 8
                LCDWriteByte LCDCharData(LCDTemp)
                wait 5 10us
            Next
    
            'Restore location
            Set LCD_RS Off
            LCDWriteByte (LCDLoc)
            wait 5 10us
        #ENDIF
    end sub
    'Create a graph character in CGRAM
    Sub LCDCreateGraph(In LCDCharLoc, In LCDValue)
        #IFNDEF LCD_CUSTOM
            'Store old location
            #IFDEF LCD_IO 4,8
                Set LCD_RS Off
                LCDLoc = LCDReadByte
                Set LCDLoc.7 On
            #ENDIF
    
            'Select location
            Set LCD_RS Off
            LCDWriteByte (64 + LCDCharLoc * 8)
            wait 5 10us
    
            'Write char for graph
            Set LCD_RS On
            For LCDTemp = 8 to 1
                If LCDTemp > LCDValue Then
                    LCDWriteByte LCD_BAR_EMPTY
                Else
                    LCDWriteByte LCD_BAR_FULL
                End If
                wait 5 10us
            Next
    
            'Restore location
            #IFDEF LCD_IO 2
                set LCD_RS off
                LCDWriteByte(0x80)
                wait 5 10us
            #ENDIF
            #IFDEF LCD_IO 4,8
                Set LCD_RS Off
                LCDWriteByte (LCDLoc)
                wait 5 10us
            #ENDIF
        #ENDIF
    
        #IFDEF LCD_CUSTOM
            'Store old location
            Set LCD_RS Off
            LCDLoc = LCDReadByte
            Set LCDLoc.7 On
    
            'Select location
            Set LCD_RS Off
            LCDWriteByte (64 + LCDCharLoc * 8)
            wait 5 10us
    
            'Write char for graph
            Set LCD_RS On
            For LCDTemp = 8 to 1
                If LCDTemp > LCDValue Then
                    LCDWriteByte LCD_BAR_EMPTY
                Else
                    LCDWriteByte LCD_BAR_FULL
                End If
                wait 5 10us
            Next
    
            'Restore location
            Set LCD_RS Off
            LCDWriteByte (LCDLoc)
            wait 5 10us
        #ENDIF
    End Sub
    
     
  • Chris

    Chris - 2012-08-19

    i have tested the software on the actual chip itself. this confirms that the issues arent from the simulator i am using. the software works fine on the chip, until i add extra lines in the code (setting the same variable to the same value multiple times). as soon as the code is over 2k in size the software no longer seems to be running at all on the chip

     
  • Chris

    Chris - 2012-08-20

    i looked more closely at my datasheet. an error im getting from the simulator  "attempt to read unimplemented memory location 0x049b" made me look at the memory location 0x049b, which is in bank 9. that location is shaded grey on the data sheet with a - there. is gcbasic trying to access a memory location that isnt accessible on my chip?

     
  • Chris

    Chris - 2012-08-20

    another thing ive noticed is the PCLATH never seems to change when run in the simulator, am i wrong or shouldnt the PCLATH be changing when reaching other memory pages. also the error im getting now is saying it cant read/write to "unimplemented memory location" 0x049c, according to the datasheet this location is in the general purpose register, so it seems its having a problem with ram? i mean i dont really know, i dont speak assembly language but i can make educated guesses

     
  • Chris

    Chris - 2012-08-20

    actually my mistake, 49c is an unimplemented area of the memory. so what i dont get is where, and why is it trying to read from 49c

     
  • Chris

    Chris - 2012-08-20

    ok, i know im making this forum post a mile long, however ive made some new discoveries. i made a much simpler program, which just simply clears an lcd, prints "Hello World" on an lcd, then waits 1 second. it does that about 40-50 times, which fills the first page of the program memory, then i go to a sub routine that does the same thing (clears the lcd, prints "Hello World" on it, then waits 1 second) and i set it to do that about 40-50 times. the program size ends up being 2968 bytes, which is over the 2k size barrier. this simple program runs just fine in the simulator, no errors or problems. so im thinking something else is causing my issues in me less simple program. maybe it could be the math (possibly a problem with math spanning multiple pages?) or i guess it could be a problem with my variable arrays? i mean im trying to track this problem down but it feels like i keep hitting a wall.

     
  • Chris

    Chris - 2012-08-21

    im getting unimplemented memory location again, this time i know what it is claiming is unimplemented. this spacific problem is this instruction "BSF Unimplemented" and the PC is 00FB
    the part that its saying is unimplemented is "0000FB 1513 BSF CCP3CON,CCP1M2"
    so it seems to be thinking "CCP3CPM,CCP1M1" is unimplemented. i think this is because its not BANKSEL'ing the CCP3CON. here is a small snippet of the .lst file

    000000  0028    PAGESEL SYSDIVSUB16
    0000F5  20FA    CALL SYSDIVSUB16
    000000  0020    PAGESEL $
    0000F7  0875    MOVF SYSCALCTEMPA,W
    000000  0026    BANKSEL CCPR3L
    0000F9  0091    MOVWF CCPR3L
    0000FA  1593    BSF CCP3CON,CCP1M3
    0000FB  1513    BSF CCP3CON,CCP1M2
    0000FC  1093    BCF CCP3CON,CCP1M1
    0000FD  1013    BCF CCP3CON,CCP1M0
            ENDIF96
    
     
  • Hugh Considine

    Hugh Considine - 2012-08-21

    Ok, I have found the bug!

    The assembler in GCBASIC is seeing "PAGESEL", and then using movlb (bank select) instead of movlp (page select). The giveaway is in the list file there - 0x0020 is BANKSEL 0, not PAGESEL $. Without pagesels, the code is probably not even running in the right order. I will upload a fix shortly.

     
  • Hugh Considine

    Hugh Considine - 2012-08-21

    I've now uploaded an updated version of GCBASIC to http://gcbasic.sourceforge.net/newfiles/update-nochipdata.zip - please try that and see if it fixes the bug!

     
  • Chris

    Chris - 2012-08-21

    perfect! thanks so much for your time it works perfect now

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.