Jump to content
IGNORED

Writing ASM programs that boot from disk


Recommended Posts

I am in the process of getting back in to ASM programming after two years or more away from it. The last time around I managed finally to get a proper handle on assembler and a good foothold in order to continue experimentation to expand and improve my grasp. I never managed to learn one very basic skill though and this time around would like to get hold of it from the get-go.

 

How do you write programmes that boot themselves from disk, or even I suppose cassette or cartridge?

 

Most programming books give small routines to store within Page 6 and run from BASIC by a 'USR' command. In addition 'Atari Roots' outlines a way to save the memory contents if you have been using the "Assembler/Editor" cartridge, allowing a programme to autorun if loaded from the DOS menu. This is not really what I want however. Moreover, this is not applicable when cross-assembling on the PC using Eclipse+WUDSN and MADS - which of course results in a *.XEX file. I understand how this can in turn be booted from Altirra directly or loaded and run from the SDX commandline during emulation or on the real hardware. Nowhere yet though have I found any method to load and run a machine-language programme directly from disk - or disk image - without needing a DOS be installed in the way retail games or applications do.

 

Can anyone point me to a book or other documentation that outlines this process?

 

Off the cuff I imagine it requires a short, standalone loader to get the programme off disk and in to memory which then passes the flow of execution on to it. If this is so then how do you get that loader routine to boot?

Link to comment
Share on other sites

The documentation that defines this process is spread across a variety of documents. You'll want:

 

The Atari 400/800 Hardware Manual:

http://www.atarimania.com/documents/atari-400-800-hardware-manual.pdf

 

Mapping the Atari:

http://www.atariarchives.org/mapping/

 

and the Atari 400/800 OS source manual:

http://www.atarimania.com/documents/atari-400-800-operating-system-source-listing.pdf

 

and most importantly, Inside Atari DOS, Specifically chapter 20, the boot process:

http://www.atariarchives.org/iad/chapter20.php

 

In order to do this, you will need to figure out:

* How to write raw sectors to the disk using the built in SIOV in the OS.

* How to read sectors from the disk, also using SIOV.

* The contents of the three boot sectors, where they are loaded, and how DOSVEC is set.

* How to assemble parts of your program into memory

* Writing a routine that can be called to read memory and write what you've assembled, into sectors on the disk, again using SIOV.

* Booting the resulting disk after you've written the sectors to verify that it is correct.

 

In other words, you'll need to write your own little routines to lay out the sectors on the disk as is needed to be able to boot. Usually, the OS boot loader loads a small chunk of code from the boot sector, which instructs how to load the rest of the program (which you'll need to write.)

 

EDIT: You'll also want to check out this thread, which contains lots of info, as well as an example chunk of assembler from JAC! to show what goes at $0700

http://atariage.com/forums/topic/207712-how-to-make-your-own-bootdisk/

 

-Thom

  • Like 2
Link to comment
Share on other sites

The authoritative reference for this is Chapter 10 of the Atari Operating System User's Manual. Only a subset of the boot sector bytes shown in Inside Atari DOS are used by the OS, specifically the first six; the rest are specific to DOS 2 and its boot sector code. The OS loads up to 255 consecutive boot sectors at a load address of your choice, and then it's your job to do the rest.

  • Like 1
Link to comment
Share on other sites

If you want a simple example, here's my two-sector standalone boot loader:

 

boot.zip

 

All it does it load a regular Atari executable. It supports INIT segments so you can have splash screens, etc. But it does NOT support RUN segments, so you must use "ini" instead of "run" for your final segment.

 

I've used variations of this loader for the disk versions of X:8, Ransack! and Bomber.

 

I found Chapter 12 of the Atari Technical Reference Manual helpful.

Edited by Xuel
  • Like 3
Link to comment
Share on other sites

Maybe this doesn't address the point for you morelenmir, but another way to get the job done is to take the standard object file of your program and feed it into a utility that will turn it into a boot disk. I guess that would be a lot easier for you if your goal is to make your own ML programs and sometimes make them into a boot disk. If the goal is to learn how to make boot disks, then you'll need to start doing some reading in the sources mentioned.

Link to comment
Share on other sites

