Author Topic: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc. Tools for development  (Read 15778 times)

touko

  • Hero Member
  • *****
  • Posts: 953
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #90 on: January 03, 2016, 06:29:51 AM »
Quote
Just beware of TRB/TSB on the $0003 takes longer than normal. Even a LDA $0003/STA $0003 takes longer than normal. TRB/TSB $0003 takes ~ 15.6 cycles on the real console. TRB/TSB $0002 takes ~ 8.9 cycles on the real console.
8.9 cycles is faster than LDA/STA, but the overhead for writing to $0003 is quite annoying  :-k .

Quote
I did some VDMA tests and can confirm that it's roughly 81 WORDs per line in 5.37mhz mode. So definitely ~324bytes per line in 10.74mhz mode. I was able to transfer 17.6k with a clipped 209 line display @ 10.74mhz. That's more than perfect for my other bitmap mode display. A few other things too.
Good news, your tests confirm what aladar said about VDMA .

Bonknuts

  • Hero Member
  • *****
  • Posts: 3292
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #91 on: January 03, 2016, 09:26:49 AM »
Yeah, the R-M-W on $0003 is disappointing. I only tested this during active display, though. Could be different for vblank.

 I guess you could do trb $0002; ldx ABS,y ; stx $0003. Or trb $0002; st2 #nn.


Bonknuts

  • Hero Member
  • *****
  • Posts: 3292
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #92 on: January 13, 2016, 11:39:50 AM »
elmer: You were right about the devil in the details (sprite faking BG layer). I was working on making a presentation/demo, but realized that I'm going to need to make a custom map utility for this.

elmer

  • Hero Member
  • *****
  • Posts: 2153
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #93 on: January 14, 2016, 03:54:15 AM »
elmer: You were right about the devil in the details (sprite faking BG layer). I was working on making a presentation/demo, but realized that I'm going to need to make a custom map utility for this.

Such are the "joys" of pushing technology forward into new areas!  :wink:

elmer

  • Hero Member
  • *****
  • Posts: 2153
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #94 on: January 17, 2016, 10:16:14 AM »
After the recent discussion on the PCE's CD booting, and my continuing discussion with TheOldMan, I thought that I'd document something that I've not seen mentioned before.

Anyone that has looked at making a PCE CD has already discovered the "IPL Information Data Block" that must be put in the 2nd sector on the CD, and who's data values tell Hudson's IPL (the code that must be put in the 1st sector on the CD) exactly where to load your game program and what address to call to run it.

Now while you can just let PCEAS handle creating a CD image for you ... you can also just do it yourself if you want complete control over the CD layout.

As a reminder, here is the "IPL Information Data Block" in PCEAS format, together with the PCEAS/HuC default values ...

                org     $3000

                ; IPL INFORMATION DATA BLOCK

                db      $00                     ; $00 IPLBLK_H (ISO Sector 2)
                db      $00                     ; $01 IPLBLK_M
                db      $02                     ; $02 IPLBLK_L
                db      $10                     ; $03 IPLBLN   (Size $8000)
                db      $00                     ; $04 IPLSTA_L (Load $4000)
                db      $40                     ; $05 IPLSTA_H
                db      $70                     ; $06 IPLJMP_L (Exec $4070)
                db      $40                     ; $07 IPLJMP_H

                db      $00                     ; $08 IPLMPR2  (bank $80)
                db      $01                     ; $09 IPLMPR3  (bank $81)
                db      $02                     ; $0A IPLMPR4  (bank $82)
                db      $03                     ; $0B IPLMPR5  (bank $83)
                db      $00                     ; $0C IPLMPR6  (bank $80)

                db      $60                     ; $0D OPENMODE
                                                ;     bit 0 - Load VRAM  : 0 = Off
                                                ;     bit 1 - Load ADPCM : 0 = Off
                                                ;     bit 5 - BG Display : 1 = Off
                                                ;     bit 6 - Play ADPCM : 1 = Off
                                                ;     bit 7 - Loop ADPCM : 0 = Off

                db      $00                     ; $0E GRPBLK_H
                db      $00                     ; $0F GRPBLK_M
                db      $00                     ; $10 GRPBLK_L
                db      $00                     ; $11 GRPBLN
                db      $00                     ; $12 GRPADR_L
                db      $00                     ; $13 GRPADR_H

                db      $00                     ; $14 ADPBLK_H
                db      $00                     ; $15 ADPBLK_M
                db      $00                     ; $16 ADPBLK_L
                db      $00                     ; $17 ADPBLN
                db      $00                     ; $18 ADPRATE

                db      $00                     ; $19 reserved
                db      $00                     ; $1A reserved
                db      $00                     ; $1B reserved
                db      $00                     ; $1C reserved
                db      $00                     ; $1D reserved
                db      $00                     ; $1E reserved
                db      $00                     ; $1F reserved

                db      $50,$43,$20,$45         ; |PC E|
                db      $6e,$67,$69,$6e         ; |ngin|
                db      $65,$20,$43,$44         ; |e CD|
                db      $2d,$52,$4f,$4d         ; |-ROM|
                db      $20,$53,$59,$53         ; | SYS|
                db      $54,$45,$4d,$00         ; |TEM.|
                db      $43,$6f,$70,$79         ; |Copy|
                db      $72,$69,$67,$68         ; |righ|
                db      $74,$20,$48,$55         ; |t HU|
                db      $44,$53,$4f,$4e         ; |DSON|
                db      $20,$53,$4f,$46         ; | SOF|
                db      $54,$20,$2f,$20         ; |T / |
                db      $4e,$45,$43,$20         ; |NEC |
                db      $48,$6f,$6d,$65         ; |Home|
                db      $20,$45,$6c,$65         ; | Ele|
                db      $63,$74,$72,$6f         ; |ctro|
                db      $6e,$69,$63,$73         ; |nics|
                db      $2c,$4c,$74,$64         ; |,Ltd|
                db      $2e,$00                 ; |..|

                ; Game Name (16 bytes)
                db      "                "
                ; Game Code (6 bytes)
                db      "      "



