Author Topic: ASM Command of the Week  (Read 20222 times)

0 Members and 1 Guest are viewing this topic.

Offline chickendude

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 817
  • Rating: +90/-1
  • Pro-Riot Squad
    • View Profile
Re: ASM Command of the Week
« Reply #15 on: January 13, 2012, 08:13:10 pm »
I haven't responded yet simply because, to be honest, i had no idea this command even existed :/ I could see it maybe being used for a fixed-width font text-wrapping routine or something, though that might not be quite so simple as you'd have to check for a space character and EOS character.

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: ASM Command of the Week
« Reply #16 on: January 13, 2012, 08:14:38 pm »
In that case, you can play with CPI >.>

Offline Hot_Dog

  • CoT Emeritus
  • LV12 Extreme Poster (Next: 5000)
  • *
  • Posts: 3006
  • Rating: +445/-10
    • View Profile
Re: ASM Command of the Week
« Reply #17 on: January 18, 2012, 03:25:53 pm »
Here's the next one:

CPL


Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: ASM Command of the Week
« Reply #18 on: January 18, 2012, 03:39:03 pm »
CPL is a great command for logic. Pretty much, it inverts the A register. The most common thing I use it for, is with drawing sprites and pixels with erasing logic. For example, to display a sprite by erasing, take the sprite data and invert it with cpl, then use AND logic on the screen. Also, you can use it to invert the graph buffer:
Code: [Select]
     ld hl,9340h
     ld bc,3
       ld a,(hl)
       cpl
       ld (hl),a
       inc hl
       djnz $-4
       dec c
       jr nz,-7
     ret

Offline calc84maniac

  • eZ80 Guru
  • Coder Of Tomorrow
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2912
  • Rating: +471/-17
    • View Profile
    • TI-Boy CE
Re: ASM Command of the Week
« Reply #19 on: January 18, 2012, 03:46:54 pm »
CPL can also be used to subtract from 255. This is useful to subtract A from any number N by doing this:

cpl
add a,N+1


Of course, if N=254, 255, or 0, replace the add with a dec a, nothing, or inc a respectively.
"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: ASM Command of the Week
« Reply #20 on: January 18, 2012, 03:55:32 pm »
Building off of what calc said, NEG is like CPL \ INC A, except NEG will modify the c flag.

Offline chickendude

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 817
  • Rating: +90/-1
  • Pro-Riot Squad
    • View Profile
Re: ASM Command of the Week
« Reply #21 on: January 18, 2012, 05:02:15 pm »
Like others have said, I use cpl for a quicker/smaller xor $FF, for example in my tilemapper to get the mask  when  rotating the screen:
Code: [Select]
updateRotation:
    ld a,(xOff)         ;what is the xOffset?
    and 7               ;we're only interested in the lower three bits (essentially xOff % 8)
    ld hl,gbufMask
    ld e,a
    ld d,0
    add hl,de           ;pointer to the rotation mask
    ld a,(hl)
    ld hl,maskLeft
    ld (hl),a
    ld hl,maskRight
    cpl                 ;xor $FF
    ld (hl),a
;...
    ret
gbufMask:
.db %11111111   ;0 display all of the first byte, none of the second
.db %11111110   ;1 after rotating left once, we only want the 7 leftern most bits of byte 1, and rightmost bit of byte 2
.db %11111100   ;2
.db %11111000   ;3
.db %11110000   ;4
.db %11100000   ;5
.db %11000000   ;6
.db %10000000   ;7
...which, btw, is based off an idea calc84maniac mentioned on IRC a few years ago of doing the rotation in the fastcopy routine, though i remember you saying that your main fastcopy loop was much faster than mine :)

Offline Hot_Dog

  • CoT Emeritus
  • LV12 Extreme Poster (Next: 5000)
  • *
  • Posts: 3006
  • Rating: +445/-10
    • View Profile
Re: ASM Command of the Week
« Reply #22 on: February 08, 2012, 12:01:46 am »
The next one is

SCF

Normally, this is used for math (do share ;D)

Sometimes I find the need to use the carry flag for conditions beyond what it is normally used for (detecting overflows or underflows).  For example, I could theoratically use C or NC to see if an object is collidable or not.  Whatever the situation, I would use SCF to set the carry flag if a condition is true. 

Offline ralphdspam

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 841
  • Rating: +38/-1
  • My name is actually Matt.
    • View Profile
Re: ASM Command of the Week
« Reply #23 on: February 08, 2012, 01:17:34 am »
Was I not updating the topic weekly?  Whoops.  :P

Anyways, there is a very nice use of SCF in Axe's sound routine.  Instead of using it for math, it is used for conditional branching.
Code: [Select]
xor a
__FreqOutLoop1:
push bc
ld e,a
__FreqOutLoop2:
ld a,h
or l
jr z,__FreqOutDone
dec hl
dec bc
ld a,b
or c
jr nz,__FreqOutLoop2
ld a,e
xor %00000011
scf
__FreqOutDone:
pop bc
out ($00),a
ret nc
jr __FreqOutLoop1
« Last Edit: February 09, 2012, 11:24:11 am by Art_of_camelot »
ld a, 0
ld a, a

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: ASM Command of the Week
« Reply #24 on: February 08, 2012, 07:42:22 am »
I often like to use it to return whether a function was successful or not. For example, the c flag here means the pixel was in bounds, so its location was computed normally:
Code: [Select]

GetPixelLoc:
;Input:
;     b is X
;     c is y
;Output:
;     HL points to byte
;     A is the mask
;     nc if not computed, c if computed
       ld a,c
       cp 64 \ ret nc
       ld a,b
       cp 96 \ ret nc
       ld l,c
       ld h,0
       ld b,h
       add hl,hl
       add hl,bc
       add hl,hl
       add hl,hl
       ld b,a
       rrca \ rrca \ rrca
       and 0Fh
       ld c,a
       ld a,b
       ld b,0
       add hl,bc
       ld bc,(BufPtr)
       add hl,bc
       and 7
       ld b,a
       inc b
       ld a,1
         rrca
         djnz $-1
       scf
       ret
