;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 22:16, local time: 2025/5/4 10:43,
|
| ©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? <A HREF="http://www.linistepper.com/Techref/scenix/sasmmem.src"> scenix sasmmem</A> |
Did you find what you needed?
|