; Orange programmer module v3.6 beta
; (c) 2001-2005 CnCLab
; Atmel AVR ATmega83, ATmega163

;CHIP=ATmega83,8K,atm163.hpl
;AREA=FLASH,8K(32),0,0
;AREA=EEPROM,512

;CHIP=ATmega163,16K,atm163.hpl
;AREA=FLASH,16K(32),0,0
;AREA=EEPROM,512


; not tested


ALLPINS=40
OPTIONS=mf,   ;FLASH: no modify, skip blank
INFO="AVR Adapter"


PINO=SCK,  0,8
PINO=MOSI, 2,6 
PINO=MISO, 1,7 
PINO=RESET,3,9 
PINI=MISO, 1,7 

PING=GND1,255,11 
PING=GND2,255,31 
PINO=VCC1,254,10

BUSO=CFREQ,128

R8=Fuses,B8
R9=Lock,C6,BLB12,BLB11,BLB02,BLB01,LB2,LB1
R10=CKSEL,L,"0000: Ext Clk,0001: IntRC 1MHz,0010: IntRC 2MHz,0011: IntRC 4MHz,0100: IntRC 8MHz,0101: ExtRC 0.9MHz,0110: ExtRC 0.9-3.0M,0111: ExtRC 3.0-8.0M,1000: ExtRC 8.0-12.0M,1001: LowFreq Crystal,1010: Crystal/Ceramic,1011: Crystal/Ceramic,1100: Crystal 0.9-3.0,1101: Crystal 0.9-3.0,1110: Crystal 3.0-8.0,1111: Crystal 3.0-8.0"
R12=BODEN,L,"0 - On,1 - Off"
R13=BODLEVEL,L,"0 - High,1 - Low"

R14=BOOTRST,L,"0 - Boot Loader","1 - Application"
R15=BOOTSZ,L,"32 pages,16 pages,8 pages,4 pages"

CDELAY=8 ; minimum periods for the serial clock (SCK) > 4 XTAL1 clock cycle!


[_DOUT]
R1=0;
LOOP=(7,0){MOSI=R0[I],SCK=1,R1[I]=MISO,SCK=0}

[_DIN]
R0=0
LOOP=(7,0){SCK=1,R0[I]=MISO,SCK=0}


[INIT]
SCK=0
MISO=Z
CFREQ=2000000
RESET=0,P=1000

LOOP=(0,31){    ; 32 attempts
RESET=1,P=250
RESET=0,P=25000
R0=0xAC,_DOUT ;Programming Enable
R0=0x53,_DOUT
R0=0x00,_DOUT
R3=R1
R0=0x00,_DOUT
R3?0x53{BREAK}
;PRINT=("ANSWER: %02lX",R1)
}
R3?!0x53{PRINT=("ANSWER ERROR: %02lX",R3),EXIT}

P=10



[READ]
$AREA?0{
R0=0x20            ;program memory area
R1=ADR,R0[3]=R1[0] ;Hi/Lo
_DOUT
LOOP=(16,9){MOSI=ADR[I],SCK=P}
LOOP=(8,1){MOSI=ADR[I],SCK=P}
}
$AREA?1{
R0=0xA0      ;eeprom area
_DOUT
LOOP=(15,8){MOSI=ADR[I],SCK=P}
LOOP=(7,0){MOSI=ADR[I],SCK=P}
}

_DIN		;common
DATA=R0


[WRITE]
$AREA?0{
PRINT=("Only Page Write Supported!")
EXIT
}

$AREA?1{
R0=0xC0 ;eeprom memory area 
_DOUT
LOOP=(15,8){MOSI=ADR[I],SCK=P}
LOOP=(7,0){MOSI=ADR[I],SCK=P}
R0=DATA,_DOUT
P=9000 ; 4ms
}


[WRITEBLOCK]
R7=ADR	;check empty (0xFF) block
LOOP=($BLOCKSIZE){
R1=DATA
R1?!0xFF{BREAK}
ADR=+1
}
R1?0xFF{RETURN}
ADR=R7

