.FILE 'HSTD.ASM' .TITLE "ROBO HIGH-SCORE-TO-DATE MANAGEMENT" .WIDTH 132 .OPTION B,D,L,T .MNOLIST ; ; SOFTWARE: LARRY DeMAR, ROBBI ASHWORTH, EUGENE JARVIS ; ; COPYRIGHT (C) 1990 WILLIAMS ELECTRONICS GAMES, INC. ; ; ; GET THE SYSTEM STUFF .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 "ROBO.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 * * OTHER MODULES * .REF RD15FONT,SYSCOPY,P1DATA,P2DATA,DELPAL,GPALOBJ .REF BINBCD .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,W ;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. .EQ. MEANS ITS AT ZERO! * * * ************************************************************************** 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 ;BITS TO SELECT IT CALLR SET_PAGE MOVI >3A0065,A10 ;SCREEN START ADDRESS MOVI ALL_TIME_ORIGIN+HS_SCORE+HS_SIZE,A7 ;TABLE START ADDRESS CALLR HSNUMDSP MOVI >380031,A10 ;SCREEN START ADDRESS MOVI ALL_TIME_ORIGIN+HS_INITS+HS_SIZE,A7 ;TABLE START ADDRESS CALLR HSINITDSP MOVI TODAYS_SELECT,A1 ;BITS TO SELECT IT CALLR SET_PAGE MOVI >3A0123,A10 ;SCREEN START ADDRESS MOVI TODAYS_ORIGIN+HS_SCORE+HS_SIZE,A7 ;TABLE START ADDRESS CALLR HSNUMDSP MOVI >3800EE,A10 ;SCREEN START ADDRESS MOVI TODAYS_ORIGIN+HS_INITS+HS_SIZE,A7 ;TABLE START ADDRESS CALLR HSINITDSP RETS * *DISPLAY SCORE TABLE SCORES IN ATTRACT *A7=TABLE INDEX *A10=DISPLAY COORD * HSNUMDSP MMTM SP,A0,A1,A3,A5,A6,A7,A8,A10,A12 MOVK 10,A11 ;START WITH SCORE 1 HSDSPLL MOVK 8,A12 CALLR RC_LONG ;GET THE FUCKING SCORE=A0 MOVE A10,A3 ;DEST Y:X CLR A6 ;BLANKING FLAG CALLR HSNUML0 ADDI >100000,A10 ;ADD VERT FOR NEXT LINE ADDI HS_SIZE,A7 DSJS A11,HSDSPLL MMFM SP,A0,A1,A3,A5,A6,A7,A8,A10,A12 RETS * *A0=NUMBER *A3=Y:X *A12=NUMBER OF DIGITS *A6=BLANK FLAG * HSNUML0 MMTM SP,A0,A1,A2,A3,A4,A5 HSNUML00 MOVE A0,A1 SRL 28,A1 ;NEXT DIGIT VALUE INTO LOWEST 4 BITS JRNE HSNUML1 MOVE A6,A6 JREQ HSNUML2 ;SKIP DIGIT IF BLANKING HSNUML1 CMPI 9,A1 ;BAD DIGIT? JRLS HSNUML10 ;NOPE... MOVK 9,A1 ;OUTPUT 9 ON AN ERROR HSNUML10 MOVK 1,A6 SLL 7,A1 ;*128 (NEXT HEADER PLEASE!!) ADDI AFONT0,A1 ;BASE ADDRESS OF IMAGE HEADER MOVE *A1,A2,L ;GET SIZE MOVE *A1(>40),A4,L ;GET SAG MOVI >0101,A1 MOVI DMAWNZ,A5 CALLA QDMAN HSNUML2 ADDI 11,A3 ;STEP TO NEXT SLL 4,A0 ;NEXT DIGIT DSJS A12,HSNUML00 MMFM SP,A0,A1,A2,A3,A4,A5 RETS * *DISPLAY SCORE TABLE INITIALS IN ATTRACT *A7=TABLE INDEX *A10=DISPLAY COORD * HSINITDSP MMTM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A10,A11,A12 MOVK 10,A11 ;START WITH SCORE 1 HSINTLL MOVK 3,A12 MOVE A10,A3 ;GET DAG SUBI HS_INITS,A7 CALLR RC_LONG ;GET THE FUCKING SCORE=A0 MOVE A0,A2 ;MOVE TO A2 ADDI HS_INITS,A7 HSINTL0 CALLR RC_BYTE ;GET INITIALS ADDK 16,A7 ;STEP TO NEXT INITIAL MOVI >3E3E0000,A1 ;FLASH IF INITS MATCH SCORE CALLR A2_CHECK JREQ HSINTL00 MOVI >27270000,A1 ;COLOR:PALETTE HSINTL00 CALLR INITOUT ;OUTPUT INITIAL DSJS A12,HSINTL0 ADDI >100000,A10 ;NEXT SPOT ON SCREEN ADDI HS_SIZE-48,A7 ;GET NEXT GUY IN CMOS DSJ A11,HSINTLL MMFM SP,A0,A1,A2,A3,A4,A5,A6,A7,A8,A10,A11,A12 RETS * *OUTPUT INITIAL RD15FONT *A0=ASCII *A1=COLOR:PALETTE *A3=COORD * INITOUT MMTM SP,A2,A4,A5 CMPI >7D,A0 JRHI INITERR SUBI 21H,A0 ;ADJUST TABLE BOGOSITY JRNN HSINTL01 INITERR ;BOGUS INITIAL SKIP IT MOVK 8,A2 JRUC HSINTL02 HSINTL01 SLL 5,A0 ADDI RD15FONT,A0 MOVE *A0,A0,L ;GET POINTER MOVE *A0,A2,L ;GET SIZE MOVE *A0(>40),A4,L ;GET SAG MOVI DMACNZ,A5 CALLA QDMAN ZEXT A2,W ;ADD CHARACTER WIDTH ADDK 2,A2 HSINTL02 ADD A2,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,W ;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 .BSS INITTIMR,16 .BSS GET1FLG,16 .BSS GET2FLG,16 * *TIMER FOR INITIAL PROCESS * INITTIM CLR A0 MOVE A0,@GET1FLG,W MOVE A0,@GET2FLG,W CREATE BONPID,INTIML MOVI 30,A1 MOVE A1,@INITTIMR,W MOVE A1,*A0(PA10),L ;SET A10 TO 60 RETS INTIML MOVE @INITTIMR,A0,W DEC A10 JRNE INTIML1 MOVI 60,A10 DEC A0 JRN INITTIMX MOVE A0,@INITTIMR,W INTIML1 CALLA BINBCD MOVI >8300BD,A3 MOVE A12,-*SP,L MOVK 2,A12 MOVK 1,A6 SLL 24,A0 ;SHIFT DIGITS INTO PLACE CALLR HSNUML0 MOVE *SP+,A12,L SLOOP 1,INTIML INITTIMX DIE ;WE FUCKING QUIT * *GET PLAYERS INITIALS - WAIT TILL DONE * GETINIT: SLEEP 10 CALLR DONCK JRNE GETINIT GETINITX SLEEP 60 ;WAIT A SEC. THEN BOOK RETP * *CHECK IF INITIALS DONE * DONCK MOVE @INITTIMR,A2,W JREQ DONCKX MOVE @GET1FLG,A0,W MOVE @GET2FLG,A1,W ADD A0,A1 DONCKX RETS * *GET PLAYER 1 INITIALS * GETINIT1 MOVI P1ITAB,A0 MOVI LTRBX,A2 ;(OIMG) JRUC GTINIT P1ITAB .LONG P1DATA+PSCORE ;SCORE VALUE ; .STRING "AAA",0 .LONG >00202020 ;STARTING INITIALS .LONG >00000000 ;START BOX COORD .IF YUNIT .LONG SWITCH,SWITCH+4,SWITCH+18 ;SWITCH LOCATIONS .ELSE .LONG SWITCH,SWITCH+8,SWITCH+24 .ENDIF .LONG >00420030 ;INITIAL DISPLAY ADDRESS .LONG >26260000 ;COLOR:PALETTE .LONG GET1FLG * *GET PLAYER 2 INITIALS * GETINIT2 MOVI P2ITAB,A0 MOVI LTRBX2,A2 ;(OIMG) JRUC GTINIT P2ITAB .LONG P2DATA+PSCORE ;SCORE VALUE ; .STRING "AAA",0 .LONG >00202020 ;STARTING INITIALS .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 >00420120 ;INITIAL DISPLAY ADDRESS .LONG >27270000 ;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 *PDATA+>60=MOVE STICK ADDRESS *PDATA+>80=FIRE STICK ADDRESS *PDATA+>A0=START BUTTON ADDRESS *PDATA+>C0=INITIAL DISPLAY BASE ADDRESS *PDATA+>E0=COLOR:PALETTE INITIAL *PDATA+>100=INITIAL D0NE 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 MOVI 0,A5 ;(OID) CLR A6 ;(OXVEL) CLR A7 ;(OYVEL) CALLA BEGINOBJ *GET MOVE SWITCHES GTL CMPI 3,A11 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),W ;SAVE COORDS MOVE A1,*A13(PDATA+>50),W *FORM BOX XY COORD AND UPDATE IT GTL5 MOVE *A13(PDATA+>40),A0,W ;GET COORDS MOVE *A13(PDATA+>50),A1,W MOVI >15,A3 MOVI >16,A5 MPYU A0,A3 ;FORM X OFFSET MPYU A1,A5 ;FORM Y OFFSET ADDI >82,A3 ADDI >0E,A5 MOVE A3,*A8(OXPOS),W ;UPDATE POSITION MOVE A5,*A8(OYPOS),W *UPDATE YOUR LETTER VALUE *A0=X OFFSET *A1=Y OFFSET MOVK 6,A3 MPYU A1,A3 ADD A0,A3 ;THIS IS THE INDEX TO MATIRX 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,W ;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 ADDI >19,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 SLEEP 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 * WONT 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 **** * **** IMPORTANT NOTE ON WORD AND LONG WORD PACKING **** * **** 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 * SCR_M $MACRO A,B,C,D .BYTE :A: .BYTE :B: .BYTE :C: .BYTE :D: $END INIT_M $MACRO A,B,C .BYTE :A: .BYTE :B: .BYTE :C: .BYTE 0 ;CHECKBYTE $END ALL_TIME_ROM_TABLE: SCR_M 22H,12H,21H,45H ;****ZERO ENTRY...NOT SEEN! INIT_M "E","P","J" ROM_ENTRY_SIZE EQU $-ALL_TIME_ROM_TABLE SCR_M 03H,05H,10H,48H INIT_M "J","O","N" ;1 SCR_M 01H,84H,80H,00H INIT_M "T","I","M" ;2 SCR_M 01H,79H,82H,18H INIT_M "T","J","E" ;3 SCR_M 01H,75H,00H,72H INIT_M "L","I","P" ;4 SCR_M 01H,69H,11H,96H INIT_M "M","L","Z" ;5 ;LOCASIO SCR_M 01H,65H,10H,08H INIT_M "G","W","S" ;6 SCR_M 01H,60H,62H,33H INIT_M "A","L","T" ;7 SCR_M 00H,57H,02H,18H INIT_M "B","L","S" ;8 SCR_M 00H,50H,00H,01H INIT_M "J","O","N" ;9 SCR_M 00H,45H,65H,71H INIT_M "H","E","Y" ;10 SCR_M 00H,45H,01H,27H ALL_TIME_ENTRIES EQU ($-ALL_TIME_ROM_TABLE)/ROM_ENTRY_SIZE TODAYS_ROM_TABLE: SCR_M 22H,12H,21H,45H ;****ZERO ENTRY...NOT SEEN! INIT_M "E","P","J" SCR_M 00H,20H,01H,27H INIT_M "M","J","T" SCR_M 00H,19H,01H,69H INIT_M "D","R","J" SCR_M 00H,10H,08H,65H INIT_M "D","J","T" SCR_M 00H,08H,21H,64H INIT_M "N","L","N" SCR_M 00H,05H,72H,18H INIT_M "M","T","N" SCR_M 00H,05H,12H,55H INIT_M "T","L","C" SCR_M 00H,04H,12H,50H INIT_M "F","A","W" SCR_M 00H,03H,19H,20H INIT_M "F","O","O" SCR_M 00H,02H,99H,44H INIT_M "B","A","T" SCR_M 00H,02H,57H,38H INIT_M "M","A","N" TODAYS_ENTRIES EQU ($-TODAYS_ROM_TABLE)/ROM_ENTRY_SIZE .END