Jump to content
IGNORED

MADS Knowledge-Base


Recommended Posts

  • 2 weeks later...

I'd consider that a bug which you should report to tebe.

 

Duly reported, and attached file was downloaded - so I assume message was read. :)

 

I messaged Tebe again last night regarding RELOC blocks (in MADS' own relocatable format, not the SDX file format). I was considering using OBX binaries for the GUI, but I'm unclear as to how to create multiple binary blocks, so that they may overspill into successive 16KB banks (either code blocks, or resource blocks). If multiple blocks (i.e. beginning FF FF) can't be created in the same file, the file format is less useful to me (although still suitable for small relocatable drivers, etc). One solution is to assemble large applications at a fixed address ($4000), using multiple segments loading at that address (and going into successive banks). Symbol tables can still be appended to such files.

 

In any case, I've edited my translation of the relocation format description in the MADS manual, if anyone's interested:

 

MADS Relocatable Binaries.txt

 

Note: the parts concerning PROC parameter passing passed through my mental process unfiltered, since I don't use the software stack anyway and don't understand this area yet.

Edited by flashjazzcat
Link to comment
Share on other sites

Nice, can you please put it into the global translation doc & thread? Most people who start newly with WUDSN IDE are convince by me to use MADS - based on your English translation :-)

 

Note: You can use parameter passing in PROC without the software stack, so it translation into plain LDA x: STA r.a: JSR r.

Link to comment
Share on other sites

Nice, can you please put it into the global translation doc & thread?

 

Done.

 

Note: You can use parameter passing in PROC without the software stack, so it translation into plain LDA x: STA r.a: JSR r.

 

Ah - of course. Forgot about that. I'll have another look at it and maybe make some changes later. Thanks! :)

Link to comment
Share on other sites

  • 5 months later...

Just noticed that this compiles without error:

 

BLK SPARTA $3000

.local test
.endl

.local test
.endl

 

It's not the very latest MADS release (I think it's the last but one), but I discovered it when I accidentally placed two subroutines of the same name in a project. The first of the duplicate routines ends up being called.

Link to comment
Share on other sites

In fact I used this as a feature once but I think it's rather unindended behaviour.

The locasl are itself is "just" scopes at first.

This one will cause on error: Label TEST.A declared twice

 

   BLK SPARTA $3000

   .local test
a    
   .endl

   .local test
a    
   .endl

 

But since locals can also be used as labels directly, and error would be better,

 

Edited by JAC!
Link to comment
Share on other sites

But since locals can also be used as labels directly, and error would be better.

 

I think so, since in this case I'd accidentally left two (supposedly mutually exclusive) LOCAL routines of the same name in the source code, and they shared no common label names inside the local block, so it was pure luck that the correct routine appeared first in the code and thus was executed by JSR. Happily my programming error was eradicated while reorganizing the code.

Link to comment
Share on other sites

  • 1 month later...

Just noticed that this compiles without error:

 

BLK SPARTA $3000

.local test
.endl

.local test
.endl

 

It's not the very latest MADS release (I think it's the last but one), but I discovered it when I accidentally placed two subroutines of the same name in a project. The first of the duplicate routines ends up being called.

 

LOCAL-s is addictive, this is not ERROR

 

use PROC, is not addictive

Edited by tebe
Link to comment
Share on other sites

  • 4 weeks later...

Having problems here:

 

I have a PBI ROM consisting of 4 2KB banks. Each segment begins (with padding):

nmb
org $C000,$e000 ; padding
.align $d800,$ff

; New Bank ********************************************************************

org $d800 ; start of code

 

Each bank ends with:

 

.align $e000,$ff

 

Now, I have an inter-bank JSR macro set up to make calls between banks. The macro calls a subroutine in RAM which handles all the bank switching via a stack.

 

I have no problems calling subroutines from bank 0 -> bank 1, but when trying to call something in bank 2 from code in bank 1, the compiler spits out an error "Undefined label". I can call stuff in bank 2 from bank 0, but not from bank 1.

 

It's a rather complex error, but it's reproducible. Basically, only code in bank 0 can see the labels in banks 1 and 2. The code in bank 1 can't see the labels in bank 2, for some reason.

 

EDIT: Hmmm... after all that, I took out all the NMBs and it works. Not sure what's going on there.

Edited by flashjazzcat
Link to comment
Share on other sites

  • 2 weeks later...

Just discovered this, and it's incredibly neat:

 

ldy #WindowData.Width
mwa (Object),y Width
ldy #WindowData.Height
mwa (Object),y Height

 

compiles to this:

 

