| Example: |
.ORG 0x1000 ; Address 0x1000 = 4096 (decimal)
ADIW R26, 0 ; If no parameter was passed in the command
BREQ ALocal_Ret ; line tail, just exit immediately
MOVW R24, R26 ; Point to the buffer and parse any value
CALL AParseValue ; string which it contains; none illegal
ADIW R26, 0 ; If no parameter was passed in the command
BREQ ALocal_Ret
MOVW R30, R24 ; Copy R25:R24:R23:R22 to R31:R30:R27:R26
PUSH R23
PUSH R22
MOVW R24, R26 ; Point to the buffer and parse any value
CALL AParseValue ; string which it contains; accept all
MOVW R20, R24
MOVW R18, R22 ; Move the multiplier to R21:R20:R19:R18
OR R25, R24
OR R25, R23 ; Determine if all 3 MSBytes of multipler
IN R26, SREG ; are 0 and store the result in R26
POP R22
POP R23 ; R25:R24:R23:R22 now has the first ULONG
MOVW R24, R30 ; value parsed, the multiplicand
DecideWhichToUse:
SBRC R26, SREG_Z ; If the ZERO flag was set, move R18 into
MOV R20, R18 ; R20 for the MultiplyULONGbyBYTE() call
SBRC R26, SREG_Z ; R26 is only modified by Multiply2ULONGs
CALL AMultiplyULONGbyBYTE ; so if R25:R24:R23 were all zero call
SBRS R26, SREG_Z ; MultiplyULONGbyBYTE(), otherwise call
CALL AMultiply2ULONGs ; Multiply2ULONGs()
BITSET = (1 << BIT_FMT_PRE_0x) | (1 << BIT_FMT_PRINT) | (1 << BIT_FMT_COMMAS)
DisplayResults:
LDI R21, 0 ; Set R21:R20 to a NULL pointer (no copy)
LDI R20, 0 ; FormatULONGHex ignores BIT_FMT_COMMAS
LDI R18, BITSET ; FormatULONG ignores BIT_FMT_PRE_0x
CALL AFormatULONGHex ; Output the value in hexadecimal format
MOVW R30, R24
MOVW R26, R22
LDI R25, 0x3A ; ACSZ_SpaceEqualSpace is found at FLASH
LDI R24, 0xD2 ; address 0x3AD2, which is " = "
CALL APrintFLASHASCIIz ; Print the " = " string, which uses R20,
MOVW R24, R30 ; R22, R24, and R25
MOVW R22, R26
LDI R21, 0 ; Set R21:R20 to a NULL pointer (no copy)
LDI R20, 0 ; FormatULONGHex ignores BIT_FMT_COMMAS
CALL AFormatULONG ; Output the same value in decimal format
CALL APrintNewLine ; and finish each set with CR, LF
Local_Ret:
RET |
| Test it: |
m>@ 4096 100 100
0x2710 = 10,000
m>@ 4096 200 200
0x9C40 = 40,000
m>@ 4096 300 300
0x15F90 = 90,000
m>@ 4096 300 10
0xBB8 = 3,000
m>@ 4096 1760 3
0x14A0 = 5,280
m>@ 4096 8000 3000
0x16E3600 = 24,000,000
m>
m>; To verify which is being called, replace one of the "CALL AMultiply..."
m>; lines with these 2 lines: "RET" and "NOP", (since we're replacing a
m>; 4-BYTE FAR CALL opcode with two 2-BYTE opcodes), for example:
m>@ 4096 257 255 ; With the original code, both work correctly
0xFFFF = 65,535
m>@ 4096 255 257
0xFFFF = 65,535
m>
m>DFH+ 0x1030 16 ; First print the original code in iHex:
FLASH (program memory) contents:
:101030000E946A30A1FF0E94693050E040E02BE03E
:00000001FF
m>; That is the original code; remove the AMultiplyULONGbyBYTE() call:
m>:1010300008950000A1FF0E94693050E040E02BE0DD
m>:00000001FF
m>@ 4096 257 255 ; MultiplyULONGbyBYTE() is not called
m>@ 4096 255 257 ; Multiply2ULONGs() is called
0xFFFF = 65,535
m>
m>; Restore the original code (not really needed, but for comparison):
m>:101030000E946A30A1FF0E94693050E040E02BE03E
m>; Remove the AMultiply2ULONGs() call:
m>:101030000E946A30A1FF0895000050E040E02BE0DC
m>:00000001FF
m>@ 4096 257 255 ; MultiplyULONGbyBYTE() is called
0xFFFF = 65,535
m>@ 4096 255 257 ; Multiply2ULONGs() is not called
m>
m>; Restore the original code:
m>:101030000E946A30A1FF0E94693050E040E02BE03E
m>:00000001FF
m>@ 4096 257 255 ; MultiplyULONGbyBYTE() is called again
0xFFFF = 65,535
m>@ 4096 255 257 ; and Multiply2ULONGs() is called again
0xFFFF = 65,535
m>
|