Jump to content

Photo

MADS Knowledge-Base


274 replies to this topic

#26 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,728 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Thu Apr 26, 2012 1:32 AM

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

#27 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Wed May 9, 2012 4:56 AM

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:

Attached File  MADS Relocatable Binaries.txt   5.35KB   218 downloads

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, Wed May 9, 2012 4:57 AM.


#28 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,728 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Wed May 9, 2012 5:19 AM

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.

#29 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Wed May 9, 2012 6:05 AM

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! :)

#30 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Fri Oct 26, 2012 4:27 AM

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.

#31 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,728 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Fri Oct 26, 2012 4:40 AM

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!, Fri Oct 26, 2012 4:43 AM.


#32 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Mon Oct 29, 2012 1:18 PM

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.

#33 tebe OFFLINE  

tebe

    Dragonstomper

  • 757 posts
  • Location:Poland

Posted Mon Dec 10, 2012 4:50 AM

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, Mon Dec 10, 2012 4:50 AM.


#34 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Mon Dec 10, 2012 7:53 AM

LOCAL-s is addictive, this is not ERROR

use PROC, is not addictive


PROCs didn't work in relocatable SDX binaries last time I tried. I was told to use LOCALs instead...

#35 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Mon Dec 17, 2012 7:10 AM

MADS doesn't generate an error for this:

rb1 DlgRadioBtn [0] (5,9,9,9,rb1_label)

(i.e. missing "dta" between the label field and the struct name).

#36 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Wed Jan 9, 2013 4:22 PM

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, Wed Jan 9, 2013 4:29 PM.


#37 tebe OFFLINE  

tebe

    Dragonstomper

  • 757 posts
  • Location:Poland

Posted Thu Jan 10, 2013 6:22 AM

Basically, only code in bank 0 can see the labels in banks 1 and 2.


bank = 0 is global
bank <> 0 is local

it's OK

#38 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Thu Jan 10, 2013 8:49 AM

Serously? I did not know that. We really need an English manual.

#39 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Tue Jan 22, 2013 10:59 AM

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

#40 Tezz OFFLINE  

Tezz

    River Patroller

  • 2,378 posts
  • Location:Manchester, England

Posted Tue Jan 22, 2013 11:13 AM

neat! Another feature of MADS that I wasn't aware of.

#41 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Tue Jan 22, 2013 11:47 AM

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.

#42 Stephen OFFLINE  

Stephen

    Quadrunner

  • 7,173 posts
  • A8 Gear Head
  • Location:No longer in Crakron, Ohio

Posted Tue Jan 22, 2013 12:03 PM

Awesome stuff - it is bringing a very C like syntax to ASM.

#43 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,728 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Tue Jan 22, 2013 12:31 PM

>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!, Tue Jan 22, 2013 12:36 PM.


#44 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Tue Jan 22, 2013 1:39 PM

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, Tue Jan 22, 2013 1:46 PM.


#45 phaeron OFFLINE  

phaeron

    River Patroller

  • 2,580 posts
  • Location:USA

Posted Tue Jan 22, 2013 9:43 PM

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?

#46 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Wed Jan 23, 2013 6:02 AM

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, Wed Jan 23, 2013 6:26 AM.


#47 1NG OFFLINE  

1NG

    Chopper Commander

  • 150 posts
  • Location:Lübeck, Germany

Posted Wed Jan 23, 2013 6:21 AM

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, Wed Jan 23, 2013 6:21 AM.


#48 MaPa ONLINE  

MaPa

    Dragonstomper

  • 951 posts
  • Location:Czech Republic

Posted Wed Jan 23, 2013 9:01 AM

IMHO you can use:
ert *>203 RMT_Zeropage overlapping!!!

and

  ert *>antic memory overlapping with Antic program!!!

Edited by MaPa, Wed Jan 23, 2013 9:05 AM.


#49 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,728 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Wed Jan 23, 2013 12:12 PM

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!, Wed Jan 23, 2013 12:16 PM.


#50 flashjazzcat OFFLINE  

flashjazzcat

    Quadrunner

  • Topic Starter
  • 13,814 posts
  • Location:United Kingdom

Posted Thu Jan 24, 2013 2:15 PM

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, Thu Jan 24, 2013 2:52 PM.





0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users