With my new version of lock addin almost finished I started working on a new clock add-in and want it to be able to change one of the sprites on the screen by itself as soon as the backlight is off. Is it possible to read some value in the memory for backlight being on or off directly or do i have to keep tracking the time elapsed since last key press vs backlight timeout settings as a work around please?
You have to read some port bit:

Code:
Ports (SH-4A):
PTN4 : Backlight  (1=on, 0=off)

Ports (SH-3):
PTD5 : Backlight  (1=on, 0=off) [Slim]
PTG7 : Backlight  (1=on, 0=off) [GII]
PTG0 : Backlight  (0=on, 1=off) [S1600]
You could use getRawBacklightSubLevel (code taken from Utilities), I think.
Note that when the brightness level is set to the system's minimum, there is no backlight level difference at the timeout.

Code:

#define LCDC *(unsigned int*)(0xB4000000)
int getRawBacklightSubLevel()
{
  Bdisp_DDRegisterSelect(0x5a1);
  return (LCDC & 0xFF) - 6;
}
void setRawBacklightSubLevel(int level)
{
  Bdisp_DDRegisterSelect(0x5a1);
  LCDC = (level & 0xFF) + 6;
}
Thank you both (also for surprising me with all the knowledge out there on this calculator).

I have used utilities code before trying to set and reset background levels for something else but did not know it detects backlight being off too - will give it a try once I start my tests on the real hardware (emulator is no good for that unfortunately).

Regarding reading ports - I have never done it before (at least not knowingly) - is PTN4 a definition of a particular memory address or something else - would you have an example of reading this in C please or is it some assembly thing?

Kind regards and thanks again
I had a look at a few things but I don't know how to detect the LCD power-saving mode in getkey().

Code:

#pragma section _BR_Size
unsigned long BR_Size;
#pragma section

#define BLACK       0
#define BLUE        1
#define GREEN       2
#define CYAN        3
#define RED         4
#define MAGENTA     5
#define YELLOW      6
#define WHITE       7

int getkey(unsigned int *key);
void locate(int col, int row);
void print(const char *str, int color);
char get_light_level(void);
void set_light_level(char level);
void dec_light_level(void);
void inc_light_level(void);
void clr_light_level(void);

int
G3A_main(void)
{
    unsigned char ptn;
    unsigned int key;
    char str[] = "Backlight (DD)  : 0";

    while (1) {
        ptn = *(unsigned char *)0xA4050138;
        locate(1, 1);

        if (ptn & 0x10) // bit 4
            print("Backlight (PTN4): ON ", BLUE);
        else
            print("Backlight (PTN4): OFF", 0);

        str[18] = get_light_level() + 0x30;
        locate(1, 2);
        print(str, 0);
        getkey(&key);

        if (key == 0x0089) // '+'
            inc_light_level();
        if (key == 0x0099) // '-'
            dec_light_level();
        if (key == 0x7539) // F1
            clr_light_level();
    }

    return (1);
}


Code:

    .MACRO SYSCALL NUM, NAME
    .EXPORT \NAME
    \NAME:
        mov.l #h'0000\NUM, r0
        mov.l #h'80020070, r1
        jmp @r1
        nop
    .ENDM

    .SECTION P, CODE, ALIGN=4

    SYSCALL 0EAB, _getkey
    SYSCALL 1863, _locate
    SYSCALL 1868, _print
    SYSCALL 1E8F, _get_light_level
    SYSCALL 0199, _set_light_level
    SYSCALL 119A, _dec_light_level
    SYSCALL 119B, _inc_light_level
    SYSCALL 119C, _clr_light_level

    .END

set_light_level() should not be used as it does not set some RAM value which is needed to make the change permanent. And get_light_level() will return wrong results in that case.

Therefore, use the inc/dec backlight syscalls which call set_light_level() as well.
Some technical details: The backlight level is set via DD register 5A1h.

Other undocumented syscalls I have discovered:
- Syscall 0x1868 (r4 = str, r5 = color)
- some Print() routine
- Syscall 0x0277 (r4 = color16)
- some Bdisp_Fill_VRAM_1() routine
- Syscall 0x1900 (r4 = col, r5 = row, r6 = message no., r7 = color)
- some Bdisp_WriteSystemMessage() routine
- Syscall 0x1905 (r4 = x, r5 = y, r6 = message no., r7 = color)
- some Bdisp_WriteSystemMessage() routine
Quote:
#define LCDC *(unsigned int*)(0xB4000000)

