Next Previous Contents

3. A complex example

Let's have a look on a quite sophisticated example for the usage of SMC. It not only modifies code, but also the modification of the code is modified - allowing reuse of some instructions.

The code is from my 'memset()'implementation:

 1:     ...
 2:     SMC_StoreAddress StoreAccuFirstSection
 3:
 4: StoreToFirstSection:
 5:     SMC StoreAccuFirstSection, { sta SMC_AbsAdr, Y }
 6:             ...
 7: RestoreCodeBranchBaseAdr:
 8:     SMC FirstIncHighByte, { SMC_OperateOnHighByte inc, StoreAccuFirstSection }              ; code will be overwritten to 'beq RestoreCode' (*)
 9:     ...
10:     SMC_TransferOpcode FirstIncHighByte, OPC_BEQ , x                                        ; change code marked above with (*)
11:     SMC_TransferValue FirstIncHighByte, #(restoreCode - RestoreCodeBranchBaseAdr-2), x      ; set relative adress to 'RestoreCode'
12:     ...
13: restoreCode:
14:     SMC_TransferOpcode FirstIncHighByte, OPC_INC_abs , x                                    ; restore original code...
15:     SMC_TransferValue FirstIncHighByte, #(<(StoreToFirstSection+2)), x                   ; (second byte of inc contained low-byte of adress)
16:             ...

Some explanation:

Line 2: The register pair A/X contains an address, which is stored on the address location of a SMC line called 'StoreAccuFirstSection'. According to cc65's calling convention, the low-byte is in accu while the high-byte is in the X-register.

Line 5: The (modified) address is accessed.

Line 8: We have a line here, which is about to be modified (it begins with SMC), but itself modifies code. Please note: Contrary to the rest of SMC-line modifying macros, the 'OperateOn'-macros just expand their given arguments into a single instruction line. These can be changed of course too.

Line 10,11: These lines construct a branch operation for line 8: The X-register will be used to change it from 'inc StoreAccuFirstSection+2' (high-byte operation) to 'beq restoreCode'. Please note: To calculate the relaive branch offset, we introduced a second label ('RestoreCodeBranchBaseAdr') for to calculate it. Some could also use the internal name of the SMC label, but you should abstain to do so - it may be changed in the future...

Line 14,15: The original code from line 8 is reestablished.


Next Previous Contents