Star Tip 8 - 128K routines - "Program Pitstop" by David Jones from Your Sinclair 24 (Dec.1987) David Jones is no stranger to these pages, having contributed a brilliant little tip to last month's Shop. Being a generous kind of gut, he's listed out some useful routines for 128 programmers, which you can use to make really whizzy games. Not much explanation is needed, because the routines are heavily commented, but here's a quick resume of what they do. PSWAP - 128 page swap PAGEA - calls sub-routine on any page IMODESET - sets up Interrupt Mode 2 IMODE - Interrupt handler MUSICON, MUSICOFF, PLAYIT - samples of how to call a sub-routine [There was no MUSICOFF routine listed in the magazine. JimG] RAM PAGE ALLOCATION --- ROM ---!-- PAGE 2 --!- FIXED RAM -!-- !- SCREEN$1 -!-- PAGE 5 --! USL PAGE 0 - NORMALLY RESIDENT AT C000H INTERRUPT VECTORS AND MAIN CODE PAGE 1 - AT C000H PAGE 2 - FIXED RAM PAGE AT 4000H PAGE 3 - AT C000H PAGE 4 - AT C000H PAGE 5 - FIXED RAM PAGE AT 8000H PAGE 6 - AT C000H PAGE 7 - SCREEN$ 2 AT C000H MUSICFLG: DB 0 DEFSCR: DB 0 FIXPAGE: DB 0 PAGENO: DB 0 ;Note: These subroutines must be placed below C000H to work properly. ; Crashes result otherwise. PAGEPORT: EQU 7FFDH ;This subroutine will change the page at C000H. ;Entry Conditions: ;A register = new page number ;Exit Conditions: ;FIXPAGE contains new page number ;A register = value sent to port ;All other registers preserved PSWAP: PUSH BC LD (FIXPAGE),A LD C,A LD A,(DEFSCR) ADD A,C ;add 8 if alternate screen is on show OR 16 LD BC,PAGEPORT ;ensure Spectrum ROM always present OUT (C),A POP BC RET ;CALL a subroutine on a given page at a given address. ;Entry Conditions: ;A register = page number ;HL register pair = address of subroutine ;Exit Conditions: ;FIXPAGE contains new page number ;A register = value sent to port ;All other registers preserved PAGEA: LD (PAGEAV+1),HL CALL PSWAP PAGEAV: CALL 0 ;call address supplied in HL on entry at PAGEA PUSH AF XOR A CALL PSWAP ;set page 0 in place (normal 48K page) POP AF RET ;Music Control Routines MUSICON: LD HL,MON ;address of Music On subroutine LD A,MPAGE ;page number where music is stored JR PAGEA PLAYIT: LD A,(MUSICFLG) OR A RET Z LD HL,MPLAY ;address of Play Music subroutine LD A,MPAGE ;page number where music is stored JR PAGEA ;Interrupt Mode Setup ;Top useable memory address equals 0FFF3H (65523) ;due to interrupt control code. ;FFF4H IVECTOR:JP IMODE ;FFF7H @BB8 :DS 8 ;(8 byte temp store buffer) ;FFFFH JR IVECTOR IMODESET: POP HL ;return address LD SP,NEWSTACK PUSH HL XOR A LD (DEFSCR),A LD (IY+65),A ;IMODE off LD (IY+87),3 ;OVER 1 LD (IY+48),8 ;CAPS on LD HL,IMODETAB IMODELP: LD A,(HL) CP 255 JR Z,IMODELX PUSH HL CALL PSWAP LD A,18H LD (0FFFFH),A LD A,0C3H LD (0FFF4H),A ;JP IMODE LD HL,IMODE LD (0FFF5H),HL POP HL INC HL JR IMODELP IMODELX: XOR A CALL PSWAP LD HL,0BE00H LD A,H ;place in I reg below LD DE,0BE01H LD BC,256 LD (HL),255 LDIR ;build 257*0FFH table DI LD I,A EI HALT XOR A LD (IY+65),A IM 2 ;re-vectored interrupts RET IMODETAB: DB 0,1,3,4,6,7,255 ;Interrupt Handler ;Note that this doesn't do anything useful here except play the tune, ;which can be placed on a different page. I have included it so that ;you can place your own sub-routines below (ie. Sprites). IMODE: PUSH AF LD A,(FIXPAGE) LD (IMODEV+1),A CALL PLAYIT ;Place your sub-routines here LD HL,(FRAMES) INC HL LD (FRAMES),HL LD A,H OR L JR NZ,IMODEX INC (IY+64) ;FRAMES+2 IMODEX: CALL 02BFH ;keyboard scan IMODEV: LD A,0 CALL PSWAP ;Now POP all the registers that you pushed earlier. POP AF EI RET