LOOP=($BLOCKSIZE){
R0=0x40 ;program memory
R1=ADR,R0[3]=R1[0],_DOUT 	;Hi/Lo
R0=0,_DOUT
LOOP=(8,1){MOSI=ADR[I],SCK=P}
R0=DATA,_DOUT
P=10
ADR=+1
}
;Write Program memory Page:
ADR=R7
_DOUT(0x4C) 
LOOP=(16,9){MOSI=ADR[I],SCK=P}
LOOP=(8,7){MOSI=ADR[I],SCK=P}
LOOP=(6,1){MOSI=0,SCK=P}
_DOUT(0) 		;dummy data
P=5000


[WRITEEND]
P=10000
RESET=1,P=20,
RESET=0,P=20000





["Read Fuses"]
R0=0x50,_DOUT	;Read Fuse bits
R0=0x00,_DOUT
R0=0x00,_DOUT
_DIN
R8=R0


R10=0,R11=0,R12=0,R13=0
R10=R8,R10=&0xF	;R10=CKSEL,L
;R11[0]=R8[4]    
;R11[1]=R8[5]
R12[0]=R8[6]    ;R12=BODEN,L,On,Off            
R13[0]=R8[7]    ;R13=BODLEVEL,L,High,Low 

R0=0x58,_DOUT   ;Read Fuse High Bits
R0=0x08,_DOUT
R0=0x00,_DOUT
_DIN
RESET=1,P=10
VCC=0

R8=R0
;GET=("Read Fuses",R8)
R14=0,R15=0,R16=0,R17=0,R18=0,R19=0
R14[0]=R8[0]	;R14=BOOTRST,C1
R15[0]=R8[1]	;R15=BOOTSZ,L,"32 pages,16 pages,8 pages,4 pages"


GET=("Read Fuses",R10,R12,R13,R14,R15)
;GET=("Read Fuses",R10,R11,R12,R13,R14)


["Write Fuses"]
GET=("Write Fuses",R10,R12,R13,R14,R15)
RA?0{EXIT}
;PRINT=("%lX",R11)
R10?0{
PRINT=A("This fuses value require Ext. Clock, continue?")
RA?0{EXIT}
}

R8=0

R8=R10,R8=&0xF	;R10=CKSEL,L
R8[6]=R12[0]   ;R12=BODEN,L,On,Off            
R8[7]=R13[0]   ;R13=BODLEVEL,L,High,Low 

R0=0xAC,_DOUT
R0=0xA0,_DOUT
R0=0x00,_DOUT
R0=R8,_DOUT
P=10000

R8=0xFF
R8[0]=R14[0]	;R14=BOOTRST,C1
R8[1]=R15[0]	;R15=BOOTSZ,L,"32 pages,16 pages,8 pages,4 pages"
R8[2]=R15[1]	

R0=0xAC,_DOUT   ;Write High Fuse
R0=0xA8,_DOUT
R0=0x00,_DOUT
R0=R8,_DOUT
P=10000

RESET=1,P=20
RESET=0,P=20000


[ReadLock]
R0=0x58,_DOUT ;Write lock bits
R0=0x00,_DOUT 
R0=0x00,_DOUT 
_DIN
R9=R0
GET=("Lock",R9)

[WriteLock]
GET=("Write Lock",R9)
RA?0{EXIT}
R0=0xAC,_DOUT ;Write lock bits
R0=0xE0,_DOUT 
R0=0x00,_DOUT 
R0=R9,R0=|0xC0,_DOUT 

P=10000
RESET=1,P=20,
RESET=0,P=20000

[ReadID]
R0=0x30,_DOUT
R0=0x00,_DOUT
R0=0x00,_DOUT
_DIN
R2=R0,R2=<<8

R0=0x30,_DOUT
R0=0x00,_DOUT
R0=0x01,_DOUT
_DIN
R2=|R0,R2=<<8

R0=0x30,_DOUT
R0=0x00,_DOUT
R0=0x02,_DOUT
_DIN
R2=|R0

R2?0x1E9305{PRINT=("ID: %06lX - ATmega83",R2),EXIT}
R2?0x1E9402{PRINT=("ID: %06lX - ATmega163",R2),EXIT}
PRINT=("ID: %06lX",R2)



[Erase]
R0=0xAC,_DOUT ;Chip Erase
R0=0x80,_DOUT 
R0=0x00,_DOUT 
R0=0x00,_DOUT 

P=50000
RESET=1,P=20,
RESET=0,P=20000



[END]
RESET=1
CFREQ=0
;EO=1,P=10 ;BB off