Note this code appears to work but the printer rejects chips it can't write too. I'm sure I could work around this but I have other things to do.

AVRASM ver. 2.1.9  E:\avr\mega8inkchip\ROchip.asm Sat Sep 20 12:57:29 2008
Copyright Eddie Matejowsky.
Free for non-commercial use only.

E:\avr\mega8inkchip\ROchip.asm(2): Including file 'E:\avr\mega8inkchip\m8def.inc'
                 
                 .list
                 .CSEG		
                 
                 ; working registers for the program. 
                 //.def 	EEdata	 = r13
                 //.def 	EEPending	 = r14
                 .def 	chipId	 = r15
                 .def	temp 	 = r16
                 
                 .def	counter1 = r17	; counters for various routines.
                 .def	EEcount  = r18
                 .def	counter2 = r19
                 .def	counter0 = r20
                 .def 	count	 = r21		; Bit counter 
                 .def	serbyte  = r22
                 
                 .def	work1	 = r23
                 .def	EEindex  = r24
                 .def	SyncFlag = r25
                 
                 .MACRO	led1on	
                 	cbi	PORTC,PB2	; LED ON
                 .ENDMACRO						
                 
                 .MACRO	led1off			
                 	sbi	portc,PB2	; LED OFF
                 .ENDMACRO
                 
                 .MACRO	led2on	
                 	sbi	PORTD,PB2	; LED ON
                 .ENDMACRO						
                 
                 .MACRO	led2off			
                 	cbi	portD,PB2	; LED OFF
                 .ENDMACRO
                 
                 ;Reset  vector (must be the first code generated)
000000 c00b              rjmp   RESET         ; Reset Handler
000001 9518              reti   ; Ext Interrupt 0 Handler (not used)
000002 9518              reti   ; Ext Interrupt 1 Handler (not used)
000003 9518              reti		     ; Timer1 Capture Handler 
000004 9518              reti   ; Timer1 Compare Handler 
000005 9518              reti   ; Timer1-B compare Handler (not used)
000006 9518              reti   ; Timer1 Overflow Handler (not used)
000007 9518      		reti   ; Timer0 Overflow Handler
000008 9518      		reti	
000009 9518      		reti	
00000a 9518      		reti	
00000b 9518      		reti	
                 ;-----------------------------------------------------------------	
                 
                 ; code starts executing here on reset
                 RESET:
00000c 98a4      	cbi	dataddr,data0bit;
00000d 98a5      	cbi	dataddr,data1bit;
00000e 98ac      	cbi	dataport,data0bit;
00000f 98ad      	cbi	dataport,data1bit;
                 
000010 e50f          ldi temp,LOW(RAMEND)    ; set the stack pointer
000011 bf0d          out SPL, temp
000012 e004          ldi temp,HIGH(RAMEND)    
000013 bf0e          out SPH, temp
000014 9aa2      	sbi	DDRC,PB2	; Enable led driver.
000015 9a8a      	sbi	DDRD,PB2	; Enable led driver.
                 
000016 9aaa      	led1off
000017 9892      	led2off
                 ; Work out chip ID from EEPROM data.
000018 e38f      	ldi EEindex,$3f			// the ID bits are in eeprom cell x3f
000019 d07d      	rcall readee			// read the eeprom.
00001a 9506      	lsr temp				// move the ID bit into the bottom 3 bits.
00001b 9506      	lsr temp
00001c 9506      	lsr temp
00001d 9506      	lsr temp
00001e 7007      	andi temp,7				// this shouldn't be needed.
00001f 2ef0      	mov chipId,temp			// mov the ID into another register where it stays forever.
                 
                 wait4sync:
000020 d06e      	rcall   waitsyncPL		// if sync is low wait.
                 // 	led1on
000021 d03d      	rcall getnib			// get the three ID bits and the R/W bit.
000022 2399      	tst	SyncFlag			// see if sync went low before nib was recieved.
000023 f421      	brne waitchip2			// sync was low back to start
000024 2d7f      	mov work1,chipId		// get chip ID from low register to working register.
000025 1707      	cp temp,work1			// compare - will be equal if ID matches and R/W = read mode.
                 
000026 f409      	brne waitchip2			// if not equal we jump to test for write mode.
000027 d002      dosend:	rcall senddata		// The ID etc match so we call the rountine to dump the EEPROM data to the printer.
                 	
                 waitchip2:
