IDT 'INTERP3' JF 9/17 * ATA * >>> GRAPHICS LANGUAGE INTERPRETER <<< * ************************************************************ * * * GRAPHICS PROGRAMMING LANGUAGE INTERPRETER * * * ************************************************************ * STATUS BLOCK CONTENTS RELATIVE TO PAD * * >70->71 LAST VDP ADDRESS FROM MONITOR* * >72 STKDAT DATA STACK POINTER * * >73 STKADD ADDRESS STACK POINTER * * >74 PLAYER PLAYER NUMBER * * >75 KEYBRD CODE FOR KEY PUSHED * * >76 JOYY Y VALUE OF JOYSTICK * * >77 JOYX X VALUE OF JOYSTICK * * >78 RANDOM RANDOM NUMBER * * >79 TIME TIMING VARIABLE * * >7A MOTION MOTION PARAMETER * * >7B VDPST VDP STATUS * * >7C STATUS STATUS REGISTER * * >7D CHRBUF CHARACTER BUFFER * * >7E YPT Y POINTER IN VIDEO DISPLAY * * >7F XPT X POINTER IN VIDEO DISPLAY * ************************************************************ * EXTERNAL DEFINITIONS DEF NEXT,VDPRD,VDPWD,WRVDP,VDPWA,XTAB9 JF 9/19 DEF GRMWA,GRMRA,GRMWD,GRMRD,H20 DEF SET,RESET,ENTRY,PUTSTK,GETSTK DEF SROM,SGROM,C2,C1000,LNKVRM,LNKCRM DEF GETDA,GETMAB,SETV,SPGROM,H0300 JF 8/24 DEF RND,GPLLNK,XXML,VDPIO,CPUIO ATA REF PARSEG,FLTTAB,WRITE,READ,TIMER,XTAB REF CONTG,EXECG,RTNG,VERIFY,CHTAB REF XTAB2,XTAB3,XTAB4,XTAB5 REF XTAB6,XTAB7,XTAB8 JF 9/17 REF MAPX3,MAPX4,MAPX5,SCRNX REF ASMCON,FILE99 JF 9/17 * I/O DEVICE ADDRESSES MAPPER EQU >8810 MAPPER COMMAND/STATUS PORT MF0 EQU >8000 ATA VDPREG EQU >8000 WRVDP EQU >4000 VDPWA EQU >8C02 LOAD VDP ADDRESS VDPSTA EQU >8802-VDPWA READ VDP STATUS VDPWD EQU >8C00-VDPWA WRITE DATA TO VDP VDPRD EQU >8800-VDPWA READ DATA FROM VDP GRMRD EQU >9800 READ GROM DATA GRMWA EQU >9C02-GRMRD LOAD GROM ADDRESS GRMRA EQU >9802-GRMRD READ GROM ADDRESS GRMWD EQU >9C00-GRMRD WRITE DATA TO GRAM SGCADR EQU >8400 LOAD SOUND CHIP ADDRESS SPKCMD EQU >9400 SPEECH WRITE SPKSTA EQU >9000 SPEECH READ *----------------------------------------------------------* * * STATUS BLOCK DEFINITIONS PAD EQU >8300 FAC EQU PAD+>4A SCLEN EQU PAD+>55 SCNAM EQU PAD+>56 TEMP2 EQU PAD+>6C TYPE EQU PAD+>6D STKDAT EQU PAD+>72 STKADD EQU PAD+>73 PLAYER EQU PAD+>74 KEYBRD EQU PAD+>75 JOYY EQU PAD+>76 JOYX EQU PAD+>77 RANDOM EQU PAD+>78 TIME EQU PAD+>79 MOTION EQU PAD+>7A VDPST EQU PAD+>7B STATUS EQU PAD+>7C CHRBUF EQU PAD+>7D YPT EQU PAD+>7E XPT EQU PAD+>7F * * WORKSPACE DEFINITIONS INTWSP EQU PAD+>C0 INTERRUPT WORKSPACE AREA GPLWS EQU PAD+>E0 RESERVE WORKSPACE AREA ATA * * * ABSOLUTE 9900 LOCATIONS RAND16 EQU PAD+>C0 SEED FOR RANDOM NUMBER INTFLG EQU PAD+>C2 Flags for VDP interrupt handler INTPTR EQU PAD+>C4 Pointer to VDP interrupt handler KBDFLG EQU PAD+>C6 KBD FLAG (0=99/4,1=PASCAL,2=TE II) OLDMOD EQU PAD+>C7 LAST MODIFIER FLAGS DBNCE EQU PAD+>C8 POSITION DEBOUNCE FOR CONSOLE KBD DBNC1 EQU PAD+>C9 POSITION DEBOUNCE FOR SPLIT KBD 1 DBNC2 EQU PAD+>CA POSITION DEBOUNCE FOR SPLIT KBD 2 SAVEG EQU PAD+>CB SAVE GROM ADDRESS OF HEADER SNDADD EQU PAD+>CC SOUND LIST ADDRESS STFLGS EQU PAD+>CE NUMBER OF SOUND BYTES CRULST EQU PAD+>D0 SADDR EQU PAD+>D2 SAVVDP EQU PAD+>D4 TIMOUT EQU PAD+>D6 RSAVE EQU PAD+>D8 SAVE R11 IN SCAN ROUTINE * EQU PAD+>DA * EQU PAD+>DC * EQU PAD+>DE * * LOCATIONS OF LOW ORDER BYTES OF REGISTERS R0LB EQU PAD+>E1 R1LB EQU PAD+>E3 R2LB EQU PAD+>E5 R3LB EQU PAD+>E7 R4LB EQU PAD+>E9 R5LB EQU PAD+>EB ATA R6LB EQU PAD+>ED R8LB EQU PAD+>F1 R7LB EQU PAD+>EF R9LB EQU PAD+>F3 R11LB EQU PAD+>F7 R12LB EQU PAD+>F9 AR12LB EQU PAD+>D9 R13LB EQU PAD+>FB * **** NEW SCRATCHPAD DEFINITIONS * SCRLBF EQU >8430 ATA SCRWS EQU SCRLBF+40 MAP0 EQU >8000 MAP FILE 0 MAP1 EQU >8040 1 MAP2 EQU >8080 2 MAP3 EQU >80C0 3 MAPWS EQU >8410 WORKSPACE FOR MAPPER XOPS ATA DELAY1 EQU >849E 60-CYCLE DELAY COUNTER FOR SPEED MATCH ATA DELAY2 EQU >849C DELAY COUNTER FOR KBD DEBOUNCE ATA VDPSPD EQU >849A 50 (EUROPE) OR 60 (USA) ATA CLKSPD EQU >849B SYSTEM CLK FREQ ON THE BUS GFH GLINK0 EQU >84A4 USED FOR GPL LINK FROM ASSEMBLY ATA GLINK1 EQU >84A6 USED FOR GPL LINK FROM ASSEMBLY ATA ***CLICK EQU >84A8 keyboard click flag ATA *----------------------------------------------------------* * SPECIAL EQUATE VALUES MONIT EQU >0000 MONITOR START ADDRESS IN GROM ATA ALPHLK EQU >83C3 ATA ROWBAS EQU 14 JOYBAS EQU 12 COLBAS EQU 32 ****BBJOY EQU MONIT+>16E0 Joystick tables ATA ****KEYTAB EQU MONIT+>1700 Table of unmodified keycodes ATA ****KSHIFT EQU MONIT+>1734 TABLE OF SHIFTED KEYCODES ATA ****KFNCTN EQU MONIT+>1768 Table of function keycodes ATA ****KCNTRL EQU MONIT+>179C Table of control keycodes ATA ****KSPLIT EQU MONIT+>17D0 TABLE OF SPLIT KEYBOARD KEYCODES ATA VDELTA EQU >2000 >C0 - >E0 INVALID VERTICAL *****RSMOT EQU >0780 SPRITE MOTION LIST ADDRESS ATA *****QSAML EQU >0480 SML - SAL ATA SAL EQU >84A0 POINTER TO SPRITE ATTRIBUTE LIST ATA SVL EQU >84A2 POINTER TO SPRITE VELOCITY LIST ATA SHIFTQ EQU >2200 HHU SHIFT Q CODE H400C EQU >400C INTERRUPT ADDRESS VECTOR H4000 EQU >4000 ROM ID LOCATION INTROM EQU >0000 CRU ADDRESS FOR PERIPH. ROM DSRWSP EQU >2800 DSR WORKSPACE FOR 99/4 DEBUGGER XOPWSP EQU >280A XOP WORKSPACE FOR AL BPS SSFLG EQU >2836 SINGLE STEP FLAG MALPC EQU >2838 MODIFIED ALPC FLAG SSTEP EQU >4024 DSR ENTRY POINT FOR SNGL STEP ALBRK EQU >4028 DSR ENTRY POINT AFTER AL BP PAGE *----------------------------------------------------------* * ***** ENTRY POINT OF EMULATOR ***** * RORG 0 DATA GPLWS,ENTRY RESET VECTOR >0000 ATA DATA INTWSP,REMOTE ALL 9901 INTERRUPTS >0004 DATA INTWSP,NULLRT UNIMPLEMENTED INSTRUCTION >0008 * (OR ARITHMETIC OVERFLOW) * IDBYTE BYTE >80 (WAS CLOCK, NOW CONSOLE MODEL) >000C ATA HAA BYTE >AA VALID ROM ID >000D ********************************************************** * CALL SCAN FROM ROM * ********************************************************** SCNKEY B @KSCAN ALWAYS BL HERE FROM ANY ROM >000E ********************************************************** BIT12 DATA >0008 >0012 * ** BRANCH TO RETURN FROM BREAKPOINT FROM 99/4 DSR * SBZ 0 DISABLE 99/4 DSR >0014 B @PROCSS RE-ENTRY ON BP IN 99/4 >0016 *** SBZ 0 DISABLE 99/4 DSR >001A B @TRYAGN RE-ENTRY ON ILLEGAL OPCODE IN 99/4 >001C ************************************************************ B @CHKBRK CHECK FOR BASIC & RS232 "BREAK" KEY >0020 ************************************************************ GPLLNK B @GPLLK0 >0024 ************************************************************ PAGE *----------------------------------------------------------* ATA * 000 001 010 011 100 ATA *MODTAB DATA KEYTAB,KSHIFT,KCNTRL,KCNTRL,KFNCTN >0028 ATA RMDTAB DATA RKEYTB,RKSHFT,RKCNTL,RKCNTL,RKFCTN ***DEBUG*** ATA * 101 110 111 ATA * DATA KFNCTN,KFNCTN,KFNCTN >0032 ATA DATA RKFCTN,RKFCTN,RKFCTN ***DEBUG*** ATA PAGE ATA *==========================================================* ATA SBZ 0 DISABLE 99/4 DSR >0038 LWPI XOPWSP SELECT CORRECT WORKSPACE >003A RTWP RETURN TO AL PROGRAM >003E DATA XOPWSP,PRCXOP XOP VECTOR FOR AL BP XOP0 >0040 * PASCAL TIBUG XOP DATA >FFD8,>FFF8 XOP1 >0044 * A SPARE XOP JUST FOR FUN DATA >83A0,>8300 XOP2 >0048 * MEMORY MAPPER XOPS DATA MAPWS,MAPX3 XOP3 >004C DATA MAPWS,MAPX4 XOP4 >0050 DATA MAPWS,MAPX5 XOP5 >0054 * SCREEN HANDLER XOPS DATA SCRWS,SCRNX XOP6 >0058 C1000 DATA >1000 PRESERVE ADDRESSES >005C H0B EQU $+1 ATA FNCEQ DATA >070B TEST BITS FOR QUIT KEY >005E LDKADD MOVB R6,@GRMWA(R13) >0060 MOVB @R6LB,@GRMWA(R13) LOAD GROM ADDRESS >0064 RESET SZCB @BIT2,@STATUS RESET CONDITION BIT >006A IN2 EQU $+2 C2 EQU IN2 RMAP1 EQU $+3 H0300 EQU $ Allows squish of 1 word in SCREEN. JF 8/24 NEXT LIMI 2 ALLOW INTERRUPTS BETWEEN LMAP1 EQU $ H03 EQU $ LIMI 0 GPL INSTRUCTIONS - TRYAGN MOVB *R13,R9 LOAD INSTRUCTION FROM GAME ROM PROCSS JLT ABOPS JUMP ON SIGN BIT MOVB R9,R4 MOVE INST INTO WORK REGISTER SRL R4,12 SHIFT TO LEAVE TOP 3 BITS * 2 MOV @ITAB(R4),R5 GET BRANCH ADDRESS B *R5 JUMP ON TOP THREE BITS *----------------------------------------------------------* * INSTRUCTIONS WITH A AND B OPERANDS ABOPS CLR R4 CLEAR VDP RAM FLAGS MOV R9,R5 LOAD R5 WITH DOUBLE FLAG ANDI R5,>100 BL @GETMAD GET FIRST OPERAND SWPB R4 MOV R1,R3 SAVE VARIABLE ADDRESS MOV R0,R2 SAVE VARIABLE VALUE CI R9,>A000 SINGLE OPERAND ? JL AOPS YES COC @IMMOPS,R9 IMMEDIATE OR VARIABLE ? JNE ABOPA VARIABLE MOV R13,R1 GET IMMEDIATE VALUE MOVB *R1,R0 GET FIRST BYTE DEC R1 MODIFY FOR COMMON ROUTINE BL @MADC2 GO TO COMMON ROUTINE JMP BOPS AOPS MOV R9,R8 BRANCH THROUGH BRANCH TABLE SRL R8,8 SETO R0 MOV @ATAB(R8),R8 B *R8 ABOPA BL @GETMAD GET SECOND VARIABLE OPERAND BOPS MOV R9,R8 BRANCH THROUGH BRANCH TABLE SRL R8,9 MOV @BTAB(R8),R8 LOAD BRANCH ADDRESS Q C R2,R0 COMPARE FOR IF PRIMITIVES B *R8 *----------------------------------------------------------* * PERFORM IF COMPARISONS GREQ JLT RESET A ALGEBRAIC .GE. B SET SOCB @BIT2,@STATUS SET CONDITION BIT JMP NEXT HIGH JH SET A LOGICAL .GT. B JMP RESET HIGHEQ JHE SET A LOGICAL .GE. B JMP RESET GREATR JGT SET A ALGEBRAIC .GT. B JMP RESET IFAND INV R0 PERFORM LOGICAL AND SZC R0,R2 JEQ SET JMP RESET IFZ MOV R2,R2 COMPARE TO ZERO EQUAL STST R4 STORE STATUS IN STATUS BYTE MOVB R4,@STATUS JMP NEXT TSTST MOV R9,R0 MOVE INST TO SHIFT REGISTER SLA R0,12 REMOVE HIGH ORDER BITS SRL R0,13 POSITION 3 REMAINING BITS MOVB @STATUS,R5 LOAD STATUS BYTE SLA R5,R0 SHIFT TO TEST BIT JOC SET JMP RESET *----------------------------------------------------------* * BRANCH INSTRUCTIONS BLONG MOVB *R13,R6 RECALL ADDRESS FROM GROM MOVB *R13,@R6LB JMP LDKADD LOAD GAME ROM ADDRESS BSET MOVB @STATUS,R4 IS CONDITION SET ? SLA R4,2 JLT BRAD YES NOBR MOVB *R13,R4 INCREMENT PROGRAM COUNTER JMP RESET BIT2 EQU $+1 CONSTANT >20 BRESET MOVB @STATUS,R4 IS CONDITION SET ? SLA R4,2 JLT NOBR YES BRAD MOVB *R13,@R9LB GET SECOND BYTE OF ADDRESS H1FFF EQU $+2 ANDI R9,>1FFF MASK TO LEAVE BRANCH ADDRESS MOVB @GRMRA(R13),R6 READ OLD MSB OF GROM ADDRES ANDI R6,>E000 LEAVE TOP 3 BITS OF ADDRESS SOC R9,R6 COMBINE TO GIVE NEW ADDRESS MOVB @GRMRA(R13),R0 get second byte for spec ATA JMP LDKADD *----------------------------------------------------------* * SINGLE OPERAND INSTRUCTIONS ABS ABS R2 ABSOLUTE VALUE JMP TRAP NEG NEG R2 NEGATE VALUE JMP TRAP CLR SETO R2 SET TO ZERO INV INV R2 INVERT VALUE JMP TRAP FETCH MOV R4,R6 SAVE ADDRESSING MODE FLAG BL @PUTSTK SAVE CURRENT PROGRAM ADDRESS DECT R4 SET I TO OLD STACK POINTER BL @GTSTK GET ADDRESS FROM STACK TOP MOVB *R13,R2 LOAD BYTE FROM GROM SRA R2,8 EXTEND SIGN INC @PAD(R4) INCREMENT RETURN ADDRESS INCT R4 SET I BACK TO NEW STACK POINTER BL @GTSTK1 RESTORE GROM ADDRESS MOV R6,R4 RESTORE ADDRESSING MODE FLAG JMP TRAP CASE DEC R2 VARIABLE DISPLACEMENT JNC RESET MOVB *R13,R5 SKIP TO NEW ADDRESS MOVB *R13,R5 SKIP TO NEW ADDRESS JMP CASE PUSH AB R14,@STKDAT LOAD STACK ADDRESS R14=01XX MOVB @STKDAT,R6 SRL R6,8 MOVB @R2LB,@PAD(R6) PUSH LSBYTE B @NEXT *----------------------------------------------------------* * TWO OPERAND INSTRUCTIONS DECT SRL R0,14 DECREMENT VALUE BY 2 INCT DEC R0 INCREMENT INSTRUCTIONS INC MINUS NEG R0 SUBTRACT OPERATION DEC ADD MOVB R5,R5 SINGLE OR DOUBLE JEQ ADDB A R0,R2 ADD OPERATION JMP FILLST AND INV R0 LOGICAL AND OPERATION SZC R0,R2 JMP FILLST OR SOC R0,R2 LOGICAL OR OPERATION JMP FILLST XOR XOR R0,R2 LOGICAL EXCLUSIVE OR OPERATION JMP FILLST STORE MOV R0,R2 STORE SOURCE INTO DESTINATION JMP TRAP EXCH MOV R2,R9 EXCHANGE A AND B MOV R0,R2 BL @TRAPA SWPB R4 MOV R1,R3 JMP MUL2 SRA SRA R2,R0 SHIFT RIGHT ARITHMETIC JMP TRAP SLL SLA R2,R0 JMP TRAP SRL MOVB R5,R5 SHIFT RIGHT LOGICAL JNE SRL1 DOUBLE INSTRUCTION SB R2,R2 SRL1 SRL R2,R0 JMP TRAP SRC MOVB R5,R5 SHIFT RIGHT CIRCULAR JNE SRC1 DOUBLE INSTRUCTION MOVB @R2LB,R2 SRC1 SRC R2,R0 JMP TRAP MUL MOV R2,R8 MULTIPLY MOVB R5,R5 SINGLE OR DOUBLE JNE MUL0 DOUBLE SB R8,R8 CLEAR EXTENDED SIGN BITS MUL0 MPY R0,R8 MOVB R5,R5 SINGLE OR DOUBLE ? JNE MUL1 DOUBLE MOVB R9,@R8LB MUL1 MOV R8,R2 STORE FIRST HALF OF RESULT BL @TRAPA MUL2 MOV R9,R2 STORE SECOND HALF OF RESULT JMP TRAP DIV MOVB R5,@STATUS CLEAR STATUS MOV R2,R8 MOV R0,R2 MOV R3,R1 SET DESTINATION ADDRESS INC R1 MOVB R5,R5 SINGLE OR DOUBLE ? JEQ DIV1 SINGLE INC R1 DIV1 MOVB R4,R4 CPU OR VDP ? JEQ DIVC CPU BL @MVDPA GET REST OF DIVIDEND FROM VDP JMP DIVB DIVC BL @MADC GET REST OF DIVIDEND FROM CPU DIVB MOV R0,R9 MOVB R5,R5 SINGLE OR DOUBLE ? JNE DIV2 MOVB @R8LB,R9 DO SIGN EXTENSION FOR BYTE SRA R8,8 OPERANDS DIV2 DIV R2,R8 PERFORM DIVISION JNO MUL1 SOCB @BIT4,@STATUS SET DIVIDE OVERFLOW JMP MUL1 * FILL IN STATUS BITS ADDB AB @R0LB,@R2LB FILLST STST R11 STORE STATUS WORD MOVB R11,@STATUS STORE STATUS BITS * * *** TRAP OUT CHANGES IN CB, XPT, AND YPT *** * TRAP LI R11,NEXT LOAD R11 TO RETURN TO NEXT TRAPA MOVB R4,R4 DESTINATION IS CPU OR VDP ? JEQ STCPU CPU MOVB @R3LB,*R15 LOAD VDP ADDRESS ORI R3,WRVDP SET BIT TO WRITE TO VDP MOVB R3,*R15 MOVB R5,R5 SINGLE OR DOUBLE JEQ TRAP1 SINGLE MOVB R2,@VDPWD(R15) MOVE 2 BYTES TO VDP INC R3 TRAP1 MOVB @R2LB,@VDPWD(R15) MOVE 1 BYTE TO VDP INC R3 H04 EQU $ TEXIT RT STCPU MOVB R5,R5 SINGLE OR DOUBLE ? JEQ TRAP2 SINGLE MOVB R2,*R3+ STORE 2 BYTE RESULT TRAP2 SWPB R2 MOVB R2,*R3+ STORE 1 BYTE RESULT CI R3,PAD+>7E IS CB THE DESTINATION ? JNE TEXIT NO MOV R11,R6 BL @GETDA GET VDP DISPLAY ADDRESS RTN MOVB R2,@VDPWD(R15) WRITE CHARACTER TO VDP B *R6 RETURN *----------------------------------------------------------* * MISCELLANEOUS INSTRUCTIONS MISCLN SLA R9,3 REMOVE TOP THREE BITS OF INST SRL R9,10 LEAVE BOTTOM FIVE BITS * 2 MOV @MSCTAB(R9),R4 GET BRANCH ADDRESS B *R4 * *----------------------------------------------------------* * GENERATE A RANDOM NUMBER RANDNO MOVB *R13,R6 LOAD MODULO VALUE SRL R6,8 SHIFT TO LOW ORDER POSITION BL @RND JMP BKGR1 * * SET BACKGROUND COLOR BKGRND LI R7,>700+VDPREG CHANGE BACKGROUND COLOR MOVB *R13,@R7LB IMMEDIATE OPERAND BL @SETVDP OUTPUT ADDRESS TO VDP BKGR1 B @NEXT PAGE * *** Check for the BASIC and RS232 "BREAK" key * CHKBRK LI R12,COLBAS Select output for rows *** LDCR @H00,4 Select line 0 ATA 7/16 LDCR R12,4 Select line 0 ATA 7/16 SRC R12,7 Kill some time LI R12,ROWBAS Select input for columns STCR R12,4 Read data CB @FNCEQ+1,R12 Is proper key down? (fctn) JNE CHKBEX No so exit LI R12,COLBAS Select output for rows LDCR @H04,4 Select '4' line SRC R12,7 Kill some time LI R12,ROWBAS Select input for columns STCR R12,4 Read data CB @FNCEQ,R12 Is proper key down? (4) CHKBEX RT Return condition to the caller PAGE *==========================================================* * INPUT / OUTPUT INSTRUCTION INOUT MOV R0,R2 GET INDEX INTO I/O TABLE MOV R3,R1 MOVE LIST ADDRESS FOR CASSETTE A R2,R2 MOV @IOTAB(R2),R4 LOAD ADDRESS OF I/O FUNCTION CLR R9 CLEAR R9 FOR CRU INSTRUCTIONS B *R4 BRANCH TO I/O FUNCTION * SOUND INSTRUCTION SOUND ANDI R14,>FFFE CLEAR SOUND SOURCE FLAG SOC R0,R14 SET SOUND SOURCE FLAG MOV *R3,@SNDADD LOAD SOUND LIST ADDRESS MOVB R14,@STFLGS SET TIME DELAY TO 1 UNIT R14=01XX QEXIT JMP BKGR1 ATA 7/16 * CRU INSTRUCTIONS * CRUIN INC R9 CRUOUT MOV *R1+,R12 LOAD CRU BASE ADDRESS A R12,R12 CLR R2 MOVB *R1+,R2 LOAD NUMBER OF BITS TO MOVE SLA R2,4 SOC R2,R9 COMBINE NUMBER AND IN/OUT FLAG SRC R9,6 REPOSITION BITS ORI R9,>3012 R9 IS NOW LDCR OR STCR MOVB *R1,R2 LOAD CPU SOURCE/DEST ADDRESS SWPB R2 AI R2,PAD X R9 EXECUTE INSTRUCTION IN R9 JMP QEXIT PAGE *==========================================================* * MOVE DATA INSTRUCTION MOVDAT MOVB R14,R5 SET DOUBLE FLAG SRL R9,9 IS LENGTH VAR OR IMMEDIATE ? JOC LIMM IMMEDIATE BL @GETMAD GET VARIABLE LENGTH MOV R0,R8 JMP MVSRC LIMM MOVB *R13,R8 LOAD IMMEDIATE LENGTH MOVB *R13,@R8LB MVSRC CLR R4 SLA R9,12 BL @MVADDR GET DEST ADDRESS MOV R1,R2 SAVE DEST ADDRESS AB R9,R9 WAS DEST VDP REGISTER ? JNC DTYPE NO AI R4,3 DESTINATION IS VDP REGISTERS DTYPE MOV R4,R7 SAVE DEST TYPE CLR R4 BL @MVADDR GET SOURCE ADDRESS * LOAD BRANCH REGISTERS A R4,R4 DOUBLE R4 MOV @MSRC(R4),R6 LOAD ADDRESS TO SOPURCE OF MOVE A R7,R7 DOUBLE R7 MOV @MDST(R7),R7 LOAD ADDRESS TO DESTINATION BL @PUTSTK SAVE PROGRAM COUNTER BSRC B *R6 BRANCH TO SOURCE * LOAD ONE BYTE FROM THE SOURCE OF THE MOVE CPUSRC MOVB *R1+,R11 LOAD BYTE FROM CPU ADDR SPACE B *R7 VDPSRC MOVB @R1LB,*R15 LOAD VDP WITH ADDRESS ATA MOVB R1,*R15 INC R1 INCREMENT SOURCE ADDRESS MOVB @VDPRD(R15),R11 LOAD BYTE FROM VDP ATA B *R7 ATA GRMSRC MOVB R1,@GRMWA(R13) LOAD GROM WITH ADDRESS ATA MOVB @R1LB,@GRMWA(R13) INC R1 INCREMENT SOURCE ADDRESS MOVB *R13,R11 LOAD BYTE FROM VDP ATA B *R7 * DESTINATIONS FOR THE MOVE INSTRUCTION CPUDST MOVB R11,*R2+ STORE BYTE IN CPU ADDR SPACE JMP TESTLP GRMDST MOVB R2,@GRMWA(R13) ATA MOVB @R2LB,@GRMWA(R13) INC R2 MOVB R11,@GRMWD(R13) ATA JMP TESTLP REGDST CB @R2LB,R14 JNE REGADJ *** ALWAYS 16K MEMORY ATA 7/16 *** COC @BIT12,R14 TEST VDP MEMORY TYPE ATA 7/16 *** JNE REG100 ATA 7/16 H8000 EQU $+2 ATA ORI R11,>8000 SET 16K MEMORY SELECT REG100 MOVB R11,@SAVVDP SAVE VDP REGISTER REGADJ MOVB R11,*R15 STORE BYTE IN VDP REGISTER MOV R2,R3 ATA 7/16 ORI R3,>80 SET FLAG FOR VDP REGISTER LOAD ATA 7/16 MOVB @R3LB,*R15 STORE REGISTER NUMBER ATA 7/16 **** ANDI R2,7 IN CASE VR0 WAS FIRST, SO WE FIND VR1 ATA 7/16 INC R2 INCREMENT REGISTER NUMBER JMP TESTLP VDPDST MOVB @R2LB,*R15 ATA ORI R2,WRVDP SET FLAG TO WRITE TO VDP ATA MOVB R2,*R15 INC R2 INCREMENT DESTINATION ADDRESS MOVB R11,@VDPWD(R15) STORE BYTE IN VDP ATA * TEST END OF LOOP FOR THE MOVE INSTRUCTION TESTLP DEC R8 DECREMENT NUMBER TO MOVE JGT BSRC LOOP UNTIL NUMBER IS ZERO TSTRTN B @RETNC RESTORE PROGRAM COUNTER PAGE *==========================================================* * COMPUTE ADDRESS FOR MOVE INSTRUCTION MVADDR AB R9,R9 IS ADDRESS IN GROM ? JOC GETMAD YES INGROM MOVB *R13,R3 LOAD GROM ADDRESS INC R4 SET GROM FLAG MOVB *R13,@R3LB MOV R11,R12 AB R9,R9 IS GROM ADDRESS INDEXED ? JNC NOGNDX NO MOVB *R13,R1 INDEX IS ONLY ONE BYTE BL @MADDA GET INDEX VALUE A R0,R3 ADD INDEX TO ADDRESS NOGNDX MOV R3,R1 RETURN ADDRESS IN R1 SRL R9,1 B *R12 RETURN *==========================================================* * GLOBAL ADDRESS DECODE: * R1 = ADDRESS OF VARIABLE * R0 = VALUE OF VARIABLE * SINGLE BYTE VALUES ARE SIGN EXTENDED * IF ADDRESS IS IN VDP, THEN THE MSBYTE OF R4 * IS SET TO >80 GETMAB CLR R5 BYTE FLAG GETMAD MOVB *R13,R1 GET NEXT BYTE FROM GAME ROM JLT MLONG LONG ADDRESS MADDA SRL R1,8 SINGLE BYTE ADDRESS MADD AI R1,PAD ADD CPU RAM ADDRESS CI R1,PAD+>7D CHARACTER BUFFER ? JNE MADC * LOAD CB FROM VDP MEMORY CLR R10 SET FLAG TO READ FROM VDP MOV R11,R6 SAVE RETURN ADDRESS BL @GETDAD SET VPD RAM ADDRESS MOV R6,R11 RESTORE RETURN ADDRESS MOVB @VDPRD(R15),R0 LOAD CB FROM DISPLAY COC @IN2,R14 IS IT MULTICOLOR MODE?????????? JNE MADE NO, WHO CARES??? JNC $+4 WHICH NYBBLE???? SLA R0,4 LOW NYBBLE SRL R0,4 HIGH NYBBLE MADE MOVB R0,@CHRBUF STORE CHARACTER MADC MOVB *R1,R0 LOAD VALUE OF VARIABLE MADC2 MOVB R5,R5 SINGLE OR DOUBLE INSTRUCTION ? JNE MDOUB DOUBLE MSIGN SRA R0,8 SIGN EXTEND BYTE VALUE RT C1 EQU $+2 MDOUB MOVB @1(R1),@R0LB GET SECOND HALF OF DOUBLE RT MLONG MOVB *R13,@R1LB GET SECOND HALF OF ADDRESS MOV R1,R10 SAVE CONTROL BITS ANDI R1,>FFF DELETE CONTROL BITS CI R1,>F00 LOOK FOR EXTENDED ADDRESS JLT MLONG1 NO, JUST A REGULAR ADDRESS SLA R1,8 EXTENDED ADDRESS. MAKE ROOM MOVB *R13,@R1LB GET ADDRESS MLONG1 SLA R10,2 BASE ADDRESS NEEDED ? JNC MVDP NO MOVB *R13,R6 GET ADDRESS OF BASE ADDRESS SRL R6,8 MOVB @PAD(R6),R0 LOAD BASE ADDRESS MOVB @PAD+1(R6),@R0LB A R0,R1 MVDP SLA R10,1 VDP OR 9985 RAM SPACE ? JNC MCPU 9985 RAM SPACE INCT R4 SET VDP INDICATOR SLA R10,1 INDIRECT ADDRESS ? JNC MVDPA NO MOVB @PAD(R1),R0 LOAD INDIRECT ADDRESS MOVB @PAD+1(R1),@R0LB MOV R0,R1 MVDPA MOVB @R1LB,*R15 LOAD ADDRESS INTO VDP MOVB R1,*R15 **** SLA R0,8 NO OP ATA 7/16 MOVB @VDPRD(R15),R0 RECALL CONTENTS OF VDP RAM MOVB R5,R5 SINGLE OR DOUBLE INSTRUCTION ? JEQ MSIGN SINGLE MOVB @VDPRD(R15),@R0LB RECALL LSBYTE FROM VDP RAM RT MCPU SLA R10,1 INDIRECT ADDRESS ? JNC MADD NO CI R1,>7C INDIRECT ON STATUS BYTE ? JNE MADB NO MOVB @STKDAT,R1 GET TOP STACK ADDRESS SB R14,@STKDAT R14=01XX JMP MADDA MADB MOVB @PAD(R1),R1 LOAD INDIRECT ADDRESS JMP MADDA *==========================================================* * RETURN ADDRESS FROM LIBRARY OR PROGRAM RGBA BL @GETSTK RECALL GROM BASE ADDRESS MOV @PAD(R4),R13 MOVB R4,@GRMWD(R13) SYNCHRONIZE YOUR GROMS RETURN SZCB @BIT2,@STATUS RESET CONDITION BIT RETNC LI R11,NEXT GETSTK MOVB @STKADD,R4 LOAD ADDRESS OF SUBROUTINE STACK SRL R4,8 MOVE TO LOW ORDER BYTE GTSTK DECT @STKADD NEW VALUE OF STACK POINTER GTSTK1 MOVB @PAD(R4),@GRMWA(R13) LOAD RETURN ADDRESS MOVB @PAD+1(R4),@GRMWA(R13) RT RTNSET SOCB @BIT2,@STATUS SET CONDITION BIT JMP RETNC * * PUSH PROGRAM COUNTER IN K ONTO STACK CALL MOVB *R13,R6 GET BRANCH ADDRESS FROM GROM LI R11,LDKADD SET RETURN POINTER MOVB *R13,@R6LB PUTSTK INCT @STKADD NEW VALUE OF STACK POINTER MOVB @STKADD,R4 LOAD ADDRESS OF STACK SRL R4,8 MOVE TO LOW ORDER BYTE MOVB @GRMRA(R13),@PAD(R4) SAVE ADDRESS ON STACK MOVB @GRMRA(R13),@PAD+1(R4) DEC @PAD(R4) RT *==========================================================* * LOAD XPTR AND RETURN CHRBUF GETDA LI R10,WRVDP LOAD VDP WRITE FLAG *** GETDAD MOVB @XPT,R7 LOAD VALUE OF XPT COC @IN2,R14 TEST IF MULTICOLOR MODE JEQ MCMDA SLA R7,3 MASK OUT TRUE XPT VALUE SRL R7,8 MOVE TO LOW ORDER BYTE MOVB @YPT,R7 LOAD VALUE OF YPT SRL R7,3 MOVE TO CORRECT POSITION A R10,R7 READ OR WRITE FLAG *** SETVDP MOVB @R7LB,*R15 LOAD CHARACTER BUFFER MOVB R7,*R15 STORE ADDRESS S R10,R7 GETRTN RT *** SETV LI R7,WRVDP WRITE TO VDP MEMORY JMP SETVDP * MULTICOLOR MODE ADDRESS COMPUTATION MCMDA MOVB @YPT,R0 LOAD YPT MOV R0,R8 SLA R8,5 GET 3 LOW BITS AS LSB SRL R8,13 SRL R0,11 POSITION 5 HIGH BITS SLA R0,8 A R8,R0 MOV R7,R8 SAVE XPT ANDI R7,>3E00 POSITION XPT BITS SRL R7,6 A R0,R7 ADD X VALUE TO DISPLAY ADDRESS AI R7,>800 MOVB @R7LB,*R15 LOAD VDP ADDRESS SLA R8,8 SET CARRY TO LSB OF XPT MOVB R7,*R15 CI R11,RTN STORE OR RETRIEVE CB ? JNE GETRTN STORE MOVB @VDPRD(R15),R0 LOAD BYTE FROM VDP MOVB @CHRBUF,R8 LOAD CB H0F EQU $+2 ANDI R8,>0F00 MASK OUT LOW DIGIT JOC USTRCB JMP IF CB IS LOW DIGIT ANDI R0,>0F00 MASK OUT LOW DIGIT SLA R8,4 MOVE CB TO HIGH DIGIT JMP VSTRCB USTRCB ANDI R0,>F000 MASK OUT HIGH DIGIT VSTRCB ORI R7,WRVDP SET BIT TO WRITE TO VDP BL @SETVDP LOAD VDP ADDRESS A R8,R0 COMBINE DIGITS MOVB R0,@VDPWD(R15) STORE BYTE IN VDP B *R6 RETURN TO NEXT * PAGE ATA *=========================================================== ATA *** KEYBOARD SCAN ATA * ATA *** Initialization ATA * ATA EVEN ATA * ATA *** Fire button positions ATA * ATA FIRE EQU $-1 ATA BYTE 1 ATA BYTE 21 ATA LINE EQU $-1 ATA BYTE >0E,>0F ATA CRULOW BYTE 0,1,6 LOWER LIMIT FOR KBD 0,1,2 ATA CRUHI BYTE 13,5,10 UPPER LIMIT FOR KBD 0,1,2 ATA EVEN ATA D11 EQU $+1 CONSTANT >0B = 11 ATA KEYSCN LI R11,NEXT RETURN TO GPL INTERPRETER ATA KSCAN MOV R11,@RSAVE save return address ATA *** *** *** MOVB @PLAYER,R5 Is it console keyboard? ATA SRL R5,8 Right justify ATA MOV R5,R6 Make a copy of keyboard number ATA JEQ KSCAN2 Scan console keyboard ATA CI R6,3 No, is it 1 or 2? ATA JL JSCAN if so, scan joysticks first ATA CI R6,5 Illegal keyboard number? ATA *** *** *** *** *** *** JH NOKEY Yes, return no key ATA AI R6,-3 ATA MOVB R6,@PLAYER Reset keyboard number to zero ATA SWPB R6 Get low byte for flag ATA MOVB R6,@KBDFLG Store new keyboard flag ATA CLR R5 ATA *** *** JMP KSCAN2 ATA * ATA *** Scan Joystick ATA * ATA JSCAN LI R12,COLBAS CRU base for column/joystick selection ATA LDCR @LINE(R5),4 SELECT LINE TO SCAN ATA SRC R4,15 kill time to ensure setup ATA * (make sure we have 10 mic.sec. ATA * (for Milton Bradley expander) ATA LI R12,JOYBAS CRU base to read directions + fire ATA CLR R3 assume no fire ATA CLR R4 clean register for read ATA STCR R4,5 Read line ATA SRL R4,9 Get the fire button ATA JOC JSCAN1 No fire button ATA MOVB @FIRE(R5),R3 Get fire button ATA JSCAN1 SLA R4,1 Times 2 = index into table ATA *** *** **** MOVB @RBBJOY(R4),@JOYY read y value into joyy ATA 7/16 *** *** **** MOVB @RBBJOY+1(R4),@JOYX read x value into joyx ATA 7/16 MOV @RBBJOY(R4),@JOYY read y and x values ATA 7/16 MOVB R3,R3 Fire button down? ATA JNE DEBOU1 Yes ATA * ATA *** Scan Keyboard for a Key ATA * ATA KSCAN2 MOVB @CRULOW(R5),R1 starting column to scan ATA ROWLP LI R12,COLBAS CRU base for column selection ATA LDCR R1,4 Output row scan to KB ATA LI R12,ROWBAS Base for column input ATA STCR R4,4 input one column of data ATA INV R4 MAKE ONE'S REPRESENT KEYS DOWN ATA ANDI R4,>0F00 LEAVE ONLY SIGNIFICANT BITS ATA MOVB R1,R1 column 0? ATA JNE NOTONE ATA * must look at column 11 also, for other shift key ATA LI R12,COLBAS ATA LI R1,>B00 ATA LDCR R1,4 scan column for second shift ATA LI R12,ROWBAS ATA STCR R6,4 ATA INV R6 ATA ANDI R6,>100 save only shift key ATA SOCB R6,R4 and or it with column 0 shift ATA CLR R1 make it column 0 again ATA SLA R4,5 test alpha lock bit ATA JNC NOALPH ATA MOVB @ALPHLK,R6 debounce the alpha lock key ATA JLT NA1 still down...do nothing ATA XOR @H81,R6 indicate key is down, and toggle ATA MOVB R6,@ALPHLK ATA BL @KL10MS wait for physical debounce ATA JMP NA1 ATA NOALPH MOVB @ALPHLK,R6 was it down before? ATA SLA R6,1 ATA JNC NA1 yes, do nothing ATA BL @KL10MS ATA SZCB @H80,@ALPHLK indicate that alpha lock key is up ATA NA1 MOVB R4,R7 save other three qualifier keys ATA JMP NXTROW ATA NOTONE CB R1,@D11 Is this column 11? (second shift) ATA JNE NOT1 ATA ANDI R4,>0E00 ignore second shift key ATA NOT1 MOVB R4,R4 ATA JEQ NXTROW IF NO KEY DOWN, TRY NEXT LINE ATA * ATA *** GOT A KEY! DETERMINE WHICH ONE! ATA * ATA MOV R1,R3 which column ATA SRL R3,8 make a word ATA DEC R3 correct for fact column 0 is not in tablesATA SLA R3,2 multiply by 4 keys per column ATA SLA R4,4 get bits in position to test ATA DEC R3 ATA CNTLP INC R3 add in another row offset ATA SLA R4,1 SHIFT NEXT BIT OUT INTO CARRY ATA JNC CNTLP BIT = 1 IS KEY DEPRESSED ATA JMP DEBOUN and debounce it ATA * ATA *** SELECT NEXT LINE TO POLL ATA * ATA NXTROW AI R1,>100 select next column ATA CB R1,@CRUHI(R5) ATA JLE ROWLP Not finished- scan next row ATA * ATA *** No Keys Down ATA * ATA NOKEY CLR R6 Condition reset ATA MOVB R6,@OLDMOD Clear old modifiers ATA SETO R0 Invalid keycode is >FF ATA CB R0,@DBNCE(R5) Was key just released? ATA JEQ NOKEY2 No so no delay ATA BL @KL10MS Kill some time for debounce ATA NOKEY2 MOVB R0,@DBNCE Always clear KBD 0 debounce ATA MOVB R0,@DBNCE(R5) Always clear KBD being scanned ATA MOV R5,R5 Is this KBD 0 ? ATA JNE OLDCHR No so done ATA MOVB R0,@DBNC1 Clear KBD 1 debounce ATA MOVB R0,@DBNC2 Clear KBD 2 debounce ATA JMP OLDCHR ATA * ATA *** Debounce key ATA * ATA ***CLKSND DATA >8903,>939F 1975 HZ, ON THEN OFF ATA DEBOUN SWPB R3 GET POSITION IN MSB ATA DEBOU1 CLR R6 ASSUME IT IS OLD KEY ATA CB R3,@DBNCE(R5) Same key position? ATA JEQ MODIFY Yes, go get old key code ATA H020 EQU $+2 ATA LI R6,>2000 Set status to new ATA *** MOVB @CLICK,R0 ATA *** JEQ DEBOU2 ATA *** LI R2,CLKSND ATA *** MOVB *R2+,@>8400 frequency ATA *** MOVB *R2+,@>8400 ATA *** MOVB *R2+,@>8400 volume on ATA DEBOU2 BL @KL10MS ATA *** MOVB R0,R0 ATA *** JEQ DEBOU3 ATA *** MOVB *R2+,@>8400 volume off ATA DEBOU3 MOVB R3,@DBNCE Always debounce KBD 0 ATA MOVB R3,@DBNCE(R5) Debounce KBD being scanned ATA MOV R5,R5 Is this KBD 0 ? ATA JNE MODIFY No so done ATA * KBD 0 - MAY ALSO NEED TO DEBOUNCE A SPLIT KBD ATA CI R3,>1300 LEFT? ATA JH DB2 ATA MOVB R3,@DBNC1 DEBOUNCE LEFT ATA * DON'T SAVE R7 IF SPLIT KBD - IT IS NOT VALID JMP NEWMOD ATA DB2 CI R3,>2800 NEITHER? ATA JHE NEWMOD ATA MOVB R3,@DBNC2 DEBOUNCE RIGHT ATA NEWMOD MOVB R7,@OLDMOD ATA * ATA *** Got the key position. Now get the key code. ATA * ATA MODIFY MOVB @OLDMOD,R7 ATA SWPB R3 RETURN POSITION TO LSB ATA LI R1,RKSPLT Assume split keyboard ATA MOV R5,R5 Split keyboard? ATA JNE MAPIT Yes ATA SRL R7,12 3 modifier bits * 2 ATA MOV @RMDTAB(R7),R1 SELECT PROPER TABLE ATA MAPIT A R3,R1 Add table offset ATA MOVB *R1,R0 Get key code from table ATA CB R0,@HFF unassigned station? ATA 7/19 JEQ NOKEY if so, do not report it ATA 7/19 MOV R5,R5 Is it split keyboard? ATA JNE OLDCHR Yes, no special mapping ATA MOVB @KBDFLG,R3 Get keyboard flag ATA SRL R3,8 make it a word ATA BL @RNGCHK Is it a lowercase letter ATA DATA 'az' ATA JNE WHCHKB No so no alpha lock ATA MOV R3,R3 Is this keyboard 0 ? ATA JEQ ALOCK Yes so map to upper case ATA MOVB @ALPHLK,R1 ATA SRL R1,9 TEST THE LOCK STATUS ATA JNC WHCHKB No alpha lock ATA ALOCK SB @H020,R0 Map to upper case ATA WHCHKB MOV R3,R3 Is it keyboard 0 ? ATA JNE WHCH2 No, so no mapping ATA * THIS IS A CONVENIENT PLACE TO INITIALIZE ALPHA LOCK CONDITION ATA MOVB R14,@ALPHLK START WITH ALPHA LOCK SET ATA BL @RNGCHK Bad key? ATA DATA >101F ATA JEQ NOKEY Yes, return no key ATA CB R0,@H5F Is it higher than "_" ? ATA JH NOKEY Yes, return no key ATA WHCH2 DEC R3 Is this keyboard 4 ? ATA JNE OLDCHR No, it's 5. So return code. ATA CB R0,@H0D Is it RETURN key? ATA JEQ OLDCHR Yes so return it ATA CB R0,@H0F Is it GPL control key (1-15) ? ATA JH MAP4 No ATA SOCB @H80,R0 Yes so set sign bit ATA JMP OLDCHR Return it ATA MAP4 BL @RNGCHK Is it ASCII printable ? ATA H80 DATA >809F ATA JNE OLDCHR Yes, return it ATA SZCB @H80,R0 Control code, reset sign bit ATA OLDCHR MOVB R0,@KEYBRD Output ASCII character ATA MOVB R6,@STATUS Store status ATA JEQ EXSCN No new key ATA MOVB @SAVVDP,*R15 Turn on the screen ATA CLR @TIMOUT Reset screen timer ATA MOVB @H81,*R15 VDP register 1 ATA EXSCN MOV @RSAVE,R11 Restore return address ATA RT ATA * *** Range check routine * RNGCHK MOV *R11+,R12 Fetch range CB R0,R12 Compare to low end of range JL RNGRT Out of range low SWPB R12 CB R0,R12 Compare to high end of range JH RNGRT Out of range high CB R0,R0 In range so set EQ bit RNGRT RT Return to caller * *** Kill time routine * KL10MS MOV @DELAY2,R12 Load up 10 m-secs of counts ATA KILTIM DEC R12 Count it down JGT KILTIM Not done yet ATA RT Return to caller PAGE *----------------------------------------------------------* * FORMAT FOR STRING FORMAT CLR R9 RESET BLOCK COUNT TO 0 CLR R3 ZERO BIAS BYTE BL @GETDA ENCODE VDP ADDRESS FUNCTN MOVB *R13,R8 GET NEXT BYTE FROM GAME ROM LI R12,STKADD MOV R8,R5 SAVE DATA BYTE SLA R8,3 SHIFT TO FIND FUNCTION TO PERFORM SRL R8,11 MOVE TO LOW ORDER POSITION INV R8 LEAVE N IN RANGE OF MINUS 1 - 32 SRL R5,12 ISOLATE FUNCTION BITS MOV @FBTAB(R5),R5 GET BRANCH ADDRESS LI R2,LOOP SETO R4 SET I TO -1 B *R5 * REPEAT CHARACTER N TIMES DOWN THE SCREEN *** RPTDWN SLA R4,5 SET I TO -32 * REPEAT CHARACTER N TIMES ACROSS THE SCREEN *** RPTACR C *R2+,*R2+ LOAD BRANCH ADDRESS FOR LOOPING JMP LOOP * STORE N CHARACTERS DOWN THE SCREEN *** STRDWN SLA R4,5 SET I TO -32 * STORE N CHARACTERS ACROSS THE SCREEN STRACR * LOOP TO STORE CHARACTERS LOOP MOVB *R13,R6 GET NEXT BYTE FROM GAME ROM LOOPB A R3,R6 ADD BIAS TO CHARACTER LOOPA MOVB R6,@VDPWD(R15) MOVE BYTE INTO DISPLAY S R4,R7 DISPLACEMENT TO NEXT CHARACTER CI R7,>320 DO I WANT WRAPAROUND? JHE ZEND NO UPXY CI R7,>300 DISPLAY ADDRESS OUT OF RANGE? JL ZEND NO AI R7,->300 SUBTRACT LENGTH OF DISPLAY ZEND BL @RESTOR BL @GETDA INC R8 INCREMENT LOOP COUNTER JEQ FUNCTN DONE WITH LOOP IF N = 0 B *R2 LOOP UNTIL N = 0 * SKIP N LINES DOWN THE SCREEN *** SKPDWN SLA R8,5 MULTIPLY LINES TO SKIP BY 32 * SKIP N SPACES ACROSS THE SCREEN *** SKPACR S R8,R7 MOVE NUMBER OF SPACES TO SKIP INTO I SETO R8 SET LOOP COUNTER TO -1 JMP UPXY GO PERFORM SKIP * REPEAT BLOCK N TIMES *** RPTBLK INC R9 INCREMENT BLOCK COUNTER INCT *R12 INCREMENT STACK POINTER MOVB *R12,R6 GET DATA STACK POINTER SRL R6,8 MOVE TO LOW ORDER BYTE SWPB R8 MOVB R8,@PAD(R6) PUSH N ONTO DATA STACK JMP FUNCTN * REPETITION OF BLOCK HAS BEEN COMPLETED FINISH DECT *R12 DECREMENT DATA STACK POINTER R14=01XX DEC R9 DECREMENT BLOCK COUNT JMP FUNCTN * END BLOCK FUNCTION ENDBLK MOV R9,R9 IS BLOCK COUNT ZERO ? JEQ ENDFMT YES - END OF FORMAT INSTRUCTION MOVB *R13,R4 LOAD LOOP ADDRESS MOVB *R12,R6 GET DATA STACK POINTER MOVB *R13,R5 SRL R6,8 AB R14,@PAD(R6) DECREMENT REPITITION COUNT R14=01XX JEQ FINISH DONE WITH BLOCK IF COUNT IS ZERO MOVB R4,@GRMWA(R13) LOAD GROM WITH LOOP ADDRESS MOVB R5,@GRMWA(R13) JMP FUNCTN * * SPECIAL FORMAT FUNCTIONS HE4 EQU $+3 SPECL CI R8,-28 WHICH FUNCTION ? JEQ ENDBLK END BLOCK JGT VARBLE VARIABLE CHARACTERS MOV R13,R1 CI R8,-30 WHICH FUNCTION ? JEQ BIASV SET COLOR BIAS JGT BIASI SET COLOR BIAS IMMEDIATE BL @RESTOR SET XPT OR YPT NEG R8 H5F EQU $+3 MOVB *R13,@PAD+>5F(R8) LOAD VALUE OF XPT OR YPT BL @GETDA COMPUTE VALUE OF ADDRESS JMP FUNCTN * SET COLOR BIAS BIASV BL @GETMAB GET MEMORY ADDRESS BIASI MOVB *R1,R3 LOAD COLOR BIAS JMP FUNCTN * VARIABLE CHARACTERS VARBLE BL @GETMAB GET MEMORY ADDRESS LI R2,LOOPV SET LOOP REGISTER LOOPV MOVB *R1+,R6 LOAD VARIABLE CHARACTER JMP LOOPB PAGE *----------------------------------------------------------* * CLEAR SCREEN ALL MOVB *R13,R5 GET CHARACTER TO STORE BL @SETV LI R7,768 NUMBER OF BYTES TO TRANSFER ALLOOP MOVB R5,@VDPWD(R15) STORE BYTE IN DISPLAY DEC R7 JNE ALLOOP * RESTORE XPT AND YPT FROM DISPLAY ADDRESS ENDFMT LI R11,NEXT END OF FORMAT *** RESTOR SLA R7,3 SHIFT YPT VALUE TO TOP BYTE MOVB R7,@YPT STORE VALUE OF YPT SLA R7,8 SHIFT OFF VALUE OF YPT SRL R7,3 LEAVE VALUE OF XPT MOVB R7,@XPT STORE VALUE OF XPT RT PAGE * REMOTE LIMI 0 LWPI GPLWS USE REGULAR REGISTERS ATA CLR R12 LOAD CRU ADDRESS COC @H20,R14 IS TIMER FLAG ON? JNE TIM1 NO, SEE WHAT IS INTERRUPTING ME B @TIMER HANDLE TIMER INTERRUPT *** TIM1 TB 2 VDP INTERRUPT?? JNE VDPINT YES * * PERIPHERAL ROM INTERRUPT ROUTINES MAY CHANGE ALL * REGISTERS EXCEPT R0,R11-R15. * R11 HAS THE RETRUN ADDRESS FOR THE INTERRUPT ROUTINE * R12 IS LOADED FOR THE CRU SPACE OF THE PERIPHERAL * R13 HAS THE CURRENT GROM SLOT ADDRESS * R14 HAS A >01XX WHERE THE XX IS USED BY THE INTERPRETER * R15 HAS THE ADDRESS OF THE VDP WRITE ADDRESS ADDRESS * INTERRUPT ROUTINE SHOULD DO A RETURN WHEN DONE * MOVB @MAPPER,R0 CLEAR PROTECTION VIOLATION JF 9/17 LI R12,>0F00 TABLE OF CRU BITS TO SELECT ROM JF 9/16 SBO 1 TURN OFF EXTERNAL INTERRUPT ATA ILOOP SBZ 0 TURN OFF LAST ROM AI R12,>0100 NEXT ROM CI R12,>3000 FINISHED? ATA JEQ EMERG2 END OF ROM CRU BITS SBO 0 LOAD CRU BITS TO SELECT ROM CB @H4000,@HAA VALID ROM? JNE ILOOP NO MOV @H400C,R2 GET INTERRUPT ROUTINE ADDRESS LOOP1 JEQ ILOOP NO ROUTINE, GO TO NEXT ROM MOV R2,R0 SAVE POINTER TO NEXT ROUTINE MOV @2(R2),R2 GET ENTRY ADDRESS BL *R2 JUMP TO INTERRUPT ROUTINE MOV *R0,R2 NEXT ROUTINE'S ADDRESS JMP LOOP1 GO TO NEXT ROUTINE EMERG2 B @EMERGE *==========================================================* * V D P I N T E R R U P T H A N D L E R * VDPINT SBO 2 RESET VDP INTERRUPT ON 9901 MOVB @INTFLG,R1 SLA R1,1 JNC TSTMOT B @VSTAT *** *** *==========================================================* * AUTOMATIC SPRITE MOTION (INTERRUPT ROUTINE) ATA TSTMOT SLA R1,1 ATA JOC TSTSND ATA MOVB @MOTION,R12 ATA JEQ TSTSND ATA SRL R12,8 ATA LI R2,VDPRD+VDPWA ATA LI R3,VDPWD+VDPWA ATA MOV @SVL,R8 ATA MOV R8,R11 R11=OFFSET FROM SAL TO SVL ATA S @SAL,R11 ATA MLOOP MOVB @R8LB,*R15 LOAD ADDRESS TO READ SML ATA MOVB R8,*R15 ATA CLR R4 ATA MOVB *R2,R4 READ DELTA Y ATA CLR R6 ATA MOVB *R2,R6 READ DELTA X ATA SRA R4,4 MOVE RIGHT ONE DIGIT ATA MOVB *R2,R5 READ TEMP Y ATA SRA R5,4 MOVE RIGHT ONE DIGIT ATA A R4,R5 ATA MOVB *R2,R7 ATA SRA R6,4 MOVE RIGHT ONE DIGIT ATA SRA R7,4 MOVE RIGHT ONE DIGIT ATA A R6,R7 ATA S R11,R8 CHANGE ADDRESS TO SAL ATA MOVB @R8LB,*R15 LOAD ADDRESS TO READ SAL ATA MOVB R8,*R15 ATA CLR R4 ATA MOVB *R2,R4 READ Y POSITION ATA A R5,R4 ADD Y MOVEMENT TO POSITION ATA ********************************************************** ATA *** To fix the sprite flicker problem, ATA *** add following code back (it has been taken out ATA *** of the /4A shipped 03/16/81) 07/29/81. ATA CI R4,6*VDELTA+255 ATA JLE ONSCRN ATA CI R4,7*VDELTA ATA JH ONSCRN ATA MOV R5,R5 ATA JGT $+6 ATA AI R4,6*VDELTA ATA AI R4,VDELTA ATA ************************************************************ ATA ONSCRN CLR R6 ATA MOVB *R2,R6 ATA A R7,R6 ATA ORI R8,WRVDP ATA MOVB @R8LB,*R15 LOAD ADDRESS TO WRITE SAL ATA MOVB R8,*R15 ATA MOVB R4,*R3 ATA A R11,R8 BACK TO SVL FOR FRACTIONS ATA INCT R8 ATA MOVB R6,*R3 ATA SWPB R5 ATA MOVB @R8LB,*R15 LOAD ADDRESS TO WRITE SML ATA MOVB R8,*R15 ATA SRL R5,4 ATA MOVB R5,*R3 ATA SWPB R7 ATA SRL R7,4 ATA MOVB R7,*R3 ATA AI R8,2-WRVDP ATA DEC R12 ATA JGT MLOOP ATA *==========================================================* * AUTO-SOUND FEATURE (INTERRUPT ROUTINE) TSTSND SLA R1,1 JOC TSTQT MOVB @STFLGS,R2 JEQ TSTQT SB R14,@STFLGS R14=01XX JNE TSTQT MOV @SNDADD,R3 MOV R14,R5 SRL R5,1 JOC SNDRAM BL @PUTSTK LI R5,GRMWA A R13,R5 MOVB R3,*R5 MOVB @R3LB,*R5 MOV R13,R6 JMP USND SNDRAM LI R5,VDPWA MOVB @R3LB,*R5 MOVB R3,*R5 LI R6,VDPRD+VDPWA USND MOVB *R6,R8 JEQ NEWADD CB @HFF,R8 DO I SWITCH SOURCE TYPE ? JEQ NEW1 YES SRL R8,8 A R8,R3 SLOOP MOVB *R6,@SGCADR SEND BYTE TO SOUND CHIP DEC R8 JNE SLOOP LOOP UNTIL COUNT IS ZERO INCT R3 MOVB *R6,R2 JEQ XSOUND JMP SNDXIT NEW1 XOR @C1,R14 CHANGE VDP TO GROM OR GROM TO VDP NEWADD MOVB *R6,R3 GET HIGH BYTE OF NEW ADDRESS LI R2,>100 MOVB *R6,@R3LB GET LOW BYTE OF NEW ADDRESS JMP SNDXIT XSOUND SB R2,R2 TURN OFF SOUND PROCESSING SNDXIT MOV R3,@SNDADD MOVB R2,@STFLGS CI R5,VDPWA JEQ TSTQT BL @GETSTK *==========================================================* TSTQT SLA R1,1 JOC VSTAT LI R12,COLBAS LOAD CONSOLE ADDRESS IN CRU BASE LDCR @H00,4 LOAD FOR COLUMN 0 SRC R12,7 KILL TIME LI R12,ROWBAS CRU ADDRESS FOR CHARACTER LINES STCR R5,4 RECALL COLUMN INFORMATION SWPB R5 GET READY TO READ RIGHT-HAND COLUMN LI R12,COLBAS LDCR @H0B,4 LOAD FOR "=" COLUMN ATA LI R12,ROWBAS STCR R5,4 READ COLUMN 13 C @FNCEQ,R5 IS IT A "FNCT'N BACKSLASH" ? JNE VSTAT BUGOUT LI R12,>2702 try a hardware reset ATA 7/16 SBO 0 ATA 7/16 * but just in case, do a soft reset ATA 7/16 BLWP @0 RESET VECTOR TRAP LOCATION *==========================================================* VSTAT MOVB @VDPSTA(R15),@VDPST LOAD VDP STATUS IN STATUS BLOCK LWPI INTWSP USE INTERRUPT WORK SPACE INCT R11 INCREMENT SCREEN TIMER JNE TIMIN1 NO TIMEOUT TIMIN MOVB R10,R12 SRL R12,8 H81 EQU $+2 ORI R12,>8160 TURN OFF VDP HFF EQU $+2 ANDI R12,>FFBF MOVB @AR12LB,@VDPWA MOVB R12,@VDPWA TIMIN1 LWPI GPLWS ATA AB R14,@TIME INCREMENT TIME IN STATUS BLOCK MOV @DELAY1,R1 DELAY COUNTER TO MATCH 4A SPEED JEQ USERI LOOP4A DEC R1 JNE LOOP4A USERI MOV @INTPTR,R12 USER INTERRUPT ROUTINE? JEQ EMERGE BL *R12 EMERGE CLR R8 CLEAR REGISTER FOR BASIC LWPI INTWSP RETURN TO CALLING ROUTINE NULLRT RTWP FROM ALTERNATE WORKSPACE PAGE * * LINK TO ROUTINE IN ROM * * ENTER WITH PAB POINTER IN >8356, (SCNAM,WORD) * AND ROUTINE TYPE IN >836D (TYPE,BYTE) * LNKVRM: PAB AND BUFFER ARE IN VDP RAM * LNKCRM: PAB AND BUFFER ARE IN CPU RAM * FALLS THROUGH INTO SROM IF NAME IS BETWEEN 1 AND 10 CHARACTERS * (WHICH RETURNS FROM A GPL CALL IS A MATCH IS FOUND) * OTHERWISE RETURNS WITH CONDITION BIT SET * LNKR9 B @SET * actual entry point ***** ***LRVM MOVB *R4,R1 ATA 7/16 ***LRCM MOVB *R4+,R1 ATA 7/16 LNKVRM MOVB @SCNAM+1,*R15 Fetch pointer into PAB MOVB @SCNAM,*R15 MOVB @VDPRD(R15),R3 fetch the name length byte *** MOV @LRVM,R0 ATA 7/16 LI R0,>D054 (MOVB *R4,R1) ATA 7/16 *** MOV R15,R4 ATA 7/16 *** AI R4,VDPRD ATA 7/16 LI R4,VDPRD+VDPWA ATA 7/16 CLR @SCLEN-1 JMP LNKR0 LNKCRM MOV @SCNAM,R4 MOVB *R4+,R3 *** MOV @LRCM,R0 ATA 7/16 LI R0,>D074 (MOVB *R4+,R1) ATA 7/16 MOV @H8000,@SCLEN-1 LNKR0 SRL R3,8 Make length a word value JEQ LNKR9 if length=0, done LI R2,FAC buffer for name CLR R1 LNKR1 X R0 Fetch a byte of name CI R1,'.'*256 Is is a period? JEQ LNKR2 if so, stop accumulating name CI R2,FAC+9 is the name too long? JH LNKR9 if > 10 bytes MOVB R1,*R2+ Put it in the buffer DEC R3 Finished with name? JGT LNKR1 if not LNKR2 AI R2,-FAC R2 contains length up to period SOC R2,@SCLEN-1 Save the length, but save memory type bit INC R2 A R2,@SCNAM And update the name pointer CLR @CRULST indicate beginning of search * fall through into SROM * * SEARCH ROM CROM GROM FOR DSR OR LINK * SROM CLR R1 VERSION FOUND OF DSR ETC MOV @CRULST,R12 SEARCH ROM FOR ROUTINE JNE SGO IF <> 0 THEN CONTINUE SEARCH LI R12,>0F00 START OVER AGAIN NOROM MOV R12,R12 ANYTHING TO TURN OFF? JEQ NOOFF NO SBZ 0 YES, TURN IT OFF ***NOOFF AI R12,>0100 NEXT ROM'S TURN ON ATA 7/19 NOOFF AB R14,R12 NEXT ROM'S TURN ON ATA 7/19 CLR @CRULST CLEAR JUST IN CASE WE'RE FINISHED *<><><><><><><><><><><><><><><><><> ATA * CRU SPACE EXTENDED FOR 99/8 (9995) ATA *<><><><><><><><><><><><><><><><><> ATA CI R12,>3000 AT THE END ATA JEQ NOSET NO MORE ROMS TO TURN ON MOV R12,@CRULST SAVE ADDRESS OF NEXT CRU SBO 0 TURN ON ROM LI R2,>4000 START AT BEGINNING SGO1 CB *R2,@HAA IS IT A VALID ROM? JNE NOROM NO SGO1A AB @TYPE,@R2LB GO TO FIRST POINTER JMP SGO2 SGO MOV @SADDR,R2 CONTINUE WHERE WE LEFT OFF SBO 0 TURN ROM BACK ON SGO2 MOV *R2,R2 IS ADDRESS A ZERO JEQ NOROM YES, NO PROGRAM TO LOOK AT MOV R2,@SADDR REMEMBER WHERE WE GO NEXT INCT R2 GO TO ENTRY POINT MOV *R2+,R9 GET ENTRY ADDRESS BL @NAME SEE IF NAME MATCHES JMP SGO NO MATCH, TRY NEXT PROGRAM INC R1 NEXT VERSION FOUND BL *R9 MATCH, CALL SUBROUTINE JMP SGO NOT RIGHT VERSION *** SBZ 0 TURN OFF ROM JMP NOGR2 SET STATUS AND GO TO GPL NOGR1 CLR *R8 NO MORE TO DO NOGR2 BL @GETSTK RESTORE GROM ADDRESS NOSET B @RESET INDICATE NO MORE *==========================================================* * spgrom is an xml3 ATA SPGROM LI R0,>F500 P-SYSTEM VALIDATION FLAG ATA JMP SGROM0 SHARE CODE ATA SGROM LI R0,>AA00 GPL VALIDATION FLAG ATA SGROM0 LI R7,SADDR ATA LI R8,CRULST BL @PUTSTK SAVE GROM ADDRESS SGROMA MOV *R7,R1 START WHERE WE LEFT OFF MOV *R8,R2 IS IT A RESTART? JNE SGROM3 NO LI R2,GRMRD START OF GROMS SGROM1 LI R1,>E000 START OF GROM SGROM3 CZC @H1FFF,R1 IS IT A NEW GROM OR A CONTINUATION JNE SGROM2 MOV R2,*R8 SAVE GROM BASE ADDRESS MOVB R1,@GRMWA(R2) LOAD ADDRESS MOVB @R1LB,@GRMWA(R2) AB @TYPE,@R1LB LOOK FOR PROGRAM ADDRESS MOVB R1,@SAVEG SAVE GROM ADDRESS OF HEADER CB *R2,R0 VALID GROM? ATA JNE NOGR NO GROM HERE *** SGROM2 MOVB R1,@GRMWA(R2) LOOK FOR PROGRAM MOVB @R1LB,@GRMWA(R2) *** MOVB *R2,R3 READ PROGRAM ADDRESS *** MOVB *R2,@R3LB MOV R3,*R7 GET NEXT HEADER'S ADDRESS JEQ NOGR IF ZERO, GO TO NEXT GROM INCT R3 GO TO PROGRAM ENTRY ADDRESS MOVB R3,@GRMWA(R2) GO TO PROGRAM ENTRY ADDRESS MOVB @R3LB,@GRMWA(R2) *** MOVB *R2,R9 ENTRY ADDRESS *** MOVB *R2,@R9LB BL @NAME SEE IF NAME MATCHES JMP SGROMA NO LOOK FOR NEXT PROGRAM AB @H2,@STKDAT FOUSP NAME SO PUSH IT AB R14,@TEMP2 INCREASE PROGRAM COUNT MOVB @STKDAT,R4 SRL R4,8 DECT R3 POINT BACK TO START OF HEADER CB @TYPE,@H06 IS IT A USER PROGRAM LOOKUP? JNE SGROM4 YES MOV R3,R9 PUSH HEADER ADDRESS FOR USER PROGRAMS SGROM4 MOVB R9,@PAD(R4) NO, PUSH ENTRY ADDRESS MOVB @R9LB,@PAD+1(R4) ***** MOV R2,R13 GO TO THAT LIBRARY ATA SGSET BL @GETSTK RESTORE GROM ADDRESS B @SET SET STATUS AND RETURN NOGR CLR R1 GET ADDRESS OF GROM HEADER MOVB @SAVEG,R1 AI R1,->2000 NEXT GROM DOWN MOV R1,*R7 SAVE ADDRESS OF WHERE WE'RE AT CI R1,>E000 FINISHED? JNE SGROM3 NO, CHECK THIS GROM *<><><><><><><><><><><><><><><><><><><><><><><><><><><> ATA * GROM LIBRARY SUPPORT REMOVED FROM 99/8 ATA *<><><><><><><><><><><><><><><><><><><><><><><><><><><> ATA *** C *R2+,*R2+ INCREMENT GROM MAPPED ADDRESS BY FOUR ATA *** MOV R2,*R8 SAVE THE NEW MAP ADDRESS ATA *** CI R2,GRMRD+>40 AT END OF LIBRARY? ATA *** JEQ NOGR1 YES ATA JMP NOGR1 FINISHED ATA *** MOVB @SCLEN,R5 ARE WE LOOKING FOR A MENU? ATA *** JNE SGROM1 YES SO DO ONLY ONE SLOT ATA *** JMP NOGR2 NO CONTINUE SEARCH ATA * *** TRY TO MATCH NAME FOR SROM,SGROM * NAME MOVB @SCLEN,R5 GET LENGTH AS COUNTER JEQ NAME2A ZERO LENGTH, DON'T DO MATCH CB R5,*R2 DOES LENGTH MATCH? JNE NAME3 NO SRL R5,8 MOVE TO RIGHT PLACE LI R6,FAC NAME1 CI R2,GRMRD IS IT GROM? JHE NAME2 YES, DON'T INCREMENT ADDRESS INC R2 NAME2 CB *R6+,*R2 IS NAME THE SAME? JNE NAME3 NO H06 DEC R5 MORE TO LOOK AT ? JNE NAME1 YES NAME2A INCT R11 RETURN , NAME FOUND NAME3 RT RETURN * * RANDOM NUMBER GENERATOR, FOR RAND INSTRUCTION IN GPL * AND RND FUNCTION IN BASICS RND LI R4,28645 MPY @RAND16,R4 AI R5,31417 MOV R5,@RAND16 *** *** INC R6 CLR R4 CLEAR UPPER HALF OF DIVIDEND SWPB R5 DIV R6,R4 PERFORM DIVISION MOVB @R5LB,@RANDOM STORE REMAINDER RT * ** INTERFACE TO DEBUGGER * OPBR EQU >4020 ADDRESS TO HANDLE OPERR IN DSR OPERR BL @SETUP B @OPBR BPBR EQU >401C ADDRESS TO HANDLE BP IN DSR BP BL @SETUP B @BPBR PRCXOP LWPI DSRWSP BL @SETUP B @ALBRK SETUP LI R12,>1B00 SET UP CRU SBO 0 RT * *** GPLLNK - ROUTINE TO CALL GPL FROM 9900 CODE *** CALLER SHOULD SET UP GPL ADDRESS IN GLINK1 (>84A6) ATA *** >84A4 IS USED. ATA *** CALL SEQUENCE IS BL @GPLLNK FROM GPLWS * GPLLK0 MOV R11,@GLINK0 RETURN TO CALLER IS VIA XML >A0 FROM GPL ATA LI R6,>42+MONIT GPL ADDRESS OF LINK ROUTINE ATA B @LDKADD START EXECUTING GPL * 0 1 2 3 ATA 7/19 MAPDAT DATA >FF00,>FF00,>0008,>0018 ATA 7/19 * 4 5 6 7 ATA 7/19 DATA >FF40,>FF50,>FF60,>FF70 ATA 7/19 * 8 9 A B ATA 7/19 DATA >FF00,>FF00,>0028,>0038 ATA 7/19 * C D E F ATA 7/19 DATA >0048,>0058,>0068,>0078 ATA 7/19 *==========================================================* * XML TABLE 7 MUST BE IN ROM 0 BECAUSE OF SPGROM!!! JF 9/17 * >70 >71 >72 JF 9/17 XTAB9 DATA ASMCON,FILE99,SPGROM JF 9/17 *==========================================================* JF 9/17 * JF 9/17 *** CAUTION !!!!! BE CAREFUL OF CODE OVERRUN RORG >C36 (COMPATABILITY WITH 99/4 AND 4A) * BRANCH TABLES ITAB DATA MISCLN,MOVDAT,BRESET,BSET >0024 *** *** *** MSCTAB DATA RETURN,RETNC,RANDNO,KEYSCN,BKGRND,BLONG,CALL,ALL *** *** DATA FORMAT,TSTST,TSTST,BUGOUT,TSTST,TSTST,PARSEG,XML ATA 7/16 * DATA CONTG,EXECG,RTNG,RGBA,OPERR,OPERR,OPERR,OPERR **** XML2 ADDED ATA 4/9/82 -- MORE XML TABLES FOR ARMADILLO DATA CONTG,EXECG,RTNG,RGBA,XML2,XML3,RTNSET,OPERR *** *** DATA OPERR,OPERR,OPERR,OPERR,OPERR,OPERR,OPERR,BP *** *** ATAB EQU $->80 DATA ABS,NEG,INV,CLR,FETCH,CASE,PUSH,IFZ *** *** DATA INC,DEC,INCT,DECT,OPERR,OPERR,OPERR,OPERR *** *** *** *** BTAB EQU $->50 DATA ADD,MINUS,MUL,DIV,AND,OR,XOR,STORE *** *** DATA EXCH,HIGH,HIGHEQ,GREATR,GREQ,EQUAL,IFAND *** *** DATA SRA,SLL,SRL,SRC,COINC,OPERR,INOUT,DGBA,OPERR *** *** MSRC DATA CPUSRC,GRMSRC,VDPSRC *** MDST DATA CPUDST,GRMDST,VDPDST,REGDST *** FBTAB DATA STRACR,STRDWN,RPTACR,RPTDWN DATA SKPACR,SKPDWN,RPTBLK,SPECL *** IOTAB DATA SOUND,SOUND,CRUIN,CRUOUT DATA WRITE,READ,VERIFY *** XMLTAB DATA FLTTAB,XTAB,>2000,>3FC0 DATA >3FE0,>4010,>4030,>6010 DATA >6030,>7000,GLINK0,>A000 ATA HC000 EQU $+2 DATA >B000,>C000,>D000,PAD XMLTB2 DATA XTAB2,XTAB3,XTAB4,XTAB5 DATA XTAB6,XTAB7,XTAB8,XTAB9 PAGE *************************************************** * POWER-UP AND RESTART INITIALIZATION * *************************************************** ENTRY EQU $ CLR R12 SBO >14 MMD AT >8000, ROM ENABLED P4 | SBO >15 NO P-CODE GROMS P5 MOVB @>2000,R0 dummy read to initialize state of mapper ATA * NOW INITIALIZE MEMORY MAPPER ATA LI R1,MF0 ATA LI R2,MAPDAT ATA LI R3,16 ATA CLR R4 ATA ENTR0 MOVB R4,*R1+ ATA MOVB *R2+,*R1+ ATA MOVB *R2+,*R1+ ATA MOVB R4,*R1+ ATA DEC R3 ATA JNE ENTR0 ATA MOVB @LMAP0,@MAPPER ATA H0D EQU $+1 ENTR1 LI R13,GRMRD GPL REGISTERS MOV R13,R2 SYNCHRONIZE ALL GROM LIBRARIES ATA ENTR2 MOVB *R2,R0 ATA AI R2,4 ATA CI R2,GRMRD+>40 ATA JNE ENTR2 ATA LMAP0 EQU $+2 COMMAND CODE TO LAD MAP FROM FILE 0 >01 | RMAP0 EQU $+3 | LI R14,>0100 | LI R15,VDPWA CLR @DELAY1 FULL SPEED LI R0,1500 ATA MOV R0,@DELAY2 KEYBOARD DEBOUNCE ATA **** CLR @CLICK assume no click ATA XOP 4,5 FIND TOP OF MEMORY H2 EQU $ IMMOPS EQU $ H20 EQU $+2 LI R0,>20+MONIT FIRST BYTE IN GROM CLR @INTPTR CLEAR USER INTERRUPT POINTER GFH 8/11 JMP DGBADD *----------------------------------------------------------* * *** BEGIN EXECUTION OF GPL INSTRUCTIONS *** * LIBRARY CALL ROUTINE DGBA BL @PUTSTK SAVE RETURN ADDRESS BL @PUTSTK INCREMENT STACK POINTER MOV R13,@PAD(R4) SAVE GROM BASE ADDRESS MOV R2,R13 NEW GROM BASE ADDRESS DGBADD MOVB *R13,R4 SYNCHRONIZE YOUR GROMS ATA MOV R0,R6 BRANCH TO ADDRESS IN GROMS ATA B @LDKADD PAGE *==========================================================* * EXECUTE 9900 CODE IN EXTERNAL ROM XML LI R2,XMLTAB XML0 BL @XMLCOM BL *R4 QEXIT2 B @NEXT * SECOND XML INSTRUCTION ADDED FOR ARMADILLO FOR MORE TABLES * ESPECIALLY FOR ROM AT >FF8000. MAP IT TO >2000 XML2 BL @X2COM ATA BL @XMLCOM ATA BL *R4 ATA BL @X2END ATA 7/16 JMP QEXIT2 X2END ATA 7/16 LI R12,>2700 ATA 7/16 SBZ 0 ATA 7/16 MOVB @LMAP0,@MAPPER ATA 7/16 RT ATA 7/16 * THIRD XML INSTRUCTION TO ACCESS ROUTINES AT >2000 * WITHOUT REMAPPING MEMORY XML3 LI R2,XMLTB2 JMP XML0 XMLCOM MOVB *R13,R9 FETCH SELECTOR BYTE FROM GROM XMLCM1 MOV R9,R4 ATA SRL R9,11 R9=LIST SELECTOR * 2 (LSB DOESN'T COUNT) *** SLA R4,4 SRL R4,11 R4= SELECTOR WITHIN LIST (LSB DOESN'T COUNT) A R2,R9 PLUS TABLE OFFSET A *R9,R4 GET TABLE POINTER IN R4 MOV *R4,R4 NOW ACTUAL CODE POINTER RT * *** XOP ENTRY POINT FOR CALLING CERTAIN XML ROUTINES *** FROM ASSEMBLY LANGUAGE *** WORKSPACE IS SCRWS * XXML MOVB *R13,R1 FIRST DATA BYTE = WHICH XML (R0) ATA SRL R1,7 ATA MOV @XXTAB(R1),R1 ATA B *R1 ATA XXTAB EQU $-2 ATA DATA XXML1,XXML2,XXML3 ATA XXML1 LI R2,XMLTAB STANDARD XML ATA XXML10 BL @XXCOM GET POINTER ATA MOV R4,@GPLWS+8 ALL ASSUME GPLWS ATA LWPI GPLWS ATA BL *R4 DO ROUTINE ATA XXML11 LWPI SCRWS NOW RETURN ATA RTWP ATA XXML3 LI R2,XMLTB2 SECONDARY TABLES ATA JMP XXML10 (ASSUME ALREADY MAPPED IN) ATA XXML2 BL @X2COM MAP IN ROMS ATA BL @XXCOM GET ADDRESS ATA MOV R4,@GPLWS+8 ALL ASSUME GPLWS ATA LWPI GPLWS ATA BL *R4 DO ROUTINE ATA BL @X2END ATA 7/16 JMP XXML11 AND RETURN ATA XXCOM MOVB @1(R13),R9 FETCH ROUTINE SELECTOR (R0LB) ATA JMP XMLCM1 (RETURNS) ATA X2COM LI R2,XMLTB2 ATA LI R3,ROMFF8 ATA LI R5,MAPPER ATA 7/16 MOVB @RMAP0,*R5 ATA 7/16 MOVB @RMAP1,*R5 ATA 7/16 LI R1,>8048 >2000 WINDOW IM MAP 1 ATA LI R4,12 12 WORDS FOR >2000 TO >7FFF ATA XML2C MOV *R3+,*R1+ ATA DEC R4 ATA JNE XML2C ATA MOVB @LMAP1,*R5 ATA 7/16 LI R12,>2700 ATA SBO 0 ATA RT ATA ************************************************************ * 4/14/78 * REVISED FROM COINC5 FOR GB REV E 8/09/78 * COINCIDENCE ROUTINE FOR INSERTION INTO REL4 INTERPRETER. * UPON ENTRANCE TO THIS ROUTINE AT LABEL 'COINC' THE * REGISTERS ARE ASSUMED TO BE SET UP: *MSBY R2 = Y2 IN MSBY AND X2 IN LSBY; *MSBY R0 = Y1 IN MSBY AND X1 IN LSBY; * * IT IS ALSO ASSUMED THAT THE GROM'S INTERNAL ADDRESS IS SET * UP PREPARED TO READ (FOLLOWING THE COINC INSTRUCTION ): * - A ONE BYTE GRANULARITY VALUE, FOLLOWED BY: * - A TWO BYTE ADDRESS POINTING TO THE COINCIDENCE * TABLE. THE TABLE IS ASSUMED TO RESIDE IN GROM, * AND HAVE THE FOLLOWING FORMAT: * * BYTE 0- TV = VERTICAL BIT SIZE OF TABLE LESS 1; * BYTE 1- TH = HORIZ. BIT SIZE OF TABLE LESS 1; * BYTE 2- V1 = VERTICAL DOT SIZE OF OBJECT 1/2**GRAN * BYTE 3- H1 = HORIZ. DOT SIZE OF OBJECT 1/2**GRAN * BYTES 4 ON - THE BIT TABLE ITSELF; THE BITS ARE * ARRANGED SUCH THAT THE FIRST (TH+1) BITS * REPRESENT BOOLEAN COINCIDENCE VALUES * CORRESPONDING TO A DELTA Y (Y1-Y2) OF * -V1 THRU -V1+TV AND DELTA X (X1-X2) VALUES OF * -H1 THROUGH -H1+TH. * COINC MOV R0,R8 MOV R8,R3 FIRST GET DELTA Y AND DELTA X: SB R2,R3 R3 = Y1-Y2 = DELTA Y. SWPB R8 GET X1 IN MSBY. SWPB R2 GET X2 IN MSBY. SB R2,R8 R8 X1-X2 = DELTA X. MOVB *R13,R0 SET RESOLUTION AND TABLE POINTER SRL R0,8 R0 = GRAN. MOVB *R13,R5 MOVB *R13,@R5LB ATA BL @PUTSTK SAVE GROM PC. * * NOW GET TV,TH,V1,H1 OUT OF THE FIRST 4 BYTES OF TABLE. * MOVB R5,@GRMWA(R13) PUT OUT TABLE PTR. LSBY. MOVB @R5LB,@GRMWA(R13)PUT OUT TABLE PTR. MSBY. ATA MOVB *R13,R2 R2 = TV (MSBY). MOVB *R13,R1 R1 = TH (MSBY). MOVB *R13,R6 R6 = V1 (MSBY). MOVB *R13,R7 R7 = H1 (MSBY). * * NOW ON WITH THE SHOW. THE REGISTERS ARE NOW SET UP AS: * * R0 = GRANULARITY; *MSBY R1 = TH = COINCIDENCE TABLE HORIZONTAL SIZE - 1. *MSBY R2 = TV = COINCIDENCE TABLE VERTICAL SIZE - 1. *MSBY R3 = Y1 - Y2 = DELTA Y; *MSBY R8 = X1 - X2 = DELTA X; * R5 = POINTER TO COINCIDENCE TABLE IN GROM. *MSBY R6 = V1 = VERTICAL SIZE OF OBJECT ONE IN DOTS. *MSBY R7 = H1 = HORIZ. SIZE OF OBJECT ONE IN DOTS. * R13= GRMRD. * MOV R0,R0 IF GRANULARITY IS 0, DON'T SHIFT JEQ DNTSHF BECAUSE 9900 SHIFT BY 0 IS FU SRA R3,R0 DIVIDE DELTA Y BY (2** GRAN). SRA R8,R0 DIVIDE DELTA X BY (2** GRAN). DNTSHF AB R7,R8 R8 = B = H1 + DELTA X. JLT NOCOIN AB R6,R3 R3 = A = V1 + DELTA Y. JLT NOCOIN CB R3,R2 A::TV JGT NOCOIN CB R8,R1 B::TH JGT NOCOIN RANGE TEST PASSED? SRL R1,8 NOW COMPUTE TABLE INDEX. INC R1 R1 = TH +1. SRL R3,8 R3 = A. MPY R3,R1 R2 = A * (TH + 1). SRL R8,8 R8 = B. A R8,R2 R2 = INDEX. COMPUTE TABLE AND BIT POSITION MOV R2,R0 R0 = INDEX ALSO. ANDI R2,>FFF8 R2 = ROUNDED DOWN TO LOWER MULT OF 8. S R2,R0 R0 = BIT DISPLACEMENT (0 = LEFTMOST). SRA R2,3 R2 = BYTE INDEX INTO TABLE. A R5,R2 R2 = ACTUAL ADDRESS OF BYTE. C *R2+,*R2+ INCREMENT PTR BY 4 FOR 4 BYTE HEADER MOVB R2,@GRMWA(R13) PULL PROPER BYTE FROM GROM INC R0 SWPB R2 MOVB R2,@GRMWA(R13) LI R2,>2000 MOVB *R13,R3 R3 = THE BYTE FROM THE TABLE. SLA R3,R0 GET PROPER BIT INTO THE STATUS CARRY. JOC YUP IF BIT IS 0, NO COINCIDENCE. NOCOIN CLR R2 NO, WE HAVE NO COINCIDENCE YUP MOVB R2,@STATUS YES, WE HAVE COINCIDENCE SOUT9 B @RETNC RETURN * VDP IO CALL FROM 9900 CODE ATA * CALLED AS XOP 7,6 (SCREEN WORK SPACE) ATA * PAB NAME POINTER IN CALLER'R R0 ATA * DATA TYPE (8 OR 10) IN CALLER'S R1 AH VDPIO LI R0,>54+MONIT VDP IO LINK W/O TYPE FETCH ATA IOCOM MOV R0,@GLINK1 POINTER TO GPL ROUTINE ATA MOV *R13,@SCNAM POINTER TO NAME LENGTH (R0) ATA MOVB @3(R13),@TYPE FETCH TYPE (R1 LSB) ATA LWPI GPLWS ATA BL @PUTSTK BL @GPLLK0 CALL I/O LINKAGE ATA BL @GETSTK LWPI SCRWS AND RETURN ATA RTWP ATA CPUIO LI R0,>56+MONIT ATA JMP IOCOM ATA *** MAP DATA FOR XML2 ATA 7/19 ROMFF8 DATA >00FF,>A000,>00FF,>B000 ATA 7/19 DATA >00FF,>4000,>00FF,>5000 ATA 7/19 DATA >00FF,>C000,>00FF,>D000 ATA 7/19 * J O Y S T I C K T A B L E ATA RBBJOY EQU $ ATA H00 EQU $ DRLU (0=TRUE) ATA DATA >0000 0000 ATA DATA >FC00 0001 ATA DATA >0004 0010 ATA DATA >FC04 0011 ATA DATA >00FC 0100 ATA DATA >FCFC 0101 ATA DATA >0000 0110 ATA DATA >FC00 0111 ATA DATA >0400 1000 ATA DATA >0000 1001 ATA DATA >0404 1010 ATA DATA >0004 1011 ATA DATA >04FC 1100 ATA DATA >00FC 1101 ATA DATA >0400 1110 ATA DATA >0000 1111 ATA * K E Y B O A R D T A B L E S ATA RKEYTB EQU $ UNMODIFIED KEYS ATA BYTE '1','q','a','z','2','w','s','x' ATA BYTE '3','e','d','c','4','r','f','v' ATA BYTE '5','t','g','b','6','y','h','n' ATA BYTE '7','u','j','m','8','i','k',',' ATA BYTE '9','o','l','.','0','p',';','/' ATA BYTE '=','[','''',>FF,'-',']',>0D,' ' ATA BYTE '\','`',>FF,>FF ATA RKSHFT EQU $ SHIFTED KEYS ATA BYTE '!','Q','A','Z','@','W','S','X' ATA BYTE '#','E','D','C','$','R','F','V' ATA BYTE '%','T','G','B','^','Y','H','N' ATA BYTE '&','U','J','M','*','I','K','<' ATA BYTE '(','O','L','>',')','P',':','?' ATA BYTE '+','{','"',>FF,'_','}',>0D,' ' ATA BYTE '|','~',>FF,>FF ATA RKFCTN EQU $ Function keys ATA BYTE >03,>C5,>FF,>FF,>04,>FF,>08,>0A Q W ATA BYTE >07,>0B,>09,>FF,>02,>FF,>FF,>7F E R ATA BYTE >0E,>FF,>FF,>BE,>0C,>C6,>BF,>C4 T Y ATA BYTE >01,>FF,>C0,>C3,>06,>FF,>C1,>B8 U I ATA BYTE >0F,>FF,>C2,>B9,>BC,>FF,>BD,>BA O P ATA BYTE >05,>FF,>FF,>FF,>FF,>FF,>0D,' ' [ ] ATA BYTE >FF,>FF,>FF,>FF ATA RKCNTL EQU $ CONTROL KEYS ATA BYTE >B1,>91,>81,>9A,>B2,>97,>93,>98 ATA BYTE >B3,>85,>84,>83,>B4,>92,>86,>96 ATA BYTE >B5,>94,>87,>82,>B6,>99,>88,>8E ATA BYTE >B7,>95,>8A,>8D,>9E,>89,>8B,>80 ATA BYTE >9F,>8F,>8C,>9B,>B0,>90,>9C,>BB ATA BYTE >9D,>FF,>FF,>FF,>FF,>FF,>0D,' ' ATA BYTE >FF,>FF,>FF,>FF ATA RKSPLT EQU $ SPLIT KEYBOARDS ATA BYTE >13,>12,>01,>0F,>07,>04,>02,>00 LEFT ATA BIT4 EQU $ ATA BYTE >08,>05,>03,>0E,>09,>06,>0C,>0D ATA BYTE >0A,>0B,>11,>10 ATA BYTE >13,>12,>01,>0F,>07,>04,>02,>00 RIGHT ATA BYTE >08,>05,>03,>0E,>09,>06,>0C,>0D ATA BYTE >0A,>0B,>11,>10 ATA END