SX Microcontroller Memory Method

Table lookups

To access tables on SX, two methods can be used:

First method should be used with special care; the table cannot cross a page boundry because the PC may overflow and jump will take you anywhere but the table. It is a good idea to include a couple directives to check for 256 word block crossing in the table. For example, a table to convert a bit number in W to its mask:

bitnum2mask
	and	W, #%00000111	;limit offset in 0-7 range
	add	PC, W		;add offset to PC
;also can be coded as 
;	jmp	PC+W
table_start
	retw	1
	retw	2
	retw	4
	retw	8
	retw	16
	retw	32
	retw	64
	retw	128
IF ((($ - 1) ^ table_start) >>  8) != 0
	error: 256 word block crossed in bitnum2mask	;it won't compile if error condition exists
ENDIF

Another disadvantage of jump-tables is that the maximum range is 0-255, i.e. 256 table entries. That's because only bits 0:7 of program counter are accessible.

Finally, despite this not really being documented anywhere (as of 2000/11/06), adding, or-ing, and-ing, moving, etc... an 8 bit value to the PC (bits 0..7) also results in CLEARING the 9th bit (bit 8) of the PC. So you can only do relative or computed jumps into the first half page of each page. Just like calls.

These are all limitations of the PIC 16C5x architecture that the SX chips cop.. err... emul.. err... work kinda the same as.

Also: My macros (a work in progress for the SXKey) has an GotoW macro that automatically generates the most compact lookup code possible depending on a jump tables length and position in program memory. It depends on part of the first half page of program memory being reserved for the jump table and generates the actuall jmp PC+W call and jmps there with a long jump to that location from the main code. Due to a limitation of the macro engine in the SXKey compiler, it does not support forward references. For SASM (in the new SXKey 2.0 beta or above) see sasmcond.src 

But there is a better way!

The SX specific IREAD instruction is specifically designed for easy table access. It returns the whole 12 bit word from program memory - lower byte is returned in W and higher byte in M. The range of table entries restricted only by program memory. Same example can be rewritten using IREAD:

bitnum2mask
;load lower byte of address plus index
	mov	temp, W		;store index	
	mov	W, #table_start && $FF	;w = lower byte of table start address
	add	W, temp		;add index to w

	mov	M, #table_start >> 8	;load higher address of table
	snb	C
	mov	M, #table_start >> 8 + 1 ;correct if carry

	IREAD			;read table to M:W
	
	mov	M, #$0F		;restore MODE to default
table_start
	dw	1, 2, 4, 8, 16, 32, 64, 128

Of course, another advantage of the IREAD instruction is that the table values are 12 bit rather than 8. This fact can be used to store more data in the same program space or to implement desination page independant "jump" tables. The bit 8 = 0 problem remains, however.

Also:

See Also:

Questions: