Jump to content



1

Request for programming tips


6 replies to this topic

#1 grafixbmp OFFLINE  

grafixbmp

    Dragonstomper

  • 659 posts
  • Location:South Central US

Posted Tue Apr 19, 2011 7:42 PM

Got a few questions dealing with proper syntax and wondered if anyone had the answers.

With illegal opcodes, what is the proper syntax and specifically the 3 cycle nop. Is it just adding an operand to it or is it some other abbreviation?

If I'm checking if a processor register has reached 0, is it a rule that it has to be check as soon as it has been decremented or any other codebetween the decrement and the branch could corrupt the result?

example:

right way

dey
beq special
~
*code*
~
special
(do stuff)


wrong way

dey
ldx temp
lda mancount,x
sta current

beq special
~
*code*
~
special
(do stuff)

I may have other questions later just wanted to confirm what i'm thinking.

#2 bogax OFFLINE  

bogax

    Star Raider

  • 61 posts

Posted Tue Apr 19, 2011 8:20 PM

Basically, any instruction that affects the contents
of A, X or Y will set the N and Z flags accordingly.
Also inc, dec, shift memory.
If you need the flag later you can push the status
register to the stack and pull it later.

So if you dey and don't do anything that affects
N or Z they'll reflect what the dey did untill
you do do something that affects N or Z.

If you dey then ldx they now reflect the effects of
ldx.

and, of course, there are instructions that don't
affect the registers but do affect the flags,
compare instructions, bit, plp, rti

Edited by bogax, Tue Apr 19, 2011 8:34 PM.


#3 grafixbmp OFFLINE  

grafixbmp

    Dragonstomper

  • 659 posts
  • Location:South Central US

Posted Tue Apr 19, 2011 8:31 PM

View Postbogax, on Tue Apr 19, 2011 8:20 PM, said:

Basically, any instruction that affects the contents
of A, X or Y will set the N and Z flags accordingly.
Also inc, dec memory.
If you need the flag later you can push the status
register to the stack and pull it later.

So if you dey and don't do anything that affects
N or Z they'll reflect what the dey did untill
you do do something that affects N or Z.

If you dey then ldx they now reflect the effects of
ldx.
Ok thats what I thought. But what about the proper illegal opcode for a 3 cycle nop? I know lax but not the nop.

#4 SeaGtGruff OFFLINE  

SeaGtGruff

    River Patroller

  • 4,545 posts
  • Location:Georgia, USA

Posted Tue Apr 19, 2011 8:50 PM

View Postgrafixbmp, on Tue Apr 19, 2011 8:31 PM, said:

But what about the proper illegal opcode for a 3 cycle nop? I know lax but not the nop.
"NOP 0" will wait 3 cycles.

Michael

#5 Omegamatrix OFFLINE  

Omegamatrix

    River Patroller

  • 4,796 posts
  • Location:Oh, Canada

Posted Wed Apr 20, 2011 12:20 AM

The 3 cycle (illegal) NOP is very useful because it preserves all flags. You can do things like this:


    lda    ufoPosition
    bpl    .clearOverflowFlag+1
.clearOverflowFlag:
    nop    $B8   ; illegal NOP
    sta    RESP0

Which can also be written this way, this makes more sense to a person reading your code!!

    lda    ufoPosition
    bne    .clearOverflowFlag
    .byte $04 ; illegal NOP, skip 1 byte
.clearOverflowFlag:
    clv
    sta    RESP0

This is similar to the Bit function. Notice the difference between the two opcodes ($24 and $04) is that bit 5 is not set with the illegal NOP opcode:

    lda    ufoPosition
    bne    .clearOverflowFlag
    .byte $24 ; BIT opcode, skip 1 byte, take 3 cycles
.clearOverflowFlag:
    clv
    sta    RESP0

Or can be written as this (more convoluted):

    lda    ufoPosition
    bpl    .clearOverflowFlag+1
.clearOverflowFlag:
    bit    $B8   ; used here to skip a byte, but is also affecting some flags...
    sta    RESP0

Summary:
$04 illegal NOP opcode, delay 3 cycles, no flags affected
$24 BIT opcode, delay 3 cycles, some flags are affected (Negative, Overflow, and Zero flag)
$B8 CLV opcode