000028 d06a      	rcall waitsyncNL		// wait for sync to go low (if it isn't already) before looping back.
000029 cff6      	rjmp wait4sync
                 ;--------------------------------------------------------------------------------------------------------
                 
                 senddata:					// Send EEPROM data to the printer.
00002a 9a92      	led2on
00002b e280       	ldi EEindex,$20			// This is where the data lives in the EEPROM.
00002c e220      	ldi EEcount,$20			// This is the maximum number of bytes to fetch and send.
                 //	rcall waitclkhilo
00002d d03e      	rcall waitclkNL			// we wait a 1/2 bit cycle 
00002e 9aa4      	sbi	dataddr,data0bit;	// make the data pin an output.
                 EEDumpLoop:
00002f d067      	rcall readee			// read a byte
000030 d051      	rcall SendByte			// send a byte
000031 2399      	tst	SyncFlag			// see if sync became low
000032 f419      	brne dumpret			// if so exit.
000033 9583      	inc EEindex				// inc address
000034 952a      	dec EEcount				// dec counter
000035 f7c9      	brne EEDumpLoop			// repeat if non-zero
                 dumpret:
000036 98a4      	cbi	dataddr,data0bit;	// make the data pin and input again.
000037 98ac      	cbi	dataport,data0bit;	// zero the databit so there is no pullup
000038 9892      	led2off
000039 9508      	ret
                 ;--------------------------------------------------------------------------------------------------------
                 
                 waitstrt:	; look for positive edge of "start" line - not the clock.
00003a b300      	in		temp,syncpin	// read the io port 		
00003b 7400      	andi	temp,1<<syncbit	// extract the wanted sync bit
00003c f7e9      	brne	waitstrt		// if pin was high repeat loop
                 waitclkhi:
00003d b300       	in		temp,syncpin	// read the io port 
00003e 7400      	andi	temp,1<<syncbit // extract the wanted sync bit
00003f f3e9      	breq	waitclkhi		// if pin was low repeat loop fall through if high
000040 9508      	ret
                 ;--------------------------------------------------------------------------------------------------------
                 ; note sync and clock are on different ports. Code for pins on same port could be shorter.
                 ; clock and data are on the same port so data can be returned in temp.
                 waitclkPE: // wait for rising clk edge
000041 2799      	clr	SyncFlag 
                 wtclklo:
000042 b300       	in		temp,syncpin		// read the io port 
000043 7400      	andi	temp,1<<syncbit 	// extract the wanted sync bit
000044 f059      	breq	noclk				// if low exit and flag it 
000045 b303      	in		temp,clockpin		// read the io port 
000046 7002      	andi 	temp,1<<clockbit	// extract the wanted clock bit
000047 f7d1      	brne	wtclklo				// repeat if clock high
                 wtclkhi:
000048 b300       	in		temp,syncpin		// read the io port 
000049 7400      	andi	temp,1<<syncbit		// extract the wanted sync bit
00004a f029      	breq	noclk				// if low exit and flag it 
00004b b373      	in		work1,clockpin		// read the io port 
00004c 2f07      	mov		temp,work1			// move to work to preserve data bit in temp
00004d 7072      	andi 	work1,1<<clockbit	// extract the wanted clock bit
00004e f3c9      	breq	wtclkhi				// repeat if clock low
00004f 9508      	ret
                 
                 noclk:							// if we are here sync was low.
000050 ef9f      	ser	SyncFlag				// flag sync as invalid
000051 9508      	ret
                 ;--------------------------------------------------------------------------------------------------------
                 
                 getbyte: ; get byte from serial stream return type in temp or ff in temp if timeout etc
000052 2766      	clr serbyte					// clear sync flag register
000053 e038      	ldi	counter2,8				// set counter for 8
                 byteloop:
000054 dfec      	rcall waitclkPE			// wait for clk high edge, data bit in temp and sync flag returned
000055 2399      	tst	  SyncFlag				// test for sync low.
000056 f439      	brne  abortGB				// if low return.
000057 9566      	lsr		serbyte				// shift the shifter
                 //	andi	temp,1<<data0bit|1<<data1bit
000058 7100      	andi	temp,1<<data0bit	// extract the data bit 
000059 f009      	breq	cntloop2			// if zero skip to loop counting
00005a 6860      	ori		serbyte,$80			// if databit is one - make msb bit a one
                 cntloop2:
00005b 953a      	dec	counter2				// dec counter 
00005c f7b9      	brne byteloop				// loop repeat if not zero.
00005d 2f06      	mov	temp,serbyte			// byte received move to temp.
00005e 9508      abortGB:	ret	
                 ;--------------------------------------------------------------------------------------------------------
                 
                 getnib: ; get nibble from serial stream, return nibble in temp, ret if timeout etc
