Jump to content
IGNORED

Mad-Assembler (MADS)


Gury

Recommended Posts

  • 4 months later...

Not sure if this is the right topic for questions about MADS, so if not please move it to wherever it fits..

 

My question is about if it's possible to iterate through those indexed arrays. Or the indexed structs.

I mean, it's really nice to have these structures and arrays, yet I somehow cannot find anything about how to iterate through these with MADS.

 

Maybe someone can give me a pointer (pun intended) on how to accomplish this.

  • Like 1
Link to comment
Share on other sites

  • 4 months later...

In an experiment with a nested .REPT I see unexpected behaviour.

 

    org $2000
    
    .rept 4, #    
;    .byte :1
    .rept 4, :1, #
    .byte :1, :2
    .endr
    .endr

 

With the line commented out the output is:

 

 mads 2.1.5 build 3 (21 Feb 22)
Source: test.asm
     1                     org $2000
     2                     
     3                     .rept 4, #    
     6                     .BYTE :1, :2
     8                     .endr
Source: REPT
     8                     .endr
Source: REPT
     6 FFFF> 2000-201F> 00 00        .BYTE 0, 0
     6 2002 00 01            .BYTE 0, 1
     6 2004 00 02            .BYTE 0, 2
     6 2006 00 03            .BYTE 0, 3
Source: test.asm
     6                     .endr
Source: REPT
     6 2008 00 00            .BYTE 0, 0
     6 200A 00 01            .BYTE 0, 1
     6 200C 00 02            .BYTE 0, 2
     6 200E 00 03            .BYTE 0, 3
Source: test.asm
     6                     .endr
Source: REPT
     6 2010 00 00            .BYTE 0, 0
     6 2012 00 01            .BYTE 0, 1
     6 2014 00 02            .BYTE 0, 2
     6 2016 00 03            .BYTE 0, 3
Source: test.asm
     6                     .endr
Source: REPT
     6 2018 00 00            .BYTE 0, 0
     6 201A 00 01            .BYTE 0, 1
     6 201C 00 02            .BYTE 0, 2
     6 201E 00 03            .BYTE 0, 3
Source: test.asm
Source: test.asm

 

But with the line included it becomes:

 

mads 2.1.5 build 3 (21 Feb 22)
Source: test.asm
     1                     org $2000
     2                     
     3                     .rept 4, #    
     4                     .BYTE :1
     6                     .BYTE :1, :2
     8                     .endr
Source: REPT
     4 FFFF> 2000-2023> 00        .BYTE 0
     4                     .endr
Source: REPT
     6 2001 00 00            .BYTE 0, 0
     6 2003 00 01            .BYTE 0, 1
     6 2005 00 02            .BYTE 0, 2
     6 2007 00 03            .BYTE 0, 3
Source: test.asm
     4 2009 01                .BYTE 1
     4                     .endr
Source: REPT
     6 200A 01 00            .BYTE 1, 0
     6 200C 01 01            .BYTE 1, 1
     6 200E 01 02            .BYTE 1, 2
     6 2010 01 03            .BYTE 1, 3
Source: test.asm
     4 2012 02                .BYTE 2
     4                     .endr
Source: REPT
     6 2013 02 00            .BYTE 2, 0
     6 2015 02 01            .BYTE 2, 1
     6 2017 02 02            .BYTE 2, 2
     6 2019 02 03            .BYTE 2, 3
Source: test.asm
     4 201B 03                .BYTE 3
     4                     .endr
Source: REPT
     6 201C 03 00            .BYTE 3, 0
     6 201E 03 01            .BYTE 3, 1
     6 2020 03 02            .BYTE 3, 2
     6 2022 03 03            .BYTE 3, 3
Source: test.asm
Source: test.asm

 

Is this a bug? I can use this as an alternative way to reference the outer variable for it to be passed correctly to the inner but not produce code:
 

    org $2000
    
    .rept 4, #    
@myvar:1 equ :1
    .rept 4, @myvar:1, #
    .byte :1, :2
    .endr
    .endr

 

Producing:

 

mads 2.1.5 build 3 (21 Feb 22)
Source: test.asm
     1                     org $2000
     2                     
     3                     .rept 4, #    
     4                 @MYVAR:1 EQU :1
     6                     .BYTE :1, :2
     8                     .endr
Source: REPT
     4 = 0000            @MYVAR0 EQU 0
     4                     .endr
Source: REPT
     6 FFFF> 2000-201F> 00 00        .BYTE 0, 0
     6 2002 00 01            .BYTE 0, 1
     6 2004 00 02            .BYTE 0, 2
     6 2006 00 03            .BYTE 0, 3
Source: test.asm
     4 = 0001            @MYVAR1 EQU 1
     4                     .endr
Source: REPT
     6 2008 01 00            .BYTE 1, 0
     6 200A 01 01            .BYTE 1, 1
     6 200C 01 02            .BYTE 1, 2
     6 200E 01 03            .BYTE 1, 3
