* * DDS MICRO-C 68HC11 Runtime library - Middle file * * 16 bit Multiply: D = ?parm * D ?mul PSHX Save index register PSHB Save low of parameter PSHA Save high of parameter PSHX Holding location for result TSX Set up addressability LDAA 3,X Get low of parm 1 LDAB ?parm+1 And low of parm 2 MUL Multiply to get result STD ,X Save partial result LDAA 2,X Get high of parm 1 LDAB ?parm+1 And low of parm 2 MUL Multiply to get result ADDB ,X Add to high of previous result STAB ,X And resave LDAA 3,X Get low of parm 1 LDAB ?parm And high of parm 2 MUL Multiply to get result ADDB ,X Add to result STAB ,X And resave PULA Get high result PULB Get low result PULX Clean original parameters PULX Restore index register RTS * 16 bit signed division: D = ?parm / D ?sdiv PSHX Save 'X' PSHB Save LOW byte of parm1 PSHA Save HIGH byte of parm1 EORA ?parm Check for differing signs PSHA Save difference TSX Address stack LDD ?parm Get parameter BPL ?sdiv1 Already positive BSR ?sdiv3 Convert to absolute STD ?parm Resave parameter ?sdiv1 LDD 1,X Get parm1 BPL ?sdiv2 Already positive BSR ?sdiv3 Convert to absolute ?sdiv2 BSR ?udiv Perform the division STD 1,X Save the result PULA Get original signs ROLA Carry = 1 if original signs differ PULA Get HIGH order result PULB Get LOW order result PULX Restore 'X' register BCC ?sdiv4 Original signs were the same ?sdiv3 COMA Ones complment COMB the 16 bit accumulator ADDD #1 Two's complement (negate) ?sdiv4 RTS * 16 bit unsigned division: D = ?parm / D ?udiv PSHX Save index register XGDX 'X' = denominator LDD ?parm Get numerator IDIV Perform divide XGDX 'D' = quotient PULX Restore index register RTS * 16 bit Modulus: D = ?parm % D ?mod PSHX Save index register XGDX 'X' = denominator LDD ?parm Get numerator IDIV Perform divide PULX Restore index register RTS * Shift left: D = ?parm << D ?shl PSHX Save index register XGDX 'X' = shift count LDD ?parm 'D' = value CPX #0 Special case (0 bit shift) BEQ ?shl2 Yes, early exit ?shl1 LSLD Shift one bit DEX Reduce count BNE ?shl1 Not finished, continue ?shl2 PULX Restore index RTS * Shift right: D = ?parm >> D ?shr PSHX Save index register XGDX 'X' = shift count LDD ?parm 'D' = value CPX #0 Special case (0 bit shift) BEQ ?shr2 Yes, early exit ?shr1 LSRD Shift one bit DEX Reduce count BNE ?shr1 Not finished, continue ?shr2 PULX Restore index RTS * Sign extend B into A (Resulting in 16 bit result) ?sign CLRA Assume positive TSTB Check sign of B BPL nargs Assumption correct DECA Convert to negative RTS * Signed >, >=, <, <= ?gt CPD ?parm D = ?parm > D BLT ?ret1 BRA ?ret0 ?ge CPD ?parm D = ?parm >= D BLE ?ret1 BRA ?ret0 ?lt CPD ?parm D = ?parm < D BGT ?ret1 BRA ?ret0 ?le CPD ?parm D = ?parm <= D BGE ?ret1 BRA ?ret0 * = amd != ?eq CPD ?parm D = ?parm == D BEQ ?ret1 * FALSE result, D=0, ZF=1 ?ret0 CLRA CLRB nargs RTS ?ne CPD ?parm D = ?parm != D BEQ ?ret0 * TRUE result, D=1, ZF=0 ?ret1 LDD #1 RTS * Unsigned >, >=, <, <= ?ugt CPD ?parm D = ?parm > D BLO ?ret1 BRA ?ret0 ?uge CPD ?parm D = ?parm >= D BLS ?ret1 BRA ?ret0 ?ult CPD ?parm D = ?parm < D BHI ?ret1 BRA ?ret0 ?ule CPD ?parm D = ?parm <= D BHS ?ret1 BRA ?ret0 * Logical negation: D = !D ?not CPD #0 BNE ?ret0 BRA ?ret1 * Switch table handler ?switch LDY ,X Get label value BEQ ?swit1 End of table, use default INX Advance to next INX 16 bit entry CPD ,X Does value match? BEQ ?swit2 yes, this is it INX Advance to next INX 16 bit entry BRA ?switch Keep looking ?swit1 LDY 2,X Get default label ?swit2 JMP ,Y Execute case