ASM makro kullanımı ile ilgili bilgiler

Başlatan alisumer, 11 Aralık 2022, 01:56:13

alisumer

  program başında "radix dec" veya    "list r=dec " ifadesi ile program içerisinde vereceğimiz desimal 8 bitlik değerleri aşmadan şu tarz oynamalar yapabiliriz.böylelikle negatif sayıları dönüştürme işi ile uğraşmadan da işlemler yapabiliriz.NOT: radix belirtmeden varsayılan olarak aynı işlemleri HEX sayı sisteminde de yapabilirsiniz ama kontrolu güç olur böyle iyi   
include   "..........."
 list r=dec 

.........
BASLA:
    CLRF        STATUS
    MOVLW    -8*11               ; 0xA8 (-88) sayısını değişkenimize yazar yazar
    MOVWF    SAYI
    MOVLW    (28<<2)-42          ;0x46 (70) sayısını değişkene yazar 
    MOVWF    KERE
    ADDWF    SAYI    ,W  ;TOPLAMA SONUCUNU 0XEE(-18) ŞEKLİNDE BULUR
bu yazım şeklini meblab ide kabul ediyor tüm denemelerim doğru sonuç verdi işlem eper 8 biti aşarsa alt byte gene doğru değeri verir ama üst byte kaybolur.bu hali ile bile birçok problemimi çözüyor.
Hep meraktan

alisumer

#16
32 Bit işaretli sayıları paket halinde değişkenlere yazmak için bir makro
#include p16F690.inc
RADIX    DEC                  :desimal sayılar ile işlem yapabilmek için gerekli
CBLOCK 0x20
Out0 :5 ;res 1 ;

ENDC
PAKET32 MACRO Var, Address ;Address meblab ide için Cblock yada udata kullanıldığında ram başlangıç adresidir(otm)
BANKSEL Address 
movlw Address 
movwf FSR                  ;fsr ye adresi yükler
movlw Var & H'FF'          ;en değersiz byte filtrelenip yazılır
movwf INDF                ;fsr nin işaretlediği adrese değeri yazar
movlw Var >>8 & H'FF'      ; Var 8 bit kaydırılır filtrelenip fsr 1 arttırılır(bir sonraki ram bölgesi yazılır)
incf FSR,F 
movwf INDF 
movlw Var >>16 & H'FF'
incf FSR,F 
movwf INDF 
movlw Var >>24 & H'FF'
incf FSR,F 
movwf INDF 

ENDM 
ORG 0
START 
PAKET32 12345678,Out0 ; PAKET32 -12345678,Out0 yazıldığında da negatif değeri yazabilir adreslere

goto START
END
yazılan değer en fazla 2.147.483.647 ile -2.147.483.648 arası olabilir
Hep meraktan

alisumer

TOGGLE	MACRO	PORT?,R0
		MOVLW	0X01<<R0
		XORWF	PORT?	,F
           ENDM
bir pinin durumunu terslemek için makro .program içerisinde örneğin "TOGGLE PORTA,5"  yazıldığında porta 5 pini durum değiştirir NOT: makro içerisindeki soru işaretine dokunmayın MEPLAB soru işaretini ana programda yazdığımızla değiştirir.
Hep meraktan

alisumer

#18
;/////////////////////////////////////////////////////////////////	
	;EEPROM YAZMA
;/////////////////////////////////////////////////////////////////
WRITE	MACRO R3,R1
	BCF		INTCON	,GIE		;KESMELERİ KAPAR (ÖNEMKİ KESME OLMAMALI YAZMA ESNASINDA)
	BCF		PIR2		,EEIF	;PAYRAĞI İNDİR
	MOVF		R3		,W		;
	BANKSEL	EEADR
	MOVWF	EEADR			;BELİRTTİĞİMİZ ADRESİ EEADR E YAZ(YAZILACAK ADRESİ SEÇ)
	BANKSEL	R1
	MOVF		R1		,W		;
	BANKSEL	EEDAT
	MOVWF	EEDAT			;VERİYİ ADRESE YAZ
	BANKSEL	EECON1
	BCF		EECON1	,EEPGD	;eeprom veya program hafızası seçilebilir.burada eeprom seçili
	BSF		EECON1	,WREN	;yazmayı aç
	MOVLW	0X55
	MOVWF	EECON2			;yazma için rutin olan h55 ve hAA komutları eecon2 ye sırası ile yazılmalı
	MOVLW	0XAA
	MOVWF	EECON2			;eecon2 ye sırası ile yazılmalı
	BSF		EECON1	,WR		;yazmaya başla
	BTFSC	EECON1 	,WR
	GOTO		$-1			 	;bitene kadar takıl
	BANKSEL	PIR2		
	BTFSS	PIR2	 	,EEIF	;TAMAMLANINCA BAYRAK KALKAR DEVAM
	GOTO		$-1
	BANKSEL	EECON1
	BCF		EECON1	,WREN	;yazmayı kapat
	BCF		STATUS	,RP1
	BCF		STATUS	,RP0			;Bank 0
	BCF		PIR2		,EEIF	;BAYRAĞI İNDİR
	ENDM

