Scenix Sasmmem.src

;MACROS --------------------------------------------------------------------------
; DecBufPtr <ptr>
; decrements buffer pointers and keeps them within one bank
; IncBufPtr <ptr>
; increments buffer pointers and keeps them within one bank
; mmov <src>,<dest>,<Count>
; Multi Move moves src to dest for count bytes.
; LookupW <12bitValue> [, <12bitValue>]
; uses IREAD (affecting M and W) to lookup values up to 12 bits indexed by W
; Subroutine
; Defines SubEntryAddr from the current address or the address of a jump from
; space in the first low half page of memory as needed to ensure global 
; CALL access to a subroutine.
; Push, Pop
; compile code to push and pop W from a stack setup in one register bank.
mmov Macro 3
 local _bank
 noexpand
 _bank = 0
 rept 3円
 IF ((2円 + %) / 10ドル) != _bank
 _bank = (2円 + %) / 10ドル
 expand
 bank (2円 + %)
 noexpand
 ENDIF
 expand
 mov w, 2円 + %
 noexpand
 IF ((1円 + %) / 10ドル) != _bank
 _bank = (1円 + %) / 10ドル
 expand
 bank (1円 + %)
 noexpand
 ENDIF
 expand
 mov 1円 + %, w
 noexpand
 ENDR
 ENDM
Push MACRO 1
	local parm
 noexpand
 parm = 1円
 expand
 DecBufPtr StackPtr	;could use incsz rather than inc to avoid modifying Z
 noexpand
 IF Parm == Wreg || parm == fsr
 IF parm != fsr
 expand
 mov fsr, w	;fsr could be anything (due to bank etc..) so use for parm
 noexpand
 parm = WReg
 ENDIF
	expand
 mov w, StackPtr ;get the StackPtr into w
 xor fsr, w	;swap w with fsr
 xor w, fsr
 xor fsr, w
 mov ind, w	;store w to Top Of Stack.
	noexpand
 ELSE
	expand
 mov fsr, StackPtr ;W used
 noexpand
 IF parm > 0ドルF
 expand
 bank parm
 mov w, parm
 bank Stack
 mov ind, w
 noexpand
 ELSE
 expand
 mov ind, parm
 noexpand
 ENDIF
 ENDIF
 ENDM
 
Pop MACRO 1
 noexpand
 expand
 mov fsr, StackPtr ;W used
 mov w, ind
 noexpand
 IF 1円 > 0ドルF
 expand
 bank 1円
 noexpand
 ENDIF
 expand
 mov 1,円w
 ;1円 is now the StackPtr
 IncBufPtr StackPtr ;point to valid data at new Top Of Stack
 noexpand
 ENDM
LookupW MACRO	;Version 2
 local _LookupWTableBegin, _LookupWTableEnd, _temp
 expand
;Defines an in-line DW/IREAD lookup table returns the 12 bit value indexed by W in M:W.
;Affects M and W.
 noexpand
 if CPUCarry == 1
 expand
 clc		;clc		to avoid adding an extra one
 noexpand
 endif
 expand
 page $+0円+3
 add w,2	;add w,2	make the index into an offset from the current location
 jmp $+0円+1
 noexpand
_LookupWTableBegin = $
 REPT 0円
 expand
 DW \%
 noexpand
 ENDR
_LookupWTableEnd = $
 expand
 mov m,#_LookupWTableBegin>>8
 noexpand
 IF (_LookupWTableBegin / 100ドル) != (_LookupWTableEnd / 100ドル)
 expand
 snc		;correct if carry due to table spanning a half page
 mov m,#_LookupWTableBegin>>8+1	
 noexpand
 ENDIF
 expand
 iread 		;Retrieve data
 noexpand
 ;{use the data}
 ENDM
