;***************************************************************************
;*
;* Title	: AVR ISP (Auto adr inc, 115200bps)
;* Version	: 3.3
;* Last updated	: Jun 25 2004 
;* Target	: AT90S2313
;* File		: avr910_2313_V33.asm 
;* Author(s)	: klaus@mikrocontroller-projekte.de, thomas@fischl.de
;* last Filename: avr910_2313_V32.asm
;* initial File: avr910_31.asm, Author: wubblick@yahoo.com, source: www.mit8.ru/~mars/ )
;*
;* DESCRIPTION
;*	The firmware on all programmers now support a unified protocol for 
;*	program and data memory programming. The host computer do not need
;*	to know if the programmer operates in serial or parallel mode.
;*
;*	The following commands are supported. All commands start with a
;*	single letter. The programmer returns 13d (carriage return) or the
;*	data read after the command is finished.
;*
;*                                     +-------------------+------------+------+
;*  Commands                           |    Host  writes   | Host reads |      |
;*  --------                           +-----------+-------+------+-----+      |
;*                                     | ID (hex ) | data  | data |     | Note |
;* +-----------------------------------+-----------+-------+------+-----+------+
;* | Enter programming mode            | 'P'(0x50) |       |      | 13d |   1  |
;* | Report autoincrement address      | 'a'(0x61) |       |      | 'Y' |      |
;* | Set address                       | 'A'(0x41) | ah al |      | 13d |   2  |
;* | Write program memory, low byte    | 'c'(0x63) |    dd |      | 13d |   3  |
;* | Write program memory, high byte   | 'C'(0x43) |    dd |      | 13d |   3  |
;* | Issue Page Write                  | 'm'(0x6d) |       |      | 13d |  13  |
;* | Read program memory               | 'R'(0x52) |       |dd(dd)|     |   4  |
;* | Write data memory                 | 'D'(0x44) |    dd |      | 13d |      |
;* | Read data memory                  | 'd'(0x64) |       |   dd |     |      |
;* | Chip erase                        | 'e'(0x65) |       |      | 13d |      |
;* | Write lock bits                   | 'l'(0x6c) |    dd |      | 13d |      |
;* | Write fuse bits (reserved)        | 'f'(0x66) |    dd |      | 13d |  11  |
;* | Read fuse and lock bits (reserved)| 'F'(0x46) |       |   dd |     |  11  |
;* | Leave programming mode            | 'L'(0x4c) |       |      | 13d |   5  |
;* | Select device type                | 'T'(0x54) |    dd |      | 13d |   6  |
;* | Read signature bytes              | 's'(0x73) |       | 3*dd |     |      |
;* | Return supported device codes     | 't'(0x74) |       | n*dd | 00d |   7  |
;* | Return software identifier        | 'S'(0x53) |       | s[7] |     |   8  |
;* | Return sofware version            | 'V'(0x56) |       |dd dd |     |   9  |
;* | Return hardware version           | 'v'(0x76) |       |dd dd |     |   9  |
;* | Return programmer type            | 'p'(0x70) |       |   dd |     |  10  |
;* | Set LED                           | 'x'(0x78) |    dd |      | 13d |  12  |
;* | Clear LED                         | 'y'(0x79) |    dd |      | 13d |  12  |
;* | Universial command                | ':'(0x3a) |  3*dd |   dd | 13d |  15  |
;* | New universal command             | '.'(0x2E) |  4*dd |   dd | 13d |  15  |
;* |-----------------------------------+-----------+-------+------+-----+------|
;* | New Commands since Version 3.3    |           |       |      |     |      |
;* | Reserved (AVRProg) usage not known| 'b'(0x62) |  ??   |  ??  | ??  |      |
;* | Exit (AVRProg only)               | 'E'(0x45) |       |      | 13d |  15  |
;* | Return Chip ID (Terminalmode only)| 'i'(0x69) |       |  s[n]|     |  14  |
;* | Commands for AVRDUDE only!!       |           |       |      |     |  14  |
;* | Report enhanced Mode(AVRDUDE only)| 'M'(0x45) |       |      | 'Y' |  14  |
;* | eNhanced Block Write(AVRDUDE only)| 'N'(0x4E) |   nn  |   dd |     |  14  |
;* | eNhanced Block Read (AVRDUDE only)| 'n'(0x6E) |   nn  |   dd |     |  14  |
;* +-----------------------------------+-----------+-------+------+-----+------+
;*
;* NOTE 1
;*	The Enter programming mode command MUST be sent one time prior to
;*	the other commands, with the exception of the 't', 'S', 'V', 'v'
;*	and 'T' commands. The 'T' command must be sent before this command
;*	(see note 6).
;*
;*	For programmers supporting both parallel and serial programming
;*	mode this command enters parallel programming mode. For programmers
;*	supporting only serial programming mode, this command enters serial
;*	programming mode.
;*
;* NOTE 2
;*	The ah and al are the high and low order bytes of the address. For
;*	parallel programmers this command issues the Load Address Low/High
;*	Byte command. For serial programmers the address byte is stored for
;*	use by the Read/Write commands.
;*
;* NOTE 3
;*	For parallel programmers this command issues the Program Flash
;*	command. For serial programmers this command iussues the Write
;*	Program Memory Command. For devices with byte-wide program memories
;*	only the low byte command should be used.
;*
;* NOTE 4
;*	The contents of the program memory at the address given by the 'A'
;*	command are written to the serial port in binary form. For byte
;*	wide memories one byte is written. For 16 bit memories two bytes
;*	are written,MSB first.
;*
;* NOTE 5
;*	This command must be executed after the programming is finished.
;*
;* NOTE 6
;*	The select device type command must be sent before the enter
;*	programming command
;*
;* NOTE 7
;*	The supported device codes are returned in binary form terminated
;*	by 0x00.
;*
;* NOTE 8
;*	This return a 7 character ASCII string identifying the programmer.
;*	For the development board it is "AVR DEV", for the parallel
;*	programmer it is "AVR PPR" and for the in-curcuit programmer it is
;*	"AVR ISP".
;*
;* NOTE 9
;*	The software/hardware version are returned as two ASCII numbers.
;*
;* NOTE 10
;*	This command should be used to identify the programmer type. The
;*	return value is 'S' for serial (or SPI) programmers or 'P' for
;*	parallel programmers.
;*
;* NOTE 11
;*	The write fuse bits command are available only on parallel
;*	programmers and only for AVR devices (device code < 0x80). The host
;*	should use the return programmer type command to determine the
;*	programmer type, do not use the  "AVR PPR" idenifier because other
;*	programmers may be available in the future.
;*
;* NOTE 12
;*	Currently only the AVR development board has LEDs. The other boards
;*	must implement this commands as NOPs.
;*
;* NOTE 13
;*  Devices using Page Mode Programming write one page of flash memory
;*  before issuing a Page Mode Write Pulse.
;*
;* NOTE 14
;*  Uses 2313 internal SRAM to buffer a number (max. 120) Bytes to be programmed.
;*  saves a lot of serial comm overhead and time for eavrdude.
;*	Command is not supported in AVRProg from Atmel (AVRProg ignores it). 
;*  Only Implemented in AVRDUDE ( http://nongnu.org/avrdude ) from Version 4.3 on.
;*  and only TOGETHER with the Patch from my Page (avr910.c.diff): 
;*  http://www.mikrocontroller-projekte.de/ (AVR910 Programmer)
;*	Other Programmers ignore this enhancement! (as known up to now)
;*  Comments, Bugs etc. about Firmware: klaus@mikrocontroller-projekte.de
;*  or thomas@fischl.de (avrdude)
;*
;*  The 'i' cammand is only used with a Terminal, for debug reasons. 
;*  Not used in any Programmer so far
;*
;* NOTE 15
;* Lock and Fuse Bits are written using the "universal command" (:) and
;* "new universal command" (.) in AVRProg and AVRDUDE.
;* AVRProg has an Exit (E) command implemented, which switches AVRProg offline
;*
;* HISTORY
;* V3.3 25.06.04 (Klaus, Thomas) added enhanced Block write commands 'M', 'n' and 'N'.
;                           See Note 14.
;                           Add 0xFF, 0x7F (2313) check for polling Mode
;* V3.2.1 18.11.03  (Klaus) Commented out some Controller Types, which are
;				            not really Supported by the hardware, but from
;				            AVRProg Software. See Comments at the end.
;* V3.2 16.11.03    (Klaus) Correctet typo in Chrystal frequency. 
;* V3.2 13.10.03    (Klaus)	7,3728 Mhz chrystal for 115.200 Baud.
;*				            Swap MOSI <-> MISO Pinnumbers.
;*				            Add dual color LED Support.
;*				            Add some new Dewices.
;* V3.0	 02.01.23 (wubble)	Ported from 1200 to 2313.
;*				            Serial IO modified to use hardware UART.
;*				            Added support for multiple new devices.
;*				            Used data polling to short write process.
;*				            Added LED support to indicate R/W process.
;* V2.2	 00.03.10 (pkastnes) Added support for multiple new devices.
;* V2.1	 98.10.26 (mlund)	New date marking.
;*				            Removed support for AT90S1200C.
;*				            Added support for AT90S4433A.
;* V2.0	 98.01.06 (mlund)	ATmega103 support.
;* V1.7	 97.11.06 (mlund)	Universial command (':') implemented.
;*				            Releases all pins when not in 
;*				            programming mode.
;* V1.6e 97.11.04 (mlund)	mega103 rev D support
;* V1.6c 97.10.30 (mlund)	Auto incrementing / SPI sync
;*				            also works for mega103.
;* V1.6	 97.09.09 (hskar)	Created Page Mode Version (mega103)
;* V1.5	 97.08.21 (mlund)	Modified / Bugfix / Major cleanup
;* ...	 ...			    (no records)
;* V?.?	 97.03.15 (OS)		Created
;* 
;*		
;* Device Support List: see table "Devices" at the end of this file.
 
;***************************************************************************

;**** includes ****

.include "2313def.inc"

;***************************************************************************
;*
;* CONSTANTES
;*
;***************************************************************************

;**** Constant declarations Data Rate ****

;******** Chrystals for maximum Baudrates
.equ	BAUD = 115200		;Data rate, bauds
;********
.equ	XTAL = 7373		;XTAL frequency, Khz (7.3728 Mhz)
.equ	N = 3			;for 7.3728 Mhz/115.200Baud
;**** definitions for different chrystals and 115.200 baud ****
;.equ	XTAL = 3686		;XTAL frequency, Khz (3.6864 Mhz)
;.equ	N = 1			;for 3.6864 Mhz/115.200Baud
;
;********* Baudrates for 8 Mhz Chrystal
;.equ	BAUD = 38400		;Data rate, bauds
;.equ	XTAL = 8000		;XTAL frequency, Khz (8.000 Mhz)
;.equ	N = 12			;for 8.00 Mhz/38.400 Baud
;*********
;.equ	BAUD = 19200		;Data rate, bauds
;.equ	XTAL = 8000		;XTAL frequency, Khz (8.000 Mhz)
;.equ	N = 25			;for 8.00 Mhz/19.200 Baud
;*********
;.equ	BAUD = 9600		;Data rate, bauds
;.equ	XTAL = 8000		;XTAL frequency, Khz (8.000 Mhz)
;.equ	N = 51			;for 8.00 Mhz/9.600 Baud

;********* Baudrates for 4 Mhz Chrystal
;.equ	BAUD = 19200		;Data rate, bauds
;.equ	XTAL = 4000		;XTAL frequency, Khz (4.000 Mhz)
;.equ	N = 12			;for 4.00 Mhz/19.200 Baud
;*********
;.equ	BAUD = 9600		;Data rate, bauds
;.equ	XTAL = 4000		;XTAL frequency, Khz (8.000 Mhz)
;.equ	N = 25			;for 4.00 Mhz/9.600 Baud

.equ RAMSTART	= 0x60	;first SRAM Adress of 2313
.equ MAXRAM = RAMEND - RAMSTART -8 + 1  ;(= Stack deep, +1 = don't forget Byte 0 )

;***************************************************************************
;*
;* PORTS
;*	Ports Definitions
;*
;* DESCRIPTION
;*	Change the following definitions if the RESET pin to the
;*	target moves and/or if the SCK/MISO/MISO/LED moves.
;*
;***************************************************************************

.equ	LEDH	= PB3		; dual color LED output, anode green  (output)
.equ	LED		= PB0		; LED output, active low, dual color LED Kathode green  (output)
.equ	MISO	= PB6		; MISO  pin of the target (input)
.equ	MOSI	= PB5		; MOSI  pin of the target (output)

.equ	RESET	= PB4		; RESET pin of the target (output)
.equ	SCK		= PB7		; SCK   pin of the target (output)
.equ	RXD		= PD0		; UART RXD line
.equ	TXD		= PD1		; UART TXD line

;***************************************************************************
;*
;* MACROS
;*	Program Macros
;*
;* DESCRIPTION
;*	Change the following macros if the RESET pin to the
;*	target moves and/or if the SCK/MISO/MISO/LED moves.
;*
;***************************************************************************

.macro	init_ports			;init ports
	ldi	temp2,0xff	
	out	PORTD,temp2
	ldi	temp2,0xff
	out	PORTB,temp2
.endm

.macro	catch_ports			;catch ports
	ldi	temp2,(1<<TXD)
	out	DDRD,temp2
	ldi	temp2,(1<<RESET) | (1<<MOSI) | (1<<SCK) | (1<<LED) | (1<<LEDH)
	out	DDRB,temp2
.endm

.macro	release_ports		;release ports
	ldi	temp2,(1<<TXD)
	out	DDRD,temp2
	ldi	temp2,(1<<RESET) | (1<<LED) | (1<<LEDH)
	out	DDRB,temp2
.endm

.macro	pas_RESET			;set RESET passive
	tst	device
	brmi	m2				; S89 device
	sbi	portb,RESET
	rjmp	m3
m2:	cbi	portb,RESET
m3:		
.endm

.macro	act_RESET			;set RESET active
	tst	device
	brmi	m4				; S89 device
	cbi	portb,RESET
	rjmp	m5
m4:	sbi	portb,RESET
m5:		
.endm

.macro	set_LED				;set LED Port -> Standart LED off, dual LED green
	sbi portb,LED
	cbi portb,LEDH			;added for dual color support
.endm

.macro	clr_LED				;clear LED Port --> Standart LED on, dual LED red
	cbi portb,LED
	sbi portb,LEDH			;added for dual color support
.endm

.macro LED_off				;for dual color LED, not in use
	cbi portb,LED
	cbi portb,LEDH
.endm

.macro	sbic_MISO			;skip if MISO cleared
	sbic	pinb,MISO
.endm

.macro	set_MOSI			;set MOSI
	sbi	portb,MOSI
.endm

.macro	clr_MOSI			;clear MOSI
	cbi	portb,MOSI
.endm

.macro	clr_SCK				;clear SCK
	cbi	portb,SCK	
.endm

.macro	pulse_SCK			;pulse SCK
	sbi	portb,SCK
	ldi	temp2,(XTAL/1500+1)		
m0:	dec	temp2
	brne	m0
	cbi	portb,SCK
	ldi	temp2,(XTAL/3000+1)
m1:	dec	temp2
	brne	m1
.endm

.macro	table				;load Z pointer
	ldi	ZL,low(@0*2)		;low
	ldi	ZH,high(@0*2)		;high
.endm

;***************************************************************************
;*
;* Global Register Variables
;*
;***************************************************************************

;r0 used with lpm instruction

.def	cmd1		= r1	; Universal commands params
.def	cmd2		= r2	; ..
.def	cmd3		= r3	; ..
.def	pol_al		= r4	; Polling address low
.def	pol_ah		= r5	; Polling address high
.def	Bcnt1		= r6	; Block Mode Counter1 (See Note 14)
.def	Bcnt2		= r7	; Block Mode Counter2 (See Note 14)
.def    B_Flag		= r8	; Flag for ws_del Routine (See Note 14)

.def	temp1		= r16	; Temporary register 1
.def	temp2		= r17	; Temporary register 2
.def	temp3		= r18	; Temporary register 3
.def	s_data		= r19	; SPI data
.def	u_data		= r20	; UART data
.def	device		= r21	; Device code
.def	param1		= r22	; Param to read signature 
.def	rd_s_data	= r23	; Read data on SPI
.def	pol_cmd		= r24	; Polling command
.def	p_data		= r25	; Polling data
;r26,r27 used as X register
.def	addrl		= r28	; (YL) Low order byte of address
.def	addrh		= r29	; (YH) High order byte of address
;r30,r31 used as Z register

;***************************************************************************
;*
;* Interrupt Vectors
;*
;***************************************************************************

.CSEG
	rjmp	INIT			; Reset Handle

;***************************************************************************
;*
;* FUNCTION
;*	u_init
;*
;* DESCRIPTION
;*	Initialize UART.
;*
;***************************************************************************

u_init:	
	ldi	temp1,N				; set baud rate
	out	UBRR,temp1
	ldi	temp1,(1<<TXEN)|(1<<RXEN) ; initialize UART for TX and RX
	out	UCR,temp1
	ret

;***************************************************************************
;*
;* FUNCTION
;*	getc
;*
;* DESCRIPTION
;*	Wait for start bit and receive a character on the UART Rx line.
;*
;***************************************************************************

getc:
	sbis	USR,RXC			; wait until a character has been received
	rjmp	getc
	in	u_data,UDR			; Read byte from the UART
	ret

;***************************************************************************
;*
;* FUNCTION
;*	putc
;*
;* DESCRIPTION
;*	Send a character on the UART Tx line.
;*
;***************************************************************************

putc:
	sbis	USR,UDRE		; test for TX register empty
	rjmp	putc			; loop until TX empty
	out	UDR,u_data			; send the byte
	ret

;***************************************************************************
;*
;* FUNCTION
;*	put_string
;*
;* DESCRIPTION
;*	Send Z - pointed null-terminated string on the UART Tx line.
;*
;***************************************************************************
	
put_string:
	lpm
	tst	r0
	breq	ps_ret			; check for end of string (0x00)
	mov	u_data,r0
	rcall	putc			; putc(char)
	adiw	ZL,1			; next char
	rjmp	put_string
ps_ret:	ret	

;***************************************************************************
;*
;* FUNCTION
;*	put_table
;*
;* DESCRIPTION
;*	Send Z - pointed table on the UART Tx line.
;*
;***************************************************************************
	
put_table:
	lpm
	tst	r0
	breq	pt_ret			; check for end of table (0x00)
	mov	u_data,r0	
	rcall	putc			; putc(Byte)
	adiw	ZL,2			; skip MSB
	rjmp	put_table
pt_ret:	ret	

;***************************************************************************
;*
;* FUNCTION
;*	bel_table
;*
;* DESCRIPTION
;*	C=0 if device belongs to table.
;*
;***************************************************************************

bel_table:
	lpm						; read table
	tst	r0					; check for end of table
	breq	c1_ret
	cp	device,r0
	breq	c0_ret			; C=0
	adiw	ZL,2			; skip MSB
	rjmp	bel_table	
c1_ret:	sec					; C=1
c0_ret:	ret		

;***************************************************************************
;*
;* FUNCTION
;*	delay
;*
;* DESCRIPTION
;*	 Make delay 1mS (x temp1).
;*
;***************************************************************************

delay:	
	ldi	temp2,40
dl2:	ldi	temp3,(XTAL/120)
dl1:	dec	temp3
	brne	dl1
	dec	temp2
	brne	dl2
	dec	temp1
	brne	delay
	ret

;***************************************************************************
;*
;* FUNCTION
;*	rdser, wrser
;*
;* DESCRIPTION
;*	 Write and read bytes on the SPI.
;*
;***************************************************************************

rdser:	
	clr	s_data
wrser:	
	ldi	temp1,8				; load bit counter
	ldi	rd_s_data,0
wrs0:
	rol	s_data
	brcc	wrs1
	set_MOSI				; MOSI = 1
	rjmp	wrs2
wrs1:
	clr_MOSI				; MOSI = 0
wrs2:
	lsl	rd_s_data
	sbic_MISO				; read MISO
	ori	rd_s_data,1
	pulse_SCK				; pulse SCK
	dec	temp1				; advance bit counter
	brne	wrs0			; loop
	mov	s_data,rd_s_data
	ret

;***************************************************************************
;*
;* FUNCTION
;*	read_send_progmem
;*
;* DESCRIPTION
;*	 Read one Byte from Program Memory and send it through UART
;*
;***************************************************************************
read_send_progmem:
	tst	device
	brmi	rsp1			; S89 device
	ldi	s_data,0x28	
	rcall	wrser			; wrser(0x28)  SPI write (byte 1)
	mov	s_data,addrh
	rjmp	rsp2
rsp1:
	mov	s_data,addrh	; s_data = (addrh << 3) | 0x01;
	rcall	shift_s_data3
	ori	s_data,0x01
rsp2:
	rcall	wrser		; wrser(addrh) SPI write (byte 2)
	mov	s_data,addrl	
	rcall	wrser			; wrser(addrl) SPI write (byte 3)
	rcall	rdser			;              SPI read  (byte 4)
	mov	u_data,s_data
	rcall	putc			; send data
	tst	device
	brmi	rsp3			; S89 device
	ldi	s_data,0x20	
	rcall	wrser			; wrser(0x20)  SPI write (byte 1)
	mov	s_data,addrh	
	rcall	wrser			; wrser(addrh) SPI write (byte 2)
	mov	s_data,addrl	
	rcall	wrser			; wrser(addrl) SPI write (byte 3)
	rcall	rdser			;              SPI read  (byte 4)
	mov	u_data,s_data
	rcall	putc			; send data
rsp3:
	adiw	addrl,1		; Auto increment address
	ret

;***************************************************************************
;*
;* FUNCTION
;*	shift_s_data3
;*
;* DESCRIPTION
;*	 Shift s_data 3 times left for S89 device.
;*
;***************************************************************************

shift_s_data3:
	lsl	s_data
	lsl	s_data
	lsl	s_data
	brcc	s3_ret
	cpi	device,0x87			; if (device != S53)
	brne	s3_ret	
	sbr	s_data, 4			; a13 +
s3_ret:	ret

;***************************************************************************
;***************************************************************************
;***************************************************************************
;*
;* INIT
;*
;* DESCRIPTION
;*	Initialization
;*
;***************************************************************************
;***************************************************************************
;***************************************************************************

INIT:
    ldi	temp1,RAMEND
    out SPL,temp1			; Locate stack
    ldi	device,0x20			; S2313 as default
    init_ports				; Initialize ports
    release_ports			; Release ports
	rcall	u_init			; Initialize UART

;show that Prog is working after Powerup	
;@@KL for dual color LED
	clr_LED					; LED red
	ldi temp1,200			; 200 ms
	rcall delay		
	ldi temp1,200			; again 200 ms
	rcall delay
	ldi s_data,200			; counter Register
	clr B_Flag				; Flag for eNhanced Block write

LEDloop:					; Pulse for yellow LED
	set_LED					; LED green
	ldi temp1,2				; 2 ms
	rcall delay
	clr_LED					; LED red
	ldi temp1,1				; 1 ms
	rcall delay
	dec s_data				; dec. counter
	brne LEDloop
	set_LED					; LED green
;@@KL end healthcheck section
	 	
;***************************************************************************
;*
;* PROGRAM
;*	waitcmd -> main
;*
;* DESCRIPTION
;*	Wait for and execute commands.
;*
;***************************************************************************

waitcmd:
	rcall	getc			; while (getc() == ESC) {};
waitcmd_compat:				; for compatibility reason of the LED on/off command (x,y) with
							; avrdude
	cpi	u_data,0x1b
	breq	waitcmd

;====== 'T' - Device Type ==================================================

	cpi	u_data,'T'			; 'T' Device type
	brne	w0
	rcall	getc
	mov	device,u_data		; get device type
	rjmp	put_ret

;====== 'S' - Return Software Identifier ===================================

w0:	
	cpi	u_data,'S'			; 'S' Return software identifier
	brne	w1
	table	ID_Str
	rcall	put_string		; put string "AVR ISP"
	rjmp	waitcmd

;====== 'V' - Return Software Version ======================================

w1:	
	cpi	u_data,'V'			;'V' Return software version
	brne	w2
	table	SW_Ver
	rcall	put_string		; put software version
	rjmp	waitcmd


;====== 'v' - Return Hardware Version ======================================

w2:	
	cpi	u_data,'v'			;'v' Return hardware version
	brne	w3
	table	HW_Ver
	rcall	put_string		; put hardware version
	rjmp	waitcmd

;====== 't' - Show Supported Devices =======================================

w3:	
	cpi	u_data,'t'			; 't' Show supported devices
	brne	w4
	table	Dev_S
	rcall	put_table		; put supported devices codes
	table	Dev_M
	rcall	put_table		; put supported devices codes
	ldi	u_data,0x00			; putc(0x00) - end of device list
	rcall	putc
	rjmp	waitcmd

;====== 'p' - Return Programmer Type =======================================

w4:	
	cpi	u_data,'p'			; 'p' Return programmer type
	brne	w5
	ldi	u_data,'S'			; putc('S') - serial programmer
	rcall	putc
	rjmp	waitcmd

;====== 'a' - Return autoincrement address support =========================

w5:	
	cpi	u_data,'a'			; 'a' Return address auto increment
	brne	w51
	ldi	u_data,'Y'			; putc('Y') - supports autoinc
	rcall	putc
	rjmp	waitcmd

;====== 'M' - Return enhanced Mode support (Note 14) ========================

w51:	
	cpi	u_data,'M'			; 'M' Return enhanced mode Support
	brne	w52
	ldi u_data,'Y'			; putc('Y') - supports enhanced Mode
	rcall putc
	rjmp	waitcmd

;====== 'i' - Return Chip ID (Note 14) ======================================
w52:
	cpi	u_data,'i'			; 'i' Return Chip ID
	brne	w6
	table	ChipID
	rcall	put_string		; put Chip ID string 
	ldi u_data,0x0a			; putc(LF)
	rcall 	putc
	rjmp	put_ret

;====== 'x' - Set LED ======================================================

w6:	
	cpi	u_data,'x'			; 'x' Set LED (LED off or green)
	brne	w61
	rcall	getc			; get parameter
	set_LED
;@@KL
	rjmp	put_ret

;====== 'y' - Clear LED ====================================================

w61:	
	cpi	u_data,'y'			; 'y' Clear LED (LED on or red)
	brne	w7
	rcall	getc			; get parameter
	clr_LED
;@@KL
	rjmp	put_ret


;===========================================================================

; We require that the device code be selected before any of the other commands

w7:
	table	Dev_S			; load pointer
	rcall	bel_table
	brcc	w71				; device belongs to table
	table	Dev_M	
	rcall	bel_table
	brcc	w71				; device belongs to table
	rjmp	put_err			; not match, goto put_err();

;====== 'P' - Enter Programming Mode =======================================

w71:	
	cpi	u_data,'P'			; 'P' Enter programming mode
	breq	w70
	rjmp	w8
w70:	
	clr_LED					; LED on
	catch_ports				; catch ports
	clr_SCK					; clear SCK
	pas_RESET				; set RESET passive
	ldi	temp1,50			; delay 50mS;
	rcall	delay
	act_RESET				; set RESET active
	ldi	temp1,50			; delay 50mS;
	rcall	delay	
	ldi	s_data,0xac	
	rcall	wrser			; wrser(0xac) SPI write (byte 1)
	ldi	s_data,0x53	
	rcall	wrser			; wrser(0x53) SPI write (byte 2)
							; SPI Synchronization (fix!)
	cpi	device,0x20			; if ( (device >= 0x20) && (device <= 0x7F) )
	brlo	s2
	tst	device
	brmi	s2	
	ldi	temp3,32			; count = 32;
s1:	rcall	rdser			; SPI read  (byte 3)
	cpi	s_data,0x53			; if (rdser == 0x53)
	breq	s3				; break
	ldi	s_data,0x00					
	rcall	wrser			; wrser(0x00) SPI write (byte 4)
	pulse_SCK				; pulse SCK
	ldi	s_data,0xac		
	rcall	wrser			; wrser(0xac) SPI write (byte 1)
	ldi	s_data,0x53		
	rcall	wrser			; wrser(0x53) SPI write (byte 2)
	dec	temp3				; count-1
	brne	s1				; loop
	rjmp	s3				; else
s2:	ldi	s_data,0x00	
	rcall	wrser			; wrser(0x00) SPI write (byte 3)
s3:	tst	device
	brmi	s4				; S89 device
	ldi	s_data,0x00	
	rcall	wrser			; wrser(0x00) SPI write (byte 4)
s4:	ldi	temp1,4				; delay 4mS;
	rcall	delay
	rjmp	put_ret

;====== 'c' - Write Program Memory, Low Byte ===============================

w8:	
	cpi	u_data,'c'			; 'c' Write program memory, low byte
	brne	w9
	rcall	getc			; get data byte
	ldi	s_data,0x40
	mov	pol_cmd,s_data		; save command for polling	
	tst	device
	brmi	w81				; S89 device
	rcall	wrser			; wrser(0x40)   SPI write (byte 1)
	mov	s_data,addrh
	rjmp	w82
w81:
	mov	s_data,addrh		; s_data = (addrh << 3) | 0x02;
	rcall	shift_s_data3
	ori	s_data,0x02
w82:
	rcall	wrser			; wrser(addrh)  SPI write (byte 2)
	mov	s_data,addrl	
	rcall	wrser			; wrser(addrl)  SPI write (byte 3)
	mov	s_data,u_data	
	rcall	wrser			; wrser(u_data) SPI write (byte 4)
	mov	p_data,u_data		; save data for polling
	mov	pol_al,addrl		; save address for polling
	mov	pol_ah,addrh
	tst	device
	brpl	w83 
	adiw	addrl,1			; Auto increment address for S89 device
w83:
	rjmp	wait_S			; write FLASH delay

;====== 'C' - Write Program Memory, High Byte ==============================

w9:	
	cpi	u_data,'C'			; 'C' Write program memory, high byte
	brne	w9A
	rcall	getc			; get data byte
	tst	device
	brmi	w91				; S89 device
	ldi	s_data,0x48	
	mov	pol_cmd,s_data		; save command for polling	
	rcall	wrser			; wrser(0x48)   SPI write (byte 1)
	mov	s_data,addrh	
	rcall	wrser			; wrser(addrh)  SPI write (byte 2)
	mov	s_data,addrl	
	rcall	wrser			; wrser(addrl)  SPI write (byte 3)
	mov	s_data,u_data		; wrser(u_data) SPI write (byte 4)
	rcall	wrser
	mov	p_data,u_data		; save data for polling
	mov	pol_al,addrl		; save address for polling
	mov	pol_ah,addrh
	adiw	addrl,1			; Auto increment address
	rjmp	wait_S			; write FLASH delay
w91:
	rjmp	put_err			; S89 device have byte wide program memory!	

;====== 'N' eNhanced Block Write Program Memory (see Note 14) ======================

w9A:	
	cpi	u_data,'N'			; 'N' eNhanced Block Write Program Memory
	breq	w9A0
	rjmp w10
w9A0:
	rcall	getc			; get count
	cpi u_data,MAXRAM+1		; check maximum count (SRAM size - Stacksize!)
	brlo w9A0a
	rjmp put_err
w9A0a:
	mov Bcnt1, u_data
	mov Bcnt2, u_data
	clr XH
	ldi XL, RAMSTART		; set X pointer to SRAM begin
w9A1:
	rcall	getc			; get data	
	st X+, u_data			; store data to SRAM
	dec Bcnt1
	brne w9A1
	clr XH
	ldi XL, RAMSTART		; set X pointer to SRAM begin

	;check if page mode supported. if not, goto "non Paged" Mode!
	table	Dev_M	
	rcall	bel_table
	brcc	w9A2			; device belongs to table
	rjmp	w9B1			; not match, goto "non Paged" Mode
w9A2:						; write low byte
	ldi	s_data,0x40
	rcall	wrser			; wrser(0x40)   SPI write (byte 1)
	mov	s_data,addrh
	rcall	wrser			; wrser(addrh)  SPI write (byte 2)
	mov	s_data,addrl	
	rcall	wrser			; wrser(addrl)  SPI write (byte 3)
	ld	s_data, X+
	rcall	wrser			; wrser(s_data) SPI write (byte 4)
	dec Bcnt2
	ldi	s_data,0x48			; write high byte
	mov	pol_cmd,s_data		; save command for polling	
	rcall	wrser			; wrser(0x48)   SPI write (byte 1)
	mov	s_data,addrh	
	rcall	wrser			; wrser(addrh)  SPI write (byte 2)
	mov	s_data,addrl	
	rcall	wrser			; wrser(addrl)  SPI write (byte 3)
	ld	s_data, X+
	mov	p_data,s_data		; save data for polling
	mov	pol_al,addrl		; save address for polling
	mov	pol_ah,addrh
	rcall	wrser			; wrser(u_data) SPI write (byte 4)
	adiw	addrl,1			; Auto increment address
	dec Bcnt2
	brne w9A2
	rjmp put_ret			; reply
w9B1:						;"Non Paged" Mode of Block write command
	ldi	s_data,0x40			; write low byte
	mov	pol_cmd,s_data		; save command for polling	
	tst	device
	brpl w9B2				; S89 device
	rjmp put_err			; Block write not supported for S89 Devices
w9B2:
	rcall	wrser			; wrser(0x40)   SPI write (byte 1)
	mov	s_data,addrh
	rcall	wrser			; wrser(addrh)  SPI write (byte 2)
	mov	s_data,addrl	
	rcall	wrser			; wrser(addrl)  SPI write (byte 3)
	ld	s_data, X+
	mov	p_data,s_data		; save data for polling
	rcall	wrser			; wrser(s_data) SPI write (byte 4)
	mov	pol_al,addrl		; save address for polling
	mov	pol_ah,addrh
	rcall Bws_pol
	dec Bcnt2
	ldi	s_data,0x48			; write high byte
	mov	pol_cmd,s_data		; save command for polling	
	rcall	wrser			; wrser(0x48)   SPI write (byte 1)
	mov	s_data,addrh	
	rcall	wrser			; wrser(addrh)  SPI write (byte 2)
	mov	s_data,addrl	
	rcall	wrser			; wrser(addrl)  SPI write (byte 3)
	ld	s_data, X+
	mov	p_data,s_data		; save data for polling
	rcall	wrser			; wrser(u_data) SPI write (byte 4)
	mov	pol_al,addrl		; save address for polling
	mov	pol_ah,addrh
	rcall Bws_pol
	adiw	addrl,1			; Auto increment address
	dec Bcnt2
	brne w9B1
	rjmp put_ret			; reply
	
;====== 'R' - Read Program Memory ==========================================

w10:	
	cpi	u_data,'R'			; 'R' Read program memory
	brne	w10A
    rcall read_send_progmem
	rjmp	waitcmd			; goto waitcmd();

;====== 'n' - eNhanced Block Read Program Memory (See Note 14) ======================

w10A:	
	cpi	u_data,'n'			; 'n' Block Read Program Memory
	brne	w11
	rcall	getc			; XH = getc();
	mov	XH,u_data
	rcall	getc			; XL = getc();
	mov	XL,u_data

w10A1:
 	rcall read_send_progmem
	sbiw XL, 1
   	brne w10A1
	rjmp waitcmd			; goto waitcmd();

;====== 'A' - Load Address =================================================

w11:	
	cpi	u_data,'A'			; 'A' Load address
	brne	w12
	rcall	getc			; addrh = getc();
	mov	addrh,u_data
	rcall	getc			; addrl = getc();
	mov	addrl,u_data
	rjmp	put_ret			; goto reply();

;====== 'D' - Write Data Memory ============================================

w12:	
	cpi	u_data,'D'			; 'D' Write data memory
	brne	w13
	rcall	getc			; get data
	tst	device
	brmi	w121			; S89 device
	ldi	s_data,0xc0
	rcall	wrser			; wrser(0xc0)   SPI write (byte 1)
	mov	s_data,addrh
	rjmp	w122	
w121:
	cpi	device,0x87			; if (device == S53)
	breq	w123
	mov	s_data,addrh
	rcall	shift_s_data3
	ori	s_data,0x06
w122:
	rcall	wrser			; wrser(addrh)  SPI write (byte 2)
	mov	s_data,addrl
	rcall	wrser			; wrser(addrl)  SPI write (byte 3)
	mov	s_data,u_data
	rcall	wrser			; wrser(u_data) SPI write (byte 4)
	ldi	temp1,10			; delay 10mS
	rcall	delay

	adiw	addrl,1			; Auto increment address
	rjmp	put_ret
w123:
	rjmp	put_err

;====== 'd' - Read Data Memory =============================================

w13:	
	cpi	u_data,'d'			; 'd' Read data memory
	brne	w14
	tst	device
	brmi	w131			; S89 device
	ldi	s_data,0xa0
	rcall	wrser			; wrser(0xa0)   SPI write (byte 1)
	mov	s_data,addrh
	rjmp	w132
w131:
	cpi	device,0x87			; if (device == S53)
	breq	w133
	mov	s_data,addrh
	rcall	shift_s_data3
	ori	s_data,0x05
w132:
	rcall	wrser			; wrser(addrh)  SPI write (byte 2)
	mov	s_data,addrl	
	rcall	wrser			; wrser(addrl)  SPI write (byte 3)
	rcall	rdser			;               SPI read  (byte 4)
	mov	u_data,s_data
	rcall	putc			; send data

	adiw	addrl,1			; Auto increment address
	rjmp	waitcmd			; goto waitcmd();
w133:
	rjmp	put_err

;====== 'L' - Leave Programming Mode =======================================

w14:	
	cpi	u_data,'L'			; 'L' Leave programming mode
	brne	w142
w141:
	release_ports			; release ports
	pas_RESET				; set RESET passive
	set_LED					; LED off
	rjmp    put_ret

;====== 'E' - Exit , release all Ports, inhibit AVRprog (AVRProg only) ======

w142:	
	cpi	u_data,'E'			; 'E' xit
	brne	w15
	rjmp w141				; exit command for AVR Prog

;====== 'e' - Chip Erase ===================================================

w15:	
	cpi	u_data,'e'     		; 'e' Chip erase
    brne	w16
	ldi	s_data,0xac
	rcall	wrser			; wrser(0xac) SPI write (byte 1)
	tst	device
	brmi	w151			; S89 device
	ldi	s_data,0x80
	rcall	wrser			; wrser(0x80) SPI write (byte 2)
w151:
	ldi	s_data,0x04
	rcall	wrser			; wrser(0x04) SPI write (byte 3)
	ldi	s_data,0x00
	rcall	wrser			; wrser(0x00) SPI write (byte 4)
	ldi	temp1,40			; delay 40mS
	rcall	delay
	rjmp	put_ret

;====== 'l' - Write Lock Bits ==============================================

w16:	
	cpi	u_data,'l'			; 'l' Write lock bits
	brne	w17
	rcall	getc			; get data
	ldi	s_data,0xac
	rcall	wrser			; wrser(0xac)   SPI write (byte 1)
	tst	device
	brmi	w161			; S89 device
	cpi	device,0x5e			; if (device == tn26)
	breq	w163	
	mov	s_data,u_data 
	andi	s_data,0x06		; (u_data & 0x06) | 0xe0
	ori	s_data,0xe0
	rcall	wrser			; wrser(u_data) SPI write (byte 2)
	ldi	s_data,0x00
	rcall	wrser			; wrser(0x00)   SPI write (byte 3)
	rjmp	w162
w163:
	ldi	s_data,0xe0			; tn26 device
	rcall	wrser			; wrser(0xe0)   SPI write (byte 2)
	ldi	s_data,0x00
	rcall	wrser			; wrser(0x00)   SPI write (byte 3)
	mov	s_data,u_data 
	ori	s_data,0xfc
	rcall	wrser			; wrser(u_data) SPI write (byte 4)
	rjmp	w164
w161:
	mov	s_data,u_data 
	andi	s_data,0xe0		; S89 device
	ori	s_data,0x07
	rcall	wrser
w162:
	ldi	s_data,0x00
	rcall	wrser			; wrser(0x00)   SPI write (byte 4)
w164:
	ldi	temp1,10			; delay 10mS
	rcall	delay
	rjmp	put_ret

;====== 's' - Read Signature Bytes =========================================

w17:	
	cpi	u_data,'s'			; 's' Read signature bytes
	brne	w18
	tst	device
	brmi	w171			; S89 device
	ldi	param1,0x02			; param1 = 0x02
	rcall	ca17
	ldi	param1,0x01			; param1 = 0x01
	rcall	ca17
	ldi	param1,0x00			; param1 = 0x00
	rcall	ca17
	rjmp	waitcmd
w171:
	rjmp	put_err
ca17:
	ldi	s_data,0x30
	rcall	wrser			; wrser(0x30)   SPI write (byte 1)
	ldi	s_data,0x00
	rcall	wrser			; wrser(0x00)   SPI write (byte 2)
	mov	s_data,param1
	rcall	wrser			; wrser(param1) SPI write (byte 3)
	rcall	rdser			;               SPI read  (byte 4)
	mov	u_data,s_data
	rcall	putc			; send data
	ret

;====== 'm' - Write Program Memory Page ====================================

w18:	
	cpi	u_data,'m'			; 'm' Write Program Memory Page
	brne	w19
	ldi	s_data,0x4c	
	rcall	wrser			; wrser(0x4c)  SPI write (byte 1)
;	mov	s_data,addrh		; original, reload address
	mov	s_data,pol_ah		; for speeding up transfer
	rcall	wrser			; wrser(addrh) SPI write (byte 2)
;	mov	s_data,addrl		; original, reload address
	mov	s_data,pol_al		; for speeding up transfer
	rcall	wrser			; wrser(addrl) SPI write (byte 3)
	ldi	s_data,0x00
	rcall	wrser			; wrser(0x00)  SPI write (byte 4)
	rjmp	wait_M			; write FLASH delay

;====== ':' - Universal Command ============================================

w19:	
	cpi	u_data,':'			; ':' Universal Command
	brne	w20
	rcall	getc			; get data1
	mov	cmd1,u_data			; cmd1 = data1
	rcall	getc			; get data2
	mov	cmd2,u_data			; cmd2 = data2
	rcall	getc			; get data3
	mov	cmd3,u_data			; cmd3 = data3
	mov	s_data,cmd1
	rcall	wrser			; wrser(cmd1)  SPI write (byte 1)
	mov	s_data,cmd2
	rcall	wrser			; wrser(cmd2)  SPI write (byte 2)
	mov	s_data,cmd3
	rcall	wrser			; wrser(cmd3)  SPI write (byte 3)
	rcall	rdser			;              SPI read  (byte 4)
	mov	u_data,s_data
	rcall	putc			; send data
	ldi	temp1,50			; delay 50mS
	rcall	delay
	rjmp	put_ret

;====== '.' - New Universal Command ========================================

w20:	
	cpi	u_data,'.'			; '.' New Universal Command
	brne	w21
	rcall	getc			; get data1
	mov	cmd1,u_data			; cmd1 = data1
	rcall	getc			; get data2
	mov	cmd2,u_data			; cmd2 = data2
	rcall	getc			; get data3
	mov	cmd3,u_data			; cmd3 = data3
	rcall	getc			; get data4
	mov	s_data,cmd1	
	rcall	wrser			; wrser(cmd1)   SPI write (byte 1)
	mov	s_data,cmd2	
	rcall	wrser			; wrser(cmd2)   SPI write (byte 2)
	mov	s_data,cmd3
	rcall	wrser			; wrser(cmd3)   SPI write (byte 3)
	mov	s_data,u_data
	rcall	wrser			; wrser(u_data) SPI write (byte 4)
	mov	u_data,rd_s_data
	rcall	putc			; send data
	ldi	temp1,50			; delay 50mS
	rcall	delay
	rjmp	put_ret
	
;====== Unknown Command ====================================================

w21:	rjmp	put_err

;====== Wait for FLASH write in byte mode ==================================

Wait_S:
	table	Dev_M	
	rcall	bel_table
	brcs	ws_pol		
	rjmp	put_ret			; device belongs to table Dev_M
							; Page mode requires no delay!
Bws_pol:					; entry adress for Block mode delay
	inc B_Flag				; set Flag that ws_poll comes back with ret ...
ws_pol:
	cpi	device,0x13			; if (device == S1200D)
	breq	ws_del			; polling not used (bug!)
	cpi device,0x20			; if (device == S2313)
	brne ws_def				; S2313 shows 0x7F during polling
	cpi p_data,0x7f			; id (data == 0x7f)
	breq ws_del				; wait default delay
ws_def:
	andi	pol_cmd,0x0f	; write command: 0x48, 0x40
	ori	pol_cmd,0x20		; read  command: 0x28, 0x20
	clr	temp3				; clear polling counter
ws_cy:
	tst	device
	brmi	ws_89			; S89 device
	mov	s_data,pol_cmd	
	rcall	wrser			; wrser(pol_cmd) SPI write (byte 1)
	mov	s_data,pol_ah
	rjmp	ws_90
ws_89:
	mov	s_data,pol_ah		; s_data = (pol_ah << 3) | 0x01;
	rcall	shift_s_data3
	ori	s_data,0x01
ws_90:
	rcall	wrser			; wrser(pol_ah) SPI write (byte 2)
	mov	s_data,pol_al	
	rcall	wrser			; wrser(pol_al) SPI write (byte 3)
	rcall	rdser			;               SPI read  (byte 4)
	tst	device
	brpl	ws_cb
	andi	s_data,0x80		; compare only MSB for S89 device
	andi	p_data,0x80
ws_cb:
	cp	s_data,p_data
	breq	ws_ok			; s_data = p_data
	dec	temp3
	brne	ws_cy			; loop
	clr B_Flag				; Reset B_Flag for normal operation 
	breq	put_err			; 256 polling cycles are over
ws_ok:
	tst	temp3				; if s_data = p_data at first cycle, 
	breq	ws_FF			; Check if 0xFF Code was sent
	rjmp ws_end
ws_FF:
	cpi p_data,0xFF
	brne ws_del				; if not 0xFF, wait standart delay
	rjmp ws_end
ws_del:
	ldi	temp1,10			; delay 10mS;
	rcall	delay
ws_end:
	tst B_Flag
	breq put_ret
	clr B_Flag				; Reset B_Flag for normal operation 
	ret
			
;====== Wait for FLASH write in page mode ==================================

Wait_M:
	cpi	device,0x41
	breq	wm_del			; polling inapplicable for m103
	cpi	device,0x42
	breq	wm_del			; polling inapplicable for m603
	andi	pol_cmd,0x0f	; write command: 0x48, 0x40
	ori	pol_cmd,0x20		; read  command: 0x28, 0x20
	clr	temp3				; clear polling counter
wm_cy:
	mov	s_data,pol_cmd	
	rcall	wrser			; wrser(pol_cmd) SPI write (byte 1)
	mov	s_data,pol_ah
	rcall	wrser			; wrser(pol_ah) SPI write (byte 2)
	mov	s_data,pol_al	
	rcall	wrser			; wrser(pol_al) SPI write (byte 3)
	rcall	rdser			;               SPI read  (byte 4)
	cp	s_data,p_data
	breq	wm_ok			; s_data = p_data
	dec	temp3
	breq	put_err			; 256 polling cycles are over
	rjmp	wm_cy			; loop
wm_ok:
	tst	temp3				; if s_data = p_data at first cycle, 
	breq	wm_del			; this is "bad" code, polling inapplicable
	rjmp	put_ret
	
wm_del:
	ldi	temp1,50			; delay 50mS
	rcall	delay
	rjmp	put_ret

;====== Command Error ======================================================

put_err:
	ldi	u_data,'?'			; putc('?')
	rcall	putc			; send '?'
	rjmp	waitcmd		

;====== Reply Command ======================================================

put_ret:
	ldi	u_data,0x0d			; putc(0x0D)
	rcall	putc			; send CR
	rjmp	waitcmd	

;***************************************************************************
;*
;* TABLE
;*	device codes
;*
;* DESCRIPTION
;*	The following device codes must be used by the host computer. Note
;*	that the device codes are arbitrary selected, they do not have any
;*	thing in common with the signature bytes stored in the device.
;* 	This are the device Codes recognized by the AVRprog Software. Some
;*	Devices may require special hardware or a different, not yet 
;*	implemented Protocol! Use at your own risk.
;*
;***************************************************************************

Dev_S:	; byte write
;new
	.dw	0x10	;AT90S1200A
	.dw	0x11	;AT90S1200B
	.dw	0x12	;AT90S1200C
	
	.dw	0x13	;AT90S1200
	.dw	0x20	;AT90S2313A
	.dw	0x28	;AT90S4414A
	.dw	0x30	;AT90S4433A
	.dw	0x34	;AT90S2333A
	.dw	0x38	;AT90S8515A
	.dw	0x48	;AT90S2323A
	.dw	0x4C	;AT90S2343A
;new
	.dw	0x50	;tn11 Needs additional High Voltage Hardware!

	.dw	0x51	;tn10
	.dw	0x55	;tn12
	.dw	0x56	;tn15
	.dw	0x58	;tn19
;new
;	.dw	0x5C	;tn28 Only supported in parallel Programming Mode!

	.dw	0x68	;AT90S8535
	.dw	0x6C	;AT90S4434
;new
;	.dw	0x70	;AT90C8534  unknown Hardware, untested!
;	.dw	0x71	;AT90C8544  unknown Hardware, untested!
;	.dw	0x80	;AT89C1051  unknown Hardware, untested!
;	.dw	0x81	;AT89C2051  unknown Hardware, untested!

;	.dw	0x86	;AT89S8252  unknown Hardware, untested!
;	.dw	0x87	;AT89S53    unknown Hardware, untested!

	.dw	0x00	;End of table
	
Dev_M:	; page write	
	.dw	0x3A	;m8515
;new
;	.dw	0x3B	;m8515boot  Bootloader Mode untested!

	.dw	0x41	;m103
	.dw	0x42	;m603 
	.dw	0x43	;m128
;new
;	.dw	0x44	;m128boot  Bootloader Mode untested!

	.dw	0x5E	;tn26
	.dw	0x60	;m161
;new
;	.dw	0x61	;m161boot  Bootloader Mode untested!

	.dw	0x64	;m163
	.dw	0x65	;m83
;new
;	.dw	0x66	;m163boot  Bootloader Mode untested!
;	.dw	0x67	;m83boot  Bootloader Mode untested!
	.dw	0x6A	;m8535
;	.dw	0x6B	;m8535boot  Bootloader Mode untested!
	.dw	0x72	;m32
;new
;	.dw	0x73	;m32boot  Bootloader Mode untested!

	.dw	0x74	;m16
;new
;	.dw	0x75	;m16boot  Bootloader Mode untested!

	.dw	0x76	;m8
;new
;	.dw	0x77	;m8boot  Bootloader Mode untested!
	.dw	0x00	;End of table

;***************************************************************************
;*
;* TABLE
;*	revision codes
;*
;***************************************************************************

SW_Ver:
	.db "33",0,0
HW_Ver:
	.db "12",0,0	

;***************************************************************************
;*
;* TABLE
;*	ID string "AVR ISP"
;*
;***************************************************************************

ID_Str:
	.db "AVR ISP",0

;***************************************************************************
;*
;* TABLE
;*	Chip ID string to identify the Firmware
;*
;***************************************************************************

ChipID:
	.db "Ver.3.3 (enhanced Mode,7.3728Mhz, 115.200 baud) for APP Note 910, AT90S2313 "
	.db "www.mikrocontroller-projekte.de 25.Jun.2004",0

;**** End of File ****