00005f 2766      	clr serbyte					// clear sync flag register
000060 e034      	ldi	counter2,4				// set counter for 4
                 nibloop:
000061 dfdf      	rcall waitclkPE			// wait for clk high edge, data bit in temp and sync flag returned
000062 2399      	tst	  SyncFlag				// test for sync low.
000063 f439      	brne  nonib					// if low return.
000064 9566      	lsr		serbyte				// shift the shifter
                 //	andi	temp,1<<data0bit|1<<data1bit
000065 7100      	andi	temp,1<<data0bit	// extract the data bit 
000066 f009      	breq	cntloop			    // if zero skip to loop counting		
000067 6068      	ori		serbyte,8			// make high bit a one
                 cntloop:
000068 953a      	dec	counter2				// dec counter 
000069 f7b9      	brne nibloop				// loop repeat if not zero.	
00006a 2f06      	mov	temp,serbyte			// byte received move to temp.
                 //	ret	
                 nonib:
                 // ldi temp,$f0
00006b 9508      	ret
                 ;--------------------------------------------------------------------------------------------------------
                 
                 waitclkNL:	// wait for clock line to go low. If sync goes low flag it and exit.
00006c 2799      	clr SyncFlag				// clear sync flag
                 wtclkhi3:
00006d b300       	in		temp,syncpin		// read the io port 
00006e 7400      	andi	temp,1<<syncbit		// extract the wanted sync bit
00006f f301      	breq	noclk				// if low exit and flag it
000070 b303      	in		temp,clockpin		// read the io port 
000071 7002      	andi 	temp,1<<clockbit	// extract the wanted clock bit
000072 f7d1      	brne	wtclkhi3			// if bit is high repeat loop
000073 9508      	ret
                 ;--------------------------------------------------------------------------------------------------------
                 
                 waitclkNE:	// wait for clock line to be high then low. If sync goes low flag it and exit.
000074 2799      	clr SyncFlag				// clear sync flag
                 wtclkhi2:
000075 b300       	in		temp,syncpin		// read the io port 
000076 7400      	andi	temp,1<<syncbit		// extract the wanted sync bit
000077 f2c1      	breq	noclk				// if low exit and flag it
000078 b373      	in		work1,clockpin		// read the io port	
000079 7072      	andi 	work1,1<<clockbit	// extract the wanted clock bit
00007a f3d1      	breq	wtclkhi2			// if bit is low repeat loop
                 wtclklo2:
00007b b300       	in		temp,syncpin		// read the io port 
00007c 7400      	andi	temp,1<<syncbit		// extract the wanted sync bit
00007d f291      	breq	noclk				// if sync low exit and flag it
00007e b303      	in		temp,clockpin		// read the io port 
00007f 7002      	andi 	temp,1<<clockbit	// extract the wanted clock bit
000080 f7d1      	brne	wtclklo2			// if bit is high repeat loop
000081 9508      	ret
                 ;--------------------------------------------------------------------------------------------------------
                 
                 SendByte: ; send byte in temp to printer/chip reader - this rouintine does not set the pin direction.
000082 e038      	ldi counter2,8				// set up to count 8 bits
000083 2f60      	mov serbyte,temp			// mov char into shifter
                 OutLoop:
000084 9566      	lsr serbyte					// shift byte = low > carry
000085 f410      	brcc OutLow					// if carry clear jump to "output a low"
000086 9aac      	sbi dataport,data0bit		// we are sending a one so set output pin high.	
000087 c001      	rjmp DecOutCount			// go to loop counting code.
                 OutLow:
000088 98ac      	cbi dataport,data0bit		// output a low - set pin low.
                 DecOutCount:	
000089 dfea      	rcall waitclkNE				// wait for a clock edge or sync low.
00008a 2399      	tst SyncFlag				// was sync low.
00008b f411      	brne abort					// yes it was low leave loop and return.
00008c 953a      	dec counter2				// dec counter
00008d f7b1      	brne OutLoop				// if non-zero repeat loop
00008e 9508      abort:	ret						// either the byte was sent or sync went low - return.
                 
                 ;--------------------------------------------------------------------------------------------------------
                 
                 waitsyncPL:	; look for positive LEVEL of "sync" line - not the clock.
