SuperH-based fx calculators
fx legacy: SMEM optimization

Storage memory optimization frame

JumpOptimizing() is called if storage memory is exhausted due to deletion-wastes.
The addin which calls JumpOptimizing() normally is restarted by the optimizing-frame.
Hence the addin has to provide for some means to recognize being restarted.
Otherwise it would be recalled eternally.

#define CODESIZE 0x100
void JumpOptimizing(){
int p0, p1;
unsigned char w[] = "SDLOADER"// title of the addin to restart after optimization
char optimizationcode[ CODESIZE ];

// reset DefaultCallbackHandler to zero to avoid a finalization crash
                GetCallbackAddressPtr( &p0, &p1 );   // see below
                *(int*)p1 = 0;
// move to optimization-frame to stack; source see below                               
                memcpy( (void*)optimizationcode, &SMEM_optimize_frame, SMEM_optimize_codelength );     
// call it
                p0 = ((int (*)( unsigned char* ))optimizationcode)( w );

typedef struct{
  char name[8];
} TAddinArrayItem;

typedef struct {
        short p1;
        short estrip_no;
} TAddinEstripInformation;

void GetCallbackAddressPtr( int*p0, int*p1 ){
TAddinEstripInformation aei;
        App_GetAddinEstripInfo( 100, 0, &aei )// syscall 0x000E
        *p0 = (int)aei.addin_array_addr;
        *p1 = *p0 + 4;

The source of the optimization-frame:

        .export _SMEM_optimize_frame
        .export _SMEM_optimize_codelength
        mov.l #\FUNO, r0
        mov.l #0x80010070, r2
        jsr @r2

SMEM_Optimization:      .EQU 0x019F
App_RegisterAddins:     .EQU 0x0005
GetAddinHeaderAddr:     .EQU 0x000A
strncpm:                .EQU 0x0AD8
App_BuiltInCount:       .EQU 0x046B
; - - - - -
; this code has to be called from an optimization-proof memory-location
; f. i. stack or a runtime library in a flash-bank other than the storage-memory-bank
        mov.l   r14, @-r15
        mov.l   r13, @-r15
        sts.l   pr, @-r15
        ; local variables
        add     #-4, r15        ; char*pwork
        ; parameter: char*name_of_addin_to_restart
        mov     r4, r13      ; pointer to the addin-title, which has to be started finally

; call storage memory optimization
        SYSCALL SMEM_Optimization       

; perhaps this is not neccessary
; App_RegisterAddins
        SYSCALL App_RegisterAddins
; now find restart-addin in the addin array according to the parameter
; for (r14=0;"true";r14++)
        mov     #0, r14
; query addin-array
        mov.l #0x1D4, r5  ; offset to the addin's title inside the addin-fileheader
        mov r15, r6     ; pointer for addin-title; pwork
        SYSCALL GetAddinHeaderAddr
        mov r14, r4
        tst     r0, r0
        bt/s    ?quit
        mov     #-1, r0 ; signal error
; now r15 points to the title of the addin with the number r14
; compare it to the string pointed to by r13 (parameter 1).
        mov @r15, r4
        mov #8, r6
        SYSCALL strncpm
        mov r13, r5

        tst     r0, r0
        bt      ?exit ; are the strings equal
        bra     ?try
        add     #1, r14
; end for (r14=0;"true";r14++)
; now get the count of the builtin-applications
        SYSCALL App_BuiltInCount

; calculate arg's addinno
        add     r0, r14
; debug 
;       bra    ?quit
;       mov r14, r0
; debug 

; finally jump(!) to App_Start, which will surrender control to the system again
        mov.l #0x049A, r0
        mov.l #0x80010070, r2
        mov     #0, r4
        mov     #1, r5       ; enable restart
        mov     r5, r7       ; force restart
        mov     r14, r6      ; appno
        add     #4, r15 ; most probably the adjustment is not neccessary, because App_Start does neccessary adjustments
        lds.l   @r15+, pr
        mov.l   @r15+, r13
        jmp @r2
        mov.l   @r15+, r14
        add     #4, r15
        lds.l   @r15+, pr
        mov.l   @r15+, r13
        mov.l   @r15+, r14
        .ALIGN 4

        .DATA.L (_SMEM_optimize_codelength-_SMEM_optimize_frame )


(19.03.2011 12:43:08)