Jump to content
IGNORED

Programmer's Reference Manual


Recommended Posts

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.

 

Right, but A bit 0 is then guaranteed to be 0 at that point and is discarded later with the ROR, so the SEC can be dropped and the SBC adjusted to SBC #$3F, or equivalently ADC #$C0 used. Did an exhaustive test of all 256 values and it seems to work fine.

 

does not change perocesor flags nor registers

 

delay6 .byte $80

delay5 .byte $80

delay4 .byte $80

delay3 .byte $04

delay2 .byte $1a

 

Thanks, but I'm avoiding including anything with illegal opcodes for now. Most of the time they are not necessary and I don't intend to encourage recreational use of them.

  • Like 3
Link to comment
Share on other sites

Hi!

 

Right, but A bit 0 is then guaranteed to be 0 at that point and is discarded later with the ROR, so the SEC can be dropped and the SBC adjusted to SBC #$3F, or equivalently ADC #$C0 used. Did an exhaustive test of all 256 values and it seems to work fine.

 

You are right, I missed the fact that adding one more is not important, as the last bit is then discarded!

 

So, now the code is une byte shorter and two cycles faster :)

  • Like 1
Link to comment
Share on other sites

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/forums/blog/563/entry-11678-hex-to-ascii-string/ - obviously it can handle word values by being called twice.

 

Cool! In the SIDE loader, I was able to replace this:

	.proc HexOut
	tax
	lda HexTable,x
	jmp PutChar
	.endp

(which required a 16 byte look up table) with this...

	.proc HexOut
	sed
	cmp #9+1
	adc #$30
	cld
	jmp PutChar
	.endp

...which is only 2 bytes longer but requires no table at all. :)

  • Like 4
Link to comment
Share on other sites

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

 

 

The variant from cc65 is also interesting:

        asl     a               ; shift out the inverse bit
        adc     #$c0            ; grab the inverse bit; convert ATASCII to screen code
        bpl     codeok          ; screen code ok?
        eor     #$40            ; needs correction
codeok: lsr     a               ; undo the shift
        bcc     done
        eor     #$80                ; restore the inverse bit
done:   ...

or my alternative to the above (one byte shorter but slower):

	asl     a               ; shift out the inverse bit
        adc     #$c0            ; grab the inverse bit; convert ATASCII to screen code
        bpl     codeok          ; screen code ok?
        eor     #$40            ; needs correction
codeok: tax
	lsr     a
	txa
        ror     a

Compared to the php/plp version this is one byte longer but one cycle faster (of course with the drawback that X is used), so a lot of versions to choose from...

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

Hi!

 

The variant from cc65 is also interesting:

        asl     a               ; shift out the inverse bit
        adc     #$c0            ; grab the inverse bit; convert ATASCII to screen code
        bpl     codeok          ; screen code ok?
        eor     #$40            ; needs correction
codeok: lsr     a               ; undo the shift
        bcc     done
        eor     #$80                ; restore the inverse bit
done:   ...

 

That is the fastest yet, at 12 to 14 cycles, but I suggest the following that returns with the carry always cleared:

 

        asl     a
        adc     #$c0
        bpl     codeok
        eor     #$40
codeok: lsr     a
        bcc     done
        adc     #$7F
done:

or my alternative to the above (one byte shorter but slower):

	asl     a               ; shift out the inverse bit
        adc     #$c0            ; grab the inverse bit; convert ATASCII to screen code
        bpl     codeok          ; screen code ok?
        eor     #$40            ; needs correction
codeok: tax
	lsr     a
	txa
        ror     a
Compared to the php/plp version this is one byte longer but one cycle faster (of course with the drawback that X is used), so a lot of versions to choose from...

 

If you are using the X register, you can do faster:

        tax            ; 1  2
        asl            ; 1  2
        sbc #$3F       ; 2  2
        bpl ok         ; 2  2 3
        eor #$40       ; 2  2 0
ok:     cpx #128       ; 2  2
        ror            ; 1  2
  • Like 4
