Welcome
Welcome to a320

You are currently viewing our boards as a guest, which gives you limited access to view most discussions and access our other features. By joining our free community, you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content, and access many other special features. Registration is fast, simple, and absolutely free, so please, join our community today!

Fast Double Buffering

Only for posting new releases of Dingoo OS based software.

Moderator: Moderators

Fast Double Buffering

Postby zaxxon on Sat Jun 20, 2009 6:29 pm

I found the address of the pointer to the video buffer for the firmware 1.03.
Changing the pointer before calling _lcd_set_frame() allows a fast double buffering.

Sample Code:
Code: Select all
int GameMain(char *respath)
{ unsigned long *Video = (unsigned long *)0x8023E07C;
  unsigned short *B1, *B2, *Old;
  KEY_STATUS KS;
  int i;
  B1 = malloc(320*240*2*2);
  B2 = &B1[320*240*2];
  Old = *Video;
  for(i=0; i<320*240; i++)
     { B1[i] = 0xF800;
       B2[i] = 0x001F;
     }
  __dcache_writeback_all();
  *Video = (unsigned long)B1;
  _lcd_set_frame();
  do { _kbd_get_status(&KS);
       if ((KS.status & CONTROL_TRIGGER_LEFT) != 0)
          { *Video = (unsigned long)B1;
            _lcd_set_frame();
          }
       if ((KS.status & CONTROL_TRIGGER_RIGHT) != 0)
          { *Video = (unsigned long)B2;
            _lcd_set_frame();
          }
       if ((KS.status & CONTROL_BUTTON_START) != 0)
          { *Video = (unsigned long)Old;
            _lcd_set_frame();
          }
     } while((KS.status & CONTROL_BUTTON_SELECT) == 0);
  *Video = (unsigned long)Old;
  __dcache_writeback_all();
  _lcd_set_frame();
  lcd_flip();
  return 0;
}


For firmware 1.03 the address is 0x8023E07C, for firmware 1.1 is 0x8023EF68.

Sorry for my bad English. :(
Attachments
Fast Double Buffer.app.zip
Demo app
(17.74 KiB) Downloaded 17 times
zaxxon
 
Posts: 4
Joined: Sat Jun 20, 2009 6:17 pm

Re: Fast Double Buffering

Postby flatmush on Sat Jun 20, 2009 10:37 pm

Good find, this is incredibly useful, now we need to either find a way to discover the address at runtime, or write a function to detect the firmware version and use the correct address. I'll certainly be using this, by the way you don't need that lcd_flip() call in your code, I haven't worked out what it does yet but it seems to have no effect.
C99 samples without using s2dsdk | MineSweeper | AstroLander
For help with dingoo programming or just in general, join our IRC at irc://irc.freenode.net/#dingoo-a320
flatmush
 
Posts: 35
Joined: Thu May 14, 2009 1:29 pm
Location: Manchester, UK

Re: Fast Double Buffering

Postby zaxxon on Sat Jun 20, 2009 10:53 pm

flatmush wrote:now we need to either find a way to discover the address at runtime, or write a function to detect the firmware version and use the correct address.


Maybe the function cmGetSysVersion ?
zaxxon
 
Posts: 4
Joined: Sat Jun 20, 2009 6:17 pm

Re: Fast Double Buffering

Postby zaxxon on Tue Jun 30, 2009 3:42 pm

With the following function is obtained pointer to pointer video independently from the version of firmware:
Code: Select all
unsigned short **GetVideoBufferPointer()
{ unsigned long *LP, LV;
  short *SP;
  LP = (unsigned long *)_lcd_get_frame;
  LV = *LP;
  LV = ((LV & 0x03FFFFFF) << 2) | 0x80000000;
  LP = (unsigned long *)LV;
  LV = LP[2];
  LV = ((LV & 0x03FFFFFF) << 2) | 0x80000000;
  LP = (unsigned long *)LV;
  LV = LP[10];
  LV = ((LV & 0x03FFFFFF) << 2) | 0x80000000;
  LP = (unsigned long *)LV;
  SP = (short *)LV;
  LV = (LP[0] << 16) + ((long)(SP[4]));
  return((unsigned short **)LV);
}


;)
zaxxon
 
Posts: 4
Joined: Sat Jun 20, 2009 6:17 pm

Re: Fast Double Buffering

Postby Reesy on Wed Jul 08, 2009 4:26 pm

Hi Zaxxon, I'm assuming you worked out the function above by disassembling the _lcd_get_frame function ( very nice work by the way), what exactly did you disassemble?

