From 91b69e62bc9575d313f0e30989bf1f004e830b74 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Wed, 1 May 2024 04:34:38 -0400 Subject: xex(5): add examples. --- xex.5 | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- xex.rst | 110 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 263 insertions(+), 1 deletion(-) diff --git a/xex.5 b/xex.5 index b46b2fb..2d38286 100644 --- a/xex.5 +++ b/xex.5 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "XEX" 5 "2024-04-30" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "XEX" 5 "2024-05-01" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME xex \- Atari 8-bit executable file format. .\" RST source for xex(5) man page. Convert with: @@ -102,7 +102,159 @@ exit. .sp The run address segment is the one that loads the 2\-byte run address into address \fB$02E0\fP, aka \fBRUNAD\fP\&. +.SS Raw Data Blocks +.sp +When init code runs, the file is still being loaded. It\(aqs open on IOCB +#1, and the init code can read some or all of the rest of the file +itself, before returning to DOS. The part of the file read by an init +segment doesn\(aqt have to conform to the regular XEX file structure, so +they\(aqre referred to here as raw data blocks. +.sp +Raw data blocks usually occur in files created with "packer" or +"compressor" programs, or occasionally in other large programs (Turbo +BASIC is an example). Raw data blocks are generally found just after +an init address segment. If you have an executable that loads just +fine on a real Atari or emulator, but fails with \fBxexcat\fP and +\fBxexamine\fP, a raw data block is usually the reason why. +.sp +Files with raw data blocks also can\(aqt be loaded by simple bootloaders +such as Fenders 3\-sector loader. .SH EXAMPLES +.SS Assembly +.sp +Here is a simple assembly language program that changes the background +of the GRAPHICS 0 text screen to black, and the text to high\-intensity white: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +1000 *= $0600 +1010 START +1020 LDA #0 +1030 STA 710 +1040 LDA #$0F +1050 STA 709 +1060 RTS +2000 *= $02E0 ; AKA RUNAD +2010 .WORD START +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To assemble this with either Atari\(aqs Assembler/Editor or OSS Mac/65, +the command is: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ASM ,,#D:COLORS.XEX +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This will create a binary file that looks like this: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +offset 0: FF FF 00 06 0A 06 A9 00 +offset 8: 8D C6 02 A9 0F 8D C5 02 +offset 16: 60 E0 02 E1 02 00 06 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This is a complete (though short) XEX file, and it can be loaded from +the DOS menu (or D1: prompt, if you use a command\-line\-based DOS). +.sp +The first 2 bytes ($FF, $FF) are the signature for the initial +segment header. +.sp +The next 2 bytes ($00, $06) are the load address of the first segment +($0600, in 6502\-style LSB\-first notation). +.sp +The next 2 bytes ($0A, $06) are the end address ($060A). +.sp +Since the header says to load data from $0600 to $060A, there are 11 +data bytes in the segment, beginning with $A9, $00 (the 6502 object +code for the \fILDA #0\fP instruction), and extending to the $60 (RTS +opcode) at offset 16. +.sp +The data from the first segment is immediately followed by the header +of the next segment, at offset 17. A $FF, $FF signature would be allowed +here, but in the example, the 2nd segment uses the 4\-byte header. +.sp +At offset 17, the $E0, $02 (aka $02E0) is the load address. $E1, $02 +($02E1) is the end address. $02E0/$02E1 is known as \fIRUNAD\fP in the +Atari world, and it\(aqs the address where DOS will find the entry point +to the program when it\(aqs done being loaded. +.sp +The next (and last) 2 bytes are $00, $06 (aka $0600), which is the run +address itself (to be deposited at \fIRUNAD\fP). +.sp +There are no more segments, since we\(aqve reached end of file. +.SS Data Only +.sp +Since a XEX file can load arbitrary data at arbitrary addresses, there\(aqs +simpler way to accomplish the color changes. Instead of writing code to +do the job, we just create a XEX file that loads the colors we want +directly into the color shadow registers. +.sp +In BASIC, you\(aqd say: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +POKE 709,15 +POKE 710,0 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\&...but BASIC doesn\(aqt have an easy way to create a XEX file. +An assembler is a more convenient tool. The code is: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +1000 *= $02C5 +1010 .BYTE $0F,$00 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The binary looks like this: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ff ff C5 02 C6 02 0F 00 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The file begins with $FF, $FF header, then the 2\-byte load address +($C5, $02 for address $02C5), then the 2\-byte end address ($C6, $02, +aka $02C6), then the 2 bytes of data to be stored there ($0F, $00). +.sp +When loaded, this will store $0F at address $02C5 (aka \fICOLOR0\fP, +the text luminance in \fIGRAPHICS 0\fP) and $00 at $02C6 (\fICOLOR1\fP, the +\fIGRAPHICS 0\fP background color). +.sp +Notice that there\(aqs no run or init address. That\(aqs because no code is +executed; it\(aqs just 2 bytes of raw data. .SH HISTORY .sp The first Atari 8\-bit binary load format was defined by Atari DOS 1.0, diff --git a/xex.rst b/xex.rst index 8f77f6e..39d32d9 100644 --- a/xex.rst +++ b/xex.rst @@ -80,9 +80,119 @@ exit. The run address segment is the one that loads the 2-byte run address into address **$02E0**, aka **RUNAD**. +Raw Data Blocks +--------------- + +When init code runs, the file is still being loaded. It's open on IOCB +#1, and the init code can read some or all of the rest of the file +itself, before returning to DOS. The part of the file read by an init +segment doesn't have to conform to the regular XEX file structure, so +they're referred to here as raw data blocks. + +Raw data blocks usually occur in files created with "packer" or +"compressor" programs, or occasionally in other large programs (Turbo +BASIC is an example). Raw data blocks are generally found just after +an init address segment. If you have an executable that loads just +fine on a real Atari or emulator, but fails with **xexcat** and +**xexamine**, a raw data block is usually the reason why. + +Files with raw data blocks also can't be loaded by simple bootloaders +such as Fenders 3-sector loader. + EXAMPLES ======== +Assembly +--------- + +Here is a simple assembly language program that changes the background +of the GRAPHICS 0 text screen to black, and the text to high-intensity white:: + + 1000 *= $0600 + 1010 START + 1020 LDA #0 + 1030 STA 710 + 1040 LDA #$0F + 1050 STA 709 + 1060 RTS + 2000 *= $02E0 ; AKA RUNAD + 2010 .WORD START + +To assemble this with either Atari's Assembler/Editor or OSS Mac/65, +the command is:: + + ASM ,,#D:COLORS.XEX + +This will create a binary file that looks like this:: + + offset 0: FF FF 00 06 0A 06 A9 00 + offset 8: 8D C6 02 A9 0F 8D C5 02 + offset 16: 60 E0 02 E1 02 00 06 + +This is a complete (though short) XEX file, and it can be loaded from +the DOS menu (or D1: prompt, if you use a command-line-based DOS). + +The first 2 bytes ($FF, $FF) are the signature for the initial +segment header. + +The next 2 bytes ($00, $06) are the load address of the first segment +($0600, in 6502-style LSB-first notation). + +The next 2 bytes ($0A, $06) are the end address ($060A). + +Since the header says to load data from $0600 to $060A, there are 11 +data bytes in the segment, beginning with $A9, $00 (the 6502 object +code for the *LDA #0* instruction), and extending to the $60 (RTS +opcode) at offset 16. + +The data from the first segment is immediately followed by the header +of the next segment, at offset 17. A $FF, $FF signature would be allowed +here, but in the example, the 2nd segment uses the 4-byte header. + +At offset 17, the $E0, $02 (aka $02E0) is the load address. $E1, $02 +($02E1) is the end address. $02E0/$02E1 is known as *RUNAD* in the +Atari world, and it's the address where DOS will find the entry point +to the program when it's done being loaded. + +The next (and last) 2 bytes are $00, $06 (aka $0600), which is the run +address itself (to be deposited at *RUNAD*). + +There are no more segments, since we've reached end of file. + +Data Only +--------- + +Since a XEX file can load arbitrary data at arbitrary addresses, there's +simpler way to accomplish the color changes. Instead of writing code to +do the job, we just create a XEX file that loads the colors we want +directly into the color shadow registers. + +In BASIC, you'd say:: + + POKE 709,15 + POKE 710,0 + +...but BASIC doesn't have an easy way to create a XEX file. +An assembler is a more convenient tool. The code is:: + + 1000 *= $02C5 + 1010 .BYTE $0F,$00 + +The binary looks like this:: + + ff ff C5 02 C6 02 0F 00 + +The file begins with $FF, $FF header, then the 2-byte load address +($C5, $02 for address $02C5), then the 2-byte end address ($C6, $02, +aka $02C6), then the 2 bytes of data to be stored there ($0F, $00). + +When loaded, this will store $0F at address $02C5 (aka *COLOR0*, +the text luminance in *GRAPHICS 0*) and $00 at $02C6 (*COLOR1*, the +*GRAPHICS 0* background color). + +Notice that there's no run or init address. That's because no code is +executed; it's just 2 bytes of raw data. + HISTORY ======= -- cgit v1.2.3