377D: A0 08 LDY #$08
377F: B1 DB LDA (OBJECT),Y
3781: 85 B1 STA WIDTH
3783: C8 INY
3784: B1 DB LDA (OBJECT),Y
3786: 85 B2 STA $B2
3788: A0 0A LDY #$0A
378A: B1 DB LDA (OBJECT),Y
378C: 85 B3 STA HEIGHT
378E: C8 INY
378F: B1 DB LDA (OBJECT),Y
3791: 85 B4 STA $B4
3793: 60 RTS

 

Obviously the built-in MWA macro handles MWA address1 address2, etc, but I did NOT think it would bump the Y index on an indirect argument like this. Very cool. :)

Link to comment
Share on other sites

Yep - and another thing I just figured out is that you can explicitly specify the value of enumerated constants. Handy for flags using bits in a byte:

 

.enum WindowFlags
 AppIcon  = 1
 Sizeable = 2
 CloseBtn = 4
 ToolBar  = 8
 TitleBar = 16
 InfoBar  =  32
 StatusBar = 64
.ende

 

Now I can write:

 

LDA WinFlags
AND #WindowFlags.TitleBar

 

Without the equates, enumeration starts at zero and just goes up by 1.

Link to comment
Share on other sites

>it is bringing a very C like syntax to ASM

Even more, with the nesting of .PROC and the feature that macros tackel parameters string resolved at compile time you almost get object based structring and generic code.

This for example outputs the address range and size of every ".local", ".proc" etc.

 

    .macro m_info
   .print ":1: " , :1, " - ", :1 + .len :1 -1, " (", .len :1,")"
   .endm

 

 

>did NOT think it would bump the Y index

It can even increment implictly ("+" becoms INX/INY), but I don't like that syntax personally.

 

mva a b,x+

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

This for example outputs the address range and size of every ".local", ".proc" etc.

 

 .macro m_info
.print ":1: " , :1, " - ", :1 + .len :1 -1, " (", .len :1,")"
.endm

 

Nice - that'll be handy!

 

It can even increment implictly ("+" becoms INX/INY), but I don't like that syntax personally.

 

mva a b,x+

 

Thanks - I didn't know about that one. Got to watch against the functionality becoming too dense for sure, otherwise it's hard to gauge the bevity of the generated code. This is a characteristic danger of macros, of course.

 

Shame this won't work, but it's easy enough to write a macro for it:

 

cpw ClientWidth (Object),y

 

This trickle-feed of information in English is great, but a lot of wasted time could be saved if the whole manual was translated. It's rather like discovering new things about a long since abandoned compiler which never had a manual.

 

Google or Bing translate provides a very rough basis on which a human English translator could build, but sadly my comprehension of English is still not matched by my understanding of the compiler's functionality. We need another ten pages of the foregoing before I could have a crack at it.

Edited by flashjazzcat
Link to comment
Share on other sites

The autoincrement/autodecrement syntax is awesome when combined with compound statements. I use it all the time for short copy loops to avoid the need for loop labels:

 

   ldy        #4
   mva:rpl    standard_colors,y color0,y-

 

That the mwa pseudoinstruction can increment Y on a (zp),Y operand is a bit questionable IMO -- usually the incrementing that mwa/mwx/mwy needs to do is done in a way that doesn't have side effects.

 

The .print statement is useful too, but so far I haven't found a way to emit values in decimal, only in hex.

 

Anyone know if there is a way to make .pages/.endpg emit an error instead of a warning on a page crossing?

  • Like 1
Link to comment
Share on other sites

The autoincrement/autodecrement syntax is awesome when combined with compound statements. I use it all the time for short copy loops to avoid the need for loop labels:

 

ldy #4
mva:rpl standard_colors,y color0,y-

 

Need a gloss on that... :o

 

EDIT: OK - got it - this equates to:

 

ldy #4
loop
lda standard_colors,y
sta color0,y
dey
bpl loop

 

The code samples do NOT survive translation well, so it's best to refer to the original HTML manual.

 

That the mwa pseudoinstruction can increment Y on a (zp),Y operand is a bit questionable IMO -- usually the incrementing that mwa/mwx/mwy needs to do is done in a way that doesn't have side effects.

 

True, but it's pretty clear that it would have to increment the index, so the side-effects aren't a nasty surprise. I'm glad it works that way.

 

he .print statement is useful too, but so far I haven't found a way to emit values in decimal, only in hex.

 

Anyone know if there is a way to make .pages/.endpg emit an error instead of a warning on a page crossing?

 

How did you develop such a facility with this assembler? Sheer ingenuity and experimentation? RTFM only applies to a limited extent here... :)

 