;////////////////////////////////////////////////////////////////
	;EEPROM OKUMA
;////////////////////////////////////////////////////////////////
READ	MACRO	R3
	MOVF 	R3, W;
	BANKSEL 	EEADR
	MOVWF	EEADR		;Data Memory ;Address to read
	BANKSEL 	EECON1
	BCF		EECON1, EEPGD	;Point to DATA memory
	BSF		EECON1, RD	;EE Read
	BTFSC	EECON1, RD
	GOTO		$-1
	BANKSEL 	EEDAT
	MOVF		EEDAT, W		;W = EEDAT
	BANKSEL PORTA
	ENDM
program içerisinde kullanılacak örnek kodlar YAZMA İÇİN " WRITE 3,VAR" okuma için "READ 3" komutları ile eepromun 3.adresine VAR değişkeni yazılır.okuma komutu ile de 3. adresten kaydedilmiş veri "W" ye yazılır.bu hali ile basic komutuna benzedi biraz.
Hep meraktan

alisumer

ETE hocam bir sorum olacaktı iki butonum var ve birine bastığımda bir word değişkeni ardışık iki adrese ve diğerine bastığımda da ilk ikisinin ardından ilk adresten itibaren diğer bir word değişkeni yazdım örnek (0,1,2,3 adresleri gibi) bu adres başlangıcı olan sayıyı yani "0"ı da 255. adreste tuttum ve her yeni eprom kaydı sonrası bu adresi bir artırıp tekrar kaydettim program başında da adresi okuyarak hangi adresten kayda başlayacağımı bildim sonra de eeprom ömrünü uzatmak için saatlerce uğraşıp çok saçma bir yere vardığımı farkettim çünkü bu sefer de adresi tuttuğum 255.adresi hunharca kullanmış oldum :o.daha önce böyle bir paylaşım yapılmıştı ama bulamadım.çözüm hakkında yardımcı olurmusunuz.
Hep meraktan

ete

Sorunu anladım. Benzer işlerle daha öncede uğraşmıştım. Burada temel amaç eprom hafızalarına dengeli biçimde gerektiği kadar yazma yapılmasıdır. Sıfır adresi dışında kalanları dengeli kullanıyorsun ama sıfırı da bu arada aşırı şekilde kullanmış oluyorsun.
Ben son olarak şöyle bir mantık kullanmıştım. Senin örneğine benzeterek açıklayayım.

Sıfır nolu adresten kayıta başladık ve ilk 4 adrese değişkenlerini kayıt ettik.
Elimizde 1 sayac daha olacak. Bu sayac ilgili adreslere kac defa kayıt ettiğimizi tutacak. Tabiiki bu değerleride kayıt etmek zorunda kalacaksın. Bu durumda kayıt adedin 5 olacak. Böylece ilk 5 adrese kayıt yaptın ve sondaki adres(baştakide olabilir) kayıt adedin olacak. Bu adreslere en azından 100 kayıt yada toplamda 255 kayıt yapacağını düşünebilirsin.
Şimdi diyelimki adres kayıt limitini doldurdun. Yapılacak iş 0+5=5 nolu adresten itibaren yenilerini kayıt etmek ve 0-4 arasına 255 değerini yeniden yazmak olacak.
Böylece okuma yaparken 255 lerin bittiği yeri bulup onu kayıt altında tutman bir dahaki kayıtı oraya yapman yeterli olacaktır. 255 den küçük bir değer bulunmaz ise işin başında olduğunu anlayabilir ve sıfır nolu adresten işe başlarsın. Böylece adresleri dengeli şekilde tutabilirsin. Önceleri adres göstergesinide kayıt ediyordum ama sonradan fazla işe yaramadığına karar verip yanlızca kayıt adedini tutuyordum.
Bu iş akıl işidir. Bir başkası daha akıllıca bir yöntem bulabilir. Kafa yormak gerek. Amacımız eprom adreslerini dengeli şekilde kullanmak hep aynı adrese kayıt yapmamak. Düşünün bakalım.

