flat assembler
Message board for the users of flat assembler.
Index
> Non-x86 architectures > [x51] Some usefull macros for 8051 |
Author |
|
Tomasz Grysztar 30 Jun 2018, 13:16
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 Code: DATA MYBYTE DB ? END DATA 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. |
|||
30 Jun 2018, 13:16 |
|
Tomasz Grysztar 30 Jun 2018, 13:21
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 Code: FLAGS MYFLAG MYOTHERFLAG END FLAGS |
|||
30 Jun 2018, 13:21 |
|
shoorick 30 Jun 2018, 17:19
Thanks!
I like this kind of data definition: Code: DATA MYBYTE DB ? END DATA ++++++++++++++++++++++++++++++++++++++++++++++++ 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 ) ++++++++++++++++++++++++++++++++++++++++++++++++ What about flags - I would prefer separate flag declaration like I did, but maybe somebody else may like your variant. _________________ UNICODE forever! |
|||
30 Jun 2018, 17:19 |
|
shoorick 06 Jul 2018, 20:00
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).
_________________ UNICODE forever! |
||||||||||
06 Jul 2018, 20:00 |
|
shoorick 08 Apr 2019, 05:03
Simple SMBus communication
Code: ;----------------------------------------------------------------------- ; Clock stretching by slave is not implemented! ; Delay set to provide ~50kHz smbus clock at 24MHz main clock. ; If the main clock is less, smb_delay must be decreased to not ; go below 10kHz smbus clock! ;----------------------------------------------------------------------- DATA SMB_ADDR ; SMBUS DEVICE ADDR shifted 1 bit left ;----------------------------------------------------------------------- SDA equ P3.3 SCL equ P3.2 ;----------------------------------------------------------------------- smb_read_byte: ; A - REG push IE clr EA push ACC call smb_start mov A,SMB_ADDR ; W call smb_put call smb_get_ack pop ACC call smb_put call smb_get_ack call smb_start mov A,SMB_ADDR inc A ; R call smb_put call smb_get_ack call smb_get call smb_get_ack ; =master nack call smb_stop pop IE ret ;----------------------------------------------------------------------- smb_write_byte: ; A - REG, B - DATA push IE clr EA push ACC call smb_start mov A,SMB_ADDR ; W call smb_put call smb_get_ack pop ACC call smb_put call smb_get_ack xch A,B call smb_put call smb_get_ack call smb_get call smb_get_ack call smb_stop pop IE ret ;----------------------------------------------------------------------- smb_start: setb SCL call smb_delay setb SDA call smb_delay clr SDA call smb_delay clr SCL call smb_delay ret ;----------------------------------------------------------------------- smb_stop: clr SDA setb SCL call smb_delay clr SCL call smb_delay setb SCL setb SDA call smb_delay ret ;----------------------------------------------------------------------- smb_get_ack: setb SDA setb SCL call smb_delay mov C,SDA clr SCL call smb_delay ret ;----------------------------------------------------------------------- smb_get: push B mov B,#8 .loop: setb SCL mov C,SDA addc A,ACC call smb_delay clr SCL call smb_delay djnz B,.loop pop B ret ;----------------------------------------------------------------------- smb_put: push B mov B,#8 .loop: add A,ACC mov SDA,C setb SCL call smb_delay clr SCL call smb_delay djnz B,.loop pop B ret ;----------------------------------------------------------------------- smb_delay: call .u5 .u5: nop ; 5 us @ 24MHz nop ; nop ; 4 us nop ; nop ; 3 us nop ; ret ; 2 us (1 us + 1 us call) ;----------------------------------------------------------------------- To make it perfect there should be checking bus for deadlock or no acknolegement by slave, but this code can be easely extended. If clock is 12MHz, smb_delay can be like this: Code: smb_delay:
nop
nop
nop
nop
nop
nop
ret Tested with used MAX6657 Reading MAX6657 manufacturer ID: Code: MAX6657_ADDR := 10011000b ; shifted left 1 bit mov SMB_ADDR,#MAX6657_ADDR ; can be set once mov A,#0xFE call smb_read_byte Setting overtemp level at 60°C: Code: mov A,#0x20 mov B,#60 call smb_write_byte _________________ UNICODE forever! |
|||
08 Apr 2019, 05:03 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.