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.