This is an archived, read-only copy of the United-TI subforum , including posts and topic from May 2003 to April 2012. If you would like to discuss any of the topics in this forum, you can visit Cemetech's z80 & ez80 Assembly subforum. Some of these topics may also be directly-linked to active Cemetech topics. If you are a Cemetech member with a linked United-TI account, you can link United-TI topics here with your current Cemetech topics.

This forum is locked: you cannot post, reply to, or edit topics. Z80 & 68k Assembly => z80 & ez80 Assembly
Author Message
simplethinker
snjwffl


Active Member


Joined: 25 Jul 2006
Posts: 700

Posted: 10 Apr 2009 12:28:52 pm    Post subject:

TKD_01 wrote:
ok...lightbulb still isn't turning on for me...Could you give an example of some source code to test say a pixel at (10,5)

So for GetPixel, the input is x-location in A and y-location in L, so to test that pixel:

Code:
  ld  A, 10d
  ld  L, 5d
  call GetPixel   ;A has bitmask, HL points to byte
  and  (HL)   ;A will be nonzero if pixel on, zero otherwise
  jr  z, _offStuff
_OnStuff:
. ;do stuff for pixel being on here
  jp _nextStuff
_offStuff:
. ;do stuff for pixel being off here
_nextStuff:
. ;hooray!  stuff was done!

(the decimal points at the front of the lines are there since for some reason leading spaces are being stripped)
Back to top
TKD_01


Advanced Newbie


Joined: 20 Feb 2009
Posts: 51

Posted: 10 Apr 2009 01:36:30 pm    Post subject:

oh, I got it! Well...partially anyways. I understand the bitmasking and byte pointing registers ('a' and 'hl', respectively). What I wasn't getting is why it wasn't working in my program. The one thing I forgot was that the getpixel routine destroys the 'hl' register, which I needed to keep track of.

To solve this, I added a push and a pop before and after calling the getpixel rountine, and it now works...in the context that my program doesn't crash anymore. However, it doesn't operate in the manner that I want it to:
My program is a new Phoenix-type program (hopefully mine will be just as good, if not better Very Happy), in which you (a ship) attempt to destroy enemy ships, which come in wave by wave. You do this by shooting bullets at them (duh), and likewise, they attempt to destroy you by shooting bullets at you.

Simply put, my problem is that many times these enemy bullets overlap and cause the overlapping sections to go blank (I'm XORing the images to the screen). What I tried to do to fix this is to use getpixel to check if a pixel is on in front of the ship, before it fires a bullet. However, the bullets are still firing, overlapping and all.
I'm not too sure why my code isn't working. I have the source code attached--scroll down 1/3 the way to the section called "Enemy Bullet Code", and the getpixel rountine is right below that. Any help would be appreciated!

The program is stable, by the way, in case you want to run it on an emulator...just don't go past the 2nd wave of enemies, because I haven't coded anything past that :)

Source code:
[attachment=2640:Ships.z80]
.8xp File:
[attachment=2641:ships.8xp]
Back to top
luby
I want to go back to Philmont!!


Calc Guru


Joined: 23 Apr 2006
Posts: 1477

Posted: 12 Apr 2009 02:38:32 pm    Post subject:


