flashjazzcat Posted March 29, 2011 Share Posted March 29, 2011 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... Quote Link to comment Share on other sites More sharing options...
+JAC! Posted March 30, 2011 Share Posted March 30, 2011 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 Quote Link to comment Share on other sites More sharing options...
+JAC! Posted March 30, 2011 Share Posted March 30, 2011 (edited) 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 March 30, 2011 by JAC! Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted March 30, 2011 Author Share Posted March 30, 2011 Thanks Jac! That was even better the second time. Seriously, I appreciate your getting the ball rolling here. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted March 30, 2011 Author Share Posted March 30, 2011 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. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted March 30, 2011 Author Share Posted March 30, 2011 OK: First one answered: ORG adr, adr2 assembles at adr, but sets binary file header to adr2. Quote Link to comment Share on other sites More sharing options...
tebe Posted April 15, 2011 Share Posted April 15, 2011 (edited) .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 April 15, 2011 by tebe Quote Link to comment Share on other sites More sharing options...
+JAC! Posted April 15, 2011 Share Posted April 15, 2011 This is cool! Available as of which MADS version? Quote Link to comment Share on other sites More sharing options...
+JAC! Posted May 4, 2011 Share Posted May 4, 2011 This is cool! Available as of which MADS version? Quote Link to comment Share on other sites More sharing options...
tebe Posted May 5, 2011 Share Posted May 5, 2011 this is old feature Quote Link to comment Share on other sites More sharing options...
+JAC! Posted June 15, 2011 Share Posted June 15, 2011 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. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted June 17, 2011 Author Share Posted June 17, 2011 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. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted June 17, 2011 Author Share Posted June 17, 2011 (edited) In the meantime, here's a new translation of the MADS docs for version 1.9.2, covering .SEGDEF and other features not covered in the last translation I uploaded: MADS 1.9.2 English Documentation.txt Edited June 17, 2011 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
+JAC! Posted June 17, 2011 Share Posted June 17, 2011 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! Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted June 17, 2011 Author Share Posted June 17, 2011 (edited) 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 June 17, 2011 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
+JAC! Posted June 17, 2011 Share Posted June 17, 2011 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 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted June 17, 2011 Author Share Posted June 17, 2011 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 Quote Link to comment Share on other sites More sharing options...
+JAC! Posted June 18, 2011 Share Posted June 18, 2011 "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. Quote Link to comment Share on other sites More sharing options...
snicklin Posted July 15, 2011 Share Posted July 15, 2011 Why don't you all post on here? http://wiki.strotmann.de/wiki/ It may be easier to structure. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted August 26, 2011 Author Share Posted August 26, 2011 I finally got around to putting the .PROC tags in the GUI source code last night following a massive re-write and the collapsible navigation pane in WUDSN is just astounding. Two amazing development tools. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted April 10, 2012 Author Share Posted April 10, 2012 The .PROC wrappers don't seem to work if the source is for a relocatable SDX application. Slightly disappointing, but not a huge problem. Is this intentional? Quote Link to comment Share on other sites More sharing options...
phaeron Posted April 25, 2012 Share Posted April 25, 2012 Does anyone know how to re-enable the Source: markers in the listing file? These used to be emitted with MADS 1.9.0, but they are missing with 1.9.3 and this breaks Altirra's source-level debugging. Quote Link to comment Share on other sites More sharing options...
+JAC! Posted April 25, 2012 Share Posted April 25, 2012 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 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted April 25, 2012 Author Share Posted April 25, 2012 (edited) 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 April 25, 2012 by flashjazzcat 1 Quote Link to comment Share on other sites More sharing options...
phaeron Posted April 26, 2012 Share Posted April 26, 2012 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.