Coming soon.
Link to uploaded text file:
Sample code: sampleFile
#picaxe20x2 setfreq m64 #simspeed 0 ' ' Calculates 32 bit data load for frequency on AD9850 ' accurate to 0.01% ' 32-Bit (unsigned) maths on a PICAXE ' J.Leach 2006 , modified PM 26/10/2012 ' Symbol Procedure0StartAddress = 0 Eeprom 0,("+E*F*G/H=I") 'Word 0 (b0 and b1) Symbol OperandLSW = w0 Symbol OperandLSWLSB = b0 Symbol OperandLSWMSB = b1 'Word 1 (b2 and b3) Symbol T = w1 Symbol Temp2Word = w1 Symbol InstructionOperand = b2 'Word 2 (b4 and b5) Symbol AccumulatorLSW = w2 Symbol AccumulatorLSWLSB = b4 Symbol AccumulatorLSWMSB = b5 'Word 3 (b6 and b7) Symbol AccumulatorMSW = w3 'Word 4 (b8 and b9) Symbol S = w4 Symbol Temp1Word = w4 'Word 5 (b10 and b11) Symbol OperandMSW = w5 Symbol Address = b10 Symbol Address1 = b10 Symbol Address2 = b11 'Word 6 (b12 and b13) Symbol InstructionCode = b12 Symbol Temp1Byte = b12 Symbol ProgramCounter = b13 Symbol Temp2Byte = b13 Symbol ErrorFlag = b13 Symbol Index = b13 'words 7-11 symbol E=w7 symbol F=w8 symbol G=w9 symbol H=w10 symbol I=w11 symbol Decade =w12 symbol byte0=0 symbol byte1=b4 symbol byte2=b5 symbol byte3=b6 symbol byte4=b7 symbol Crystalmult=10000 Symbol LCDOutPin = 6 'LCD used for alerting, but other methods can be used. Symbol RTStartAddress = 80 Symbol RTEndAddress = 83 Symbol DenominatorLSBAddress = 84 Symbol DenominatorMSBAddress = 85 Symbol ErrorFlagAddress = 86 Symbol GPRStartAddress = 88 Symbol ProgramCounterAddress = 87 Symbol ERROR_Overflow = 0 Symbol ERROR_NegativeResult = 1 Symbol ERROR_DivideByZero = 2 Symbol RTStartLessb4Address = 76 '(80 - 4) Symbol GPRStartAddressLessb0Address = 88 '(87 - 0) Main: Decade=100 'Multiply base frequency by this to get target frequency '1, 10, 100, 1000, 10000 are valid values for the decade multiplier E = 5000 ' base frequency set for 500Khz (5000 * 100) '1-9999 are valid values for the base frequency F = 42950 'approx 2^32/1000000 G = 8 'scale to use max precision for 125MHz crystal (1,000,000,000/125,000,000) H = 10000/Decade 'scale the answer based on the decade selected ProgramCounter = Procedure0StartAddress Gosub ExecuteProcedure ' 'substitute serial or parallel chip load here based on hardware I/F selected ' b0=byte4 gosub writehex b0=byte3 gosub writehex b0=byte2 gosub writehex b0=byte1 gosub writehex End '************************************************* '**** VIRTUAL ARITHMETIC AND LOGIC UNIT (ALU) **** '************************************************* Add: Poke ErrorFlagAddress,ERROR_Overflow 'Add LSW AccumulatorLSW = AccumulatorLSW + OperandLSW If AccumulatorLSW >= OperandLSW Then Add_1 'Add Carry to MSW and jump to error routine if overflow AccumulatorMSW = AccumulatorMSW + 1 If AccumulatorMSW = 0 Then CPU_Error 'Add MSW Add_1: AccumulatorMSW = AccumulatorMSW + OperandMSW 'Jump to error routine if overflow If AccumulatorMSW < OperandMSW Then CPU_Error Return Subtract: Poke ErrorFlagAddress,ERROR_NegativeResult 'Subtract LSW Temp1Word = AccumulatorLSW AccumulatorLSW = AccumulatorLSW - OperandLSW If Temp1Word >= AccumulatorLSW Then Subtract_1 'Borrow from MSW and jump to error routine if this will make the overall result 'negative. If AccumulatorMSW = 0 Then CPU_Error AccumulatorMSW = AccumulatorMSW - 1 'Note: No need to Subtract MSW as only OperandLSW is being used Subtract_1: Goto Fetch Multiply: Poke ErrorFlagAddress,ERROR_Overflow 'Calculate the higher multiple and keep in Accumulator Temp1Word = AccumulatorLSW Temp2Word = AccumulatorMSW AccumulatorLSW = 0 AccumulatorMSW = OperandLSW * Temp2Word Temp2Word = OperandLSW ** Temp2Word 'Check for overflow If Temp2Word > 0 Then CPU_Error 'Calculate the lower multiple and put in Operand OperandMSW = Temp1Word ** OperandLSW OperandLSW = Temp1Word * OperandLSW 'Add the multiples to get the final result Gosub Add Goto Fetch Divide: Poke ErrorFlagAddress,ERROR_DivideByZero 'Check for error If OperandLSW = 0 Then CPU_Error 'Zero the Running Total For Address = RTStartAddress To RTEndAddress Poke Address,0 Next 'Calculate the quotient and remainder for 65535/OperandLSW S = 65535 / OperandLSW T = 65535 // OperandLSW 'Store the denominator Poke DenominatorLSBAddress,OperandLSWLSB Poke DenominatorMSBAddress,OperandLSWMSB Divide_1: 'Calculate S * AccumulatorMSW in the Operand, and add to Running Total. 'Note: uses variables very carefully ! OperandLSW = AccumulatorMSW Gosub SwapAccumulatorWithRT OperandMSW = S ** OperandLSW OperandLSW = S * OperandLSW Gosub Add 'Update the running total Gosub SwapAccumulatorWithRT 'Calculate the new Numerator OperandMSW = 0 OperandLSW = AccumulatorLSW + AccumulatorMSW If OperandLSW > AccumulatorMSW Then Divide_2 OperandMSW = 1 Divide_2: AccumulatorLSW = AccumulatorMSW * T AccumulatorMSW = AccumulatorMSW ** T Gosub Add 'Check to see if the new numerator is a single word. Loop back if it isn't If AccumulatorMSW > 0 Then Divide_1 Temp1Word = AccumulatorLSW 'Retrieve the running total Gosub SwapAccumulatorWithRT 'Retrieve the denominator Peek DenominatorLSBAddress,OperandLSWLSB Peek DenominatorMSBAddress,OperandLSWMSB 'Calculate AccumulatorLSW/Demominator and store in Operand OperandLSW = Temp1Word / OperandLSW OperandMSW = 0 'and add to the Running total to give the final result Gosub Add Goto Fetch SwapAccumulatorWithRT: 'Swaps the Accumulator value with the Running Total value For Address1 = RTStartAddress To RTEndAddress Address2 = Address1 - RTStartLessb4Address Peek Address1,Temp1Byte Peek Address2,Temp2Byte Poke Address1,Temp2Byte Poke Address2,Temp1Byte Next Return StoreAccumulatorLSW: Address = InstructionOperand - "E" * 2 +14 Poke Address,AccumulatorLSWLSB Address = Address + 1 Poke Address,AccumulatorLSWMSB Return CPU_Error: Peek ErrorFlagAddress,ErrorFlag Sertxd("ERROR: ",#ErrorFlag," ") End ExecuteProcedure: 'ON ENTRY: ProgramCounter has been set to the start of the Procedure 'Save the Program Counter Poke ProgramCounterAddress,ProgramCounter 'Save the ProgramCounter 'Load General Purpose registers with corresponding E to I4 values For Address1 = 14 To 23 Address2 = Address1 + GPRStartAddress -14 Peek Address1,Temp1Byte Poke Address2,Temp1Byte Next 'Set the Accumulator to 0 AccumulatorMSW = 0 AccumulatorLSW = 0 Fetch: 'Fetch an Instruction code and operand from Program Memory Peek ProgramCounterAddress,ProgramCounter 'Retrieve the ProgramCounter Read ProgramCounter,InstructionCode ProgramCounter = ProgramCounter + 1 Read ProgramCounter,InstructionOperand ProgramCounter = ProgramCounter + 1 Poke ProgramCounterAddress,ProgramCounter 'Save the ProgramCounter 'Load the contents of the specified Register into OperandLSW Address = InstructionOperand - "E" * 2 + GPRStartAddress Peek Address,OperandLSWLSB Address = Address + 1 Peek Address,OperandLSWMSB OperandMSW = 0 Execute: 'Execute the loaded Instruction Lookdown InstructionCode,("+","-","*","/","="),Index Branch Index,(Instruction_Add,Subtract,Multiply,Divide,StoreAccumulatorLSW) Instruction_Add: Gosub Add Goto Fetch writehex: b1=b0>>4 gosub hexit sertxd (b1) b1=b0 & $0F gosub hexit sertxd (b1,cr,lf) return hexit: lookup b1,("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"),b1 return