Code:
[b]UnlockFlash:[/b]
;Unlocks Flash protection.
;Destroys: appBackUpScreen
;          pagedCount
;          pagedGetPtr
;          arcInfo
;          iMathPtr5
;          pagedBuf
;          ramCode
        in a,(6)
        push af
        ld a,7Bh
        call translatePage
        out (6),a
        ld hl,5092h
        ld e,(hl)
        inc hl
        ld d,(hl)
        inc hl
        ld a,(hl)
        call translatePage
        out (6),a
        ex de,hl
        ld a,0CCh
        ld bc,0FFFFh
        cpir
        ld e,(hl)
        inc hl
        ld d,(hl)
        push de
        pop ix
        ld hl,9898h
        ld (hl),0C3h
        inc hl
        ld (hl),returnPoint & 11111111b
        inc hl
        ld (hl),returnPoint >> 8
        ld hl,pagedBuf
        ld (hl),98h
        ld de,pagedBuf+1
        ld bc,49
        ldir
        ld (iMathPtr5),sp
        ld hl,(iMathPtr5)
        ld de,9A00h
        ld bc,50
        ldir   
        ld de,(iMathPtr5)
        ld hl,-12
        add hl,de
        ld (iMathPtr5),hl
        ld iy,0056h-25h
        ld a,50
        ld (pagedCount),a
        ld a,8
        ld (arcInfo),a
        jp (ix)
translatePage:
        ld b,a
        in a,(2)
        and 80h
        jr z,_is83P
        in a,(21h)
        and 3
        ld a,b
        ret nz
        and 3Fh
        ret
_is83P: ld a,b
        and 1Fh
        ret
returnPoint:
        ld iy,flags
        ld hl,(iMathPtr5)
        ld de,12
        add hl,de
        ld sp,hl
        ex de,hl
        ld hl,9A00h
        ld bc,50
        ldir
        pop af
        out (6),a
        ret
Back to top
Xeda112358


Active Member


Joined: 19 May 2009
Posts: 520

Posted: 08 Jan 2010 02:45:17 pm    Post subject:

Here is a simple, fast getKey routine I discovered yesterday.
There is no delay between key presses and keys can be held down.

3A3F84 ;This is where the key is detected. 843F is kbdScanCode. 3A4584 will never return zero, but it tells the last key press.
EF8C47 ;setxxOP1
EFBF4A ;Stores keypress to Ans
C9

Change EFBF4A to any of these:
EFCB4A;Store to n (this is the one found in the catalog)
EFC54A;Store to R
EFCE4A;Store to T
EFC24A;Store to θ
EFD14A;Store to X
EFC84A;Store to Y
EFBF4A;Store to Ans


Last edited by Guest on 25 Feb 2011 07:14:10 pm; edited 1 time in total
Back to top
Madskillz


Active Member


Joined: 02 Jan 2004
Posts: 608

Posted: 09 Jan 2010 03:36:43 am    Post subject:

I recognize that from ticalc.org. Nice work on that as well as all those other routines, these should be pretty useful for the BASIC programmers.
Back to top
Xeda112358


Active Member


Joined: 19 May 2009
Posts: 520

Posted: 15 Jan 2010 02:39:05 pm    Post subject:

If you want a ton of opcodes, check out EnPro. I included over 30 opcodes, some of which made their first appearance there (because I made them myself, unlike the other 20 or so).


EDIT: My original post seemed a little rude and I had a bunch of opcodes that don't really belong here...


Last edited by Guest on 16 Nov 2010 02:11:08 pm; edited 1 time in total
Back to top
Xeda112358


Active Member


Joined: 19 May 2009
Posts: 520

Posted: 13 May 2010 10:02:45 am    Post subject:


Code:

HL_Times_A
;Inputs are A and HL (obviously)
;Outputs:
;     HL contains the product of A and HL
;     DE is the old value of HL
;     A  and C remain the same
;     B is 0
 ld b,8         ;2   0608      7        7
 ld de,0        ;3   110000   10        10
 ex de,hl       ;1   EB        4         4
  add hl,hl      ;1   29      11        88
  rlca           ;1   07       4        32
  jr nc,1        ;2   3001    12 or 7   12 if true, 11+7 if not
   add hl,de      ;1   19     11        ...
  djnz -7        ;2   10F9    13 or 8   13x7+8
 ret            ;1   C9       10        10
