Jump to content

Photo

Programmer's Reference Manual


34 replies to this topic

#1 phaeron OFFLINE  

phaeron

    River Patroller

  • 2,701 posts
  • Location:Bay Area, CA, USA

Posted Sun Mar 10, 2019 12:12 AM

I've been writing a programming manual on the side as a companion to the Altirra Hardware Reference Manual and Altirra BASIC manuals. It's been going a bit slow and I decided to post a preliminary copy here to gauge interest and if it might be useful. The intended scope is to cover what is needed to write software on the Atari and isn't covered by the Hardware or BASIC manuals, mainly the OS and DOS.

 

Right now, it is a mix of reference and how-to information. I'm not sure if I'll keep the how-to guide stuff as I'm not as good at it and it would easily fill a book on its own. The reference stuff is a mix of information that you could already have gotten from the official sources but just collected, and some information that is not as easy to find, like the DOS 3 and ARC formats and bugs in the OS and DOS. I have some other info that is waiting to be added, such as the SpartaDOS 1.1 disk format. It doesn't have an OS variable database listing, since that's a lot of work and the official OS Manual does a good job of it that I'm not sure is worth redoing.

 

Unlike the Altirra Hardware Reference Manual where I strictly stuck to describing the real hardware only (despite the name), this manual does include some information on emulator behavior, due to more considerations at the OS level with hooks like SIO patches. The OS behavior is for the Atari OS; AltirraOS is not described as it's not intended to be a separate OS that you program for.

 

Attached Files



#2 flashjazzcat ONLINE  

flashjazzcat

    Quadrunner

  • 14,437 posts
  • Location:United Kingdom

Posted Sun Mar 10, 2019 5:38 AM

Interest present here. I've just scanned quickly through the opening pages (replacing 6502 addition with subtraction, etc) which are already useful since I usually end up finding myself Googling that exact topic since I previously forgot to write it down or can't remember where else I used it. :)


Edited by flashjazzcat, Sun Mar 10, 2019 5:38 AM.


#3 therealbountybob OFFLINE  

therealbountybob

    High Score Club Overlord and Caretaker

  • 8,240 posts
  • still bl**dy assembling
  • Location:The Atariage High Score Club World HQ

Posted Sun Mar 10, 2019 6:27 AM

Had a quick browse - looks great :thumbsup:

Interest here too if there is a book run :thumbsup:

 

I have lots of the assembler books but there is a gap between them and some of the more advanced techniques used - esp re games programming; e.g. splitting players, calculating their hits, data manipulation tricks, compression...



#4 E474 OFFLINE  

E474

    Chopper Commander

  • 190 posts

Posted Sun Mar 10, 2019 6:48 AM

Hi,

I think the table of contents needs regenerating, ATX format isn't listed, but is in section 14.4.

Personally, I would keep the how-to stuff, it's nice if I can go from, "I need to do this", to copy/paste code that does what I need doing (or something close to it), and it's also sometimes easier to get the principles from working code than a text description.

Thanks for writing the programming manual, I hope I have time to sit down and go through it properly in the next few days.

#5 ebiguy OFFLINE  

ebiguy

    Chopper Commander

  • 213 posts
  • Location:Paris, France

Posted Sun Mar 10, 2019 7:01 AM

Of course this kind of manual in invaluable.

 

I would like all AA users to consider how lucky we are having phaeron writing down his knowledge.

That's a huge work made in a spirit of sharing all what he knows and I am really gratefull for that.



#6 E474 OFFLINE  

E474

    Chopper Commander

  • 190 posts

Posted Sun Mar 10, 2019 7:27 AM

Hi,

I noticed there is a miss-match between central-io and character-io (I think it is central IO, CIO). Also, I think it would be useful to include the summary table of math functions (like the one in De Re), and a little bit on page zero usage (what is available in different environments).

Maybe a chapter listing all the current development environments (if only briefly mentioning each one, e.g. cc65, Atasm, Wudsn, mads Pascal)? Maybe organised by interpreted, compiled, assembled?

