Jump to content
IGNORED

MADS Knowledge-Base


Recommended Posts

MADS now being my assembler of choice, I'm keen to master some of its more advanced features. Rough English translation of the Polish docs to hand, I set about using "OPT ?+" to make labels prefixed with "?" behave as local rather than temporary labels. I assumed this would mean I could re-use "?1", "?2", etc, as loop labels without having to set up local ranges. Unfortunately, "OPT ?+" at the top of my source file had disastrous effects on all my struct and enum definitions. MADS suddenly seemed to to think they were all multiply defined, and they weren't. I'm not sure if there's a bug in that switch, or not.

 

I know there are some pretty good examples in the MADS distro, but all the comments are in Polish. Before I try and run them all through Google Translate, I thought some shared knowledge on MADS's more esoteric features and constructs would be pretty cool. I've posted examples of the very cool "structs" in the GUI thread, but I'm sure there are many other compiler features which would make life easier if only I knew how to use them.

 

Maybe we could add to this topic as we discover new stuff...

Link to comment
Share on other sites

Hi Jon,

 

I'd recommend not to use this generic approache to local labels. The problem with locality is that you have to speciy "how local" the label should be. The ".PROC/.ENDP" of MADS is the perfit fit to express how local something is. Everthing within this block is local. And the very cool thing: It is still globally accssible.

 

.PROC main

 

mva #1 routine.counter

jsr routine

 

.PROC routine

.var counter .byte

 

loop lda counter

sta colbk

dec counter

 

rts

 

.ENDP

 

.ENDPRO

Link to comment
Share on other sites

Hi Jon,

 

I'd recommend not to use this generic approache to local labels. The problem with locality is that you have to speciy "how local" the label should be. That is the case in many compilers. They try some heuristic approach or implicit logic ("Everything until the next XYZ statement). The ".PROC/.ENDP" of MADS is the perfect fit to express how local something is. Everthing within this block is local. Most of my procs only have one "loop" or some "loopx/loopy" labels.

 

And the very cool thing: It is still globally accssible from every other location in the source using qualified access.

 

.PROC main

loop mva #2 routine.counter
    jsr routine
    jmp loop ;Main loop


.PROC routine
.var counter .byte

loop lda counter
    sta colbk
    dec counter
    bne loop
    rts

.ENDP

.ENDP

Edited by JAC!
Link to comment
Share on other sites

An elementary question:

 

How do you set the location counter separately from the program counter (i.e. in order to compile code which will be relocated to the shadow RAM at runtime)?

 

Secondly, I see several potentially useful references to relocation and built-in "virtual" and "hardware" memory bank handling. Unfortunately the Google translated docs are impenetrable to my tired eyes. :)

Link to comment
Share on other sites

  • 3 weeks later...

.proc label , new_org

.endp

 

 

.local label , new_org

.endl

 

.proc zp_routine,$80    ; backup original ORG, switch assembles ORG to $80
;  code
.endp                   ; restore original ORG ADD PROC (LOCAL) LENGTH and set new assembles ORG

Edited by tebe
Link to comment
Share on other sites

  • 3 weeks later...
  • 1 month later...

I'm trying to create an 8k ROM cardidge consisting of two 4k banks with MADS 1.9.2 build 21 (21 Jan 11).

 

opt h-f+

.segdef bank0 $f000 $1000 RW 0
.segdef bank1 $f000 $1000 RW 1

.segment bank0		;Main part

org $f000
.proc any
.endp
.proc chunky_zp_template, chunky_zp;  chunky_zp=$A0 <= first error
.endp
.endseg; <= second error

 

When I use the ",chunky_zp" addition to relocate the procedure to $A0, i get "Segment BANK0 error at $00A0".

When I remove the addition, I get "Can't fill from higher to lower memory location".

 

Any ideas? It's the first time I'm using segments, and I'm not sure about the documentation.

Link to comment
Share on other sites

Can't really suggest anything since I don't know what the .segdef and .segment statements do. Could you explain these? I'm building a banked cart with MADS too, and I figure I should be using them. Once I understand them, I'll have better insight into your problem. I'm struggling with the Google translated docs at the moment.

 

 

 

Link to comment
Share on other sites

Compiling the example from the documentation results in an error and a warning "Memory segments overlap".

Interesting: Lost of new directies and support for illegal opcodes contained in 1.9.2!

Link to comment
Share on other sites

So - to be clear about .SEGDEF: in your code example, you're defining labels "bank0" and "bank1" as shorthand for the parameters which follow them (i.e. "$f0000 $1000 RW 0").

 

".PROC label, new_org" looks useful: I'd missed that before. I need an init bank to include code assembled at $2000, which is copied to the target region at runtime. This should do the job nicely.

 

I should really take the time to edit the translated manual and PDF it as I become more familiar with all the directives. It's a huge document, though. I'd appreciate any help from MADS experts who'd be willing to take the raw translation and tidy it up.

