Shop OBEX P1 Docs P2 Docs Learn Events
Testing rdbyte/word/long and wrbyte/word/long - Page 2 — Parallax Forums

Testing rdbyte/word/long and wrbyte/word/long

2

Comments

  • evanhevanh Posts: 15,915
    78rpm wrote: »
    If data addresses below $400 are in Hub RAM, how does Hub Exec work?
    Data accesses to HubRAM are explicit load and store instructions. They aren't used for CogRAM accesses.
    My understanding is:
    long aligned x 512, long access only, +1 adddresses next long
    $000 <= Cog RAM <= $1ff
    $200 <= LUT RAM <= $3ff

    This a Program-Counter only concern, ie: Affects instruction fetching. The general data manipulation instructions are all CogRAM only.
  • evanhevanh Posts: 15,915
    edited 2015-10-25 06:21
    You had "loc ptrb, #message", which gets the code address of message into ptrb. You wanted "mov ptrb, ##message", which puts the data address of message into ptrb. Code and data addresses are the same for addresses greater than or equal to $400, which is why it worked with "orgh $400".

    Hmm, me needs to do some reading too ... some PNUT specific detail there I'd guess.
  • evanh wrote: »
    78rpm wrote: »
    If data addresses below $400 are in Hub RAM, how does Hub Exec work?
    Data accesses to HubRAM are explicit load and store instructions. They aren't used for CogRAM accesses.
    My understanding is:
    long aligned x 512, long access only, +1 adddresses next long
    $000 <= Cog RAM <= $1ff
    $200 <= LUT RAM <= $3ff

    This a Program-Counter only concern, ie: Affects instruction fetching. The general data manipulation instructions are all CogRAM only.

    So, in Hub Exec, where division_by_zero_error is a Hub label for a byte array of data, are you saying...
    		loc	adrb, #@division_by_zero_error
    		calla	#@send_msg
    
    ...is wrong?
    Because the loc adrb is operating on a cog register and division_by_zero is in Hub space?



  • evanhevanh Posts: 15,915
    Sorry, brain hurts, I've not read up on PNUT's immediate handlings. I'll defer to Electrodude there. No doubt Oz will chime in.
  • Here's a closer look at the different possible results.
    loc ptrb,#message    returns 000000EE
    loc ptrb,#@message   returns 000003DF
    loc ptrb,#\message   returns 00000040
    mov ptrb,##@message  returns 00000100
    
    from the following code
    dat		orgh	0
    		org
    
    		setb	dirb,#62
    		setb	outb,#62
    
    wait4key	jp	#63,#wait4key
    
    		loc	ptrb,#msg1
    		call	#send_msg
    		loc	ptrb,#message
    		mov	dx,ptrb
    		call	#show_hex
    
    		loc	ptrb,#msg2
    		call	#send_msg
    		loc	ptrb,#@message
    		mov	dx,ptrb
    		call	#show_hex
    		call	#send_msg
    
    		loc	ptrb,#msg3
    		call	#send_msg
    		loc	ptrb,#\message
    		mov	dx,ptrb
    		call	#show_hex
    
    		loc	ptrb,#msg4
    		call	#send_msg
    		mov	ptrb,##@message
    		mov	dx,ptrb
    		call	#show_hex
    
    here		jmp	#here
    
    show_hex	mov	cx,#8
    .loop		getnib	ax,dx,#7
    		cmp	ax,#9 wz,wc
    	if_a	add	ax,#"A"-10
    	if_be	add	ax,#"0"
    		call	#send_byte
    		shl	dx,#4
    		djnz	cx,#.loop
    		mov	ax,#13
    		call	#send_byte
    		ret
    
    send_msg	rdbyte	ax,ptrb++ wz
    	if_z	ret
    		call	#send_byte
    		jmp	#send_msg
    
    send_byte	setb	ax,#8
    		shl	ax,#1
    		getcnt	bx
    
    		rep	@sb_loop,#10
    		addcnt	bx,bit_time
    		testb	ax,#0 wz
    		setbnz	outb,#62
    		waitcnt
    		shr	ax,#1
    sb_loop		ret
    
    bit_time	long	50_000_000 / 115_200
    ax		long	0
    bx		long	0
    cx		long	0
    dx		long	0
    
    		orgf	$40
    message		byte	"Ozpropdev was here!",13,0
    
    		orgh	$400
    
    msg1		byte	"loc ptrb,#message    returns ",0
    msg2		byte	"loc ptrb,#@message   returns ",0
    msg3		byte	"loc ptrb,#\message   returns ",0
    msg4		byte	"mov ptrb,##@message  returns ",0
    
    
  • cgraceycgracey Posts: 14,152
    LOC is useful for getting the address of anything in hub RAM. Doesn't matter if it's code or data.

    There should be no trouble reading and writing below $400 in hub. The only caveat is that if you jump to any of those locations, you are executing from the cog/lut. Remember that reads and writes to anywhere in hub must use RDxxxx/WRxxxx. If you do 'MOV 0,#100' you are moving 100 into cog register $000, not into hub RAM $00000.
  • cgracey wrote: »
    LOC is useful for getting the address of anything in hub RAM. Doesn't matter if it's code or data.

    There should be no trouble reading and writing below $400 in hub. The only caveat is that if you jump to any of those locations, you are executing from the cog/lut. Remember that reads and writes to anywhere in hub must use RDxxxx/WRxxxx. If you do 'MOV 0,#100' you are moving 100 into cog register $000, not into hub RAM $00000.
    I think my code is the problem, not your image! I have used
    loc adrb, #@symbol
    in my Hub Exec code for symbols in Hub RAM.
    It looks like I should have been using
    loc adrb, #\symbol
    in order to get its' absolute address.
    Therefore, it may explain the problem I've been experiencing. I will change my code and see if that resolves the matter.

    I have drawn a diagram which I think may explain things a bit clearer than words, attached as file for comment.

  • cgraceycgracey Posts: 14,152
    edited 2015-10-25 09:39
    78rpm wrote: »
    cgracey wrote: »
    LOC is useful for getting the address of anything in hub RAM. Doesn't matter if it's code or data.

    There should be no trouble reading and writing below $400 in hub. The only caveat is that if you jump to any of those locations, you are executing from the cog/lut. Remember that reads and writes to anywhere in hub must use RDxxxx/WRxxxx. If you do 'MOV 0,#100' you are moving 100 into cog register $000, not into hub RAM $00000.
    I think my code is the problem, not your image! I have used
    loc adrb, #@symbol
    in my Hub Exec code for symbols in Hub RAM.
    It looks like I should have been using
    loc adrb, #\symbol
    in order to get its' absolute address.
    Therefore, it may explain the problem I've been experiencing. I will change my code and see if that resolves the matter.

    I have drawn a diagram which I think may explain things a bit clearer than words, attached as file for comment.

    It's not nearly that complicated!

    Lack of documentation is causing problems.

    All cog register accesses are direct via instructions (MOV rega,regb).

    All lut access is via RDLUT/WRLUT (cog registers <--> lut registers) or SETQ2+RDLONG (hub --> lut).

    All hub accesses are via RDxxxx/WRxxxx/RFxxxx/WFxxxx, only.

    "@", "#hublabel", "#\hublabel" refers to hub RAM, only.

    "#@hublabel" is the same as "#hublabel".

    "@", "#\", and "#@" cannot be used to point at anything in the cog or lut. They always denote hub memory.

    I think we need to develop some syntax that inhibits all this confusion over addressing.
  • cgracey wrote: »
    78rpm wrote: »
    cgracey wrote: »
    LOC is useful for getting the address of anything in hub RAM. Doesn't matter if it's code or data.

    There should be no trouble reading and writing below $400 in hub. The only caveat is that if you jump to any of those locations, you are executing from the cog/lut. Remember that reads and writes to anywhere in hub must use RDxxxx/WRxxxx. If you do 'MOV 0,#100' you are moving 100 into cog register $000, not into hub RAM $00000.
    I think my code is the problem, not your image! I have used
    loc adrb, #@symbol
    in my Hub Exec code for symbols in Hub RAM.
    It looks like I should have been using
    loc adrb, #\symbol
    in order to get its' absolute address.
    Therefore, it may explain the problem I've been experiencing. I will change my code and see if that resolves the matter.

    I have drawn a diagram which I think may explain things a bit clearer than words, attached as file for comment.

    It's not nearly that complicated!

    Lack of documentation is causing problems.

    All cog register accesses are direct via instructions (MOV rega,regb).

    All lut access is via RDLUT/WRLUT (cog registers <--> lut registers) or SETQ2+RDLONG (hub --> lut).

    All hub accesses are via RDxxxx/WRxxxx/RFxxxx/WFxxxx, only.

    "@", "#hublabel", "#\hublabel" refers to hub RAM, only.

    "#@hublabel" is the same as "#hublabel".

    "@", "#\", and "#@" cannot be used to point at anything in the cog or lut. They always denote hub memory.

    I think we need to develop some syntax that inhibits all this confusion over addressing.

    I am very good at complicating things, me :smile:

    What I am after is how to obtain the address of a location of a symbol in Cog, and also in Hub and Lut. The assembler knows them, I wish to know them, too.
            org 0
            mov     my_addr,  magic_address_of_long_in_cog_for my_reg
    
    my_reg   long  0
    my_addr long  0
    
    so my_reg is at address 1 in Cog long RAM, my_addr at 2, and in my example woud contain the value 1.

    I am after the same in LUT and Hub RAM.

    I await clarification, then hopefully my memory overwrites, I think we can all see why that is happening, even though I'm not sure, will logically resolve themselves. :smile:

  • cgraceycgracey Posts: 14,152
    All symbols defined under ORGH are hub addresses. Any reference to one of them returns a hub address.

    All symbols defined under ORG are both cog and hub addresses, with a direct reference returning a cog address. Using @ before one of those symbols returns the hub address, instead.
  • cgracey wrote: »
    All symbols defined under ORGH are hub addresses. Any reference to one of them returns a hub address.

    All symbols defined under ORG are both cog and hub addresses, with a direct reference returning a cog address. Using @ before one of those symbols returns the hub address, instead.
    That is so concise and elegant compared to my understanding :smile: Good job there's only us two mice here reading this! :blush:

    Ah, so in your all_cogs_blink.spin example in the FPGA download, you use the coginit cognum,#@blink because the binary is initially loaded into hub ram, however, they are really cog programs within cog space. Thus #@blink gives the source hub address from which to load the cog from that image.

    So if I had a cog binary image loaded into hub ram at startup, and I wished to change some information in it, I would need to use the #@ for hub ram address, make any necessary changes, and then it could be loaded into a cog.

    To setup address registers with loc, the simple loc ptrb, #symbol is all that is required?

    I have changed and checked my code for the test harness. I am using a hub based stack with ptra as the stack pointer. All calls and rets are by calla #function and reta, all stack pushes and pops are pusha and popa. All locs use loc ptrb, #symbol.

    However, at present I am still experiencing corruption of data as before. I will check through carefully on what happens to my registers, it sounds like I must be corrupting one for some reason, but thinking about it I think it has always happened in the decimal conversion process chain somewhere.

    I'll get there eventually. :smile:


  • jmgjmg Posts: 15,173
    cgracey wrote: »
    I think we need to develop some syntax that inhibits all this confusion over addressing.
    I agree - the P2 has multiple memory areas now, combined with value and opcode rules for access.

    It would be good (and not too difficult) to have the tools check and confirm correct indexing context, otherwise there will be a lot of slip-ups (as these posts show)
    HLL's have this index context control more naturally handled, but there will be more ASM exposed to users on P2 than other MCUs, so good ASM support is important.
  • jmg wrote: »
    cgracey wrote: »
    I think we need to develop some syntax that inhibits all this confusion over addressing.
    I agree - the P2 has multiple memory areas now, combined with value and opcode rules for access.

    It would be good (and not too difficult) to have the tools check and confirm correct indexing context, otherwise there will be a lot of slip-ups (as these posts show)
    HLL's have this index context control more naturally handled, but there will be more ASM exposed to users on P2 than other MCUs, so good ASM support is important.

    I agree about the tools checking and assisting as much as possible with these 'seperate yet combined' memory areas. Anything which makes the path easier.

    HLLs have to be adapted / written first, then tested to ensure that they too are analysing and synthesising correctly. Obviously that takes time, so what we currently use needs to be supportive. In the mean time I will become quite proficient at PASM2 (sans macros) I hope! :smile:

    Now, what we could do for macros is use have a preprocessor, obviuously the C preprocessor won't be suitable because of the liberal sprinkling of # characters in PASM2. What we need is:
    openfile_for_read( PNut_editor_file_or_memory )
    openfile_for_write( spin_file_for_PNut_editor )
    while readlines() ' a token could be a multiline comment
      while get_token_from_lines()  ' this would include comment tokens
        if token == "macro" ) 
          make_a_macro_from_what_follows_on_lines() ' macros span lines
        else 
          if token == a_macro_we_have_defined( )
            expand_macro_for_tokens_from_what_follows_on_lines( token )
          else
            put_token_to_output_spin_file( token ) 
            ' hopefully it's real pasm, not the stuff 78rpm TRIES to write
      endwhile
    endwhile
    closeallfiles( )
    return_to_PNut()
    
    Now something like that would help and work, especially if the macroed source can be edited within PNut, then launched for pre-processing and the output spin file then assembled by PNut. Life would be a far easier. Perhaps there is something already around like that, or could be tailored for use. Simply a case of deciding if the word "macro" defines the start of a macro definition and how parameters are passed and expanded and any other fancy stuff like looping.
  • jmgjmg Posts: 15,173
    78rpm wrote: »
    I agree about the tools checking and assisting as much as possible with these 'seperate yet combined' memory areas. Anything which makes the path easier.

    ....

    Now, what we could do for macros is use have a preprocessor, obviuously the C preprocessor won't be suitable because of the liberal sprinkling of # characters in PASM2. What we need is:

    I was thinking of something easier to add to PNUT than macros (but macros would be nice, & they are in GAS)

    Some checking could be done with a mnemonic expansion, that tags the register with memory area.
    When used, that register is checked for correct memory area for that opcode.

    This would also allow easier relocate of buffers/arrays.

    The classic # immediate would still work, such as HLL's might generate.

  • jmg wrote: »
    78rpm wrote: »
    I agree about the tools checking and assisting as much as possible with these 'seperate yet combined' memory areas. Anything which makes the path easier.

    ....

    Now, what we could do for macros is use have a preprocessor, obviuously the C preprocessor won't be suitable because of the liberal sprinkling of # characters in PASM2. What we need is:

    I was thinking of something easier to add to PNUT than macros (but macros would be nice, & they are in GAS)

    Some checking could be done with a mnemonic expansion, that tags the register with memory area.
    When used, that register is checked for correct memory area for that opcode.

    This would also allow easier relocate of buffers/arrays.

    The classic # immediate would still work, such as HLL's might generate.

    The memory tagging I think I understand.

    Relocating arrays and buffers. This is at assembly time for intended use at runtime? So are you suggesting this is for use with the memory area tag, such that at runtime you intend to move something, in hub space, or to a different memory space, cog or lut? And thus check that your pasm is checked such that a rdlong in hub space to memory in hub space, doesn't get moved to cog space with the associated hub buffer moved into say the lut?

    I can see that would be a big boost. More of a directive to PNut than a macro, that this symbol may be declared here, but I intend to use it elsewhere, such as here? If was called "relocate", then "relocate destination, source", would follow in the Propeller and pasm spirit.
  • jmgjmg Posts: 15,173
    edited 2015-10-25 22:59
    78rpm wrote: »

    The memory tagging I think I understand.

    Relocating arrays and buffers. This is at assembly time for intended use at runtime? So are you suggesting this is for use with the memory area tag, such that at runtime you intend to move something, in hub space, or to a different memory space, cog or lut? And thus check that your pasm is checked such that a rdlong in hub space to memory in hub space, doesn't get moved to cog space with the associated hub buffer moved into say the lut?

    I can see that would be a big boost. More of a directive to PNut than a macro, that this symbol may be declared here, but I intend to use it elsewhere, such as here? If was called "relocate", then "relocate destination, source", would follow in the Propeller and pasm spirit.

    That's quite close.
    Yes, it is a build time choice, as during a design you may not be sure if you want or need buffers in HUB or LUT for example.
    Yes, you can declare variables in one area, and use them later in the code.
    ( If there is no checking, you tend to code differently in style )

    The memory tag is another field in the symbol record, so is easy to add.
    If you move the memory area, but forget to move one opcode, this would catch that.

    Once you have that, you can even code generic items
    ( similar to CALL and JMP ) and have the tools know what you intend

    an example of pointer loading with address of label, could be in generic form :
    	GADR_H	Reg_or_Ptr,HUBLabel	' Loads Reg_or_Ptr with Hub Label addr, chk & tags as HUB
    	GADR_L	Reg_or_Ptr,LUTLabel	' Loads Reg_or_Ptr with LUT Label addr, chk & tags as LUT
    	GADR_C	Reg_or_Ptr,COGLabel	' Loads Reg_or_Ptr with COG Label addr, chk & tags as COG
    	GADR_T	Reg_or_Ptr,ANYLabel	' Loads Reg_or_Ptr with ANY Label addr, tags as that Area
    
    	
    	GADR_L	Reg_or_Ptr,LUTLabel	' Loads Reg_or_Ptr with LUT Label address & tags as LUT
    	RDLUT	D,[Reg_or_Ptr]		' Checks [S] field for LUT tagged 
    	WRLUT	[Reg_or_Ptr],S		' Checks [D] field for LUT tagged 
    	
    	GADR_T	Reg_or_Ptr,HUBLabel	' Auto tags as HUB
    	RDLONG	D,[Reg_or_Ptr]		' Checks [S] field for HUB tagged 
    	WRLONG	[Reg_or_Ptr],S		' Checks [D] field for HUB tagged 
    
    
  • jmg wrote: »
    78rpm wrote: »

    The memory tagging I think I understand.

    Relocating arrays and buffers. This is at assembly time for intended use at runtime? So are you suggesting this is for use with the memory area tag, such that at runtime you intend to move something, in hub space, or to a different memory space, cog or lut? And thus check that your pasm is checked such that a rdlong in hub space to memory in hub space, doesn't get moved to cog space with the associated hub buffer moved into say the lut?

    I can see that would be a big boost. More of a directive to PNut than a macro, that this symbol may be declared here, but I intend to use it elsewhere, such as here? If was called "relocate", then "relocate destination, source", would follow in the Propeller and pasm spirit.

    That's quite close.
    Yes, it is a build time choice, as during a design you may not be sure if you want or need buffers in HUB or LUT for example.
    Yes, you can declare variables in one area, and use them later in the code.
    ( If there is no checking, you tend to code differently in style )

    The memory tag is another field in the symbol record, so is easy to add.
    If you move the memory area, but forget to move one opcode, this would catch that.

    Once you have that, you can even code generic items
    ( like CALL and JMP ) and have the tools know what you intend

    an example of pointer loading with address of label, could be in generic form :
    	GADR_H	Reg_or_Ptr,HUBLabel	' Loads Reg_or_Ptr with Hub Label addr, chk & tags as HUB
    	GADR_L	Reg_or_Ptr,LUTLabel	' Loads Reg_or_Ptr with LUT Label addr, chk & tags as LUT
    	GADR_C	Reg_or_Ptr,COGLabel	' Loads Reg_or_Ptr with COG Label addr, chk & tags as COG
    	GADR_T	Reg_or_Ptr,ANYLabel	' Loads Reg_or_Ptr with ANY Label addr, tags as that Area
    
    	
    	GADR_L	Reg_or_Ptr,LUTLabel	' Loads Reg_or_Ptr with LUT Label address & tags as LUT
    	RDLUT	D,[Reg_or_Ptr]		' Checks [S] field for LUT tagged 
    	WRLUT	[Reg_or_Ptr],S		' Checks [D] field for LUT tagged 
    	
    	GADR_T	Reg_or_Ptr,HUBLabel	' Auto tags as HUB
    	RDLONG	D,[Reg_or_Ptr]		' Checks [S] field for HUB tagged 
    	WRLONG	[Reg_or_Ptr],S		' Checks [D] field for HUB tagged 
    
    

    Ah, I see clearly there. That type of checking would be of great advantage. I wonder how easily that could be integrated and tested into PNut or a PNut clone. As far as documentation, it could generate reports of symbols and memory spaces marked for access and/or relocation.
  • jmgjmg Posts: 15,173
    78rpm wrote: »
    Ah, I see clearly there. That type of checking would be of great advantage.

    Yes, and notice the hieroglyphs have gone away...

    78rpm wrote: »
    I wonder how easily that could be integrated and tested into PNut or a PNut clone.
    I've kept the idea simple, & PNUT could add a single byte record field and check that.
    78rpm wrote: »
    As far as documentation, it could generate reports of symbols and memory spaces marked for access and/or relocation.
    Yes, MAP files would naturally show the memory-area of each variable, and LST files would show the actual binary opcode ASM chose for that operation.


  • jmg wrote: »
    Yes, and notice the hieroglyphs have gone away...

    You mean the full message quote?
    I've kept the idea simple, & PNUT could add a single byte record field and check that.

    Without seeing the source, in asm86?, I wouldn't like to say.
    However, the idea is simple in practice.
    Yes, MAP files would naturally show the memory-area of each variable, and LST files would show the actual binary opcode ASM chose for that operation.

    Agreed, the traditional approach does work. Tha MAP file would be somewhat different from other processors due to these three memory areas and the fact you are able to relocate within them.


    As an additional thought. The names I use may be wrong, I see a similarity to scoping at global and function level. Your ANY label would be the global case, and COG would be within COG function and not reference the global instance.

    It would also need to support, could still be done in a single byte, that a data structure could exist in all three memory spaces, though each instance would be dealt with in the code. This to be is quite specific in that it could be anywhere because you perhaps haven't specified, but it could in fact exist everywhere.

    Now, carrying on that thought, would you wish to annotate LST an MAP files with all known locations as indicated by your code. I would say yes.
  • jmgjmg Posts: 15,173
    edited 2015-10-25 23:54
    78rpm wrote: »
    As an additional thought. The names I use may be wrong, I see a similarity to scoping at global and function level. Your ANY label would be the global case, and COG would be within COG function and not reference the global instance.
    To clarify, the ANY case is a slight elevation in IQ, whilst the earlier GADR_H, GADR_L, GADR_C explicitly define the memory area, and the Label is checked for correct match.
    The GADR_T 'auto-typed' form, auto-extracts the memory area from the label (which is tagged by its ORG_C,ORG_H,ORG_L).
    It still gives pointer use checking, but it can open the door to easier move between (supported) Arrays in LUT or HUB, for example.
            GADR_T	Reg_or_Ptr,HUBLabel 	' Auto tags as HUB
    ..
    	RDLNG	D,[Reg_or_Ptr]		 ' Reads Long from HUB
    	WRLNG	[Reg_or_Ptr],S		 ' Writes Long to HUB
    ' -- or --
            GADR_T	Reg_or_Ptr,LUTLabel	 ' Auto tags as LUT
    ..
    	RDLNG	D,[Reg_or_Ptr]		 ' Reads Long from LUT
    	WRLNG	[Reg_or_Ptr],S		 ' Writes Long to LUT
    
    ASM form chosen in those cases is either RDLONG or RDLUT, with the label declaration being the only item needing edit to move a buffer.

    78rpm wrote: »
    It would also need to support, could still be done in a single byte, that a data structure could exist in all three memory spaces, though each instance would be dealt with in the code. This to be is quite specific in that it could be anywhere because you perhaps haven't specified, but it could in fact exist everywhere.

    Now, carrying on that thought, would you wish to annotate LST an MAP files with all known locations as indicated by your code. I would say yes.

    That may be going beyond what PNUT can support - I'm trying to keep this simple :).

    What you describe sounds like it needs run-time support, and I've seen that for example in some 8051 HLL compilers, where a 3rd byte is added to pointers, that is run-time checked for the various memory areas in 8051.
    In the 8051, DATA and CODE use different RdByte opcodes and IDATA and XDATA and PDATA also have different RdByte opcodes, so issues are similar to P2.
  • jmg wrote: »
    To clarify, the ANY case is a slight elevation in IQ, whilst the earlier GADR_H, GADR_L, GADR_C explicitly define the memory area, and the Label is checked for correct match.
    The GADR_T 'auto-typed' form, auto-extracts the memory area from the label (which is tagged by its ORG_C,ORG_H,ORG_L).
    It still gives pointer use checking, but it can open the door to easier move between (supported) Arrays in LUT or HUB, for example.

    GADR_T Reg_or_Ptr,HUBLabel ' Auto tags as HUB
    ..
    RDLNG D,[Reg_or_Ptr] ' Reads Long from HUB
    WRLNG [Reg_or_Ptr],S ' Writes Long to HUB
    ' -- or --
    GADR_T Reg_or_Ptr,LUTLabel ' Auto tags as LUT
    ..
    RDLNG D,[Reg_or_Ptr] ' Reads Long from LUT
    WRLNG [Reg_or_Ptr],S ' Writes Long to LUT

    ASM form chosen in those cases is either RDLONG or RDLUT, with the label declaration being the only item needing edit to move a buffer.

    Those look like rules for the access rights and permitted operations of the memory areas, we'll say an array,in this example.

    So the macro in this case may be GET to read from the array, and PUT to write. In your code you may have GETBYTE my_reg,ptrb. The tagging for both code and data, and the rule check the access is permitted. If so, GETBYTE is replaced with the appropriate rdbyte, or rdlut, or mov, sequence. Reading a byte may involve a LONG operation, so the instruction is susbtituted and another is automatically inserted to give the byte access, my_reg,#$ff. Thus we have the code from the data space.

    Or is that going a little too far. Is it slightly toward HLL in thinking? You can extend the idea with passing arguments on the stack, for if you require reentrant code in HUB. Issue a GETARG_1 my_reg and the register selected as the stack pointer can be substituted, along with the appropriate offsets for a rdlong my_reg,ptrb[ THIS_FUNCTIONS_ARG_1 ]. It could be a great aid, because coding would be more precise. If you defined your routine as FUNCTION a1, a2, a3, a4, the macro could generate the relevant constant index values for that function. They would only need to be local scope constants, similar to local .LABEL .
    What you describe sounds like it needs run-time support, and I've seen that for example in some 8051 HLL compilers, where a 3rd byte is added to pointers, that is run-time checked for the various memory areas in 8051.
    In the 8051, DATA and CODE use different RdByte opcodes and IDATA and XDATA and PDATA also have different RdByte opcodes, so issues are similar to P2.
    It may need some runtime support, but if you're having the memory area and symbol checking done for you, it can also insert the necessary runtime support code for you. Akin to a source level linker :smile:
  • jmgjmg Posts: 15,173
    78rpm wrote: »
    So the macro in this case may be GET to read from the array, and PUT to write. In your code you may have GETBYTE my_reg,ptrb. The tagging for both code and data, and the rule check the access is permitted. If so, GETBYTE is replaced with the appropriate rdbyte, or rdlut, or mov, sequence. Reading a byte may involve a LONG operation, so the instruction is susbtituted and another is automatically inserted to give the byte access, my_reg,#$ff. Thus we have the code from the data space.

    Or is that going a little too far. Is it slightly toward HLL in thinking?

    That's going somewhat further than I was thinking, but it is possible.

    I limited the use to where direct equivalent opcodes existed, in this case LONG access on HUB and LUT.
    That keeps things very simple (within the realms of PNIUT x86 ASM ) and there is always a predicable 'opcode outcome'.

    GETBYTE into LUT needs more than one opcode, and PUT is even trickier, and how that is implemented may depend on what else is happening. So I'd call that a little out of scope, for now.

    The intention is to keep 'Assembler level thinking', but add just enough IQ to remove the obtuse character tags used to denote address spaces (which also fail to check)

  • jmgjmg Posts: 15,173
    78rpm wrote: »
    It may need some runtime support, but if you're having the memory area and symbol checking done for you, it can also insert the necessary runtime support code for you. Akin to a source level linker :smile:

    I'm still on the fence over run-time, but that is only code & the user can do what they like.... *

    Maybe not for PNUT, but a better Assembler could open some more build-time decisions.

    eg a Library could use an Assembler Conditional build test of
    .IF (GetSeg(SymbolName) = HUB)
    ..
    .ELSIF (GetSeg(SymbolName) = COG)
    ..
    .ENDIF
    and the tools/linker stage could include just one, or both code expansions aka dead code removal.

    Some label alias mechanism would be needed, but this could give smallest-possible memory footprints, and a general ASM library coding style.

    * eg For those wanting run-time decisions, that Assembler directive GetSeg() could be used to load address upper bits, to be run-time checked.

  • jmg wrote: »
    78rpm wrote: »
    So the macro in this case may be GET to read from the array, and PUT to write. In your code you may have GETBYTE my_reg,ptrb. The tagging for both code and data, and the rule check the access is permitted. If so, GETBYTE is replaced with the appropriate rdbyte, or rdlut, or mov, sequence. Reading a byte may involve a LONG operation, so the instruction is susbtituted and another is automatically inserted to give the byte access, my_reg,#$ff. Thus we have the code from the data space.

    Or is that going a little too far. Is it slightly toward HLL in thinking?

    That's going somewhat further than I was thinking, but it is possible.

    I limited the use to where direct equivalent opcodes existed, in this case LONG access on HUB and LUT.
    That keeps things very simple (within the realms of PNIUT x86 ASM ) and there is always a predicable 'opcode outcome'.

    GETBYTE into LUT needs more than one opcode, and PUT is even trickier, and how that is implemented may depend on what else is happening. So I'd call that a little out of scope, for now.

    The intention is to keep 'Assembler level thinking', but add just enough IQ to remove the obtuse character tags used to denote address spaces (which also fail to check)

    Ok, so we're looking for a 1:1 on directives for checking and substitution. That is indeed simpler, and would provide less of path for instruction substitution and insertion which may by classified as 'interesting, WHAT!" One does indeed need to consider the task for x86 ASM coder, though if it were accomplished by another task which was launched, perhaps returning line numbers and the attribute tag in another file where the memory access checking directives were detected. Then PNut could read that file, apply the tags as it reads lines, etc. That way, it could be written in a HLL to tackle advantage of a more abstract code nature. It also makes integration easy. If the memory tagger failed to launch, PNut defaults to feeding itself internally your ANY tag on every line read, similar to the current arrangment. That would work, even if not quite what you had in mind.

    I understand about the abstraction level at asm level. At least if PNut provided the appropriate memory access operators itself internally the approach would be consistant, especially for people new to the Propeller, and to the P2. I think that is the direction you're going in here.
  • jmgjmg Posts: 15,173
    78rpm wrote: »
    Ok, so we're looking for a 1:1 on directives for checking and substitution. That is indeed simpler...
    Yes, but if you want to be strictly correct on the 1:1 there can be one minor exception around address range : The tools can decide on whether to use a AUGS to extend to 32b immediate load , or if 9 bits will fit, use that smaller form.
    COG and LOW-HUB vars, can use the smaller immediate load.
    78rpm wrote: »
    I understand about the abstraction level at asm level. At least if PNut provided the appropriate memory access operators itself internally the approach would be consistant, especially for people new to the Propeller, and to the P2. I think that is the direction you're going in here.
    Yes, direction is keeping it 'very much assembler' in coding and thinking, but hiding some of the kludges so the code is easier to maintain and read.

  • jmg wrote: »
    Yes, but if you want to be strictly correct on the 1:1 there can be one minor exception around address range : The tools can decide on whether to use a AUGS to extend to 32b immediate load , or if 9 bits will fit, use that smaller form.
    COG and LOW-HUB vars, can use the smaller immediate load.
    That makes sense and is the optimal step. It may even be useful in hub ram on a Nano FPGA, like I use, limited to 32K.
    jmg wrote: »
    Yes, direction is keeping it 'very much assembler' in coding and thinking, but hiding some of the kludges so the code is easier to maintain and read.
    Readability is a big plus, it enables easier maintenance as it's more quickly understood.

    Readability also plays in to an introduction to pasm by avoiding as many pitfalls as possible. That is something to be pursued. If the assembler is responsible for allocating memory locations for code and symbols, why does it insist on making the user play games when it has enough information to do the job. It knows when # or similar is required, it most cases it can supply it itself based on a little extra logic.

    Now, can I interest you in saving pasm files in .RTF files for viewing in Windows WordPad with the correct syntax highlighting? :smile:
  • .rtf?

    Um, NO!!
  • jmgjmg Posts: 15,173
    78rpm wrote: »
    Now, can I interest you in saving pasm files in .RTF files for viewing in Windows WordPad with the correct syntax highlighting? :smile:

    That's a different topic entirely, but syntax highlighting editors can often do this.
    eg I see Notepad++ has plugins that export RTF and HTML, and you can add your own language highlighters to Notepad++
  • mindrobots wrote: »
    .rtf?

    Um, NO!!
    Well, I am in full agreement with you, but I'm sure you must find the idea entertaining that WordPad could show pasm colour highlighting as in the PST.
  • 78rpm wrote: »
    mindrobots wrote: »
    .rtf?

    Um, NO!!
    Well, I am in full agreement with you, but I'm sure you must find the idea entertaining that WordPad could show pasm colour highlighting as in the PST.
    Um, NO!!! :)

    I find little about using WordPad as a programming editor entertaining.

    (Wait, should there be another smiley some place in there?)
Sign In or Register to comment.