Edited by E474, Sun Mar 10, 2019 7:29 AM.


#7 Stephen ONLINE  

Stephen

    Quadrunner

  • 7,539 posts
  • A8 Gear Head
  • Location:No longer in Crakron, Ohio

Posted Sun Mar 10, 2019 10:42 AM

Interest peaked - will give this a better read once I finish up work.



#8 MrFish ONLINE  

MrFish

  • 5,426 posts

Posted Sun Mar 10, 2019 2:25 PM

It's a great idea, and looks like it will be another great reference work. Please continue!



#9 dmsc OFFLINE  

dmsc

    Moonsweeper

  • 499 posts
  • Location:Viņa del Mar, Chile

Posted Sun Mar 10, 2019 3:09 PM

Hi!
 

I've been writing a programming manual on the side as a companion to the Altirra Hardware Reference Manual and Altirra BASIC manuals. It's been going a bit slow and I decided to post a preliminary copy here to gauge interest and if it might be useful. The intended scope is to cover what is needed to write software on the Atari and isn't covered by the Hardware or BASIC manuals, mainly the OS and DOS.
 
Right now, it is a mix of reference and how-to information. I'm not sure if I'll keep the how-to guide stuff as I'm not as good at it and it would easily fill a book on its own. The reference stuff is a mix of information that you could already have gotten from the official sources but just collected, and some information that is not as easy to find, like the DOS 3 and ARC formats and bugs in the OS and DOS. I have some other info that is waiting to be added, such as the SpartaDOS 1.1 disk format. It doesn't have an OS variable database listing, since that's a lot of work and the official OS Manual does a good job of it that I'm not sure is worth redoing.
 
Unlike the Altirra Hardware Reference Manual where I strictly stuck to describing the real hardware only (despite the name), this manual does include some information on emulator behavior, due to more considerations at the OS level with hooks like SIO patches. The OS behavior is for the Atari OS; AltirraOS is not described as it's not intended to be a separate OS that you program for.


Thanks for doing this, an OS guide to programming the Atari 8bit was really needed.

A few comments:
- In page 6, the "MIN" example writes an erroneous value into A+1, a possible fix could be:
 LDX B
 CPX A
 LDA B+1
 TAY
 SBC A+1
 BCS b_ge_a
 STX A
 STY A+1
b_ge_a:
- In page 7, the table at top should say "Takes one stack byte" for the PHA/PLA and PHP/PLP combos.

You could add the technique for testing if a value is between two numbers, instead of:
 cmp #low_val
 bcc skip
 cmp #high_val+1
 bcs skip

 ; handle values
it can be written as:
 sec
 sbc #low_val
 cmp #high_val-low_val+1
 bcs skip

 ; handle values
This is specially useful when you already know the state of the C flag, as the "sec" can be omitted.

And at last, I have seen big code to convert ATASCII to screen-codes many times, I think this could be added to the examples:
 asl
 php
 sec
 sbc #$40
 bpl ok
 eor #$40
ok:
 plp
 ror


#10 E474 OFFLINE  

E474

    Chopper Commander

  • 190 posts

Posted Sun Mar 10, 2019 5:40 PM

Hi,

One quick comment, you might want to include a section on interfacing Basic (and other languages) with assembler, e.g., how arguments are pushed/pulled from the stack, and values returned (I think via FP0?).

Also a list of different antic display types, e.g. bytes/line, colours (and registers used), etc.

Edited by E474, Sun Mar 10, 2019 5:40 PM.


#11 phaeron OFFLINE  

phaeron

    River Patroller

  • Topic Starter
  • 2,701 posts
  • Location:Bay Area, CA, USA

Posted Sun Mar 10, 2019 7:24 PM

I think the table of contents needs regenerating, ATX format isn't listed, but is in section 14.4.

