Announcement

Collapse
No announcement yet.

Code Pointers

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Code Pointers

    Is there any real advantage to using code pointers to point to a user written subprocedure inbedded in the main module? If so, what is the advantage?
    Walt Decker

  • #2
    I have used code pointers in my Virtual Micro Code Simulator. I have
    150 subroutines, each sub handles one instruction. I keep all the
    code pointers in an array syncronized with several other arrays. During
    a dissassembly operation when I have identified the instruction, the
    index is used to get the code pointer from the array and then I call
    the sub. If I did not have this feature, I would have had to pass on
    a number to a huge Select Case Block(or several broken down blocks).

    It just made it alot cleaner for my application.

    i.e.
    Code:
    GLOBAL op16()   AS STRING     '16 bit opcode lookup table
    GLOBAL m16()    As Integer    '16 bit mask
    GLOBAL c16()    As Integer    '16 bit compare word
    GLOBAL op32()   As String     '32 bit opcode lookup table
    GLOBAL m132()   As Integer    '1st 32 bit mask
    GLOBAL m232()   As Integer    '2nd 32 bit mask
    GLOBAL c132()   As Integer    '1st 32 bit compare word
    GLOBAL c232()   As Integer    '2nd 32 bit compare word
    GLOBAL Diss()   AS ASCIIZ*100 'Dissassembled strings
    GLOBAL RunOp()  AS DWORD      'Code pointers to 16 bit Run opcodes
    GLOBAL RunOp2() AS DWORD      'Code pointers to 32 bit Run opcodes
    GLOBAL DisOp()  AS DWORD      'Code pointers to 16 bit dissassemble opcodes
    GLOBAL DisOp2() AS DWORD      'Code pointers to 32 bit dissassemble opcodes
      
    ...etc
      
    '---------------------------------------------------------
    'Note1: Array is sorted 0000 to FFFF, so I can do a value
    'compare and divide the large array in 1/2 or 1/4 to narrow
    'the search inside the for/next loop.
    'Note2: With PBDLL5 I can change to a structure.
    'This structure of opcode string as follows:
    '[string         ] [xxxx] [xxxx  ] [subroutine]
    '[nmemonic string] [mask] [opcode] [code pointer]
    '----------------------------------------------------------
     
     op16$(1) = "NOP"
      m16%(1) = Val("&H" + "FFFF" + "%")
      c16%(1) = Val("&H" + "0000" + "%")
     RunOp(1) = CODEPTR(NOP1)
     DisOp(1) = CODEPTR(dNOP1)
     
     op16$(2) = "SLEEP"
      m16%(2) = Val("&H" + "FFFF" + "%")
      c16%(2) = Val("&H" + "0180" + "%")
     RunOp(2) = CODEPTR(SLEEP2)
     DisOp(2) = CODEPTR(dSLEEP2)
     
    op16$(3) = "STC CCR,Rd"
     m16%(3) = Val("&H" + "FF00" + "%")
     c16%(3) = Val("&H" + "0200" + "%")
    RunOp(3) = CODEPTR(STC3)
    DisOp(3) = CODEPTR(dSTC3)
     
    op16$(4) = "LDC Rs,CCR"
     m16%(4) = Val("&H" + "FF00" + "%")
     c16%(4) = Val("&H" + "0300" + "%")
    RunOp(4) = CODEPTR(LDC4)
    DisOp(4) = CODEPTR(dLDC4)
     
    op16$(5) = "ORC #xx,CCR"
     m16%(5) = Val("&H" + "FF00" + "%")
     c16%(5) = Val("&H" + "0400" + "%")
    RunOp(5) = CODEPTR(ORC5)
    DisOp(5) = CODEPTR(dORC5)
     
    ...etc
     
     
    '       **  Initialize all opcode arrays **
    '           ============================
    Dim op16(1:100)     '16 bit opcode strings
    Dim op32(1:50)      '32 bit opcode strings
    Dim m16(1:100)      '16 bit mask word
    Dim c16(1:100)      '16 bit compare word
    Dim m132(1:50)      '32 bit 1st mask word
    Dim m232(1:50)      '32 bit 2nd mask word
    Dim c132(1:50)      '32 bit 1st compare word
    Dim c232(1:50)      '32 bit 2nd compare word
    Dim RunOp(1:100)    'Run/Sim 16 bit opcodes
    Dim RunOp2(1:50)    'Run/Sim 32 bit opcodes
    Dim DisOp(1:100)    'Dissassemble 16 bit opcodes
    Dim DisOp2(1:50)    'Dissassemble 32 bit opcodes
     
    ...etc
    
     
    '**********************************************************
    '16/32 bit Instruction routines: 16 bit = 100x subs total '
    '                                32 bit = 50x  subs total '
    'Dissassemble opcodes, convert them to strings and display
    'them to the Code Window.
    '**********************************************************
     
    $INCLUDE "C:\PROJECTS\MCHILD\RESOLVE.INC"
     
    '-------------------------------------------------------------
    ' First the 16 bit instructions, 100x subs. Addressing mode
    ' already broken down for each sub.
    ' Opcode Place holder strings found in op16(i) array.
    '-------------------------------------------------------------
    SUB dNOP1()      'NOP            [0 0 0 0]
        operand$ = op16$(i)
    END SUB
    '---
     
    SUB dSLEEP2()    'SLEEP          [0 1 8 0]
        operand$ = op16$(i)
    END SUB
     
    '---
    SUB dSTC3()      'STC CCR,Rd     [0 2 0 rd]
       Call resolve_rd_8()
    END SUB
     
    '---
    SUB dLDC4()      'LDC Rs,CCR     [0 3 0 rs]
        Call resolve_rs_8_R()
    END SUB
     
    ...etc
    
     
    '**********************************************************
    '16/32 bit Instruction routines: 16 bit = 100x subs total '
    '                                32 bit = 50x  subs total '
    '                                                         '
    '**********************************************************
     
     
    '-------------------------------------------------------------
    ' First the 16 bit instructions, 100x subs. Addressing mode
    ' already broken down for each sub.
    ' Opcode Place holder strings found in op16(i) array.
    '-------------------------------------------------------------
    SUB NOP1()      'NOP            [0 0 0 0]
        'Simulate instruction
    END SUB
    '---
     
    SUB SLEEP2()    'SLEEP          [0 1 8 0]
        'simulate instruction
    END SUB
     
    '--- 
    SUB STC3()      'STC CCR,Rd     [0 2 0 rd]
       'Simulate instruction
    END SUB
     
    '---
    SUB LDC4()      'LDC Rs,CCR     [0 3 0 rs]
        'simulate instruction
    END SUB
     
    '---
    SUB ORC5()      'ORC #xx,CCR    [0 4 imm imm]
       'simulate instruction
    END SUB
     
    ...etc
     
    
    '------------------------------------------------------
    'Simulate an instruction and return the results.
    '
    'Single Step, Animate or Run mode.
    'Entry:  Lines
    '
    'Returns:
    '------------------------------------------------------
    SUB SimInstruct()
     
    Local x  as word
    Local y  as word
    Local z  as word
    Local r  as word
    Local xx as word
    Local yy as word
    Local zz as word
    Local rr as word
     
    adr = 0
    'lines = Len(rom$)/2 'average out to 2 bytes per line
    fDiss = 0 'set simulation flag
     
    SimNext:        '**Main Simulator Loop**
    While lines > 0 And adr < Len(rom$)
        Call adrs_cnvt()
        Call getword()
        x = mWord
        'Bytes12 = mWord
        mem1$ = h1$ + h2$
     
        For i = 1 To 100
            y = m16%(i)
            z = c16%(i)
            r = y And x
            If r = z Then
                '**Resolve operand and simulate
                CALL DWORD RunOp(i)                   <---- ****
                lines = lines - 1
                GoTo SimNext
            End If
        Next i
     
        '**Fall thru and test for 32 bit opcodes
        mem1$ = h1$ + h2$
        Call getword()
        xx = mWord
        'Bytes34 = mWord
        mem2$ = h1$ + h2$
        For i = 1 To 50
            y = m132%(i)
            z = c132%(i)
            r = y And x
            yy = m232%(i)
            zz = c232%(i)
            rr = yy And xx
            If r = z And rr = zz Then
                '***Resolve operand and simulate
                CALL DWORD RunOp2(i)
                lines = lines - 1
                GoTo SimNext
            End If
        Next i
     
        '**Invalid instruction, initiate error handler
        '**Hopefully, I will never need to do this!!!
        adr = adr - 2
        lines = lines - 1
        GoTo SimNext
     
    WEND
    END SUB
    ...etc


    There are other reasons in general, but I will let others post them.
    Regards, Jules

    [This message has been edited by Jules Marchildon (edited January 04, 2000).]
    Best regards
    Jules
    www.rpmarchildon.com

    Comment


    • #3
      I have used them for several different things. One example is in a large program I work on. It has a couple routines we use for user input. In these routines, one thing they do is check a global code pointer...if it's set, it will call this sub every so often. This allows us to do things like update the date/time from anywhere in the program, no matter where on the screen the date/time is, or what it looks like. The user input code dosen't know what it's calling, it just knows to call it every 30 seconds or so.

      Another example from that same program... the program stores it's version information in a database. If we put a newer version of the program on, it may need to change something in some databases...it can look at the stored version, compare it to it's own internal version, and figure out what needs to happen. The way I implemented this was to use pointers to functions.
      The program will look at what version the data is and build a list of functions (in an array) to call to bring the data up to date with the current version of the program. This enables us to put any version of the program with any version of the data and the program can convert the data to the correct format. This could be handled differently, but it makes the code easy to maintain...as Jules pointed out, it saves us from having a huge case statement or multiple IF statements.


      Jason

      Comment


      • #4
        Thanks for the info. I haven't been involved with PB for long, so I've decided to work out things I don't understand or have little feel for in a consiencious manner. I've been working with the pointers to get a feel for how things work, and the code pointers were next on the agenda.

        Thanks again.
        Walt Decker

        Comment


        • #5
          Another use of CODEPTR:

          In the Source Code section, I found two good examples how to connect
          an interrupt to PB code. This code uses CODEPTR in order to tell the
          interrupt where to find its handler. (I had tried to do the same
          before, but I was not able to find out how to set up the stack for the
          interrupt handler. Thank you at PB Inc. for posting that code!
          - If you write the entire interrupt handler in inline assembler,
          it is even easier to connect the routine to the interrupt:

          IntHandler:
          ! ... (all ASM statements go here
          ! IRET

          and then you establish CODEPTR32(IntHandler) as the new interrupt vector.

          Comment

          Working...
          X