Ete

alisumer

Anladım sanırım tek eksi yanı sisteme ilk enerji verildiğinde epromda ff harici ilk değeri bulana kadar okuma yapıp ilk baştaki 0-254 arası sınırladığım kayıt adedini bulana kadar bir gecikme olacak.teşekkürler hocam.
Hep meraktan

ete

Eprom okumasında bekleme yapılmıyor biliyorsun. Toplam 256 adres okunacak ki bu çok kısa sürede halledilir. Üstelik her açılışta belirli bir gecikme uygulandığınıda unutma. Onu minimumda (150ms dir) tutarsın gerisi 100 ms bile tutmaz diye düşünüyorum. Kısaca sorun olmaz. Ama emniyetli bir sistem bana kalırsa.

Ete

alisumer

Karşılaştırma fonksiyonları için makrolar.
;///////////////////DEĞER KIYASLAMASI//////////////////////////////////
;KULLANIMI= KARŞILAŞTIRILACAK HER BİR "WORD" DEĞERİ ARDIŞIK RAM BÖLGELERİNDE TUTULMALI 
;R4 VE R5 DEĞERLERİNİ ASCII DEĞERLER OLARAK İLGİLİ İŞARETLER OLARAK SEÇTİM 
;MAKRODA "=" SENBOLÜ KABUL EDİLMEDİĞİ İÇİN DEC KARŞILIĞI YAZILDI
;AMA ANA PROGRAMDA KULLANILABİLİR OLDU
;ÖRNEK KODLAR= KIYAS A,"<","=",B 
;			KIYAS A,"<"," ",B
;			KIYAS A,"="," ",B
;			BTFSS	R6	,0
;			GOTO	****
;			GOTO ****
;BOŞ BIRAKILAN SEMBOL YERİNE ASCII BOŞLUK BIRAKILMALI
;R6 ADRESİNİN İLK BİTİ TRUE/FALSE DÖNDÜRÜR 
;MAKRO ÇIKIŞI R6 , 0 BİTİ KONTROL EDİLEREK İŞLEM YAPILIR
;" > " YADA ">=" İŞARETİ İÇİN AYRI BİR İŞLEME GEREK YOK MEVCUT İŞLEMLERİN TERSİ OLDUĞUNDAN SADECE DEĞİŞKEN YERİ DEĞİŞECEK	
KIYAS	MACRO	R0,R4,R5,R2
	IF   R4 == "<" && R5 == 61
		MOVF		R0+1		,W			;IF Y <= ART THEN GOTO KAPA
		SUBWF	R2+1		,W			;
		BTFSS	STATUS	,C			;
		GOTO		YANLIS				;GOTO		SAG_KAPA
		BTFSS	STATUS	,Z
		GOTO		DOGRU				;GOTO		SAG_AC	
		MOVF		R0		,W								
		SUBWF	R2		,W
		BTFSS	STATUS	,C
		GOTO		YANLIS
		GOTO		DOGRU
		
	
		

		ENDIF
	IF   R4 == "<" && R5 == 32
		MOVF		R0+1		,W			;IF Y < ART THEN 
		SUBWF	R2+1		,W			;
		BTFSS	STATUS	,C			;
		GOTO		YANLIS					;GOTO		SAG_KAPA
		BTFSS	STATUS	,Z
		GOTO		DOGRU			;GOTO		SAG_AC	
		MOVF		R0		,W								
		SUBWF	R2		,W
		BTFSC	STATUS	,Z
		GOTO		YANLIS
		BTFSS	STATUS	,C
		GOTO		YANLIS
		GOTO		DOGRU
	
		ENDIF
		
	IF	R4 == 61 && R5 == 32		;IF A=B
		MOVF		R0+1		,W
		XORWF	R2+1		,W
		BTFSS	STATUS	,Z
		GOTO		YANLIS
		MOVF		R0		,W
		XORWF	R2		,W
		BTFSS	STATUS	,Z
		GOTO 	YANLIS
		GOTO		DOGRU
		ELSE

		GOTO	EXT
		ENDIF