Personally, I would keep the how-to stuff, it's nice if I can go from, "I need to do this", to copy/paste code that does what I need doing (or something close to it), and it's also sometimes easier to get the principles from working code than a text description.

 
Yeah, I have to remember to update the TOC manually in LibreOffice Writer and forgot to do so.
 
The thing about code examples is that they very quickly get too big to keep inline in the document, and I don't have most of them written. Also, subjects like P/M graphics multiplexing and music I don't have much experience in. It feels like this might be too much going down the rabbit hole of rewriting stuff that has already been covered in a lot of books and other practical examples (e.g. demo source and MADS samples). But it might be a good place to dump reusable code I've had lying around like the TIA sound emulator.
 

I noticed there is a miss-match between central-io and character-io (I think it is central IO, CIO). Also, I think it would be useful to include the summary table of math functions (like the one in De Re), and a little bit on page zero usage (what is available in different environments).

Maybe a chapter listing all the current development environments (if only briefly mentioning each one, e.g. cc65, Atasm, Wudsn, mads Pascal)? Maybe organised by interpreted, compiled, assembled?

 
Derp, I realized a while back that I had gotten the name of CIO wrong but hadn't finished correcting it, thanks. Current environments might be a bit much to cover, plus I haven't actually used most of them. I'll probably stick to mostly MADS assembly while trying not to use too many esoteric MADS features so the 6502 assembly is recognizable.
 

A few comments:
- In page 6, the "MIN" example writes an erroneous value into A+1, a possible fix could be:
- In page 7, the table at top should say "Takes one stack byte" for the PHA/PLA and PHP/PLP combos.


Derp, thx, fixed. The problem with code fragments in the document is that you can't directly execute them to test them. :(
 

You could add the technique for testing if a value is between two numbers, instead of:
...
This is specially useful when you already know the state of the C flag, as the "sec" can be omitted.

Yeah, I need to add that one. For some ranges the SBC can be swapped with EOR, which is more convenient flags-wise -- I think I used that in an isdigit() routine.
 

And at last, I have seen big code to convert ATASCII to screen-codes many times, I think this could be added to the examples:

 

I've only learned of this trick recently and hadn't had time to analyze it. Don't want to just copy and paste other people's code in without understanding it, that's kind of janky. It's a neat trick, though, I might be able to save some bytes and cycles in AltirraOS with it.
 

One quick comment, you might want to include a section on interfacing Basic (and other languages) with assembler, e.g., how arguments are pushed/pulled from the stack, and values returned (I think via FP0?).

Also a list of different antic display types, e.g. bytes/line, colours (and registers used), etc.

 

I'm deliberately keeping BASIC stuff in the BASIC manual instead. At one point I started including it and then realized it would fill several chapters by itself. The Altirra Extended BASIC manual might be able to become an all-encompassing BASIC book, once I actually finish it. Same with the Hardware Manual, though it's more of a problem there as there's no how-to in that book.

 



#12 mono OFFLINE  

mono

    Chopper Commander

  • 103 posts

Posted Mon Mar 11, 2019 5:51 AM

Thanks Avery. Maybe it's obvious, maybe not, but inverse conversion (from INTERNAL->ATASCII) is possible with calling ATASCII->INTERNAL twice when this routine is given. And the same is truth when INTERNAL->ATASCII is given and ATASCII->INTERNAL is desired.



#13 danwinslow OFFLINE  

danwinslow

    River Patroller

  • 2,574 posts

Posted Mon Mar 11, 2019 6:54 AM

Definitely great interest here. Willing to help if I can in any way. I would suggest as a title : De Rursus Atari (once again atari). ;)



#14 dmsc OFFLINE  

dmsc

    Moonsweeper

  • 499 posts
  • Location:Viņa del Mar, Chile

Posted Mon Mar 11, 2019 7:06 AM

Hi!
 