Sometimes I need to correct an addition or subtraction by also adding or subtracting one:
Code: [Select]

OP1NameLength:
;Returns the name length in HL
        ld hl,8478h
NameLength:
        xor a \ ld b,a \ ld c,a
        cpir
        ld h,a \ ld l,a
        scf \ sbc hl,bc
        ret
 
(There is a better version of that)
Also, sometimes there are some very specific adjustments. In this case, you will see scf is used only when the end of the file is met, so an extra 1 must be subtracted to get the line length:
Code: [Select]

SearchLine:
;Inputs:
;     HL points to the start
;     BC is the number of bytes to search
;     DE is the line number
;     A is the line byte
;Outputs:
;     A is not changed
;     BC is the number of bytes left for the search
;     DE points to the line
;     HL is the length of the line
;===============================================================
     dec de \ inc d \ inc e
     or a
     ld (TempWord1),hl
SearchLoop:
     cpir                       ;21X-5
     jp po,EndSearchLoop+1
     dec e \ jr nz,SearchLoop-3
     dec d \ jr nz,SearchLoop-3
EndSearchLoop:
     scf
     ld de,(TempWord1)
     sbc hl,de
     ret

Offline Hot_Dog

  • CoT Emeritus
  • LV12 Extreme Poster (Next: 5000)
  • *
  • Posts: 3006
  • Rating: +445/-10
    • View Profile
Re: ASM Command of the Week
« Reply #25 on: February 16, 2012, 11:30:06 am »
OR

In bit manipulation, you can use this to set bits

Code: [Select]

ld a, %10000000
or %10000001   ;The first and last bits will be set no matter what.  All others will not be affected.


OR A is a wonderful substitue to "CP 0."  Also, OR A is a great way to reset the carry flag.  Whenever you want to subtract something from HL, you have to use the instruction SBC, and in a lot of cases, you want to make sure that the carry flag is reset, or your subtraction result could come out wrong.

Code: [Select]

ld hl, 10000
ld de, 5000
or a
sbc hl, de  ;Now it's guranteed that HL = 5000 instead of 4999.


Offline calc84maniac

  • eZ80 Guru
  • Coder Of Tomorrow
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2912
  • Rating: +471/-17
    • View Profile
    • TI-Boy CE
Re: ASM Command of the Week
« Reply #26 on: February 16, 2012, 01:44:27 pm »
OR can be used to check if a multi-byte value is zero. For example, to check if BC is zero, use
ld a,b
or c
jr z,Value_Is_Zero


If you have a 32-bit value in DEHL, you can similarly use
ld a,d
or e
or h
or l
jr z,Value_Is_Zero
"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman

Offline Hot_Dog

  • CoT Emeritus
  • LV12 Extreme Poster (Next: 5000)
  • *
  • Posts: 3006
  • Rating: +445/-10
    • View Profile
Re: ASM Command of the Week
« Reply #27 on: March 13, 2012, 11:20:24 pm »
BIT

This will test a bit in a register to see if it's 1 or 0.  I find this instruction especially useful for (hl) and A  (If I don't want to lose the value that I have stored in register A with bit manipulation)

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: ASM Command of the Week
« Reply #28 on: March 13, 2012, 11:55:16 pm »
In a similar vein, you can do some soft-core SMC to speed up a routine such as pixel-testing or even turning the pixel on or off:
Code: [Select]
;===============================================================
PlotPixel:
;===============================================================
;Inputs:
;     B is the x-coordinate
;     C is the y-coordinate
;     D=Method
;        1=Test
;        2=Off
;        3=On
;     (BufPtr) points to the buffer to draw to
;Outputs:
;     BC is equal to (BufPtr)
;     DE not modified
;     HL points to the byte the pixel is drawn to
;     When using the pixel test method:
;       z means pixel off
;       nz means pixel on
;Destroys:
;     A
;===============================================================
     ld a,3Fh            ;7
     srl b \ rra         ;12    19
     srl b \ rra         ;12    31
     srl b \ rra         ;12    43
     cpl                 ;4     47
     or d                ;4     51
     rrca \ rrca         ;8     59
     ld (Method),a       ;13    72
     ld a,b              ;4     76
     ld b,0              ;7     83
     ld h,b \ ld l,c     ;4     87
     add hl,bc           ;11    98
     add hl,bc           ;11   109
     add hl,hl           ;11   120
     add hl,hl           ;11   131
     ld c,a              ;4    135
     add hl,bc           ;11   146
     ld bc,(BufPtr)      ;20   166    BufPtr points to the buffer
     add hl,bc           ;11   177
     .db $CB             ;15   192    First byte of BIT
Method:
     .db 46h             ;            second byte of the BIT instruction
     ret                 ;10   202  37 bytes

Offline Quigibo

  • The Executioner
  • CoT Emeritus
  • LV11 Super Veteran (Next: 3000)
  • *
  • Posts: 2031
  • Rating: +1075/-24
  • I wish real life had a "Save" and "Load" button...
    • View Profile
Re: ASM Command of the Week
« Reply #29 on: March 14, 2012, 04:36:21 am »
Code: [Select]
bit 5,a
bit 3,a

These will set the hidden flag in the F register in the same way as, and in addition to, the z flag.  Obsucre? Yes.  Useful? >:D
« Last Edit: March 14, 2012, 04:36:57 am by Quigibo »
___Axe_Parser___
Today the calculator, tomorrow the world!