Jump to content
IGNORED

Assemble from MADS directly into an ATR image


DjayBee

Recommended Posts

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.

 

  1. 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.
     
  2. 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.
     
  3. 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 by DjayBee
  • Like 3
  • Thanks 1
Link to comment
Share on other sites

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.

  • Like 2
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

 

6 hours ago, DjayBee said:
  1. 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?

Link to comment
Share on other sites

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 by pps
  • Like 1
Link to comment
Share on other sites

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 :)

Link to comment
Share on other sites

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 by DjayBee
  • Like 1
Link to comment
Share on other sites

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

  • Like 2
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...