I've not found anything with the actual code in ( unless I'm going about it the wrong way of course ), there's some other functions I'd like to have a closer look at so I'm interested in how you actually did it, if you don't mind sharing that is.

Thanks
Reesy
Reesy
 
Posts: 4
Joined: Wed Jul 08, 2009 4:10 pm

Re: Fast Double Buffering

Postby zaxxon on Wed Jul 08, 2009 8:59 pm

Use this python script for explode a320.HXF file in HXF_root directory:
Code: Select all
#!/usr/bin/python

import struct, os, os.path

def CreateFilePath(name, data):
    r = name.split('\\')
    path = "HXF_root"
    for i in range(len(r)-1):
        path = "%s/%s" % (path,r[i])
    filename = r[len(r)-1]
    if not os.path.exists(path):
       os.makedirs(path)
    FF = open("%s/%s" % (path,filename), "wb")
    FF.write(data)
    FF.close()

def ReadFilename(HXF, offset):
    HXF.seek(offset)
    st = HXF.read(4)
    if len(st) != 4:
       return -1
    ret = struct.unpack("L", st)
    n = ret[0]
    fmt = "%dsc" % (n)
    st = HXF.read(n+1)
    if len(st) != (n+1):
       return -1
    ret = struct.unpack(fmt, st)
    s = ret[0]
    st = HXF.read(4)
    if len(st) != 4:
       return -1
    ret = struct.unpack("L", st)
    size = ret[0]
    print "File: %s of %d bytes" % (s,size)
    st = HXF.read(size)
    if len(st) != size:
       return -1
    CreateFilePath(s, st)
    return size+n+9

F = open("a320.HXF", "rb")
offset = 0x40
ret = 1
while(ret > 0):
     ret = ReadFilename(F, offset)
     offset += ret
F.close()


Use objdump for disassembly ccpmp.bin file:
Code: Select all
mipsel-dingoo-elf-objdump -b binary -m mips:isa32 --prefix-addresses --adjust-vma=0x80004000 --show-raw-insn -w -EL -D HXF_root/ccpmp.bin > ccpmp.dump


This script extract symbols from ccpmp.bin file:
Code: Select all
#!/usr/bin/python

import struct

def ReadEntryTable(CCPMP, offset):
    Table = []
    CCPMP.seek(offset)
    while True:
          entry = CCPMP.read(8)
          val = struct.unpack("LL", entry)
          if (val[0] == 0) or (val[1] == 0):
             return Table
          Table.append((val[0],val[1]))

def ReadString(CCPMP, offset):
    Ret = ""
    CCPMP.seek(offset)
    while True:
          c = CCPMP.read(1)
          if ord(c[0]) == 0:
             return Ret
          Ret = Ret + c

F = open("HXF_root/ccpmp.bin", "rb")
T = ReadEntryTable(F, 0x0016B048)
S = open("SymbolTable.txt", "wt")
for t in T:
    FuncName = ReadString(F, t[1]-0x80004000)
    FuncAddr = t[0]   
    print "%08X - %s" % (FuncAddr, FuncName)
    S.write("%08X - %s\n" % (FuncAddr, FuncName))
F.close()
S.close()

offset 0x0016B048 is for firmware version 1.03

Last, this script search symbols in disassembled code:
Code: Select all
#!/usr/bin/python

import sys

def GetSymbolTable():
    ST = open("SymbolTable.txt", "rt")
    st = ST.readlines()
    ST.close()
    ret = {}
    for s in st:
        v = s.strip().split(" - ")
        ret[int(v[0],16)] = v[1]
    return ret

def FindSymbol(Row, Syms):
    if len(Row) < 20:
       return None
    addr = Row.split()[-1]
    if (addr[0:2] == "0x") and (len(addr) == 18):
       addr = int(addr, 16)
       if addr in Syms.keys():
          return Syms[addr]
    return None

def GetPrintfString(Rows, Bin):
    addr = -1
    if (Rows[1].find("addiu") != -1) and (Rows[1].find("a0") != -1):
       if (Rows[0].find("lui") != -1) and (Rows[0].find("a0") != -1):
          addr = int(Rows[0].split(',')[-1],16) << 16
          addr = addr + int(Rows[1].split(',')[-1], 10)
    if (Rows[1].find("lui") != -1) and (Rows[1].find("a0") != -1):
       if (Rows[3].find("addiu") != -1) and (Rows[3].find("a0") != -1):
          addr = int(Rows[1].split(',')[-1],16) << 16
          addr = addr + int(Rows[3].split(',')[-1], 10)
    if addr != -1:
       offset = addr - 0x80004000
       Bin.seek(offset)
       S = ""
       b = Bin.read(1)
       while(b != chr(0)):
            S = S + b
            b = Bin.read(1)
       return S
    return None

