please dont rip this site

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 > $0F
   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 > $0F
  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 21:16, local time: 2024/11/8 13:45,
TOP NEW HELP FIND: 
18.216.111.153:LOG IN
©2024 PLEASE DON'T RIP! THIS SITE CLOSES OCT 28, 2024 SO LONG AND THANKS FOR ALL THE FISH!

 ©2024 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!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .