Jump to content
IGNORED

Changing a character set in a display list interrupt


Recommended Posts

I'm trying to do this - several articles said it's possible, but they didn't include an example.

 

I'm trying to use a different characterset midway down the screen, but obviously I'm doing something wrong.

 

when I run this, only the last character set is used - for the entire screen.

 

However the color changes work as expected. So, you don't just poke in the high byte of the character set location?

        .export _setup_dli_asm
        .import FONTADR, FONTADR2
        .segment "CODE" 
_setup_dli_asm: 
        ldy #<DLIRTN
        sty $0200
        ldy #>DLIRTN
        sty $0201
        RTS 
DLIRTN: 
        WSYNC=$D40A
        COLOR0=$D016
        COLOR1=$D017
        COLOR2=$D018
        COLOR3=$D019
        COLOR4=$D01A ; color 4 is background
        PHA
        LDA #$00
        STA WSYNC
        LDA #$E0 ; 
	    STA $02F4
        LDA #10
        STA COLOR0   ; PF0 black
        LDA #14      
        STA COLOR1   ; PF1 white
        LDA #6       ; 
        STA COLOR2   ; PF2 darker grey
        LDA #34 ;
        STA COLOR3   ; PF3 red
        LDA #0 ;
        STA COLOR4   ; PF4, BAK is lighter grey
        LDA #<DLIRTN2
        STA $0200
        LDA #>DLIRTN2
        STA $0201
        PLA
        RTI
          
DLIRTN2:
        PHA
        LDA #$00
        STA WSYNC;
        LDA #>FONTADR2 
	    STA $02F4
        LDA #$C4 ;  green
		STA COLOR2;
        LDA #<DLIRTN3
        STA $0200
        LDA #>DLIRTN3
        STA $0201
        PLA
        RTI
        
 DLIRTN3: 
        PHA
        LDA #$00
        STA WSYNC
        LDA #>FONTADR
	    STA $02F4
        LDA #10
        STA COLOR0   ; set up this third one just for testing
        LDA #14      
        STA COLOR1   
        LDA #6       ; 
        STA COLOR2  
        LDA #34 ;
        STA COLOR3   
        LDA #0 ;
        STA COLOR4   
        LDA #<DLIRTN
        STA $0200
        LDA #>DLIRTN
        STA $0201
        PLA
        RTI
Link to comment
Share on other sites

CHBAS ($02F4) is the OS shadow location of the hardware register CHBASE ($D409). The OS copies CHBAS to CHBASE in vertical blank. This means that you can change CHBAS without causing a glitch in the middle of the screen, but since you actually need to do that for a DLI handler, you need to write to CHBASE directly.

 

Incidentally, you have the wrong names for the color registers. COLOR0-COLOR4 are the OS shadow registers at $02C4-02C8. The hardware color registers at $D016-D01A are called COLPF0-COLPF3 and COLBK.

Link to comment
Share on other sites

You could equally do what you want with the same block of code for 2 or more DLIs. Just maintain an index then keep stuff like chset values and colours in tables.

 

That said, your program has a bug. When it's initializing there's no way to know which DLI will trigger first, so each run there's random chance of where each chset appears (of course the one that the OS sets in VBlank will be always right).

 

The trick there is either use indexes and same routine like I said, then set the index value to 0 again in a VBlank Immediate routine.

Or have the initialize part of your program wait for the active scanline to be outside the display.

 

 

  lda $14 ; get rtclock value
waitvb  cmp $14
  beq waitvb ; wait until rtclock changes, this means the active scanline will be offscreen
  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

btw small update on this, I did change to indexing. But, I find that changing a charset in a dli takes a lot of time, I don't know why. But I can do very little in one scan line, I'm often taking a second one. The charset command, by my eyes, isn't a lot of cycles...I mean to just STA ---but on the simulators if I do much else, it's going to go into the next scanline.

Link to comment
Share on other sites

The trick is to preload registers. How many you do depends on how many you've saved to the stack. But generally if you save A, X, Y to the stack you'll run past the point where a STA WSYNC would return control.

 

At the least you can preload A. Also, if you do your calculations right you can do without the STA WSYNC altogether in some situations. As long as the DMA situation is fairly stable, ie PMGs are always active or not, fine scrolling of either type isn't active on that scanline, and the line isn't in wide DMA mode.

 

Sometimes you just don't have enough time. It's at that point where you either have to sacrifice something, or use a blank line to free up more cycles.

Link to comment
Share on other sites

Saving and reloading the index registers to and from some pre-defined ZP locations is faster than TXA/PHA, PLA/TAX, etc. Then you have a little more time and can pre-load registers as Rybags suggests. Load up A, X and Y before STA WSYNC, then STA/STX/STY to your hardware registers. You may need to load and store again (if you're hitting more than three registers), but at least the WSYNC store was pushed back somewhat and you did more work beforehand, so there's less to do in the horizontal blank.

Link to comment
Share on other sites

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...