SYMS = GetSymbolTable()
Dump = open("ccpmp.dump", "rt")
Bin = open("HXF_root/ccpmp.bin", "rb")
Out = open("ccpmp.txt", "wt")
R = []
for i in range(2):
    r = Dump.readline()
    if r == "":
       sys.exit(0)
    s = FindSymbol(r, SYMS)
    if s != None:
       r = r.strip() + "\t\t; %s\n" % (s)
    R.append(r)
r = Dump.readline()
if r == "":
   sys.exit(0)
R.append(r)
r = Dump.readline()
while(r != ""):
     R.append(r)
     s = FindSymbol(R[2], SYMS)
     if s != None:
        R[2] = R[2].strip() + "\t\t; %s" % (s)
        if (s == "printf") or (s == "serial_puts"):
           ps = GetPrintfString(R, Bin)
           if ps != None:
              R[2] = "%s(\"%s\")" % (R[2],ps.strip())
        R[2] = R[2] + "\n"
     if (len(R[0]) > 20) and (R[0][0:2] == "0x"):
        addr = int(R[0][0:18], 16)
        if addr in SYMS.keys():
           Out.write("\n%s:\n" % (SYMS[addr]))
     Out.write(R[0])
     R = R[1:]
     r = Dump.readline()
Out.write(R[0])
Out.write(R[1])
s = FindSymbol(R[2], SYMS)
if s != None:
   R[2] = R[2].strip() + "\t\t; %s\n" % (s)
Out.write(R[2])
Out.close()
Bin.close()
Dump.close()


This is the code for _lcd_get_frame():
Code: Select all
lcd_get_frame:
0x0000000080004d78 3c028024         lui        v0,0x8024
0x0000000080004d7c 8c42e078         lw        v0,-8072(v0)
0x0000000080004d80 27bdffe8         addiu        sp,sp,-24
0x0000000080004d84 14400006         bnez        v0,0x0000000080004da0
0x0000000080004d88 afbf0010         sw        ra,16(sp)
0x0000000080004d8c 0c0019e3         jal        0x000000008000678c
0x0000000080004d90 00000000         nop
0x0000000080004d94 8fbf0010         lw        ra,16(sp)
0x0000000080004d98 03e00008         jr        ra
0x0000000080004d9c 27bd0018         addiu        sp,sp,24
0x0000000080004da0 0c001639         jal        0x00000000800058e4
0x0000000080004da4 00000000         nop
0x0000000080004da8 08001366         j        0x0000000080004d98
0x0000000080004dac 8fbf0010         lw        ra,16(sp)

0x00000000800058e4 3c028024         lui        v0,0x8024
0x00000000800058e8 03e00008         jr        ra
0x00000000800058ec 8c42e07c         lw        v0,-8068(v0)

0x000000008000678c 27bdffe8         addiu        sp,sp,-24
0x0000000080006790 afbf0010         sw        ra,16(sp)
0x0000000080006794 0c001639         jal        0x00000000800058e4
0x0000000080006798 00000000         nop
0x000000008000679c 8fbf0010         lw        ra,16(sp)
0x00000000800067a0 03e00008         jr        ra
0x00000000800067a4 27bd0018         addiu        sp,sp,24

_lcd_get_frame:
0x000000008000d550 27bdffe8         addiu        sp,sp,-24
0x000000008000d554 afbf0010         sw        ra,16(sp)
0x000000008000d558 0c00135e         jal        0x0000000080004d78                ; lcd_get_frame
0x000000008000d55c 00000000         nop
0x000000008000d560 8fbf0010         lw        ra,16(sp)
0x000000008000d564 03e00008         jr        ra
0x000000008000d568 27bd0018         addiu        sp,sp,24


Sorry for my very very bad english. :P
zaxxon
 
Posts: 4
Joined: Sat Jun 20, 2009 6:17 pm

Re: Fast Double Buffering

Postby Reesy on Thu Jul 09, 2009 6:29 am

Wow Zaxxon, I was not expecting such a detailed response. Thanks so much for taking the time to share this knowledge. Time for some hacking...

Thanks again

Reesy.
Reesy
 
Posts: 4
Joined: Wed Jul 08, 2009 4:10 pm


Return to Dingoo OS Releases

Who is online

Users browsing this forum: No registered users and 1 guest