;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/12/7 22:46,
18.97.14.80:LOG IN
|
©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? <A HREF="http://www.piclist.com/techref/scenix/sasmmem.src"> scenix sasmmem</A> |
Did you find what you needed? |
PICList 2024 contributors:
o List host: MIT, Site host massmind.org, Top posters @none found - Page Editors: James Newton, David Cary, and YOU! * Roman Black of Black Robotics donates from sales of Linistep stepper controller kits. * Ashley Roll of Digital Nemesis donates from sales of RCL-1 RS232 to TTL converters. * Monthly Subscribers: Gregg Rew. on-going support is MOST appreciated! * Contributors: Richard Seriani, Sr. |
Welcome to www.piclist.com! |
.