Ich hatte das vor drei Monaten mal gemacht um das FujiNet NOS anzupassen und den Code jetzt mit einem Beispiel zusammengepackt.
Vielleicht kann es ja jemand hier gebrauchen.
Wie schon geschrieben, ist der Code für MADS, sollte aber für jeden Assembler anpassbar sein, dem man das Erzeugen von XEX-Headern abgewöhnen kann und der sinnvoll rechnen kann (Integer Division und Modulo).
Die von MADS erstellte Datei heißt immer *.XEX und muss noch in *.ATR umbenannt werden. (Vielleicht kennt jemand eine Direktive, die beliebige Extensions zulässt.)
Da der Atari Bootvorgang nur ein Byte für die Sektorzahl vorsieht (1-255) und davon noch sechs Byte für den Bootheader abgehen, verbleiben maximal 32634 Bytes für euch.
Die Geschichte hat auch ein paar Randbedingungen, die vermutlich analog zu denen sind, die beim Bau von ROMs auch gelten:
- Euer Code muss an einem Stück sein weil der Bootlader alle Sektoren in einen zusammenhängenden Speicherbereich lädt.
Ihr könnt also kein "ORG" oder "*=*+x" innerhalb des zu ladenden Programmcodes verwenden. - Aus demselben Grund dürft ihr keine Speicherbereiche nur definieren, sondern müsst sie mit einem (ggf. Dummy) Wert initialisieren.
".DS 10" geht z.B. nicht. Ihr müsst dafür ":10 .BYTE $00" verwenden, weil dann die entsprechende Anzahl an $00-Bytes eingefügt wird, anstatt nur den Programmzähler hochzuzählen. - Wenn das OS den Bootcode geladen hat, macht es zwingend einen JSR zum 7. Byte des geladenen Codes.
Wenn euer Programm dort keinen Init-Code hat, müsst ihr dort entweder einen JMP zu eurem Init-Code einbauen oder ein RTS falls ihr gar keinen Init-Code habt. (Siehe auskommentierte Zeilen in meiner Source.)
Anmerkung zu 1. und 2.:
Wenn zusätzlicher Speicher erst zur Laufzeit befüllt wird, kann dieser durchaus mit weiteren ORGs und .DS definiert werden, nur muss das außerhalb des geladenen Bereichs passieren.
In meinem Beispiel habe ich einen Block hinter EODISK eingefügt um den veränderten Zeichensatz abzulegen.
Es sollte auch direkt am Anfang vor "meinem" ORG möglich sein. Dann müsst ihr zusätzlich das "OPT h-" so verschieben, dass es direkt hinter dem ersten ORG steht. (Getestet habe ich das aber nicht.)
Code: Alles auswählen
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