00008f b300       	in		temp,syncpin
000090 7400      	andi	temp,1<<syncbit
000091 f3e9      	breq	waitsyncPL	// wait for sync high level
000092 9508      	ret
                 ;--------------------------------------------------------------------------------------------------------
                 
                 waitsyncNL:	; look for negative LEVEL of "sync" line - not the clock.
000093 b300       	in		temp,syncpin
000094 7400      	andi	temp,1<<syncbit
000095 f7e9      	brne	waitsyncNL	// wait for sync high level
000096 9508      	ret
                 ;--------------------------------------------------------------------------------------------------------
                 ; look in  atmel data sheet for epprom programming info.
                 readee:
000097 2700      	clr temp
000098 bb0f      	out eearh,temp
000099 bb8e      	out	eearl,EEindex
00009a e001      	ldi temp,1<<eere
00009b bb0c      	out eecr,temp
00009c b30d      	in	temp,eedr
00009d 9508      	ret


RESOURCE USE INFORMATION
------------------------

Notice:
The register and instruction counts are symbol table hit counts,
and hence implicitly used resources are not counted, eg, the
'lpm' instruction without operands implicitly uses r0 and z,
none of which are counted.

x,y,z are separate entities in the symbol table and are
counted separately from r26..r31 here.

.dseg memory usage only counts static data declared with .byte

ATmega8 register use summary:
r0 :   0 r1 :   0 r2 :   0 r3 :   0 r4 :   0 r5 :   0 r6 :   0 r7 :   0 
r8 :   0 r9 :   0 r10:   0 r11:   0 r12:   0 r13:   0 r14:   0 r15:   2 
r16:  46 r17:   0 r18:   2 r19:   6 r20:   0 r21:   0 r22:  10 r23:   7 
r24:   4 r25:   9 r26:   0 r27:   0 r28:   0 r29:   0 r30:   0 r31:   0 
x  :   0 y  :   0 z  :   0 
Registers used: 8 out of 35 (22.9%)

ATmega8 instruction use summary:
adc   :   0 add   :   0 adiw  :   0 and   :   0 andi  :  17 asr   :   0 
bclr  :   0 bld   :   0 brbc  :   0 brbs  :   0 brcc  :   1 brcs  :   0 
break :   0 breq  :  11 brge  :   0 brhc  :   0 brhs  :   0 brid  :   0 
brie  :   0 brlo  :   0 brlt  :   0 brmi  :   0 brne  :  15 brpl  :   0 
brsh  :   0 brtc  :   0 brts  :   0 brvc  :   0 brvs  :   0 bset  :   0 
bst   :   0 call  :   0 cbi   :   9 cbr   :   0 clc   :   0 clh   :   0 
cli   :   0 cln   :   0 clr   :   6 cls   :   0 clt   :   0 clv   :   0 
clz   :   0 com   :   0 cp    :   1 cpc   :   0 cpi   :   0 cpse  :   0 
dec   :   4 eicall:   0 eijmp :   0 elpm  :   0 eor   :   0 fmul  :   0 
fmuls :   0 fmulsu:   0 icall :   0 ijmp  :   0 in    :  15 inc   :   1 
jmp   :   0 ld    :   0 ldd   :   0 ldi   :   9 lds   :   0 lpm   :   0 
lsl   :   0 lsr   :   7 mov   :   6 movw  :   0 mul   :   0 muls  :   0 
mulsu :   0 neg   :   0 nop   :   0 or    :   0 ori   :   2 out   :   5 
pop   :   0 push  :   0 rcall :  11 ret   :  12 reti  :  11 rjmp  :   3 
rol   :   0 ror   :   0 sbc   :   0 sbci  :   0 sbi   :   6 sbic  :   0 
sbis  :   0 sbiw  :   0 sbr   :   0 sbrc  :   0 sbrs  :   0 sec   :   0 
seh   :   0 sei   :   0 sen   :   0 ser   :   1 ses   :   0 set   :   0 
sev   :   0 sez   :   0 sleep :   0 spm   :   0 st    :   0 std   :   0 
sts   :   0 sub   :   0 subi  :   0 swap  :   0 tst   :   5 wdr   :   0 

Instructions used: 22 out of 114 (19.3%)

ATmega8 memory use summary [bytes]:
Segment   Begin    End      Code   Data   Used    Size   Use%
---------------------------------------------------------------
[.cseg] 0x000000 0x00013c    316      0    316 9999999   0.0%
[.dseg] 0x000060 0x000060      0      0      0 9999999   0.0%
[.eseg] 0x000000 0x000000      0      0      0 9999999   0.0%

Assembly complete, 0 errors, 0 warnings

eddie