That is a bug. Address 0xB4000000 always requires 16-bit word access!
This should be corrected to: #define LCDC (*(unsigned short *)0xB4000000)

Bad things can happen when the access size is wrong. E.g, when you access ports using the wrong register size, it will reset or hang the CPU.

And there is another bug: Always execute a SYNCO instruction (opcode 0x00AB) after writing to area 0xB4000000! Again, nasty things can happen when the CPU gets out of sync. When reading from area 0xB4000000, SYNCO does not seem to be required.

And there is a third bug: Bdisp_DDRegisterSelect() takes a word argument. This one could be ignored, but it would be better if the definition is changed to: void Bdisp_DDRegisterSelect(unsigned short reg);

Here is some assembly code from Prizm OS 2.00 for setting the backlight level:

Code:

    mov.w   #h'5A1, r4      ; r4 is the first function argument
    bsr     dd_reg_select   ; syscall 0x01A2 uses "mov.w r4, @(2,r15)"
    nop                     ; thus, r4 is expected to contain word data
    mov     #h'FFFFFFB4, r2
    extu.b  r14, r6         ; write data is byte (high byte is cleared)
    shll8   r2              ;
    shll16  r2              ; h'FFFFFFB4 is shifted to h'B4000000
    mov.w   r6, @r2         ;<-- word access for address 0xB4000000!
    synco                   ;<-- synco after data write to DD!
Thank you very much, TeamFX.

I will give it a try and report back.
Thanks again for all this above. I had a quick try of parts of your respective codes like this:

Code:
   int backlight;
   char level[21];
   while(1){
      backlight = GetBacklightSubLevel_RAW();
      itoa(backlight,(unsigned char*) level);
      PrintCXY(0,0,level,0,-1,0,BGC,1,0);
      if (ptn & 0x10) //by TeamFX
         PrintCXY(0,24,"ON ",0,-1,0,BGC,1,0);
      else PrintCXY(0,24,"OFF",0,-1,0,BGC,1,0);
.....
where GetBacklightSubLevel_RAW() is gbl08ma's getRawBacklightSubLevel() routine (and BGC a definition of background colour) and have so far the following observations:
gbl08ma's routine detects reduction of back light at power saving, and with the ptn routine above way and when using backlight.g3a on the emulator backlight shows as ON and on the real hardware it shows as off for backlight levels 1-3 and as on for levels 4-5.

TeamFX, I wonder if me hardware has different LCD to yours perhaps causing this problem - I will eventually try your add-in on another FX-CG to see if the outcome differs. Thanks in meantime for pointing out the other bugs before - I still have not figured out the synco bit - in an ideal world would it require the change in SDK libraries? I have never succeeded with assembly code yet...

Many thanks again
Quote:

...and with the ptn routine above way and when using backlight.g3a on the emulator backlight shows as ON and on the real hardware it shows as off for backlight levels 1-3 and as on for levels 4-5.
TeamFX, I wonder if me hardware has different LCD to yours perhaps causing this problem...

If the hardware shows a different behavior, then the emulator is doing a bad job.
PTN4 is only set for backlight levels 4 and 5, otherwise it is off.

Quote:
I still have not figured out the synco bit - in an ideal world would it require the change in SDK libraries?

I'm using the old ClassPad Hitachi compiler and this compiler does not know the SYNCO instruction. But I can add the line ".DATA.W h'00AB" somewhere in the assembly code and that's all I have to do. Yet, I have not figured out how to insert SYNCO in a C program without calling a subroutine. "#pragma inline_asm" seems to have a lot of restrictions.
TeamFX wrote:
Quote:

...and with the ptn routine above way and when using backlight.g3a on the emulator backlight shows as ON and on the real hardware it shows as off for backlight levels 1-3 and as on for levels 4-5.
TeamFX, I wonder if me hardware has different LCD to yours perhaps causing this problem...

If the hardware shows a different behavior, then the emulator is doing a bad job.
PTN4 is only set for backlight levels 4 and 5, otherwise it is off.

Quote:
I still have not figured out the synco bit - in an ideal world would it require the change in SDK libraries?

I'm using the old ClassPad Hitachi compiler and this compiler does not know the SYNCO instruction. But I can add the line ".DATA.W h'00AB" somewhere in the assembly code and that's all I have to do. Yet, I have not figured out how to insert SYNCO in a C program without calling a subroutine. "#pragma inline_asm" seems to have a lot of restrictions.
Thank you very much for explaining it all. Kind regards
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement