;
; ********************************************
; * [cnc operating system]                 *
; * [beta 0.1] *
; * (C)2010 by [ahmed esmaeil]     *
; ********************************************
;
; Included header file for target AVR type
.NOLIST
.INCLUDE "m16def.inc" ; Header for ATMEGA16
.LIST
;
; ============================================
;   H A R D W A R E   I N F O R M A T I O N   
; ============================================
;
; [Add all hardware information here]
;
; ============================================
;      P O R T S   A N D   P I N S 
; ============================================
;
; [Add names for hardware ports and pins here]
; Format: .EQU Controlportout = PORTA
;         .EQU Controlportin = PINA
;         .EQU LedOutputPin = PORTA2
		  .EQU dataport = PORTC
		  .EQU datain = PINC
		  .EQU datadir = DDRC
		  .EQU ds1 = PORTB2
		  .EQU ds0 = PORTB1
		  .EQU sts_prt = PORTB
		  .EQU clk = PORTB4
		  .EQU intrd = PORTB0
		  .EQU cprt = PINA


;
; ============================================
;    C O N S T A N T S   T O   C H A N G E 
; ============================================
;
; [Add all constants here that can be subject
;  to change by the user]
; Format: .EQU const = $ABCD
	.EQU addframestart = $0060
;
; ============================================
;  F I X + D E R I V E D   C O N S T A N T S 
; ============================================
;
; [Add all constants here that are not subject
;  to change or calculated from constants]
; Format: .EQU const = $ABCD
	.EQU Start_packet = 0x1
;
; ============================================
;   R E G I S T E R   D E F I N I T I O N S
; ============================================
;
; [Add all register names here, include info on
;  all used registers without specific names]
; Format: .DEF rmp = R16
.DEF rmp = R16 ; Multipurpose register
.DEF cnt = R3 ; Limited counter register
.DEF gpm = R1 ; general purpose mathimatic register

;==============================================
		;ADD ALL MACROS HERE
;==============================================

.MACRO set_display
	cbi sts_prt, ds0
	cbi sts_prt, ds1
.ENDMACRO

;
; ============================================
;       S R A M   D E F I N I T I O N S
; ============================================
;
.DSEG
.ORG  0X0060
; Format: Label: .BYTE N ; reserve N Bytes from Label:
;
; ============================================
;   R E S E T   A N D   I N T   V E C T O R S
; ============================================
;
.CSEG
.ORG $0000
	jmp Main ; Reset vector
	reti ; Int vector 1
	nop
	reti ; Int vector 2
	nop
	reti ; Int vector 3
	nop
	reti ; Int vector 4
	nop
	reti ; Int vector 5
	nop
	reti ; Int vector 6
	nop
	reti ; Int vector 7
	nop
	reti ; Int vector 8
	nop
	reti ; Int vector 9 TIM0_OVF
	nop
	reti ; Int vector 10
	nop
	reti ; Int vector 11
	nop
	reti ; Int vector 12
	nop
	reti ; Int vector 13
	nop
	reti ; Int vector 14
	nop
	reti ; Int vector 15
	nop
	reti ; Int vector 16
	nop
	reti ; Int vector 17
	nop
	reti ; Int vector 18
	nop
	reti ; Int vector 19
	nop
	reti ; Int vector 20
	nop
;
; ============================================
;     I N T E R R U P T   S E R V I C E S
; ============================================
;
; [Add all interrupt service routines here]
;
; ============================================
;     M A I N    P R O G R A M    I N I T
; ============================================
;
Main:

; =============================================
;		TIMER SETTING
; ++++++++++++++++++++++++++++++++++++++++++++

	ldi rmp,0x01
	out TCCR0,rmp ;out setting for timer control register no prescaler
	out TIMSK,rmp ;enable overflow bit in the interupt mask
	sei ;set global interrupt


; Init stack
	ldi rmp, HIGH(RAMEND) ; Init MSB stack
	out SPH,rmp
	ldi rmp, LOW(RAMEND) ; Init LSB stack
	out SPL,rmp
; Init Port A
	ldi rmp,0 ; Direction Port A
	out DDRA,rmp
; Init Port B
	ldi rmp,0xff ; Direction Port B
	out DDRB,rmp
	;out PORTB,rmp
; [Add all other init routines here]
	ldi rmp,1<<SE ; enable sleep
	out MCUCR,rmp
	sei
;
; ============================================
;         P R O G R A M    L O O P
; ============================================
;
Loop:

;	ldi XH,HIGH(0x100)
;	ldi XL,LOW(0x100)
;	ldi ZH,HIGH(2*txt)
;	ldi ZL,LOW(2*txt)
;	lpm cnt,Z
;	inc cnt
;	mov R0,cnt
;	st X,cnt

plp:
;	lpm rmp,Z+
;	st X+,rmp
;	dec cnt
;	brne plp
	  
	

;	sub XL,R0
;	clr R0
;	sbc XH,R0
;	ldi rmp,01
;	call OutData
;

;	call delay
;	call delay
;	call delay
;	call delay
;	call delay
;	call delay
;prog 1

;	ldi XH,HIGH(0x100)
;	ldi XL,LOW(0x100)
;	ldi ZH,HIGH(2*txt1)
;	ldi ZL,LOW(2*txt1)
;	lpm cnt,Z
;	inc cnt
;	mov R0,cnt
;	st X,cnt

plp2:
;	lpm rmp,Z+
;	st X+,rmp
;	dec cnt
;	brne plp2
	  
	

;	sub XL,R0
;	clr R0
;	sbc XH,R0
;	ldi rmp,01
;	call OutData


;	call delay
;	call delay
;	call delay
;	call delay
;	call delay
;	call delay