**************

The "IPL Information Data Block" is 128 bytes long, which leaves 1920 bytes of unused space in the 2nd sector on the CD.

This space is normally wasted, but TheOldMan has found that he can put some program code in there that's "hidden" from HuC, and execute it before his HuC program starts up.

He can do this because he's found that Hudson's IPL code always loads that block into memory at $3000.

So just by setting the IPLJMP address to $3080 instead of PCEAS's default $4070, he can run his own code before jumping to the normal PCEAS/HuC startup at $4070.

Since PCEAS is designed to always load the user's program at $4000, and execute it at $4070, then this technique doesn't cause any problems.

While this is a neat trick, I'm 100% sure that the leftover space had a different purpose ... one that I've not seen mentioned before.

That is as a way for a developer to create their own IPL code that gets control of the system as-soon-as-possible after boot.

If you set the IPLBLN value to $00, which means that you don't want the IPL to load any game code at all, then you can set IPLJMP to $0080 (NOT $3080), and the IPL will jump to the 1920 bytes of code that you've put in the 2nd sector.

That's not a lot of code space ... but it is enough to create your own IPL program that then loads up your game code however and from wherever you wish.

Some obvious things that you could do with this are to create a startup logo that animates while the main game code is loading, or to immediately jump to a totally different boot loader if you find that you are running on a System Card 2.0 instead of a System Card 3.0.

It could also be used to create a complicated loading system that would be hard to crack/copy ... although that idea had more value in the 1980s and 1990s, before Mednafen and other emulators were written.  :wink:


**************

Because Hudson make you specify an IPLJMP address that is relative to the start of the sector, rather than just setting it to $3080, then I'm pretty sure that they didn't want developers to always rely on that sector getting loaded at $3000.

Console manufacturers tend not to like developers relying on the undocumented "internal behavior" of the manufacturer's system, and so I'm guessing that if you took advantage of this capability, then you would not be allowed to just assume that you code would run at $3080.

Luckily, it is easy to copy your code from whatever address the sector is loaded at, to a fixed location in memory and then just run it from there.

Here is a small example startup that would do that (copying the code to $2680 to run there) ...

                org     $3080

                bsr     *+2
                pla
                dec     a
                sta     <_al
                plx
                stx     <_ah
                ldy     #$12
                sta     [_ax],y
                txa
                iny
                sta     [_ax],y
                tii     $0000,$2680,$0780
                jmp     $2680+$1b

code_at_269b:   nop


Of course, 25 years later on, we know that Hudson never did create a different IPL, and that the 2nd sector is always-and-forever going to be loaded at $3000 ... so we don't need to bother with the code above. But it was interesting to write it, just to see what it might look like.
« Last Edit: January 17, 2016, 10:29:06 AM by elmer »

TheOldMan

  • Hero Member
  • *****
  • Posts: 958
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #95 on: January 17, 2016, 02:55:37 PM »
More fun with the IPL...

Set the GRPBLK_  stuff and load your graphics and a palette before anything actually runs...
Set the ADPBLK_ stuff and OpenMode, and play an adpcm tune (or whatever) before loading....

Both of those also require adjusting the IPLBLK_ record number so the program will load (set it to start record of games actual code)

Stash your actual exec address (original IMLJMP,  default = $4070) at the start of the free area and jump to it from the custom code area. Game should run like normal :)

Or for even more fun, use the custom code area to do a cd_read via mpr....and load as much as needed from the cd....(you still have to specify length, etc for cd_read)