;==============================
;Ruben Jönsson
;AB Liros Electronic
;Box 9124, 200 39 Malmö, Sweden
;TEL INT +46 40142078
;FAX INT +46 40947388
;ruben@pp.sbbs.se
;==============================
;
;...a macro that will pack 3 
;characters at a time, from the string, into 2 program memory locations in 
;order to save program memory. 
;
;Since a program memory location can hold 12 bits it can store 1.5 
;characters if all 12 bits are used instead of using the RETLW instruction 
;which only can store 8 bits. Of course, I have to use the IREAD instruction 
;to read the characters. (The IREAD, by the way seems to have a problem when 
;used on the SX52 (and probably the 48), but It's quite easy to make a fix 
;for it.)
;
;I store the first character and the upper nibble of the third character in 
;the first memory location and the second character and the lower nibble of 
;the third character in the second memory location. The 3 characters 'ABC' 
;would be stored as
;
;dw 441,ドル342ドル	;41,ドル42,ドル43ドル=ABC
;
;in 2 words of the 12 bit program memory.
;
;This is the (SASM) macro I use for this:
;--------------------------------------------------------------------------
;	Macro to pack 8 bit character strings into 12 bit program memory
;	words. 3 character per 2 words of program memory. 1st memory
;	location holds character 1 and upper nibble of character 3, 2nd
;	memory location holds charachter 2 and lower nibble of character
;	3, 3rd location holds character 4 and upper nibble of character
;	6 and so on...
;	If one string is split over several lines (several PackTXT macros)
;	make sure that it is split on an even length of 3 characters.
PackTXT	MACRO
 LOCAL char1, char2
 noexpand
 char1=-1 ;Temp variable for 1st character.
 char2=-1 ;Temp variable for 2nd character
 rept 0円	 ;Repeat through all arguments to this
 ;macro (all characters).
 if ((%-1)//3 == 0) ;Is it charachter 1 (4, 7...)?
 char1=\%	 ;Save it for later 
 endif
 if ((%-1)//3 == 1) ;Is it character 2 (5, 8...)?
 char2=\%	 ;Save it for later.
 endif
 if ((%-1)//3 == 2) ;If it is character 3 (6, 9...) we
 ;have a group of 3 characters to
 ;store 2 in memory words
 expand
 dw (((\% & $f0) << 4) + char1),(((\% & $f) << 8) + char2)
 noexpand
 char1=-1
 char2=-1
 endif
 endr
 if char1 != -1 ;If the number of characters are 1 or 2
 ;(4,5,7,8....) store character 1 (4,7...)
 ;in a single word
 expand
 dw char1
 noexpand
 endif
 if char2 != -1 ;If the number of characters are 2 (5,8...)
 ;store character 2 (5,8...) in a single word.
 expand
 dw char2
 noexpand
 endif	
endm
;With the Parallax assembler I can just write
;
;	PackTXT	'ABCDEFG'
;
;But the SASM assembler requires me to write
;
;	PackTXT	'A','B','C','D','E','F','G'
;Here is the code I have used for reading back my packed 
;strings. It could probably be more generalized regarding 
;register usage, but this is how it is done in my application.
;
;It uses two global registers, TMP1 and TMP3, and 2 non global 
;registers MEM_PTR_L and CHAR3. It takes an offset to the first 
;character in the string in a string table as input in W. This 
;function is optimized for a string table of up to 256 program 
;words - up to 384 characters (384 is 256 * 1.5 but this 
;requires all strings to be of a length even divisible by 3 - 
;which most likely isn't the case, making the maximum number of 
;characters somewhat less than 384). This routine also requires 
;all strings to be in the same 256 byte (half) page. I have used 
;a constant, LCD_END_STR, instead of 0 as an end marker for the 
;strings since I also need to send the character 0 (user defined 
;character and definition of this to an LCD).
;
;string_to_lcd_buff
;	bank		MEM_PTR_L
;	mov		MEM_PTR_L,w		;Offset in string table
;	clr		TMP3				;Byte read counter
;string_to_lcd_buff_loop
;	mov		m,#(rom_strings>>8);High nibble offset
;	mov		w,MEM_PTR_L		
;	iread					;Read character
;	inc		TMP3				;Inc byte read counter
;string_to_lcd_buff_001
;	mov		TMP1,w			;Save read byte.
;	xor		w,#LCD_END_STR		;Is it the end of the 
;string?
;	snz
;	retp						;Yes - exit
;	swap		CHAR3			;Make the 3rd character from 
;							;The two previously read
;	mov		w,#$f0			;Mask off the lower nibble
;	and		CHAR3,w
;	mov		w,m
;	and		w,#$f			;Add the high order nibble
;							;from this IREAD.
;	or		CHAR3,w
;	call		@putchar_lcd+1		;Sends TMP1 to LCD buff
;	sb		TMP3.1			;Is 2 bytes read?
;	jmp		not_third_char		;No - continue with next 
;char
;	clr		TMP3				;Yes - clear counter and
;	mov		w,CHAR3			;send the char in CHAR3
;	jmp		string_to_lcd_buff_001
;not_third_char
;	inc		MEM_PTR_L			;Increment pointer to next 
;							;memory location.
;	jmp		string_to_lcd_buff_loop
;
Subroutine MACRO
 noexpand
;Usage: Define a Global lable, 
; Execute Subroutine macro, 
; Assign :Entry to the value now set in SubEntryAddr. 
; Continue the definition of the subroutine. 
; Elsewhere, call @Sub:Entry where Sub is the global lable
; you defined for the subroutine.
;Example
;SUB1	Subroutine 
;:Entry = SubEntryAddr
;....
;	Call SUB1:Entry
 _SubAddr = $
 IF (_SubAddr & 100ドル) != 0 
 org LowHalfPage
 SubEntryAddr = $
;if we got here, the pagesel bits must be set for here
 IF ($ / 100ドル) == (_SubAddr / 100ドル)
 expand
 jmp _SubAddr
 noexpand
 ELSE
 expand
 jmp @_SubAddr
 noexpand
 ENDIF
 LowHalfPage = $
 IF $+1 > HighHalfPage
 ERROR 'Out of LowHalfPage Space'
 ENDIF
 org _SubAddr
 ELSE ;The subroutine was already starting in a LowHalfPage
 SubEntryAddr = $
 ENDIF
 ENDM
DecBufPtr MACRO 1
 noexpand
;decrements buffer pointers and keeps them within one bank
 IF CPUPins > 28
 expand
 dec 1円
 setb 1円.5
 noexpand
 ELSE
 expand
 dec 1円
 setb 1円.4
 noexpand
 ENDIF
 ENDM
IncBufPtr MACRO 1
 noexpand
;increments buffer pointers and keeps them within one bank
 IF CPUPins > 28
 expand
 inc 1円
 setb 1円.5
 noexpand
 ELSE
 expand
 inc 1円
 setb 1円.4
 clrb 1円.5
 noexpand
 ENDIF
 ENDM
Inc24 MACRO 1
 inc 1円+0
 snz
 inc 1円+1
 snz
 inc 1円+2
 ENDM

file: /Techref/scenix/sasmmem.src, 9KB, , updated: 2002年8月8日 22:16, local time: 2025年9月7日 21:30,
40.74.122.252:LOG IN

©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://massmind.org/techref/scenix/sasmmem.src"> scenix sasmmem</A>

Did you find what you needed?

Welcome to massmind.org!

Welcome to massmind.org!

.

AltStyle によって変換されたページ (->オリジナル) /