Videopac / Odyssey2 forum
December 14, 2019, 09:32:37 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Join Rafael's Haunted Woods contest and win a copy of the game!
 
   Home   arcade Help Login Register links videopac.nl  
Pages: [1]   Go Down
  Print  
Author Topic: "Horizontal flip" by software  (Read 11718 times)
LD
Pedit5
Attacked the Timelord
*
Posts: 136



« on: March 22, 2015, 04:40:44 PM »

On Atari 2600 we have a register (REFPx) that turns the sprite horizontally, so if you have a sprite facing to right, set this register and the sprite is displayed facing to the left.
There's no such feature on Odyssey 2, you need to draw the same sprite twice, one for each facing.
Each sprite facing waste 8 bytes of ROM, so I had the idea to make a code to switch the facing by software.

There are 3 ways to make this (that I know) :

1 - Set individual pixels each time using byte shift and carry. The problem this code is very slow and need 64 loops to change all the 8 bytes of a single sprite. Probably this take more of the available time you have on VBlank.

2 - Flip each nibble at time. This is the code I'm using, still slow, and require a table of 16 bytes. The code itself including the table takes about 50 bytes of ROM space. It require 8 loops to flip the sprite.

3 - Flip each byte at time - The faster one, done in 8 loops,  but require a table of 256 bytes, you can store 32 sprites in this amount of ROM.

So my code flips each nibble at time, and like I said, uses about 50 bytes of ROM. You can store 6 sprites on that amount of ROM, so this code only is useful if you need flip more than 6 individual sprites, less than that you should flip them manually and not using the code, else you're wasting ROM and VBlank Time.

How it works : put the sprite on VDC RAM normally, after that, call a subroutine and it will flip the sprite that is pointed at R0, here's the code :
(no RAM needed and uses registers R0 to R4)

Code:
   mov R0,#080h       ;Sprite to be mirrored (80 or 88 or 90 or 98)
   call Mirroring     ;go to mirror code

;----------------------------------------------
Mirroring ;Subroutine
;----------------------------------------------
mov R4,#8
GetNibble
movx a,@R0
mov R1,a
;---
anl a,#00Fh
mov R2,#TableMirror & 0ffh
add a,R2
movp a,@a
swap a
mov R3,a
;---
mov a,R1 ;xxxx0000
swap a ;0000xxxx
anl a,#00Fh
mov R2,#TableMirror & 0ffh
add a,R2
movp a,@a
orl a,R3
movx @R0,a
inc R0
djnz R4,GetNibble
ret
TableMirror
db 0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15

The code needs to be run during Vblank (VDC Off) but you can store the result on extra RAM and later update to the sprite RAM, for calculate it off VBlank time.

EDIT : Code was optimized
« Last Edit: December 30, 2016, 05:20:34 PM by LD » Logged
gertk
Post Axe Pete!
*****
Posts: 859



gertk64
WWW
« Reply #1 on: March 22, 2015, 05:08:21 PM »

There are several ways to flip a byte but each of these routines will consume more memory than the 8 bytes you try to spare...  Smiley
Logged

>>G7000 G7200(P+S) G7400 N60 JET27 VG5000 ZX80 ZX81 ORIC-1 COMX35 Aquarius<<
LD
Pedit5
Attacked the Timelord
*
Posts: 136



« Reply #2 on: March 22, 2015, 09:35:21 PM »

If you know a faster way please, share Smiley

I'm not trying to make something smaller than 8 bytes, but something small and fast as possible. Smiley

This code based on nibble is half way between others two.
Logged
Rene_G7400
Pedit5
I take the Videopac and leave the Canoli!
*
Posts: 2519



WWW
« Reply #3 on: March 23, 2015, 09:24:07 AM »

Although this is a very interesting experiment, I think that CPU time (especially in Vblank) will usually be a bigger problem than ROM space (especially on NTSC consoles).
Logged
gertk
Post Axe Pete!
*****
Posts: 859



gertk64
WWW
« Reply #4 on: March 23, 2015, 12:10:35 PM »

If you know a faster way please, share Smiley

I'm not trying to make something smaller than 8 bytes, but something small and fast as possible. Smiley

This code based on nibble is half way between others two.


The fastest and smallest way is to pre-calculate every sprite which needs reversing and store that data in rom, then use (unrolled) loops to copy them to the VDC. If you place them smartly into different pages you can use a single pointer/index register.
Logged

>>G7000 G7200(P+S) G7400 N60 JET27 VG5000 ZX80 ZX81 ORIC-1 COMX35 Aquarius<<
LD
Pedit5
Attacked the Timelord
*
Posts: 136



« Reply #5 on: March 23, 2015, 11:07:05 PM »

Although this is a very interesting experiment, I think that CPU time (especially in Vblank) will usually be a bigger problem than ROM space (especially on NTSC consoles).

Usually games for Odyssey 2 / Videopac are minimalist in usage of sprites and animations.
But in games that you need a lot of animation frames, perhaps this code can help to save some ROM.
I don't know exactly how many cycles this code will take, but assuming it's something like 30 cycles, it will takes 1.5 scanline to flip the sprite.
Not that bad, actually.
Logged
Mux
Trying to get the cartridge in...
*
Posts: 40



« Reply #6 on: April 25, 2019, 10:04:37 PM »

Couple of years late but optimization is always a trade-off between CPU and memory. A bit of an in-between would be to have a 16-byte look-up table and use SWAP to get the upper / lower nibbles. Won't be as fast but faster than using rotates only..

-Mux
Logged
LD
Pedit5
Attacked the Timelord
*
Posts: 136



« Reply #7 on: May 02, 2019, 11:27:22 PM »

That's what I'm doing Wink

Actually, now reading my old code, I found some optimizations....
I don't need R1 and R2 at all... this saves 2 cycles and 3 bytes... not much but works!
The new code uses now registers R0 to R2 Smiley
It takes about 26 cycles and waste 39 bytes.

Here is  :

Code:
   mov R0,#080h       ;Sprite to be mirrored (80 or 88 or 90 or 98)
   call Mirroring     ;go to mirror code

;----------------------------------------------
Mirroring ;Subroutine
;----------------------------------------------
mov R1,#8
GetNibble
movx a,@R0
anl a,#00Fh
add a,#TableMirror & 0ffh
movp a,@a
swap a
mov R2,a
;---
movx a,@R0 ;xxxx0000
swap a ;0000xxxx
anl a,#00Fh
add a,#TableMirror & 0ffh
movp a,@a
orl a,R2
movx @R0,a
inc R0
djnz R1,GetNibble
ret
TableMirror
db 0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15

And the ROM for you try on emulators.
Hold button to flip the sprite! What a demo!
Logged
Janzl
Administrator
I'd sell my mother for a Videopac
*****
Posts: 2331


I now can cross that bloody street...


facebook@janzl.com
WWW
« Reply #8 on: May 03, 2019, 07:45:19 AM »

And the ROM for you try on emulators.
Hold button to flip the sprite! What a demo!

You should start up a scene  Cheesy
Logged

Ne tirez pas sur le administrator!
LD
Pedit5
Attacked the Timelord
*
Posts: 136



« Reply #9 on: May 04, 2019, 12:37:50 AM »

I have some ideas for a demo, actually...
The problem I'm not that good for code it.  Cry
Logged
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!