Jump to content
IGNORED

Assembly is hard.


atari2600land

Recommended Posts

Somehow I managed to cobble up two games, but I'm having some troubles on this one, mainly due to the fact that I can't figure out how to display just one part of a sprite. Suppose I have some code that looks like this:

enemy
   db  01111100b
   db  11010110b
   db  11111110b
   db  10000010b
   db  11111110b
   db  01000100b
   db  01000100b
   db  11000110b    

   db    01111000b
   db    11111110b
   db    11111110b
   db    01111100b
   db    00000000b
   db    00011110b
   db    00111111b
   db    00011110b            
   

   
setshape
; r0=spritepointer, r1=pointer to image in rom
   mov    r7,#8        ; 8 bytes

   
   
copyspriteloop:
   mov    a,r1
   movp    a,@a        ; get byte
   movx    @r0,a
   inc    r0
   inc    r1
   djnz    r7,copyspriteloop
   ret

At the beginning, I called the certain shape to appear using this:

   mov    r0,#vdc_spr2_shape
   mov    r1,#enemy & 0ffh
   call    setshape

My question is, how would I get the next 8 lines of the sprite to appear instead of the first 8?

Link to comment
Share on other sites

  • 2 weeks later...

I don't know the Z80 equalivant to (indirect),y addressing...or much else pertaining to Z80 for that matter...but couldn't you just alter the value of r1 before entering the loop?

 

Its not Z80. Its 8048 which is the CPU in the Philips G7000.

 

My question is, how would I get the next 8 lines of the sprite to appear instead of the first 8?

 

Try :-

 

   mov    r0,#vdc_spr2_shape
   mov    r1,#enemy+8 & 0ffh
   call    setshape

Link to comment
Share on other sites

Thanks, groovybee, but I've given up on that game. It was just too hard for me to contemplate how to do other stuff.

 

OK, well, next question. I'm working on a Freeway type game, and I was just wondering how to make a non-appearing timer like in Freeway? I struggled with this for days on end and what I've tried doesn't make any sense whatsoever.

traff4.txt

Edited by atari2600land
Link to comment
Share on other sites

There is a vsyncirq in the vector table but no source code to handle it in your example. Put an increment of a RAM variable in there. When it gets to 50 or 60 (depending on TV region) then reset it back to 0 and subtract 1 from your seconds counter. When the seconds counter reaches 0 then your time has run out. With a single byte containing the seconds you can have a maximum time out of 255 seconds.

Link to comment
Share on other sites

Why does this not work?

   ;timer part
   mov r0,#thissucks
   movx a,@r0
   add a,#1
   movx @r0,a    

   mov r0,#thissucks
   movx a,@r0    
   xrl a,#60
   jz loop_000

   jmp loop_00

loop_000

   call add_score

   mov r0,#thissucks
   mov @r0,#000h

   mov r0,#seconds
   movx a,@r0    
   add a,#0ffh
   movx @r0,a    

   mov r0,#seconds
   movx a,@r0    
   xrl a,#000h
   jz gameover_4
   
   jmp loop_00

gameover_4
   jmp gameover

loop_00
  -rest of program-

Link to comment
Share on other sites

Never mind. As someone pointed out in the other thread, and I didn't know this, the whole game would run slower, so there's no need to make the clock run slower.

 

Not true! You need to account for the difference in the number of vblanks per second. If you are counting to 60 on NTSC the clock will roll over every second as expected. If you are counting to 60 on PAL the clock will roll over every 1.2 seconds. For a 60 second time limit you get (60*60)/60 seconds running on NTSC. If you run on PAL without changing the code you'd get (60*60)/50 seconds. So PAL people would get 72 seconds to complete the same course. That wouldn't be good if the game was ever used in an international high score contest.

Link to comment
Share on other sites

You need to do the following steps:

 

- Load a data register with the source address (the variable you want to read).

- Move the contents of the address pointed to by the register into the accumulator.

- Load a data register with the destination address (the variable you want to write).

- Move the accumulator into the address pointed at by that register.

Link to comment
Share on other sites

Cool, thanks, I ended up with this:

   mov r0,#011h
   movx a,@r0
   mov r1,#001h
   movx @r1,a

(In Odyssey2 assembly, #11h is char0x and #001h is sprite0x. I am still wondering what exactly @ does, though. Keep in mind I learned/ am learning how to do different things by tweaking different examples)

Link to comment
Share on other sites

I am still wondering what exactly @ does, though.

 

It roughly means "the contents of the address". Its a bit like saying "let fred=1" in BASIC except that in the Videopac's case "1" would have moved into the accumulator first and the address of "fred" would be moved into a data register.

Link to comment
Share on other sites

We discussed "if statements" back in February. I'm not an 8048 programmer but the code would be something like :-

 

; Check if val>=88
   add a, #168
   jc OutOfRange

; Val is in the range 0 to 87 at this point.

; You need to restore A here it was just trashed with the add.
...

; Check if val>=81
   add a, #175
   jnc OutOfRange

; Get here if val>80 and val<88
InRange:

; Do something because its in range...

; Jump to somewhere.

; Get here if val<=80 or val >=88
OutOfRange:

; Do something because its out of range...

Link to comment
Share on other sites

  • 2 weeks later...

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