YANLIS:
		BCF		R6		,0
		GOTO		EXT
DOGRU:							;GOTO		SAG_KAPA	
		BSF		R6		,0
		GOTO		EXT

EXT:
		ENDM    
	  
işaretleri ascii olarak kullanmak zorunda kalmam dışında iş görür tabi bide adı kıyas  ::) .ayrıca diğer dillerin karşılaştırma sonucu çıkardığı koddan çok daha kısa kod üretiyor.kullanımını kodun üzerinde başlık kısmında yapmaya çalıştım soru yada kodda bir sorun olursa bildirin lütfen.denemelerini yaptım hata bulamadım ama insanlık hali.
Hep meraktan

alisumer

#24
programı işlemciye yazdığımız esnada eeprom'a veri yazmak içindir,program çalışması esnasında herhangi bir yazma yapmaz.program içerisinde rutin eprom yazma kodları ile tekraren değiştirilebilir tabiki.
        
        org      0x00
        basla:
        çalışan programlarımız
        ......
        .......
        goto basla
        ORG    0X2100         ; eepromun çoğu 16 f serisinde başlangıç adresi 
        DE  0, 0, 0, 0, 0, 0    ;ilk adresten başlayarak 5. adrese kadar 0 yazar
        END 
   
Hep meraktan

alisumer

#25
aynı formatı gene ilgili adreslerinde örneğin org 0x800  kullanılarak bu sefer program hafızasına "data,da veya dw"komutları kullanılarak yazılabilir
Hep meraktan

alisumer

Klasik for-next döngüsü için bir makro "FOR 10,200" şeklinde kullanımı pic basic pro ya oldukça benzer oldu,işlevi ise  for dan sonraki kodu next makrosunu görene kadar çalıştırır next makrosunda fordaki verilen koşula bakar ona göre kodu yeniden tekrarlar yada bir altından devam eder.şu an için sadece 255 e kadar tekrar yapabiliyor,for ve next iki ayrı makro olarak çalışır
FOR	MACRO	R0,R2
		MOVLW	R2 	
		MOVWF	R4
		MOVLW	R0	
		SUBWF	R4	,F
FOR1:
		ENDM
		
NEXT	MACRO	
		DECFSZ	R4	,F
		GOTO		FOR1
		ENDM	
kullanımı ise
FOR 10,220
BSF PORTA ,0
NOP
BCF PORTA ,0
.........
........
NEXT
Bu kodda for next arasına yazdığımız kodun 210 kere tekrar etmesi sağlanır
Hep meraktan

alisumer

#27
Map fonksiyonu için makro bildiğimiz arduino map fonksiyonu ile aynı çalışıyor hayırlı olsun :)
bir hata yapmışım düzeltip paylaşacağım
Hep meraktan

alisumer

