flat assembler
Message board for the users of flat assembler.

flat assembler > Non-x86 architectures > [x51] Some usefull macros for 8051

Author
Thread Post new topic Reply to topic
shoorick



Joined: 25 Feb 2005
Posts: 1606
Location: Ukraine
Code:
;-----------------------------------------------------------------------
include "8051.inc"
;-----------------------------------------------------------------------
macro ORGX? addr,filler=0 ; org with padding (aka align)
  if ~ (addr = $) 
    db (addr - $) dup (filler)
  end if
end macro  
;-----------------------------------------------------------------------
macro SELECT_BANK? n ; select working register bank
   if n>3
     err "Wrong bank number!"
   end if
   if n and 1
     setb RS0
   else
     clr  RS0
   end if
   if n and 2
     setb RS1
   else
     clr  RS1
   end if
end macro
;-----------------------------------------------------------------------
LAST_FLAG_ADDR=1Fh
;-----------------------------------------------------------------------
macro FLAG? new_flag        ; define a flag in the bit-addressable area
    if ~ defined LAST_FLAG
      restore LAST_FLAG
      LAST_FLAG=0
    else
      LAST_FLAG=LAST_FLAG+1
    end if
    if LAST_FLAG > 7Fh
      err "Too many flags!"
    end if
    
    new_flag := LAST_FLAG
    
    LAST_FLAG_ADDR=LAST_FLAG shr 3 + 20h
    
end macro
;-----------------------------------------------------------------------
macro DATA? new_data,bytes=1 ; define byte(s) from the top
    if ~ defined MEM_TOP     ; of the scratchpad 
      restore MEM_TOP        ; by default is not including
      MEM_TOP=80h            ; range above 7Fh (i8052)
    end if
    if ~ defined MEM_BOTTOM
      restore MEM_BOTTOM
      MEM_BOTTOM=30h ; 20h..2Fh - bitfield area (flags)
    end if
    MEM_TOP=MEM_TOP-bytes
    if MEM_TOP<MEM_BOTTOM
      err "DATA declaration address is below MEM_BOTTOM"
    end if
    
    new_data := MEM_TOP
    
end macro
;-----------------------------------------------------------------------
    STACK=2Fh
    STACK_SIZE=16
;-----------------------------------------------------------------------
    DATA_BOTTOM=STACK+STACK_SIZE+1  
;-----------------------------------------------------------------------
    

These macros make simple framework to manage internal RAM of x51 MCU.

Simply, you may do that:
- allocate byte in scratchpad:
DATA MYBYTE
mov MYBYTE,#15

- allocate some bytes:
DATA MYBYTES,4
mov R0,#MYBYTES

- define a bit flag:
FLAG BLINK
jnb BLINK,.m1


The idea is in defining RAM areas: The stack is placed above flags area (bit-addressable locations), free memory is limited with ram top (7Fh) and ram bottom (top of the stack).
Implicit allocation gives some insurance of not overlapping of data with checking for crossing boundaries, if there is an insufficiency of resources the warning will be flagged - then some rearrangement can be performed.

Also there is a macro for easy selection of the bank of registers:
SELECT_BANK 1
keep in mind that this selection does not preserve previous bank settings, so, PUSH PSW/POP PSW in procedure must be present to restore bank on return.

also, there is an orgx - a variant of org with aligning, usefull for binary output

_________________
UNICODE forever!


Last edited by shoorick on 02 Jul 2018, 10:15; edited 1 time in total
Post 27 Jun 2018, 10:03
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6981
Location: Kraków, Poland
These are some interesting subjects for a macro design. Just as an exercise I made a different variant of the DATA macro that allows to defined data in virtual blocks and preserves the order of defined variables in memory, while still allocating them off the top of the 30h-80h area. The new feature of VIRTUAL block continuation (implemented both in fasmg and fasm 1) is perfect for this:
Code:
MEM_BOTTOM := 30h
MEM_TOP := 80h

assert MEM_TOP-MEM_BOTTOM >= SCRATCHPAD_SIZE

virtual at 80h-SCRATCHPAD_SIZE
  ScratchPad::
end virtual

postpone
  virtual ScratchPad
    SCRATCHPAD_SIZE := $-$$
  end virtual
end postpone

macro DATA?
  virtual ScratchPad
end macro

macro END?.DATA?
  end virtual
end macro    
The syntax for this variant looks like this:
Code:
DATA
  MYBYTE DB ?
END DATA    
But you could also make a variant that would accept either syntax:
Code:
macro DATA? name,size:1
  virtual ScratchPad
  match any, name
    name rb size
    end virtual
  end match
end macro

macro END?.DATA?
  end virtual
end macro    


Well, you could also use "VIRTUAL ScratchPad" + "END VIRTUAL" directly, I think it could also look good.
Post 30 Jun 2018, 13:16
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6981
Location: Kraków, Poland
Also, for your FLAG macro I could suggest a small syntax wrapper:
Code:
macro FLAGS?
  macro ?! line&
    match =END? =FLAGS?, line
      purge ?
    else
      FLAG line
    end match
  end macro
end macro    
And then the flag definition could alternatively look like this:
Code:
FLAGS
  MYFLAG
  MYOTHERFLAG
END FLAGS    
What do you think of it?
Post 30 Jun 2018, 13:21
View user's profile Send private message Visit poster's website Reply with quote
shoorick



Joined: 25 Feb 2005
Posts: 1606
Location: Ukraine
Thanks!

I like this kind of data definition:
Code:
DATA
  MYBYTE DB ?
END DATA    
, it can be used alternatively (both variants can not be used simultaneusly I think).

++++++++++++++++++++++++++++++++++++++++++++++++
With your DATA definition there will be no necessity in such tricks like I made to adapt one known library to use with fasmg:
Code:
DATA Math_32_Data,Math_32_Data.size
virtual at Math_32_Data
Load_16_byte:   dw 0
Load_32_byte:   dd 0
Mul_16_byte:    dw 0
Div_16_byte:    dw 0
Add_16_byte:    dw 0
Sub_16_byte:    dw 0
Add_32_byte:    dd 0
Sub_32_byte:    dd 0
OP_0:           db 0
OP_1:           db 0
OP_2:           db 0
OP_3:           db 0
TMP_0:          db 0
TMP_1:          db 0
TMP_2:          db 0
TMP_3:          db 0
Math_32_Data.size=$-$$
end virtual    


I think I'll modify all my projects to use new DATA variant (thanks to gods there are only few of them yet Rolling Eyes )
++++++++++++++++++++++++++++++++++++++++++++++++

What about flags - I would prefer separate flag declaration like I did, but maybe somebody else may like your variant.

_________________
UNICODE forever!
Post 30 Jun 2018, 17:19
View user's profile Send private message Visit poster's website Reply with quote
shoorick



Joined: 25 Feb 2005
Posts: 1606
Location: Ukraine
well, I made this new version of data management:
Code:
;-----------------------------------------------------------------------
include "8051.inc"
;-----------------------------------------------------------------------
macro ORGX? addr,filler=0 ; org with padding (aka align)
  if ~ (addr = $) 
    db (addr - $) dup (filler)
  end if
end macro  
;-----------------------------------------------------------------------
macro SELECT_BANK? n ; select working register bank
   if n>3
     err "Wrong bank number!"
   end if
   if n and 1
     setb RS0
   else
     clr  RS0
   end if
   if n and 2
     setb RS1
   else
     clr  RS1
   end if
end macro
;-----------------------------------------------------------------------
LAST_FLAG_ADDR=1Fh
;-----------------------------------------------------------------------
macro FLAG? new_flag        ; define a flag in the bit-addressable area
    if ~ defined LAST_FLAG
      restore LAST_FLAG
      LAST_FLAG=0
    else
      LAST_FLAG=LAST_FLAG+1
    end if
    if LAST_FLAG > 7Fh
      err "Too many flags!"
    end if
    
    new_flag := LAST_FLAG
    
    LAST_FLAG_ADDR=LAST_FLAG shr 3 + 20h
    
end macro
;-----------------------------------------------------------------------
STACK_SIZE=16

if ~ defined MEM_TOP     ; of the scratchpad 
  restore MEM_TOP        ; by default is not including
  MEM_TOP=80h            ; range above 7Fh (i8052)
end if                   ; can be overrided in the start of main prog

assert MEM_TOP-DATA_BOTTOM >= SCRATCHPAD_SIZE

virtual at MEM_TOP-SCRATCHPAD_SIZE
  ScratchPad::
end virtual

postpone
  STACK=LAST_FLAG_ADDR
  DATA_BOTTOM=STACK+STACK_SIZE+1  
  virtual ScratchPad
    SCRATCHPAD_SIZE := $-$$
  end virtual
end postpone

macro DATA?
  virtual ScratchPad
end macro

macro END?.DATA?
  end virtual
end macro
;-----------------------------------------------------------------------    

The main difference in logic is calculating of DATA_BOTTOM: DATA_BOTTOM is similar to STACK with STACK_SIZE offset, but STACK now is LAST_FLAG_ADDR, so, bit-addresable bytes unused for flags are now wasted, stack is shifted in their area and area for data is increasing.
It looks as it works, but there is a problem appeared: it does not work with listing macro :S Thus, I've got some proofs through monitor program (see picture).


Description:
Filesize: 12 KB
Viewed: 503 Time(s)

2018-07-06-225759_1280x1024_scrot.png



_________________
UNICODE forever!
Post 06 Jul 2018, 20:00
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2018, Tomasz Grysztar.

Powered by rwasa.