Link to comment
Share on other sites

These solutions are almost as efficient as my preferred solution where it's possible: reordering the font data so that ASCII = internal. Unfortunately this method is useless if you a) want to use the resident font or b) want to share the display with anything else (TD Line, etc).

  • Like 1
Link to comment
Share on other sites

These solutions are almost as efficient as my preferred solution where it's possible: reordering the font data so that ASCII = internal. Unfortunately this method is useless if you a) want to use the resident font or b) want to share the display with anything else (TD Line, etc).

Does anybody know why the font was arranged this way? Probably to save a few transistors in ANTIC and have the extra colours in the low res text modes?

Link to comment
Share on other sites

Hi!

 

Does anybody know why the font was arranged this way? Probably to save a few transistors in ANTIC and have the extra colours in the low res text modes?

My guess, to make the useful characters - numbers and upper case letters, ASCII from $20 to $5F - available in antic modes 6 and 7 (the 64 character modes).

 

But of course, if they had put lowercase into $40 to $5f and control chars into $60 to $7f, the code to transform ATASCII to screen would be shorter and faster :P

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

Hi,

 

I wrote asking about adding a chapter on different programming environments a while back, but I think that would probably just end up duplicating the info in http://atariwiki.orgso it's probably better not to do so.

 

I wonder if it's worth listing other resources available, e.g. atarimania, atariwiki, atari8, pigwa, atariage, etc., or pointing to a list of these, just as a useful list of resources for people getting back in to the 8-bit scene?

Link to comment
Share on other sites

  • 4 weeks later...

Phaeron - excellent work, any type of work like that is most welcome and much appreciated!

 

i wonder if there is a typo in section 4.6 display list interrupt

 

 

Enabling DLIs

To enable a display list interrupt, bit 7 of NMIST must be set and at least one instruction in the display
list must have its interrupt bit set (bit 7). The OS has support for neither, so both NMIST and the
display list must be modified directly.

 

shouldn this be

54286 0xD40E NMIEN

?

  • Like 1
Link to comment
Share on other sites

The OS has support for neither, so both NMIST and the

display list must be modified directly.

Being overly pedantic... the OS does use a DLI when fine scrolling

is enabled, e.g. POKE 622,1:GR.0

 

Which doesn't change the conclusion that DLIs have to be enabled manually

for user code, of course.

Link to comment
Share on other sites

Being overly pedantic... ;) we could also say that "To enable a display list interrupt, bit 7 of NMIEN must be set." is enough to ENABLE DLI. Instructions in DLIST "only" triggers DLI if it's ENABLED ;) (but maybe I'm mistaken because my English is bad).

Link to comment
Share on other sites

Being overly pedantic... ;) we could also say that "To enable a display list interrupt, bit 7 of NMIEN must be set." is enough to ENABLE DLI. Instructions in DLIST "only" triggers DLI if it's ENABLED ;) (but maybe I'm mistaken because my English is bad).

 

Well, as long as we're being pedantic -- this may not be quite true either, depending on your word interpretation. NMIEN[7] = 0 prevents the CPU from receiving DLIs, but the DLI instruction bit still causes NMIST[7] to be set. This is useful if you want the CPU to wait for a point on screen but don't need a full DLI, for which a simple BIT NMIST / BPL loop suffices. One use for this is to start VBI processing earlier than the actual start of vertical blank at line 248, which is later than necessary in many cases. I've used this trick in a couple of 2600 conversions to get more VBI time.

  • Like 5
Link to comment
Share on other sites

This is really good reading, there is a bunch of useful information here.

 

Just started reading through this, and noticed a typo on page 11 (or maybe I am not familiar enough with the syntax).

 

It reads:

 

LDX #$F6

shift_loop:


LDA array-$F7,Z
STA array-$F6,Z
INX
BNE shift_loop

 

Shouldn't it read?

 

LDX #$F6

shift_loop:


LDA array-$F7,X
STA array-$F6,X
INX
BNE shift_loop

 

 

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