Edited by flashjazzcat
Link to comment
Share on other sites

At least I found a way to create a banked ROM without ".SEGDEF" now ;-)

The trick is to disable fill mode before the next ORG statement.

This way you can have code at the same address origins.

 

;	Create a ROM with two 4K banks
opt h-		;Disbale headers

org $f000	;Set origin
opt f+		;Enable ROM mode

.proc bank1
lda #2

org $fffe	;Make sure bank is full
.byte $12,$34
.endp
opt f-		;Disable ROM mode

org $f000	;Set origin
opt f+		;Enable ROM mode

.proc bank2
lda #2

org $fffe	;Make sure bank is full
.byte $56,$78
.endp

Link to comment
Share on other sites

Heh... there seem to be many ways to break an egg here. I was using .ALIGN $C000, $FF at the end of each bank (actually, the fill will be six bytes short and have the cart header bytes at the end of each bank, similar to your example). What does ROM mode do, exactly?

 

Here is the inter-bank JMP/JSR mechanism as it stands:

 

ljsr .macro ; do a long JSR to a label in a different bank
sta asave
sty ysave
stx xsave
lda #= :1 ; get bank number of target label
sta target_bank
?1	ldy #= ?1 ; get current bank
lda #< :1
ldx #> :1
jsr :long_jump
.endm
;

ljmp .macro ; do a long JMP to a label in a different bank
sta asave
sty ysave
lda #= :1 ; get bank number of target label
tay
lda #$FF
sta cart_banks,y ; switch in target bank
lda #< :1
sta jmp_vec
lda #> :1
sta jmp_vec+1
lda asave
ldy ysave
jmp (jmp_vec)
.endm

...

long_jump ; execute "far" subroutine (this code must reside in low RAM)
sta jmp_vec
stx jmp_vec+1
tya ; push return bank on stack
pha
lda #> [return-1] ; push address of return routine on the stack
pha
lda #< [return-1]
pha
ldy target_bank ; get bank number
lda #$FF
sta cart_banks,y ; switch in the target bank
lda asave
ldy ysave
ldx xsave
jmp (jmp_vec) ; execute the routine
;

return ; handle return from banked routine
sta asave
sty ysave
pla ; get return bank
tay
lda #$FF
sta cart_banks,y ; switch in originating bank
lda asave
ldy ysave
rts

Link to comment
Share on other sites

"OPT f+" fills all intermediate space between the first and the last byte with $FF (does not create COM segments in case of large ".ALIGN", ".DS" or "ORG" spacing) and makes sure that the ORG statements only have addresses in ascending order.

Link to comment
Share on other sites

  • 4 weeks later...
  • 1 month later...
  • 7 months later...
  • 2 weeks later...

I assume you mean the include file references. At least 1.9.2 and 1.9.3 work as expected for me:

I use "-p" in the compiler options and "OPT l+" in the source. The resulting .lst file contains:

 

 

mads 1.9.3 build 49 (31 Jul 11)

2 opt l+

3 org $2000

4

5 icl "Test-include.asm"

Source: C:\Users\D025328\Documents\Eclipse\runtime-WUDSN-IDE\Test\Test-include.asm

1 FFFF> 2000-2008> AD 0B + loop lda $d40b

2 2003 8D 1A D0 sta $d01a

3 2006 4C 00 20 jmp loop

6

Link to comment
Share on other sites

Here's one I just discovered after an hour trying to understand the translated manual:

 

ptr1  equ $80
ptr2  equ $82

addw .macro " "
.if :3 = '#'
 lda ptr1
 clc
 adc #< :4
 sta ptr1
 lda ptr1+1
 adc #> :4
 sta ptr1+1
.else
 lda ptr1
 clc
 adc :4
 sta ptr1
 lda ptr1+1
 adc :4+1
 sta ptr1+1
.endif
.endm

;
org $4000

addw ptr1 #200
addw ptr1 ptr2

 

The pair of double quotes after the macro name cause the parameters to be split into addressing mode and argument. So, the first call yields " ", PTR1, "#", 200, while the second yields " ", PTR1, " ", PTR2. Thus the macro can check the addressing mode and react accordingly. The first call will add 200 to PTR1, while the second will add PTR1 and PTR2 together. This is useful, because I want to make my 16 bit signed integer macros behave this way.

 

NOTE: I'm aware MADS has inbuilt macros for performing unsigned 16-bit arithmetic - the above is just an example.

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

I assume you mean the include file references. At least 1.9.2 and 1.9.3 work as expected for me:

I use "-p" in the compiler options and "OPT l+" in the source. The resulting .lst file contains:

 

Figured it out -- the Source: lines disappear if MADS 1.9.3 is fed a relative path. "mads -l foo.s" and "mads -l d:\test\foo.s" generate source file indicators, but "mads -l test\foo.s" and "mads -l .\foo.s" don't. Now I just need to figure out how to derive absolute paths in NMAKE.

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