Other than the k-file method, there is no standard utility to do it, because often if you're doing boot loaded disks, it means you want to maximize the use of the disk, make it easy to use via booting, and/or apply copy protection. It's very much a do-it-yourself affair.

 

-Thom

Link to comment
Share on other sites

I have continued to read, both from those links you chaps provided and also an old favourite of mine 'Advanced Programming Techniques for The Atari', which has a short but very clear section that covers the same ground.

 

In very basic terms it seems you can have the Atari automatically read, store in memory and then execute up to 256 bytes from a specified section of the disk when certain values are stored at very specific locations on the disk. Obviously some programmes may well fit in this small length, especially from the guys who specialize in ultra-optimized code. However, generally speaking I think the original idea is to use those 256 bytes to load a 'loader' programme in to memory and set it running which will then itself perform a longer IO job to load your main programme and pass the flow of execution to it.

 

The easiest way to do this seems to be to use IOCB commands to read the main programme data. This would work I am sure, but require that your main programme has been previously saved via DOS with a filename. If you are going to do it at this level then I guess you may as well use the 'autorun.sys' approach. A quick look with 'MakeATR' and the 'Altirra' *.ATR viewer shows very few retail game disks have standard file systems - so I dare say their data has been written 'raw', sector by sector to the disk. I wonder then if there is a way to just read raw sectors from the disk, which does not require a filename?

 

This is where SIOV comes in I think? But I thought that worked with with IOCB only...

 

Update:

A little more reading of 'Mapping The Atari' suggests to me that you use the Page 3 'DCB' commands directly, instead of through the SIOV/IOCB mechanism.

Link to comment
Share on other sites

You have the first three sectors to hold your loader code. This is how I did it for my version of a Dos:

 