Source: test.asm
     4 = 0002            @MYVAR2 EQU 2
     4                     .endr
Source: REPT
     6 2010 02 00            .BYTE 2, 0
     6 2012 02 01            .BYTE 2, 1
     6 2014 02 02            .BYTE 2, 2
     6 2016 02 03            .BYTE 2, 3
Source: test.asm
     4 = 0003            @MYVAR3 EQU 3
     4                     .endr
Source: REPT
     6 2018 03 00            .BYTE 3, 0
     6 201A 03 01            .BYTE 3, 1
     6 201C 03 02            .BYTE 3, 2
     6 201E 03 03            .BYTE 3, 3
Source: test.asm
Source: test.asm

 

Link to comment
Share on other sites

@Wrathchild these nested loops are not behaving good, I had an issue and got elegant solution directly in this very thread:

 

it is using the temporary labels (those with questionmarks)... it is well readable and what is important is that it is forward compatible (not relying on nested loop behavior of particular mads release)

 

  • Like 1
Link to comment
Share on other sites

  • 3 months later...
  • 1 month later...

Anybody know how to build a macro that will repeat over a variable number of args?

 

I'd like to call it thusly:

      SetTabs %00001000

or

      SetTabs %00001000 %00100001 %00000010

 

Something like:

.macro SetTabs

.rept :0
?i=#+1
        lda #:?i
        sta TABMAP+#
.endr

.endm

 

That fails because it's looking for the global label ?i on the LDA and not finding it.

 

I've also tried it with %%?i and it assembles but results in the raw index value. The %% seems to be ignored.

 

I'll probably just use a bunch of ".if :0 > x" lines to check each arg index for now.

Link to comment
Share on other sites

Thanks @tebe

 

I'll just have to make a long .put line. And put a :0 check to catch when there's too many args.

 

You should add a description of that .put usage in the docs.

 

I also see .wget (etc) got added. Any chance of matching .wput (etc) for this kind of usage?

 

Link to comment
Share on other sites

  • 1 month later...
ins "filename.dat"*

it does not invert the bytes, it only inverts the highest bit (like when used with strings in dta d'xx'*)  - is that intentional or bug? Documentation says it inverts bytes.

Edited by matosimi
Link to comment
Share on other sites

50 minutes ago, matosimi said:
ins "filename.dat"*

it does not invert the bytes, it only inverts the highest bit (like when used with strings in dta d'xx'*)  - is that intentional or bug? Documentation says it inverts bytes.

'*' invert bit 7

 

Link to comment
Share on other sites

  • 9 months later...

I was wondering if this works yet:

blk.thumb.png.5936d883326876d6e20297160f15df44.png

 

I asked @tebe about the ability to generate multiple RELOC blocks in the same source file more than ten years ago, so I figured it might not be too soon to bring it up again. :)

 

Although the instructions appear to cleam it's (now) possible to have multiple RELOC blocks, I'm unable to get this to work since it keeps throwing out compiler errors ('ORG in reloc block', etc). To be clear, what I was hoping to accomplish is exactly what's already supported by the SDX relocatable format (multiple reloc blocks of different types with inter-block references included in the fix-up table) but without the annoying limitations of said SDX relocatable format (eight character label names, no lo/hi fixups, etc).

 

For clarity, perhaps an example will help:

	blk absolute $3000	; loads at arbitary address, and is jettisoned after use

Init
	jsr something
	rts

	blk reloc main	; loader relocates this block down to MEMLO in base memory
DriverStart

	; do stuff

	blk reloc ext	; loader relocates this block into extended memory (if available)
ExtCode
	; do more stuff

	blk update address	; produce fixup table	

I realise the relocatable format was ostensibly designed for use with the MADS linker, but I wrote the relocating, linking loader more than a decade ago and the MADS proprietary format is otherwise perfectly usable, aside from the inability to produce a compound file which can be efficiently relocated into main and extended memory as required.

Edited by flashjazzcat
  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
Posted (edited)
On 5/1/2024 at 7:43 PM, tebe said:

.nowarn

LOL. Just tried this and it didn't work as expected, so I looked it up:

image.thumb.png.cc049ce5d21c100f022956c9466c3fcd.png

Couid we just have a global flag to turn this off entirely? I don't think it's reasonable to have to edit every line containing DEW and similar just to silence a warning that older versions of the assembler never produced in the first place.

image.thumb.png.0e391c386f27dd4780ef9e64611725e6.png

Edited by flashjazzcat
Link to comment
Share on other sites

Posted (edited)
3 hours ago, flashjazzcat said:

DEW and similar just to silence a warning that older versions of the assembler never produced in the first place

users wanted a message with a warning

 

disable further warnings if one has already been disabled? interesting idea for learning warnings

Edited by tebe
Link to comment
Share on other sites

Posted (edited)
19 minutes ago, tebe said:

users wanted a message with a warning