Bölme fonksiyonu hata veriyordu düzelttim
MAP    MACRO    R0,R0+1,VAR,VAR1,VAR2,VAR3,ADDRESS ;address =VAR
 ;{
;return ((value - fS) * (tE - tS)) / ((fE - fS) + tS);
;map(value,fS, fE, tS,tE)
;map(512, 0, 1023,0, 2000)            ((512-0)*(2000-0)/(1023-0)+0)
    BANKSEL ADDRESS
    movlw    ADDRESS ;
    movwf    FSR                    ;fsr ye adresi yükler
    movlw    VAR & H'FF'            ;;en değersiz byte filtrelenip yazılır
    movwf    INDF                ;fsr nin işaretlediği adrese değeri yazar
    movlw    VAR >>8 & H'FF'        ;; Var 8 bit kaydırılır filtrelenip fsr 1 arttırılır(bir sonraki ram bölgesi yazılır)
    incf    FSR        ,F
    movwf    INDF

    MOVLW    VAR1 &0XFF
    INCF        FSR        ,F
    MOVWF    INDF
    MOVLW    VAR1>>8 & 0XFF
    INCF        FSR        ,F
    MOVWF    INDF
    
    MOVLW    VAR2 & 0XFF
    INCF        FSR        ,F
    MOVWF    INDF
    MOVLW    VAR2 >> 8 &0XFF
    INCF        FSR        ,F
    MOVWF    INDF

    MOVLW    VAR3 & 0XFF
    INCF        FSR        ,F
    MOVWF    INDF
    MOVLW    VAR3 >> 8 &0XFF
    INCF        FSR        ,F
    MOVWF    INDF
;*******************************************************************FONKSİYONLAR**************************    
    MOVF        R1        ,W
    SUBWF    R0        ,F
    BTFSS    STATUS    ,C
    INCF        R1+1        ,F    ;VALUE-FS
    MOVF        R1+1        ,W    ;SONUC    R0 
    SUBWF    R0+1        ,F
;///////////////////////////////
    MOVF        R3        ,W
    SUBWF    R4        ,W
    MOVWF    R5
    BTFSS    STATUS    ,C
    INCF        R3+1        ,F    ;TE-TS
    MOVF        R3+1        ,W    ;SONUC    R5 
    SUBWF    R4+1        ,W
    MOVWF    R5+1
;********************************
    MULL32    R5,R5+1,R0,R0+1            ;((value - fS) * (tE - tS))  ;SONUC= XSL-XSH    32BİT
    
    MOVF        R1        ,W                ;    60  62 64  66  68            ADRESLER
    SUBWF    R2        ,W
    MOVWF    R5                        ;        R0  R1 R2  R3  R4            DEĞİŞKENLER
    BTFSS    STATUS    ,C                ;    MAP    SAYI,0,1023,800,2200,R1        HARİTA
    INCF        R1+1        ,F                ;    (1023-0)+800                    İŞLEM
    MOVF        R1+1        ,W                ;    map(value,fS, fE, tS,tE)
    SUBWF    R2+1        ,W
    MOVWF    R5+1                        ;  R2 - R1 + R3
                                    ;((fE - fS) + tS);
    CLRF        R6                                ;SONUÇ = R2
    CLRF        R6+1
    BOL    XSL,XSL+1,XSH,XSH+1,R5,R5+1,R6,R6+1
    MOVF        R3        ,W
    ADDWF    XSL        ,F
    MOVF        R3+1        ,W
    BTFSC    STATUS    ,C
    INCF        XSL+1        ,F
    ADDWF    XSL+1        ,F
    BTFSC    STATUS    ,C
    INCFSZ    XSH
    GOTO    $+2
    INCF        XSH+1
    MOVF        XSL        ,W
    MOVWF    MAP_SNC
    MOVF        XSL+1    ,W
    MOVWF    MAP_SNC+1    
    MOVF        XSH    ,W
    MOVWF    MAP_SNC+2    
    MOVF        XSH    ,W
    MOVWF    MAP_SNC+3        
    
    ENDM    
Hep meraktan

alisumer

#29
yeni bölme fonksiyonu bi kısmı araklama tabi :P işaretli 32 bit sayılarla işlem yapabiliyor 32/32=32 sonucu da 32 bit içinde saklıyor biraz zaman alıyor ama kısaltmanın yolunu buldum gibi deniyorum paylaşırım başarınca.MAP ile ilgili tüm makrolar 32 bit çarpma ve 32 bit bölme makrosundan ibaret.ikisi de aşağıda
;****************************************************************
;* MUL        : 16 x 16 = 32 multiply                           *
;*                                                              *
;* Input      : R3 * R1                                         *
;* Output     : R2, W = low word                                *
;*            : R0, R2 + 1 = mid word                           *
;*            : R0 = high word                                  *
;*                                                              *
;* Notes      :                                                 *
;****************************************************************
MULL32  MACRO   X1,X1+1,X2,X2+1

		
 
MUL3:       
	 
		MOVLW   	.16              ; For 16 shifts
        	MOVWF   	XX
       	CLRF   	XSH + 1
        	CLRF    	XSH
mulloop: 
		BCF		STATUS, C
		RRF     	X1 + 1, F
       	RRF     	X1, F
        	BTFSS   	STATUS, C		;
        	GOTO    	mull1           	; Skip add
        	MOVF    	X2, W           ; 16-bit add with carry out
        	ADDWF   	XSH, F
        	MOVF    	X2 + 1, W
        	BTFSC   	STATUS, C
        	INCFSZ  	X2 + 1, W
        	ADDWF   	XSH + 1, F
mull1: 
		RRF    	XSH + 1, F
       	RRF     	XSH	,F
        	RRF     	XSL + 1,F
        	RRF     	XSL	,F  
        	DECFSZ  	XX	,F
        	GOTO    	mulloop
DONE:   
  		CLRF		X1
  		CLRF		X1+1
  		CLRF		X2
  		CLRF		X2+1
 
          ENDM

               
;****************************************************************
;* DIV        : 16 x 16 (31 x 15) divide                        *
;*                                                              *
;* Input      : R0 / R1                                         *
;* Output     : R0, R0+1  =     bolüm                           * 
;*           	 : R2 = remainder            kalan                     *
;*                                                              *
;* Notes      : R2 = R0 MOD R1                                  *
;****************************************************************
;		----BÖLÜNEN---	 ----BÖLEN----
;*** 32 BIT SIGNED DIVIDE ***
;REGA / REGB -> REGA
;Remainder in REGC
;Return carry set if overflow or division by zero
;*** 32 BIT SIGNED DIVIDE ***
;REGA / REGB -> REGA
;Remainder in REGC
;Return carry set if overflow or division by zero
BOL	MACRO	D0,D1,D2,D3,B0,B1,B2,B3
divide:
	clrf		DD1		;Reset sign flag
	call	absa		;Make dividend (REGA) positive
	skpc
	call	absb		;Make divisor (REGB) positive
	skpnc
	return				;Overflow
	clrf		DR0		;Clear remainder
	clrf		DR1
	clrf		DR2
	clrf		DR3
	movlw	D'32'		;Loop counter
	movwf	DD
	;call	slac				;Purge sign bit

dvloop:
	call	slac		;Shift dividend (REGA) msb into remainder (REGC)
	movf		B3,w		;Test if remainder (REGC) >= divisor (REGB)
	subwf	DR3,w
	skpz
	goto	dtstgt
	movf		B2,w
	subwf	DR2,w
	skpz
	goto	dtstgt
	movf		B1,w
	subwf	DR1,w
	skpz
	goto	dtstgt
	movf		B0,w
	subwf	DR0,w
dtstgt:	
	skpc			;Carry set if remainder >= divisor
	goto	dremlt
	movf		B0,w		;Subtract divisor (REGB) from remainder (REGC)
	subwf	DR0,f
	movf		B1,w
	skpc
	incfsz	B1,w
	subwf	DR1,f
	movf		B2,w
	skpc
	incfsz	B2,w
	subwf	DR2,f
	movf		B3,w
	skpc
	incfsz	B3,w
	subwf	DR3,f
	clrc
	bsf		D0,0		;Set quotient bit

dremlt:
	decfsz	DD,f	;Next
	goto	dvloop
	btfsc	DD1,0		;Check result sign
	call	negatea		;Negative
	GOTO	DIVCIK
;/////////////////////////////////////////////////////////////////	
absa:
	rlf		D3,w
	skpc
	return			;Positive
negatea:
	movf		D3,w		;Save sign in w
	andlw	0x80

	comf		D0,f		;2's complement
	comf		D1,f
	comf		D2,f
	comf		D3,f
	incfsz	D0,f
	goto	nega1
	incfsz	D1,f
	goto	nega1
	incfsz	D2,f
	goto	nega1
	incf		D3,f
nega1:
	incf		DD1,f		;flip sign flag
	addwf	D3,w		;Return carry set if -2147483648
	return
;/////////////////////////////////////////////////////////////////
absb:
	rlf		B3,w
	skpc
	return				;Positive
negateb:
	movf		B3,w		;Save sign in w
	andlw	0x80
	comf		B0,f		;2's complement
	comf		B1,f
	comf		B2,f
	comf		B3,f
	incfsz	B0,f
	goto	negb1
	incfsz	B1,f
	goto	negb1
	incfsz	B2,f
	goto	negb1
	incf		B3,f
negb1
	incf		DD1,f		;flip sign flag
	addwf	B3,w		;Return carry set if -2147483648
	return
;///////////////////////////////////////////////////////////
slac:
	rlf		D0,f
	rlf		D1,f
	rlf		D2,f
	rlf		D3,f
slc:
	rlf		DR0,f
	rlf		DR1,f
	rlf		DR2,f
	rlf		DR3,f
	return
DIVCIK:
	ENDM
Hep meraktan

Powered by EzPortal