kaneda23 Posted January 18, 2007 Share Posted January 18, 2007 I wish to use DASM on my Mac to create an executable that I can load directly on Atari800MacX. Can someone explain (in the most simplest terms) how to do this? I understand that there is some sort of header that I need to assemble into the binary file, but am not sure how to do this. Quote Link to comment Share on other sites More sharing options...
pps Posted January 19, 2007 Share Posted January 19, 2007 (edited) I don´t use this xass, cause I got no MAC, but here a little help with fileheader. First two bytes has to be $FF then comes (low/high) the address, where to load the file and then the end address (low/high), then all data bytes. e.g. if a programme loads into page six and has a length of 84 Bytes: $FF $FF $00 $06 $53 $06 .PROGRAMME DATA If no other way exists, you can compile your programme, so you know, how long it´ll be, then add the needed bytes to your sourcecode and compile it again. If you want the programme to automaticly get startet after loading, at the end of file must be a routine, that sets the startaddress into $02E0 Vector e.g. if programme starts at $2000: .PROGRAMME DATA $E0 $02 $E1 $02 $00 $20 Edited January 19, 2007 by pps Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted January 19, 2007 Share Posted January 19, 2007 I don´t use this xass, cause I got no MAC, but here a little help with fileheader. First two bytes has to be $FF then comes (low/high) the address, where to load the file and then the end address (low/high), then all data bytes. e.g. if a programme loads into page six and has a length of 84 Bytes: $FF $FF $00 $06 $53 $06 .PROGRAMME DATA If no other way exists, you can compile your programme, so you know, how long it´ll be, then add the needed bytes to your sourcecode and compile it again. If you want the programme to automaticly get startet after loading, at the end of file must be a routine, that sets the startaddress into $02E0 Vector e.g. if programme starts at $2000: .PROGRAMME DATA $E0 $02 $E1 $02 $00 $20 Seems like you should be able to set this up so it calculates the length after the first pass, and then sets the length during the second pass. Michael Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted January 20, 2007 Share Posted January 20, 2007 and how will you handle multiple segments with DASM? Quote Link to comment Share on other sites More sharing options...
Urchlay Posted February 11, 2007 Share Posted February 11, 2007 Here's how I do it. It's not the only way, and probably isn't the best way, but... ; Assemble this with: dasm junk.asm -f3 -ojunk.bin processor 6502 include "equates.inc" ;If you don't have an equates file, at least define RUNAD: ;RUNAD = $02E0 ; If you use an init routine, you'll need this too: ;INITAD = $02E2 LOAD_ADDR = $8000; or wherever you want org LOAD_ADDR-6; make room for 6-byte header ; 2-byte Atari executable header: byte $FF, $FF; let DOS know it's a binary load file ; start of first segment ; 4-byte segment header: word LOAD_ADDR; Load address word endbin-1; Last byte to load ; Rest of segment contains code and data org LOAD_ADDR; not really needed, guards against errors in header ; You can put data tables before the code if you want: ;YOUR_TABLE byte yourdata1, yourdata2, etc ; If you prefer, you can put subroutines before the main entry point: ;DO_NOTHING subroutine ; RTS ; Main entry point. This is where your code starts executing after it's loaded: main: lda #0 ; replace this junk ;sta whatever; with your code ; ...rest of your code/data here endbin ; end of code/data segment, start of run address segment ; 4-byte segment header: word RUNAD ; load address (loading into RUNAD lets our code run) word RUNAD+1 ; Last byte to load ; Segment data contains 2 bytes (the actual run address) word main ; the 2 bytes to stuff into RUNAD ; That's it... The example is for a simple executable with one segment full of code/data, and one containing the run address. You could easily extend this to use multiple segments, including one that loads at INITAD (which will get executed as soon as it's loaded: do an RTS to continue loading the file). There are a couple of rules to follow: - DASM requires that the origin (program counter) always increases, at least when you run it with -f3. If you're doing multiple code segments, the one with the lowest address has to come first. - For code segments after the first one, you'll want to use RORG instead of ORG, otherwise you'll end up with a non-functional mess instead of a loadable executable I haven't yet written anything with DASM that needs multiple code segments, so there might be more "gotchas" than that. The other approach to creating a multi-segment Atari exe with DASM is to assemble the file with -f2 instead of -f3. This produces an object file with a structure similar (but not identical) to an Atari exe file. You can write a program (in C, or perl, or whatever language you like) that turns this into a valid Atari file: - DASM doesn't use the $FF, $FF prefix, so you'd have to add that - Instead of storing the start and end addresses in the segment header, "DASM -f2" stores the start address and the segment length (in bytes). It would also be easy to modify DASM to output Atari exe format directly (assuming you know a little C). In -f2 mode, you'd just directly ORG your segments where you wanted them: processor 6502 include "equates.inc" org $8000 main: ; "main" is your entry point, and could be defined in any segment ; code ; code org $7000; Note: $7000 < $8000, DASM only allows this in -f2 mode ; more code/data ; whatever org RUNAD; or "org $02E0" if you don't define RUNAD = $02E0 word main You'd assemble that with "dasm file.asm -f2 -ofile.bin", then run your (hypothetical, so far) program that turns file.bin into a valid Atari load file. 1 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted March 1, 2016 Share Posted March 1, 2016 Here's how I do it. It's not the only way, and probably isn't the best way, but... ; Assemble this with: dasm junk.asm -f3 -ojunk.bin processor 6502 include "equates.inc" ;If you don't have an equates file, at least define RUNAD: ;RUNAD = $02E0 ; If you use an init routine, you'll need this too: ;INITAD = $02E2 LOAD_ADDR = $8000; or wherever you want org LOAD_ADDR-6; make room for 6-byte header ; 2-byte Atari executable header: byte $FF, $FF; let DOS know it's a binary load file ; start of first segment ; 4-byte segment header: word LOAD_ADDR; Load address word endbin-1; Last byte to load ; Rest of segment contains code and data org LOAD_ADDR; not really needed, guards against errors in header ; You can put data tables before the code if you want: ;YOUR_TABLE byte yourdata1, yourdata2, etc ; If you prefer, you can put subroutines before the main entry point: ;DO_NOTHING subroutine ; RTS ; Main entry point. This is where your code starts executing after it's loaded: main: lda #0 ; replace this junk ;sta whatever; with your code ; ...rest of your code/data here endbin ; end of code/data segment, start of run address segment ; 4-byte segment header: word RUNAD ; load address (loading into RUNAD lets our code run) word RUNAD+1 ; Last byte to load ; Segment data contains 2 bytes (the actual run address) word main ; the 2 bytes to stuff into RUNAD ; That's it... The example is for a simple executable with one segment full of code/data, and one containing the run address. You could easily extend this to use multiple segments, including one that loads at INITAD (which will get executed as soon as it's loaded: do an RTS to continue loading the file). There are a couple of rules to follow: - DASM requires that the origin (program counter) always increases, at least when you run it with -f3. If you're doing multiple code segments, the one with the lowest address has to come first. - For code segments after the first one, you'll want to use RORG instead of ORG, otherwise you'll end up with a non-functional mess instead of a loadable executable I haven't yet written anything with DASM that needs multiple code segments, so there might be more "gotchas" than that. The other approach to creating a multi-segment Atari exe with DASM is to assemble the file with -f2 instead of -f3. This produces an object file with a structure similar (but not identical) to an Atari exe file. You can write a program (in C, or perl, or whatever language you like) that turns this into a valid Atari file: - DASM doesn't use the $FF, $FF prefix, so you'd have to add that - Instead of storing the start and end addresses in the segment header, "DASM -f2" stores the start address and the segment length (in bytes). It would also be easy to modify DASM to output Atari exe format directly (assuming you know a little C). In -f2 mode, you'd just directly ORG your segments where you wanted them: processor 6502 include "equates.inc" org $8000 main: ; "main" is your entry point, and could be defined in any segment ; code ; code org $7000; Note: $7000 < $8000, DASM only allows this in -f2 mode ; more code/data ; whatever org RUNAD; or "org $02E0" if you don't define RUNAD = $02E0 word main You'd assemble that with "dasm file.asm -f2 -ofile.bin", then run your (hypothetical, so far) program that turns file.bin into a valid Atari load file. Where can I find the equates.inc include for dasm, and do you still have to transform the .bin (from the first -f3 example) into a valid Atari load file? Quote Link to comment Share on other sites More sharing options...
Urchlay Posted March 2, 2016 Share Posted March 2, 2016 Where can I find the equates.inc include for dasm, and do you still have to transform the .bin (from the first -f3 example) into a valid Atari load file? Wow, old post... long time since I've been on Atariage. The -f3 example produces a valid Atari executable, no need to transform it. I originally was going to submit the equates.inc file to the dasm maintainer, but that never happened... there's a copy here: http://urchlay.naptime.net/~urchlay/src/equates.inc I've since pretty much completely switched to using ca65 (from the cc65 suite) instead of dasm, but that equates.inc file works for ca65 also. 1 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted March 2, 2016 Share Posted March 2, 2016 Wow, old post... long time since I've been on Atariage. The -f3 example produces a valid Atari executable, no need to transform it. I originally was going to submit the equates.inc file to the dasm maintainer, but that never happened... there's a copy here: http://urchlay.naptime.net/~urchlay/src/equates.inc I've since pretty much completely switched to using ca65 (from the cc65 suite) instead of dasm, but that equates.inc file works for ca65 also. Awesome! Thanks Urchlay This is a big file - 53k compared to the 10k include vcs.h for the VCS. Do you know of an include file like this for the 5200 or are most of the addresses the same? Quote Link to comment Share on other sites More sharing options...
Urchlay Posted March 3, 2016 Share Posted March 3, 2016 Awesome! Thanks Urchlay This is a big file - 53k compared to the 10k include vcs.h for the VCS. Do you know of an include file like this for the 5200 or are most of the addresses the same? Nah, the addresses for 5200 are different, and there aren't so many of them. You might check the atari5200.inc that ships with cc65. Here's a copy: https://raw.githubusercontent.com/cc65/cc65/master/asminc/atari5200.inc It .includes a few other files, which can be found in the same directory. Edit the URL, or check out the source from git, or install cc65 on your system... vcs.h is 10K now? 10-12 years ago it was around 2K... nothing's immune from software bloat it seems. 1 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted March 3, 2016 Share Posted March 3, 2016 Nah, the addresses for 5200 are different, and there aren't so many of them. You might check the atari5200.inc that ships with cc65. Here's a copy: https://raw.githubusercontent.com/cc65/cc65/master/asminc/atari5200.inc It .includes a few other files, which can be found in the same directory. Edit the URL, or check out the source from git, or install cc65 on your system... vcs.h is 10K now? 10-12 years ago it was around 2K... nothing's immune from software bloat it seems. Thanks! Yes the vcs.h I have is 10K but looking at it I'd say it's at least 70% comments so probably not too different. Where are RSYNC, WSYNC, VSYNC and timers like TIM1T for CTIA? Having a blast playing with display lists, need to read alot more about them to understand how they work. I don't think I'll need to use CTIA directly but I still want to know it's mapping, maybe there is a seperate CTIA/GTIA include? 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.