...regarding CPW: can't see how to write a macro which can detect (ZP),Y addressing (although detecting immediate mode is easy enough, using definable delimiters). No big deal, though: an "ICW" macro specially for indirect word comparisons is perfectly acceptable.

Edited by flashjazzcat
Link to comment
Share on other sites

Anyone know if there is a way to make .pages/.endpg emit an error instead of a warning on a page crossing?

 

I know it is not what you need, but I wanted to check for a range in zero page because of of the rmt used range.

And this method checks for any boundary, not only page boundaries, so the use is quiet different.

 

At the end of my zero page variables is the following code:

;safty for Raster Music Tracker zero page
RMT_ZP
.if RMT_ZP>203
RMT_Zeropage overlapping!!!
.endif

 

It generates an error if the zero page usage extends free space given if using rmt

 

Same Test for overlapping different code blocks

ProgramMemory1End
.if ProgramMemory1End>antic
Program memory overlapping with Antic program!!!
.endif

 

Maybe a diffent modulo statement can check for some other usefull cases too.

Edited by 1NG
Link to comment
Share on other sites

So maybe I'll post my standard "code checking" macros here. All based on the fact that I LOVE ".PROC" and ".LOCAL" and uses to package and structure everything.

So for your pages problem, I'd simply use

 

.PROC pagedcode

.ENDP

 

.IF .len pagedcode>$4000...

 

   .macro m_info    ;Works with ranges like ".PROC", ".LOCAL"
   .print ":1: " , :1, " - ", :1 + .len :1 -1, " (", .len :1,")"
   .endm

   .macro m_align_page    ;Fills with 0 and prints how much space is "lost"
   here = *
   size = [[[here+255]/256]*256]-*
   .print "Alignment added at ",here,": ", size, " bytes."
   .rept size
   .byte 0
   .endr
   .endm

   .macro m_assert_same_page ;For timing critical loop or ranges enclosed by ".PROC" or ".LOCAL"
   .if :1 / $100 <> (:1 + .len :1 - 1) / $100
       .if .def alignment_mode
           .error ":1 crosses page boundary between ", :1, , " - ", :1 + .len :1 - 1
       .else
           .print ":1 crosses page boundary between ", :1, , " - ", :1 + .len :1 - 1
       .endif
   .else
       .print ":1 within page boundary between ", :1, , " - ", :1 + .len :1 - 1
   .endif
   .endm

   .macro m_assert_same_1k    ;For Display Lists
   .if :1 / $400 <> (:1 + .len :1 - 1) / $400
       .if .def alignment_mode
           .error ":1 crosses 1k boundary between ", :1, , " - ", :1 + .len :1 - 1
       .else
           .print ":1 crosses 1k boundary between ", :1, , " - ", :1 + .len :1 - 1
       .endif
   .else
       .print ":1 within 1k boundary between ", :1, , " - ", :1 + .len :1 - 1
   .endif
   .endm

   .macro m_assert_align    ; Uses .def alignment_mode to control if misaligment is error or warning
   .if :1 / :2 <> (:1 + :2 - 1) / :2
       .if .def alignment_mode
           .error ":1 crosses ",:2," boundary between ", :1, , " - ", :1 + :2 - 1
       .else
           .print ":1 crosses ",:2," boundary between ", :1, , " - ", :1 + :2 - 1
       .endif
   .else
       .print ":1 within ",:2," boundary between ", :1, , " - ", :1 + :2 - 1
   .endif
   .endm

   .macro m_assert_end_of_code ;For assuring the code does not overlap some data    
end_of_code
   .if end_of_code > :1
   .error "END_OF_CODE (",end_of_code,") > :1 (",:1,"), ", end_of_code-:1, " bytes too far" 
   .else
   .print "END_OF_CODE (",end_of_code,") <= :1 (",:1,"), ", :1-end_of_code, " bytes free" 
   .endif
   .endm

Edited by JAC!
  • Like 2
Link to comment
Share on other sites

Long sigh... deep breath...

 

This doesn't seem to work as expected:

 

WindowData .struct
...
Title		 .word ; address of the title line text (terminated by 0)
Info		 .word ; address of the info line text (terminated by 0)
WinContent	 .word ; address of the control group data record for the window content
Reserved	 .ds 150 ; reserved space for internal control records
.ends

 

(Note the structure fields are abridged for brevity). Now, when instancing one of these structs, I'd expect the PC to skip 150 bytes after the last populated field - but it doesn't. If .DS doesn't work in structs, is there another way to allocate undefined space?

 

EDIT: Other than simply placing .DS 150 after the structure, which I've done for now...

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...