+DjayBee Posted December 25, 2022 Share Posted December 25, 2022 (edited) In another thread @Ecernosoft asked for a way to write directly from assembly to a disk image and @xxl found the idea a good one. Here is my take on it. The below code is for MADS and creates a full ATR image with all headers and a dummy directory for DOS 2.x when assembled. You only need to rename the file from *.XEX to *.ATR. Please remember that the Atari can only boot up to 255 sectors which translates to 32634 bytes. If somebody knows a directive for MADS which allows to define a different file extension, please let us know. There are a few constraints in doing so which I guess are the same if you build for ROMs. The code must be one continuous block because the boot process loads all sectors into continuous memory space. You cannot have any "ORG" or "*=*+x" inside. For the same reason you may not define memory locations inside your code block without initializing them. Don't use ".DS 10" but instead use ":10 .BYTE $00" which will insert ten bytes of $00 instead of only allocationg space. Don't unse ".ALIGN $80" which will only reserve bytes but ".ALIGN $80, $00" which will insert as many $00 bytes as needed. After the OS has loaded the boot data, it will unconditionally JSR to the 7th byte of the loaded code. If you do not have your initialization code in this place, you either have to insert a JMP to your INIT or (if you have no initialization at all) a plain RTS before your code (see the commented lines in my source). An addition to 1. and 2. above: If you have larger areas of memory which are populated at run-time, you can have "ORG" and ".DS" outside the loaded code. I did this in my example after EODISK for the copied character set data. You can also have it at the beginning before "my" ORG but then you must move "OPT h-" to right behind your first added ORG directive. (I did not try this but it should work.) asm2atr.asm asm2atr.atr CODEST EQU $4000 ; start of program code ; Start of code minus size of boot-header minus size of ATR-header ORG CODEST-6-16 ; directive to only create code and not create any XEX-headers OPT h- ; ATR Header for SD disk 90K DTA $96,$02,$80,$16,$80 :11 DTA $00 ; boot header HDR .BYTE $00 ; BFLAG: Boot flag equals zero (unused) .BYTE [BOOTEND+127-HDR]/128 ; BRCNT: Number of consecutive sectors to read .WORD HDR ; BLDADR: Boot sector load address ($3FFA) .WORD RUN ; RUN address (called after RTS from INIT) ; The OS will unconditionally JSR to here after the boot process INIT: ; Uncomment in case you do not have any initialization code ; RTS ; Uncomment in case your initialization code is not right at the beginning ; JMP myINIT ; CODEST: points to here ; START of example program - REPLACE with your code LDX $2f4 INX STX $cc LDY #0 STY $cb chloop LDA ($cb),y STA chset+$100,y INY BNE chloop LDY #7 aloop LDA tree,y STA chset+$108,y DEY BPL aloop LDA #>chset STA $2f4 LDA #<dlist STA $230 LDA #>dlist STA $231 RTS tree .BYTE %00000000 .BYTE %00001000 .BYTE %00011100 .BYTE %00111110 .BYTE %01111111 .BYTE %00001000 .BYTE %00001000 .BYTE %00000000 dlist .BYTE $70,$70,$70,$70,$70 .BYTE $47 .WORD screen .BYTE $41 .WORD dlist screen .BYTE " MERRY XMAS " ; The OS will JMP to here after the RTS from INIT above RUN: LDX #0 dlloop STX $d40a STX $d016 DEX JMP dlloop ; END of example program - REPLACED by your code BOOTEND: PGEND = * ; ================================================================= ; VTOC and Directory ; ; $10 is the added ATR-header :($B390-*+HDR-$10) DTA $00 VTOCSTA: DTA $02,$BD,$02 VTOCEND: ; Fill the remaining bytes of the VTOC sector :($80+VTOCSTA-VTOCEND) DTA $00 DIRSTA: DTA $60,$00,$00,$00,$00,C"***********" DTA $60,$00,$00,$00,$00,C"This text " DTA $60,$00,$00,$00,$00,C"will show " DTA $60,$00,$00,$00,$00,C"up as DOS 2" DTA $60,$00,$00,$00,$00,C"directory. " DTA $60,$00,$00,$00,$00,C" ---- " DTA $60,$00,$00,$00,$00,C"maximum " DTA $60,$00,$00,$00,$00,C"64 lines " DTA $60,$00,$00,$00,$00,C"***********" DTA $C0 DIREND: ; Fill the remaining sectors of the directory :($400+DIRSTA-DIREND) DTA $00 ; Sectors behind directory :($80*352) DTA $00 EODISK: ; END of disk image ; from here on NO MORE data but only definitions, if needed ORG $1000 chset .DS $200 END Edited December 25, 2022 by DjayBee 3 1 Quote Link to comment Share on other sites More sharing options...
Rybags Posted December 25, 2022 Share Posted December 25, 2022 Just as you create a file with ATR header followed by raw disk data, you could equally create it with a stage 1 loader which bypasses the 256 sector boot limit. Or better still do it as a binary loader and you could have the XEX appended as raw data following it. But... in the modern day it's usually desirable to just have an XEX file and let the end user decide what to do with it. Many good modern day addons such as the IDE expansions and carts like AVG and SIDE have menu loaders built in that work on standard disks with files contained within. 2 Quote Link to comment Share on other sites More sharing options...
+DjayBee Posted December 25, 2022 Author Share Posted December 25, 2022 All this is true but it beats Ecernosoft's idea to have no touch point with the OS and have one code for 5200 and 8-Bit. It also beats my use-case where I patched/adapted Michael Sternberg's FujiNet NOS to run SynCalc. NOS must be a boot disk and I had to assemble quite often and had no intention to manually add the boot header after each iteration. In the end a script can do what I did as well. Quote Link to comment Share on other sites More sharing options...
ggn Posted December 25, 2022 Share Posted December 25, 2022 6 hours ago, DjayBee said: For the same reason you may not define memory locations inside your code block without initializing them. Don't use ".DS 10" but instead use ":10 .BYTE $00" which will insert ten bytes of $00 instead of only allocationg space. Don't unse ".ALIGN $80" which will only reserve bytes but ".ALIGN $80, $00" which will insert as many $00 bytes as needed. If I may ask: What does happen if you add a .ds statement in the middle of your source? Does the assembler force a new segment there and skips the area you .ds? Quote Link to comment Share on other sites More sharing options...
pps Posted December 25, 2022 Share Posted December 25, 2022 (edited) 35 minutes ago, ggn said: If I may ask: What does happen if you add a .ds statement in the middle of your source? Does the assembler force a new segment there and skips the area you .ds? .DS is for reserving space, but it will be untouched by assembler. So a real hole in your code will be there. You may have to clean that space, to be sure that there is no garbage of old code in memory. .ds 10 is almost same as .he 00 00 00 00 00 00 00 00 00 00 or :10 .he 00 But with the difference, that you don't really know, if space reserved with .ds is really at zero. Edited December 25, 2022 by pps 1 Quote Link to comment Share on other sites More sharing options...
ggn Posted December 25, 2022 Share Posted December 25, 2022 52 minutes ago, pps said: .DS is for reserving space, but it will be untouched by assembler. So a real hole in your code will be there. You may have to clean that space, to be sure that there is no garbage of old code in memory. .ds 10 is almost same as .he 00 00 00 00 00 00 00 00 00 00 or :10 .he 00 But with the difference, that you don't really know, if space reserved with .ds is really at zero. Thanks. I'm just wondering what happens in the case of creating a .xex (.com) file. In order for what you and @DjayBee to happen is for the assembler to force a new segment when encountering .ds statements, some bytes would have to be written. I guess I should just stop being lazy and try it out for myself! The reason I'm asking is that I do maintain an assembler with XEX support (http://rmac.is-slick.com), so at the off chance someone wants to use it I should make sure that its behaviour is what the standard is for Atari 800 assemblers Quote Link to comment Share on other sites More sharing options...
+DjayBee Posted December 25, 2022 Author Share Posted December 25, 2022 (edited) 2 hours ago, ggn said: If I may ask: What does happen if you add a .ds statement in the middle of your source? Does the assembler force a new segment there and skips the area you .ds? You may. I can only speak for MADS but guess thatt other assemblers will do it the same way. If you assemble to a XEX, it is exactly as you suppose: It creates a new segment which begins with the first initialzed byte following the .DS(s). If you assemble with "OPT h-", all labels etc. will be correct but the code written out just skips these bytes. Thus everything following the .DS ends up in the wrong place. ORG $1000 .BYTE 1,2,3 .DS 1 .BYTE 4,5,6 As XEX: $FF $FF $00 $10 $02 $01 $01 $02 $03 $FF $FF $04 $10 $06 $10 $04 $05 $06 With OPT h- the .DS-byte ist just missing: $01 $02 $03 $04 $05 $06 Edited December 25, 2022 by DjayBee 1 Quote Link to comment Share on other sites More sharing options...
ggn Posted December 25, 2022 Share Posted December 25, 2022 Ok, thanks for the reply. It seems that switch h- is useful for creating a single blob of code assembled at a fixed address, so: all good! (rmac does this using the -fr switch: http://rmac.is-slick.com/manual/rmac.html#the-command-line but it disallows using more than one contiguous segment) Quote Link to comment Share on other sites More sharing options...
pps Posted December 26, 2022 Share Posted December 26, 2022 10 hours ago, ggn said: Thanks. I'm just wondering what happens in the case of creating a .xex (.com) file. In order for what you and @DjayBee to happen is for the assembler to force a new segment when encountering .ds statements, some bytes would have to be written. I guess I should just stop being lazy and try it out for myself! The reason I'm asking is that I do maintain an assembler with XEX support (http://rmac.is-slick.com), so at the off chance someone wants to use it I should make sure that its behaviour is what the standard is for Atari 800 assemblers Cool. Another option to code for our beloved machines And you can code for 6502, 68k and JAG with that one assembler - one asm to rule them all 😁 I will definetly have a look into it. Nice idea on website, too 2 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.