NAM SBUG18 MP-09 MONITOR OPT PAG PAG * MONITOR PROGRAM FOR THE SOUTHWEST TECHNICAL * PRODUCTS MP-09 CPU BOARD AS COMMENTED BY.... * ALLEN CLARK WALLACE WATSON * 2502 REGAL OAKS LANE 4815 EAST 97th AVE. * LUTZ, FLA. 33549 TEMPLE TERRACE, FLA. 33617 * PH. 813-977-0347 PH. 813-985-1359 * MODIFIED TO SBUG09 VER 1.8 BY: RANDY JARRETT * 2561 NANTUCKET DR APT. E * ATLANTA, GA 30345 * PH. 404-320-1043 * *** COMMANDS *** * CONTROL A = ALTER THE "A" ACCUMULATOR * CONTROL B = ALTER THE "B" ACCUMULATOR * CONTROL C = ALTER THE CONDITION CODE REGISTER * CONTROL D = ALTER THE DIRECT PAGE REGISTER * CONTROL P = ALTER THE PROGRAM COUNTER * CONTROL U = ALTER USER STACK POINTER * CONTROL X = ALTER "X" INDEX REGISTER * CONTROL Y = ALTER "Y" INDEX REGISTER * B hhhh = SET BREAKPOINT AT LOCATION $hhhh * D = BOOT A SWTPC 8 INCH FLOPPY SYSTEM * U = BOOT A SWTPC 5 INCH FLOPPY SYSTEM * E ssss-eeee = EXAMINE MEMORY FROM STARTING ADDRESS ssss * -TO ENDING ADDRESS eeee. * G = CONTINUE EXECUTION FROM BREAKPOINT OR SWI * L = LOAD TAPE * M hhhh = EXAMINE AND CHANGE MEMORY LOCATION hhhh * P ssss-eeee = PUNCH TAPE, START ssss TO END eeee ADDR. * Q ssss-eeee = TEST MEMORY FROM ssss TO eeee * R = DISPLAY REGISTER CONTENTS * S = DISPLAY STACK FROM ssss TO $DFC0 * X = REMOVE ALL BREAKPOINTS TSTPAT EQU $55AA TEST PATTERN ORG $DFC0 STACK RMB 2 ; TOP OF INTERNAL STACK / USER VECTOR SWI3 RMB 2 ; SOFTWARE INTERRUPT VECTOR #3 SWI2 RMB 2 ; SOFTWARE INTERRUPT VECTOR #2 FIRQ RMB 2 ; FAST INTERRUPT VECTOR IRQ RMB 2 ; INTERRUPT VECTOR SWI RMB 2 ; SOFTWARE INTERRUPT VECTOR SVCVO RMB 2 ; SUPERVISOR CALL VECTOR ORGIN SVCVL RMB 2 ; SUPERVISOR CALL VECTOR LIMIT LRARAM RMB 16 ; LRA ADDRESSES CPORT RMB 2 ; RE-VECTORABLE CONTROL PORT ECHO RMB 1 ; ECHO FLAG BPTBL RMB 24 ; BREAKPOINT TABLE BASE ADDR ACIAS EQU $E004 ; CONTROL PORT Comreg EQU $E018 ; COMMAND REGISTER Drvreg EQU $E014 ; DRIVE REGISTER Secreg EQU $E01A ; SECTOR REGISTER Datreg EQU $E01B ; DATA REGISTER ADDREG EQU $F000 ; ADDRESS REGISTER CNTREG EQU $F002 ; COUNT REGISTER CCREG EQU $F010 ; CHANNEL CONTROL REGISTER PRIREG EQU $F014 ; DMA PRIORITY REGISTER AAAREG EQU $F015 ; ??? BBBREG EQU $F016 ; ??? COMREG EQU $F020 ; 1791 COMMAND REGISTER SECREG EQU $F022 ; SECTOR REGISTER DRVREG EQU $F024 ; DRIVE SELECT LATCH CCCREG EQU $F040 ; ??? IC11 EQU $FFF0 ; DAT RAM CHIP ORG $F800 FDB MONITOR FDB NEXTCMD FDB INCH FDB INCHE FDB INCHEK FDB OUTCH FDB PDATA FDB PCRLF FDB PSTRNG FDB LRA * MONITOR * VECTOR ADDRESS STRING IS..... * $F8A1-$F8A1-$F8A1-$F8A1-$F8A1-$FAB0-$FFFF-$FFFF MONITOR LDX #RAMVEC ; POINT TO VECTOR ADDR. STRING LDY #STACK ; POINT TO RAM VECTOR LOCATION LDB #$10 ; BYTES TO MOVE = 16 LOOPA LDA ,X+ ; GET VECTOR BYTE STA ,Y+ ; PUT VECTORS IN RAM / $DFC0-$DFCF DECB ; SUBTRACT 1 FROM NUMBER OF BYTES TO MOVE BNE LOOPA ; CONTINUE UNTIL ALL VECTORS MOVED * CONTENTS FROM TO FUNCTION * $F8A1 $FE40 $DFC0 USER-V * $F8A1 $FE42 $DFC2 SWI3-V * $F8A1 $FE44 $DFC4 SWI2-V * $F8A1 $FE46 $DFC6 FIRQ-V * $F8A1 $FE48 $DFC8 IRQ-V * $FAB0 $FE4A $DFCA SWI-V * $FFFF $FE4C $DFCC SVC-VO * $FFFF $FE4E $DFCE SVC-VL LDX #ACIAS ; GET CONTROL PORT ADDR. STX CPORT ; STORE ADDR. IN RAM LBSR XBKPNT ; CLEAR OUTSTANDING BREAKPOINTS LDB #12 ; CLEAR 12 BYTES ON STACK CLRSTK CLR ,-S DECB BNE CLRSTK LEAX MONITOR,PCR ; SET PC TO SBUG-E ENTRY STX 10,S ; ON STACK LDA #$D0 ; PRESET CONDITION CODES ON STACK STA ,S TFR S,U LBSR ACINIZ ; INITIALIZE CONTROL PORT LDX #MSG1 ; POINT TO 'SBUG 1.8' MESSAGE LBSR PDATA ; PRINT MSG LDX #LRARAM ; POINT TO LRA RAM STORAGE AREA CLRA ; START TOTAL AT ZERO LDB #13 ; TOTAL UP ALL ACTIVE RAM MEMORY FNDREL TST B,X ; TEST FOR RAM AT NEXT LOC. BEQ RELPAS ; IF NO RAM GO TO NEXT LOC. ADDA #4 ; ELSE ADD 4K TO TOTAL DAA ; ADJ. TOTAL FOR DECIMAL RELPAS DECB ; SUB. 1 FROM LOCS. TO TEST BPL FNDREL ; PRINT TOTAL OF RAM LBSR OUT2H ; OUTPUT HEX BYTE AS ASCII LDX #MSG2 ; POINT TO MSG 'K' CR/LF + 3 NULS LBSR PDATA ; PRINT MSG ***** NEXTCMD ***** NEXTCMD LDX #MSG3 ; POINT TO MSG ">" LBSR PSTRNG ; PRINT MSG LBSR INCH ; GET ONE CHAR. FROM TERMINAL ANDA #$7F ; STRIP PARITY FROM CHAR. CMPA #$0D ; IS IT CARRIAGE RETURN ? BEQ NEXTCMD ; IF CR THEN GET ANOTHER CHAR. TFR A,B ; PUT CHAR. IN "B" ACCUM. CMPA #$20 ; IS IT CONTROL OR DATA CHAR ? BGE PRTCMD ; IF CMD CHAR IS DATA, PRNT IT LDA #'^ ; ELSE CNTRL CHAR CMD SO... LBSR OUTCH ; PRINT "^" TFR B,A ; RECALL CNTRL CMD CHAR ADDA #$40 ; CONVERT IT TO ASCII LETTER PRTCMD LBSR OUTCH ; PRNT CMD CHAR LBSR OUT1S ; PRNT SPACE CMPB #$60 BLE NXTCH0 SUBB #$20 ***** DO TABLE LOOKUP ***** * FOR COMMAND FUNCTIONS NXTCH0 LDX #JMPTAB ; POINT TO JUMP TABLE NXTCHR CMPB ,X+ ; DOES COMMAND MATCH TABLE ENTRY ? BEQ JMPCMD ; BRANCH IF MATCH FOUND LEAX 2,X ; POINT TO NEXT ENTRY IN TABLE CMPX #TABEND ; REACHED END OF TABLE YET ? BNE NXTCHR ; IF NOT END, CHECK NEXT ENTRY LDX #MSG4 ; POINT TO MSG "WHAT?" LBSR PDATA ; PRINT MSG BRA NEXTCMD ; IF NO MATCH, PRMPT FOR NEW CMD JMPCMD JSR [,X] ; JUMP TO COMMAND ROUTINE BRA NEXTCMD ; PROMPT FOR NEW COMMAND * "G" GO OR CONTINUE GO TFR U,S RTI RTI * "R" DISPLAY REGISTERS REGSTR LDX #MSG5 ; POINT TO MSG " - " LBSR PSTRNG ; PRINT MSG LBSR PRTSP ; $FCBF LBSR PRTUS ; $FCCA LBSR PRTDP ; $FCD5 LBSR PRTIX ; $FCE0 LBSR PRTIY ; $FCEB LDX #MSG5 ; POINT TO MSG " - " LBSR PSTRNG ; PRINT MSG LBSR PRTPC ; $FCF5 LBSR PRTA ; $FCFF LBSR PRTB ; $FD09 LBRA PRTCC ; $FD13 * ALTER "PC" PROGRAM COUNTER ALTRPC LBSR PRTPC ; $FCF5 PRINT MSG " PC = " LBSR OUT1S ; OUTPUT SPACE LBSR IN1ADR ; GET NEW CONTENTS FOR "PC" BVS ALTPCD ; EXIT IF INVALID HEX STX 10,U ; POKE IN NEW CONTENTS ALTPCD RTS * ALTER "U" USER STACK POINTER ALTRU LBSR PRTUS ; $FCCA PRINT MSG " US = " LBSR OUT1S ; OUTPUT SPACE LBSR IN1ADR BVS ALTUD STX 8,U ALTUD RTS * ALTER "Y" INDEX REGISTER ALTRY LBSR PRTIY ; PRINT MSG " IY = " LBSR OUT1S ; OUTPUT SPACE LBSR IN1ADR BVS ALTYD STX 6,U ; $F8F0 ALTYD RTS * ALTER "X" INDEX REGISTER ALTRX LBSR PRTIX ; $FCE0 PRINT MSG " IX = " LBSR OUT1S ; OUTPUT SPACE LBSR IN1ADR BVS ALTXD STX 4,U ALTXD RTS * ALTER "DP" DIRECT PAGE REGISTER ALTRDP LBSR PRTDP ; $FCD5 PRINT MSG " DP = " LBSR OUT1S ; OUTPUT SPACE LBSR BYTE ; INPUT BYTE (2 HEX CHAR) BVS ALTDPD STA 3,U ALTDPD RTS * ALTER "B" ACCUMULATOR ALTRB LBSR PRTB ; $FD09 PRINT MSG " B = " LBSR OUT1S ; OUTPUT SPACE LBSR BYTE ; INPUT BYTE (2 HEX CHAR) BVS ALTBD STA 2,U ALTBD RTS ; $F91C * ALTER "A" ACCUMULATOR ALTRA LBSR PRTA ; $FCFF PRINT MSG " A = " LBSR OUT1S ; OUTPUT SPACE LBSR BYTE ; INPUT BYTE (2 HEX CHAR) BVS ALTAD STA 1,U ALTAD RTS * ALTER "CC" REGISTER ALTRCC LBSR PRTCC ; $FD13 PRINT MSG " CC: " LBSR OUT1S ; OUTPUT SPACE LBSR BYTE ; INPUT BYTE (2 HEX CHAR) BVS ALTCCD ORA #$80 ; SETS "E" FLAG IN PRINT LIST STA ,U ALTCCD RTS ***** "M" MEMORY EXAMINE AND CHANGE ***** MEMCHG LBSR IN1ADR ; INPUT ADDRESS BVS CHRTN ; IF NOT HEX, RETURN TFR X,Y ; SAVE ADDR IN "Y" MEMC2 LDX #MSG5 ; POINT TO MSG " - " LBSR PSTRNG ; PRINT MSG TFR Y,X ; FETCH ADDRESS LBSR OUT4H ; PRINT ADDR IN HEX LBSR OUT1S ; OUTPUT SPACE LDA ,Y ; GET CONTENTS OF CURRENT ADDR. LBSR OUT2H ; OUTPUT CONTENTS IN ASCII LBSR OUT1S ; OUTPUT SPACE LBSR BYTE ; LOOP WAITING FOR OPERATOR INPUT BVC CHANGE ; IF VALID HEX GO CHANGE MEM. LOC. CMPA #8 ; IS IT A BACKSPACE (CNTRL H)? BEQ MEMC2 ; PROMPT OPERATOR AGAIN CMPA #$18 ; IS IT A CANCEL (CNTRL X)? BEQ MEMC2 ; PROMPT OPERATOR AGAIN CMPA #'^ ; IS IT AN UP ARROW? BEQ BACK ; DISPLAY PREVIOUS BYTE CMPA #$D ; IS IT A CR? BNE FORWRD ; DISPLAY NEXT BYTE CHRTN RTS ; EXIT ROUTINE CHANGE STA ,Y ; CHANGE BYTE IN MEMORY CMPA ,Y ; DID MEMORY BYTE CHANGE? BEQ FORWRD ; $F972 LBSR OUT1S ; OUTPUT SPACE LDA #'? ; LOAD QUESTION MARK LBSR OUTCH ; PRINT IT FORWRD LEAY 1,Y ; POINT TO NEXT HIGHER MEM LOCATION BRA MEMC2 ; PRINT LOCATION & CONTENTS BACK LEAY -1,Y ; POINT TO LAST MEM LOCATION BRA MEMC2 ; PRINT LOCATION & CONTENTS * "S" DISPLAY STACK * HEX-ASCII DISPLAY OF CURRENT STACK CONTENTS FROM * CURRENT STACK POINTER TO INTERNAL STACK LIMIT. DISSTK LBSR PRTSP ; PRINT CURRENT STACK POINTER TFR U,Y LDX #STACK ; LOAD INTERNAL STACK AS UPPER LIMIT LEAX -1,X ; POINT TO CURRENT STACK BRA MDUMP1 ; ENTER MEMORY DUMP OF STACK CONTENTS * "E" DUMP MEMORY FOR EXAMINE IN HEX AND ASCII * AFTER CALLING 'IN2ADR' LOWER ADDRESS IN Y-REG. * UPPER ADDRESS IN X-REG. * IF HEX ADDRESSES ARE INVALID (V)=1. MEMDUMP LBSR IN2ADR ; INPUT ADDRESS BOUNDRIES BVS EDPRTN ; NEW COMMAND IF ILLEGAL HEX MDUMP1 PSHS Y ; COMPARE LOWER TO UPPER BOUNDS CMPX ,S++ ; LOWER BOUNDS > UPPER BOUNDS? BCC AJDUMP ; IF NOT, DUMP HEX AND ASCII EDPRTN RTS * ADJUST LOWER AND UPPER ADDRESS LIMITS * TO EVEN 16 BYTE BOUNDRIES. * IF LOWER ADDR = $4532 * LOWER BOUNDS WILL BE ADJUSTED TO = $4530. * IF UPPER ADDR = $4567 * UPPER BOUNDS WILL BE ADJUSTED TO = $4570. * ENTER WITH LOWER ADDRESS IN X-REG. * -UPPER ADDRESS ON TOP OF STACK. AJDUMP TFR X,D ; GET UPPER ADDR IN D-REG ADDD #$10 ; ADD 16 TO UPPER ADDRESS ANDB #$F0 ; MASK TO EVEN 16 BYTE BOUNDRY PSHS A,B ; SAVE ON STACK AS UPPER DUMP LIMIT TFR Y,D ; $F9A5 GET LOWER ADDRESS IN D-REG ANDB #$F0 ; MASK TO EVEN 16 BYTE BOUNDRY TFR D,X ; PUT IN X-REG AS LOWER DUMP LIMIT NXTLIN CMPX ,S ; COMPARE LOWER TO UPPER LIMIT BEQ SKPDMP ; IF EQUAL SKIP HEX-ASCII DUMP LBSR INCHEK ; CHECK FOR INPUT FROM KEYBOARD BEQ EDUMP ; IF NONE, CONTINUE WITH DUMP SKPDMP LEAS 2,S ; READJUST STACK IF NOT DUMPING RTS * PRINT 16 HEX BYTES FOLLOWED BY 16 ASCII CHARACTERS * FOR EACH LINE THROUGHOUT ADDRESS LIMITS. EDUMP PSHS X ; PUSH LOWER ADDR LIMIT ON STACK LDX #MSG5 ; POINT TO MSG " - " LBSR PSTRNG ; PRINT MSG LDX ,S ; LOAD LOWER ADDR FROM TOP OF STACK LBSR OUT4H ; PRINT THE ADDRESS LBSR OUT2S PRINT 2 SPACES LDB #$10 ; LOAD COUNT OF 16 BYTES TO DUMP ELOOP LDA ,X+ ; GET FROM MEMORY HEX BYTE TO PRINT LBSR OUT2H ; OUTPUT HEX BYTE AS ASCII LBSR OUT1S ; OUTPUT SPACE DECB ; $F9D1 DECREMENT BYTE COUNT BNE ELOOP ; CONTINUE TIL 16 HEX BYTES PRINTED * PRINT 16 ASCII CHARACTERS * IF NOT PRINTABLE OR NOT VALID * ASCII PRINT A PERIOD (.) LBSR OUT2S ; 2 SPACES LDX ,S++ ; GET LOW LIMIT FRM STACK - ADJ STACK LDB #$10 ; SET ASCII CHAR TO PRINT = 16 EDPASC LDA ,X+ ; GET CHARACTER FROM MEMORY CMPA #$20 ; IF LESS THAN $20, NON-PRINTABLE? BCS PERIOD ; IF SO, PRINT PERIOD INSTEAD CMPA #$7E ; IS IT VALID ASCII? BLS PRASC ; IF SO PRINT IT PERIOD LDA #'. ; LOAD A PERIOD (.) PRASC LBSR OUTCH ; PRINT ASCII CHARACTER DECB ; DECREMENT COUNT BNE EDPASC BRA NXTLIN ***** "Q" MEMORY TEST ***** MEMTST CLR ,-S ; CLEAR BYTE ON STACK CLR ,-S ; CLEAR ANOTHER BYTE LBSR IN2ADR ; GET BEGIN(Y) & END(X) ADDR. LIMITS PSHS X,Y ; SAVE ADDRESSES ON STACK BVS ADJSK6 ; EXIT IF NOT VALID HEX CMPX 2,S ; COMPARE BEGIN TO END ADDR. BCS ADJSK6 ; EXIT IF BEGIN > END ADDR. LBSR OUT1S ; OUTPUT SPACE MEMSET TFR Y,D ; PUT BEGIN ADDR. IN 'D'-ACCUM. ADDD 4,S ; ADD PASS COUNT TO BEGIN ADDR PSHS B ; ADD LS BYTE TO MS BYTE OF BEGIN ADDR ADDA ,S+ STA ,Y+ ; SAVE THIS DATA BYTE AT BEGIN ADDR CMPY ,S ; COMPARE END TO BEGIN ADDR BCS MEMSET ; IF BEGIN LOWER, CONTINUE TO SET MEMORY LDY 2,S ; RELOAD BEGIN ADDRESS TEST1 TFR Y,D ; PUT BEGIN ADDR IN 'D'-ACC. ADDD 4,S ; ADD PASS COUNT TO ADDRESS PSHS A ; ADD MS BYTE TO LS BYTE OF ADDRESS ADDB ,S+ EORB ,Y+ ; EX-OR THIS DATA WITH DATA IN MEMORY LOC. BEQ GUDPAS ; IF (Z) SET, MEMORY BYTE OK LDX #MSG5 ; POINT TO MSG " - " LBSR PSTRNG ; PRINT MSG LEAX -1,Y ; GET ERROR ADDRESS IN X-REG LBSR OUT4H ; OUTPUT IT PSHS X ; PUSH ERROR ADDR ON STACK LDX #MSG8 ; POINT TO MSG " =>" LBSR PDATA ; PRINT MSG PULS X ; POP ERROR ADDR FROM STACK LBSR LRA ; GET PHYSICAL ADDR FROM LRA LBSR XASCII ; OUTPUT EXTENDED 4 BITS OF PHYSICAL ADDR LBSR OUT4H ; OUTPUT LS 16 BITS OF PHYSICAL ADDR LDX #MSG6 ; POINT TO MSG ", PASS " LBSR PDATA ; PRINT MSG LDX 4,S ; LOAD PASS COUNT LBSR OUT4H ; OUTPUT IT LDX #MSG7 ; POINT TO MSG ", BITS IN ERROR LBSR PDATA ; PRINT MSG TFR B,A ; GET ERROR BYTE INTO A-ACC LDX #MSG9 ; POINT TO MSG "76543210" LBSR BIASCI ; OUTPUT IN BINARY/ASCII FORMAT LBSR INCHEK ; CHECK FOR INPUT FROM KEYBOARD $FA56 BNE ADJSK6 ; IF SO, EXIT MEMORY TEST GUDPAS CMPY ,S ; COMPARE END ADDR TO BEGIN ADDR BCS TEST1 LDA #'+ ; GET "PASS" SYMBOL IF MEMORY PASS OK LBSR OUTCH ; OUTPUT SYMBOL TO TERMINAL LBSR INCHEK ; INPUT FROM KEYBOARD? BNE ADJSK6 ; IF SO, EXIT MEMORY TEST LDY 2,S ; LOAD BEGIN ADDRESS INC 5,S ; INCREMENT LS BYTE OF PASS COUNT BNE MEMSET ; IF NOT ZERO, SET NEXT MEMORY BYTE INC 4,S ; INCREMENT MS BYTE OF PASS COUNT BNE MEMSET ; DONE WITH 65,535 PASSES OF MEMORY? ADJSK6 LEAS 6,S ; ADJ STACK POINTER BY 6 RTS ***** "B" SET BREAKPOINT ***** BRKPNT LBSR IN1ADR ; GET BREAKPOINT ADDRESS BVS EXITBP ; EXIT IF INVALID HEX ADDR. CMPX #STACK ; ADDRESS ILLEGAL IF >=$DFC0 BCC BPERR ; IF ERROR PRINT (?), EXIT PSHS X ; $FA82 PUSH BP ADDRESS ON STACK LDX #$FFFF ; LOAD DUMMY ADDR TO TEST BP TABLE BSR BPTEST ; TEST BP TABLE FOR FREE SPACE PULS X ; POP BP ADDRESS FROM STACK BEQ BPERR ; (Z) SET, OUT OF BP TABLE SPACE LDA ,X ; GET DATA AT BREAKPOINT ADDRESS CMPA #$3F ; IS IT A SWI? BEQ BPERR ; IF SWI ALREADY, INDICATE ERROR STA ,Y+ ; SAVE DATA BYTE IN BP TABLE STX ,Y ; SAVE BP ADDRESS IN BP TABLE LDA #$3F ; LOAD A SWI ($3F) STA ,X ; SAVE SWI AT BREAKPOINT ADDRESS EXITBP RTS * INDICATE ERROR SETTING BREAKPOINT BPERR LBSR OUT1S ; OUTPUT SPACE LDA #'? ; LOAD (?), INDICATE BREAKPOINT ERROR LBRA OUTCH ; PRINT "?" *** "X" CLEAR OUTSTANDING BREAKPOINTS *** XBKPNT LDY #BPTBL ; POINT TO BREAKPOINT TABLE LDB #8 ; LOAD BREAKPOINT COUNTER XBPLP BSR RPLSWI ; REMOVE USED ENTRY IN BP TABLE DECB ; $FAAC DECREMENT BP COUNTER BNE XBPLP ; END OF BREAKPOINT TABLE? RTS ***** SWI ENTRY POINT ***** SWIE TFR S,U ; TRANSFER STACK TO USER POINTER LDX 10,U ; LOAD PC FROM STACK INTO X-REG LEAX -1,X ; ADJUST ADDR DOWN 1 BYTE. BSR BPTEST ; FIND BREAKPOINT IN BP TABLE BEQ REGPR ; IF FOUND, REPLACE DATA AT BP ADDR STX 10,U ; SAVE BREAKPOINT ADDR IN STACK BSR RPLSWI ; GO REPLACE SWI WITH ORIGINAL DATA REGPR LBSR REGSTR ; GO PRINT REGISTERS LBRA NEXTCMD ; GET NEXT COMMAND RPLSWI LDX 1,Y ; LOAD BP ADDRESS FROM BP TABLE CMPX #STACK ; COMPARE TO TOP AVAILABLE USER MEMORY BCC FFSTBL ; GO RESET TABLE ENTRY TO $FF'S LDA ,X ; GET DATA FROM BP ADDRESS CMPA #$3F ; IS IT SWI? BNE FFSTBL ; IF NOT, RESET TABLE ENTRY TO $FF'S LDA ,Y ; GET ORIGINAL DATA FROM BP TABLE STA ,X ; $FAD3 RESTORE DATA AT BP ADDRESS FFSTBL LDA #$FF ; LOAD $FF IN A-ACC STA ,Y+ ; RESET BREAKPOINT TABLE DATA TO $FF'S STA ,Y+ ; RESET BREAKPOINT TABLE ADDR TO $FF'S STA ,Y+ RTS ** SEARCH BREAKPOINT TABLE FOR MATCH ** BPTEST LDY #BPTBL ; POINT TO BREAKPOINT TABLE LDB #8 ; LOAD BREAKPOINT COUNTER FNDBP LDA ,Y+ ; LOAD DATA BYTE CMPX ,Y++ ; COMPARE ADDRESS, IS IT SAME? BEQ BPADJ ; IF SO, ADJUST POINTER FOR TABLE ENTRY DECB ; IF NOT, DECREMENT BREAKPOINT COUNTER BNE FNDBP ; AND LOOK FOR NEXT POSSIBLE MATCH RTS BPADJ LEAY -3,Y ; MOVE POINTER TO BEGIN OF BP ENTRY RTS *** "D" DISK BOOT FOR DMAF2 *** DBOOT LDA #$DE STA DRVREG LDA #$FF STA PRIREG ; $FAF8 STA CCREG STA AAAREG STA BBBREG TST CCREG LDA #$D8 STA COMREG LBSR DLY DBOOT0 LDA COMREG BMI DBOOT0 LDA #$09 STA COMREG LBSR DLY DISKWT LDA COMREG ; FETCH DRIVE STATUS BITA #1 ; TEST BUSY BIT BNE DISKWT ; LOOP UNTIL NOT BUSY BITA #$10 BNE DBOOT LDX #$C000 ; LOGICAL ADDR. = $C000 BSR LRA ; GET 20 BIT PHYSICAL ADDR. OF LOG. ADDR. ORA #$10 STA CCCREG TFR X,D COMA COMB STD ADDREG LDX #$FEFF ; LOAD DMA BYTE COUNT = $100 STX CNTREG ; STORE IN COUNT REGISTER LDA #$FF ; LOAD THE CHANNEL REGISTER STA CCREG LDA #$FE ; SET CHANNEL 0 STA PRIREG LDA #1 ; SET SECTOR TO "1" STA SECREG ; ISSUE COMMAND LDA #$8C ; SET SINGLE SECTOR READ STA COMREG ; ISSUE COMMAND BSR DLY * THE FOLLOWING CODE TESTS THE STATUS OF THE * CHANNEL CONTROL REGISTER. IF "D7" IS NOT * ZERO THEN IT WILL LOOP WAITING FOR "D7" * TO GO TO ZERO. IF AFTER 65,536 TRIES IT * IS STILL A ONE THE BOOT OPERATION WILL * BE STARTED OVER FROM THE BEGINING. CLRB DBOOT1 PSHS B ; $FB55 CLRB DBOOT2 TST CCREG BPL DBOOT3 DECB BNE DBOOT2 PULS B DECB BNE DBOOT1 BRA DBOOT DBOOT3 PULS B LDA COMREG BITA #$1C BEQ DBOOT4 RTS DBOOT4 LDB #$DE STB DRVREG LDX #$C000 STX 10,U TFR U,S ; $FB7B RTI ***** LRA LOAD REAL ADDRESS ***** * THE FOLLOWING CODE LOADS THE 20-BIT * PHYSICAL ADDRESS OF A MEMORY BYTE * INTO THE "A" AND "X" REGISTERS. THIS * ROUTINE IS ENTERED WITH THE LOGICAL * ADDRESS OF A MEMORY BYTE IN THE "IX" * REGISTER. EXIT IS MADE WITH THE HIGH- * ORDER FOUR BITS OF THE 20-BIT PHYSICAL * ADDRESS IN THE "A" REGISTER, AND THE * LOW-ORDER 16-BITS OF THE 20-BIT * PHYSICAL ADDRESS IN THE "IX" REGISTER. * ALL OTHER REGISTERS ARE PRESERVED. * THIS ROUTINE IS REQUIRED SINCE THE * DMAF1 AND DMAF2 DISK CONTROLLERS MUST * PRESENT PHYSICAL ADDRESSES ON THE * SYSTEM BUS. LRA PSHS A,B,X,Y ; PUSH REGISTERS ON STACK LDA 2,S ; GET MSB LOGICAL ADDR FRM X REG ON STACK LSRA LSRA ; ADJ FOR INDEXED INTO LSRA ; CORRESPONDING LOCATION LSRA ; IN LRA TABLE LDY #LRARAM ; LOAD LRA TABLE BASE ADDRESS LDB A,Y ; GET PHYSICAL ADDR. DATA FROM LRA TABLE LSRB ; ADJ. REAL ADDR. TO REFLECT EXTENDED LSRB ; PHYSICAL ADDRESS. LSRB ; EXTENDED MS 4-BITS ARE RETURNED LSRB ; IN THE "A" ACCUMULATOR STB ,S ; MS 4 BITS IN A ACCUM. STORED ON STACK LDB A,Y ; LOAD REAL ADDRESS DATA FROM LRA TABLE COMB ; COMP TO ADJ FOR PHYSICAL ADDR. IN X REG ASLB ; ADJ DATA FOR RELOCATION IN X REG ASLB ASLB ; $FB97 ASLB LDA 2,S ; GET MS BYTE OF LOGICAL ADDR. ANDA #$0F ; MASK MS NIBBLE OF LOGICAL ADDRESS STA 2,S ; SAVE IT IN X REG ON STACK ORB 2,S ; SET MS BYTE IN X REG TO ADJ PHY ADDR. * PLUS LS NIBBLE OF LOGICAL ADDRESS STB 2,S ; SAVE AS LS 16 BITS OF PHY ADDR IN X REG * ON STACK PULS A,B,X,Y ; POP REGS. FROM STACK RTS * DELAY LOOP DLY PSHS B ; SAVE CONTENTS OF "B" LDB #$20 ; GET LOOP DELAY VALUE SUB1 DECB ; SUBTRACT ONE FROM VALUE BNE SUB1 ; LOOP UNTIL ZERO PULS B ; RESTORE CONTENTS OF "B" RTS ***** "U" MINIDISK BOOT ***** MINBOOT TST Comreg CLR Drvreg ; SELECT DRIVE 0 * DELAY BEFORE ISSUING RESTORE COMMAND LDB #3 LDX #0 LOOP LEAX 1,X ; $FBBB CMPX #0 BNE LOOP DECB ; $FBC2 BNE LOOP LDA #$0F ; *LOAD HEAD, VERIFY, 20msec/step STA Comreg ; ISSUE RESTORE COMMAND BSR DELAY LOOP1 LDB Comreg ; $FBCC BITB #1 BNE LOOP1 ; LOOP UNTIL THRU LDA #1 STA Secreg ; SET SECTOR REGISTER TO ONE BSR DELAY LDA #$8C ; LOAD HEAD, DELAY 10msec, STA Comreg ; AND READ SINGLE RECORD BSR DELAY LDX #$C000 BRA LOOP3 LOOP2 BITB #2 ; $FBE6 DRQ? BEQ LOOP3 LDA Datreg STA ,X+ LOOP3 LDB Comreg ; FETCH STATUS BITB #1 ; BUSY? BNE LOOP2 BITB #$2C ; CRC ERROR OR LOST DATA? BEQ LOOP4 RTS LOOP4 LDX #$C000 ; $FBFB STX 10,U TFR U,S RTI * DELAY DELAY LDB #$20 LOOP5 DECB BNE LOOP5 RTS ***** "L" LOAD MIKBUG TAPE ***** LOAD LDA #$11 ; LOAD 'DC1' CASS. READ ON CODE LBSR OUTCH ; OUTPUT IT TO TERMINAL PORT CLR ECHO ; TURN OFF ECHO FLAG LOAD1 LBSR ECHON ; INPUT 8 BIT BYTE WITH NO ECHO LOAD2 CMPA #'S ; IS IT AN "S", START CHARACTER ? BNE LOAD1 ; IF NOT, DISCARD AND GET NEXT CHAR. LBSR ECHON CMPA #'9 ; IS IT A "9" , END OF FILE CHAR ? BEQ LOAD21 ; IF SO, EXIT LOAD CMPA #'1 ; IS IT A "1" , FILE LOAD CHAR ? BNE LOAD2 ; IF NOT, LOOK FOR START CHAR. LBSR BYTE ; INPUT BYTE COUNT PSHS A ; PUSH COUNT ON STACK BVS LODERR ; (V) C-CODE SET, ILLEGAL HEX LBSR IN1ADR ; INPUT LOAD ADDRESS BVS LODERR ; (V) C-CODE SET, ADDR NOT HEX PSHS X ; PUSH ADDR ON STACK LDB ,S+ ; LOAD MSB OF ADDR AS CHECKSUM BYTE ADDB ,S+ ; ADD LSB OF ADDR TO CHECKSUM ADDB ,S ; ADD BYTE COUNT BYTE TO CHECKSUM DEC ,S ; $FC37 DECREMENT BYTE COUNT 2 TO BYPASS DEC ,S ; ADDRESS BYTES. LOAD10 PSHS B ; PUSH CHECKSUM ON STACK LBSR BYTE ; INPUT DATA BYTE (2 HEX CHAR) PULS B ; POP CHECKSUM FROM STACK BVS LODERR ; (V) SET, DATA BYTE NOT HEX PSHS A ; PUSH DATA BYTE ON STACK ADDB ,S+ ; ADD DATA TO CHECKSUM, AUTO INC STACK DEC ,S ; DECREMENT BYTE COUNT 1 BEQ LOAD16 ; IF BYTE COUNT ZERO, TEST CHECKSUM STA ,X+ ; SAVE DATA BYTE IN MEMORY BRA LOAD10 ; GET NEXT DATA BYTE LODERR CLRB ; ERROR CONDITION, ZERO CHECKSUM LOAD16 PULS A ; ADJUST STACK (REMOVE BYTE COUNT) CMPB #$FF ; CHECKSUM OK? BEQ LOAD ; IF SO, LOAD NEXT LINE LDA #'? ; LOAD (?) ERROR INDICATOR LBSR OUTCH ; OUTPUT IT TO TERMINAL LOAD21 COM ECHO ; TURN ECHO ON LDA #$13 ; $FC5F LOAD 'DC3' CASS. READ OFF CODE LBRA OUTCH ; OUTPUT IT ***** "P" PUNCH MIKBUG TAPE ***** PUNCH CLR ,-S ; CLEAR RESERVED BYTE ON STACK LBSR IN2ADR ; GET BEGIN AND END ADDRESS PSHS X,Y ; SAVE ADDRESSES ON STACK BVS PUNEXT ; (V) C-CODE SET, EXIT PUNCH CMPX 2,S ; COMPARE BEGIN TO END ADDR BCS PUNEXT ; IF BEGIN GREATER THAN END, EXIT PUNCH LEAX 1,X ; INCREMENT END ADDRESS STX ,S ; STORE END ADDR ON STACK LDA #$12 ; LOAD 'DC2' PUNCH ON CODE LBSR OUTCH ; OUTPUT IT TO TERMINAL PUNCH2 LDD ,S ; LOAD END ADDR IN D-ACC SUBD 2,S ; SUBTRACT BEGIN FROM END BEQ PUNCH3 ; SAME, PUNCH 32 BYTES DEFAULT CMPD #$20 ; LESS THAN 32 BYTES? BLS PUNCH4 ; PUNCH THAT MANY BYTES PUNCH3 LDB #$20 ; LOAD BYTE COUNT OF 32. PUNCH4 STB 4,S ; STORE ON STACK AS BYTE COUNT LDX #MSG20 ; POINT TO MSG "S1" LBSR PSTRNG ; PRINT MSG ADDB #3 ; ADD 3 BYTES TO BYTE COUNT TFR B,A ; GET BYTE COUNT IN A-ACC TO PUNCH LBSR OUT2H ; OUTPUT BYTE COUNT LDX 2,S ; LOAD BEGIN ADDRESS LBSR OUT4H ; PUNCH ADDRESS ADDB 2,S ; ADD ADDR MSB TO CHECKSUM ADDB 3,S ; ADD ADDR LSB TO CHECKSUM PUNCHL ADDB ,X ; ADD DATA BYTE TO CHECKSUM LDA ,X+ ; LOAD DATA BYTE TO PUNCH LBSR OUT2H ; OUTPUT DATA BYTE DEC 4,S ; DECREMENT BYTE COUNT BNE PUNCHL ; NOT DONE, PUNCH NEXT BYTE COMB 1's ; COMPLIMENT CHECKSUM BYTE TFR B,A ; GET IT IN A-ACC TO PUNCH LBSR OUT2H ; OUTPUT CHECKSUM BYTE STX 2,S ; SAVE X-REG IN STACK AS NEW PUNCH ADDR CMPX ,S ; COMPARE IT TO END ADDR BNE PUNCH2 ; $FCB5 PUNCH NOT DONE, CONT. PUNEXT LDA #$14 ; LOAD 'DC4' PUNCH OFF CODE LBSR OUTCH ; OUTPUT IT LEAS 5,S ; READJUST STACK POINTER RTS PRTSP LDX #MSG10 ; POINT TO MSG "SP=" LBSR PDATA ; PRINT MSG TFR U,X LBRA OUT4H PRTUS LDX #MSG12 ; POINT TO MSG "US=" LBSR PDATA ; PRINT MSG LDX 8,U LBRA OUT4H PRTDP LDX #MSG15 ; POINT TO MSG "DP=" LBSR PDATA ; PRINT MSG LDA 3,U LBRA OUT2H ; OUTPUT HEX BYTE AS ASCII PRTIX LDX #MSG14 ; POINT TO MSG "IX=" LBSR PDATA ; PRINT MSG LDX 4,U ; $FCE6 LBRA OUT4H PRTIY LDX #MSG13 ; POINT TO MSG "IY=" LBSR PDATA ; PRINT MSG LDX 6,U LBRA OUT4H PRTPC LDX #MSG11 ; POINT TO MSG "PC=" LBSR PDATA ; PRINT MSG LDX 10,U BRA OUT4H PRTA LDX #MSG16 ; POINT TO MSG "A=" LBSR PDATA ; PRINT MSG LDA 1,U BRA OUT2H ; OUTPUT HEX BYTE AS ASCII PRTB LDX #MSG17 ; POINT TO MSG "B=" LBSR PDATA ; PRINT MSG LDA 2,U BRA OUT2H ; OUTPUT HEX BYTE AS ASCII PRTCC LDX #MSG18 ; POINT TO MSG "CC:" LBSR PDATA ; PRINT MSG LDA ,U LDX #MSG19 ; POINT TO MSG "EFHINZVC" BRA BIASCI ; OUTPUT IN BINARY/ASCII FORMAT * THE FOLLOWING ROUTINE LOOPS WAITING FOR THE * OPERATOR TO INPUT TWO VALID HEX ADDRESSES. * THE FIRST ADDRESS INPUT IS RETURNED IN "IY". * THE SECOND IS RETURNED IN "IX". THE "V" BIT * IN THE C-CODE REG. IS SET IF AN INVALID HEX * ADDRESS IS INPUT. IN2ADR BSR IN1ADR ; GET FIRST ADDRESS BVS NOTHEX ; EXIT IF NOT VALID HEX TFR X,Y ; SAVE FIRST ADDR. IN "IY" LDA #'- LBSR OUTCH ; PRINT " - " * THE FOLLOWING ROUTINE LOOPS WAITING FOR THE * OPERATOR TO INPUT ONE VALID HEX ADDRESS. THE * ADDRESS IS RETURNED IN THE "X" REGISTER. IN1ADR BSR BYTE ; INPUT BYTE (2 HEX CHAR) BVS NOTHEX ; EXIT IF NOT VALID HEX TFR D,X BSR BYTE ; INPUT BYTE (2 HEX CHAR) BVS NOTHEX PSHS X STA 1,S PULS X RTS ***** INPUT BYTE (2 HEX CHAR.) ***** BYTE BSR INHEX ; GET HEX LEFT BVS NOTHEX ; EXIT IF NOT VALID HEX ASLA ASLA ASLA ; SHIFT INTO LEFT NIBBLE ASLA TFR A,B ; PUT HEXL IN "B" BSR INHEX ; GET HEX RIGHT BVS NOTHEX ; EXIT IF NOT VALID HEX PSHS B ; PUSH HEXL ON STACK ADDA ,S+ ; ADD HEXL TO HEXR AND ADJ. STK RTS ; RETURN WITH HEX L&R IN "A" INHEX BSR ECHON ; INPUT ASCII CHAR. CMPA #'0 ; IS IT > OR = "0" ? BCS NOTHEX ; IF LESS IT AIN'T HEX CMPA #'9 ; IS IT < OR = "9" ? BHI INHEXA ; IF > MAYBE IT'S ALPHA SUBA #$30 ; ASCII ADJ. NUMERIC RTS INHEXA CMPA #'A ; IS IT > OR = "A" BCS NOTHEX ; IF LESS IT AIN'T HEX CMPA #'F ; IS IT < OR = "F" ? BHI INHEXL ; IF > IT AIN'T HEX SUBA #$37 ; ASCII ADJ. ALPHA RTS INHEXL CMPA #'a ; IS IT > OR = "a" BCS NOTHEX ; IF LESS IT AIN'T HEX CMPA #'f ; IS IT < "f" BHI NOTHEX ; IF > IT AIN'T HEX SUBA #$57 ; ADJUST TO LOWER CASE RTS NOTHEX ORCC #2 ; SET (V) FLAG IN C-CODES REGISTER RTS OUT4H PSHS X ; PUSH X-REG. ON THE STACK PULS A ; POP MS BYTE OF X-REG INTO A-ACC. BSR OUTHL ; OUTPUT HEX LEFT PULS A ; POP LS BYTE OF X-REG INTO A-ACC. OUTHL EQU * OUT2H PSHS A ; SAVE IT BACK ON STACK LSRA ; CONVERT UPPER HEX NIBBLE TO ASCII LSRA LSRA LSRA BSR XASCII ; PRINT HEX NIBBLE AS ASCII OUTHR PULS A ; CONVERT LOWER HEX NIBBLE TO ASCII ANDA #$0F ; STRIP LEFT NIBBLE XASCII ADDA #$30 ; ASCII ADJ CMPA #$39 ; IS IT < OR = "9" ? BLE OUTC ; IF LESS, OUTPUT IT ADDA #7 ; IF > MAKE ASCII LETTER OUTC BRA OUTCH ; OUTPUT CHAR * BINARY / ASCII --- THIS ROUTINE * OUTPUTS A BYTE IN ENHANCED * BINARY FORMAT. THE ENHANCEMENT * IS DONE BY SUBSTITUTING ASCII * LETTERS FOR THE ONES IN THE BYTE. * THE ASCII ENHANCEMENT LETTERS * ARE OBTAINED FROM THE STRING * POINTED TO BY THE INDEX REG. "X". BIASCI PSHS A ; SAVE "A" ON STACK LDB #8 ; PRESET LOOP# TO BITS PER BYTE OUTBA LDA ,X+ ; GET LETTER FROM STRING ASL ,S ; TEST BYTE FOR "1" IN B7 BCS PRTBA ; IF ONE PRINT LETTER LDA #'- ; IF ZERO PRINT "-" PRTBA BSR OUTCH ; PRINT IT BSR OUT1S ; PRINT SPACE DECB ; SUB 1 FROM #BITS YET TO PRINT BNE OUTBA PULS A RTS * PRINT STRING PRECEEDED BY A CR & LF. PSTRNG BSR PCRLF ; PRINT CR/LF BRA PDATA ; PRINT STRING POINTED TO BY IX * PCRLF PCRLF PSHS X ; SAVE IX LDX #MSG2+1 ; POINT TO MSG CR/LF + 3 NULS BSR PDATA ; PRINT MSG PULS X ; RESTORE IX RTS PRINT BSR OUTCH * PDATA PDATA LDA ,X+ ; GET 1st CHAR. TO PRINT CMPA #4 ; IS IT EOT? BNE PRINT ; IF NOT EOT PRINT IT RTS ECHON TST ECHO ; IS ECHO REQUIRED ? BEQ INCH ; ECHO NOT REQ. IF CLEAR * INCHE * ---GETS CHARACTER FROM TERMINAL AND * ECHOS SAME. THE CHARACTER IS RETURNED * IN THE "A" ACCUMULATOR WITH THE PARITY * BIT MASKED OFF. ALL OTHER REGISTERS * ARE PRESERVED. INCHE BSR INCH ; GET CHAR FROM TERMINAL ANDA #$7F ; STRIP PARITY FROM CHAR. BRA OUTCH ; ECHO CHAR TO TERMINAL * INCH * GET CHARACTER FROM TERMINAL. RETURN * CHARACTER IN "A" ACCUMULATOR AND PRESERVE * ALL OTHER REGISTERS. THE INPUT CHARACTER * IS 8 BITS AND IS NOT ECHOED. INCH PSHS X ; SAVE IX LDX CPORT ; POINT TO TERMINAL PORT GETSTA LDA ,X ; FETCH PORT STATUS BITA #1 ; TEST READY BIT, RDRF ? BEQ GETSTA ; IF NOT RDY, THEN TRY AGAIN LDA 1,X ; FETCH CHAR PULS X ; RESTORE IX RTS * INCHEK * CHECK FOR A CHARACTER AVAILABLE FROM * THE TERMINAL. THE SERIAL PORT IS CHECKED * FOR READ READY. ALL REGISTERS ARE * PRESERVED, AND THE "Z" BIT WILL BE * CLEAR IF A CHARACTER CAN BE READ. INCHEK PSHS A ; SAVE A ACCUM. LDA [CPORT] ; FETCH PORT STATUS BITA #1 ; TEST READY BIT, RDRF ? PULS A ; RESTORE A ACCUM. RTS OUT2S BSR OUT1S ; OUTPUT 2 SPACES OUT1S LDA #$20 ; OUTPUT 1 SPACE * OUTCH * OUTPUT CHARACTER TO TERMINAL. * THE CHAR. TO BE OUTPUT IS * PASSED IN THE A REGISTER. * ALL REGISTERS ARE PRESERVED. OUTCH PSHS A,X ; SAVE A ACCUM AND IX LDX CPORT ; GET ADDR. OF TERMINAL FETSTA LDA ,X ; FETCH PORT STATUS BITA #2 ; TEST TDRE, OK TO XMIT ? BEQ FETSTA ; IF NOT LOOP UNTIL RDY PULS A ; GET CHAR. FOR XMIT STA 1,X ; XMIT CHAR. PULS X ; RESTORE IX RTS ACINIZ LDX CPORT ; POINT TO CONTROL PORT ADDRESS LDA #3 ; RESET ACIA PORT CODE STA ,X ; STORE IN CONTROL REGISTER LDA #$11 ; SET 8 DATA, 2 STOP AN 0 PARITY STA ,X ; STORE IN CONTROL REGISTER TST 1,X ; ANYTHING IN DATA REGISTER? LDA #$FF ; TURN ON ECHO FLAG STA ECHO RTS * MONITOR KEYBOARD COMMAND JUMP TABLE JMPTAB EQU * FCB 1 ; "^A" $F91D FDB ALTRA FCB 2 ; "^B" $F90F FDB ALTRB FCB 3 ; "^C" $F92B FDB ALTRCC FCB 4 ; "^D" $F901 FDB ALTRDP FCB $10 ; "^P" $F8C9 FDB ALTRPC FCB $15 ; "^U" $F8D7 FDB ALTRU FCB $18 ; "^X" $F8F3 FDB ALTRX FCB $19 ; "^Y" $F8E5 FDB ALTRY FCC 'B' FDB BRKPNT ; *$FA78 FCC 'D' FDB DBOOT ; *$FAF1 FCC 'E' FDB MEMDUMP ; *$F990 FCC 'G' FDB GO ; *$F89F FCC 'L' FDB LOAD ; *$FC09 FCC 'M' FDB MEMCHG ; *$F93B FCC 'P' FDB PUNCH ; *$FC64 FCC 'Q' FDB MEMTST ; *$F9EF FCC 'R' FDB REGSTR ; *$F8A2 FCC 'S' FDB DISSTK ; *$F984 FCC 'U' FDB MINBOOT ; *$FBB0 FCC 'X' FDB XBKPNT ; *$FAA4 TABEND EQU * * ** 6809 VECTOR ADDRESSES ** * FOLLOWING ARE THE ADDRESSES OF THE VECTOR ROUTINES * FOR THE 6809 PROCESSOR. DURING INITIALIZATION THEY * ARE COPIED TO RAM FROM $DFC0 TO $DFCF. THEY ARE * REDORECTED TO RAM SO THAT THE USER MAY REVECTOR TO * HIS OWN ROUTINES IF HE SO DESIRES. RAMVEC FDB SWIE ; USER-V FDB RTI ; SWI3-V FDB RTI ; SWI2-V FDB RTI ; FIRQ-V FDB RTI ; IRQ-V FDB SWIE ; SWI-V FDB $FFFF ; SVC-VO FDB $FFFF ; SVC-VL * PRINTABLE MESSAGE STRINGS MSG1 FCB $0,$0,$0,$D,$A,$0,$0,$0 ; 0, CR/LF, 0 FCC 'S-BUG 1.8 - ' FCB 4 MSG2 FCB 'K,$D,$A,$0,$0,$0,4 ; K, CR/LF + 3 NULS MSG3 FCC '>' FCB 4 MSG4 FCC 'WHAT?' FCB 4 MSG5 FCC ' - ' FCB 4 MSG6 FCC ', PASS ' FCB 4 MSG7 FCC ', BITS IN ERROR: ' FCB 4 MSG8 FCC ' => ' FCB 4 MSG9 FCC '76543210' MSG10 FCC ' SP=' FCB 4 MSG11 FCC ' PC=' FCB 4 MSG12 FCC ' US=' FCB 4 MSG13 FCC ' IY=' FCB 4 MSG14 FCC ' IX=' FCB 4 MSG15 FCC ' DP=' FCB 4 MSG16 FCC ' A=' FCB 4 MSG17 FCC ' B=' FCB 4 MSG18 FCC ' CC: ' FCB 4 MSG19 FCC 'EFHINZVC' MSG20 FCC 'S1' FCB 4 * MESSAGE EXPANSION AREA FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF FCB $FF,$FF,$FF,$FF,$FF,$FF,$FF * POWER UP/ RESET/ NMI ENTRY POINT ORG $FF00 START LDX #IC11 ; POINT TO DAT RAM IC11 LDA #$F ; GET COMPLIMENT OF ZERO * INITIALIZE DAT RAM --- LOADS $F-$0 IN LOCATIONS $0-$F * OF DAT RAM, THUS STORING COMPLEMENT OF MSB OF ADDRESS * IN THE DAT RAM. THE COMPLEMENT IS REQUIRED BECAUSE THE * OUTPUT OF IC11, A 74S189, IS THE INVERSE OF THE DATA * STORED IN IT. DATLP STA ,X+ ; STORE & POINT TO NEXT RAM LOCATION DECA ; GET COMP. VALUE FOR NEXT LOCATION BNE DATLP ; FIRST 15 LOCATIONS INITIALIZED ? * NOTE: IX NOW CONTAINS $FFFF, DAT RAM IS NO LONGER * ADDRESSED, AND LOGICAL ADDRESSES NOW EQUAL * PHYSICAL ADDRESSES. LDA #$F0 STA ,X ; STORE $F0 AT $FFFF LDX #$D0A0 ; ASSUME RAM TO BE AT $D000-$DFFF LDY #TSTPAT ; LOAD TEST DATA PATTERN INTO "Y" TSTRAM LDU ,X ; SAVE DATA FROM TEST LOCATION STY ,X ; STORE TEST PATTERN AT $D0A0 CMPY ,X ; IS THERE RAM AT THIS LOCATION ? BEQ CNVADR ; IF MATCH THERE'S RAM, SO SKIP LEAX -$1000,X ; ELSE POINT 4K LOWER CMPX #$F0A0 ; DECREMENTED PAST ZER0 YET ? BNE TSTRAM ; IF NOT CONTINUE TESTING FOR RAM BRA START ; ELSE START ALL OVER AGAIN * THE FOLLOWING CODE STORES THE COMPLEMENT OF * THE MS CHARACTER OF THE FOUR CHARACTER HEX * ADDRESS OF THE FIRST 4K BLOCK OF RAM LOCATED * BY THE ROUTINE "TSTRAM" INTO THE DAT RAM. IT * IS STORED IN RAM IN THE LOCATION THAT IS * ADDRESSED WHEN THE PROCESSOR ADDRESS IS $D---, * THUS IF THE FIRST 4K BLOCK OF RAM IS FOUND * WHEN TESTING LOCATION $70A0, MEANING THERE * IS NO RAM PHYSICALLY ADDRESSED IN THE RANGE * $8000-$DFFF, THEN THE COMPLEMENT OF THE * "7" IN THE $70A0 WILL BE STORED IN * THE DAT RAM. THUS WHEN THE PROCESSOR OUTPUTS * AN ADDRESS OF $D---, THE DAT RAM WILL RESPOND * BY RECOMPLEMENTING THE "7" AND OUTPUTTING THE * 7 ONTO THE A12-A15 ADDRESS LINES. THUS THE * RAM THAT IS PHYSICALLY ADDRESSED AT $7--- * WILL RESPOND AND APPEAR TO THE 6809 THAT IT * IS AT $D--- SINCE THAT IS THE ADDRESS THE * 6809 WILL BE OUTPUTING WHEN THAT 4K BLOCK * OF RAM RESPONDS. CNVADR STU ,X ; RESTORE DATA AT TEST LOCATION TFR X,D ; PUT ADDR. OF PRESENT 4K BLOCK IN D COMA ; COMPLEMENT MSB OF THAT ADDRESS LSRA ; PUT MS 4 BITS OF ADDRESS IN LSRA ; LOCATION D0-D3 TO ALLOW STORING LSRA ; IT IN THE DYNAMIC ADDRESS LSRA ; TRANSLATION RAM. STA $FFFD ; STORE XLATION FACTOR IN DAT "D" LDS #STACK ; INITIALIZE STACK POINTER * THE FOLLOWING CHECKS TO FIND THE REAL PHYSICAL ADDRESSES * OF ALL 4K BLKS OF RAM IN THE SYSTEM. WHEN EACH 4K BLK * OF RAM IS LOCATED, THE COMPLEMENT OF IT'S REAL ADDRESS * IS THEN STORED IN A "LOGICAL" TO "REAL" ADDRESS XLATION * TABLE THAT IS BUILT FROM $DFD0 TO $DFDF. FOR EXAMPLE IF * THE SYSTEM HAS RAM THAT IS PHYSICALLY LOCATED (WIRED TO * RESPOND) AT THE HEX LOCATIONS $0--- THRU $F---.... * 0 1 2 3 4 5 6 7 8 9 A B C D E F * 4K 4K 4K 4K 4K 4K 4K 4K -- 4K 4K 4K 4K -- -- -- * ....FOR A TOTAL OF 48K OF RAM, THEN THE TRANSLATION TABLE * CREATED FROM $DFD0 TO $DFDF WILL CONSIST OF THE FOLLOWING.... * 0 1 2 3 4 5 6 7 8 9 A B C D E F * 0F 0E 0D 0C 0B 0A 09 08 06 05 00 00 04 03 F1 F0 * HERE WE SEE THE LOGICAL ADDRESSES OF MEMORY FROM $0000-$7FFF * HAVE NOT BEEN SELECTED FOR RELOCATION SO THAT THEIR PHYSICAL * ADDRESS WILL = THEIR LOGICAL ADDRESS; HOWEVER, THE 4K BLOCK * PHYSICALLY AT $9000 WILL HAVE ITS ADDRESS TRANSLATED SO THAT * IT WILL LOGICALLY RESPOND AT $8000. LIKEWISE $A,$B, AND $C000 * WILL BE TRANSLATED TO RESPOND TO $9000,$C000, AND $D000 * RESPECTIVELY. THE USER SYSTEM WILL LOGICALLY APPEAR TO HAVE * MEMORY ADDRESSED AS FOLLOWS.... * 0 1 2 3 4 5 6 7 8 9 A B C D E F * 4K 4K 4K 4K 4K 4K 4K 4K 4K 4K -- -- 4K 4K -- -- LDY #LRARAM ; POINT TO LOGICAL/REAL ADDR. TABLE STA 13,Y ; STORE $D--- XLATION FACTOR AT $DFDD CLR 14,Y ; CLEAR $DFDE LDA #$F0 ; DESTINED FOR IC8 AND MEM EXPANSION ? STA 15,Y ; STORE AT $DFDF LDA #$0C ; PRESET NUMBER OF BYTES TO CLEAR CLRLRT CLR A,Y ; CLEAR $DFDC THRU $DFD0 DECA SUB. 1 ; FROM BYTES LEFT TO CLEAR BPL CLRLRT ; CONTINUE IF NOT DONE CLEARING FNDRAM LEAX -$1000,X ; POINT TO NEXT LOWER 4K OF RAM CMPX #$F0A0 ; TEST FOR DECREMENT PAST ZERO BEQ FINTAB ; SKIP IF FINISHED LDU ,X ; SAVE DATA AT CURRENT TEST LOCATION LDY #TSTPAT ; LOAD TEST DATA PATTERN INTO Y REG. STY ,X ; STORE TEST PATT. INTO RAM TEST LOC. CMPY ,X ; VERIFY RAM AT TEST LOCATION BNE FNDRAM ; IF NO RAM GO LOOK 4K LOWER STU ,X ; ELSE RESTORE DATA TO TEST LOCATION LDY #LRARAM ; POINT TO LOGICAL/REAL ADDR. TABLE TFR X,D ; PUT ADDR. OF PRESENT 4K BLOCK IN D LSRA ; PUT MS 4 BITS OF ADDR. IN LOC. D0-D3 LSRA ; TO ALLOW STORING IT IN THE DAT RAM. LSRA LSRA TFR A,B ; SAVE OFFSET INTO LRARAM TABLE EORA #$0F ; INVERT MSB OF ADDR. OF CURRENT 4K BLK STA B,Y ; SAVE TRANSLATION FACTOR IN LRARAM TABLE BRA FNDRAM ; GO TRANSLATE ADDR. OF NEXT 4K BLK FINTAB LDA #$F1 ; DESTINED FOR IC8 AND MEM EXPANSION ? LDY #LRARAM ; POINT TO LRARAM TABLE STA 14,Y ; STORE $F1 AT $DFCE * THE FOLLOWING CHECKS TO SEE IF THERE IS A 4K BLK OF * RAM LOCATED AT $C000-$CFFF. IF NONE THERE IT LOCATES * THE NEXT LOWER 4K BLK AND XLATES ITS ADDR SO IT * LOGICALLY RESPONDS TO THE ADDRESS $C---. LDA #$0C ; PRESET NUMBER HEX "C" FINDC LDB A,Y ; GET ENTRY FROM LRARAM TABLE BNE FOUNDC ; BRANCH IF RAM THIS PHYSICAL ADDR. DECA ; ELSE POINT 4K LOWER BPL FINDC ; GO TRY AGAIN BRA XFERTF FOUNDC CLR A,Y ; CLR XLATION FACTOR OF 4K BLOCK FOUND STB $C,Y ; GIVE IT XLATION FACTOR MOVING IT TO $C--- * THE FOLLOWING CODE ADJUSTS THE TRANSLATION * FACTORS SUCH THAT ALL REMAINING RAM WILL * RESPOND TO A CONTIGUOUS BLOCK OF LOGICAL * ADDRESSES FROM $0000 AND UP.... CLRA ; START AT ZERO TFR Y,X ; START POINTER "X" START OF "LRARAM" TABLE. COMPRS LDB A,Y ; GET ENTRY FROM "LRARAM" TABLE BEQ PNTNXT ; IF IT'S ZER0 SKIP CLR A,Y ; ELSE ERASE FROM TABLE STB ,X+ ; AND ENTER ABOVE LAST ENTRY- BUMP PNTNXT INCA ; GET OFFSET TO NEXT ENTRY CMPA #$0C ; LAST ENTRY YET ? BLT COMPRS * THE FOLLOWING CODE TRANSFERS THE TRANSLATION * FACTORS FROM THE LRARAM TABLE TO IC11 ON * THE MP-09 CPU CARD. XFERTF LDX #IC11 ; POINT TO DAT RAM IC11 LDB #$10 ; GET NO. OF BYTES TO MOVE FETCH LDA ,Y+ ; GET BYTE AND POINT TO NEXT STA ,X+ ; POKE XLATION FACTOR IN IC11 DECB ; SUB 1 FROM BYTES TO MOVE BNE FETCH ; CONTINUE UNTIL 16 MOVED COMB ; SET "B" NON-ZERO STB ECHO ; TURN ON ECHO FLAG LBRA MONITOR ; INITIALIZATION IS COMPLETE V1 JMP [STACK] V2 JMP [SWI2] V3 JMP [FIRQ] V4 JMP [IRQ] V5 JMP [SWI] * SWI3 ENTRY POINT SWI3E TFR S,U LDX 10,U ; *$FFC8 LDB ,X+ STX 10,U CLRA ASLB ROLA LDX SVCVO ; GET SWI3 DISPATCH TABLE ADDRESS CMPX #$FFFF ; NO DISPATCH TABLE BEQ SWI3Z LEAX D,X ; INDEX INTO DISPATCH TABLE CMPX SVCVL ; COMPARE WITH TABLE END ADDRESS BHI SWI3Z ; PAST END OF DISPATCH TABLE PSHS X LDD ,U LDX 4,U JMP [,S++] SWI3Z PULU A,B,X,CC,DP LDU 2,U JMP [SWI3] * 6809 VECTORS FDB V1 ; USER-V FDB SWI3E ; SWI3-V FDB V2 ; SWI2-V FDB V3 ; FIRQ-V FDB V4 ; IRQ-V FDB V5 ; SWI-V FDB V1 ; NMI-V FDB START ; RESTART-V END