Thanks Avery. Maybe it's obvious, maybe not, but inverse conversion (from INTERNAL->ATASCII) is possible with calling ATASCII->INTERNAL twice when this routine is given. And the same is truth when INTERNAL->ATASCII is given and ATASCII->INTERNAL is desired.


I don't think it is obvious!

So a routine that does both is:
scr2ata:
  jsr ata2scr
ata2scr:
  asl
  php
  sec
  sbc #$40
  bpl ok
  eor #$40
ok:
  plp
  ror
  rts
Also, you can invert the above routine for a faster version:
scr2ata:
 asl
 php
 bpl add
 eor #$40
add:
 clc
 adc #$40
 plp
 ror


#15 flashjazzcat ONLINE  

flashjazzcat

    Quadrunner

  • 14,437 posts
  • Location:United Kingdom

Posted Mon Mar 11, 2019 10:21 AM

Not remotely sophisticated (nor compact), but I found this method of testing bits used as flags when the accumulator needs to be left intact (so, no LSR or AND) quite useful:

	lda flags
	bit bit0
	bne DoSomething1
	bit bit3
	bne DoSomething2

...

bit0
	.byte 1
bit1
	.byte 2
bit2
	.byte 4
bit3
	.byte 8



#16 phaeron OFFLINE  

phaeron

    River Patroller

  • Topic Starter
  • 2,701 posts
  • Location:Bay Area, CA, USA

Posted Mon Mar 11, 2019 10:46 PM

So a routine that does both is:

scr2ata:
  jsr ata2scr
ata2scr:
  asl
  php
  sec
  sbc #$40
  bpl ok
  eor #$40
ok:
  plp
  ror
  rts

 

Is SEC/CLC actually needed? Bit 0 is guaranteed 0 after the ASL and is discarded on the ROR, so it should be safe to occasionally set it.

 

 

Not remotely sophisticated (nor compact), but I found this method of testing bits used as flags when the accumulator needs to be left intact (so, no LSR or AND) quite useful:

	lda flags
	bit bit0
	bne DoSomething1
	bit bit3
	bne DoSomething2

...

bit0
	.byte 1
bit1
	.byte 2
bit2
	.byte 4
bit3
	.byte 8

 

Interesting. Takes a bit of space, but not actually too bad for cycles. This is one of the cases where a 65C02/65C816 would come in handy due to BIT #imm.



#17 Rybags OFFLINE  

Rybags

    Gridrunner

  • 16,029 posts
  • Location:Australia

Posted Tue Mar 12, 2019 3:10 AM

Only had a quick look but good idea.

 

Though not Atari specific I would also welcome the 6502 coding tricks that tend to not find their way into a single document.

 

Of course hardware exploits by software such as the VScroll tricks and 480i interlace would be welcome too.



#18 E474 OFFLINE  

E474

    Chopper Commander

  • 190 posts

Posted Tue Mar 12, 2019 3:42 AM

Hi,

It's a horrible optimization, but you can do the BIT against byte values in your code, e.g. if you want to do a BIT against a byte value of 1, you just need to look for an LDA #1 in your code.

#19 flashjazzcat ONLINE  

flashjazzcat

    Quadrunner

  • 14,437 posts
  • Location:United Kingdom

Posted Tue Mar 12, 2019 4:06 AM

 

Interesting. Takes a bit of space, but not actually too bad for cycles. This is one of the cases where a 65C02/65C816 would come in handy due to BIT #imm.

 

Indeed: it's a direct substitute for BIT #imm. The reason for implementing it was some pre-determined, arcane bit order in the U1MB PBI BIOS which made testing bits by shifting them into the carry flag inconvenient, since I needed to test (say) bit 3 first. Quite verbose, but oddly it ended up being no bigger than other convoluted implementations. I had no idea that BIT would set the Z flag in this particular context until I tried it.


Edited by flashjazzcat, Tue Mar 12, 2019 4:06 AM.


#20 dmsc OFFLINE  

dmsc

    Moonsweeper

  • 499 posts
  • Location:Viņa del Mar, Chile

