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