Sometimes you need to waste time in a kernel. You can do it efficiently with a delay table. I made one here that uses a lot of illegal NOP's as well as regular NOP's. You can trim it down or expand it if you wish. Right now it's good for delaying any amount of cycles from 12-36, excluding 13 cycles.

; nops, and illegal nops preserve all flags...

WasteTime SUBROUTINE
     .byte $04    ;+0    36  cycles
     .byte $04    ;+1    35
     .byte $04    ;+2    33
     .byte $04    ;+3    32
     .byte $04    ;+4    30
     .byte $04    ;+5    29
     .byte $04    ;+6    27
     .byte $04    ;+7    26
     .byte $04    ;+8    24
     .byte $04    ;+9    23
     .byte $04    ;+10   21
     .byte $04    ;+11   20
     .byte $04    ;+12   18
     nop          ;+13   17
     .byte $04    ;+14   15
;--------------------------
     .byte $04    ;+15   34
     rts
     .byte $04    ;+17   31
     nop
     .byte $04    ;+19   28
     nop
     .byte $04    ;+21   25
     nop
     .byte $04    ;+23   22
     nop
     .byte $04    ;+25   19
     nop
     nop          ;+27   16
     nop          ;+28   14
     rts          ;+29   12

The last column in the above code is how many cycles the delay takes. For example, if you wanted to delay 28 cycles you would have "jsr WasteTime+19" in your program.
I.e.:

    sta    WSYNC
;--------------------------------
    lda    #RED+4           ;2  @2
    sta    COLUP0           ;3  @5
    lda    (ufoGfx),Y       ;5  @10
    sta    GRP0             ;3  @13
    jsr    WasteTime+19     ;28 @41
    sta    RESP1            ;3  @44
;code continues...

Edited by Omegamatrix, Wed Apr 20, 2011 12:25 AM.


#6 Thomas Jentzsch OFFLINE  

Thomas Jentzsch

    Thrust, Jammed, SWOOPS!

  • 16,745 posts
  • Always left from right here!
  • Location:Düsseldorf, Germany

Posted Thu Apr 21, 2011 1:08 AM

View PostOmegamatrix, on Wed Apr 20, 2011 12:20 AM, said:

The 3 cycle (illegal) NOP is very useful because it preserves all flags.
NOP #imm (e.g. $89) takes only 2 cycles and does the same, just faster.

So you have the option between 2 cycles and 3 cycles. Useful when exact timing matters like in the example code.

#7 Omegamatrix OFFLINE  

Omegamatrix

    River Patroller

  • 4,796 posts
  • Location:Oh, Canada

Posted Fri Apr 22, 2011 5:35 PM

View PostThomas Jentzsch, on Thu Apr 21, 2011 1:08 AM, said:

View PostOmegamatrix, on Wed Apr 20, 2011 12:20 AM, said:

The 3 cycle (illegal) NOP is very useful because it preserves all flags.
NOP #imm (e.g. $89) takes only 2 cycles and does the same, just faster.

So you have the option between 2 cycles and 3 cycles. Useful when exact timing matters like in the example code.
I forgot all about immediate mode for illegal NOP's. That greatly simplifies my delay table:


; nops, and illegal nops preserve all flags...

WasteTime SUBROUTINE
     .byte $80    ;+0    36   cycles
     .byte $80    ;+1    35
     .byte $80    ;+2    34
     .byte $80    ;+3    33
     .byte $80    ;+4    32
     .byte $80    ;+5    31
     .byte $80    ;+6    30
     .byte $80    ;+7    29
     .byte $80    ;+8    28
     .byte $80    ;+9    27
     .byte $80    ;+10   26
     .byte $80    ;+11   25
     .byte $80    ;+12   24
     .byte $80    ;+13   23
     .byte $80    ;+14   22
     .byte $80    ;+15   21
     .byte $80    ;+16   20
     .byte $80    ;+17   19
     .byte $80    ;+18   18
     .byte $80    ;+19   17
     .byte $80    ;+20   16
     .byte $04    ;+21   15
     nop          ;+22   14
     rts          ;+23   12

Now every byte is used, and it's easier to expand or contract the table. Cool! :)




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users