[stella] Usefull illegal opcodes (part 2: NOP)

Subject: [stella] Usefull illegal opcodes (part 2: NOP)
From: "Thomas Jentzsch" <tjentzsch@xxxxxx>
Date: Tue, 6 Mar 2001 10:31:34 +0100
Hi again,
here is another example of an usefull illegal opcode: NOP!
Yes, there exists a legal NOP (opcode $ea, 1 byte), but there a lot of undocumented NOPs with different lenghts and cycles. Believe me, there are situations where even illegal NOPs can be usefull, I'll show you later. First, I need to explain something:

When your are short of ROM space, there exists a nice trick to save bytes: use BIT.

Example:
There is a often called subroutine which needs an input parameter. This parameter is mostly one of only some different values:

A straightforward solution may look like this:
    lda     #0          ; or 1,2
    jsr     MySub
    ...
    lda     #0          ; or 1,2
    jsr     MySub
    ...
MySub:


A simple optimization is to add different entries into the subroutine:
    jsr     MySub0
    ...
    jsr     MySub1
    ...
MySub0:
    lda     #0
    beq     MySub
MySub1:
    lda     #1
    bne     MySub
    ...
MySub:


However, there are a lot of branches (2 bytes) which can be easily replaced with BIT (1 byte):
    ...
MySub0:
    lda #0
    .byte   $2c     ; opcode for BIT ABS, this skips the next two bytes!
MySub1:
    lda #1
    .byte   $2c     
    ...
MySub:

This is my optimal solution for that.


The only problem is, that BIT changes flags (V,N,Z) which are sometimes needed later. But there is an illegal opcode solution for that: NOP.
To replace BIT ABS (opcode $2c) you can use $0c (NOP ABS). Here is an example from my Thrust code:

This code is used to simulate the (sometimes reverse) gravity:
    lda     PlanetHi            ; bit 0 of PlanetHi contains the gravity state
    lsr                         ;  the state bit is shifted into the carry-flag 
    lda     P1speedY            ; load the current y-speed of the ship (-128..+127)
    bcs     .reverseGravity     ;
    sbc     #GRAVITY-1          ; normal gravity, subtract the gravity factor (carry flag=0)
    .byte   $0c                 ; <-- here I use an illegal NOP because I need the overflow- and negative-flags!
.reverseGravity:
    adc     #GRAVITY-1          ; in case of reverse gravity I have to add the factor (carry flag=1)
.contGravity:
    bvc     .ySpeedOk           ; no overflow, the result is ok, else limit the speed to the maximum
    bmi     .ySpeedPos          ; a negative value shows, that the overflowed speed was positive before
    lda     #-128               ; the maximum negative speed
    .byte   $2c                 ; <- here I use BIT ABS, but $0c would to the job too
.ySpeedPos:
    lda     #127                ; the maximum positive speed
.ySpeedOk:
    sta     P1speedY            ; save the new y-speed

Ok, that looks a bit complicated, but it saved me some bytes. 

Have fun!
_______________________________________________________
Thomas Jentzsch         | *** Every bit is sacred ! ***
tjentzsch at web dot de |


______________________________________________________________________________
Die Fachpresse ist sich einig: WEB.DE 20mal Testsieger! Kostenlos E-Mail, 
Fax, SMS, Verschlüsselung, POP3, WAP....testen Sie uns! http://freemail.web.de


-
Archives (includes files) at http://www.biglist.com/lists/stella/archives/
Unsub & more at http://www.biglist.com/lists/stella/

Current Thread