; DOS BOOT LOADER
; LAST REVISED: APRIL 16, 2003
;
;
.OUTPI ALFDOS
;
; ZERO PAGE HELPS TO KEEP CODE SMALL
;
*= $43
;
SEGLEN *=*+2 CURRENT SEGMENT LENGTH
SEGADR *=*+2 SEGMENT START ADDRESS
LNKOFF *=*+1 LINK OFFSET
CUROFF *=*+1 CURRENT DATA OFFSET
HDRFLG *=*+1
;
*= $3D00
;
; SECTOR 1 LAYOUT
;
DBUF *=*+256 SECTOR BUFFER
;
; SOME FIELDS EXPORTED FOR THE XINIT/FMTDIR PROGRAMS
; ANY CHANGES TO THE S1 VARIABLES WILL REQUIRE THAT THE
; S1EQU FILE BE UPDATED FOR THE DOS ROUTINES.
;
.ENTRY S1HDR,S1FREE,S1DEN,S1VLSR
.ENTRY S1TSEC
;
S1HDR .BYTE "A" ALFDOS FLAG (@$00)
BTCNT .BYTE 3 BOOT 3 SECTORS (@$01)
BTADR .WORD S1HDR LOADED HERE (@$02)
BTINI .WORD XBCRET SIMPLE RTS (@$04)
BCONT JMP XBCONT JUMP TO BOOT CONTINUE (@$06)
S1FREE .BYTE 0,0,0 FREE SECTORS (@$09)
S1DEN .BYTE 0 BOOT DENSITY (@$0C)
S1VLSR .BYTE "AlfDOS " (@$0D)
S1FMAP .BYTE 12,0,0 FREE SECTOR HEAD (@$15)
S1UPDF .BYTE 0 (@$18)
S1BFMP .BYTE 0,0,0 BOOT FILE DATA SECTOR (@$19)
S1BFID .BYTE 0 BOOT FILE IDENTIFIER (@$1C)
S1MAGC .BYTE 0 MAGIC # (@$1D)
S1TSEC .BYTE 0,0,0 TOTAL SECTORS ON DISK (@$1E)
;
; THE BOOT PROCESS BEGINS WITH THE OS LOADING THE BOOT SECTORS
; IT LOADS BTCNT SECTORS STARTING AT ADDRESS BTADR. IN REALITY
; IT LOADS EACH SECTOR AT $0400 AND THEN MOVES IT TO THE PROPER
; ADDRESS.
;
; ONCE THE SECTORS ARE LOADED, THE OS JUST JUMPS TO BTADR+6 [bCONT].
; IN OUR CASE WE JUMP TO XBCONT, THE BOOT CONTINUATION ROUTINE. THIS
; IS WHERE WE BINARY LOAD THE SPECIFIED FILE.
;
; ON RETURN FROM XBCONT, CY = 0 MEANS SUCCESS.
; CY = 1 IS FAILURE, AND THE OS WILL ISSUE THE "BOOT ERROR" MSG.
;
; WITH A GOOD BOOT, THE OS THEN VECTORS THROUGH DOSINI. THE OS
; INITIALIZES DOSINI WITH THE BTINI ADDRESS. IT IS THE RESPONSIBILTY
; OF THE LOADED PROGRAM TO CHANGE THIS.
;
; IN OUR CASE, THE STARTUP MODULE CHANGES DOSINI TO POINT TO THE
; RESET HANDLER TO FINISH OUR INITIALIZATION.
;
; BECAUSE THE OS DOES NOT ALLOW FOR DENSITY CHANGES, WE ARE
; LIMITED TO A 3 SECTOR BOOT, IN CASE IT'S A DOUBLE DENSITY
; DISK DRIVE.
;
; VALID ADDRESS RANGE IS : $3000-$317F
; BOOT CODE MUST FIT WITHIN THIS.
;
; ON ENTRY TO XBCONT, THE SYSTEM DCB AT $0300 IS POPULATED WITH
; THE LAST BOOT SECTOR VALUES.
;
;
XBCONT LDA S1DEN IF SINGLE DENSITY
BNE XBCINI SKIP
ASL $0308 ELSE UPDATE TO 256 BYTE SECTOR
ROL $0309
LDX #$FC DD LINK OFFSET
.BYTE $2C
XBCINI LDX #$7C SD/ED LINK OFFSET
STX LNKOFF SET ALL FLAGS
STX CUROFF
LDA S1BFMP HAS A BOOT FILE BEEN SET ?
ORA S1BFMP+1
ORA S1BFMP+2
BNE XBCLDR YES
;
; NO BOOT FILE HAS BEEN SET ON THIS DISK.
; ISSUE THE NO DOS ERROR MESSAGE AND HALT
;
LDA #.LO.NODOSM
STA $0344
LDA #.HI.NODOSM
STA $0345
STA $0349
LDA #9
STA $0342
LDX #0
JSR $E456
LOCK JMP LOCK
;
; BINARY LOADER STARTS HERE
;
XBCLDR LDA S1BFMP SETUP FOR INITIAL DATA
LDX S1BFMP+1 SECTOR READ
LDY S1BFMP+2
STA $030A
STX $030B
STY $030C
LDA #0
STA $02E1 CLEAR RUN ADDRESS
STA HDRFLG NEED $FFFF HEADER
;
; BINARY FILE HEADER IS $FF,$FF
; FOLLOWED BY START ADDRESS, END ADDRESS-1
;
XBLOAD JSR XBGET FETCH FIRST BYTE
BCC XBL050 CONTINUE IF GOOD
;
; EOF REACHED. TEST THE RUN VECTOR
;
XBL010 LDA $02E1 CHECK FOR A RUN ADDRESS
BEQ XBCBAD ZERO MEANS NONE
JMP ($02E0) VECTOR THROUGH RUN
XBCBAD SEC TELL OS BOOT HAS FAILED
XBCRET RTS
XBRE2 JMP ($02E2) VECTOR THROUGH INIT
;
XBL050 STA SEGADR SAVE POSSIBLE SEGMENT START
JSR XBGET
BCS XBCBAD EOF INVALID HERE
STA SEGADR+1
;
; CHECK IF IT'S THE $FF HEADER
;
CMP #$FF WELL ?
BNE XBL060 NO, KEEP GOING
CMP SEGADR TEST AGAINST LSB
BNE XBL060 KEEP LOADING
DEC HDRFLG NO LONGER HAVE TO HAVE THE HEADER
BMI XBLOAD FETCH TRUE HEADER
XBL060 LDA HDRFLG CHECK MUST FIND
BEQ XBCBAD FAILED, NO $FF START
;
; REST OF HEADER NOW
;
JSR XBGET
BCS XBCBAD
STA SEGLEN
JSR XBGET
BCS XBCBAD
STA SEGLEN+1
SEC CALCULATE THE SEGMENT
LDA SEGLEN LENGTH NOW
SBC SEGADR
TAX
LDA SEGLEN+1
SBC SEGADR+1
TAY
INX ADJUST FOR -1 HEADER
BNE XBL070
INY
XBL070 STX SEGLEN
STY SEGLEN+1
LDA #0 CLEAR THE INIT
STA $02E3 ADDRESS
;
; BINARY LOADING CAN NOW BEGIN. FIRST THING
; IS TO TEST IF WE CAN DO BURST I/O
;
XBL100 LDY CUROFF ARE WE AT A SECTOR BNDRY
BNE XBL110 NO, CAN'T BURST
LDA SEGLEN+1 IS THERE 256 BYTES LEFT ?
BNE XBL200 YES, GO BURST
XBL110 JSR XBGET FETCH THE BYTE
LDY #0
STA (SEGADR),Y STORE THE DATA BYTE
INY
JSR XBINC UPDATE ADR & LEN
LDA SEGLEN IS SEGMENT LOADED ?
ORA SEGLEN+1
BNE XBL100 NO, KEEP TESTING FOR BURST
LDA $02E3 DID INIT GET LOADED ?
BEQ XBL120
JSR XBRE2 RUN THE INIT CODE
XBL120 JMP XBLOAD LOAD NEXT SEGMENT
;
; COPY DATA WHOLE SECTOR AT A TIME
;
XBL200 LDA DBUF,Y COPY DATA BYTE
STA (SEGADR),Y
INY
CPY LNKOFF END OF DATA ?
BCC XBL200 NO
STY CUROFF SET CURRENT OFFSET
JSR XBINC UPDATE POINTERS
LDA SEGLEN+1 CAN BURST CONTINUE ?
BEQ XBL110 NO, IT'S OVER
JSR XBG020 FETCH NEXT DATA SECTOR
LDY #0
BEQ XBL200 GO AGAIN
;
; FETCH A BYTE FROM THE DRIVE
;
XBGET LDX CUROFF CHECK IF EOD
CPX LNKOFF
BCS XBG020
XBG010 LDA DBUF,X FETCH DATA BYTE
INC CUROFF UPDATE OFFSET
CLC SET GOOD CC
RTS BACK TO CALLER
;
; NEED A NEW DATA SECTOR
; ENTERED HERE FROM BURST/IO ROUTINE
;
XBG020 JSR XBLINK LINK TO NEXT SECTOR
BNE XBG050
XBG030 SEC RETURN WITH ERROR
XBG040 RTS
XBG050 JSR RDSEC READ THE SECTOR
BMI XBG030 RETURN IF ERROR
LDX #0 RESET TO ZERO
STX CUROFF
BEQ XBG010 RETURN TO GET
;
; READ SECTOR - OS HAS FILLED IN MOST FIELDS
;
RDSEC LDA #$40 IT'S A READ
STA $0303
JMP $E459 GO DO IT
;
; UPDATE SECTOR WITH NEW LINKAGE
;
XBLINK LDX LNKOFF
LDY #0
XBK010 LDA DBUF+1,X
STA $030A,Y
INX
INY
CPY #3 END OF SECTOR ?
BCC XBK010
ORA $030A MAKE SURE SECTOR IS VALID
ORA $030B
BEQ XBK020 ERROR
LDX LNKOFF
LDA DBUF,X CHECK THAT THE LINK IS VALID
CMP S1BFID
BNE XBK020 NOT VALID
TXA CLEAR ZERO FLAG
RTS
XBK020 LDA #0
RTS
;
; UPDATE THE SEGMENT POINTERS
;
XBINC TYA
CLC
ADC SEGADR
STA SEGADR
BCC XBI010
INC SEGADR+1
XBI010 STY $2B
SEC
LDA SEGLEN
SBC $2B
STA SEGLEN
BCS XBI020
DEC SEGLEN+1
XBI020 RTS
NODOSM .BYTE "Error: No DOS",$9B
;
; S1 = 3E00-3E7F
; S2 = 3E80-3EFF
; S3 = 3F00-3F7F
;
; BTEND MUST BE $3F7F OR LESS.
;
BTEND = * [$3F77]
;
; END BOOT