I've wanted stuff for ten years, but not this. :) Allow me to just tactfully register interest in a way to turn off intrusive new features which either break existing source code (for example, the insistence on a non-anonymous label in front of a dta instance even if the label serves no purpose, which we already discussed a few years back; I ended up laboriously changing my code to suit) or introduce spurious warnings when compiling code which previously produced no warnings at all (i.e. it compiled 'clean').

 

I appreciate the purpose of warnings relating to non-compliant coding practice or unexpected conditions of which the assembler is nevertheless tolerant, and I thought this was purpose of compiler warnings in general - not to remind the programmer of the obvious (in this case that it's impossible to perform a 16-bit decrement operation without use of a register, in this case A). Perhaps that kind of thing could be opt-in:

 

.statetheobvious

 

Quote

disable further warnings if one has already been disabled? interesting idea for learning warnings

See above. Using a built-in macro should not trigger a compiler warning.

Edited by flashjazzcat
  • Like 1
Link to comment
Share on other sites

Posted (edited)

I have to agree with flashjazzcat (almost in full), and I understand we want learning to be key as well. How about...global

.learning

.moderate

.expert

warning levels set accordingly maybe.

 

and still keep, if you wish to help those on  the way

.nowarn

Edited by _The Doctor__
  • Like 1
Link to comment
Share on other sites

Posted (edited)

Could this be elaborated on at all, if possible:

 

image.png.3bd07d84e1d2f453a77aad20ff9ae1c9.png

 

This produces the usual 'ORG at reloc block' error:

 

	.reloc 0
	
Start
	lda #0
	rts
	
	.reloc 1
	
Main
	lda #1
	
	

 

No matter whether RELOC has a number after it or not, it's impossible to declare more than one. I'm not sure if I'm misunderstanding the 2022 response to my question, or if the question itself hasn't been phrased well enough.

Edited by flashjazzcat
  • Like 1
Link to comment
Share on other sites

8 hours ago, flashjazzcat said:

LOL. Just tried this and it didn't work as expected, so I looked it up:

image.thumb.png.cc049ce5d21c100f022956c9466c3fcd.png

Couid we just have a global flag to turn this off entirely? I don't think it's reasonable to have to edit every line containing DEW and similar just to silence a warning that older versions of the assembler never produced in the first place.

image.thumb.png.0e391c386f27dd4780ef9e64611725e6.png

1) We already have a command switch disable infos, So extending this seem logical.
"-s:  Use the -s switch to activate the so-called 'Silent mode', where no messages will be displayed, only errors (ERROR) and warnings (WARNING)."
2) A good system for disabling warnings would assign IDs to them and support selectively suppressing them. Generally, suppressing all warnings is not what you want.
Reference: https://learn.microsoft.com/de-de/cpp/preprocessor/warning?view=msvc-170

  • Like 5
Link to comment
Share on other sites

  • 4 weeks later...
Posted (edited)

Is there any particular reason why .local scopes (which the documentation asserts are cumulative, so multiple instances of the same local scope with the same name may exist) of the same name throw an error if the bank number has changed?

image.thumb.png.c831db8efb0ac98ac8fedf6354e393c4.png

The test code above illustrates the problem I just ran into with my 50,000 line project which runs off a banked cartridge ROM. The bank number (set with LMB) is important since it tells my inter-bank JSR macro which bank the target resides in, so I can't just do away with LMB. Meanwhile, some local scopes necessarily spread across multiple banks - not to mention the fact I need the equates declared in RAM to be in bank 0, outside of the ROM banks entirely, but belonging to the same scope.

 

Everything works just fine if all the cumulative scopes share the same bank number, but since this will break the whole project, that's not really an option.

 

EDIT: Interestingly, you can change the bank number inside a single LOCAL scope declaration and the compiler doesn't throw an error. However, this results in labels with the same scope in different banks being inaccessible, resulting in a slew of 'undefined label' errors. The labels defined in RAM are similarly out of scope as well, and if they're made accessible (via LMB #0 to make them global), the compiler throws the error described above.

 

Completely out of workarounds at this point. I cannot understand why we can't have fs.label0 in bank 0, fs.label1 in bank 1, fs.label2 in bank 4, or whatever, without having to prepend scope qualifiers for the scope we're already in.

Edited by flashjazzcat
Link to comment
Share on other sites

you want to sum two LOCAL areas from two different spaces, LOCAL areas are additive

 

LMB > 0 creates new namespace, LMB #0 has access to all namespaces, > 0 does not

 

why don't you choose another name ?

Link to comment
Share on other sites

Posted (edited)
10 minutes ago, tebe said:

why don't you choose another name ?

Because I want the same named scope to span different banks - simple as that. Plus which, I want to define the RAM-based variables in the same scope. The JSR macro just gets the bank number of the target label with [=:1].

 

If it's impossible, it's impossible. I'll just scrap this approach and use the more laborious method which provides no encapsulation properties whatsoever (prepending every file system driver function and variable name with 'fs').

Edited by flashjazzcat
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...