| www.retrosoftware.co.uk http://www.retrosoftware.co.uk/forum/ |
|
| Multimode and Multipalette http://www.retrosoftware.co.uk/forum/viewtopic.php?f=73&t=568 |
Page 1 of 1 |
| Author: | tautology [ Mon Jan 17, 2011 3:31 pm ] |
| Post subject: | Multimode and Multipalette |
Alright I see some of you 6502 and Beeb experts trivial refer to doing this as if it was an every day occurrence but never actually detail the logic or code behind it. Assuming I need to do two things:
How would I do this? I can poke like mad on &FE20/&FE21 to mangle mode and palette changes; but I can never get text right (I can get 40 characters, but it stays in the mode 5/mode 4 font). I've tried looking at the AUG for the System VIA; but the scan's pretty poor and the writing seems to assume that people are only going to use it for device IO. The example in Mastering Assembler Code doesn't seem to work. I've even disassembled the BBC Elite for the mode changing code, which loses me at this bit: Code: lsr a lda #&1e sta &8b sta &fe44 lda #&39 sta &fe45 lda &348 bne &116f (Which seems to be setting up the timer). Has anybody got any working, sample code for getting the system VIA timer working for a mode/palette switch? |
|
| Author: | RichTW [ Mon Jan 17, 2011 3:57 pm ] |
| Post subject: | Re: Multimode and Multipalette |
It sounds like you have the mode split working OK, but the OS is configured for Mode 5 when displaying characters. So the simplest thing would be to explicitly select Mode 4 instead, and perform your mode split exactly as you are now - and then, calls to OSWRCH should display Mode 4 characters correctly. I'm assuming you don't need any Mode 5 text at all, right? The mechanics of the mode split are something like this. I'm going to describe a method which uses 'legal' methods, i.e. work alongside the OS without problems, so you can still do character printing and input via the normal calls. Hook into the VSync event: - put the address of your handler in &220/&221 - enable the VSync event with *fx 14,4 In the VSync event handler: - check if it's a VSync event, like this: Code: CMP #4 BNE notvsync <handle vsync here> - set up the Video ULA (&FE20/&FE21) for the top screen mode. - set an unused timer (e.g. User VIA T2 at &FE68) to interrupt a certain time later. Do that like this: Code: LDA #time MOD 256 ; set timer low byte STA &FE68 LDA #time DIV 256 ; set timer high byte STA &FE69 As a rough guide, if the screen is positioned with *TV 0,1, the value of time is (5 + screen character row) * 512. There'll be a fair amount of wobble if you're doing it 'legally' like this, due to the latency which arises from the OS's interrupt handler running with interrupts disabled, and not always letting the split mode interrupt get serviced immediately. I recommend, when trying to get the value right, have it change the background colour, so you can clearly see where the split is. Also leave a blank buffer of at least 3 or 4 pixel lines, to hide any wobble. Enable and hook into the User VIA T2 interrupt: - Enable the interrupt, like this: Code: LDA #&A0 STA &FE6E - Claim the IRQ1V, like this: Code: SEI LDA #irqhandler MOD 256 STA &204 LDA #irqhandler DIV 256 STA &205 CLI - Check for the timer interrupt in irqhandler, like this: Code: LDA &FE6D AND #&20 ; check T2 flag BNE nottimer STA &FE6D ; acknowledge interrupt .. - Then perform palette and mode changes for bottom screen mode (&FE20/&FE21), and finally JMP (oldirq1v) which should contain the previous contents of the IRQ1V. As long as you touch only A (not X or Y), there's no need to preserve any registers or flags on the stack, because the 6502 has already pushed the flags to the stack, and the OS handler stub has already saved A in &FC. Also, somewhere on this forum, I did post some sample code for doing pretty much this, although it was not an OS-friendly method, so it might not be so useful. |
|
| Author: | tautology [ Mon Jan 17, 2011 6:40 pm ] |
| Post subject: | Re: Multimode and Multipalette |
Hmmm, this sort of works, but from the top of the screen until the interrupt point I'm getting a moving line, which starts replacing the colour, then moves down till the interrupt point; then goes back to the top again! The other question is why are we using VIA2, instead of VIA1, when we could just set up one interrupt to manage both the vsync and timer (as Elite does)? |
|
| Author: | RichTW [ Mon Jan 17, 2011 10:57 pm ] |
| Post subject: | Re: Multimode and Multipalette |
Hmm, I didn't try the code, so there's every chance I missed something somewhere. I have no idea what the moving line is though. Could you post the code perhaps, and maybe we can spot the problem? You need two interrupts because you need to set up the Video ULA twice per frame - the VSync makes sure we are synched to the same point each frame, and then the timer (which is set to a constant value relative to the VSync) interrupts at a regular place in the middle of the frame. It'd be possible to use Timer 1 too, and it could be set up in free-run mode to interrupt every 50Hz (so there was no need to write its value each VSync), but this is a bit more fiddly to set up. I just used Timer 2 in this example so that there's still a free-run timer free should it be needed. Also the example uses the User VIA rather than the System VIA, because the latter is used by the OS, and certain things stop working properly if you change its values. |
|
| Author: | tautology [ Tue Jan 18, 2011 12:25 am ] | ||
| Post subject: | Re: Multimode and Multipalette | ||
Unfortunately for me - I tried in the BASIC assembler, rather than beebasm, but I managed to get it out using print to file from beebem: Code: 20FOR ION=0 TO 2 STEP 2 30P%=&A00 40[OPTION 50.INIT 60SEI 70LDA &220 80STA &70 90LDA &221 100STA &71 110LDA #event MOD 256 120STA &220 130LDA #event DIV 256 140STA &221 141LDA #14 142LDX #4 143JSR &FFF4 150LDA &204 160STA &72 170LDA &205 180STA &73 190LDA #irq MOD 256 200STA &204 210LDA #irq DIV 256 220STA &205 221LDA #&A0 222STA &FE6E 230CLI 240RTS 250.event 260CMP #4 270BNE notvsync 280TXA:PHA 290LDX #3 300.loop LDA pal1,X 310STA &FE21 320DEX 330BPL loop 340PLA:TAX 350LDA #3680 MOD 256 360STA &FE68 370LDA #3680 DIV 256 380STA &FE69 390.notvsync 400JMP (&70) 410.irq 420LDA &FE6D 430AND #&20 440BNE nottimer 450STA &FE6D 460TXA:PHA 470LDX #3 480.loop2:LDA pal2,X 490STA &FE21 500DEX 510BPL loop2 520PLA:TAX 530.nottimer 540JMP (&72) 550.pal1 560EQUD &00104050 570.pal2 580EQUD &07174757 590] 591NEXT 595MODE 1 596CALL INIT 600FOR I=0 TO 25:COLOUR I MOD 4:PRINT "WIBBLE":NEXT 610GOTO 610 This only does a palette switch of colour 0 at the moment (starting small). I'm using X as an index, so I'm having to save X to the stack (which I know isn't production perfect - even though Elite does this). I've attached the UEF if that makes it easier. Also, thanks in advance for helping me with this - I may not even use it (as I may end up using a 16k squeezed mode 1 screen) - but its helpful for me to try and get around the nuts and bolts of how the Beeb hardware works, which I missed as I was an Elk owner!
|
|||
| Author: | RichTW [ Tue Jan 18, 2011 8:14 am ] |
| Post subject: | Re: Multimode and Multipalette |
Oops, sorry it's my fault. Change BNE nottimer to BEQ nottimer, and all works as expected! |
|
| Author: | tautology [ Tue Jan 18, 2011 10:46 pm ] |
| Post subject: | Re: Multimode and Multipalette |
Yep it now works; that's neat and easy to do (as long as I get the palette right and leave a gap). I'm impressed that you wrote that from first principles with only one minor error (and I should've spotted it too)! Thanks very much - even if I don't use it - it's useful to have! |
|
| Author: | tautology [ Wed Feb 09, 2011 1:19 pm ] |
| Post subject: | Re: Multimode and Multipalette |
I was messing around with the concepts above... I found the quickest way of getting 7 colours on Mode 1 is to mess around with the flashing colours:
Attachment: This way the interrupt is simply (for MODE 1): Code: LDA #&D8 andSTA &FE20 Code: LDA #&D9 STA &FE20 Saves messing around with changing all the palette registers! Now if only I can get this to work in the middle of a line (though I'm not certain that's possible). I'm still not 100% certain how the timing works. |
|
| Author: | RichTW [ Wed Feb 09, 2011 2:14 pm ] |
| Post subject: | Re: Multimode and Multipalette |
Ahhh that's a good idea - I never thought of that one! You can do the colour/mode split at any point, even halfway across a scanline if you want. But if you're still letting the OS in, the latency is far too high to be able to get this accurate enough - as I say, you'll most likely have an uncertainty of a couple of scanlines (and even more if you keep pressing keys and generating a load of interrupts, or using the disc system, for example). The timer value can be worked out exactly; it depends on:
But it's difficult to come up with a precise formula when trying to do everything legally (so it works alongside the OS). The important thing to know is that (in non-interlaced modes), each scanline takes exactly 128 clock cycles (which is 64 ticks of the 1MHz timers), so from this you can probably position your split more-or-less by trial and error. |
|
| Author: | tautology [ Mon Feb 14, 2011 7:02 pm ] |
| Post subject: | Re: Multimode and Multipalette |
I did do some messing around; I couldn't get an interrupt to occur in the middle of a line, but managed about 8 palette changes without massive slowdown. This is on mode 1, so you may be able to get more on mode 5. Then I had to stop as the flickering lines I used to show me that it was working started to give me a migraine! |
|
| Author: | BillCarr [ Wed Feb 23, 2011 2:06 pm ] | ||
| Post subject: | Re: Multimode and Multipalette | ||
Found this on an eBay disk. Haven't checked the code to see exactly how it works, but thought it applied to this thread!
|
|||
| Author: | DaveM [ Wed Feb 23, 2011 2:44 pm ] |
| Post subject: | Re: Multimode and Multipalette |
Cor blimey! |
|
| Author: | tautology [ Wed Feb 23, 2011 7:09 pm ] |
| Post subject: | Re: Multimode and Multipalette |
Interesting - it saves the OS vdu variables whilst setting up the screen and copies them all during the interrupt. Nicely done and the minimal amount of judder is very good! Good find! |
|
| Page 1 of 1 | All times are UTC [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|