The only big problem with this kind of stuff is HuC keeps a list of offsets for overlays. Those have to be patched if you use the graphics/sound stuff, since the game won't start at sector 2 on disc, and HuC assumes that it will. Somewhere I have a tool that patches all that stuff, if I can ever find it again. (And someone wants to host it)

....And the final piece of the puzzle, elmer.  Use the last 3 sectors of the program code (or add 3 sectors to it) and load those in the custom code. (Or,  if you prefer,  set the size in bytes and call cd_read with _dh = 0: that forces a byte->sector conversion) Then you can jump to a small routine that will load those last sectors into $2800.....

I *think* that will let you load 6K into the ram bank, and all of the cd card memory. Well, except for the load routine extension....which is < 64 bytes, iirc.

Bonknuts

  • Hero Member
  • *****
  • Posts: 3292
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #96 on: January 18, 2016, 07:04:37 AM »
Ahh, so this is what you guys were talking about. I've used IPL to load a few graphic (and I think ADPCM) things like a splash screen, but I mostly just use it for the CD version detection routine; basically just a boot loader for the SCD or ACD program. I just jump into system ram and load all SCD/ACD banks and then jump to my exec address.

 So what you guys are talking about, is similar? Jump into system ram ($3000 range) and execute detection and call CD load routines from there? While animation and/or sound is playing?

elmer

  • Hero Member
  • *****
  • Posts: 2153
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #97 on: January 18, 2016, 09:23:26 AM »
So what you guys are talking about, is similar? Jump into system ram ($3000 range) and execute detection and call CD load routines from there? While animation and/or sound is playing?

Your small "Boot Loader" is the normal way that games are written, IMHO.

Here is my understanding of the options for getting a logo displayed and potentially animating it ...


1) Normal Game flow (no undocumented assumptions are needed)..

  Hudson IPL
    Load graphic to VRAM
    Load ADPCM to CD RAM
    IPL displays logo in VRAM and starts playing the ADPCM jingle
    The logo does not animate at this point
    Load boot code to $2680/$3000/$4000 or wherever (MPR2/MPR3/MPR4/MPR5/MPR6)
    IPLJMP is set to somewhere in the area that you just loaded

  Developer's Boot Code
    Check CD/SCD/ACD and decide what to load
    Animate logo while loading up the 3rd stage
    Load and Run 3rd stage to display an Error Message or start the Main Menu.



2) Custom IPL Game flow (no undocumented assumptions are needed).

  Hudson IPL
    Load graphic to VRAM
    Load ADPCM to CD RAM
    IPL displays logo in VRAM and starts playing the ADPCM jingle
    IPLJMP is set to $0080, no assumption is made about where the IPL is loaded
    IPL jumps to $3080 as soon as the ADPCM starts playing
   
  Developer's Boot Code
    Copy $0780 bytes of boot code to somewhere specific (say $2680)
    Jump to the code's new location
    Start the logo animation
    Check CD/SCD/ACD and decide what to load, and start loading it
    Run 3rd stage once it has loaded, or when the animation has finished



3) TheOldMan's flow (assumes IPL is loaded from $2800-$37FF, which is undocumented).

  Hudson IPL
    Load graphic to VRAM
    Load ADPCM to CD RAM
    IPL displays logo in VRAM and starts playing the ADPCM jingle
    The logo does not animate at this point
    Load HuC boot code to $4000 (MPR2/MPR3/MPR4/MPR5/MPR6 or a subset)
    IPLJMP is set to $3080 (within the IPL sectors that the System Card loaded)

  Developer's Boot Code
    Code at $3080 runs and bounces the logo.
    Code jumps to $4070 to run the regular HuC startup.



[EDIT]
Upon further clarification we've been having a bit of a misunderstanding, and TheOldMan is actually using a variant of Method 2, but without relocating the code, and so is still assuming that it won't be overwritten when he loads up the HuC Boot Code.
That's my current understanding, anyway.  :wink:
[END EDIT]

Now, there's not really very much difference between the first 2 if your Boot Code is fairly small, but the Custom IPL option does potentially offer the developer some (small) advantages if the Boot Code is tiny, and the 3rd-stage load is very long.

I don't see any advantage to the 3rd method, since TheOldMan could just as easily achieve exactly the same end result without having to rely on the undocumented knowledge of where the System Card loads the 2 IPL sectors.

a) If he isn't moving the location of the HuC code in the ISO, then he could just set the load addresses (IPLSTA) to $3800, set the execution address (IPLJMP) to $3880, and set the CD start sector (IPLBLK) to 1 instead of 2.

b) If he has to mess around with the PCEAS ISO output anyway in order to inject the logo and sound sectors, and so has to move the HuC Boot Code location, then it would be easy to just add an extra sector on the front and change the load and execution addresses as above.

c) Just modify HuC's "startup.asm" to include the logo bouncing code and run it before the rest of the startup procedure.