Link to comment
Share on other sites

I have found what I think is exactly the type of routine I am after in the "COMPUTE's Atari Collection, Vol. 1", page 229 and 230. This explains a BASIC programme to directly read the contents of a disk using DCB by sector number rather than via IOCB 'filename' method. However it is trivial to transliterate this approach in to ASM. You simply input the command code decimal '82' to read data, provide the address of a section of memory in to which the data from the disk will be stored, the disk sector to start reading from and the number of sectors to read. You then call the OS to perform the read itself. Incidentally; exactly the same process is used to write data from the buffer to disk, except using the write data code decimal '87'. The precise places in memory to put these values can be determined via 'Mapping The Atari'.

 

So, using the method you chaps have already given me, I read and then boot a small loader program from disk which then uses the 'COMPUTE' method to read in the larger main programme to an appropriate area of memory. When the read is complete I then jump the flow of execution to the start address of this memory area and the main programme begins to run!

 

Obviously this is described in the very broadest terms possible, but that will be my general approach I believe.

Link to comment
Share on other sites

DCB (DCOMND...) is for direct sector access through SIOV/DSKINV, IOCB (ICCMD...) is for character I/O through CIOV. You can only use character I/O if you're reading from D: with DOS loaded, and if you have DOS loaded, you might as well just use AUTORUN.SYS. If you want to learn more about how to use these, I'd recommend the OS Manual over Mapping the Atari -- the latter sometimes teaches you things that you shouldn't rely on and then stuff breaks on a custom OS or a fast loader.

 