Posted Tue Mar 12, 2019 7:31 AM

Hi!
 

scr2ata:
  jsr ata2scr
ata2scr:
  asl
  php
  sec
  sbc #$40
  bpl ok
  eor #$40
ok:
  plp
  ror
  rts
Is SEC/CLC actually needed? Bit 0 is guaranteed 0 after the ASL and is discarded on the ROR, so it should be safe to occasionally set it.


Yes, the ASL stores the high bit (inverse video) into the carry, then pushed in the stack with the PHP, so the state is unknown at the SBC.

The idea is to first get out the high bit, as the result does not depend on it, then you need to change the top bits as:
 00  ->  10
 01  ->  00
 10  ->  01
 11  ->  11
Subtracting $40, you already have the "01" and "10" cases right, and to fix the "00" and "11" cases you need to invert the second it, so you need the "EOR #$40" only if the result is negative.


You can do it in one cycle less, but three bytes more, using a ZP location:
                ; Bytes   Cycles
 sta zp         ; 2       3
 and #$60       ; 2       2
 asl            ; 1       2
 bmi ok         ; 2       2 3
 eor #$40       ; 2       2 0
ok:
 adc #$40       ; 2       2
 lsr            ; 1       2
 eor zp         ; 2       3
Now, the rules change because we compute the XOR mask needed to change from ATASCII to screen code. This code is better yet if you already have the ATASCII code in the ZP location, then is only one byte more and 4 cycles less. as that location is not changed.

I did a loop and tried various combinations but could net find any smaller or faster.

#21 E474 OFFLINE  

E474

    Chopper Commander

  • 190 posts

Posted Tue Mar 12, 2019 8:23 AM

Hi,

 

   One routine that I end up using in almost all my code is byte -> 2 digit hex code, I copied it from: http://atariage.com/...o-ascii-string/ - obviously it can handle word values by being called twice.



#22 Sheddy OFFLINE  

Sheddy

    Dragonstomper

  • 771 posts
  • Location:UK

Posted Tue Mar 12, 2019 8:27 AM

There is some middle ground between basics and "assumed already expert" that something like this with practical examples can fill nicely. Seems like a great idea.
EG on disk handler sector read, what kind of status should we expect. If it fails should we try again, or assume bad sector.

On topic of exact cycle wasting I nominate clockslide https://www.pagetable.com/?p=669as one of the sneakiest tricks. Not something that instantly springs to mind!

cmp (0,x)
6 cycle wait in 2 bytes if you don't mind messing up the carry

#23 xxl OFFLINE  

xxl

    Stargunner

  • 1,127 posts
  • Location:Rabka-Zdrķj /Poland

Posted Tue Mar 12, 2019 8:48 AM

does not change perocesor flags nor registers
 
delay6 .byte $80
delay5 .byte $80
delay4 .byte $80
delay3 .byte $04
delay2 .byte $1a


#24 dmsc OFFLINE  

dmsc

    Moonsweeper

  • 499 posts
  • Location:Viņa del Mar, Chile

Posted Tue Mar 12, 2019 9:35 AM

Hi!

does not change perocesor flags nor registers
 
delay6 .byte $80
delay5 .byte $80
delay4 .byte $80
delay3 .byte $04
delay2 .byte $1a


Wow, do you really like undocumented opcodes, you even used $1A instead of $EA....

At least you can make the code compatible with the 65C02 by using:
delay6 .byte $E2
delay5 .byte $E2
delay4 .byte $E2
delay3 .byte $44
delay2 .byte $EA


#25 flashjazzcat ONLINE  

flashjazzcat

    Quadrunner

  • 14,437 posts
  • Location:United Kingdom

Posted Tue Mar 12, 2019 4:24 PM

Useful resource (which includes the BIT abs method of testing all bits of the accumulator and even the 'nasty optimisation', so maybe that's where I originally saw it): https://wiki.nesdev....y_optimisations






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users