;prog 2

;	ldi XH,HIGH(0x100)
;	ldi XL,LOW(0x100)
;	ldi ZH,HIGH(2*txt2)
;	ldi ZL,LOW(2*txt2)
;	lpm cnt,Z
;	inc cnt
;	mov R0,cnt
;	st X,cnt

plp3:
;	lpm rmp,Z+
;	st X+,rmp
;	dec cnt
;	brne plp3
	  
	

;	sub XL,R0
;	clr R0
;	sbc XH,R0
;	ldi rmp,01
;	call OutData


;	call delay
;	call delay
;	call delay
;	call delay
;	call delay
;	call delay


;prog 3

;	ldi XH,HIGH(0x100)
;	ldi XL,LOW(0x100)
;	ldi ZH,HIGH(2*txt3)
;	ldi ZL,LOW(2*txt3)
;	lpm cnt,Z
;	inc cnt
;	mov R0,cnt
;	st X,cnt

plp4:
;	lpm rmp,Z+
;	st X+,rmp
;	dec cnt
;	brne plp4
	  
	

;	sub XL,R0
;	clr R0
;	sbc XH,R0
;	ldi rmp,01
;	call OutData


;	call delay
;	call delay
;	call delay
;	call delay
;	call delay
;	call delay


;	sleep ; go to sleep
;	nop ; dummy for wake up
	rjmp loop ; go back to loop


;++++======++++++++++==========+++++++++++++++++++++++=
;+++++++++++++++++FUNCTIONS+++++++++++++++++++++++++++

OutData:
; ToDo push needed registers 
	PUSH cnt
	PUsh R0
	push gpm
	;+++++++++++++
	; adjusting the first byte in protocole
	mov gpm,rmp
	ldi rmp,4
	mul gpm,rmp
	mov gpm,R0
	ldi rmp,Start_packet
	add gpm,rmp
	;starting ofset addressing for data transfer
	set_display
	sbi sts_prt,intrd
	;call delay

tryagn:	
	;in rmp,PINA
;chek both of first two pins for read initiation
	;andi rmp,3
	;cpi rmp,3
	call wait_ready
	; ToDo return invalid after 3 trials
	;brne tryagn
	cbi sts_prt,intrd ; for the pc to get ready
	ser rmp
	out datadir,rmp	; prepare dataport for output
	mov rmp,gpm		; get first byte of the protocol
	out dataport,rmp ; out first byte of the protocol
	call oscy	; oscylate clock signal
	ld rmp,X+	
	mov cnt,rmp ;set the counter for the nuber of bytes to be outed
	mov gpm,rmp
	out dataport,rmp	; out the 2nd byte "number of bytes"
	call oscy	;clock signal
	;dec cnt
	
load:	; loop to out the remainning data
	ld rmp,X+
	out dataport,rmp
	call oscy
	dec cnt
	brne load
	inc gpm ; to set the correct value for the base adress
	sub XL,gpm
	clr gpm
	sbc XH,gpm


	;out the last byte
	; dummy byte right now
	ldi rmp,11
	out dataport,rmp
	call oscy

	
	;preparing for output stage
	call wait_outst ;wait for the pc to start returning
	;jmp hey
	clr rmp
	out datadir,rmp ;set data port for input

	call oscy
	in rmp,datain ;get data from pc
	;mov gpm,rmp
	;mov cnt,rmp
	;st X+,rmp
	call oscy
	in rmp,datain ;get data from pc
	mov gpm,rmp
	mov cnt,rmp	
	
	clr rmp
	cp cnt,rmp
	breq fcall
store:
	in rmp,datain ;get data to store
	st X+,rmp	;store data
	call oscy
	dec cnt		;decrement counter
	brne store
	rjmp nst
fcall:
	call oscy
	
nst:
	st X+,rmp	;store crc byte
	inc gpm
	sub XL,gpm
	clr gpm
	sbc XH,gpm
	

hey:
; ToDo Pull needed registers
	pop gpm
	pop R0
	pop cnt
	ret


delay:
	push rmp
	push R18

	ser rmp
	
cntp:
	dec rmp
	breq nd
	ser R18
cnt1:
	dec R18
	breq nd1
	rjmp cnt1
nd1:
	rjmp cntp  
nd:
	pop R18
	POP rmp
	ret

delay1:
	push rmp
	ldi rmp,0xff
dc:
	dec rmp
	breq nd11
	rjmp dc 

nd11:
	pop rmp
	ret

Wait_bussy:
;waiting for response from the pc for synchrounization
	push rmp
	
dob:
	in rmp, cprt
	andi rmp,0x03
	cpi rmp,0x02
	brne dob
	pop rmp
	ret

Wait_ready:
;waiting for response from the pc for synchrounization
	push rmp
	
dordy:
	in rmp, cprt
	andi rmp,0x03
	cpi rmp,0x03
	brne dordy
	pop rmp
	ret

wait_outst:
	push rmp
doout:
	in rmp,cprt
	andi rmp,0x03
	cpi rmp,0x01
	brne doout
	pop rmp
	ret

oscy:
	;oscylate clock and chek that pc admits
	cbi sts_prt,clk
	call wait_ready ; pc shoud iniate ready for that request
	sbi sts_prt,clk	
	call wait_bussy	; pc should iniate bussy for processing the request after
					; taking data
	ret
	
txt:
.DB 2,"my name is ahmed esmaeil and this is my system "
txt1:
.DB 19,"program 1 says high"
txt2:
.DB 21,"hello! from program 2"
txt3:
.DB 24,"It's me the 3rd program",13 


.org $1c00
strts:
	JMP strts
	
;
; End of source code
;
