Grevle Posted July 18, 2016 Share Posted July 18, 2016 Variable subroutines,I wonder if this is something that is common in mac65 assembler, And how its done, to show what i mean heres a example in Basic: 50 Gosub X So it will gosub the value that is stored in X, the value in X can be changed when needed so that the subroutine can reach different places in the program from the same line 50 Gosub X. How is this done in assembler ? and it is a normal practis to use this kind of feature ? Maybe it something like this ? JSR VARIABLE So it will JSR whatever value is in the VARIABLE Equate ? but then how to change that Varable ? Do i need the exact memory adress for the program line to put in the VARIABLE Equate ? The Atasm compiler shows the memory adresses for the program lines, but when editing the assembler program these adresses can easily change making this very cumbersome when programming. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted July 18, 2016 Share Posted July 18, 2016 Common method is to push the subroutine address minus one (MSB first) onto the stack then RTS. You can have a look up table of addresses and index them with the X or Y registers depending on some condition. LDX INDEX LDA ADDRESSHI,X PHA LDA ADDRESSLO,X PHA RTS ... ADDRESSLO .BYTE <ADDR1-1, <ADDR2-1, ... ADDRESSLO .BYTE >ADDR1-1, >ADDR2-1, ... Quote Link to comment Share on other sites More sharing options...
mono Posted July 19, 2016 Share Posted July 19, 2016 Another method is using indirect jump: lda tabl,x sta jpad lda tabh,x sta jpad+1 jmp (jpad) tabl: .byte <proc1 .byte <proc2 tabh: .byte >proc1 .byte >proc2 or selfmodifying code: lda tabl,x sta jpad lda tabh,x sta jpad+1 jpad = *+1 jmp $ffff The last one must be placed in RAM of course. 1 Quote Link to comment Share on other sites More sharing options...
Grevle Posted July 19, 2016 Author Share Posted July 19, 2016 Thank you. I think the indirect jump is easiest for me to understand. So it can use JSR (JPAD) instead of JMP (JPAD) ? should work equally well ? Quote Link to comment Share on other sites More sharing options...
Rybags Posted July 19, 2016 Share Posted July 19, 2016 (edited) They forgot to put a JSR(ind) instruction into the original 6502 design. So you have to implement it as previously illustrated. The pushing <address - 1> onto the stack method has the advantage of not needing you to reserve the temporary vector in memory. Of course another alternate could be to use self-modifying code so rather than maintain a vector you just alter the operand of a JMP instruction. For either method, it's probably a good idea to do bounds checking on the parameter just to make sure you don't jump to some random location. Edited July 19, 2016 by Rybags Quote Link to comment Share on other sites More sharing options...
sup8pdct Posted July 19, 2016 Share Posted July 19, 2016 The indirect JMP must never have the data starting on the last byte of a page. ie JMP ($xxFF) Lets say location is at $30FF The low byte will come from 30FF but high byte will come from $3000. James Quote Link to comment Share on other sites More sharing options...
mono Posted July 19, 2016 Share Posted July 19, 2016 Thank you. I think the indirect jump is easiest for me to understand. So it can use JSR (JPAD) instead of JMP (JPAD) ? should work equally well ? As they wrote earlier - there is no jsr (ind), but in self-modifying code you can use jsr $ffff. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted July 19, 2016 Share Posted July 19, 2016 (edited) If you want to use an indirect jump, put it in a subroutine so that the called procedure will fall back through: jsr IndirectJSR <continues here when Routine1 exits> ... IndirectJSR jmp (address) ... Routine1 <code> rts Edited July 19, 2016 by flashjazzcat 1 Quote Link to comment Share on other sites More sharing options...
576XE Posted August 1, 2016 Share Posted August 1, 2016 Is there a way to automatically setup origin of program to content of lomem? Quote Link to comment Share on other sites More sharing options...
pirx Posted August 1, 2016 Share Posted August 1, 2016 only in SpartaDosX Quote Link to comment Share on other sites More sharing options...
sanny Posted August 1, 2016 Share Posted August 1, 2016 ...with special SpartaDOS programs Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted August 1, 2016 Share Posted August 1, 2016 (edited) Or you can write your own on-board relocation module as found in many resident drivers (Z: handler driver for SpartaDOS 3.x being a good example; source code is in the ICD RTime-8 manual). Edited August 1, 2016 by flashjazzcat 1 Quote Link to comment Share on other sites More sharing options...
Rybags Posted August 1, 2016 Share Posted August 1, 2016 The XL OS has provision for relocatable handlers though I think the documentation is a bit thin. Not sure it could be used on general programs though. 1 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted August 1, 2016 Share Posted August 1, 2016 There's a pretty good description of relocatable handlers in Avery's Altirra Hardware manual. Quote Link to comment Share on other sites More sharing options...
576XE Posted August 1, 2016 Share Posted August 1, 2016 Thank you friends Quote Link to comment Share on other sites More sharing options...
phaeron Posted August 2, 2016 Share Posted August 2, 2016 As far as I know, there is no way to get to the built-in relocatable handler on the 1200XL or 800XL OS as it has no public vector and is invoked only by the SIO-based loader. The only way you can get to it is by creating an SIO device that can push such a handler or emulating one through a PBI device. I don't know if any exist; the only way I was able to test my own implementation was to create an emulated device for it in Altirra. On top of that, the peripheral handler loader is one of the first things people rip out when they're looking for space in the OS ROM, and it uses a weird format that no assembler generates. I don't recommend trying to use it. If you want to make your own relocatable executable, it's easiest to either use a toolchain already set up to generate them and with a relocator already written (ca65/ld65), or assemble your executable twice at two different addresses and generate only high-byte relocations. Relocating only by whole page avoids a lot of headaches; it's easier to generate, easier to relocate, and you don't have to worry about JMP (abs) blowing up because MEMLO happened to be at an odd address. 2 Quote Link to comment Share on other sites More sharing options...
576XE Posted August 4, 2016 Share Posted August 4, 2016 It seems to me that I asked a question not clearly enough... I'm learning MAE macroassembler now and found in manual .MC adr pseudo-operator .MC adr Move Code to a different address than the .OR assembly origin. If you are assembling to RAM, your code will be stored starting at the address after the .MC pseudo-op. When assembling to disk, the .MC address will be used when creating the binary file headers, affecting where the code will be loaded into. Then I've thought about the ability to extract memlo data while assembling by means of assembler itself and use this data as an address part of .MC pseudo-op before runtime period. Another sorry for my Google translator Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted August 4, 2016 Share Posted August 4, 2016 Since you can't know what MEMLO will be when the program is run, you might as well pick a safe load address (e.g. $2000) use that as the origin (".OR"). Loading code at a different address to the run address is useful mainly when it's not possible to load code at the address it will execute. For example, TBXL has code segments which load in RAM (at the ".MC" address) and are moved under the OS before execution (at the ".OR" address). But in that case, both addresses are known at compile time and will not change at run time. 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.