You are only limited to three sectors for the OS boot when one of the following is true:

  • You are booting off of a double density disk. This is because the OS only knows how to boot 128 byte sectors, and disk drives report the first three sectors on a double-density disk as 128 bytes long. In this case, the boot loader needs to switch the sector size to 256 bytes for the rest of the load.
  • You are using a DOS-compatible filesystem on the disk and want the VTOC to be correct. In that case, the sectors from 4+ would need to be assigned to a file or else the VTOC would be invalid. Problem with assigning the sectors to a file is that the last three bytes in each sector are used for file metadata -- yuck.

The third case is if you want to accelerate load when a high-speed capable disk drive is available, in which case you would want the boot loader to be a minimum stub to switch to high speed I/O as soon as possible. However, that requires a replacement for the standard SIO routines, so that's a whole 'nother ball of wax. Don't recommend you try that until you've gotten standard loads working cleanly.

 

Otherwise, there's nothing wrong with having a boot loader longer than three sectors on an SD disk and having the OS read in the full program. If all you're going to do is load a few dozen sectors sequentially into memory through SIOV anyway, why not just let the OS do it all for you? This also means that I/O errors are automatically handled for you, by printing BOOT ERROR and then retrying the load.

 

One more thing: make sure that System Reset does what you expect after your loader runs. Either make sure DOSINI points at an appropriate routine to reinitialize your program, or stomp enough of the OS vars to force a cold boot.

  • Like 3
Link to comment
Share on other sites

DCB (DCOMND...) is for direct sector access through SIOV/DSKINV, IOCB (ICCMD...) is for character I/O through CIOV. You can only use character I/O if you're reading from D: with DOS loaded, and if you have DOS loaded, you might as well just use AUTORUN.SYS. If you want to learn more about how to use these, I'd recommend the OS Manual over Mapping the Atari -- the latter sometimes teaches you things that you shouldn't rely on and then stuff breaks on a custom OS or a fast loader.

 

You are only limited to three sectors for the OS boot when one of the following is true:

  • You are booting off of a double density disk. This is because the OS only knows how to boot 128 byte sectors, and disk drives report the first three sectors on a double-density disk as 128 bytes long. In this case, the boot loader needs to switch the sector size to 256 bytes for the rest of the load.
  • You are using a DOS-compatible filesystem on the disk and want the VTOC to be correct. In that case, the sectors from 4+ would need to be assigned to a file or else the VTOC would be invalid. Problem with assigning the sectors to a file is that the last three bytes in each sector are used for file metadata -- yuck.

