Author Topic: Translate from asm to C  (Read 3514 times)

0 Members and 1 Guest are viewing this topic.

Offline pomprockerTopic starter

  • Supreme Robot
  • *****
  • Posts: 1,431
  • Helpful? 16
  • Sorry miss, I was giving myself an oil-job.
    • Nerdcore - Programming, Electronics, Mechanics
Translate from asm to C
« on: March 21, 2009, 02:06:57 PM »
I found this asm code for a pic and I need code that does the same thing for a mega8 in C. Can anyone translate?
Code: [Select]
;
;    IR Widget Firmware
;
;    Copyright (C) 2007, 2008 Kevin Timmerman
;    irwidget [@t] compendiumarcana [d0t] com
;    http://www.compendiumarcana.com/irwidget
;
;    This program is free software; you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation; either version 3 of the License, or
;    (at your option) any later version.
;
;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.
;
;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.

;
;
; Version History
;----------------
; Rev 0
; 2006-10-19
; First release
;
; Rev 1
; 2007-01-08
; Added support for using an IR LED as a IR detector. The comparator is used,
;  so the I/O changes a bit when this option is enabled. (#define LED_DET)
; Changed 19200 bps rate for compat time mode, now 57600
; Added support for host control of sending on and off times in time mode (was a #define option)
; Count mode trasmission will not start until the first IR pulse is received
;
; Rev 2
; 2007-01-11
; Count mode can be stopped and restarted under host control
;
; Rev 3
; 2007-08-18
; -> Uses revision 2 schematic and PCB <-
; Support for PICs other than 12F629/675 removed
; Support for compatibility with 74HC circuits removed
; Time capture is now 15 bits with 16 uS resolution sent at 115 kbps
; Default time capture mode is rising and falling edge
; Autodetect QSE15x or LED
; Tx output pin changed to allow IR pulse detector autodetect
; Output reserved for wake-on-ring
;
; Rev 4
; 2008-08-15
; Suppoort for use of FTDI232 USB to serial converter chip (inverted I/O, reset pin enabled)
; Status LED output
; License change to GPLv3
;



;#define HW_USB ; Define this for USB version only!


#ifdef __12F629
include <P12F629.INC>
#define CORE14
#define FIRSTREG 0x20
#define PGMSIZE 1024
#endif
#ifdef __12F675
include <P12F675.INC>
#define CORE14
#define FIRSTREG 0x20
#define PGMSIZE 1024
#endif

; Configuration bits
#ifdef HW_USB
__config _CPD_OFF & _CP_OFF & _BODEN_ON & _MCLRE_ON & _PWRTE_ON & _WDT_ON & _INTRC_OSC_NOCLKOUT
#else
__config _CPD_OFF & _CP_OFF & _BODEN_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_ON & _INTRC_OSC_NOCLKOUT
;__config _CPD_OFF & _CP_OFF & _BODEN_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_ON & _INTRC_OSC_CLKOUT ; For testing internal osc freq only
#endif

errorlevel -220 ; Stupid MPLAB complains about IDLOCS
org 0x2000 ; IDLOCS
dw 'I','R','W','4' ; IR Widget Rev 4
errorlevel +220


BANK1 equ 0x80 ; Reduce assembler whining

radix dec ; Default radix of decimal


; --- I/O
; 8 Ground
;
bSerTx equ 0 ; 7 Serial data to host PC
pSerTx equ GPIO ;
#ifdef HW_USB ;
bOpMode equ 1 ; 6 Operational Mode (RTS) [USB]
pOpMode equ GPIO ;
#else ;
bLED equ 1 ; 6 IR LED input [Serial]
pLED equ GPIO ;
#endif ;
bIRDetect equ 2 ; 5 IR Detector module (QSE15x) input and
pIRDetect equ GPIO ;     comparator output (-> TMR0 input)
;
; 4 Reset (DTR) [USB]
#ifndef HW_USB ;
bOpMode equ 3 ; 4 Operational Mode (RTS) [Serial]
pOpMode equ GPIO ;
#endif ;
bStatus equ 4 ; 3 Status LED output (RI)
pStatus equ GPIO ;
;
bIRDemod equ 5 ; 2 IR Demodulator module input
pIRDemod equ GPIO ;
;
; 1 Power
;



cblock FIRSTREG ; Registers
time_h
time_l
prev_time_h
prev_time_l
prev_count
flags
temp1
endc

fEdge equ 0 ; IR Demod edge flag bit


org 0x0000 ; - Start of program memory

nop ;
#ifdef HW_USB ;
movlw (1<<bStatus) | (1<<bSerTx) ; Idle outputs
movwf GPIO ;
#else ;
clrf GPIO ; All outputs off
#endif ;
goto skip_isr ; Jump over the ISR
;
org 0x0004 ; - ISR
goto $ ; Let the watchdog handle this
;
;
skip_isr ;
; - Initiailize peripherals
;
movlw (1<<CM0) | (1<<CM1) | (1<<CM2) ; Disable comparator
movwf CMCON ;
;
call PGMSIZE-1 ; Get OSCCAL
;
bsf STATUS,RP0 ; Bank 1
;
movwf OSCCAL ^ BANK1 ; Setup OSCCAL
;
#ifdef ANSEL ;
movlw (1<<ADCS0) | (1<<ADCS2) ; Make all pins digital I/O
movwf ANSEL ^ BANK1 ;
#endif ;
;
#ifdef HW_USB ;
movlw (1<<bIRDetect) | (1<<bOpMode) | (1<<bIRDemod) ; Setup TRIS
#else ;
movlw (1<<bLED) | (1<<bIRDetect) | (1<<bOpMode) | (1<<bIRDemod) ; Setup TRIS
#endif ;
movwf TRISIO ^ BANK1 ;
;
errorlevel -219 ;
movwf WPU ^ BANK1 ; Setup WPU
errorlevel +219 ;
;
; *GPPU = 0 - WPU enabled
; INTEDG = 0
; T0CS = 0 - Internal clock source
; T0SE = 0 - Inc on rising edge
; PSA = 0 - Assign prescaller to TMR0
; PSx - Prescaler = 1:16 (16 uS)
movlw (1<<PS1) | (1<<PS0) ;
movwf OPTION_REG ^ BANK1 ;
;
#ifdef HW_USB ;
bcf STATUS,RP0 ; Bank 0
;
; Check operational mode
btfsc pOpMode,bOpMode ;
goto irw_count ; Pulse count mode...
;  ...else pulse time mode...
#else ;
; Setup voltage ref for LED IR detector
movlw (1<<VREN) | (1<<VRR) | (1<<VR0) ; 1 / 24 * Vdd (~200 mV)
movwf VRCON ^ BANK1 ;
;
bcf STATUS,RP0 ; Bank 0
;
;
btfsc pLED,bLED ; Check if LED is present
goto noled ; No...
;
movlw (1<<CM0) | (1<<CM1) ; Enable comparator with internal ref and out -> GP2 (TMR0 ext in)
movwf CMCON ;
noled ;
; Check operational mode
btfss pOpMode,bOpMode ;
goto irw_count ; Pulse count mode...
;  ...else pulse time mode...
#endif ;
;
;
; ----- Pulse time capture -----
;
; - Initialize registers
;
bcf flags,fEdge ; Start with falling edge
clrf prev_time_h ; Init previous pulse time
clrf prev_time_l ;
clrf time_h ; Init current time
clrf TMR0 ;
;
ptloop ;
btfsc flags,fEdge ;
goto ptwr ;
;
ptwf ; - Wait for falling edge
clrwdt ; Prevent watchdog timeout while waiting
btfss pIRDemod,bIRDemod ; Check IR demodulator output level
goto ptfe ; Low, capture time...
btfss INTCON,T0IF ; Check for TMR0 overflow
goto ptwf ; No overflow, loop...
incf time_h,F ; Increment time high byte
bcf INTCON,T0IF ; Clear TMR0 interrupt flag
goto ptwf ; Loop...
;
ptfe ;
#ifdef HW_USB ;
bcf pStatus,bStatus ; Turn on status LED
#else ;
bsf pStatus,bStatus ; Turn on status LED
#endif ;
goto ptcap ;
;
ptwr ; - Wait for rising edge
clrwdt ; Prevent watchdog timeout while waiting
btfsc pIRDemod,bIRDemod ; Check IR demodulator output level
goto ptre ; High, check if capture required...
btfss INTCON,T0IF ; Check for TMR0 overflow
goto ptwr ; No overflow, loop...
incf time_h,F ; Increment time high byte
bcf INTCON,T0IF ; Clear TMR0 interrupt flag
goto ptwr ; Loop...
;
ptre ;
#ifdef HW_USB ;
bsf pStatus,bStatus ; Turn off status LED
btfsc pOpMode,bOpMode ; Only send on and off time if RTS is high
#else ;
bcf pStatus,bStatus ; Turn off status LED
btfss pOpMode,bOpMode ; Only send on and off time if RTS is high
#endif ;
goto ptedge ; Not wanted, skip calcutlation and trasmission...
;
ptcap ; - Capture current time
movf TMR0,W ; Get TMR0 value
movwf time_l ; Save it
btfss time_l,7 ; If not a low value, no need to check for TMR0 overflow...
btfss INTCON,T0IF ; It is zero, so check for overflow
;  This is necessary because TMR0 may have oveflowed
;  between the time it was last checked and the time it
;  was read. It will be zero if that has happened.
goto ptcno ; Skip overflow code
incf time_h,F ; Increment time high byte
bcf INTCON,T0IF ; Clear TMR0 interrupt flag
ptcno ;
; - Send elapsed time to host
movf prev_time_l,W ; Get previous time low byte
subwf time_l,W ; Subtract last time from current time
;  W now holds elapsed time
btfss STATUS,C ; Adjust time high byte for borrow
incf prev_time_h,F ; time_h must not be changed, so adjust prev_time_h instead
call tx115 ; Send elapsed time low byte to host
;
movf prev_time_h,W ; Get previous time high byte
subwf time_h,W ; Subtract last time from current time
andlw 0x7F ; Assume falling edge, clear msb
btfsc flags,fEdge ; Check edge flag, skip next if falling edge
iorlw 0x80 ; Rising edge, set msb
call tx115 ; Send elapsed time high byte to host
;
movf time_l,W ; Update previous time
movwf prev_time_l ;
movf time_h,W ;
movwf prev_time_h ;
;
ptedge ;
movlw 1<<fEdge ; Toggle edge
xorwf flags,F ;
;
goto ptloop ; Loop...
;
;
;
; ----- Pulse count capture ------
;
;
irw_count ; - Change the TMR0 clock from internal to external. This
;    must be done as specified in the data sheet to avoid
;    false trigger of the watchdog timer.
;
clrwdt ;
clrf TMR0 ;
bsf STATUS,RP0 ; Bank 1
;
movlw (1<<T0CS) | (1<<T0SE) | (1<<PSA) | 7 ;
movwf OPTION_REG ^ BANK1 ;
clrwdt ;
; *GPPU = 0 - WPU enabled
; INTEDG = 0
; T0CS = 1 - External clock source
; T0SE = 1 - Inc on falling edge
; PSA = 1 - Assign prescaller to WDT
; PSx - Prescaler = 0 (1:1)
movlw (1<<T0CS) | (1<<T0SE) | (1<<PSA) ;
movwf OPTION_REG ^ BANK1 ;
;
bcf STATUS,RP0 ; Bank 0
;
ircw ; - Wait for the host signal to proceed
clrwdt ;
#ifdef HW_USB ;
btfsc pOpMode,bOpMode ;
#else ;
btfss pOpMode,bOpMode ;
#endif ;
goto ircw ;
;
clrf TMR0 ; - Wait for first IR pulse
clrf prev_count ;
irpw ;
clrwdt ;
movf TMR0,W ;
btfsc STATUS,Z ;
goto irpw ;
movlw 0 ;
goto spc ;
;
; --- Count pulses and send to host every 100 microseconds ---
ircl ;
clrwdt ;  1
movf TMR0,W ;  2 Get pulse count
spc ;
movwf temp1 ;  3 Save pulse count
xorwf prev_count,F ;  4 Compare to previous pulse count
movwf prev_count ;  5 Update previouse pulse count
#ifdef HW_USB ;
btfss STATUS,Z ;  6 Count has changed...
bcf pStatus,bStatus ;  7  turn on status LED
btfsc STATUS,Z ;  8 Count has not changed...
bsf pStatus,bStatus ;  9  turn off status LED
#else ;
btfss STATUS,Z ;  6 Count has changed...
bsf pStatus,bStatus ;  7  turn on status LED
btfsc STATUS,Z ;  8 Count has not changed...
bcf pStatus,bStatus ;  9  turn off status LED
#endif ;
;
call tx115 ; 10 Send pulse count to host
;
nop ; 96
nop ; 97
;
#ifdef HW_USB ;
btfss pOpMode,bOpMode ; 98 Continue until host says stop...
#else ;
btfsc pOpMode,bOpMode ; 98 Continue until host says stop...
#endif ;
goto ircl ; 99,100
;
goto ircw ; Restart count mode...
;
;
;
; --- Async 115 kbps transmission ---
;
; - Macros for 4 and 5 cycle delays used for serial
;    tx timing
;
delay4 macro ; 4 cycle delay call
call dly4 ;
endm ;
delay5 macro ; 4 cycle delay call
call dly5 ;
endm ;
;
#ifdef HW_USB ;
#define TXHIGH andlw ~(1<<bSerTx) ;
#define TXLOW iorlw (1<<bSerTx) ;
#else ;
#define TXHIGH iorlw (1<<bSerTx) ;
#define TXLOW andlw ~(1<<bSerTx) ;
#endif ;
;
sendbit macro reg, bit ; Macro to send a bit
;  4 cycles
TXLOW ; 1  Assume bit is a 1, drive output low - tx data is inverted
btfss reg,bit ; 2  Test it
TXHIGH ; 3  It is a 1, not zero, drive output high
movwf pSerTx ; 4  Update output
endm ;
;
;       115200 bps bit times
; 0.00 8.68 17.36 26.04 34.72
; 43.40 52.08 60.76 69.44 78.13
tx115 ;
movwf temp1 ;
movf pSerTx,W ;       Get port output latch
TXHIGH ;       Start bit - high
movwf pSerTx ; 0
delay5 ; 1-5
sendbit temp1,0 ; 6-9    Bit 0
delay4 ; 10-13
sendbit temp1,1 ; 14-17  Bit 1
delay5 ; 18-22
sendbit temp1,2 ; 23-26  Bit 2
delay5 ; 27-31
sendbit temp1,3 ; 32-35  Bit 3
delay4 ; 36-39
sendbit temp1,4 ; 40-43  Bit 4
delay5 ; 44-48
sendbit temp1,5 ; 49-52  Bit 5
delay5 ; 53-57
sendbit temp1,6 ; 58-61  Bit 6
delay4 ; 62-65
sendbit temp1,7 ; 66-69  Bit 7
delay5 ; 70-74
goto $+1 ; 75,76
TXLOW ; 77     Stop bit - low
movwf pSerTx ; 78
return ;
;
dly5 ; 5 cycle delay subroutine
nop ;
dly4 ; 4 cycle delay subroutine
return ;
;
;
end ;
;

Offline airman00

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 3,650
  • Helpful? 21
  • narobo.com
    • Narobo.com - Mechatronics and related
Re: Translate from asm to C
« Reply #1 on: March 21, 2009, 04:20:28 PM »
For those who want the background to what the code does: http://www.compendiumarcana.com/irwidget

Check out the Roboduino, Arduino-compatible board!


Link: http://curiousinventor.com/kits/roboduino

www.Narobo.com

Offline pomprockerTopic starter

  • Supreme Robot
  • *****
  • Posts: 1,431
  • Helpful? 16
  • Sorry miss, I was giving myself an oil-job.
    • Nerdcore - Programming, Electronics, Mechanics
Re: Translate from asm to C
« Reply #2 on: April 04, 2009, 11:43:18 PM »
any takers?

Offline chelmi

  • Supreme Robot
  • *****
  • Posts: 496
  • Helpful? 15
    • Current projects
Re: Translate from asm to C
« Reply #3 on: April 05, 2009, 10:25:01 AM »
any takers?

I'm not surprised nobody is interested, this is a rather tedious and not that interesting task. Unless somebody is also interested by this function, I don't see why anybody would do this "for free" ;)
Learn PIC ASM and do it yourself, it will be faster :p

Offline pomprockerTopic starter

  • Supreme Robot
  • *****
  • Posts: 1,431
  • Helpful? 16
  • Sorry miss, I was giving myself an oil-job.
    • Nerdcore - Programming, Electronics, Mechanics
Re: Translate from asm to C
« Reply #4 on: April 05, 2009, 03:12:28 PM »
Or i could just buy a PIC and program it?

I've never done anything with PICs before, any remarks?

Offline chelmi

  • Supreme Robot
  • *****
  • Posts: 496
  • Helpful? 15
    • Current projects
Re: Translate from asm to C
« Reply #5 on: April 05, 2009, 04:59:03 PM »
Or i could just buy a PIC and program it?

I've never done anything with PICs before, any remarks?

The only thing I've heard about PIC is that the C compilers sucks :D
But it's cheap...

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,703
  • Helpful? 173
    • Society of Robots
Re: Translate from asm to C
« Reply #6 on: May 13, 2009, 08:43:12 PM »
You've probably given up already but . . . you forgot to say what the code does . . .

Also, probably easier to just understand how it works, then rewrite it for ATmega8 from scratch.