;Size=14 bytes
;Speed=344~392 (multiples of six depending on # of bits in A)


Last edited by Guest on 23 Oct 2010 03:26:56 pm; edited 1 time in total
Back to top
Xeda112358


Active Member


Joined: 19 May 2009
Posts: 520

Posted: 05 Nov 2010 12:06:16 am    Post subject:

EDIT: Fixed a typo found by calc84maniac...

Revival! HAHAHAHAHAHA...(*searching through routines...)

Swap Bytes

Code:

;Swaps BC bytes pointed to by HL and DE
;Inputs:
;     HL points to a spot in memory
;     DE points to a spot in memory
;     BC number of bytes to swap
;Outputs:
;     A is 0
;     BC is 0
;     HL is incremented BC times
;     DE is incremented BC times
;
  ld a,(de)
  ldi
  dec hl
  ld (hl),a
  inc hl
  ld a,b
  or c
  jr nz,-10
  ret


I am not sure if that is the right format, but here is the hex code just in case:
1AEDA02B772378B120F6C9

**For any BASIC programmers playing with opcodes, do this before the code:
:11EC86
:214093
:010003

Check the graph screen and run the program.
Check the screen again
Run the program again
Check screen

Or if you like, add EF6A48 before the C9 and then run the program twice.

Code:

:AsmPrgm
:11EC86     86EC is the saveSScreen
:214093     9340 is the plotSScreen
:010003     0300 is 768 (the number of bytes in the buffer)
:1AEDA0     Loop starts here
:2B7723
:78B1
:20F6       Jumps back to the start of the loop if it isn't finished
:EF6A48     Displays the updated graph screen
:C9         Ends the code


Last edited by Guest on 11 Nov 2010 10:32:08 am; edited 1 time in total
Back to top
calc84maniac


Elite


Joined: 22 Jan 2007
Posts: 770

Posted: 06 Nov 2010 09:20:08 pm    Post subject:

There seems to be a typo in your source (though it is correct in the hex codes): ld (de),a should be ld a,(de).

Oh, and did you know that you can use the overflow flag to check the state of BC after an LDI instruction? The following code isn't position-independent, but it is smaller and faster:

Code:
SwapBytes:
  ld a,(de)
  ldi
  dec hl
  ld (hl),a
  inc hl
  jp pe,SwapBytes
  ret
Back to top
Xeda112358


Active Member


Joined: 19 May 2009
Posts: 520

Posted: 11 Nov 2010 10:30:15 am    Post subject:

calc84maniac wrote:

There seems to be a typo in your source (though it is correct in the hex codes): ld (de),a should be ld a,(de).

Oh, and did you know that you can use the overflow flag to check the state of BC after an LDI instruction? The following code isn't position-independent, but it is smaller and faster:

Code:
SwapBytes:
  ld a,(de)
  ldi
  dec hl
  ld (hl),a
  inc hl
  jp pe,SwapBytes
  ret


Oh, thanks for correcting me! And no I did not know. [s]What do you mean by position-independent?
[/s]
EDIT: Okay, never mind, I see. JP, not JR...

A different code, now:

DE_Times_A

Code:

DE_Times_A
;Inputs are A and DE (obviously)
;Outputs:
;     HL contains the product of A and HL
;     A unchanged
;     C unchanged
;     DE unchanged
;     B is 0
 ld b,8         ;2   0608      7        7
 ld hl,0        ;3   210000   10        10
  add hl,hl      ;1   29      11        88
  rlca           ;1   07       4        32
  jr nc,1        ;2   3001    12 or 7   12 if true, 11+7 if not
   add hl,de      ;1   19     11        ...
  djnz -7        ;2   10F9    13 or 8   13x7+8
 ret            ;1   C9       10        10
;Size=13 bytes
;Speed=342~390 (multiples of six depending on # of bits in A)


Last edited by Guest on 11 Nov 2010 10:52:14 am; edited 1 time in total
Back to top
Xeda112358


Active Member


Joined: 19 May 2009
Posts: 520

Posted: 16 Nov 2010 02:29:40 pm    Post subject:

I hate double posting, but the forum isn't very active at the moment and I have some random stuff still scattered on my computer...

Okay, so with the post before, you can change that to HL_Times_A by simply adding ex de,hl to the very beginning. I personally use HL_Times_A more often, but if I like to have the option open and, hey, it is two routines in one for only one byte more:


Code:

HL_Times_A:
 ex de,hl       ;1   EB        4        4
DE_Times_A:
 ld b,8         ;2   0608      7        7
 ld hl,0        ;3   210000   10        10
  add hl,hl      ;1   29      11        88
  rlca           ;1   07       4        32
  jr nc,1        ;2   3001    12 or 7   12 if true, 11+7 if not
   add hl,de      ;1   19     11        ...
  djnz -7        ;2   10F9    13 or 8   13x7+8
 ret            ;1   C9       10        10

So pretty much, DE_Times_A is the same as HL_Times_A+1

I believe these are both faster and smaller than the routine in "Learn Z80 in 28 days"

So now here comes the BC_Times_DE routine!

BC_Times_DE

Code:

BC_Times_DE:
;Inputs:
;     BC and DE are factors
;Outputs:
;     A is 0
;     DE is 0
;     BC is unchanged
;     HL has the product (Least Significant Word, so mod 65536)
 ld hl,0        ;3   210000
 ld a,16        ;2   3E10
  add hl,hl      ;1   29
  ex de,hl       ;1   EB
  add hl,hl      ;1   29
  ex de,hl       ;1   EB
  jr nc,1        ;2   3001
   add hl,bc      ;1   09
  dec a          ;1   3D
  jr nz,-10      ;2   2002
 ret            ;1   C9

(And again, to make use of BC_Times_HL, just add ex de,hl to the beginning)


Last edited by Guest on 16 Nov 2010 02:31:01 pm; edited 1 time in total
Back to top
calc84maniac


Elite


Joined: 22 Jan 2007
Posts: 770

Posted: 18 Nov 2010 11:06:37 am    Post subject:

Here is a BC_Times_DE that is the same size, but quite a bit faster (4 cycles extra in overhead, but 10 cycles saved per loop)

Code:
BC_Times_DE:
  ld hl,0
  ld a,b
  ld b,16
BC_Times_DE_Loop:
  add hl,hl
  sla c
  rla
  jr nc,$+3
  add hl,de
  djnz BC_Times_DE_Loop
  ret


Edit:
And I believe this 16x16->32bit multiplication routine should work: (BC x DE -> DEHL)

Code:
  ld hl,0
  ld a,16
mult_loop:
  add hl,hl
  rl e
  rl d
  jr nc,_
  add hl,bc
  jr nc,_
  inc de
_:
  dec a
  jr nz,mult_loop
  ret


Last edited by Guest on 18 Nov 2010 12:44:27 pm; edited 1 time in total
Back to top
Xeda112358


Active Member


Joined: 19 May 2009
Posts: 520

Posted: 18 Nov 2010 02:07:20 pm    Post subject:

Thank you! Those are very helpful Very Happy Now for another code... A personal favorite that I have used often... PutSpriteXxY
PutSpriteXxY

Code:

PutSpriteXxY:
;Inputs:
;     a is the height
;     b
;     de points to the sprite data
;     hl points to the output location on plotSScreen
;Outputs:
;     a is 0
;     b is unchanged
;     c is 12-b
;     hl is a*12 larger (next sprite down?)
;     de points to data after sprite
;**As a note, the tenth byte or PutSpriteXxY+9 can be changed to some form of
;logic since my calls are usually in RAM, I usually give the option of sprite
;logic, so I change this byte instead of making the call 4 different times.
  ld (hl),a        ;77
  ld a,12          ;3E0C
  sub b            ;90
  ld c,a           ;4F
  ld a,(hl)        ;7E
Loop1:
   push bc          ;C5
   push af          ;F5
Loop2:
    ld a,(de)        ;1A
    nop              ;00    This byte gets changed to logic... read the note
    ld (hl),a        ;77
    inc de           ;13
    inc hl           ;23
    djnz -7          ;10F9
   add hl,bc        ;09
   pop af           ;F1
   pop bc           ;C1
   dec a            ;3D
   jr nz,-15        ;20F1
   ret              ;C9


Last edited by Guest on 18 Nov 2010 05:28:25 pm; edited 1 time in total
Back to top
Xeda112358


Active Member


Joined: 19 May 2009
Posts: 520

Posted: 19 Nov 2010 04:00:20 pm    Post subject:

Okay, I guess it is time for another... HexTok! This will convert an ASCII string of hex into the actual tokens! So... "310441" would translate into "0→A"

HexTok

Code:

HexTok:
;====================================================
;Inputs:
;     BC is half the size of the input (in bytes)
;     DE points to the input string of hex
;     HL points to where the converted hex is output.
;Outputs:
;     A is 0
;     BC is 0
;     DE points to the byte after the input string
;     HL points to the byte after the output string
;====================================================
  Call GetHexAtDE     ;CD****
  Call GetHexAtDE     ;CD****
  inc hl              ;23
  dec bc              ;0B
  ld a,b              ;78
  or c                ;B1
  jr nz,-12           ;20F4
  ret                 ;C9
GetHexAtDE:
  ld a,(de)           ;1A
  cp 3Ah              ;FE3A
  jr c,2              ;3802
   sub 7               ;D607
  inc de              ;13
  rld                 ;ED6F
  ret                 ;C9


I use this code when I am making a function to compress a hex string, like in SpriteLib or EnPro.
Back to top
calc84maniac


Elite


Joined: 22 Jan 2007
Posts: 770

Posted: 19 Nov 2010 08:21:42 pm    Post subject:

Here is a neat trick I like to use:

Code:
;Rather than
 inc hl
 dec bc
 ld a,b
 or c
 jr nz,loop

;instead do
 cpi
 jp pe,loop


This works because CPI tests if A is equal to (HL), increases HL, decreases BC, and puts the boolean BC != 0 into the parity/overflow flag. The comparison to (HL) is unneeded in this case, but the rest of the operations match exactly what I want to do here.
Back to top
Xeda112358


Active Member


Joined: 19 May 2009
Posts: 520

Posted: 19 Nov 2010 08:34:31 pm    Post subject:

Well, thank you! That is indeed a neat trick! Thank you much, I will be using that...
Back to top
Xeda112358


Active Member


Joined: 19 May 2009
Posts: 520

Posted: 12 Mar 2012 02:12:22 pm    Post subject:

Okay, now this is weird, I have this code that I absolutely love and I seem to have not uploaded it anywhere! Seriously, I just checked through all the sites I am often on and even my opcodes list and I never released this! I've been using it for years! These codes are why RRD and RLD are some of my favorite instructions!


Code:

ShiftScreenRight4:
;Shifts the graph screen right 4 pixels
     ld hl,plotSScreen
     ld c,64
       xor a
       ld b,12
         rrd
         inc hl
         djnz $-3
       dec c
       jr nz,$-9
     ret
ShiftScreenLeft4:
;Shifts the graph screen left 4 pixels
     ld hl,plotSScreen+767
     ld c,64
       xor a
       ld b,12
         rld
         dec hl
         djnz $-3
       dec c
       jr nz,$-9
     ret

Those routines are the same size as the traditional routine to shift left or right one pixel, but 7680 cycles slower, if I counted correctly. Still, 22166*4 cycles to shift left 4 times compared to 29846 once... That is about 3 times faster Very Happy
Back to top
Display posts from previous:   
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
    » Goto page Previous  1, 2, 3, 4, 5
» View previous topic :: View next topic  
Page 5 of 5 » All times are UTC - 5 Hours

 

Advertisement