Judging by the flow of PMs ... TheOldMan and I have somewhat differing opinions on the matter.  :wink:
« Last Edit: January 18, 2016, 01:14:32 PM by elmer »

TheOldMan

  • Hero Member
  • *****
  • Posts: 958
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #98 on: January 18, 2016, 12:48:33 PM »
Quote
Ahh, so this is what you guys were talking about. I've used IPL to load a few graphic (and I think ADPCM) things like a splash screen, but I mostly just use it for the CD version detection routine; basically just a boot loader for the SCD or ACD program. I just jump into system ram and load all SCD/ACD banks and then jump to my exec address.

Yeah, that's pretty much what we are talking about.
And debating (he from an asm, me from a Huc point of view) whether it's "better" to use the ipl empty space or load part of the program into Ram and execute it there.

We agree we disagree, mostly. Though I do have to say I could see loading initialized data and possibly kernel/irq functions into ram as a good thing. Can't do that with Huc (well, I could, but it's a lot of work)

And a note for anyone else playing with this: IIRC, it's not a background kind of operation.  (At least on the HuC side). Your graphics load, and display. Then (I think) the screen blanks while the program is loading. So, alas, no loading progress screen :(

Bonknuts

  • Hero Member
  • *****
  • Posts: 3292
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #99 on: January 18, 2016, 02:48:30 PM »
(At least on the HuC side). Your graphics load, and display. Then (I think) the screen blanks while the program is loading. So, alas, no loading progress screen :(
That must be an huc thing. I don't remember what project it was, but I did have the logo static on screen with an adpcm jingle, while I did stuff (and CD loading) in the background.

TheOldMan

  • Hero Member
  • *****
  • Posts: 958
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #100 on: January 18, 2016, 02:52:32 PM »
Quote
That must be an huc thing

Could be. I didn't hunt it down :)
I suspect part of the HuC startup code does things like disable the user irqs, resets the display size, and turns the display off.
Which is why I wish I could replace the HuC startup sequence.

(Yes, I know it's possible. But I haven't gone through it enough to actually do it :)

elmer

  • Hero Member
  • *****
  • Posts: 2153
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #101 on: January 18, 2016, 03:07:04 PM »
Which is why I wish I could replace the HuC startup sequence.

One day you may decide to take a serious look at CC65.

Their PCE-specific support is still pretty shallow at the moment, but it's not actually necessary.

It only took me a few hours to put in my own startup code to get a test program running, and the flexibilty that it offers in where you put things (like its startup code and libraries) is absolutely tremendous.

It was really pleasant to be able to actually compile real ANSI C library code on the PCE (for utilities, if nothing else).

touko

  • Hero Member
  • *****
  • Posts: 953
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #102 on: March 03, 2016, 09:41:53 PM »
i found on real hardware that large VRAM transferts with TXX can cause some random artifacts on screen (you can see it at start or after some repetitive reset).
Even with 32 bytes chunks,the problem is solved with classic transferts LDA/STA(i think CPU can be halted,and not with Txx) .
Maybe if Txx occur in some hblank timings the VDC can miss some write because he is busy,and CPU can be halted ??,i don't know if it's possible or not, but i cannot find any other good explanation .
Of course that large transferts were done with display off .
« Last Edit: April 04, 2016, 02:14:33 AM by touko »

ccovell

  • Hero Member
  • *****
  • Posts: 2245
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #103 on: April 04, 2016, 01:18:32 PM »
Well, if you're doing HBlank timing, the problem could be this:

Acknowledging the HBlank and setting up the VDC for the next Hblank split requires writing to the VDC register.

Your non-interrupt code might be writing to the VDC as well.

So an H-interrupt might occur at any time between writing to the VDC register, address low-byte, and address high-byte, and data (or TXX inst.) of course.

So, that's 3 different places close together where the wrong data could go to the wrong add/reg, causing corruption (seen in BAT / tile errors).

Bonknuts

  • Hero Member
  • *****
  • Posts: 3292
Re: Graphic, Sound, & Coding Tips / Tricks / Effects / Etc.
« Reply #104 on: April 04, 2016, 02:45:38 PM »
i found on real hardware that large VRAM transferts with TXX can cause some random artifacts on screen (you can see it at start or after some repetitive reset).
Even with 32 bytes chunks,the problem is solved with classic transferts LDA/STA(i think CPU can be halted,and not with Txx) .
Maybe if Txx occur in some hblank timings the VDC can miss some write because he is busy,and CPU can be halted ??,i don't know if it's possible or not, but i cannot find any other good explanation .
Of course that large transferts were done with display off .
Txx cannot be interrupted by any interrupt (although /RDY works just fine). If you have a setup where the first hsync line is setting display attributes (X/Y position ,etc), it can delay it. Are you using HuC mixed with ASM?