;Routine "MODESWIT.O" ;(C)1992 JMP-SOFT ;Well, as with a few of the routines on this issue I've put the ;instructions for using this routine in here with the source ;code listing. The routine is what I modestly call the ULTIMATE ;in mode switchers and is extremely easy to use. ;The code is relocatable to the extent that it must be resident ;in the SYSTEM PAGE (ie 16384 to 32767) and so as usual I would ;recommend that it be loaded into the SYSTEM HEAP (and as usual ;I will remind you to reserve some space first!). ;Once the code is loaded and has been called the routine is ;totally transparent to the operating system and everything will ;appear to be as normal. (If you have an issue 1 ROM (see SEXING ;SAM) then everything WILL be as normal 'cos it wont work!). ;The only difference, as far as your SAM is concerned, will be ;when any PALETTE LINEs are executed. The vector at &5B70 which ;is jumped to when ANY interrupt occurs has been made to point ;to the MODESWITCH routine and this in turn checks to see if the ;interrupt was caused by the LINE INTERRUPT REG. Just in case ;you're wondering, it is NOT possible to use the LINE INTERRUPT ;VECTOR because the code to check the existance of a value with- ;in this vector has been left out of the ROM!!! (After writing ;this routine I think it was left out because of reasons to do ;with speed, but don't quote me on that one.) ;If the interrupt is not caused by the LINE INTERRUPT then the ;routine simply passes control to the ROMs interrupt handler & ;things continue as normal. If it IS a LINE INTERRUPT then ;things are a little different. ;First a check is made to see if the palette to be changed is ;either PALETTE 3 or 4. If it isn't then a normal PALETTE LINE ;change is performed. If the PALETTE is 3 or 4 then instead of ;changing the PALETTE colour at the specified line, the routine ;changes the SCREEN MODE to the PALETTE number (3 or 4) at the ;specified line. In these cases the actual colours to place into ;the palette number are irrelevant. ;So basically if you enter PALETTE 4,0 LINE 100 then the screen ;mode will be set to MODE 4 at line 100. Similarly if you enter ;PALETTE 3,0 LINE 30 then MODE 3 will be selected at line 30. ;SOME THINGS TO REMEMBER: The MODE is not reset to its original ;state at the bottom of the screen so if you start with a MODE 3 ;screen and switch it to MODE 4 part way down but don't switch ;it back to MODE 3 then you'll just end up with a completely ;MODE 4 screen! The same limitations as with 'standard' PALETTE ;LINEs still apply. ie If you have more that one PALETTE change ;(or a MODE SWITCH and PALETTE change) on the same scan line ;then you may encounter flickering. The routine can be switched ;off by calling its start address+10. ;SOME TIPS. ;---------- ;Probably the best use for the MODESWITCHER is to start with a ;MODE 3 screen for your text and have part of it set aside for ;some MODE 4 graphics as in split screen adventures. To prepare ;the MODE 4 section of the screen I would recommend that you ;use FLASH to draw your screen in MODE 4 but before you save it ;swap to MODE 3. Then when you reload the screen into your ;program you can modeswitch the sections that you want as MODE 4 ;and use a BASIC WINDOW to do your normal MODE 3 printing within ;the window. ;THESE NEXT 2 POINTS ARE ALSO VALID FOR STANDARD PALETTE LINES. ;-------------------------------------------------------------- ;An easy way to get rid of all PALETTE LINEs (including MODE- ;SWITCHES) is to POKE &5600,&FF (this is the start of the LINE ;INTERRUPT COLOUR TABLE). You can just enter PALETTE but this ;also resets your current palette settings which is not always ;what you want! ;Because of hardware limitations it isn't possible to switch ;screen colours (or modes) at the very top line (line 191 if ;yos= -18) but it is the BASIC interpreter that wont allow you ;to use the very bottom line. However, you can get round this by ;issuing the colour change or mode switch so it is the first ;entry in the line interrupt colour table and then poking &5600 ;with 191. The mode switch or palette line will then take effect ;on the bottom line of the screen. ;The routine could also have catered for MODE 1 or 2 screens but ;because of the difference in screen formats you would just have ;ended up with a screen full of garbage!! So I didn't bother!!! ; John. ;Here comes the code starting with 2 short pieces to switch the ;routine on or off. ORG 30000 ;It is relocatable. DUMP $ start: DI ;We don't want any interrupts to ;occur whilst altering the vector. ;On entry to any code from BASIC the BC register pair will hold ;the address that has just been called. We can use this fact to ;calculate the start address of the MODESWITCHER code and then ;set the ANY INTERRUPT VECTOR to point to this address. LD HL,swap-start ;Load HL with the offset from ;the start of the code to the MODESWITCHER proper. ADD HL,BC ;Calculate modeswitch address LD (&5B70),HL ;and load the VECTOR. EI RET stop: DI LD HL,&0049 ;Address of ROMs int handler. LD (&5B70),HL ;Reset ANY INTERRUPT. EI RET ;The MODESWITCHER proper. swap: LD A,C ;On entry C = status register RRCA ;If bit 0 is reset then the ;PALETTE reg is requesting. JP C,&0049 ;It isn't so let ROM have it. LD (&5AD2),SP ;Save the stack pointer, LD SP,&4C00 ;& put it in the system page. ;By the time we get control AF, BC and HL have already been ;stacked so we only have to save DE. However B now holds the ;LO-MEM status from when the interrupt occured so we also have ;to save that. PUSH BC PUSH DE LD HL,(&5A09) ;Current address in LINE ;INTERRUPT COLOUR TABLE. another: INC HL LD A,(HL) ;See which PALETTE DEC HL CP &04 ;If 3 or 4 then modeswitch JR Z,modeswitch CP &03 JR NZ,paletteline ;otherwise paletteline. modeswitch: DEC A ;Modes 1 to 4 should be 0-3 RRCA ;Rotate them round to RRCA ;bits 7,6 and 5. RRCA LD B,A ;and save in B. IN A,(&FC) ;Get current screen page. AND &1F ;Strip off the mode bits OR B ;and replace with new mode. OUT (&FC),A ;Set new screen mode. LD D,(HL) ;Get this line and jump INC HL ;forward to see if any INC HL ;more mode switches or INC HL ;palette lines are requested INC HL ;on this or the next line. JR nextcheck paletteline: LD BC,&01F8 ;If I'd had time I'd have ;checked the scan line for a change but it's too late. However ;this still sets up the base address for the CLUT. LD D,(HL) ;Load D with scan line. INC HL LD B,(HL) ;Load B with palette number. INC HL LD A,(HL) ;Load A with the colour. OUT (C),A ;Send it out through the ;appropriate port. INC HL ;Point HL to the next entry INC HL ;in LINE INT COL TABLE. nextcheck: LD A,(HL) SUB D JR Z,another ;Another so jump back. ;Now a check is made to see if a palette line or mode switch is ;required on the next line down because there wouldn't be enough ;to return from this interrupt in time to 'catch' the next one. CP &01 JR NZ,notnextline LD B,&08 ;Wait until we're in the delay: DJNZ delay ;border again and jump back JR another ;to change on next line. notnextline: ADD D ;Set A back to next line. LD (&5A09),HL ;Update table position. OUT (&F9),A ;Output new line to L I port. POP DE ;retrieve DE POP AF ;& put LO-MEM value into A. LD SP,(&5AD2) ;Get the stack back and let JP &0054 ;the ROM finish off for us. Comet symbol tabel 00009 Labels used start 30000 &7530 stop 30010 &753A swap 30019 &7543 another 30036 &7554 modeswitch 30047 &755F paletteline 30066 &7572 nextcheck 30078 &757E delay 30088 &7588 notnextline 30092 &758C