**************************************************************** * * Software: LARRY DeMAR, EUGENE JARVIS * Modified: Shawn Liptak 8/6/91 - Multi color fonts * * COPYRIGHT (C) 1991 WILLIAMS ELECTRONICS GAMES, INC. * *.Last mod - 9/25/91 14:55 **************************************************************** .FILE 'HSTD.ASM' .TITLE "ROBO HIGH-SCORE-TO-DATE MANAGEMENT" .WIDTH 132 .OPTION B,D,L,T .MNOLIST .INCLUDE "MPROC.EQU" ;MPROC EQUATES .INCLUDE "DISP.EQU" ;DISPLAY PROC. EQUATES .INCLUDE "\VIDEO\SYS\SYS.INC" ;Z UNIT SYSTEM EQUATES .INCLUDE "\VIDEO\SYS\MACROS.HDR" ;MACROS DEFINITIONS .INCLUDE "GAME.EQU" .INCLUDE "IMGTBL.GLO" .INCLUDE "LINK.EQU" ;LINKY EQUATES .TEXT * IN THIS MODULE .DEF GET_HSCR .DEF RC_BYTEI .DEF RC_BYTE .DEF RC_WORD .DEF RC_LONG .DEF RC_LONGI .DEF WC_BYTE .DEF WC_BYTEI .DEF WC_WORD .DEF WC_WORDI .DEF WC_LONG .DEF WC_LONGI .DEF PT_ENTRY .DEF INIT_TB .DEF INIT_TAB ;GEORGES POWER UP ENTRY .DEF P_FORK .DEF VAL_TAB .DEF ROM_PTRS .DEF ALL_TAB .DEF TOD_TAB .DEF ISHSTD,GETINIT,GETINIT1,GETINIT2,INITTIM .DEF SET_PAGE .DEF A2_CHECK .DEF DEC_HSR,INIT_HSR,GET_HSC .DEF GETHIGH .def INITMAT * OTHER MODULES .REF RD15FONT,SYSCOPY,P1DATA,P2DATA,GPALOBJ .REF BINBCD,FON150 ; .REF AFONT0,GOGO * HELP.ASM .REF DEF_PAGE,GET_ADJ .TEXT ************************************************************************** * * HIGH SCORE TABLE DEFINITIONS * ************************************************************************** ALL_TAB .LONG ALL_TIME_ORIGIN ;LOCATION OF TABLE .WORD ALL_TIME_ENTRIES-1 ;NUMBER IN THE TABLE (DON'T COUNT ZERO FILLER) .WORD ALL_TIME_VISIBLE ;# VISIBLE (SHOW 20 ALL TIME) .WORD ALL_TIME_SELECT ;BITS TO SELECT IT .LONG ALL_TIME_ROM_TABLE ;ROM IMAGE OF TABLE .WORD ALL_TIME_ENTRIES/5 ;RESET TABLE IF 1/5 OR MORE BAD TOD_TAB .LONG TODAYS_ORIGIN ;LOCATION OF TABLE .WORD TODAYS_ENTRIES-1 ;NUMBER IN THE TABLE (DON'T COUNT ZERO FILLER) .WORD TODAYS_VISIBLE ;# VISIBLE (SHOW 20 ALL TIME) .WORD TODAYS_SELECT ;BITS TO SELECT IT .LONG TODAYS_ROM_TABLE ;ROM IMAGE OF TABLE .WORD TODAYS_ENTRIES/5 ;RESET TABLE IF 1/5 OR MORE BAD P_FORK MMTM SP,A1 MOVE *A13(PROCID),A1 ;PASS OUR ID TO FORKED PROCESS CALLA GETPRC ;MAKE THE PROCESS MMFM SP,A1 RETS ************************************************************************** * * AUTO HIGH SCORE TABLE RESET HANDLING * ************************************************************************** * * DEC_HSR * * THIS IS CALLED WITH EACH START OR CONTINUE FOR * A PLAYER. IT REMOVES 1 FROM THE HSTD COUNTER UNLESS * ITS ALREADY SITTING AT ZERO. * ************************************************************************** DEC_HSR MMTM SP,A0 CALLR GET_HSC ;THIS IS EASY...GET THE COUNTER JRZ DECHX ;ITS ZERO....NO ACTION. DEC A0 ;REMOVE A TICK CALLR PUT_HSC ;PUT IT BACK JAK DECHX MMFM SP,A0 RETS ************************************************************************** * * DELAY_HSRESET * * THIS IS CALLED WHEN A NEW ENTRY IS MADE IN THE ALL TIME * HIGH SCORE TABLE. IF WE'RE CLOSE TO A HIGH SCORE * RESET, WE PUT IT OFF AWHILE SO HE CAN SHOW HIS FRIENDS * FOR A FEW DAYS. * ************************************************************************** HS_MIN EQU 750 ;ALWAYS 750 PLAYS BEFORE REMOVING A FRESH * ;NAME. DELAY_HSRESET: MMTM SP,A0 CALLR GET_HSC ;THIS IS EASY...GET THE COUNTER CMPI HS_MIN,A0 ;IS IT TOO LOW JRHS DHX ;NOPE...NO ACTION MOVI HS_MIN,A0 ;STOP THE RESET! CALLR PUT_HSC ;THIS MANY PLAYS TILL RESET! DHX: MMFM SP,A0 RETS ************************************************************************** * * INIT_HSR * * THIS IS CALLED TO INITIALIZE THE HIGH SCORE RESET * COUNTER TO ITS ADJUSTED VALUE. * ************************************************************************** INIT_HSR MMTM SP,A0 MOVI ADJHSRES,A0 CALLA GET_ADJ ;GET THE ADJUSTED VALUE CALLR PUT_HSC ;SET IT TO THIS VALUE MMFM SP,A0 RETS ************************************************************************** * * PUT_HSC * * THIS IS CALLED TO SET THE HIGH SCORE RESET COUNTER * TO THE VALUE IN A0. * ************************************************************************** PUT_HSC MMTM SP,A7,A0 CALLR HSR_PAGE ;HIGH SCORE PAGE MOVI HRESET_COUNTER,A7 ;POINT AT CALLR WC_LONGI ;WRITE OUR PARAMETER NOT A0 ;NEGATE IT. CALLR WC_LONG ;AND WRITE IN SUBSEQUENT SPOT. CALLA DEF_PAGE ;FLIP PAGE MMFM SP,A7,A0 ;AND RETURN RETS ************************************************************************** * * GET_HSC * * THIS IS CALLED TO FETCH THE HIGH SCORE COUNTER IN A0. * IF IT IS INVALID, IT WILL IMMEDIATELY BE RESET TO THE * ADJUSTED VALUE AND THIS IS WHAT WILL BE RETURNED * IN A0. Z set if 0 * ************************************************************************** GET_HSC MMTM SP,A7,A1 CALLR HSR_PAGE ;POINT PAGE AT HSR MOVI HRESET_COUNTER,A7 ;POINT AT CALLR RC_LONGI ;READ THE VALUE MOVE A0,A1 ;STASH IT CALLR RC_LONG ;READ VERIFIER NOT A0 ;SEE IF ITS VALID CMP A0,A1 JRZ GET_HSCX ;IT IS....RETURN IT. CALLR INIT_HSR ;REFRESH IT WITH FACTORY VALUE * * NOW RETURN THE FACTORY VALUE IN CASE IT DIDN'T TAKE * MOVI ADJHSRES,A0 CALLA GET_ADJ ;GET THE ADJUSTED VALUE GET_HSCX CALLA DEF_PAGE ;FLIP PAGE AWAY FROM US MOVE A0,A0 ;SET Z FLAG BASED ON COUNTER MMFM SP,A7,A1 RETS HSR_PAGE MMTM SP,A1 MOVI HSR_SELECT,A1 CALLR SET_PAGE MMFM SP,A1 RETS ********************************************************************** * *DISPLAY HIGH SCORE TABLE * ********************************************************************** GETHIGH movi ALL_TIME_SELECT,a1 callr SET_PAGE movi [62,27],a10 ;Screen start address movi ALL_TIME_ORIGIN+HS_INITS+HS_SIZE,a8 ;Table start address JSRP HSINITDSP movi [62,63],a10 movi ALL_TIME_ORIGIN+HS_SCORE+HS_SIZE,a8 JSRP HSNUMDSP movi TODAYS_SELECT,a1 CALLR SET_PAGE movi [62,227],a10 movi TODAYS_ORIGIN+HS_INITS+HS_SIZE,a8 JSRP HSINITDSP movi [62,263],a10 movi TODAYS_ORIGIN+HS_SCORE+HS_SIZE,a8 JSRP HSNUMDSP RETP ******************************** * DISPLAY SCORE TABLE SCORES IN ATTRACT * A8=TABLE INDEX * A10=DISPLAY COORD Y:X HSNUMDSP MOVK 10,A11 ;START WITH SCORE 1 movi >1010101,a9 ;Start color 1, pal 1 hsn10 move a8,a7 CALLR RC_LONG ;GET THE SCORE=A0 move a7,a8 MOVE A10,A3 ;DEST Y:X CLR A6 ;BLANKING FLAG move a12,-*sp,L MOVK 8,A12 CALLR HSNUML0 move *sp+,a12,L SLEEPK 1 addi HS_SIZE,a8 addi >120000,a10 ;Next line dsj a11,hsn10 RETP ******************************** * DMA a BCD number * A0=# * A3=Y:X * A6=Blank flag (0=ON) * A9=Color:Pal * A12=#Digits *Rets: * A9=Next Color:Pal HSNUML0 mmtm sp,a2,a3,a4,a5,a7,a8,a10 move a0,a1 srl 4*3,a1 jrz hsn2 ;No comma? subk 6,a3 ;-X hsn2 move a0,a1 srl 28,a1 ;Next digit value into lowest 4 bits jrnz hsn5 move a6,a6 jrz hsn50 ;Skip digit if blanking hsn5 cmpi 3,a12 jrnz hsn13 move a6,a6 jrz hsn13 ;1st non zero? move a1,-*sp movi RD15FONT+11*32,a1 ;Comma move *a1,a1,L move a3,a10 addi >b0000,a3 ;+Y callr font_dma move a10,a3 addk 6,a3 ;+X move *sp+,a1 hsn13 cmpi 9,a1 jrls hsn15 ;Digit ok? movk 9,a1 ;Output 9 on an error hsn15 movk 1,a6 ;Blanks off move a3,a10 cmpi 1,a1 jrnz hsn30 addk 3,a3 ;Offset 1's X hsn30 sll 7,a1 ;*128 (next header please!!) addi FON150,a1 ;Base address of image header callr font_dma move a10,a3 hsn50 addk 14,a3 ;step to next sll 4,a0 ;next digit dsj a12,hsn2 addi >f0f0000,a9 cmpi >30300000,a9 jrls hsnx addi >101,a9 ;Next PAL zext a9 addi >1010000,a9 ;Color 1 hsnx mmfm sp,a2,a3,a4,a5,a7,a8,a10 rets ******************************** * DMA a character (trashes a1-a5,a7-a8) * A1=*Obj header * A3=Y:X * A9=Color:Pal font_dma move *a1(>40),a4,L ;Get sag move *a1+,a2 ;Get X size move a2,a7 addk 3,a7 ;Round up to 4 bit boundary srl 2,a7 sll 5,a7 ;X size*8 addi >10000,a2 ;Y Size 1 move *a1+,a8 ;Get Y size movi DMACNZ,a5 move a9,a1 fd20 calla QDMAN addi >1010000,a1 ;Next color add a7,a4 ;Set SAG for next line addi >10000,a3 ;Y+1 dsj a8,fd20 rets ******************************** * DISPLAY SCORE TABLE INITIALS IN ATTRACT * A8=TABLE INDEX * A10=DISPLAY COORD Y:X HSINITDSP movk 10,a11 ;10 Scores hsid10 move a8,a7 subi HS_INITS,a7 callr RC_LONG ;Get the score in a0 move a0,a2 addi HS_INITS,a7 move a10,a3 ;Y:X movi >01010101,a1 ;Flash if inits match score callr A2_CHECK jrz hsid30 movi >1f1f0303,a1 ;Color:pal hsid30 move a12,-*sp,L movk 3,a12 hsid50 callr RC_BYTE ;Get initial addk 16,a7 ;Step to next initial callr initout ;Output initial dsj a12,hsid50 move *sp+,a12,L addi >120000,a10 ;Next Y move a7,a8 SLEEPK 1 addi HS_SIZE-48,a8 ;Get next guy in cmos dsj a11,hsid10 RETP ******************************** *OUTPUT INITIAL RD15FONT * A0=ASCII * A1=COLOR:PALETTE * A3=Y:X *Rets: * A3=New Y:X initout mmtm sp,a1,a2,a4,a5,a7,a8,a9,a10 subi >21,a0 ;Start of table cmpi >7d->21,a0 jrhi inox sll 5,a0 addi RD15FONT,a0 move *a0,a0,L ;Get pointer move *a0(>40),a4,L ;Get sag move *a0+,a2 ;Get X size move a2,a7 addk 3,a7 ;Round up to 4 bit boundary srl 2,a7 sll 5,a7 ;X size*8 movk 12,a9 sub a2,a9 sra 1,a9 ;/2 add a9,a3 ;Add X offset so letter centered addi >10000,a2 ;Y Size 1 move *a0+,a8 ;Get Y size move a3,a10 movi DMACNZ,a5 ino20 calla QDMAN addi >1010000,a1 ;Next color add a7,a4 ;Set SAG for next line addi >10000,a3 ;Y+1 dsj a8,ino20 move a10,a3 sub a9,a3 inox addk 17,a3 mmfm sp,a1,a2,a4,a5,a7,a8,a9,a10 rets ******************************** *OUTPUT INITIAL RD15FONT *A0=ASCII *A1=COLOR:PALETTE *A3=COORD Y:X INITOUT MMTM SP,A2,A4,A5 SUBI >21,A0 ;ADJUST TABLE BOGOSITY CMPI >7D->21,A0 jrhi initerr SLL 5,A0 ADDI RD15FONT,A0 MOVE *A0,A0,L ;GET POINTER MOVE *A0,A2,L ;GET SIZE movk 12,a4 subxy a2,a4 sext a4 sra 1,a4 ;/2 add a4,a3 ;Add X offset so letter centered move a4,-*sp MOVE *A0(>40),A4,L ;GET SAG MOVI DMACNZ,A5 CALLA QDMAN move *sp+,a0 sub a0,a3 initerr addk 17,a3 MMFM SP,A2,A4,A5 RETS ************************************************************************** * * HIGH LEVEL HSTD ROUTINES * ************************************************************************** ;TEN_X EQU 0F00000H ;ONE_O_X EQU 0F40000H ;ONE_X EQU 0FE0000H ; ;TIMER_TENS: ; .LONG 0,0,TEN_X,1500000H ;XV, YV, XP, YP ; .WORD 0,30 ;Z VEL 10....Z POS 0 ; .LONG NO_IMG,1,0 ;IMG, Z SIZE, COLLISION VECT ; .WORD DMACNZ,5 ;WRITE NON-ZERO CONSTANT, OBJECT ID ; .LONG 0 ;NO SCANNER BLIP ; ;TIMER_UNITS: ; .LONG 0,0,ONE_X,1500000H ;XV, YV, XP, YP ; .WORD 0,30 ;Z VEL 10....Z POS 0 ; .LONG NO_IMG,1,0 ;IMG, Z SIZE, COLLISION VECT ; .WORD DMACNZ,5 ;WRITE NON-ZERO CONSTANT, OBJECT ID ; .LONG 0 ;NO SCANNER BLIP ; ;NO_IMG: ; ; .WORD 4,4,0,0 ;WIDTH, HEIGHT, OFFSET,OFFSET ; .LONG IROM,0 ;SOURCE, PALETTE ; ;TIMER_COLOR EQU 0F5F5H ;CONSTANT USED FOR TIMER ; ;SETUP_TIMER: ; MOVI TIMER_UNITS,A14 ; CALLR GET_DIGIT ; MOVE A0,A9 ;KEEP UNITS IN A9 ; ; MOVI TIMER_TENS,A14 ; CALLR GET_DIGIT ; MOVE A0,A10 ;THEY'RE SET! ; RETS ; ;GET_DIGIT: ; MMTM SP,A1 ; CALLA GPALOBJ ;GET THE STUFF ; CALLA STFOBJ ; ; MOVI TIMER_COLOR,A1 ; MOVE A1,*A0(OCONST),W ; ; CALLA INSOBJ ;ITS SET ; MMFM SP,A1 ; RETS ; ;UPDATE_TIMER: ; MOVE A0,A3 ;FIRST DO TENS ; MOVE A3,A1 ; SRL 4,A1 ; JRNZ REAL_TENS ; ; MOVE A10,A0 ; JRZ TENS_GONE ; CALLA DELPAL ;TRASH IT! ; CALLA DELOBJ ; CLR A10 ; ; MOVI (TEN_X+ONE_X)/2,A0 ; MOVE A0,*A9(OXVAL),L ;CENTER THE ONES ; ; JRUC TENS_GONE ; ;REAL_TENS: ; CMPI 1,A1 ;ARE WE DOWN TO "10" ; JRNZ NOT_ONE_0 ; ; MOVI ONE_O_X,A0 ; MOVE A0,*A10(OXVAL),L ;SLIDE IT OVER TO LOOK NICE! ;NOT_ONE_0: ; MOVE A10,A2 ;GET 10'S OBJECT IN A2 ; CALLR UPDATE_NUMBER ;OBJECT A2 GETS NUMBER IN A1 ; ;TENS_GONE: ; MOVE A3,A1 ; MOVE A9,A2 ; CALLR UPDATE_NUMBER ; RETS ; ;BLANK_TIMER: ; MMTM SP,A0 ; CLR A0 ; MOVE A0,*A9(OCONST),W ; MOVE A10,A10 ;TENS PRESENT? ; JREQ BT_NT ;NOPE ; MOVE A0,*A10(OCONST),W ;BT_NT: ; MMFM SP,A0 ; RETS ; ************************************************************************** * * UPDATE_NUMBER * * OBJECT IN A2 * NIBBLE IN A1 * * GET CORRECT NUMBER IMAGE IN THE OBJECT. * ************************************************************************** ;UPDATE_NUMBER: ; MMTM SP,A1,A4,A6,A7,A8 ; MOVI RD15FONT,A6 ; ANDI 0FH,A1 ; ADDI LET_0-EX_PT,A1 ;INDEX TO TABLE ; SLL 5,A1 ; ADD A1,A6 ;POINT TO IMAGE (A1 FOR ANI) ; MOVE *A6,A1,L ;FETCH THE IMAGE FOR ANI ; ; MOVE A2,A8 ;OBJECT STRUCTURE FOR ANI ; MOVE *A2(OFLAGS),A4 ;FETCH THE OFLAGS ; CALLA ANI ;SET NEW ANIMATION PICTURE ; ; MOVI TIMER_COLOR,A6 ;GET THE DRAWING COLOR BACK OUT. ; MOVE A6,*A2(OCONST),W ; ; MMFM SP,A1,A4,A6,A7,A8 ; RETS ; *************************************************************************** * * ISHSTD * * DID ANYONE MAKE THE HIGH SCORE TABLE. * A0=0 NO (EQ) * A0=1 PLAYER 1 MADE IT (NE) * A0=2 PLAYER 2 MADE IT (NE) * A0=3 NOBODY MADE IT (NE) * *************************************************************************** ISHSTD MMTM SP,A8,A10 MOVK 1,A0 MOVE @P1DATA+PSCORE,A8,L MOVE @P2DATA+PSCORE,A10,L CALLR CHECK_ALL_TIME JRNZ ISHSTD1 CALLR CHECK_TODAY JRNZ ISHSTD1 CLR A0 ISHSTD1 SWAP A8,A10 ADDK 2,A0 CALLR CHECK_ALL_TIME JRNZ VERY_HIGH CALLR CHECK_TODAY JRNZ VERY_HIGH SUBK 2,A0 VERY_HIGH MMFM SP,A8,A10 RETS CHECK_ALL_TIME MMTM SP,A0,A2,A8 MOVE A8,A0 MOVE A10,A2 ;SHOW "OTHER" SCORE IN A2 MOVI ALL_TAB,A8 CALLR CHECK_SCORE MMFM SP,A0,A2,A8 RETS CHECK_TODAY MMTM SP,A0,A2,A8 MOVE A10,A2 ;SHOW "OTHER" SCORE IN A2 MOVE A8,A0 MOVI TOD_TAB,A8 CALLR CHECK_SCORE MMFM SP,A0,A2,A8 RETS ******************************** *TIMER FOR INITIAL PROCESS .BSS INITTIMR,16 .BSS GET1FLG,16 .BSS GET2FLG,16 INITTIM CLR A0 MOVE A0,@GET1FLG MOVE A0,@GET2FLG CREATE HISCPID,INTIML MOVI 30,A1 MOVE A1,@INITTIMR MOVE A1,*A0(PA10),L ;SET A10 TO 60 RETS INTIML MOVE @INITTIMR,A0 DEC A10 JRNE INTIML1 MOVI 60,A10 DEC A0 JRN INITTIMX MOVE A0,@INITTIMR INTIML1 CALLA BINBCD MOVI [19,194],A3 MOVE A12,-*SP,L MOVK 2,A12 MOVK 1,A6 SLL 24,A0 ;SHIFT DIGITS INTO PLACE movi >1010101,a9 CALLR HSNUML0 MOVE *SP+,A12,L SLOOP 1,INTIML INITTIMX DIE ******************************** *GET PLAYERS INITIALS - WAIT TILL DONE GETINIT SLEEPK 10 CALLR DONCK JRNE GETINIT GETINITX SLEEP 60 ;WAIT A SEC. THEN BOOK RETP ******************************** *CHECK IF INITIALS DONE DONCK MOVE @INITTIMR,A2 JREQ DONCKX MOVE @GET1FLG,A0 MOVE @GET2FLG,A1 ADD A0,A1 DONCKX RETS ******************************** *GET PLAYER 1 INITIALS GETINIT1 MOVI P1ITAB,A0 MOVI LTRBOX1,A2 ;(OIMG) ;SHELL PROGRAM JRUC GTINIT P1ITAB .LONG P1DATA+PSCORE ;SCORE VALUE .byte " ",0 .LONG >00000000 ;START BOX COORD .IF YUNIT .LONG SWITCH,SWITCH+4,SWITCH+18 ;SWITCH LOCATIONS .ELSE .LONG SWITCH,SWITCH+8,SWITCH+24 .ENDIF .LONG >002c0030 ;INITIAL DISPLAY ADDRESS .LONG >3b3b0000 ;COLOR:PALETTE .LONG GET1FLG ******************************** *GET PLAYER 2 INITIALS GETINIT2 MOVI P2ITAB,A0 MOVI LTRBOX2,A2 ;OIMG JRUC GTINIT P2ITAB .LONG P2DATA+PSCORE ;SCORE VALUE .byte " ",0 .LONG >00000005 ;START BOX COORD .IF YUNIT .LONG SWITCH+8,SWITCH+12,SWITCH+21 ;SWITCH LOCATIONS .ELSE .LONG SWITCH+4,SWITCH+12,SWITCH+25 .ENDIF .LONG >002c0124 ;INITIAL DISPLAY ADDRESS .LONG >3b3b0000 ;COLOR:PALETTE .LONG GET2FLG ******************************** *GET YOUR INITIALS PROCESS *A0=POINTER TO SETUP TABLE *A2=OIMG *A8=POINTER TO BOX OBJECT *A9=DEBOUNCE TIMER, INITIAL ENTRY *A10=DEBOUNCE TIMER, MOVE JOYSTICK *A11=INITIAL # *PDATA=SCORE *PDATA+>20,PDATA+>28,PDATA+>30,PDATA+>38 = INITIAL STRING *PDATA+>40=CURRENT BOX COORD Y:X *PDATA+>60=MOVE STICK ADDRESS *PDATA+>80=FIRE STICK ADDRESS *PDATA+>A0=START BUTTON ADDRESS *PDATA+>C0=INITIALS DISPLAY Y:X OFFSET *PDATA+>E0=COLOR:PALETTE INITIAL *PDATA+>100=INITIAL DONE FLAG (DONE=0) GTINIT MOVE A13,A8 ADDI PDATA,A8 MOVE *A0+,A1,L MOVE *A1+,*A8+,L ;PUT THE SCORE MOVK 8,A1 GTI0L MOVE *A0+,A3,L MOVE A3,*A8+,L DSJS A1,GTI0L MOVK 1,A1 MOVE A1,*A3,W ;INCREMENT DONE FLAG CLR A11 ;CURRENT INITIAL WORKING ON CLR A10 ;JOYSTICK DEBOUNCE TIMER CLR A9 ;FIRE/START DEBOUNCE *CREATE BOX OBJECT CLR A0 ;A0=OXVAL CLR A1 ;A1=OYVAL MOVI 9EH,A3 ;(OZPOS) MOVI DMAWNZ,A4 ;(OFLAGS) NON-ZERO VALUE clr a5 ;(OID) CLR A6 ;(OXVEL) CLR A7 ;(OYVEL) CALLA BEGINOBJ GTL CMPI 3,A11 ;GET MOVE SWITCHES JRHS GTL4 ;ENTERED 'EM ALL CALLR DONCK JRNE GTL0 MOVI 3,A11 ;TIMES UP STUFF EM IN JRUC GTL3X GTL0 MOVE *A13(PDATA+>60),A0,L ;GET MOVE SWITCH ADDRESS MOVE *A0,A1,W NOT A1 SLL 28,A1 SRL 28,A1 JRNE GTL1 CLR A10 ;CLEAR DEBOUNCE TIMER JRUC GTL5 GTL1 MOVE A10,A10 JRNE GTL5 MOVK 12,A10 SLL 4,A1 ADDI IJOYTAB,A1 MOVB *A1,A0 ;GET DX MOVB *A1(8),A1 ;GET DY MOVE *A13(PDATA+>40),A2 ;GET X COORD MOVE *A13(PDATA+>50),A3 ;GET Y COORD ADD A2,A0 ;ADD DX, CHECK LIMITS JRNN GM1 CLR A0 GM1 CMPI 5,A0 JRLS GM2 MOVK 5,A0 GM2 ADD A3,A1 ;ADD DY CHECK LIMITS JRNN GM3 CLR A1 GM3 CMPI 4,A1 JRLS GM4 MOVK 4,A1 GM4 MOVE A0,*A13(PDATA+>40) ;SAVE COORDS MOVE A1,*A13(PDATA+>50) *FORM BOX XY COORD AND UPDATE IT GTL5 MOVE *A13(PDATA+>40),A0 ;Get X MOVE *A13(PDATA+>50),A1 ;Get Y movk 21,a3 movk 22,a5 MPYU A0,A3 ;FORM X OFFSET MPYU A1,A5 ;FORM Y OFFSET move @WORLDTLX+16,a2 add a2,a3 addi 137,a3 move @WORLDTLY+16,a2 add a2,a5 addi 41,a5 MOVE A3,*A8(OXPOS) ;UPDATE POSITION MOVE A5,*A8(OYPOS) *UPDATE YOUR LETTER VALUE *A0=X OFFSET *A1=Y OFFSET MOVK 6,A3 MPYU A1,A3 ADD A0,A3 ;THIS IS THE INDEX TO MATRIX SLL 3,A3 ADDI INITMAT,A3 MOVB *A3,A0 MOVE A11,A4 SLL 3,A4 ADD A13,A4 ADDI PDATA+>20,A4 MOVB A0,*A4 ;STORE OUT CURRENT INITIAL *UPDATE LETTER POSITION SELECTED MOVE *A13(PDATA+>80),A0,L ;FIRE STICK COORD MOVE *A0,A0,W ;READ IT FOLKS NOT A0 SLL 28,A0 SRL 27,A0 MOVE *A13(PDATA+>A0),A1,L MOVE *A1,A1,W NOT A1 SLL 31,A1 SRL 31,A1 ADD A1,A0 JRNE GTL3 CLR A9 ;CLEAR DEBOUNCE TIMER JRUC GTL4 GTL3 MOVE A9,A9 ;DEBOUNCE STILL ON JRNE GTL4 MOVI 120,A9 MOVB *A4,A0 ;CHECK FOR RUB DUDES... CMPI >3C,A0 JRNE GTL3A ;NO.... DEC A11 JRNN GTL30 CLR A11 ;CAN'T RUB FIRST CHAR JRUC GTL4 GTL30 PUSH A0 ; MOVI GOGO,A0 ; CALLA ONESND PULL A0 MOVK >20,A0 MOVB A0,*A4 ;THROW OUT A SPACE JRUC GTL4 GTL3A PUSH A0 ; MOVI GOGO,A0 ; CALLA ONESND PULL A0 INC A11 CMPI 3,A11 JRLO GTL4 GTL3X MOVE A8,A0 CALLA DELOBJ MOVE *A13(PDATA+>100),A0,L CLR A1 MOVE A1,*A0 ;CLEAR DONE FLAG CALLR GTX ;UPDATE TABLE ENTRY *UPDATE YOUR LETTER DISPLAY GTL4 MOVE A13,A2 ;GET INITIAL STORE ADDRESS ADDI PDATA+>20,A2 MOVK 3,A1 ;DO THREE INITIALS MOVE *A13(PDATA+>C0),A3,L ;GET BASE SCREEN ADDRESS GTL5L MOVB *A2,A0 MMTM SP,A1,A2,A3 MOVE *A13(PDATA+>E0),A1,L ;GET COLOR:PALETTE CALLR INITOUT MMFM SP,A1,A2,A3 ADDK >16,A3 ;INC SCREEN COORD ADDK 8,A2 ;INC DISPLAY ADDRESS DSJS A1,GTL5L *DEC DEBOUNCE TIMERS MOVE A10,A10 ;DEC TIMER ? JREQ GTL6 ;NO, ALREADY ZERO DEC A10 ;DEC IT GTL6 MOVE A9,A9 ;DEC TIMER ? JREQ GTL7 ;NO, ALREADY ZERO DEC A9 ;DEC IT GTL7 SLEEPK 1 JRUC GTL ; CALLR DONCK ; JRNE GTL *STUFF HI SCORE GTX MOVE *A13(PDATA),A0,L ;GET SCORE POINTS MOVE A13,A1 ADDI PDATA+>20,A1 ;POINT TO INITIAL STORAGE MOVI TOD_TAB,A8 ;ALWAYS ADD TO TODAYS (EVEN IF SPACES) CALLR ADD_ENTRY ;ADD EM TO THIS ONE IF NEC. MOVI ALL_TAB,A8 CALLR ADD_ENTRY ;ADD EM TO THE TABLE JRC TOO_BAD ;DIDN'T MAKE ALL TIME CALLR DELAY_HSRESET ;NEW ENTRY....DON'T RESET TOO QUICK TOO_BAD RETS ******************************** *INITIAL ENTRY JOYSTICK TABLE ;RLDU IJOYTAB .BYTE 0,0 ;0000 .BYTE 0,-1 ;0001 .BYTE 0,1 ;0010 .BYTE 0,0 ;0011 .BYTE -1,0 ;0100 .BYTE -1,-1 ;0101 .BYTE -1,1 ;0110 .BYTE -1,0 ;0111 .BYTE 1,0 ;1000 .BYTE 1,-1 ;1001 .BYTE 1,1 ;1010 .BYTE 1,0 ;1011 .BYTE 0,0 ;1100 .BYTE 0,-1 ;1101 .BYTE 0,1 ;1110 .BYTE 0,0 ;1111 *INITIAL MATRIX INITMAT .STRING "ABCDEFGHIJKLMNOPQRSTUVWXYZ!? <" ************************************************************************** * * A2_CHECK * * DOES THE SCORE IN A2 MATCH EITHER OF THE PLAYER'S SCORE. * .EQ. MEANS YES * .NE. MEANS NO * * THIS IS A NARCSPRY MODULE MOVED HERE TO FREE * NARCSPRY DEPENDANCY ON NARCEQU (T.I. B.D. OVERFLOWS) * ************************************************************************** A2_CHECK MMTM SP,A0 MOVE @P1DATA+PSCORE,A0,L CMP A2,A0 JREQ A2_SUCC ;IT WAS PLAYER 1'S SCORE MOVE @P2DATA+PSCORE,A0,L CMP A2,A0 A2_SUCC MMFM SP,A0 RETS ************************************************************************** * * CHECK_INITS * * A1 POINTS AT A SET OF INITIALS ENTERED. RETURN .EQ. * IF THEY'RE ALL SPACES (OR ZERO). * ************************************************************************** CHECK_INITS: MMTM SP,A0,A1,A2 MOVI NUM_INITS,A2 CHECK_NEXT: MOVB *A1,A0 ;GET AN INITIAL JRZ SPACE_FOUND ;NULL IS A SPACE CMPI SPACE,A0 ;IS IT A REAL SPACE? JRNZ LET_FOUND SPACE_FOUND: ADDI BYTE_SIZE,A1 DSJS A2,CHECK_NEXT CLR A2 ;SET Z BIT ON FALL THROUGH LET_FOUND: MMFM SP,A0,A1,A2 RETS ************************************************************************** * * CHECK_SCORE * * THIS IS CALLED WITH A SCORE IN A0 TO SEE IF IT * IS HIGH ENOUGH TO MAKE THE TABLE. * * THE OTHER PLAYER'S SCORE IS PASSED IN A2. IF * THE PLAYER MAKES THE LAST POSITION OF THE TABLE, * THEN HIS SCORE IS COMPARED AGAINST THE OTHER SCORE * IT MUST BE HIGHER THAN THE OTHER SCORE, OTHERWISE * HE WILL ENTER HIS INITIALS, BUT THERE WILL BE NO * PLACE TO PUT THEM WHEN HIS BUDDY IS DONE ENTERING HIS! * * THIS ROUTINE CALLS FIND_TABLE_LEVEL WHICH RETURNS * THE POINT IN THE TABLE THAT THE PASSED SCORE WOULD * LAND. THIS VALUE MUST BE LESS THAN OR EQUAL TO * THE "TB_VISIBLE" VALUE FOR THE TABLE. THIS WOULD * MEAN THAT WE WANT TO GET THE PLAYER'S INITIALS. * * A8 CONTAINS ROM POINTER FOR TABLE TO CHECK. * RETURN A0 = 0 (AND .EQ.) IF SCORE ISN'T HIGH ENOUGH * AND A0 = POSITION IN TABLE IF SCORE MAKES IT. * ************************************************************************** CHECK_SCORE: MMTM SP,A1,A3,A9,A10 MOVE A0,A3 ;STASH SCORE IN A3 CALLR FIND_TABLE_LEVEL ;SEE WHERE WE LAND IN THIS TABLE JRZ ANSWER_IN_A0 ;ZERO.....GUY DIDN'T MAKE IT MOVE *A8(TB_VISIBLE),A1,W ;GET THE NUMBER "ENTERED" CMP A1,A0 ;A0 MUST BE LESS OR EQUAL JRLO ANSWER_IN_A0 ;NOT LAST ENTRY...RETURN SUCCESS JRHI DIDNT_MAKE_HSTD * * GUY IS GOING FOR LAST POSITION.....SEE IF HIS BUDDY IS * GOING TO NOSE HIM OUT: * CMP A2,A3 ;HI MUST BE HIGHER THAN BUDDY JRHI ANSWER_IN_A0 * * * ****** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ****** * ****** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ****** * * NOTE THAT IF BOTH PLAYERS HAVE AN IDENTICAL SCORE THAT * WOULD MAKE THE LAST POSITION OF A TABLE, THEN THEY * WON'T GET TO ENTER THEIR INITIALS!!!!!! * * TOUGH LUCK! -LED 10/22/88 * * ****** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ****** * ****** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ****** * * * WE WOULD MAKE THE PHYSICAL TABLE, BUT WE'RE OUT OF * WHAT THE PLAYER CAN SEE....RETURN FALSE * DIDNT_MAKE_HSTD: CLR A0 ;RETURN FAILURE ANSWER_IN_A0: MOVE A0,A0 ;SET EQ BIT ACCORDINGLY MMFM SP,A1,A3,A9,A10 RETS ************************************************************************** * * ADD_ENTRY * * THIS IS CALLED AFTER "ENTER YOUR INITIALS" TO * ADD AN ENTRY TO THE TABLE. A0 CONTAINS THE * SCORE OF THE PLAYER. A1 CONTAINS A POINTER * TO THE FETCHED INITIALS. THE INITIALS ARE * STORED AS CONSECUTIVE BYTES IN CONVENTIONAL * (1 BYTE TAKES 1 BYTE SPACE) RAM. * * A8 contains a the table to store the entry in. * * RETURN CARRY SET IF IT DIDN'T MAKE IT INTO REQUESTED TABLE * ************************************************************************** ADD_ENTRY: MMTM SP,A0,A1,A2,A3,A4,A7,A9,A10 CALLR ROM_PTRS ;SETUP FOR THIS TABLE MOVE A0,A4 ;STASH THE SCORE A SEC. CLR A2 ;DONT WORRY ABOUT OTHER GUY AT THIS POINT CALLR CHECK_SCORE ;DOES THE REQUEST MAKE IT? SETC ;ANTICIPATE FAILURE JRZ DIDNT_MAKE_IT ;DON'T KNOW WHY I GOT THESE INITS. * * A0 NOW HAS THE PLACE FOR THE NEW GUY. * MOVE THE ENTIRE TABLE DOWN 1 UNIT. * MOVE A10,A3 ;LAST GUY IN TABLE IS DESTINATION COPY_DOWN_LOOP: MOVE A3,A2 ;GUY BEFORE HIM IS SOURCE DEC A2 ;A2 NOW HAS SOURCE CMP A0,A2 ;IS SOURCE LOWER THAN OUR SLOT? JRLO COPY_DONE ;IT IS...DON'T MOVE HIM. CALLR COPY_ENTRY ;COPY A2 ENTRY TO A3 DEC A3 ;MOVE DOWN TO ONE BEFORE JRUC COPY_DOWN_LOOP COPY_DONE: CALLR PUT_SCORE_FOR_ENTRY ;SCORE IN A4 WRITTEN TO ENTRY A0 * * INITAIAL POINTER IS IN A1 * TABLE OFFSET IN A0 * CALLR PT_ENTRY ;GET ENTRY POINTER IN A7 ADDI HS_INITS,A7 ;POINT AT FIRST INITIAL MOVI NUM_INITS,A2 ;THIS IS NUMBER OF INITIALS MMTM SP,A0 ;SAVE A0 INIT_COPY_LOOP: MOVB *A1,A0 ;GET AN INITIAL JRNZ NOT_BLANK MOVI SPACE,A0 ;REPLACE BLANKS WITH SPACES NOT_BLANK: CALLR WC_BYTEI ;WRITE THE BYTE AND INCREMENT ADDI BYTE_SIZE,A1 ;A1 TO NEXT BYTE PLEASE DSJ A2,INIT_COPY_LOOP MMFM SP,A0 ;GET BACK ENTRY NUMBER CALLR FORM_HS_CKSUM_AND_STORE ;FOR CHECKSUM FOR THIS ENTRY AND STORE! CLRC ;RETURN SUCCESS! DIDNT_MAKE_IT MMFM SP,A0,A1,A2,A3,A4,A7,A9,A10 RETS ************************************************************************** * * FIND_TABLE_LEVEL * * THIS IS CALLED TO COMPARE THE SCORE IN A0 TO * THE TABLE POINTED TO BY A8. * * RETURN PHYSICALLY WHERE IT FITS IN A0, AND * SET THE Z FLAG ACCORDINGLY * ************************************************************************** FIND_TABLE_LEVEL MMTM SP,A1,A2,A3 CALLR ROM_PTRS ;SETUP FOR THIS TABLE CALLR VAL_TAB ;FIX THE TABLE IN CASE ITS BROKEN. JRC FTL_FAIL ;CAN'T VALIDATE..SAY SCORE DIDN'T MAKE IT MOVE A0,A2 ;KEEP SCORE IN A2 MOVK 1,A0 ;START AT 1 AND WORK UP. CHECK_NEXT_SCORE: CALLR GET_HSCR ;FETCH A0 ENTRY'S SCORE IN A1 CMP A1,A2 ;HOW DO WE FARE AGAINST A1? JRHI FOUND_THE_SPOT ;WE FOUND THE SPOT INC A0 ;KEEP MOVING DOWN TILL WE FIT CMP A10,A0 ;ARE WE LOOKING AT THE LAST ONE? JRLS CHECK_NEXT_SCORE FTL_FAIL: CLR A0 ;WE'RE NOT HIGH ENOUGH RETURN FAILURE FOUND_THE_SPOT: MOVE A0,A0 ;MAKE SURE YOU SET THE FLAGS MMFM SP,A1,A2,A3 RETS ************************************************************************** * * GET_HSCR * * THIS IS CALLED TO FETCH THE SCORE FROM CMOS FOR * A GIVEN ENTRY. * * ENTRY NUMBER PASSED IN A0. * SCORE RETURNED IN A1. * ************************************************************************** GET_HSCR MMTM SP,A7,A0 CALLR PT_ENTRY ;POINT A7 AT ENTRY ADDI HS_SCORE,A7 ;INDEX SCORE PART. CALLR RC_LONG ;FETCH THE LONG WORD INTO A0 MOVE A0,A1 ;MOVE TO A1 MMFM SP,A7,A0 RETS ************************************************************************** * * PUT_SCORE_FOR_ENTRY * * THIS IS CALLED TO WRITE OUT THE SCORE FOR A GIVEN ENTRY. * ENTRY SPECIFIED BY A0. * SCORE PASSED IN A4. * ************************************************************************** PUT_SCORE_FOR_ENTRY MMTM SP,A7,A0 CALLR PT_ENTRY ;POINT A7 AT ENTRY ADDI HS_SCORE,A7 ;INDEX SCORE PART. MOVE A4,A0 ;MOVE SCORE TO A0 CALLR WC_LONG ;WRITE OUT THE LONG WORD MMFM SP,A7,A0 RETS ************************************************************************** * * LOW LEVEL HSTD PROCESSING * ************************************************************************** * * FOR HIGH SCORE ROUTINES * * A8 = ROM POINTER FOR A GIVEN TABLE STATS * A9 = RAM POINTER FOR CMOS DATA * A10 = NUMBER OF ENTRIES IN THE TABLE * * A0 = PARTICULAR ENTRY TO DEAL WITH * 0 = FILL ENTRY (POINTER ROUTINES POINT HERE IF ERROR) * 1 = HIGHEST SCORE IN TABLE * N = NTH SCORE * * A1 = OUTPUT OF CHECKSUM ROUTINE (BYTE) * * A7 = POINTER TO CURRENT ENTRY * * A4,A5,A6 SCRATCH * ************************************************************************** * * FORM_HS_CKSUM * * THIS IS CALLED TO FORM THE CHECKSUM FOR THE SCORE * NUMBER IN A0. (RAM POINTER ASSUMED IN A9). * CHECKSUM IS RETURNED IN A1. THIS IS A *BYTE*. * * CHECKSUM IS COMPUTED AS THE COMPLEMENT OF THE SIMPLE SUM * OF THE BYTES IN THE ENTRY. * * THIS ROUTINE RETURNS WITH THE Z BIT SET (.EQ.) IF THE * CHECKSUM FOR THIS ENTRY MATCHES. * ************************************************************************** FORM_HS_CKSUM: MMTM SP,A0,A4,A6,A7 CALLR PT_ENTRY ;A7 = POINTER TO CURRENT ENTRY MMTM SP,A7 ;SAVE POINTER TO ENTRY MOVI HS_BYTES_TO_CHECK,A4 ;COUNT DOWN THE BYTES CLR A1 ;KEEP SUM IN A1 ADD_A_BYTE: CALLR RC_BYTEI ;GET A BYTE INTO A0 ADD A0,A1 ;ADD TO SUM DSJ A4,ADD_A_BYTE ;ONE MORE ADDED NOT A1 ;CHECKSUM IS NOW IN LOW BYTE ANDI BYTE_MASK,A1 ;MASK SO ITS COOL MMFM SP,A7 ;GET POINTER BACK ADDI HS_CKBYTE,A7 ;POINT AT CHECKBYTE CALLR RC_BYTE ;READ IN THE BYTE CMP A0,A1 ;COMPARE WHAT'S THERE TO WHAT WE GOT MMFM SP,A0,A4,A6,A7 ;Z BIT RETURNS COMPARE RETS ;A1 RETURNS CKSUM ************************************************************************** * * FORM_HS_CKSUM_AND_STORE * * THIS IS USED TO SET THE CHECKSUM FOR THE CURRENT * ENTRY (A0) TO THE CORRECT VALUE. * ************************************************************************** FORM_HS_CKSUM_AND_STORE: MMTM SP,A0,A7 CALLR FORM_HS_CKSUM ;GET THE CKSUM IN A1, POINTER IN A7 CALLR PT_ENTRY ;POINT AT THE VALUE ADDI HS_CKBYTE,A7 ;POINT AT CHECKBYTE MOVE A1,A0 ;GET CHECKBYTE TO A0 CALLR WC_BYTE ;WRITE OUT THE BYTE MMFM SP,A0,A7 RETS ************************************************************************** * * PT_ENTRY * * THIS IS CALLED TO POINT AT A GIVEN ENTRY OF * THE HIGH SCORE TABLE. THIS ROUTINE BASES * ACTIVITY ON ROM POINTER IN A8. IT FETCHES * FRESH COPIES OF THE A9 RAM POINTER AND THE * A10 ENTRY COUNTER. IT RETURNS THE ENTRY * POINTER IN A7. * * A0 SPECIFIES WHICH ENTRY TO POINT AT * A8,A9,A10 AND SYSCTRL ASSUMED SET PROPERLY * A7 RETURNED POINTING TO THAT ENTRY * ************************************************************************** PT_ENTRY: CMP A10,A0 ;A10 IS MAX VALUE JRLS POINTER_IN_RANGE .IF DEBUG JRUC $ ;HANG IN DEVELOPMENT .ENDIF MOVE A9,A7 ;RETURN ZERO OFFSET IN FIELD RETS POINTER_IN_RANGE: MOVI HS_SIZE,A7 ;SIZE OF ENTRY MPYU A0,A7 ;OFFSET OF ENTRY ADD A9,A7 ;ADD IN THE BASE RETS ************************************************************************** * * ROM_PTRS * * THIS IS CALLED TO LOAD UP THE ROM STRUCTURE * DATA INTO REGISTERS. * * THIS ALSO SETS UP STATUS WORD TO SELECT THE CMOS * BANK SELECT FOR WHERE THE PARTICULAR TABLE RESIDES. * * INPUT A8=HSTD STRUCTURE ROM POINTER. * * OUTPUT A9 = CMOS RAM POINTER TO BASE OF TABLE * OUTPUT A10= LAST ENTRY IN TABLE. TABLE WILL * HAVE A10+1 ENTRIES SINCE ENTRY * 0 IS A FILLER. * ************************************************************************** ROM_PTRS: MMTM SP,A0,A1 ;SCRATCH REGGIES MOVE *A8(TB_POINTER),A9,L ;GET CMOS POINTER MOVE *A8(TB_COUNT),A10,W ;GET NUMBER OF ENTRIES MOVE *A8(TB_PAGE_BITS),A1 ;GET OUR CMOS PAGE BITS CALLR SET_PAGE MMFM SP,A0,A1 ;SCRATCH REGGIES RETS ************************************************************************** * * SET_PAGE * * This is called to set the CMOS page to the bits * contained in A1. * ************************************************************************** SET_PAGE MMTM SP,A0,A1 ANDI CMOS_PAGE_SELECT_BITS,A1 ;KILL SIGN EXTEND..SAVE BITS PUSHST ;SAVE INTERRUPT STATUS DINT ;STOP INTERRUPTS MOVE @SYSCOPY,A0,W ;GET THE RAM COPY ANDNI CMOS_PAGE_SELECT_BITS,A0 ;REMOVE THE CURRENT PAGE SELECT OR A1,A0 ;ADD IN OUR BITS MOVE A0,@SYSCOPY,W ;PUT THEM BACK IN THE RAM COPY MOVE A0,@SYSCTRL,W ;NOW THE HARDWARE POPST ;OK TO RE-START INTS MMFM SP,A0,A1 RETS ************************************************************************** * * INIT_TAB * * This entrypoint is called at power up to * clear out "today's" high score table. We do * this job, and then we do the job on the * all time table for high score reset if * necessary. * ************************************************************************** INIT_TAB MMTM SP,A8,A0 MOVI TOD_TAB,A8 CALLR INIT_TB ;RESET TODAYS TABLE CALLR GET_HSC ;CHECK THE HIGH SCORE RESET COUNTER JRNZ INIT_TAB1 ;NOT ZERO...NO MORE ACTIVITY * * ITS ZERO....SEE IF ITS TURNED OFF * MOVI ADJHSRES,A0 CALLA GET_ADJ ;GET THE ADJUSTED VALUE JRZ INIT_TAB1 ;ITS TURNED OFF...NO ACTION. MOVI ALL_TAB,A8 ;RESET THE ALL TIME TABLE CALLR INIT_TB ;INIT THE ALL TIME TABLE CALLR INIT_HSR ;RESET THE COUNTER TO ADJUSTED VALUE INIT_TAB1 MMFM SP,A8,A0 RETS ************************************************************************** * * INIT_TB * * THIS IS CALLED TO SETUP A HIGH SCORE TABLE WITH * FACTORY ENTRIES. * * A8 = ROM TABLE POINTER * ************************************************************************** INIT_TB: MMTM SP,A5,A6,A7,A0 CALLR ROM_PTRS ;STUFF TABLE DATA MOVE *A8(TB_FACTORY),A6,L ;GET THE FACTORY TABLE MOVE A10,A5 ;NUMBER OF VALID ENTRIES INC A5 ;1 MORE TO HOLD ZERO ENTRY MOVI HS_SIZE_IN_BYTES,A1 ;SIZE OF 1 ENTRY MPYU A1,A5 ;A7 HAS NUMBER OF WORDS TO MOVE MOVE A9,A7 ;CMOS POINTER IN A7 INIT_TB_1: MOVB *A6,A0 ;GET A BYTE FROM ROM ADDI BYTE_SIZE,A6 ;KICK ROM POINTER CALLR WC_BYTEI ;WRITE THE BYTE AND INCREMENT DSJS A5,INIT_TB_1 ;UNTIL THEY'RE ALL THERE. MOVE A10,A0 ;POINT AT LAST ENTRY INIT_TB_2: CALLR FORM_HS_CKSUM_AND_STORE ;SET ITS CHECKSUM DEC A0 ;MOVE DOWN JRNN INIT_TB_2 ;SET EACH ONE INCLUDING ZERO MMFM SP,A5,A6,A7,A0 RETS ************************************************************************** * * COPY_ENTRY * * THIS IS CALLED TO COPY 1 ENTRY OF THE TABLE TO A * DIFFERENT LOCATION IN THE TABLE. * * A8,A9,A10,SYSCTRL ASSUMED TO BE SETUP ALREADY * A2 = SOURCE ENTRY (NUMBER) * A3 = DESTINATION ENTRY (NUMBER) * ************************************************************************** COPY_ENTRY: MMTM SP,A0,A4,A5,A6,A7 MOVI HS_SIZE_IN_BYTES,A4 ;ENTRY SIZE IN BYTES MOVE A2,A0 ;FIRST POINT FOR A0 CALLR PT_ENTRY MOVE A7,A6 ;A6 = SOURCE POINTER MOVE A3,A0 CALLR PT_ENTRY ;A5 = DESTINATION MOVE A7,A5 COPY_LOOP: * * IN THIS LOOP WE MOVE A BYTE AT A TIME. * SINCE THE WORD AND LONG DO THE SHIFTING AND * MASKING AND CALL MULTIPLE ROUTINES, THIS IS * THE MOST EFFICIENT MODE OF OPERATION. * MOVE A6,A7 ;SOURCE IN CMOS REGGIE CALLR RC_BYTEI ;FETCH A WORD MOVE A7,A6 MOVE A5,A7 ;DESTINATION CALLR WC_BYTEI ;WRITE IT MOVE A7,A5 ;BACK TO DEST REGGIE DSJ A4,COPY_LOOP ;UNTIL ALL WORDS ARE COPIED MMFM SP,A0,A4,A5,A6,A7 RETS ************************************************************************** * * VAL_TAB * * THIS ROUTINE IS CALLED WHEN WE ARE INTERESTED IN * THE HSTD TABLE DATA. A8 CONTAINS THE ROM POINTER * FOR THE TABLE. FOR ANY ENTRIES THAT WE THROW * OUT, WE MOVE THE REST OF THE TABLE UP, AND CREATE * A NEW ENTRY AT THE END OF THE TABLE. * * A2 = 0 ON OUTSIDE CALL. * A2 = 1 ON RECURSIVE CALL (THE CHECK AFTER RE-INIT) * * THERE ARE 3 CHECKS MADE FOR EACH ENTRY: * * 1) IS CHECKSUM CORRECT. * 2) IS SCORE ALL NUMERIC * 3) ARE INITIALS ALL VALID ENTRIES. * * OUTPUT CC = TABLE OK * CS = PROBLEM THAT CAN'T BE RECTIFIED * (PROBABLY BAD RAM) * * A2 = 0 ...table ok, or cleaned up * A2 otherwise meanes table initialized * ************************************************************************** VAL_TAB CLR A2 ;indicate first call in CALLR DO_VALIDATE ;validate RETS DO_VALIDATE MMTM SP,A0,A1,A3,A4,A5,A6,A7 CALLR ROM_PTRS ;SETUP FOR TABLE MOVI 1,A0 ;ITERATE THROUGH THE ENTRIES CLR A1 ;COUNT ERRORS CHECK_A0_ENTRY: CALLR CHECK_ENTRY ;IS THE ENTRY OK? JRNC VT_1 ;YEP. CALLR REMOVE_ENTRY ;REMOVE THIS ENTRY INC A1 MOVE *A8(TB_ERROR_COUNT),A3 ;GET THRESHOLD CMP A3,A1 ;ARE WE THERE? JRLO CHECK_A0_ENTRY ;NOPE...CHECK MOVE UP ENTRY AT A0 * * TABLE IS MESSED UP....RE-INITIALIZE IT PLEASE * MOVE A2,A2 ;IS THIS RECURSIVE CHECK AFTER INIT? JRNZ CANT_VALIDATE ;THEN RETURN FAILURE CALLR INIT_TB ;INIT THIS TABLE PLEASE MOVK 1,A2 ;INDICATE RECURSIVE CALL CALLR DO_VALIDATE ;IS IT ALRIGHT NOW? MMFM SP,A0,A1,A3,A4,A5,A6,A7 RETS * * LAST ENTRY WAS VALID...MOVE TO NEXT * VT_1: INC A0 ;KICK IT CMP A10,A0 ;STILL IN TABLE? JRLS CHECK_A0_ENTRY ;YEP....CHECK THIS ENTRY CLRC ;RETURN VALID! MMFM SP,A0,A1,A3,A4,A5,A6,A7 RETS CANT_VALIDATE: SETC ;RETURN FAILURE! MMFM SP,A0,A1,A3,A4,A5,A6,A7 RETS ************************************************************************** * * CHECK_ENTRY * * THIS IS CALLED TO CHECK THE ENTRY INDICATED BY A0. * * CC = OK * CS = ENTRY BAD * ************************************************************************** CHECK_ENTRY MMTM SP,A0,A1,A2,A3,A7 CALLR FORM_HS_CKSUM ;CHECK OUT CKSUM FIRST JRNZ CHECK_FAIL ;BAD CHECKSUM....ITS BAD * * CHECKSUM OK...CHECK SCORE * CALLR GET_HSCR ;SCORE IN A1 MOVE A1,A3 ;SAVE COPY OF SCORE CHECK_DIGIT: MOVE A1,A2 ;COPY FOR NEXT NIBBLE ANDI 0FH,A2 ;MASK THE NIBBLE CMPI 9,A2 JRHI CHECK_FAIL ;NIBBLE TOO HIGH SRL 4,A1 ;SHIFT DOWN TO NEXT NIBBLE JRNZ CHECK_DIGIT DEC A0 ;MAKE SURE WE ARE LOWER THAN PREVIOUS SCORE! JREQ FIRST_ENT ;WE'RE THE 1ST IN THE TABLE CALLR GET_HSCR ;GET THE SCORE FOR THE GUY BEFORE US CMP A1,A3 ;OURS MUST BE LOWER OR SAME JRHI CHECK_FAIL ;OURS IS BIGGER....REMOVE US FIRST_ENT: INC A0 ;RESTORE THE ENTRY NUMBER * * SCORE OK...CHECK INITIALS * CALLR PT_ENTRY ;POINT A7 AT ENTRY ADDI HS_INITS,A7 ;POINT AT FIRST INITIAL MOVI NUM_INITS,A2 ;THIS IS NUMBER OF INITIALS NEXT_LETTER: CALLR RC_BYTEI ;FETCH A BYTE CALLR VERIFY_LETTER ;SEE IF ITS VALID. JRC CHECK_FAIL ;NOT A LETTER...BYTE DSJ A2,NEXT_LETTER CLRC ;RETURN PASS MMFM SP,A0,A1,A2,A3,A7 RETS CHECK_FAIL: SETC MMFM SP,A0,A1,A2,A3,A7 RETS ************************************************************************** * * VERIFY_LETTER * * THIS IS CALLED FOR EACH INITIAL LETTER TO SEE * IF ITS VALID. * * CC = VALID * CS = NOT VALID * ************************************************************************** VERIFY_LETTER: ANDI BYTE_MASK,A0 ;KEEP JUST THE BYTE CMPI '!',A0 ;SPACE? JREQ VERIFY_PASS ;ITS OK. CMPI '%',A0 ;SPACE? JREQ VERIFY_PASS ;ITS OK. CMPI '?',A0 ;SPACE? JREQ VERIFY_PASS ;ITS OK. CMPI SPACE,A0 ;SPACE? JREQ VERIFY_PASS ;ITS OK. CMPI LET_A,A0 ;BETWEEN A-Z? JRLO VERIFY_FAIL CMPI LET_Z,A0 JRHI VERIFY_FAIL VERIFY_PASS: CLRC RETS VERIFY_FAIL: SETC RETS ************************************************************************** * * REMOVE_ENTRY * * THIS IS CALLED TO REMOVE A BAD ENTRY FROM THE TABLE. * IT DELETES THE ENTRY INDICATED BY A0. * * IT BUBBLES THE REST OF THE TABLE UP 1 UNIT. * * IT THEN PUTS THE LOWEST SCORE FROM THE ROM TABLE * WITH INITIALS IN THAT ENTRY. * ************************************************************************** REMOVE_ENTRY: MMTM SP,A0,A1,A2,A6,A7 MOVE A0,A3 ;THIS IS DEST MOVE A3,A2 ;SOURCE IS 1 BELOW BUBBLE_ANOTHER: INC A2 ;NOW WE'RE SET FOR A COPY... CMP A10,A2 ;IS SOURCE OUT OF RANGE? JRHI BUBBLE_DONE ;YEP....WE'RE AT THE BOTTOM (A3) CALLR COPY_ENTRY INC A3 JRUC BUBBLE_ANOTHER BUBBLE_DONE: MOVE A3,A0 ;THIS IS BOTTOM OF TABLE CALLR PT_ENTRY ;A7 POINTS AT CMOS BLOCK MOVE *A8(TB_FACTORY),A6,L ;GET FACTORY TABLE MOVI HS_ROM_SIZE,A1 ;SIZE OF ENTRY MPYU A10,A1 ;TIMES NUMBER OF VALID ENTRIES..POINTS AT LAST. ADD A1,A6 ;NOW WE POINT AT END OF ROM TABLE MOVI HS_SIZE_IN_BYTES,A2 ;SIZE OF ENTRY REPLACE_LOOP: MOVB *A6,A0 ;MOVE A ROM BYTE TO A0 ADDI BYTE_SIZE,A6 CALLR WC_BYTEI ;WRITE THE WORD AND INCREMENT DSJ A2,REPLACE_LOOP ;UNTIL THEY'RE ALL THERE. MOVE A10,A0 ;POINT AT "LAST" ENTRY CALLR FORM_HS_CKSUM_AND_STORE ;STORE THE CHECKBYTE MMFM SP,A0,A1,A2,A6,A7 ;AND RETURN RETS ************************************************************************** * * CMOS UTILITIES * ************************************************************************** ************************************************************************** * * FOR ALL OF THESE CMOS ROUTINES. * * A7 = POINTER TO MEMORY * A0 = DATA TO/FROM MEMORY * ************************************************************************** * * **** IMPORTANT NOTE ON WORD AND LONG WORD PACKING **** * **** IMPORTANT NOTE ON WORD AND LONG WORD PACKING **** * * NOTE THAT REQUESTS FOR WORDS RETURN THE 2 BYTES PACKED * INTO A WORD AS <1ST BYTE><2ND BYTE>. THIS IS NOT * THE SAME WAY THAT THE GSP HANDLES A WORD POINTED AT * WITH A POINTER. * * LONG WORDS WORK SIMILARLY: * * MSB LSB * <1ST BYTE> <2ND BYTE> <3RD BYTE> <4TH BYTE> * * TOUGH LUCK INTEL HACKERS! * * * RC_BYTE * WC_BYTE * * These 2 routines are the only routines that ever touch * CMOS ram. This is done to localize the effect of * changes in the architecture. All efforts to deal with * CMOS should come through these routines. Locking * hardware will be easily added in the future (as well * as different memory mapping). RC_BYTE MOVB *A7,A0 ANDI BYTE_MASK,A0 RETS WC_BYTE .IF YUNIT MOVE A1,-*SP,L MOVI 0200H,A1 ;UNLOCK THE CMOS MOVE A1,@SECCHIP,W .ENDIF MOVB A0,*A7 ;WRITE OUT THE BYTE .IF YUNIT MOVI 0300H,A1 ;LOCK THE CMOS MOVE A1,@SECCHIP,W MMFM SP,A1 .ENDIF RETS ;AND RETURN ************************************************************************** * * RC_BYTEI * * READ BYTE POINTED TO BY A7...INCREMENT POINTER TO * "NEXT" BYTE. * ************************************************************************** RC_BYTEI: CALLR RC_BYTE ADDI C_BYTE_SIZE,A7 ;WORDS SEPARATE CMOS BYTES. MOVE A0,A0 ;RETURN FLAGS ACCORDINGLY RETS RC_WORD: MMTM SP,A1,A7 ;USE A1 TO COMBINE BYTES CALLR RC_BYTEI ;GET A BYTE MOVE A0,A1 ;SAVE IN A1 ANDI BYTE_MASK,A1 ;MASK ONLY BYTE SLL 8,A1 ;SHIFT TO HIGH BYTE CALLR RC_BYTE ;GET THE 2ND BYTE ANDI BYTE_MASK,A0 OR A1,A0 ;A0 HAS THE WORD MMFM SP,A1,A7 RETS RC_WORDI: CALLR RC_WORD ADDI C_WORD_SIZE,A7 ;LONG SEPARATE CMOS WORDS. MOVE A0,A0 ;RETURN FLAGS ACCORDINGLY RETS RC_LONG: MMTM SP,A1,A7 ;USE A1 TO COMBINE BYTES CALLR RC_WORDI ;GET A WORD MOVE A0,A1 ;SAVE IN A1 ANDI WORD_MASK,A1 ;MASK ONLY WORD SLL 16,A1 ;SHIFT TO HIGH WORD CALLR RC_WORD ;GET THE 2ND WORD ANDI WORD_MASK,A0 OR A1,A0 ;A0 HAS THE LONG WORD MMFM SP,A1,A7 RETS RC_LONGI: CALLR RC_LONG ADDI C_LONG_SIZE,A7 ;DOUBLE THE DISTANCE FOR BRAIN DAMIJ MOVE A0,A0 ;RETURN FLAGS ACCORDINGLY RETS WC_BYTEI: CALLR WC_BYTE ADDI C_BYTE_SIZE,A7 RETS WC_WORD: MMTM SP,A0,A1,A7 MOVE A0,A1 ;MAKE COPY OF WORD SRL 8,A0 ;GET HIGH BYTE IN A0 CALLR WC_BYTEI ;WRITE THE HIGH BYTE MOVE A1,A0 ;NOW GET THE LOW BYTE BACK CALLR WC_BYTE ;WRITE IT MMFM SP,A0,A1,A7 ;AND RESTORE ALL WE TOUCHED RETS WC_WORDI: CALLR WC_WORD ADDI C_WORD_SIZE,A7 RETS WC_LONG: MMTM SP,A0,A1,A7 MOVE A0,A1 ;MAKE COPY OF LONG SRL 16,A0 ;GET HIGH WORD IN A0 CALLR WC_WORDI ;WRITE THE HIGH WORD MOVE A1,A0 ;NOW GET THE LOW WORD BACK CALLR WC_WORD ;WRITE IT MMFM SP,A0,A1,A7 ;AND RESTORE ALL WE TOUCHED RETS WC_LONGI: CALLR WC_LONG ADDI C_LONG_SIZE,A7 RETS ***************************************************************************** ***************************************************************************** ***** ***** DEFAULT ROM HSTD TABLES AND TABLE DEFINITIONS ***** ***************************************************************************** ***************************************************************************** TB_POINTER EQU 0 ;LONG-POINTER TO BEGINNING OF TABLE TB_COUNT EQU TB_POINTER+LONG_SIZE ;WORD....# IN THE TABLE. TB_VISIBLE EQU TB_COUNT+WORD_SIZE ;WORD....NUMBER DISPLAYED TB_PAGE_BITS EQU TB_VISIBLE+WORD_SIZE ;WORD....STATUS WORD FOR CMOS PAGE TB_FACTORY EQU TB_PAGE_BITS+WORD_SIZE ;LONG....ROM STARTUP TABLE TB_ERROR_COUNT EQU TB_FACTORY+LONG_SIZE ;WORD....NUM ERRORS TO RE-INIT SCRM $MACRO a,b .byte :a:/>1000000,:a:/>10000&>ff,:a:/>100&>ff,:a:&>ff,:b:,0 $END ALL_TIME_ROM_TABLE SCRM >22122145,"EPJ" ;****ZERO ENTRY...NOT SEEN! ROM_ENTRY_SIZE EQU $-ALL_TIME_ROM_TABLE SCRM >98765,"HI " SCRM >90,"AAA" SCRM >80,"BBB" SCRM >70,"CCC" SCRM >60,"DDD" SCRM >50,"EEE" SCRM >40,"FFF" SCRM >30,"GGG" SCRM >20,"HHH" SCRM >10,"III" ALL_TIME_ENTRIES EQU ($-ALL_TIME_ROM_TABLE)/ROM_ENTRY_SIZE TODAYS_ROM_TABLE SCRM >22122145,"EPJ" ;****ZERO ENTRY...NOT SEEN! SCRM >11111,"SL!" SCRM >90,"AAA" SCRM >80,"BBB" SCRM >70,"CCC" SCRM >60,"DDD" SCRM >50,"EEE" SCRM >40,"FFF" SCRM >30,"GGG" SCRM >20,"HHH" SCRM >10,"III" TODAYS_ENTRIES EQU ($-TODAYS_ROM_TABLE)/ROM_ENTRY_SIZE .END