The third case is if you want to accelerate load when a high-speed capable disk drive is available, in which case you would want the boot loader to be a minimum stub to switch to high speed I/O as soon as possible. However, that requires a replacement for the standard SIO routines, so that's a whole 'nother ball of wax. Don't recommend you try that until you've gotten standard loads working cleanly.

 

Otherwise, there's nothing wrong with having a boot loader longer than three sectors on an SD disk and having the OS read in the full program. If all you're going to do is load a few dozen sectors sequentially into memory through SIOV anyway, why not just let the OS do it all for you? This also means that I/O errors are automatically handled for you, by printing BOOT ERROR and then retrying the load.

 

One more thing: make sure that System Reset does what you expect after your loader runs. Either make sure DOSINI points at an appropriate routine to reinitialize your program, or stomp enough of the OS vars to force a cold boot.

 

That is another approach again Phaeron! I did not realize you could use more than 3 sectors at boot - purely based on what I read over the last week. If you can get it to read an arbitrary number of sectors then yes indeed, that is obviously the best way to do it.

 

I am surprized at your suggestion against 'Mapping The Atari'! I thought that was considered something of a 'foundational text' for ASM programming! The problem with the OS Manual you and the other chaps have mentioned is I cannot find a PDF of a full scan!!!

Link to comment
Share on other sites

I am surprized at your suggestion against 'Mapping The Atari'! I thought that was considered something of a 'foundational text' for ASM programming! The problem with the OS Manual you and the other chaps have mentioned is I cannot find a PDF of a full scan!!!

 

Mapping is a really good book describing the purpose of memory locations when the official Atari OSs are used. A lot of the information can apply to unofficial OSs also, but not all information. Primarily relying on a book like Mapping can lure someone into the mistake of coding directly for conditions which may not be universally true. That concept is responsible for a lot of the software incompatabilities of older 400/800 apps with the XL/XEs. The OS Manual describes the practice of using vectors to access routines, which can be updated whenever an OS is updated.

Link to comment
Share on other sites

 

Mapping is a really good book describing the purpose of memory locations when the official Atari OSs are used. A lot of the information can apply to unofficial OSs also, but not all information. Primarily relying on a book like Mapping can lure someone into the mistake of coding directly for conditions which may not be universally true. That concept is responsible for a lot of the software incompatabilities of older 400/800 apps with the XL/XEs. The OS Manual describes the practice of using vectors to access routines, which can be updated whenever an OS is updated.

 

'Vectors' are... What would be called function-pointers in C? They give a level of indirection so the underlying location can be changed without having to change every program that calls it - so long as the pointer is also updated?

  • Like 1
Link to comment
Share on other sites

Vectors proper are like C pointers, yes, including function pointers. But there are also JMPs in the jump table (at $e45x), which are also called vectors, while they are just entry points to system routines.

 

So to continue the simile, you might say these jumps are like API functions? Morevoer, you pass 'arguments' to these functions by storing data at specified addresses in memory ahead of 'calling' them through the 'JMP' command?

Link to comment
Share on other sites

What it means is let's say OS "White Rabbit" has the CIO routine located at $C400 but there is a vector to it at location $02E4. Now lets say a new OS comes out. We'll call it "Snow Rat". "Snow Rat" has the CIO routine located at $C4800 instead, but still has a vector at $02E4 which points to the updated location. If someone wrote software when "White Rabbit" was current to access CIO, and they simply had their program call it by going directly to $C400, that software would fail badly on "Snow Rat." However, if their program properly used the published vector at $02E4 to access CIO, then it would work fine.

Link to comment
Share on other sites

What it means is let's say OS "White Rabbit" has the CIO routine located at $C400 but there is a vector to it at location $02E4. Now lets say a new OS comes out. We'll call it "Snow Rat". "Snow Rat" has the CIO routine located at $C4800 instead, but still has a vector at $02E4 which points to the updated location. If someone wrote software when "White Rabbit" was current to access CIO, and they simply had their program call it by going directly to $C400, that software would fail badly on "Snow Rat." However, if their program properly used the published vector at $02E4 to access CIO, then it would work fine.

 

