; ; Title: Machine Language Manager ; Author: Andy Guevara ; ; For the Bally Astrocade ; ; Made ready to assemble by Adam Trionfo ; ; .03 - Jan. 3, 2004 ; - Finished cleanup of code ; - First assemble with no errors ; - Matches EXACTLY with MLM cart ; .02 - May 27, 2003 ; - Cleaned up a bit - needs LOTS of work ; .01 - Mar. 27, 2002 ; - Scanned ; - Noticed it's not identical to cart ; ; Assemble using Zmac ; ; zmac -i -m -o mlmsourc.bin -x mlmsourc.lst mlmsourc.asm ; ; ; ******************************************************** ; * * ; * BALLY ARCADE UTILITY PACKAGE * ; * OR * ; * "HOW TO GET STUFF IN AND OUT IN MACHINE LANGUAGE" * ; * * ; * (C) 1981 ANDY GUEVARA JULY 29, 1981 * ; ******************************************************** ; ; ; SKYD EQU 0013H DISP EQU 0D7H ; RST 10 STRING EQU 0DFH ; RST 18 SYSSUK EQU 0FFH SYSTEM EQU 0FFH UPRAM EQU 4F50H ; BEGINNING OF U.P. RAM ; ROOM FOR STACK: ; UPSTK EQU 4FACH ; U.P. STACK-GROWS DOWNWARD MODE EQU 4FADH ; MODE REGISTER IOB EQU 4FAEH ; I/0 INFORMATION BYTE KEYN EQU 4FAFH ; KEY INPUT NUMBER LPINT EQU 4FB0H ; LIGHT PEN INTERRUPT VECTOR SCINT EQU 4FB2H ; SCREEN INTERRUPT VECTOR IN1 EQU 4FB4H ; INPUT REGISTERS IN2 EQU 4FB5H ADRG1 EQU 4FB6H ; ADDRESS REGISTERS ADRG2 EQU 4FB7H SCRN EQU 4FB8H ; SCREEN SIZE-BYTES SCRLN EQU 4FBAH ; SCRATCH AT THIS LINE AND BELOW HRZCB EQU 4FBBH ; HORIZONTAL COLOR BOUNDARY LFLG EQU 4FBCH ; LIST FLAG RFG EQU 4FBDH ; REGISTER FLAG PWRUP EQU 4FBEH ; POWER UP SIGNATURE PW2 EQU 4FC0H ; 3RD BYTE END_ EQU 4FC1H ; END OF FILE MARKER COORD EQU 4FC3H ; XY COORDS FOR SCREEN ; D IS Y COORDINATE POPT EQU 4FC5H ; PRINT OPTIONS BYTE COLORS EQU 4FC6H ; COLOR 3 CD EQU 4FC7H ; COLOR 2 FCOL EQU 4FC8H ; FOREGROUND COLOR (1) BCOL EQU 4FC9H ; BACKGROUND COLOR (0) M4BA EQU 4FCAH ; ENTRY ADDRESS FOR MODE 4 ; ORG 2000H START JP INIT DB 44H,42H,32H ; * NOW MATCHES MLM CART ; DEFS 3 ; EMPTY SPACE DEFB 23 ; BUP REVISION LEVEL 2.3 BPE JP BRKPT ; BREAKPOINT ENTRY DEP JP DISPLAY ; DISPLAY ENTRY POINT SEP JP STRDIS ; STRING DISPLAY INIT DI ; DISABLE INTERRUPTS LD SP,UPSTK ; RESET STACK LD HL,(PWRUP) ; CHECK IF BEEN AWAKE LD DE,0AA00H ; SIGNATURE VALUE OR A ; CLEAR CARRY SBC HL,DE JR NZ,STSPC ; BEEN ASLEEP, SET VALUES ; OK SO FAR LD A,(PW2) ; 3RD BYTE CP 0FAH JR Z,CONT ; JUMP IF OK STSPC DEFB SYSSUK ; ASLEEP, SET DEFAULT SPECS DEFB 00H ; START INTERPRETER DEFB 1BH ; DO FILL DEFW MODE ; SYSTEM RAM START DEFW 23H ; HOW MANY DEFB 00H ; WITH WHAT DEFB 17H ; DO SETOUT DEFB 90 SHL 1 ; BLANK LINE 90 DECIM. AND BELOW ; THIS ALLOWS 360 BYTES OF RAM DEFB 2CH ; 44 DECIMAL--MOVE R/L BOUNDARY ; TO FAR RIGHT DEFB 8H ; INTERRUPT MODE 8 DEFB 5FH ; MOVE BYTES DEFW COLORS ; TO WHERE DEFW 04H ; HOW MANY DEFW COLIST ; FROM WHERE DEFB 19H ; COLSET--SET COLORS DEFW COLORS ; ADDR OF COLOR LIST DEFB 03H ; EXIT INTERPRETER LD HL,0E10H ; DEFAULT VALUE OF SCREEN SIZE LD (SCRN),HL LD A,90 ; 90 DEC. LD (SCRLN),A ; VERT BLANK. LINE CALL CLEAR ; WIPE SCREEN CLEAN CALL READY CONT DEFB SYSSUK DEFB 15H ; DO EMUSIC--STOP MUSIC CALL ININT ; SET UP INTERRUPTS LD HL,0AA00H ; WRITE POWER UP SIGNATURE LD (PWRUP),HL LD A,0FAH LD (PW2),A LD HL,SCRSP ; SET UP CALL TO LD (IN1),HL ; SCREEN SPEC PROGRAM CALL INAD ; KEEPS LIST FROM RUNNING AWAY XOR A ; CLEAR FLAGS AND MODE LD (IOB),A ; CLEAR I/0 BYTE LD (MODE),A LD (POPT),A LD (LFLG),A LD (RFG),A CALL CRLF DEFB STRING DEFW OKM ; SYSTEM PROMPT ; MAIN LD HL,MAIN ; MAIN LOOP PUSH HL ; THIS CAUSES RETURNS FROM ; MAIN ROUTINES TO RETURN HERE CALL KEYGET ; RETURNS WITH KEY N0. IN A ; USED AS A ; DISPLACEMENT IN JUMP TABLE DEFB SYSSUK ; INTERPRETER CALL' DEFB 5DH ; INDEXB--BYTE TABLE LOOKUP DEFW TTT-1 ; RETURNS WITH KEY TYPE IN ; HI NIBBLE ; TRANSLATION IN LOW NIBBLE ; TYPE=0 MEANS NUMBER, ; =1 MEANS COMMAND ; NOTE: THE -1 IS FOR THE ZERO ENTRY THAT DOESN'T EXIST AND 0FH ; ISOLATE TRANSLATION LD C,A ; COPY DIGIT TO C XOR (HL) ; PICK OUT TYPE JP Z,NUMBER ; IF TYPE 0, SKIP AHEAD LD A,(MODE) ; IF NOT THEN MUST BE TYPE 1 ; FIND MODE DEFB SYSSUK DEFB 5BH ; INDEXW--WORD TABLE LOOKUP DEFW MDTBL ; MODE TABLE PUSH DE RET ; SNEAKY WAY TO JUMP TO COMMAND ; ; ******** TYPE-TRANSLATE TABLE *************************** ; ; TTT DEFB 0DH ; 1 D DEFB 0EH ; 2 E DEFB 0FH ; 3 F DEFB 12H ; 4 CALL DEFB 0AH ; 5 A DEFB 0BH ; 6 B DEFB 0CH ; 7 C DEFB 15H ; 8 REG (*TAPE DISPLAY) DEFB 07H ; 9 7 DEFB 08H ; 10 8 DEFB 09H ; 11 9 DEFB 13H ; 12 LIST (*PRINT) DEFB 04H ; 13 4 DEFB 05H ; 14 5 DEFB 06H ; 15 6 DEFB 17H ; 16 INS (*DELETE) DEFB 01H ; 17 1 DEFB 02H ; 18 2 DEFB 03H ; 19 3 DEFB 11H ; 20 READ (:*TAPE INPUT) DEFB 16H ; 21 * DEFB 00H ; 22 0 DEFB 14H ; 23 WRITE (*TAPE OUTPUT) DEFB 10H ; 24 ADDR ; ; ; ********* MODE JUMP TABLE **************** MDTBL DEFW MODE0 ; NORMAL COMMANDS DEFW MODE1 ; REGISTER COMMANDS DEFW MODE2 ; STAR (2ND SET) COMMANDS DEFW MODE3 ; SCREEN SPECIFICATIONS DEFW MODE4 ; EXTERNAL (USER) COMMANDS ; ; ; *********** JUMP TABLE FOR MODE 0 ********************** ; ; ROUTINE KEY VAL. M0JT DEFW ADDR ; 0, ADDRESS DEFW READ_ ; 1, READ AND INCREMENT DEFW ACALL ; 2, CALL DEFW LIST_ ; 3, LIST DEFW WRITE ; 4, WRITE TO MEMORY DEFW REG ; 5, LOAD REGISTERS DEFW STAR0 ; 6, SET OPTIONS FLAG DEFW INS ; 7, INSERT IN MEMORY ; ; ************ MODE 1 JUMP TABLE ************************** ; ; ROUTINE KEY VAL. M1JT DEFW M1RT ; 0, IGNORE 'ADDR' KEYPUSH DEFW RPLUS ; 1, SKIP TO NEXT REGISTER DEFW M1RT ; 2, IGNORE 'CALL' DEFW RLIST ; 3, LIST REGISTERS DEFW RWRT ; 4, CHANGE REGISTER CONTENTS DEFW M1RT ; 5, IGNORE 2ND 'REG' DEFW M1RT ; 6, IGNORE '*' DEFW M1RT ; 7, IGNORE 'INS' ; ; ************ MODE 2 JUMP TABLE **************** ; M2JT DEFW ADDR ; 0 DEFW TAPIN ; 1 DEFW ACALL ; 2 DEFW PRINT ; 3 DEFW TAPOUT ; 4 DEFW TADIS ; 5 DEFW STAR2 ; 6 DEFW DEL ; 7 ; ; ; ; ************ MODE 3 JUMP TABLE ***************** M3JT DEFW M30 DEFW M31 DEFW M32 DEFW M33 ; ; NUMBER INPUT ; NUMBER LD HL,IN1 ; SET UP IN1 LD A,C ; DIGIT IN LO HALF OF C RLD ; RLD: A 4-BIT SHIFT AS FOLLOWS-- ; LOW A -> LOW IN1, LOW IN1 -> HI IN1, HI IN1 -> LOW A ; THE EFFECT IS TO SHIFT INDIVIDUAL HEX DIGITS INTO IN1. ; ONLY THE LAST 4 ARE REMEMBERED IN IN1 & IN2. ; INC HL ; BINK POINTER (TO IN2) RLD ; DO IT AGAIN LD A,C ; RELOAD A WITH DIGIT CALL NUMDIS ; DISPLAY IT RET ; AND GO HOME ; ; MODE0 LD A,C ; MODE 0, GET DISPLACEMENT DEFB SYSSUK DEFB 5BH ; INDEXW--WORD TABLE LOOKUP DEFW M0JT ; JUMP TABLE ADDRESS PUSH DE RET ; JUMP TO COMMAND ; MODE1 LD A,C ; PUT DISPLACEMENT IN A DEFB SYSSUK ; REG OPERATIONS DEFB 5BH ; INDEXW--WORD TABLE DEFW M1JT ; JUMP TABLE ADDRESS PUSH DE ; JUMP TO PROCESS M1RT RET ; ; ; ADDRESS ROUTINE ; ADDR CALL INAD ; MOVE DATA FROM INPUT TO ADDR REG LD A,':' ; COLON TO A DEFB DISP XOR A ; CLEAR LIST FLAG LD (LFLG),A RET ; AND GO HOME ; INAD LD DE,ADRG1 ; MOVE ADDRESS TO ADRG1 LD HL,IN1 ; FROM INPUT REGISTER 1 LDI ; SINGLE INSTRUCTION MOVE LDI ; BETWEEN MEMORY LOCATIONS ; IT'S DONE TWICE BECAUSE TWO BYTES ; OF INFO ARE BEING MOVED RET ; READ_ LD HL,(ADRG1) ; LOAD ADDRESS LD A,(HL) ; LOAD CONTENTS TO A INC HL ; INCREMENT CONTENTS LD (ADRG1),HL ; STORE BACK CALL RGDIS ; DISPLAY WHAT'S IN A CALL SPACE_ RET ; ; WRITE TO MEMORY ; WRITE LD HL,(ADRG1) ; PICK UP ADDRESS LD A,(IN1) ; PICK UP INPUT BYTE LD (HL),A ; STORE IT INC HL ; BINK ADDRESS LD (ADRG1),HL ; STORE IT PACK CALL SPACE_ ; OUTPUT A SPACE RET ; GO HOME ; ; INSERT INTO MEMORY ; ; THIS ROUTINE MAKES USE OF AN END OF FILE MARKER (END_) ; THAT SHOULD POINT TO THE LAST BYTE IN A PROGRAM +1. ; THE ROUTINE TESTS FOR ATTEMPTS TO WRITE INTO THE ; STACK, AND MAKES ALLOWANCES FOR ADDED MEMORY. ; IF 'END_' IS LESS THAN THE PRESENT ADDRESS REGISTER ; CONTENTS, THE ROUTINE WILL UPDATE IT TO (ADRG1)+1. ; INS LD HL, (END_) ; GET ADDRESS LD DE,UPRAM ; TEST IF PUSHING SYSTEM RAM OR A ; CLEAR CARRY FLAG FOR SBC SBC HL,DE JR C,INS2 ; ADDRESS IS LESS THAN UPRAM JR NZ,INS1 ; ADDRESS IS GREATER CALL RED ; IF THE SAME ISSUE WARNING DEFB STRING DEFW WAM CALL NORM ; BACK TO NORMAL PRINT JR INS2 ; AND GO ON INS1 LD DE,4FFFH ; SEE IF INTO ADDED MEMORY LD HL,(ADRG1) SBC HL,DE JR NC,INS2 ; OK IF POSITIVE CALL ERR ; OTHERWISE OOPS RET ; INS2 LD HL, (END_) ; GET THE END OF FILE LD DE,(ADRG1) ; SEE IF END>ADRG1 OR A ; CLEAR CARRY SBC HL,DE ; (HL)-(DE) LD B,H LD C,L ; MOVE RESULT TO BC (COUNTER) JR NC,INS3 ; ALL SET EX DE,HL ; HL=(ADRG1) INC HL ; OTHERWISE END=ADRG+1 LD (END_),HL LD BC,01H ; SET COUNT TO 1 INS3 LD DE,(END_) PUSH DE POP HL DEC HL ; HL=END-1 LDDR ; COPY FROM (HL) TO (DE), ; (BC) TIMES ; AND DECREMENT EACH TIME. CALL WRITE ; STUFF THE INFO LD HL,END_ ; INC. END INC (HL) RET ; AND GO HOME ; ; ; EXECUTE A PROGRAM ; NOTE: CALL AND TAPE INPUT ARE INCOMPATIBLE FOR USE ; AT THE SAME TIME BECAUSE BOTH USE ALTERNATE REGISTER ; SET. ; ACALL LD HL,CART ; SET UP RETURN PROCESS PUSH HL ; ON STACK LD HL,(IN1) ; GET ADDRESS OF PROGRAM PUSH HL EX AF,AF' ; EXCHANGE 'A' REGISTER ; FOR ITS ALTERNATE 'A' REGISTER EXX ; EXCHANGE THE REST OF ; THE BEGS FOR THEIR ALTERNATES RET ; POP THE ADDRESS OFF THE STACK ; AND JUMP TO THE PROGRAM ; ; CART EX AF,AF' ; CALL RETURN PROCESS EXX ; GET BACK ORIG. SET RET ; ALL DONE, GO HOME ; ; SET UP FOR MODE ; STAR0 LD A,02H LD (MODE),A ; SET MODE 2 CALL RED LD A,'*' DEFB DISP ; TELL OPERATOR CALL NORM RET ; ; ; LIST ROUTINE ; ; LFLAG INDICATES BEING IN THE MIDDLE OF SUCCESSIVE SINGLE ; LIST OPERATIONS. IT'S CLEARED BY THE ADDRESS KEY. ; LIST_ LD A,(LFLG) ; TEST THE FLAG AND A JR NZ,OUTLN ; IF SET, DO A LINE AND GO HOME ; LD A,0DH ; OTHERWISE END THIS LINE DEFB DISP LD DE,(IN1) ; CHECK IF END ADDR WAS INPUT LD HL,(ADRG1) SBC HL,DE JR Z,OUTLN ; IF SAME, DO A LINE, AND GO HOME ; ; MULTI-LINE LIST ; MLIST_ CALL OUTLN ; EA WAS INPUT, DO A LINE AND ; COME BACK. ; LD HL,(IN1) ; ENDING ADDRESS LD DE,(ADRG1) ; NEW BEGINNING ADDRESS SBC HL,DE ; SUBTRACT LEA FROM EA JR NC,MLIST_ ; IF POS, DO ANOTHER LINE RET ; ELSE, GO BACK ; ; OUTPUT A LINE ; OUTLN LD A,0FFH ; SET FLAG LD (LFLG),A LD HL,(ADRG1) ; PICK: UP BEG. ADDR. CALL HLIST ; DISPLAY 1ST BYTE ADDRESS LD A,':' DEFB DISP CALL SPACE_ OL1 CALL READ_ ; GET AND DISPLAY DATA LD A,L ; CHECK FOR END OF LINE AND 07H ; EDIT MASK ; IF 00 OR 08H, ; THE LAST 3 BITS ARE ZERO JR NZ,OL1 ; IF NOT, GO BACK ; END OF LINE LD A,(IOB) ; CHECK IF TAPE OUT BIT 0,A ; TURNED ON JR Z,LASC ; IF NOT, DO ASCII PART JR LA3 ; AND EXIT ; ; LIST ASCII INTERPRETATION ; LASC LD BC,08H ; BACK UP POINTER 8 BYTES SBC HL,BC LD B,C ; B=8 AS A COUNTER LAI LD A,(HL) ; DISPLAY ASCII INTERPRETATION CP 0DH ; DON'T DISPLAY A CR JR NZ,LA2 LD A,'.' ; DO A DOT INSTEAD LA2 DEFB DISP INC HL ; INC. POINTER DJNZ LAI ; DECR. COUNT & LOOP LA3 LD A,0DH ; CARRIAGE RETURN DEFB DISP RET ; GO HOME ; ; LOAD REGISTERS ; REG LD A,01H LD (MODE),A ; SET MODE TO 1 DEFB STRING DEFW AFM ; PUT OUT MESSAGE XOR A LD (RFG),A ; TABLE INITIALIZATION RET ; ; ; ************ REGISTER TABLE ******** ; ADDR RFG RGTBL DEFW AFG ; 0 DEFW BCG ; 1 DEFW DEG ; 2 DEFW HLG ; 3 ; ; RFG OFFSET DETERMINES WHICH REGS TO PULL ; ; REGISTER WRITE ROUTINE ; RWRT LD A,(RFG) DEFB SYSSUK DEFB 5BH ; INDEXW--WORD TABLE LOOKUP DEFW RGTBL ; GET JUMP ADDRESS PUSH DE ; SET UP JUMP RET ; POP, JUMP AFG LD A,(IN1) ; LOAD NEW VALUE EX AF,AF' ; PUT IN ALTERNATE A CALL RPLUS ; OUTPUT DESIGNATOR AND UPDATE RP? RET BCG LD BC,(IN1) ; GET NEW VALUES PUSH BC EXX ; EXCHANGE REGISTER S'E'TS POP BC ; PUT IN NEW VALUES EXX ; SWAP BACK CALL RPLUS RET DEG LD DE,(IN1) PUSH DE EXX POP DE EXX CALL RPLUS RET HLG LD HL,(IN1) PUSH HL EXX POP HL EXX XOR A ; CLEAR A LD (RFG),A ; CLEAR FLAG JR RLIST ; LIST THE REG SET ; RPLUS LD A , (RFG) CP 03H ; DONE YET? JR Z, RP1 ; SKIP AHEAD IF SO INC A LD (RFG),A DEFB SYSSUK DEFB 5BH ; INDEXW, GET MESSAGE ADDR DEFW RMTBL ; REGISTER MSG TABLE CALL STR1 ; PUT OUT MESSAGE RET RP1 XOR A LD (RFG),A ; CLEAR FLAG JP MOD0 ; GO HOME ; ; RMTBL DEFW AFM ; 0 DEFW BCM ; 1 DEFW DEM ; 2 DEFW HLM ; 3 ; ; OUTPUT REGISTER CONTENTS ; RLIST XOR A LD (RFG),A ; CLF FLAG CALL CRLF DEFB STRING DEFW AFM ; OUTPUT DESIGNATOR EX AF,AF' ; GET REG CONTENTS PUSH AF EX AF,AF' POP AF CALL RGDIS CALL RPLUS ; DESIGNATOR & RFG UPDATE EXX ; ALTERNATE SET PUSH BC ; SAVE REGISTER CALL SWDIS ; SWAP AND DISPLAY PUSH DE CALL SWDIS PUSH HL CALL SWDIS EXX ; BACK TO NORMAL SET DEFB STRING DEFW ADM LD HL,(ADRG1) CALL HLIST ; DISPLAY ADDRESS REGISTER CALL CRLF JP MOD0 ; ; SWAP AND DISPLAY A REGISTER ; SWDIS EXX ; NORMAL SET POP DE POP HL ; GET CONTENTS PUSH DE ; PUT BACK RETURN ADDR CALL HLIST ; SHOW CONTENTS CALL RPLUS ; DESIG. AND RFG UPDATE EXX ; ALTERNATE SET RET ; ; CLEAN UP AND RESET MODE MOD0 XOR A ; CLEAR A TO ZERO LD (MODE),A ; SET MODE TO 0 LD (LFLG),A ; CLEAR LIST FLAG LD (POPT),A ; CLEAR PRINT OPTIONS RET ; GO HOME ; ; ************ MODE 2 OPERATIONS *********** ; MODE2 LD A,C ; GET DISPLACEMENT DEFB SYSSUK DEFB 5BH ; INDEXW DEFW M2JT ; JUMP TABLE PUSH DE RET ; POP, JUMP ; ; TAPIN DI ; INITIALIZE INTERRUPTS EXX LD B,0FCH ; SET COUNT EXX LD A,18H ; INT. ENABLE AND MODE OUT (0EH),A EI CALL CRLF JP MOD0 ; CLEAN UP AND GO HOME ; TADIS CALL TAPIN ; INIT INTERRUPTS LD HL,IOB ; SET TAPE DISPLAY BIT SET 3,(HL) JP MOD0 ; ; ; WRITE TO TAPE ; TAPOUT LD HL,IOB ; GET I/0 INFO BIT 0,(HL) ; TAPE OUT SET? JR NZ,TO1 ; YES, CLEAR IT SET 0,(HL) ; NO, SET I T RES 1,(HL) ; CLEAR PRINT BIT CALL RED JR TO2 TO1 RES 0,(HL) CALL GREEN TO2 LD A,'T' DEFB DISP JP MOD0 ; ; PRINT LD HL,IOB ; GET I/O BYTE BIT 1,(HL) ; PRINT EDIT CLEAR? JR Z,PR1 ; YES, SET IT RES 1,(HL) ; NO., CLEAR IT CALL GREEN JR PR2 PR1 CALL RED SET 1,(HL) ; SET PRINT BIT RES 0,(HL) ; CLEAR TAPE BIT PR2 LD A,'P' DEFB DISP JP MOD0 ; GO HOME ; ; STAR2 LD A,08H ; DISABLE TAPE INPUT OUT (0EH),A LD HL,IOB ; GET I/0 INFO RES 3,(HL) ; CLEAR TAPE DISPLAY MODE CALL GREEN LD A,'*' DEFB DISP JP MOD0 ; ; ; DELETE ; DEL OR A ; FIX CARRY FLAG LD HL,(END_) LD DE,(ADRG1) SBC HL,DE ; GET NUMBER T'7 MOVE LD B,H LD C,L ; COUNT TO PC LD H,D LD L,E INC HL ; (ADRG1) +1 TO HL LDIR ; COPY FROM (Hl) TO (DE), ; (BC) TIMES LD A,'<' ; A MARKER CALL RED DEFB DISP LD HL,END_ ; UPDATE END DEC (HL) JP MOD0 ; GO HOME ; ******** MODE 4 OPERATIONS ************ ; ; MODE 4 IS AVAILABLE FOR REDEFINING THE KEYPAD FOR ; OTHER USES. USER MUST ENTER THE ADDRESS OF HIS ; KEYPAD HANDLING ROUTINE IN M4BA (ADDRESS 4FC8), ; LOWER HALF FIRST. SETTING THE MODE TO 4 ; IN THE STARTUP ROUTINE WILL ROUTE CONTROL IN THIS ; DIRECTION. ; MODE4 LD HL,(M4BA) ; GET ENTRY ADDRESS JP (HL) ; JUMP TO IT ; ; ; ******* DISPLAY CONTROL ROUTINES ******* ; CLEAR LD BC,(SCRN) ; SIZE OF SCREEN LD DE,4000H ; START OF SCREEN LD A,0H ; DATA TO FILL WITH DEFB SYSTEM DEFB 1AH ; DO NT FILL--CLEAR SCREEN LD HL,00H LD (COORD),HL ; SET COORDINATES TO 0,0 RET ; ; DISPLAY IS THE GENERAL DISPLAY ROUTINE FOR THE ; SYSTEM. IT TAKES CARE OF THE SCREEN, TAPE, AND PRINTER ; PORTS. PRINT DIFFERS FROM TAPE ONLY IN THAT ; NONPRINTABLES ARC FILTERED OUT AND LINE FEEDS ; ARE INSERTED. ; DISPLAY PUSH HL PUSH DE PUSH BC PUSH AF LD HL,IOB ; TEST FOR TAPE OR PRINT OUT BIT 0,(HL) ; TAPE OUT BIT CALL NZ,TWRT ; DO IT ; SIMPLE DISPLAY POP AF ; RESTORE CHARACTER PUSH AF ; PUT IT BACK CP 0DH ; CHECK IF CARR. RETURN JR NZ,D1 ; IF NOT, GO AHEAD BIT 1,(HL) ; PRINT ON? CALL NZ,TWRT ; YES, SEND CR TO PRINTER D0 CALL CRLF ; DO IT ON SCREEN JR DRET D1 CP 20H ; CHECK IF PRINTABLE JR C,DOT ; JUMP IF MINUS CP 5BH ; UPPER LIMIT JR C,OK ; JUMP IF NEG. DOT LD A,'.' ; DO A DOT IF NOT PRINTABLE OK PUSH AF ; SAVE IT BIT 1,(HL) ; PRINT ON? CALL NZ,TWRT ; YEP, DO IT LD DE,(COORD) ; GET X,Y COORDINATES LD A,(POPT) ; PICK UP OPTIONS, IF ANY LD C,A ; PUT IN C AND A JR NZ,OK1 ; IF NONZERO, USE IT LD C,04H ; OTHERWISE STANDARD PRINT OK1 POP AF ; GET CHAR BACK XOR 80H ; ALTERNATE FONT INDICATOR LD IX,SMLFNT ; SMALL CHAR. FONT DESCRIPTOR DEFB SYSTEM DEFB 32H ; CHRDIS--OUTPUT CHARACTER ROUTINE ; RETURNS WITH UPDATED X,Y COORDS ; IN DE, D=Y, E=X LD A,9BH ; TEST FOR END OF LINE CP E CALL C,CLF ; IF SO,SET UP NEXT LINE CALL CON ; PAINT CURSOR DRET POP AF ; AND GO HOME POP BC POP DE POP HL RET ; CON LD BC,0503H ; PAINT 3X5 CURSOR LD A,55H ; BINARY 01010101 COLOR MASK ; (COLOR #1) LD (COORD),DE ; STORE COORDS BACK DEFB SYSTEM DEFB 1CH ; RECTAN--PAINT RECTANGLE RET ; ; NOTE: STRING CLOBBERS ALMOST EVERYTHING, USE WITH CARE ; STRDIS EX (SP),HL ; GET ADDRESS FROM CALLING ROUTINE LD E,(HL) INC HL LD D,(HL) INC HL EX (SP),HL ; FIX THE STACK STR1 LD A,(DE) ; PICK UP CHARACTER CP 00H ; IF NULL, END RET Z DEFB DISP ; DISPLAY CHARACTER INC DE ; INCREMENT ADDRESS JR STR1 ; DO ANOTHER ; ; COLOR CHANGES ; GREEN PUSH AF LD A,0CH ; GREEN ON BLACK OPTION G1 LD (POPT),A POP AF RET ; RED PUSH AF LD A,08H ; RED ON BLACK JR G1 ; NORM PUSH AF XOR A ; BACK TO NORMAL JR G1 ; ; NUMERICAL DISPLAY ROUTINE ; NUMDIS CP 0AH ; CHECK IF WITHIN NUMERICAL LIMITS JR C,NUM1 ; JUMP IF NEG. ; ELSE NUMBER IS >= 'A' (HEX) ADD A,07H ; SET UP FOR ASCII NUM1 ADD A,30H ; MAKE IT ASCII DEFB DISP RET ; ; CHECK AND SCROLL IF NEEDED ; SCROLL LD A,(SCRLN) SUB 6 ; SCRLN-6 IS LOWER LIMIT OF SCREEN CP D ; D IS Y COORDINATE RET P ; GO HOME IF NOT THERE YET PUSH AF ; SAVE THIS VALUE XOR A ; CLEAR A AND CARRY FLAG LD HL,(SCRN) ; GET SCREEN SIZE LD BC,0F0H ; MINUS 1 LINE'S WORTH SBC HL,BC JR Z,SCR1 ; IF ZERO, JUST BLANK TOP LINE PUSH HL POP BC ; HOW MANY TO MOVE LD HL,40F0H ; SOURCE LD DE,4000H ; DESTINATION LDIR ; MOVE (HL) TO (DE) BC TIMES SCR1 LD BC,06A0H ; BLACK OUT LAST LINE LD E,A POP AF ; RESET COORDS LD D,A XOR A ; DATA FOR RECTANGLE DEFB SYSTEM DEFB 1CH ; RECTAN RET ; GO HOME ; CRLF LD DE,(COORD) ; GET CURSOR COORDS LD BC,0503H ; PAINT 3X5 BLANK LD A,00H ; COLOR DEFB SYSTEM DEFB 1CH ; RECTAN ; UPDATE COORDINATES CLF LD E,0 ; 'CARRIAGE RETURN' LD A,06H ; 'LINE FEED' ADD A,D LD D,A CALL SCROLL CALL CON ; PAINT CURSOR LD HL,IOB BIT 0,(HL) ; TAPE WRITE IN PROGRESS? RET Z ; NOPE, GO HOME DEFB SYSSUK DEFB 51H ; PAWS DEFB 8 ; 4 CHARACTERS' WORTH RET ; AND GO HOME RET ; ; THIS ROUTINE OUTPUTS ANY 8 BIT VALUE IN THE A REGISTER ; TO THE TAPE OUTPUT PORT. ; NOTE: THE TAPE PORT IS THE SAME AS THE PRINTER PORT ; SO IT IS SUGGESTED THAT FOR PRINTING THE PRINT COMMAND ; BE USED SO THAT THE PRINTER DOESN'T GO BANANAS. ; TWRT ; WRITE TO TAPE LD C,A ; CHAR. TO C RLC C ; SHIFT LEFT ONCE TW1 IN A,(12H) ; TAPE PORT FEEDBACK AND 2 ; WAIT FOR CLOCK HIGH JR Z,TW1 LD B,0AH ; BIT COUNTER TW2 LD A,0C0H ; TIME COUNTER (192 DECIMAL) TW3 DEC A JR NZ,TW3 ; 1.72 MSEC., HALF OF 300 HZ ; CLOCK NOW LOW DEC B ; START COUNTING BITS RET Z ; GO HOME IF ALL DONE IN A,(12H) ; IS FEEDBACK STILL SAME STATE? LD E,A ; IF SO, THEN CLOCK IS LOW TW4 IN A,(12H) XOR E ; IF SAME, RESULT IS 0 AND 2 ; ELSE RESULT IS 2 JR Z,TW4 ; TRY AGAIN ; CLOCK HIGH LD A,E ; OLD BIT TO A XOR C ; SEE IF NEED TO CHANGE STATE AND 2 ; OF OUTPUT JR Z,TW5 ; N0, SKIP AHEAD IN A,(12H) ; TOGGLE OUTPUT TW5 SET 1,C ; PUT IN STOP BITS RRC C ; SET FOR NEXT BIT JR TW2 ; DO IT AGAIN ; ; ; ; ; SPACE_ LD A,20H ; ASCII SPACE DEFB DISP RET ; ; ERR CALL RED DEFB STRING DEFW ERM JP MOD0 ; ; THIS ROUTINE DISPLAYS THE CONTENTS OF THE A REGISTER. ; THUS ANY BYTE OF DATA CAN BE DISPLAYED BY PUTTING IT ; IN A AND CALLING RGDIS. RGDIS PUSH AF ; DISPLAY REGISTER CONTENTS AND 0F0H ; MASK OUT LOWER HALF RLCA RLCA RLCA RLCA CALL NUMDIS POP AF AND 0FH ; MASK OFF UPPER HALF CALL NUMDIS RET ; HLIST LD A,H ; SHOW HL ROUTINE CALL RGDIS LD A,L CALL RGDIS RET ; ; READY LD DE,(SCRN) ; HOW MANY SCREEN BYTES LD HL,UPRAM ; 1ST SYSTEM SCRATCH BYTE RES 6,H ; MAKE INTO A RELATIVE NUMBER OR A ; CLEAR CARRY FLAG SBC HL,DE ; (TOTAL RAM-SCREEN RAM) CALL HLIST ; DISPLAY IT DEFB STRING DEFW RMSG ; STRING TO GO ALONG WITH IT LD HL,(SCRN) SET 6,H ; FUDGE IT INTO AN ADDRESS CALL HLIST ; DUMP IT OUT CALL CRLF RET ; ; ; *********** KEYBOARD INTERFACE ************* ; ; SCANS THE KEYPAD UNTIL A KEY IS PRESSED. RETURNS WITH ; THE NUMBER OF THE KEY IN B. NUMBERS ARE ROW-WISE ; RIGHT TO LEFT, 1 THROUGH 24. ; KEYGET LD HL,KEYGET ; SAVE THIS ADDRESS PUSH HL DEFB SYSSUK ; DEFB 51H ; PAWS--KEY DEBOUNCER, HOLD FOR DEFB 02H ; 2/60 OF A SECOND ; KEYPAD INPUT RETURNS WITH KEY N0. IN A LD DE,KEYN ; OLD KEY NUMBER LD BC,414H ; B=COUNT, C=STARTING PORT KG1 IN A,(C) ; CHECK OUT PORT AND 3FH ; GET RID OF EXTRANEOUS BITS JR NZ,KG2 ; JUMP IF GOT A GOOD ONE INC C ; NOPE, DO ANOTHER DJNZ KG1 XOR A ; NONE AT ALL LD (DE),A ; KEEP TRACK OF LAST KEY RET ; BACK TO KEYGET ; KG2 DEC B LD C,0 KG3 RRCA ; FIND THE RIGHT BIT JR C,KG4 INC C JR KG3 KG4 LD A,C ; BIT # RLCA ; MULT BY 4 RLCA OR B INC A ; NOW HAVE KEY NO. LD B,A LD A,(DE) ; OLD NUMBER XOR B ; COMPARE RET Z LD A,B ; DIFFERENT, UPDATE LD (DE),A POP HL ; FIX THE STACK RET ; AND GO BACK ; ; ********** INTERRUPT ROUTINES ***************** ; ; ; INITIALIZE INTERRUPTS ; ININT IN A,(12H) ; TAPE INPUT PORT AND 2 ; MAKE SURE IT'S SET TO 0 JR NZ,ININT DI ; DISABLE INTERRUPTS IM 2 ; INTERRUPT MODE LD A,4FH ; SET INTERRUPT PAGE LD I,A LD A,0B2H ; SCREEN INTERRUPT VECTOR OUT (0DH),A LD A,08 OUT (0EH),A ; SCREEN INTS ONLY LD A,200 OUT (0FH),A ; SCREEN INT. EVERY 200 LINES LD HL,TAPINT ; LOAD INTERRUPT VECTORS LD (LPINT),HL LD HL,SCRINT LD (SCINT),HL EI ; ENABLE INTERRUPTS RET ; ; ***** LIGHT PEN INTERRUPT HANDLER ******* ; ; THE TAPE INPUT HANDLER RECOGNIZES A COLON AS AN ; ADDRESS DIRECTIVE, AND SPACE AND CR AS WRITE DIRECTIVES. ; TAPINT PUSH AF EXX CALL COLL ; GET A CHARACTER TI1 LD HL,IOB ; TEST TAPE DISPLAY BIT BIT 3,(HL) JR NZ,TID ; IF SET, GO DISPLAY CP 0DH ; ELSE TEST FOR CR JR NZ,TI2 ; SKIP IF NOT CALL WRITE ; DO A WRITE LD A,0DH ; REPLACE CR JR TID ; DISPLAY IT TI2 CP 20H ; ELSE, ACT ON IT JR C,TID ; EXIT IF NOT DISPLAYABLE JR NZ,TI3 ; ZERO MEANS A SPACE BIT 7,(HL) ; BIT 7 IN IOB IS ADDR FLAG MEANING IGNORE 1ST SPACE ; FOLLOWING COLON PUSH HL ; SAVE IOB CALL Z,WRITE ; IF CLEAR POP HL RES 7,(HL) ; CLEAR THE BIT JR TIX ; EXIT ; TI3 RES 7,(HL) ; CLEAR BIT IF NOT A SPACE CP 30H ; CHECK NUMBER LIMITS JR C,TID ; LESS THAN CP 3AH JR NC,TI4 ; >= TI3A AND 0FH ; STRIP AWAY ASCII LD C,A CALL NUMBER JR TIX TI4 JR NZ,TI5 ; JUMP IF NOT A COLON PUSH HL ; SAVE IOB CALL ADDR POP HL SET 7,(HL) ; IGNORE NEXT SPACE JR TIX ; EXIT TI5 CP 41H ; 'A' JR C,TID CP 47H ; 'G' JR NC,TID ADD A,09H ; SET UP FOR NUMBER JR TI3A ; GO TO IT TID DEFB DISP TIX LD A,(MODE) CP 4 ; MODE 4 SET? JP Z,MODE4 ; SKIP OUT POP AF EXX EI RET ; COLL IN A,(12H) ; COLLECT HITS FROM TAPE RRA ; BIT TO CARRY LD A,C ; BITS SO FAR RRA ; NEW BIT SHIFTED IN LD C,A LD A,B ; COUNT AND A JR C,CO1 ; NEG. JR NZ,CO2 ; NONZERO BIT 7,C ; ZERO, TEST HIGHEST BIT JR NZ,EXIT ; NOT READY YET LD B,08H ; GOT ONE JR EXIT CO1 INC B ; NEG. COUNT LOOP BIT 7,C ; STILL COLLECTING BITS JR NZ,EXIT LD B,0FCH ; A ZERO CAME THRU WITH ; COUNT WRONG EXIT POP HL ; DROP RETURN ADDRESS JR TIX ; AND GET OUT CO2 DJNZ EXIT ; POS COUNT, NOT DONE YET LD A,C ; DONE RET ; ; *********** SCREEN INTERRUPT HANDLER ************ ; SCRINT EI ; ENABLE INTERRUPTS RET ; AND GO BACK ; ; ; ; ********** UTILITY PROGRAMS ********** ; ; ; BREAKPOINTS ARE SET BY WRITING 'CF' AT DESIRED LOCATIONS ; BRKPT CALL CART ; BREAKPOINT ROUTINE CALL CRLF ; CART GETS ORIGINAL REG SET DEFB STRING DEFW BKM POP HL ; GET BRKPT ADDR DEC HL ; BACK OFF ONE CALL HLIST ; SHOW IT CALL RLIST ; SHOW REGISTERS JP START ; ; ; ; SET SCREEN SPECIFICATIONS ; SCRSP CALL CRLF ; OUTPUT A CARRIAGE RETURN LD A,90 ; DEFAULT VALUE LD (IN1),A ; TO INPUT REGISTER DEFB STRING DEFW BLM ; BLANK SPECS MESSAGE XOR A ; USE REG TYPE SEQUENCE LD (RFG),A LD A,3 LD (MODE),A ; SET MODE 3 RET ; ; THE FOLLOWING SECTION WILL BE ENTERED EACH TIME A 'W' IS ; INPUT WHILE IN MODE 3 ; MODE3 LD A,C ; GET KEY VALUE CP 4H RET NZ ; ACCEPT WRITE ONLY LD A,(RFG) ; PICK UP FLAG DEFB SYSSUK DEFB 5BH ; INDEXW-JUMP BASED ON FLAG DEFW M3JT ; JUMP TABLE PUSH DE ; RETURNED ADDRESS LD A,(IN1) ; GET INPUT VALUE RET ; JUMP TO ROUTINE M30 ; CALCULATE WHERE BLANKING ; SHOULD START CP 5AH ; IF 90 DECIMAL JR Z,M302 ; LEAVE ALONE AND 0FH ; MASK OUT UPPER DIGIT JR NZ,M300 ; IF ZERO, MAKE IT ONE INC A M300 LD B,A ; N0. OF TEXT LINES INPUT XOR A M301 ADD A,06H ; CHARACTER FRAME SIZE DJNZ M301 M302 LD (ADRG1),A ; TEMP. LINE STORAGE LD A,2CH ; 44 DECIMAL LD (IN1),A ; HORIZONTAL COLOR BOUNDARY CALL CRLF DEFB STRING DEFW CBM LD A,1 ; INCREMENT PROCESS POINTER LD (RFG),A RET ; GET THE NEXT SPEC. ; M31 LD (HRZCB),A ; NO LIMIT CHECKS LD A,00H ; DEFAULT BACK COLOR LD (IN1),A CALL CRLF DEFB STRING DEFW BCLM ; BACK COLOR MESSAGE LD A,2 ; SET UP FOR NEXT PROCESS LD (RFG),A RET ; GO BACK ; M32 LD (BCOL),A ; SET BCOLOR LD A,07H ; FORE COLOR LD (IN1),A CALL CRLF DEFB STRING DEFW FCLM ; FORE COLOR MESSAGE LD A,3 ; SET UP FOR NEXT PROCESS LD (RFG),A RET ; THIS IS THE ACTION OF THE LAST KEYPUSH OF THE ; SCREEN SPEC. ROUTINE M33 LD (FCOL),A ; SET FCOLOR LD A,(ADRG1) ; GET BLANK LINE # LD (SCRLN),A ; INTO ITS PROPER PLACE RLCA ; SETOUT NEEDS IT ; SHIFTED LEFT ONE BIT LD D,A LD A,(HRZCB) ; COLOR BOUNDARY LD B,A LD A,08H ; INTERRUPT MODE DEFB SYSTEM DEFB 16H ; DO NT SETOUT LD HL,COLORS ; GET ADDRESS OF COLOR LIST DEFB SYSTEM DEFB 18H ; COLSET LD HL,00H ; CALCULATE SCREEN SIZE ; FROM N0. OF LINES DISPLAYED LD A,(SCRLN) LD B,A LD DE,40 ; DECIMAL BYTES PER LINE M331 ADD HL,DE DJNZ M331 ; FIGURE OUT LD (SCRN),HL ; NO. OF BYTES IN SCREEN CALL CLEAR ; CLEAR SCREEN CALL READY XOR A ; CLEAN OF LD (RFG),A LD (MODE),A RET ; GO HOME ; ******** MESSAGE TABLE ******** AFM DEFB 'A:' DEFB 00 BCM DEFB ' BC:' DEFB 00 DEM DEFB ' DE:' DEFB 00 HLM DEFB ' HL:' DEFB 00 ADM DEFB ' ADDR:' DEFB 00 BKM DEFB 'BKPT ADDR:' DEFB 00 FCLM DEFB 'FOREGROUND: ' DEFB 00 WAM DEFB '*WARNING*' DEFB 00 RMSG DEFB ' BYTES AVAILABLE STARTING AT ' DEFB 00 BLM DEFB 'TEXT LINES: ' DEFB 00 CBM DEFB 'COLOR BOUNDARY: ' DEFB 00 BCLM DEFB 'BACKGROUND COLOR: ' DEFB 00 ERM DEFB 'ERR' DEFB 00 OKM DEFB 'OK' DEFB 00 ; ; ; ********** COLOR LIST ********* COLIST DEFB 0A3H ; GREEN DEFB 52H ; RED DEFB 07H ; WHITE DEFB 00H ; BLACK ; ; ; ******* SMALL CHARACTER FONT DESCRIPTOR ***** SMLFNT DEFB 0A0H ; 1ST CHARACTER DEFB 4 ; X FRAME SIZE DEFB 6 ; Y FRAME SIZE DEFB 1 ; NO. OF BYTES X PATTERN DEFB 5 ; NO. OF BYTES Y PATTERN DEFW SMLCHR ; ADDRESS OF CHARACTER TABLE ; ; ; ****** CHARACTER TABLE ******** SMLCHR DEFB 00,00,00,00,00 ; SPACE DEFB 20H,20H,20H,00,20H ; ! DEFB 0A0H,0A0H,00,00,00 ; " DEFB 0A0H,0E0H,0A0H,0E0H,0A0H ; # DEFB 0,0,0,0,0 ; UNDEFINED DEFB 0A0H,20H,40H,80H,0A0H ; % DEFB 0,0,0,0,0 ; UNDEFINED DEFB 40H,80H,0,0,0 ; ' DEFB 40H,80H,80H,80H,40H ; ( DEFB 40H,20H,20H,20H,40H ; ) DEFB 00H,0A0H,40H,0A0H,00H ; * DEFB 00H,40H,0E0H,40H,00H ; + DEFB 00H,00H,00H,40H,80H ; , DEFB 00H,00H,0E0H,00H,00H ; - DEFB 00H,00H,00H,00H,40H ; . DEFB 20H,20H,40H,80H,80H ; / DEFB 40H,0A0H,0A0H,0A0H,40H ; 0 DEFB 40H,40H,40H,40H,40H ; 1 DEFB 0E0H,20H,0E0H,80H,0E0H ; 2 DEFB 0E0H,20H,60H,20H,0E0H ; 3 DEFB 0A0H,0A0H,0E0H,20H,20H ; 4 DEFB 0E0H,80H,0E0H,20H,0E0H ; 5 DEFB 0E0H,80H,0E0H,0A0H,0E0H ; 6 DEFB 0E0H,20H,20H,20H,20H ; 7 DEFB 0E0H,0A0H,0E0H,0A0H,0E0H ; 8 DEFB 0E0H,0A0H,0E0H,20H,20H ; 9 DEFB 00H,40H,00H,40H,00H ; : DEFB 00H,40H,00H,40H,80H ; ; DEFB 20H,40H,80H,40H,20H ; < DEFB 00H,0E0H,00H,0E0H,00H ; = DEFB 80H,40H,20H,40H,80H ; > DEFB 0E0H,20H,60H,40H,40H ; ? DEFB 0E0H,0A0H,20H,0E0H,0E0H ; @ DEFB 40H,0A0H,0E0H,0A0H,0A0H ; A DEFB 0C0H,0A0H,0C0H,0A0H,0C0H ; B DEFB 0E0H,80H,80H,80H,0E0H ; C DEFB 0C0H,0A0H,0A0H,0A0H,0C0H ; D DEFB 0E0H,80H,0C0H,80H,0E0H ; E DEFB 0E0H,80H,0C0H,80H,80H ; F DEFB 0E0H,80H,0A0H,0A0H,0E0H ; G DEFB 0A0H,0A0H,0E0H,0A0H,0A0H ; H DEFB 40H,40H,40H,40H,40H ; I DEFB 20H,20H,20H,0A0H,0E0H ; J DEFB 0A0H,0A0H,0C0H,0A0H,0A0H ; K DEFB 80H,80H,80H,80H,0E0H ; L DEFB 0A0H,0E0H,0A0H,0A0H,0A0H ; M DEFB 80H,0E0H,0E0H,0A0H,0A0H ; N DEFB 0E0H,0A0H,0A0H,0A0H,0E0H ; O DEFB 0E0H,0A0H,0E0H,80H,80H ; P DEFB 0E0H,0A0H,0A0H,0E0H,20H ; Q DEFB 0E0H,0A0H,0C0H,0A0H,0A0H ; R DEFB 60H,80H,0E0H,20H,0C0H ; S DEFB 0E0H,40H,40H,40H,40H ; T DEFB 0A0H,0A0H,0A0H,0A0H,0E0H ; U DEFB 0A0H,0A0H,0A0H,0A0H,40H ; V DEFB 0A0H,0A0H,0A0H,0E0H,0A0H ; W DEFB 0A0H,0A0H,40H,0A0H,0A0H ; X DEFB 0A0H,0A0H,40H,40H,40H ; Y DEFB 0E0H,20H,40H,80H,0E0H ; Z DEFB '(C) 1981 A. GUEVARA' DEFB 00 ; DEFB 00 ; * NOW MATCHES MLM CART ; END OF PROGRAM