[comp.sys.intel] Problems with the 80C196KC windowing feature

wbeebe@bilver.UUCP (Bill Beebe) (06/02/90)

      Apologies in advance to readers of this newsgroup if this is the
      wrong place for this message.

      I am developing a controller board using the Intel 80C196KC. I
      chose the KC variant because of it's additional 256 bytes of
      internal ram immediately above the page zero register file, and
      the ability to use the wsr to window sections of the upper 256
      bytes into a section of the original register file. In attempting
      to write code that takes advantage of this feature I have run
      into the following anamolous behavior. First a little background.

      I have written a kernel, and one of its services are a set of
      routines to read and write to a Dallas Semiconductor SmartWatch,
      a 1216C. The socket supports a 32K by 8-bit Intel P51256SL-10
      SRAM from 8000H to F800H. The highest 1K is devoted to external
      I/O. The lower 32K is a 32K by 8 EPROM from 200H to 7FFFH. The
      following is a list of the SmartWatch routines.


;-----------------------------------------------------------------------
;
; SmartWatch interface routines.
;
; Unlike the previous routines for the 65C02/802, the wake subroutine
; is combined with the read and write routines so that there are no
; internal calls during reading or writing the Smartwatch. This was
; done so that if the stack is in the SRAM supported by the Smartwatch
; socket there will be no other reads or writes after the initialization
; read and subsequent write of the wake-up pattern.
;
;-----------------------------------------------------------------------

;-----------------------------------------------------------------------
;
; SmartWatch read routine. This routine reads data out of the SmartWatch
; into page zero internal ram and into the following data structure.
;
;	   bits 7-4		   bits 3-0		Range (BCD)
; swdata	        10 year		year		00-99
; swdata+1	0 0 0   10 month	month		01-12
; swdata+2	0 0     10 date		date		01-31
; swdata+3	0 0 osc rst		0 day		01-07
; swdata+4  12/24 0 10 hr/pm hr		hour		01-12 or 00-23
; swdata+5	0       10 minutes	minutes		00-59
; swdata+6	0       10 seconds	seconds		00-59
; swdata+7	0.1 seconds		0.01 sec	00-99
;
;-----------------------------------------------------------------------
	page

SWpat:	dcb	5CH,0A3H,3AH,0C5H	;SmartWatch comparison register
	dcb	5CH,0A3H,3AH,0C5H	;definition in reverse order.

SWByte	equ	r0		; assembly byte.
SWBit	equ	r0+1		; incoming bit data.
SWIndex	equ	r1		; general index.
SWInner	equ	r2		; inner loop counter.
SWOuter	equ	r2+1		; outer loop counter.

sw_read:
	pushf				; disable all interrupts.
	push	r0
	push	r1
	push	r2
	ldb	tram,smartwatch		; reset SmartWatch internal counter.
	ldbze	SWIndex,#8		; load Smartwatch pattern count.
sw_read2:
	ldb	SWByte,SWpat-1[SWIndex]	; load pattern byte.
	ldb	SWInner,#8		; load shift count.
sw_read3:
	stb	SWByte,smartwatch	; move pattern LSB into smart watch LSB.
	shrb	SWByte,#1		; roll byte down one for next bit.
	djnz	SWInner,sw_read3	; do for eight bits.
	djnz	SWIndex,sw_read2	; do for eight bytes.

	ldb	SWOuter,#8		; outer loop counter.
	ldbze	SWIndex,#swdata+7	; index data storage area.
sw_read4:
	ldb	SWInner,#8		; shift counter.
sw_read5:
	ldb	SWBit,smartwatch	; get serial data bit from SmartWatch.
	shr	SWByte,#1		; shift byte of incoming indexed data rignt.
	djnz	SWInner,sw_read5	; continue for eight bits.

	stb	SWByte,[SWIndex]	; store assembled byte
	dec	SWIndex
	djnz	SWOuter,sw_read4	; continue for all smartwatch bytes.
	stb	tram,smartwatch
	pop	r2
	pop	r1
	pop	r0
	popf
	ret
	page
;-----------------------------------------------------------------------
;
; SmartWatch write routine. This routine writes data out to the SmartWatch
; from the same data structure defined in sw_read.
;
; NOTE: According to docs, bit 7 of register 3 (swdata + 4) should be 0
;	to select 24 hour mode. Bit 5 of register 4 (swdata + 3) should
;	be 0 to turn the on-chip oscillator ON. Bit 4 should be 1 so that
;	the on-chip reset pin is ignored. This should be done so that any
;	spurious noise will not reset the chip, as that pin is not used.
;
;-----------------------------------------------------------------------

sw_wrt:
	pushf
	push	r0
	push	r1
	push	r2
	ldb	tram,smartwatch		;reset SmartWatch internal counter.
	ld	SWIndex,#8		;load Smartwatch pattern count.
sw_wrt2:
	ldb	SWByte,SWpat-1[SWIndex]	;load pattern byte.
	ldb	SWInner, #8		;load shift count.
sw_wrt3:
	stb	SWByte, smartwatch	;move pattern LSB into smart watch LSB.
	shrb	SWByte,#1		;roll byte down one for next bit.
	djnz	SWInner,sw_wrt3
	djnz	SWIndex,sw_wrt2

	%clrbit	swhour,7		;set for 24 hour mode.
	%setbit	swday,4			;ignore reset pin.
	%clrbit	swday,5			;make sure oscillator is always on.
	ldb	SWOuter,#8		; outer loop counter.
	ldbze	SWIndex,#swdata+7	; index data storage area.
sw_wrt4:
	ldb	SWByte,[SWIndex]	;get data to program into smartwatch.
	dec	SWIndex
	ldb	SWInner,#8
sw_wrt5:
	stb	SWByte,smartwatch	;store data in smartwatch.
	shrb	SWByte,#1
	djnz	SWInner,sw_wrt5
	djnz	SWOuter,sw_wrt4
	stb	tram,smartwatch
	pop	r2
	pop	r1
	pop	r0
	popf
	ret



      The basic architecture is to use memory locations E0H to FFh as
      16, 16-bit registers r0 to r15. The SmartWatch routines read to
      or write from registers r8, r9, r10, and r11. As you can see from
      the routines I use simple indirect addressing to manipulate the
      byte data in these four registers. The variable swdata is equated
      to r8, so that loading SWIndex (r1, E2h) with swdata+7 allows
      SWIndex to start with r11+1. As bytes are assembled from incoming
      serial data or sent out to the SmartWatch, the index is
      decremented to pick up the data from the simple array. The
      anomoly occurs when the wsr is non-zero, i.e. pointing to any of
      the eight windows in the internal ram array from 100H to 1FFH. If
      the wsr is loaded with 4FH (mapping internal ram addresses
      1E0H-1FFH to E0H-FFH (r0-r15)), then when sw-read is called the data
      are written NOT to the swapped-in registers, but to the
      underlying, original register context. I have tried both indirect
      and indexed addressing using one register to address other
      registers within the windows, and the the behavior is always the
      same; no matter what I do I clobber the underlying registers.

      This code works; it reads and writes to the SmartWatch correctly,
      so that is *NOT* the issue here.

      Has anyone else worked with the KC? Is there something I don't
      understand about the register file window facility on the KC
      concerning indexed addressing? I find this behaviour extremely
      annoying. If anyone's interested the part I'm using is a
      CJ87C196KC16, SAMP27 (yes, it's an engineering sample). Is my
      problem real, and if so, limited to the engineering sample I
      have?

      Thank you.