Excellent!, a very handy way of arranging things at the cost of an extra 2 bytes of memory per indirect 'function call' I guess? Again - a pointer approach.

 

I have not checked, but are these vectors not listed in 'Mapping The Atari'? Or is it more of a case where the book gives examples that does not use the vector approach?

Link to comment
Share on other sites

Yes, Mapping the Atari does list vectors that are part of the Atari OSs up to the point of publication of the book. Really the only updated OS Atari released after that was the XEGS OS I think. Anyway, MtA (short for "Mapping the Atari", because I am too lazy to type that all the time), lists most everything. So someone who is wanting to write software might find some things in there which perhaps shouldn't be accessed directly. MtA primarily attempts to document what is in the various parts of the Atari's memory map. It does not try very hard to instruct someone on the best practices for using all of the information. De Re Atari is a good book that does that, along with many others. Don't misunderstand, MtA is a "must have" book. It's just not the only one.

 

Addendum: not that it mattered for the example I gave, but vectors on the Atari often are not just the address of a routine, but a JMP instruction followed immediately by the address. But maybe not too. It can depend (I think, I'm not much of an expert on Atari vectors). For example DOSVEC. DOSVEC lives at $000A. There are 3 bytes involed and they go like this:

ADDR  VALUE
=====  =================
$000A  $4C (6502 jump inst.)
$000B  LSB of address to jump to
$000C MSB of address to jump to
Edited by fujidude
Link to comment
Share on other sites

Yes, Mapping the Atari does list vectors that are part of the Atari OSs up to the point of publication of the book. Really the only updated OS Atari released after that was the XEGS OS I think. Anyway, MtA (short for "Mapping the Atari", because I am too lazy to type that all the time), lists most everything. So someone who is wanting to write software might find some things in there which perhaps shouldn't be accessed directly. MtA primarily attempts to document what is in the various parts of the Atari's memory map. It does not try very hard to instruct someone on the best practices for using all of the information. De Re Atari is a good book that does that, along with many others. Don't misunderstand, MtA is a "must have" book. It's just not the only one.

 

I guess 'Reference' rather than 'tutorial' though. Do you happen to have a link to a PDF of the recommended OS manual?

 

In a more general sense, I wish there were more instructional books that dealt with techniques instead of raw information for ASM. There must be literally hundreds of BASIC guides to any level of expertise required but almost none for ASM. And in my opinion assembler is not any 'harder' to use than BASIC. That idea has been perpetuated ever since the a8's came out - that ASM was for 'experts' and everyone else should use BASIC. Nonsense in my opinion. You just need to know the techniques - exactly like you do for BASIC. I think Atari made a huge mistake in bundling a built-in version of BASIC with the new XL's but not their ASM editor or Macro Editor as well and then some way to switch between the two... Not dissimilar to a certain "Ultimate1MB"!!!

Link to comment
Share on other sites

@morelenmir: yes.

 

Except that unfortunately there is no RAM-based vector pointing to CIO and SIO. They should have done it, but they have not. There is plenty of space for that in page 0 (0-1, 4-5, 6-7). But well.

 

So there are only entry points at $e456 and $e459 respectively, in ROM.

 

@fuijdude: err, no. the vector at $0a/b is a true vector and occupies 2 bytes. Just that what it points to may begin with a JMP instruction ($4c).

Edited by drac030
Link to comment
Share on other sites

@drac030

Thanks... I messed that up. It is where it points to that I have typically seen a JMP instruction at.

 

@morelenmir

Here is a good place to get some book (also manuals and other stuff to, if you click the links for those).

You can get De Re Atari, Atari Roots, Machine Language for Beginners, and gobs and gobs more.

 

They also have the best book I have ever personally come across for the 6502 (computer neutral): 6502 Assembly Language Programming by Leventhal. That is great from a purely 6502 perspective.

Edited by fujidude
Link to comment
Share on other sites

Off the cuff I imagine it requires a short, standalone loader to get the programme off disk and in to memory which then passes the flow of execution on to it. If this is so then how do you get that loader routine to boot?

 

 

get this: http://xxl.atari.pl/download/xboot.obx (dissasemble for training purposes... more info: http://xxl.atari.pl/)

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