URL
https://opencores.org/ocsvn/System09/System09/trunk
Subversion Repositories System09
[/] [System09/] [trunk/] [src/] [sys09bug/] [sys09bug.asm] - Rev 221
Compare with Previous | Blame | View Log
* NAM SYS09BUG12 SYSTEM09 MONITOROPT lPAGE** 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** MODIFIED TO SYS09BUG VER 1.0* FOR: SYSTEM09 FPGA SYSTEM* BY: JOHN KENT* DATE: 21ST NOVEMBER 2006* REMOVED: DISK BOOTS* MEMORY TEST* ADDED: ADM3A VDU DRIVER** MODIFIED TO SYS09BUG VER 1.1* BY: JOHN KENT* DATE: 7TH JANUARY 2007* ADDED: 'U' USER EXTENTION COMMANDS AT $F000* CONDITIONAL ASSEMBLY OF FLOPPY BOOTS* AND REALTIME CLOCK** MODIFIED TO SYS09BUG VER 1.2* BY: JOHN KENT* DATE: 21ST MAY 2007* ADDED: COMPACT FLASH BOOT TO FPGA VERSION* REMOVED PORT REDIRECTION ON PUNCH & LOAD** Modified to SYS09BUG VER 1.3* BY: JOHN KENT* DATE: 8TH JAN 2008* ADDED: CONDITIONALS FOR SPARTAN3E STARTER BOARD* WITH ONLY 32K OF RAM** Modified to SYS09BUG VER 1.4* BY: JOHN KENT* DATE: 3RD FEB 2008* ADDED: CONDITIONALS FOR XESS BOARD WITH IDE* SEPERATE CONDITIONAL FOR S3 STARTER AND B5-X300* 16 BIT IDE DISK BOOT STRAP ROUTINE** Modified to SYS09BUG VER 1.5* BY: JOHN KENT* DATE: 7TH SEP 2008* ADDED: ADDED "B3-S2+" STRING** Modified to SYS09BUG VER 1.6* BY: JOHN KENT* DATE: 2ND DEC 2008* ADDED: ADDED HARDWARE FLOW CONTROL** CHANGED: SEPARARTED OPTIONS EQUATES AND BODY INTO SEPARATE FILES** Modified to SYS09BUG VER 1.7* BY: JOHN KENT* DATE: 16TH OCT 2010* ADDED: "DE2-70" STRING** *** 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 = 5.25" MINIFLOPPY BOOT* 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.* R = DISPLAY REGISTER CONTENTS* S = DISPLAY STACK FROM ssss TO $DFC0* U = 8" DMAF2 FLOPPY BOOT* U = USER EXTENSION COMMANDS AT $F000* X = REMOVE ALL BREAKPOINTS****************************************************** SYS09BUG VARIABLE SPACE****************************************************ORG MONRAMSTACK EQU * ; TOP OF INTERNAL STACKNMI RMB 2 ; USER NMI VECTORSWI3 RMB 2 ; SOFTWARE INTERRUPT VECTOR #3SWI2 RMB 2 ; SOFTWARE INTERRUPT VECTOR #2FIRQ RMB 2 ; FAST INTERRUPT VECTORIRQ RMB 2 ; INTERRUPT VECTORSWI RMB 2 ; SOFTWARE INTERRUPT VECTORSVCVO RMB 2 ; SUPERVISOR CALL VECTOR ORGINSVCVL RMB 2 ; SUPERVISOR CALL VECTOR LIMITIFD DATOPTLRARAM RMB 16 ; LRA ADDRESSESENDIF DATOPTCPORT RMB 2 ; RE-VECTORABLE CONTROL PORTECHO RMB 1 ; ECHO FLAGBPTBL RMB 24 ; BREAKPOINT TABLE BASE ADDRIFD TRAOPTNMISAV RMB 2 ; NMI Jump Vector BackupTRACNT RMB 2 ; Trace CountENDIF TRAOPTIFD VDUOPT**************************************************** VDU8 DISPLAY DRIVER VARIABLES ******************************************************** ALWAYS KEEP COLADX AND ROWADX TOGETHER ******COLADX RMB 1 ; CURSOR COLUMNROWADX RMB 1 ; CURSOR ROW***************************************************NEWROW RMB 1 ; NEW ROW TEMP FOR ESCAPEESCFLG RMB 1 ; ESCAPE SEQUENCE ACTIVEENDIF VDUOPTIFD DG640OPT***************************************************** DG640 MEMORY MAPPED DISPLAY DRIVER VARIABLES ********************************************************** ALWAYS KEEP THESE TWO BYTES TOGETHER *****COLADX RMB 1 ; CURSOR COLUMNROWADX RMB 1 ; CURSOR ROW*************************************************CURSOR RMB 2 ; ABSOLUTE SCREEN ADDRESSNEWROW RMB 1 ; NEW ROW TEMP FOR ESCAPEESCFLG RMB 1 ; ESCAPE SEQUENCE ACTIVEENDIF DG640OPT****************************************************** START OF ROM *****************************************************ORG MONROMFDB MONITORFDB NEXTCMDFDB INCHFDB INCHEFDB INCHEKFDB OUTCHFDB PDATAFDB PCRLFFDB PSTRNGFDB LRA*IFD ADSOPTFDB PCHK ; CHECK FOR PRINTER INPUTFDB PINIZ ; INITIATE PRINTERFDB POUTCH ; OUTPUT CH. TO PRINTERFDB VINIZFDB VOUTCHFDB ACINIZFDB AOUTCHENDIF ADSOPT** MONITOR** VECTOR ADDRESS STRING IS.....* $F8A1-$F8A1-$F8A1-$F8A1-$F8A1-$FAB0-$FFFF-$FFFF*MONITOR LDX #RAMVEC ; POINT TO VECTOR ADDR. STRINGLDY #STACK ; POINT TO RAM VECTOR LOCATIONLDB #$10 ; BYTES TO MOVE = 16LOOPA LDA ,X+ ; GET VECTOR BYTESTA ,Y+ ; PUT VECTORS IN RAM / $DFC0-$DFCFDECB ; SUBTRACT 1 FROM NUMBER OF BYTES TO MOVEBNE 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 #ACIASSTX CPORT ; STORE ADDR. IN RAMLBSR XBKPNT ; CLEAR OUTSTANDING BREAKPOINTSLDB #12 ; CLEAR 12 BYTES ON STACKCLRSTK CLR ,-SDECBBNE CLRSTKLEAX MONITOR,PCR ; SET PC TO SBUG-E ENTRYSTX 10,S ; ON STACKLDA #$D0 ; PRESET CONDITION CODES ON STACKSTA ,STFR S,ULBSR IOINIZ ; INITIALIZE CONTROL PORTLDX #MSG1 ; POINT TO MONITOR MESSAGELBSR PDATA ; PRINT MSG*IFD DATOPTLDX #LRARAM ; POINT TO LRA RAM STORAGE AREACLRA START ; TOTAL AT ZEROLDB #13 ; TOTAL UP ALL ACTIVE RAM MEMORYFNDREL TST B,X ; TEST FOR RAM AT NEXT LOC.BEQ RELPAS ; IF NO RAM GO TO NEXT LOC.ADDA #4 ; ELSE ADD 4K TO TOTALDAA ; ADJ. TOTAL FOR DECIMALRELPAS DECB ; SUB. 1 FROM LOCS. TO TESTBPL FNDREL ; PRINT TOTAL OF RAMLBSR OUT2H ; OUTPUT HEX BYTE AS ASCIILDX #MSG2 ; POINT TO MSG 'K' CR/LF + 3 NULSLBSR PDATA ; PRINT MSGENDIF DATOPT*IFD TRAOPTLBSR TRAINZENDIF TRAOPT****** NEXTCMD ******NEXTCMD LDX #MSG3 ; POINT TO MSG ">"LBSR PSTRNG ; PRINT MSGLBSR INCH ; GET ONE CHAR. FROM TERMINALANDA #$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 ITLDA #'^ ; ELSE CNTRL CHAR CMD SO...LBSR OUTCH ; PRINT "^"TFR B,A ; RECALL CNTRL CMD CHARADDA #$40 ; CONVERT IT TO ASCII LETTERPRTCMD LBSR OUTCH ; PRNT CMD CHARLBSR OUT1S ; PRNT SPACECMPB #$60BLE NXTCH0SUBB #$20****** DO TABLE LOOKUP ****** FOR COMMAND FUNCTIONS*NXTCH0 LDX #JMPTAB ; POINT TO JUMP TABLENXTCHR CMPB ,X+ ; DOES COMMAND MATCH TABLE ENTRY ?BEQ JMPCMD ; BRANCH IF MATCH FOUNDLEAX 2,X ; POINT TO NEXT ENTRY IN TABLECMPX #TABEND ; REACHED END OF TABLE YET ?BNE NXTCHR ; IF NOT END, CHECK NEXT ENTRYLDX #MSG4 ; POINT TO MSG "WHAT?"LBSR PDATA ; PRINT MSGBRA NEXTCMD ; IF NO MATCH, PRMPT FOR NEW CMDJMPCMD JSR [,X] ; JUMP TO COMMAND ROUTINEBRA NEXTCMD ; PROMPT FOR NEW COMMAND** "G" GO OR CONTINUE*GO TFR U,SRTI RTI****** "M" MEMORY EXAMINE AND CHANGE ******MEMCHG LBSR IN1ADR ; INPUT ADDRESSBVS CHRTN ; IF NOT HEX, RETURNTFR X,Y ; SAVE ADDR IN "Y"MEMC2 LDX #MSG5 ; POINT TO MSG " - "LBSR PSTRNG ; PRINT MSGTFR Y,X ; FETCH ADDRESSLBSR OUT4H ; PRINT ADDR IN HEXLBSR OUT1S ; OUTPUT SPACELDA ,Y ; GET CONTENTS OF CURRENT ADDR.LBSR OUT2H ; OUTPUT CONTENTS IN ASCIILBSR OUT1S ; OUTPUT SPACELBSR BYTE ; LOOP WAITING FOR OPERATOR INPUTBVC CHANGE ; IF VALID HEX GO CHANGE MEM. LOC.CMPA #8 ; IS IT A BACKSPACE (CNTRL H)?BEQ MEMC2 ; PROMPT OPERATOR AGAINCMPA #$18 ; IS IT A CANCEL (CNTRL X)?BEQ MEMC2 ; PROMPT OPERATOR AGAINCMPA #'^ ; IS IT AN UP ARROW?BEQ BACK ; DISPLAY PREVIOUS BYTECMPA #$D ; IS IT A CR?BNE FORWRD ; DISPLAY NEXT BYTECHRTN RTS ; EXIT ROUTINE**CHANGE STA ,Y ; CHANGE BYTE IN MEMORYCMPA ,Y ; DID MEMORY BYTE CHANGE?BEQ FORWRD ; $F972LBSR OUT1S ; OUTPUT SPACELDA #'? ; LOAD QUESTION MARKLBSR OUTCH ; PRINT ITFORWRD LEAY 1,Y ; POINT TO NEXT HIGHER MEM LOCATIONBRA MEMC2 ; PRINT LOCATION & CONTENTSBACK LEAY -1,Y ; POINT TO LAST MEM LOCATIONBRA 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 POINTERTFR U,YLDX #STACK ; LOAD INTERNAL STACK AS UPPER LIMITLEAX -1,X ; POINT TO CURRENT STACKBRA 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 BOUNDRIESBVS EDPRTN ; NEW COMMAND IF ILLEGAL HEXMDUMP1 PSHS Y ; COMPARE LOWER TO UPPER BOUNDSCMPX ,S++ ; LOWER BOUNDS > UPPER BOUNDS?BCC AJDUMP ; IF NOT, DUMP HEX AND ASCIIEDPRTN 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-REGADDD #$10 ; ADD 16 TO UPPER ADDRESSANDB #$F0 ; MASK TO EVEN 16 BYTE BOUNDRYPSHS A,B ; SAVE ON STACK AS UPPER DUMP LIMITTFR Y,D ; $F9A5 GET LOWER ADDRESS IN D-REGANDB #$F0 ; MASK TO EVEN 16 BYTE BOUNDRYTFR D,X ; PUT IN X-REG AS LOWER DUMP LIMITNXTLIN CMPX ,S ; COMPARE LOWER TO UPPER LIMITBEQ SKPDMP ; IF EQUAL SKIP HEX-ASCII DUMPLBSR INCHEK ; CHECK FOR INPUT FROM KEYBOARDBEQ EDUMPSKPDMP LEAS 2,S ; READJUST STACK IF NOT DUMPINGRTS ;** PRINT 16 HEX BYTES FOLLOWED BY 16 ASCII CHARACTERS* FOR EACH LINE THROUGHOUT ADDRESS LIMITS.*EDUMP PSHS X ; PUSH LOWER ADDR LIMIT ON STACKLDX #MSG5 ; POINT TO MSG " - "LBSR PSTRNG ; PRINT MSGLDX ,S ; LOAD LOWER ADDR FROM TOP OF STACKLBSR OUT4H ; PRINT THE ADDRESSLBSR OUT2S ; 2 SPACESLDB #$10 ; LOAD COUNT OF 16 BYTES TO DUMPELOOP LDA ,X+ ; GET FROM MEMORY HEX BYTE TO PRINTLBSR OUT2H ; OUTPUT HEX BYTE AS ASCIILBSR OUT1S ; OUTPUT SPACEDECB ; $F9D1 DECREMENT BYTE COUNTBNE ELOOP ; CONTINUE TIL 16 HEX BYTES PRINTED** PRINT 16 ASCII CHARACTERS* IF NOT PRINTABLE OR NOT VALID* ASCII PRINT A PERIOD (.)LBSR OUT2S ; 2 SPACESLDX ,S++ ; GET LOW LIMIT FRM STACK - ADJ STACKLDB #$10 ; SET ASCII CHAR TO PRINT = 16EDPASC LDA ,X+ ; GET CHARACTER FROM MEMORYCMPA #$20 ; IF LESS THAN $20, NON-PRINTABLE?BCS PERIOD ; IF SO, PRINT PERIOD INSTEADCMPA #$7E ; IS IT VALID ASCII?BLS PRASC ; IF SO PRINT ITPERIOD LDA #'. ; LOAD A PERIOD (.)PRASC LBSR OUTCH ; PRINT ASCII CHARACTERDECB ; DECREMENT COUNTBNE EDPASCBRA NXTLIN****** "B" SET BREAKPOINT ******BRKPNT LBSR IN1ADR ; GET BREAKPOINT ADDRESSBVS EXITBP ; EXIT IF INVALID HEX ADDR.CMPX #STACK ; ADDRESS ILLEGAL IF >=$DFC0BCC BPERR ; IF ERROR PRINT (?), EXITPSHS X ; $FA82 PUSH BP ADDRESS ON STACKLDX #$FFFF ; LOAD DUMMY ADDR TO TEST BP TABLEBSR BPTEST ; TEST BP TABLE FOR FREE SPACEPULS X ; POP BP ADDRESS FROM STACKBEQ BPERR ; (Z) SET, OUT OF BP TABLE SPACELDA ,X ; GET DATA AT BREAKPOINT ADDRESSCMPA #$3F ; IS IT A SWI?BEQ BPERR ; IF SWI ALREADY, INDICATE ERRORSTA ,Y+ ; SAVE DATA BYTE IN BP TABLESTX ,Y ; SAVE BP ADDRESS IN BP TABLELDA #$3F ; LOAD A SWI ($3F)STA ,X ; SAVE SWI AT BREAKPOINT ADDRESSEXITBP RTS ;** INDICATE ERROR SETTING BREAKPOINT*BPERR LBSR OUT1S ; OUTPUT SPACELDA #'? ; LOAD (?), INDICATE BREAKPOINT ERRORLBRA OUTCH ; PRINT "?"**** "X" CLEAR OUTSTANDING BREAKPOINTS ****XBKPNT LDY #BPTBL ; POINT TO BREAKPOINT TABLELDB #8 ; LOAD BREAKPOINT COUNTERXBPLP BSR RPLSWI ; REMOVE USED ENTRY IN BP TABLEDECB $FAAC ; DECREMENT BP COUNTERBNE XBPLP ; END OF BREAKPOINT TABLE?RTS****** SWI ENTRY POINT ******SWIE TFR S,U ; TRANSFER STACK TO USER POINTERLDX 10,U ; LOAD PC FROM STACK INTO X-REGLEAX -1,X ; ADJUST ADDR DOWN 1 BYTE.BSR BPTEST ; FIND BREAKPOINT IN BP TABLEBEQ REGPR ; IF FOUND, REPLACE DATA AT BP ADDRSTX 10,U ; SAVE BREAKPOINT ADDR IN STACKBSR RPLSWI ; GO REPLACE SWI WITH ORIGINAL DATAREGPR LBSR REGSTR ; GO PRINT REGISTERS*IFD TRAOPTLDX #0STX TRACNTENDIF TRAOPT*LBRA NEXTCMD ; GET NEXT COMMAND*RPLSWI LDX 1,Y ; LOAD BP ADDRESS FROM BP TABLECMPX #STACK ; COMPARE TO TOP AVAILABLE USER MEMORYBCC FFSTBL ; GO RESET TABLE ENTRY TO $FF'SLDA ,X ; GET DATA FROM BP ADDRESSCMPA #$3F ; IS IT SWI?BNE FFSTBL ; IF NOT, RESET TABLE ENTRY TO $FF'SLDA ,Y ; GET ORIGINAL DATA FROM BP TABLESTA ,X ; $FAD3 RESTORE DATA AT BP ADDRESSFFSTBL LDA #$FF ; LOAD $FF IN A-ACCSTA ,Y+ ; RESET BREAKPOINT TABLE DATA TO $FF'SSTA ,Y+ ; RESET BREAKPOINT TABLE ADDR TO $FF'SSTA ,Y+RTS*** SEARCH BREAKPOINT TABLE FOR MATCH ***BPTEST LDY #BPTBL ; POINT TO BREAKPOINT TABLELDB #8 ; LOAD BREAKPOINT COUNTERFNDBP LDA ,Y+ ; LOAD DATA BYTECMPX ,Y++ ; COMPARE ADDRESS, IS IT SAME?BEQ BPADJ ; IF SO, ADJUST POINTER FOR TABLE ENTRYDECB ; IF NOT, DECREMENT BREAKPOINT COUNTERBNE FNDBP ; AND LOOK FOR NEXT POSSIBLE MATCHRTS ;**BPADJ LEAY -3,Y ; MOVE POINTER TO BEGIN OF BP ENTRYRTS*IFD TRAOPT*** TRACE from address AAAA BB bytes*TRACE LBSR ALTPC1 ; SET UP NEW PCBVS TREXIT ; ADDRESS ERROR, EXITLBSR OUT1SLBSR IN1ADR ; Fetch Byte CountBVS TREXIT ; Byte Count error, EXITSTX TRACNT*LDX NMI ; Save NMI VectorSTX NMISAVLDX #NMIE ; Set up NMI for TracingSTX NMILBSR TRAINZ ; Initialise HardwareBRA TRACEG ; Start TraceTREXIT RTS** CRA0 = 0 CA1 IRQ DISAB, CRA0 = 1 CA1 IRQ ENAB* CRA1 = 1 CA1 Rising edge IRQ* CRA2 = 0 TADATA = Data Direction, CRA2 = 1 TADATA = I/O Register* CRA3 = 0 CA2 = 0 output, CRA3 = 1 CA2 = 1* CRA4 = 1 ] CA2 = Set/Reset output* CRA5 = 1 ]* CRA6 = X CA2 Input Interrupt Flag* CRA7 = X CA1 Interrupt Flag** CRB0 = 0 CB1 IRQ DISAB, CRB0 = 1 CA1 IRQ ENAB* CRB1 = 1 CB1 Rising edge IRQ* CRB2 = 0 TBDATA = Data Direction, CRB2 = 1 TBDATA = I/O Register* CRB3 = 0 CB2 = 0 output, CRB3 = 1 CB2 = 1* CRB4 = 1 ] CB2 = Set/Reset output* CRB5 = 1 ]* CRB6 = X CB2 Input Interrupt Flag* CRB7 = X CB1 Interrupt Flag**** TRACE NMI ENTRY POINT*NMIE TFR S,ULDA #$36 ; Disable Interrupt, CA2 LowSTA TACTRLLDA TADATA ; Clear Interrupt flag by reading data port*LBSR REGSTR ; DUMP REGISTERS*LDX 10,U ; TEST IF NEXT INSTRUCTION IS A SWILDA ,XCMPA #$3FBEQ TRACEX ; EXIT ON SWI*LDX TRACNT ; CHECK IF TRACE COUNT EXPIREDBEQ TRACEX ; YES, GO BACK TO THE MONITORLEAX -1,X ; ECREMENT TRACE COUNTSTX TRACNT*** TRACE GO (RESUME SINGLE STEP)*TRACEG TFR U,S ; SET UP PROGRAM STACK POINTERLDA #TRADEL ; SET UP TIMER DELAY (NUMB CYCLES FOR RTI+1)STA TADATALDA #$36 ; LOAD STROBE LOWSTA TACTRLLDA TADATA ; CLEAR INTERRUPTLDA #$36 ; RELEASE RESETSTA TBCTRLLDA #$3F ; RELEASE LOAD, ENABLE CA1 NMI, CA1 RISING EDGESTA TACTRLRTI ; GO EXECUTE INSTRUCTION*TRACEX LDX NMISAV ; Restore NMI vectorSTX NMILBRA NEXTCMD ; Jump back to the command loop.*** TRACE HARDWARE INITIALISATION*TRAINZ LDA #$32 ; SELECT DDRA, CA2 LOW, NMI DISABLEDSTA TACTRLLDA #$3A ; SELECT DDRB, CB2 HIGH, FIRQ DISABLEDSTA TBCTRLLDA #$FF ; PORTA = OUTPUTSTA TADATALDA #$00 ; PORTB = INPUTSTA TBDATALDA #$36 ; SELECT OUTPUT REGISTER A, CA2 LOWSTA TACTRLLDA #$3E ; SELECT OUTPUT REGISTER B, CB2 HIGHSTA TBCTRLRTS*ENDIF TRAOPTIFD MFDCOPT*** "U" MINI DISK BOOT*MINBOOT TST CMDFDCCLR DRVFDCLDX #$0000LOOP LEAX $01,XCMPX #$0000BNE LOOPLDA #$0FSTA CMDFDCBSR DELAYLOOP1 LDB CMDFDCBITB #$01BNE LOOP1LDA #$01STA SECFDCBSR DELAYLDA #$8CSTA CMDFDCBSR DELAYLDX #$C000BRA LOOP3LOOP2 BITB #$02BEQ LOOP3LDA DATFDCSTA ,X+LOOP3 LDB CMDFDCBITB #$01BNE LOOP2BITB #$2CBEQ LOOP4RTS*LOOP4 LDX #$C000STX $0A,UTFR U,SRTI*DELAY LDB #$04LOOP5 DECBBNE LOOP5RTSENDIF MFDCOPT*IFD DMAFOPT**** "D" DISK BOOT FOR DMAF2 ****DBOOT LDA #$DESTA DRVREGLDA #$FFSTA PRIREG ; $FAF8STA CCREGSTA AAAREGSTA BBBREGTST CCREGLDA #$D8STA COMREGLBSR DLYDBOOT0 LDA COMREGBMI DBOOT0LDA #$09STA COMREGLBSR DLY*DISKWT LDA COMREG ; FETCH DRIVE STATUSBITA #1 ; TEST BUSY BITBNE DISKWT ; LOOP UNTIL NOT BUSY*BITA #$10BNE DBOOT*LDX #$C000 ; LOGICAL ADDR. = $C000BSR LRA ; GET 20 BIT PHYSICAL ADDR. OF LOG. ADDR.ORA #$10STA CCCREGTFR X,DCOMA ;COMB ;STD ADDREGLDX #$FEFF ; LOAD DMA BYTE COUNT = $100STX CNTREG ; STORE IN COUNT REGISTERLDA #$FF ; LOAD THE CHANNEL REGISTERSTA CCREGLDA #$FE ; SET CHANNEL 0STA PRIREGLDA #1 ; SET SECTOR TO "1"STA SECREG ; ISSUE COMMANDLDA #$8C ; SET SINGLE SECTOR READSTA COMREG ; ISSUE COMMANDBSR 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 ; $FB55CLRB ;DBOOT2 TST CCREGBPL DBOOT3DECB ;BNE DBOOT2PULS BDECBBNE DBOOT1BRA DBOOTDBOOT3 PULS BLDA COMREGBITA #$1CBEQ DBOOT4RTS ;**DBOOT4 LDB #$DESTB DRVREGLDX #$C000STX 10,UTFR U,S ; $FB7BRTI ;ENDIF DMAFOPT*IFD CF8OPT** COMPACT FLASH BOOT*CFBOOT BSR WAITRDYLDA #HEADLBASTA CF_HEADBSR WAITRDYLDA #FEAT8BITSTA CF_FEATURELDA #CMDFEATURESTA CF_COMANDBSR WAITRDY** READ SECTORS FROM CF*CFREAD LDA #$01STA CF_SECCNTCLRASTA CF_SECNUMSTA CF_CYLLOSTA CF_CYLHI*LDA #CMDREAD ; IDE READ MULTIPLESTA CF_COMANDBSR WAITRDYLDX #$C000** READ LOOP*RDLOOP BSR WAITDRQLDA CF_DATASTA ,X+CMPX #$C200BNE RDLOOP*LDX #$C000STX $0A,UTFR U,SRTI** WAIT UNTIL READY*WAITRDY LDA CF_STATUSBITA #BUSYBNE WAITRDYLDA CF_STATUSBITA #DRDYBEQ WAITRDYRTS** WAIT FOR DATA REQUEST*WAITDRQ LDA CF_STATUSBITA #DRQBEQ WAITDRQRTSENDIF CF8OPT*IFD IDEOPT** XESS 16 BIT IDE BOOT*IDEBOOT LDD #AUXRESETSTD CF_AUXLDD #AUXRSTRELSTD CF_AUXLDD #HEADLBASTD CF_HEADBSR WAITRDY** READ SECTORS FROM CF*LDD #$01STD CF_SECCNTCLRBSTD CF_SECNUMSTD CF_CYLLOSTD CF_CYLHI*LDB #CMDREAD ; IDE READ MULTIPLESTD CF_COMANDBSR WAITRDYLDX #$C000** READ LOOP*RDLOOP BSR WAITDRQLDD CF_DATASTB ,X+CMPX #$C100BNE RDLOOP*LDX #$C000STX $0A,UTFR U,SRTI** WAIT UNTIL READY*WAITRDY LDD CF_STATUSBITB #BUSYBNE WAITRDYLDD CF_STATUSBITB #DRDYBEQ WAITRDYRTS** WAIT FOR DATA REQUEST*WAITDRQ LDD CF_STATUSBITB #DRQBEQ WAITDRQRTSENDIF IDEOPT*IFD RTCOPT** CLOCK INTER FACE UTILITY** TIME <Hours> <Minuits> <Seconds>* If no argument is specified, the current time* will be displayed.** READ A REGISTER FROM THE COUNTER.* The X Index rgister points to the register* to be read. The Status Register is checked* before and after the register is read before* returning a value in accumulator A*RDCLK TST CLKSTABNE RDCLKRDCLK1 LDA 0,XTST CLKSTABNE RDCLK1RTS** MAIN PROGRAM:*TIMSET LDX #COUNTR ; POINT TO TIMERLBSR BYTE ; READ HOURSBVS SHOWTM ; NO ARG, DISP TIMESTA HOUR,XLBSR OUT1SLBSR BYTE ; READ MINUITESBVS SHOWTMSTA MINUIT,XLBSR OUT1SLBSR BYTE ; SECONDS.BVS SHOWTMSTA SECOND,X** DISPLAY CURRENT TIME*SHOWTM LBSR PCRLFLDX #COUNTR+HOURLDB #3SHOWLP BSR RDCLKLBSR OUT2HLDA #':LBSR OUTCHLEAX -1,XDECBBNE SHOWLPRTS** INITIATE CLOCK.* MASK INTERRUPTS.*CLKINZ CLR CINTCR ; MASK ALL INTERRUPTSTST CINTSR ; CLEAR ANY INTERRUPTSRTSENDIF RTCOPTIFD DATOPT****** 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 STACKLDA 2,S ; GET MSB LOGICAL ADDR FRM X REG ON STACKLSRA ;LSRA ; ADJ FOR INDEXED INTOLSRA ; CORRESPONDING LOCATIONLSRA ; IN LRA TABLELDY #LRARAM ; LOAD LRA TABLE BASE ADDRESSLDB A,Y ; GET PHYSICAL ADDR. DATA FROM LRA TABLELSRB ; ADJ. REAL ADDR. TO REFLECT EXTENDEDLSRB ; PHYSICAL ADDRESS.LSRB ; EXTENDED MS 4-BITS ARE RETURNEDLSRB ; IN THE "A" ACCUMULATORSTB ,S ; MS 4 BITS IN A ACCUM. STORED ON STACKLDB A,Y ; LOAD REAL ADDRESS DATA FROM LRA TABLECOMB ; COMP TO ADJ FOR PHYSICAL ADDR. IN X REGASLB ; ADJ DATA FOR RELOCATION IN X REGASLB ;ASLB ; $FB97ASLB ;LDA 2,S ; GET MS BYTE OF LOGICAL ADDR.ANDA #$0F ; MASK MS NIBBLE OF LOGICAL ADDRESSSTA 2,S ; SAVE IT IN X REG ON STACKORB 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 STACKPULS A,B,X,Y,PC ; POP REGS. FROM STACKENDIF DATOPT** DELAY LOOP*DLY PSHS B ; SAVE CONTENTS OF "B"LDB #$20 ; GET LOOP DELAY VALUESUB1 DECB ; SUBTRACT ONE FROM VALUEBNE SUB1 ; LOOP UNTIL ZEROPULS B,PC ; RESTORE CONTENTS OF "B"* RTS ;****** "L" LOAD MIKBUG TAPE ******LOAD JSR ACINIZLDA #$11 ; LOAD 'DC1' CASS. READ ON CODELBSR OUTCH ; OUTPUT IT TO TERMINAL PORTCLR ECHO ; TURN OFF ECHO FLAGLOAD1 LBSR ECHON ; INPUT 8 BIT BYTE WITH NO ECHOLOAD2 CMPA #'S ; IS IT AN "S", START CHARACTER ?BNE LOAD1 ; IF NOT, DISCARD AND GET NEXT CHAR.LBSR ECHONCMPA #'9 ; IS IT A "9" , END OF FILE CHAR ?BEQ LOAD21 ; IF SO, EXIT LOADCMPA #'1 ; IS IT A "1" , FILE LOAD CHAR ?BNE LOAD2 ; IF NOT, LOOK FOR START CHAR.LBSR BYTE ; INPUT BYTE COUNTPSHS A ; PUSH COUNT ON STACKBVS LODERR ; (V) C-CODE SET, ILLEGAL HEXLBSR IN1ADR ; INPUT LOAD ADDRESSBVS LODERR ; (V) C-CODE SET, ADDR NOT HEXPSHS X ; PUSH ADDR ON STACKLDB ,S+ ; LOAD MSB OF ADDR AS CHECKSUM BYTEADDB ,S+ ; ADD LSB OF ADDR TO CHECKSUMADDB ,S ; ADD BYTE COUNT BYTE TO CHECKSUMDEC ,S ; $FC37 DECREMENT BYTE COUNT 2 TO BYPASSDEC ,S ; ADDRESS BYTES.LOAD10 PSHS B ; PUSH CHECKSUM ON STACKLBSR BYTE ; INPUT DATA BYTE (2 HEX CHAR)PULS B ; POP CHECKSUM FROM STACKBVS LODERR ; (V) SET, DATA BYTE NOT HEXPSHS A ; PUSH DATA BYTE ON STACKADDB ,S+ ; ADD DATA TO CHECKSUM, AUTO INC STACKDEC ,S ; DECREMENT BYTE COUNT 1BEQ LOAD16 ; IF BYTE COUNT ZERO, TEST CHECKSUMSTA ,X+ ; SAVE DATA BYTE IN MEMORYBRA LOAD10 ; GET NEXT DATA BYTELODERR CLRB ; ERROR CONDITION, ZERO CHECKSUM ;LOAD16 PULS A ; ADJUST STACK (REMOVE BYTE COUNT)CMPB #$FF ; CHECKSUM OK?BEQ LOAD1 ; IF SO, LOAD NEXT LINELDA #'? ; LOAD (?) ERROR INDICATORLBSR OUTCH ; OUTPUT IT TO TERMINALLOAD21 COM ECHO ; TURN ECHO ONLDA #$13 ; $FC5F LOAD 'DC3' CASS. READ OFF CODELBRA OUTCH ; OUTPUT IT****** "P" PUNCH MIKBUG TAPE ******PUNCH CLR ,-S ; CLEAR RESERVED BYTE ON STACKLBSR IN2ADR ; GET BEGIN AND END ADDRESSPSHS X,Y ; SAVE ADDRESSES ON STACKBVS PUNEXT ; (V) C-CODE SET, EXIT PUNCHCMPX 2,S ; COMPARE BEGIN TO END ADDRBCS PUNEXT ; IF BEGIN GREATER THAN END, EXIT PUNCHLEAX 1,X ; INCREMENT END ADDRESSSTX ,S ; STORE END ADDR ON STACKJSR ACINIZLDA #$12 ; LOAD 'DC2' PUNCH ON CODELBSR OUTCH ; OUTPUT IT TO TERMINALPUNCH2 LDD ,S ; LOAD END ADDR IN D-ACCSUBD 2,S ; SUBTRACT BEGIN FROM ENDBEQ PUNCH3 ; SAME, PUNCH 32 BYTES DEFAULTCMPD #$20 ; LESS THAN 32 BYTES?BLS PUNCH4 ; PUNCH THAT MANY BYTESPUNCH3 LDB #$20 ; LOAD BYTE COUNT OF 32.PUNCH4 STB 4,S ; STORE ON STACK AS BYTE COUNTLDX #MSG20 ; POINT TO MSG "S1"LBSR PSTRNG ; PRINT MSGADDB #3 ; ADD 3 BYTES TO BYTE COUNTTFR B,A ; GET BYTE COUNT IN A-ACC TO PUNCHLBSR OUT2H ; OUTPUT BYTE COUNTLDX 2,S ; LOAD BEGIN ADDRESSLBSR OUT4H ; PUNCH ADDRESSADDB 2,S ; ADD ADDR MSB TO CHECKSUMADDB 3,S ; ADD ADDR LSB TO CHECKSUMPUNCHL ADDB ,X ; ADD DATA BYTE TO CHECKSUMLDA ,X+ ; LOAD DATA BYTE TO PUNCHLBSR OUT2H ; OUTPUT DATA BYTEDEC 4,S ; DECREMENT BYTE COUNTBNE PUNCHL ; NOT DONE, PUNCH NEXT BYTECOMB 1's ; COMPLIMENT CHECKSUM BYTETFR B,A ; GET IT IN A-ACC TO PUNCHLBSR OUT2H ; OUTPUT CHECKSUM BYTESTX 2,S ; SAVE X-REG IN STACK AS NEW PUNCH ADDRCMPX ,S ; COMPARE IT TO END ADDRBNE PUNCH2 ; $FCB5 PUNCH NOT DONE, CONT.PUNEXT LDA #$14 ; LOAD 'DC4' PUNCH OFF CODELBSR OUTCH ; OUTPUT ITLEAS 5,S ; READJUST STACK POINTERRTS ;** PRINT STRING PRECEEDED BY A CR & LF.*PSTRNG BSR PCRLF ; PRINT CR/LFBRA PDATA ; PRINT STRING POINTED TO BY IX** PCRLF*PCRLF PSHS X ; SAVE IXLDX #MSG2+1 ; POINT TO MSG CR/LF + 3 NULSLBSR PDATA ; PRINT MSGPULS X,PC ; RESTORE IX & RETURN** LONG BRANCHES TO COMMON ROUTINES*JOUT1S LBRA OUT1SJBYTE LBRA BYTEJIN1ADR LBRA IN1ADR** ALTER "PC" PROGRAM COUNTER*ALTRPC LBSR PRTPC ; $FCF5 PRINT MSG " PC = "ALTPC1 BSR JOUT1S ; OUTPUT SPACEBSR JIN1ADR ; GET NEW CONTENTS FOR "PC"BVS ALTPCD ; EXIT IF INVALID HEXSTX 10,U ; POKE IN NEW CONTENTSALTPCD RTS ;** ALTER "U" USER STACK POINTER*ALTRU BSR PRTUS ; $FCCA PRINT MSG " US = "BSR JOUT1S ; OUTPUT SPACEBSR JIN1ADR ; GET NEW CONTENTS FOR "US"BVS ALTUD ; EXIT IF INVALID HEXSTX 8,U ; POKE IN NEW CONTENTSALTUD RTS ;** ALTER "Y" INDEX REGISTER*ALTRY BSR PRTIY ; PRINT MSG " IY = "BSR JOUT1S ; OUTPUT SPACEBSR JIN1ADR ; GET NEW CONTENTS FOR "IY"BVS ALTYD ; EXIT IF INVALID HEXSTX 6,U ; $F8F0 POKE IN NEW CONTENTSALTYD RTS ;** ALTER "X" INDEX REGISTER*ALTRX BSR PRTIX ; $FCE0 PRINT MSG " IX = "BSR JOUT1S ; OUTPUT SPACEBSR JIN1ADRBVS ALTXDSTX 4,UALTXD RTS ;** ALTER "DP" DIRECT PAGE REGISTER*ALTRDP BSR PRTDP ; $FCD5 PRINT MSG " DP = "BSR JOUT1S ; OUTPUT SPACEBSR JBYTE ; INPUT BYTE (2 HEX CHAR)BVS ALTDPDSTA 3,UALTDPD RTS ;** ALTER "B" ACCUMULATOR*ALTRB BSR PRTB ; $FD09 PRINT MSG " B = "BSR JOUT1S ; OUTPUT SPACEBSR JBYTE ; INPUT BYTE (2 HEX CHAR)BVS ALTBDSTA 2,UALTBD RTS ; $F91C** ALTER "A" ACCUMULATOR*ALTRA BSR PRTA ; $FCFF RINT MSG " A = "BSR JOUT1S ; OUTPUT SPACEBSR JBYTE ; INPUT BYTE (2 HEX CHAR)BVS ALTADSTA 1,UALTAD RTS ;** ALTER "CC" REGISTER*ALTRCC BSR PRTCC ; $FD13 PRINT MSG " CC: "BSR JOUT1S ; OUTPUT SPACEBSR JBYTE ; INPUT BYTE (2 HEX CHAR)BVS ALTCCDORA #$80 ; SETS "E" FLAG IN PRINT LISTSTA ,UALTCCD RTS ;** PDATA*PRINT LBSR OUTCHPDATA LDA ,X+ ; GET 1st CHAR. TO PRINTCMPA #4 ; IS IT EOT?BNE PRINT ; IF NOT EOT PRINT ITRTS ;** PRINT REGISTERS*PRTSP LDX #MSG10 ; POINT TO MSG "SP="BSR PDATA ; PRINT MSGTFR U,XJOUT4H LBRA OUT4H*PRTUS LDX #MSG12 ; POINT TO MSG "US="BSR PDATA ; PRINT MSGLDX 8,UBRA JOUT4H*PRTDP LDX #MSG15 ; POINT TO MSG "DP="BSR PDATA ; PRINT MSGLDA 3,UJOUT2H LBRA OUT2H ; OUTPUT HEX BYTE AS ASCII*PRTIX LDX #MSG14 ; POINT TO MSG "IX="BSR PDATA ; PRINT MSGLDX 4,U ; $FCE6BRA JOUT4H*PRTIY LDX #MSG13 ; POINT TO MSG "IY="BSR PDATA ; PRINT MSGLDX 6,UBRA JOUT4H*PRTPC LDX #MSG11 ; POINT TO MSG "PC="BSR PDATA ; PRINT MSGLDX 10,UBRA JOUT4H*PRTA LDX #MSG16 ; POINT TO MSG "A="BSR PDATA ; PRINT MSGLDA 1,UBRA JOUT2H ; OUTPUT HEX BYTE AS ASCII*PRTB LDX #MSG17 ; POINT TO MSG "B="BSR PDATA ; PRINT MSGLDA 2,UBRA JOUT2H ; OUTPUT HEX BYTE AS ASCII*PRTCC LDX #MSG18 ; POINT TO MSG "CC:"BSR PDATA ; PRINT MSGLDA ,ULDX #MSG19 ; POINT TO MSG "EFHINZVC"LBRA BIASCI ; OUTPUT IN BINARY/ASCII FORMAT** "R" DISPLAY REGISTERS*REGSTR LDX #MSG5 ; POINT TO MSG " - "LBSR PSTRNG ; PRINT MSGBSR PRTSP ; $FCBFBSR PRTUS ; $FCCABSR PRTDP ; $FCD5BSR PRTIX ; $FCE0BSR PRTIY ; $FCEBLDX #MSG5 ; POINT TO MSG " - "LBSR PSTRNG ; PRINT MSGBSR PRTPC ; $FCF5BSR PRTA ; $FCFFBSR PRTB ; $FD09BRA PRTCC ; $FD13** 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 ADDRESSBVS NOTHEX ; EXIT IF NOT VALID HEXTFR 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 HEXTFR D,XBSR BYTE ; INPUT BYTE (2 HEX CHAR)BVS NOTHEXPSHS XSTA 1,SPULS X,PC****** INPUT BYTE (2 HEX CHAR.) ******BYTE BSR INHEX ; GET HEX LEFTBVS NOTHEX ; EXIT IF NOT VALID HEXASLA ;ASLA ;ASLA ; SHIFT INTO LEFT NIBBLEASLA ;TFR A,B ; PUT HEXL IN "B"BSR INHEX ; GET HEX RIGHTBVS NOTHEX ; EXIT IF NOT VALID HEXPSHS B ; PUSH HEXL ON STACKADDA ,S+ ; ADD HEXL TO HEXR AND ADJ. STKRTS ; 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 HEXCMPA #'9 ; IS IT < OR = "9" ?BHI INHEXA ; IF > MAYBE IT'S ALPHASUBA #$30 ; ASCII ADJ. NUMERICRTS ;**INHEXA CMPA #'A ; IS IT > OR = "A"BCS NOTHEX ; IF LESS IT AIN'T HEXCMPA #'F ; IS IT < OR = "F" ?BHI INHEXL ; IF > IT AIN'T HEXSUBA #'A-10 ; ($37) ASCII ADJ. ALPHARTS ;*INHEXL CMPA #'a ; IS IT > OR = "a"BCS NOTHEX ; IF LESS IT AIN'T HEXCMPA #'f ; IS IT < "f"BHI NOTHEX ; IF > IT AIN'T HEXSUBA #'a-10 ; ($57) ADJUST TO LOWER CASERTS ;**NOTHEX ORCC #2 ; SET (V) FLAG IN C-CODES REGISTERRTS ;**OUT4H PSHS X ; PUSH X-REG. ON THE STACKPULS A ; POP MS BYTE OF X-REG INTO A-ACC.BSR OUTHL ; OUTPUT HEX LEFTPULS A ; POP LS BYTE OF X-REG INTO A-ACC.OUTHL EQU *OUT2H PSHS A ; SAVE IT BACK ON STACKLSRA ; CONVERT UPPER HEX NIBBLE TO ASCIILSRA ;LSRA ;LSRA ;BSR XASCII ; PRINT HEX NIBBLE AS ASCIIOUTHR PULS A ; CONVERT LOWER HEX NIBBLE TO ASCIIANDA #$0F ; STRIP LEFT NIBBLEXASCII ADDA #$30 ; ASCII ADJCMPA #$39 ; IS IT < OR = "9" ?BLE OUTC ; IF LESS, OUTPUT ITADDA #7 ; IF > MAKE ASCII LETTEROUTC 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 STACKLDB #8 ; PRESET LOOP# TO BITS PER BYTEOUTBA LDA ,X+ ; GET LETTER FROM STRINGASL ,S ; TEST BYTE FOR "1" IN B7BCS PRTBA ; IF ONE PRINT LETTERLDA #'- ; IF ZERO PRINT "-"PRTBA BSR OUTCH ; PRINT ITBSR OUT1S ; PRINT SPACEDECB ; SUB 1 FROM #BITS YET TO PRINTBNE OUTBAPULS A,PC*IFD EXTOPT** EXTENDED USER COMMANDS*USRCMD JMP [MONEXT+EXTCMD]ENDIF EXTOPT**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 TERMINALANDA #$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 IXIFD HFCOPTLDA #$11 ; SET RTS* LOW, REQUEST FAR END TO TXSTA [CPORT]ENDIF HFCOPTGETSTA LDX CPORT ; POINT TO TERMINAL PORTLDA ,X ; FETCH PORT STATUSBITA #1 ; TEST READY BIT, RDRF ?IFD PS2OPTBNE GETST1LDX #PS2KBDLDA ,XBITA #1ENDIF PS2OPTBEQ GETSTA ; IF NOT RDY, THEN TRY AGAINGETST1 EQU *IFD HFCOPTLDA #$51 ; SET RTS* HIGH, STOP FAR END FROM TXING, UNTIL NEXT INPUTSTA [CPORT]ENDIF HFCOPTLDA 1,X ; FETCH CHARPULS X,PC ; RESTORE IX** 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 ACCUMIFD HFCOPTLDA #$11 ; SET RTS* LOW, REQUEST FAR END TO TXSTA [CPORT]ENDIF HFCOPTLDA [CPORT] ; FETCH PORT STATUSBITA #1 ; TEST READY BIT, RDRF ?IFD PS2OPTBNE INCHEK1LDA PS2KBDBITA #1 ; TEST READY BIT< RDRF ?ENDIF PS2OPTINCHEK1 PULS A,PC ; RESTORE A ACCUM.*OUT2S BSR OUT1S ; OUTPUT 2 SPACESOUT1S 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 IFD VDUOPTBSR VOUTCHENDIF VDUOPTIFD DG640OPTBSR VOUTCHENDIF DG640OPTAOUTCH PSHS A,X ; SAVE A ACCUM AND IXLDX CPORT ; GET ADDR. OF TERMINALFETSTA LDA ,X ; FETCH PORT STATUSBITA #2 ; TEST TDRE, OK TO XMIT ?BEQ FETSTA ; IF NOT LOOP UNTIL RDYBITA #8 ; CLEAR TO SEND ?BNE FETSTA ; NO, LOOP UNTIL CLEARPULS A ; GET CHAR. FOR XMITSTA 1,X ; XMIT CHAR.PULS X,PC ; RESTORE IX** IO INITIALIZATION*IOINIZ EQU *IFD VDUOPTBSR VINIZENDIF VDUOPTIFD DG640OPTBSR VINIZENDIF DG640OPTACINIZ LDX CPORT ; POINT TO CONTROL PORT ADDRESSLDA #3 ; RESET ACIA PORT CODESTA ,X ; STORE IN CONTROL REGISTERLDA #$51 ; SET 8 DATA, 2 STOP AN 0 PARITY RTS* HIGHSTA ,X ; STORE IN CONTROL REGISTERTST 1,X ; ANYTHING IN DATA REGISTER?LDA #$FF ; TURN ON ECHO FLAGSTA ECHORTS*IFD VDUOPT***************************************************** VDU8 ADM3A REGISTER-MAPPED EMULATOR ** ** 80 x 25 Characters********************************************************************************************************* INITIALIZE EMULATOR *****************************************************VINIZ LDX #VDULDD #0STD COLADX ; AND ROWADXSTA VDUCOL,XSTB VDUROW,XSTB VDUOFF,XSTD NEWROW ; AND ESCFLGLDB #$02STB VDUATT,XCLR ESCFLGLDA #$1B ; SEND ESCAPEBSR VOUTCHLDA #'Y ; CLEAR TO END OF SCREEN*** VIDEO OUTPUT ROUTINE*VOUTCH PSHS A,B,X ; SAVE REGISTERSLDX #VDU ; POINT TO VDU REGISTERS*** CHECK FOR ESCAPE SEQUENCE*TST ESCFLG ; ESCAPE ACTIVE?BEQ SOROU1 ; BRANCH IF NOTBSR ESCAPE ; ELSE DO ESCAPEBRA RETURN ; AND RETURN*** CHECK FOR CONTROL CHARACTERS*SOROU1 CMPA #$20 ; CONTROL CODES?BHS SOROU2BSR CONTRL ; BRANCH IF SOBRA RETURN*** OUTPUT TEXT CHARACTER*SOROU2 STA VDUCHR,X ; DISPLAY CHARACTERLBSR NEWCOL ; UPDATE COLUMN*** DISPLAY CURSOR AND RETURN*RETURN PULS A,B,X,PC ; RESTORE REGISTERS AND RETURN***************************************************** CONTROL CODE HANDLERS *****************************************************CONTRL CMPA #$08 ; CTRL H - BACKSPACE ?BEQ BACKSPCMPA #$1B ; ESCAPE SEQUENCE?BEQ SETESCCMPA #$1A ; CTRL Z - Clear ScreenLBEQ CLRSCRCMPA #$16 ; CTRL ^ - HomeBEQ HOMECMPA #$0D ; CTRL M - RETURN?LBEQ CRETNCMPA #$0C ; CTRL L - CHAR RIGHTBEQ CHRIGHTCMPA #$0B ; CTRL K - MOVE UP ONE LINEBEQ LINEUPCMPA #$0A ; CTRL J - LINE FEEDBNE RETESC ; NONE OF THESE, RETURN****************************************** LINE FEED*LINEFD LDD COLADX ; GET CURRENT COLUMN AND ROWINCB ; BUMP ROWCMPB #NUMLIN ; SCROLL TIME?BNE NEWCUR ; POSITION CURSOR IF NOTLBRA SCROLL ; ELSE SCROLL IT****************************************** LINE FEED*LINEUP LDD COLADX ; GET CURRENT COLUMN AND ROWTSTB ; AT TOP OF SCREEN ?BEQ RETESC ; Yes, IgnoreDECB ; No, Decrement ROWBRA NEWCUR ; POSITION CURSOR************************************ BACK SPACE*BACKSP LDA COLADXBEQ RETESC ; RETURNDECABRA POSCOL ; POSITION CURSOR************************************ CURSOR RIGHT*CHRIGHT LDA COLADXINCACMPA #LINLENBEQ RETESCBRA POSCOL************************************ CURSOR RIGHT*HOME LDD #0 ; HOME - POSITION TOP OF SCREENBRA NEWCUR***************************************************** ESCAPE HANDLERS *****************************************************ESCAPE LDB ESCFLG ; GET FLAGCMPB #'= ; SETTING CURSOR?BEQ ESCCUR ; BRANCH IF SOCMPA #'Y ; CLEAR TO END OF SCREEN?BEQ ESCCLSCMPA #'T ; CLEAR TO END OF LINE?BEQ ESCCLLCMPA #'= ; STARTING CURSOR SET?BNE CLRESC ; BRANCH IF NOT****************************** START ESCAPE SEQUENCE*SETESC STA ESCFLG ; ELSE START CURSORINGRTS ; AND RETURN*CLRESC CLR ESCFLG ; NO OTHERS SUPPORTEDRETESC RTS ; SO RETURN********************************** SET SCREEN CURSOR*ESCCUR TST NEWROW ; ROW SET?BNE ESCCU1 ; BRANCH IF SOSTA NEWROW ; ELSE SET NEW ROWRTS ; AND RETURN*ESCCU1 CLR ESCFLGSUBA #$20 ; ADJUST COLUMN ADDRESSCMPA #LINLEN-1 ;CHECK FOR ACCEPTABLE COLUMBHI RETESC ; NOT OK, DO NOTHING*ESCCU2 LDB NEWROWCLR NEWROWSUBB #$20 ; ADJUST TO ROW ADDRESSCMPB #NUMLIN-1 ; CHECK FOR ACCEPTABLE ROWBHI RETESC ; ELSE RETURN DOING NOTHINGBRA NEWCUR ; GO SET NEW CURSOR IF SO******************* CLEAR FROM CURSOR TO END OF LINE*CLRSCR LDD #0 ; CLEAR FROM TOP OF SCREENBSR NEWCURESCCLL LDA COLADXLDB #$20 ; AND CLEAR CHARESCCL1 STB VDUCHR,X ; DISPLAY TEXTINCASTA VDUCOL,XCMPA #LINLEN ; UNTIL END OF LINEBNE ESCCL1CLR ESCFLGRTS************************************ CARRIAGE RETURN*CRETN CLRA ; SET COLUMN ZEROPOSCOL LDB ROWADX ; GET CURRENT ROW************ GENERATE NEW CURSOR POSITION AND RETURN*NEWCUR STD COLADX ; SAVE NEW ROW AND COLUMNSTA VDUCOL,X ; SET NEW COLUMNSTB VDUROW,X ; SET NEW ROWRTS ; AND RETURN********************** UPDATE CURRENT COLUMN AND ROW*NEWCOL LDD COLADX ; GET ROW AND COLUMNINCA ; BUMP COLUMNCMPA #LINLEN ; ROLL?BNE NEWCUR ; BRANCH IF NOTCLRA ; ELSE RESET TO ZEROINCB ; AND BUMP ROWCMPB #NUMLINBNE NEWCURDECB ; BOTTOM ROWBSR NEWCUR********************************** SCROLL THE SCREEN*SCROLL LDB VDUOFF,XINCBCMPB #NUMLINBLO SCROL1CLRBSCROL1 STB VDUOFF,X***************** CLEAR FROM CURSOR TO END OF SCREEN*ESCCLS LDB COLADX ; GET CURSORLDA #$20 ; GET A SPACEESCCLS1 STB COLADXSTB VDUCOL,XSTA VDUCHR,XINCBCMPB #LINLENBNE ESCCLS1*LDB ROWADXINCBCMPB #NUMLINBEQ ESCCLS2STB ROWADXSTB VDUROW,XCLRBBRA ESCCLS1*ESCCLS2 CLRBSTB COLADXSTB VDUCOL,XSTB ESCFLGRTSENDIF VDUOPT*IFD DG640OPT**************************************************** TELEVIDEO-TYPE MEMORY-MAPPED EMULATOR ** ** FOR HARD-WIRED MEMORY-MAPPED DISPLAYS USING THE ** HIGH ORDER BIT OF EACH BYTE FOR REVERSE VIDEO ** CURSORING (SUCH AS THE THOMAS INSTRUMENTATION ** 16x64 BOARD). ********************************************************************************************************* INITIALIZE EMULATOR *****************************************************VINIZ LDX #0STX COLADX ; AND ROWADXSTX NEWROW ; AND ESCFLGLDX #SCREEN ; POINT TO SCREENSTX CURSOR ; SET PROGRAM CURSORLDA #$1B ; SEND ESCAPEBSR VOUTCHLDA #'Y ; CLEAR TO END OF SCREEN*** VIDEO OUTPUT ROUTINE*VOUTCH PSHS A,B,X ; SAVE REGISTERS*** CLEAR CURSOR*LDX CURSORLDB 0,XANDB #$7FSTB 0,X*** CHECK FOR ESCAPE SEQUENCE*TST ESCFLG ; ESCAPE ACTIVE?BEQ SOROU1 ; BRANCH IF NOTBSR ESCAPE ; ELSE DO ESCAPEBRA RETURN ; AND RETURN*** CHECK FOR CONTROL CHARACTERS*SOROU1 CMPA #$20 ; CONTROL CODES?BHS SOROU2BSR CONTRL ; BRANCH IF SOBRA RETURN*** OUTPUT TEXT CHARACTER*SOROU2 LDX CURSOR ; ELSE GET CURSORSTA 0,X ; DISPLAY CHARACTERLBSR NEWCOL ; UPDATE COLUMN*** DISPLAY CURSOR AND RETURN*RETURN LDX CURSOR ; AND DISPLAY ITLDB ,XORB #$80 ; WITH REVIDSTB ,XPULS A,B,X,PC ; RESTORE REGISTERS AND RETURN***************************************************** CONTROL CODE HANDLERS *****************************************************CONTRL CMPA #$08 ; CTRL H - BACKSPACE ?LBEQ BACKSPCMPA #$1B ; ESCAPE SEQUENCE?LBEQ SETESCCMPA #$D ; CTRL M - RETURN?LBEQ CRETNCMPA #$0A ; CTRL J - LINE FEEDBNE RETESC ; NONE OF THESE, RETURN****************************************** LINE FEED*LINEFD LDD COLADX ; GET CURRENT COLUMN AND ROWINCB ; BUMP ROWCMPB #NUMLIN ; SCROLL TIME?LBNE NEWCUR ; POSITION CURSOR IF NOTLBRA SCROLL ; ELSE SCROLL IT****************************************** LINE FEED*LINEUP LDD COLADX ; GET CURRENT COLUMN AND ROWTSTB ; AT TOP OF SCREEN ?BEQ RETESC ; YES, RETURNDECB ; NO, DECREMENT ROWLBRA NEWCUR ; POSITION CURSOR************************************ BACK SPACE*BACKSP LDA COLADX ; GET CURRENT COLUMN AND ROWBEQ RETESC ; IF AT TOP LEFT CORNER RETURNDECA ; OTHERWISE BACK STEP ONE CHARACTERLBRA POSCOL ; POSITION CURSOR************************************ CURSOR RIGHT*CHRIGHT LDA COLADX ; GET CURRENT COLUMN AND ROWINCA ; MOVE RIGHT ONE CHARACTERCMPA #LINLEN ; ARE WE AT THE END OF THE LINE ?BEQ RETESC ; YES, RETURNLBRA POSCOL ; NO, POSITION CURSOR***************************************************** ESCAPE HANDLERS *****************************************************ESCAPE LDB ESCFLG ; ARE WE IN AN ESCAPE SEQUENCE ?CMPB #'= ; ARE WE SETTING CURSOR?BEQ ESCCUR ; YES BRANCH TO SET CURSORCMPA #'Y ; CLEAR TO END OF SCREEN?LBEQ ESCCLS ; YES, CLEAR SCREENCMPA #'T ; CLEAR TO END OF LINE?BEQ ESCCLL ; YES, CLEAR LINECMPA #'E ; INSERT LINE?BEQ ESCINLCMPA #'R ; DELETE LINE?BEQ ESCDLLCMPA #'= ; STARTING CURSOR SET?BNE CLRESC ; BRANCH IF NOT****************************** START ESCAPE SEQUENCE*SETESC STA ESCFLG ; ELSE START CURSORINGRTS ; AND RETURN*CLRESC CLR ESCFLG ; NO OTHERS SUPPORTEDRETESC RTS ; SO RETURN********************************** SET SCREEN CURSOR*ESCCUR TST NEWROW ; ROW SET?BNE ESCCU1 ; BRANCH IF SOSTA NEWROW ; ELSE SET NEW ROWRTS ; AND RETURN*ESCCU1 CLR ESCFLGSUBA #$20 ; ADJUST COLUMN ADDRESSCMPA #LINLEN-1 ; CHECK FOR ACCEPTABLE COLUMBHI RETESC ; NOT OK, DO NOTHING*ESCCU2 LDB NEWROWCLR NEWROWSUBB #$20 ; ADJUST TO ROW ADDRESSCMPB #NUMLIN-1 ; CHECK FOR ACCEPTABLE ROWBHI RETESC ; ELSE RETURN DOING NOTHINGBRA NEWCUR ; GO SET NEW CURSOR IF SO**************************** DELETE LINE FROM SCREEN*ESCDLL BSR CRETN ; GO COL. ZEROLDB ROWADXCMPB #NUMLIN-1BEQ SCROL3BRA SCROL1 ; AND DELETE THIS LINE**************************** INSERT LINE INTO SCREEN*ESCINL BSR CRETN ; GO TO COL. ZEROLDB ROWADXCMPB #NUMLIN-1BEQ ESCCLL*** SCROLL SCREEN DOWN FROM CURSOR*LDX #SCREEN+SCNLEN-LINLENESCIN0 LDA ,-XSTA LINLEN,XLDA SCNLEN,XSTA SCNLEN+LINLEN,XCMPX CURSORBNE ESCIN0******************* CLEAR FROM CURSOR TO END OF LINE*ESCCLL LDA COLADX ; GET CURRENT COLUMNLDX CURSOR ; GET CURSORLDB #$20 ; AND CLEAR CHARESCLL1 STB SCNLEN,X ; CLEAR ATTRIBUTESTB ,X+ ; CLEAR TEXTINCACMPA #LINLEN ; UNTIL END OF LINEBNE ESCLL1CLR ESCFLGRTS************************************ CARRIAGE RETURN*CRETN CLRA ; SET COLUMN ZEROPOSCOL LDB ROWADX ; GET CURRENT ROW************ GENERATE NEW CURSOR POSITION AND RETURN*NEWCUR STD COLADX ; SAVE NEW ROW AND COLUMNLDA #LINLEN ; ELSE ADD A LINEMUL ; LINLEN * ROWADXADDB COLADXADCA #0ADDD #SCREEN ; ADD SCREEN BASE.STD CURSOR ; SAVE NEW CURSORTFR D,X ; GET CURSOR IN XRTS ; AND RETURN********************** UPDATE CURRENT COLUMN AND ROW*NEWCOL LDD COLADX ; GET ROW AND COLUMNINCA ; BUMP COLUMNCMPA #LINLEN ; ROLL?BNE NEWCUR ; BRANCH IF NOTCLRA ; ELSE RESET TO ZEROINCB ; AND BUMP ROWCMPB #NUMLINBNE NEWCURDECB ; BOTTOM ROWBSR NEWCUR********************************** SCROLL THE SCREEN*SCROLL LDX #SCREEN ; POINT TO SCREENSCROL1 LDA SCNLEN+LINLEN,XSTA SCNLEN,XLDA LINLEN,X ; MOVE TWO BYTESSTA ,X+ ; UP ONE LINECMPX #SCREEN+SCNLEN-LINLENBNE SCROL1 ; LOOP UNTIL DONEBRA SCROL3***************** CLEAR FROM CURSOR TO END OF SCREEN*ESCCLS LDX CURSOR ; GET CURSORSCROL3 LDA #$20 ; GET A SPACESCROL2 STA SCNLEN,X ; CLEAR ATTRIBUTESSTA ,X+ ; AND TEXTCMPX #SCREEN+SCNLENBNE SCROL2 ; UNTIL DONECLR ESCFLGRTSENDIF DG640OPT*IFD PRTOPT**************************************** PRINTER DRIVER ROUTINES***************************************** PINIZ - INITIATE PRINTER PORT*PINIZ PSHS BLDD #DIRMSK*256+$04 ; ACCA=DIRMSK ACCB=$04STD PADATA ; SET DDR AND SELECT DATA*** RESET PRINTER*LDB #PRESETSTB PADATARESTLP INCB ; DELAY FOR RESETBNE RESTLPSTA PADATA ; ACCA=DIRMSK*** INITALIZE PORT B (DATA PORT)*LDA #$2ASTA PBCTRLLDD #$FF2E ; ACCA=$FF ACCB =%00101110STD PBDATA ; PBDREG PBCTRL*** SELECT 66 LINES/PAGE*LDA #$1BBSR POUTCHLDA #'CBSR POUTCHLDA #66PULS B**************************************** OUTPUT A CHARACTER TO THE PRINTER**************************************POUTCH PSHS BLDB PBDATA ; CLEAR INTERRUPT BIT*** WAIT TILL NOT BUSY*BUSYLP LDB PADATABITB #PERRORBEQ PEXITTSTBBMI BUSYLP*** NOW OUTPUT CHARACTER*STA PBDATAPEXIT PULS B,PC**************************************** PCHK TEST IFD PRINTER READY**************************************PCHK TST PBCTRL ; TEST STATE OF CRB7RTS ; SET ON ACKNOWLEDGEENDIF PRTOPT*************************************** MONITOR KEYBOARD COMMAND JUMP TABLE***************************************JMPTAB EQU *FCB 1 " ^A "FDB ALTRAFCB 2 " ^B "FDB ALTRBFCB 3 " ^C "FDB ALTRCCFCB 4 " ^D "FDB ALTRDPFCB $10 " ^P "FDB ALTRPCFCB $15 " ^U "FDB ALTRUFCB $18 " ^X "FDB ALTRXFCB $19 " ^Y "FDB ALTRY*FCC 'B'FDB BRKPNTFCC 'E'FDB MEMDUMPFCC 'G'FDB GOFCC 'L'FDB LOADFCC 'P'FDB PUNCHFCC 'M'FDB MEMCHGFCC 'R'FDB REGSTRFCC 'S'FDB DISSTKFCC 'X'FDB XBKPNTIFD MFDCOPTFCC 'D' ; *** SWTPC USES 'U' FOR MINIBOOTFDB MINBOOTENDIF MFDCOPTIFD CF8OPTFCC 'D' ; *** FPGA 8 BIT USES 'D' FOR CFBOOTFDB CFBOOTENDIF CF8OPTIFD IDEOPTFCC 'D' ; *** XESS FPGA 16 BIT IDE USES 'D' FOR IDEBOOTFDB IDEBOOTENDIF IDEOPTIFD DMAFOPTFCC 'U' ; *** SWTPC USES 'D' FOR DMAF2 BOOTFDB DBOOTENDIF DMAFOPTIFD EXTOPTFCC 'U' ; *** IF FPGA, 'U' IS FOR USERFDB USRCMDENDIF EXTOPTIFD RTCOPTFCC 'T'FDB TIMSETENDIF RTCOPTIFD TRAOPTFCC "T"FDB TRACEENDIF TRAOPT*TABEND EQU *** ** 6809 VECTOR ADDRESSES **** FOLLOWING ARE THE ADDRESSES OF THE VECTOR ROUTINES* FOR THE 6809 PROCESSOR. DURING INITIALIZATION THEY* ARE RELOCATED TO RAM FROM $DFC0 TO $DFCF. THEY ARE* RELOCATED TO RAM SO THAT THE USER MAY REVECTOR TO* HIS OWN ROUTINES IF HE SO DESIRES.**RAMVEC FDB SWIE ; USER-VFDB RTI ; SWI3-VFDB RTI ; SWI2-VFDB RTI ; FIRQ-VFDB RTI ; IRQ-VFDB SWIE ; SWI-VFDB $FFFF ; SVC-VOFDB $FFFF ; SVC-VL** PRINTABLE MESSAGE STRINGS*MSG1 FCB $D,$A,$0,$0,$0 * 0, CR/LF, 0FCC 'Sys09Bug 1.7 FOR 'IFD SWTOPTFCC 'SWTPC'ENDIF SWTOPTIFD ADSOPTFCC 'ADS6809'ENDIF ADSOPTIFD B3SOPTFCC 'B3-S2+'ENDIF B3SOPTIFD B5XOPTFCC 'B5-X300'ENDIF B5XOPTIFD S3SOPTFCC 'S3STARTER'ENDIF S3SOPTIFD S3EOPTFCC 'S3E'ENDIF S3EOPTIFD XESOPTFCC 'XESS'ENDIF XESOPTIFD ATLOPTFCC 'Atlys'ENDIF ATLOPTIFD DE270OPTFCC 'DE2-70'ENDIF DE270OPTFCC ' - 'FCB 4MSG2 FCB 'K,$0D,$0A,$00,$00,$00,$04 ; K,<CR>,<LF>,3 NULS,<EOT>MSG3 FCC '>'FCB 4MSG4 FCC 'WHAT?'FCB 4MSG5 FCC ' - 'FCB 4'MSG10 FCC ' SP='FCB 4MSG11 FCC ' PC='FCB 4MSG12 FCC ' US='FCB 4MSG13 FCC ' IY='FCB 4MSG14 FCC ' IX='FCB 4MSG15 FCC ' DP='FCB 4MSG16 FCC ' A='FCB 4MSG17 FCC ' B='FCB 4MSG18 FCC ' CC: 'FCB 4MSG19 FCC 'EFHINZVC'MSG20 FCC 'S1'FCB 4IFD DATOPT** POWER UP/ RESET/ NMI ENTRY POINT*ORG $FF00**START LDX #IC11 ; POINT TO DAT RAM IC11LDA #$0F ; 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 LOCATIONDECA ; GET COMP. VALUE FOR NEXT LOCATIONBNE DATLP ; ALL 16 LOCATIONS INITIALIZED ?** NOTE: IX NOW CONTAINS $0000, DAT RAM IS NO LONGER* ADDRESSED, AND LOGICAL ADDRESSES NOW EQUAL* PHYSICAL ADDRESSES.*LDA #$F0STA ,X ; STORE $F0 AT $FFFFLDX #$D0A0 ; ASSUME RAM TO BE AT $D000-$DFFFLDY #TSTPAT ; LOAD TEST DATA PATTERN INTO "Y"TSTRAM LDU ,X ; SAVE DATA FROM TEST LOCATIONSTY ,X ; STORE TEST PATTERN AT $D0A0CMPY ,X ; IS THERE RAM AT THIS LOCATION ?BEQ CNVADR ; IF MATCH THERE'S RAM, SO SKIPLEAX -$1000,X ; ELSE POINT 4K LOWERCMPX #$F0A0 ; DECREMENTED PAST ZER0 YET ?BNE TSTRAM ; IF NOT CONTINUE TESTING FOR RAMBRA 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 LOCATIONTFR X,D ; PUT ADDR. OF PRESENT 4K BLOCK IN DCOMA ; COMPLEMENT MSB OF THAT ADDRESSLSRA ; PUT MS 4 BITS OF ADDRESS INLSRA ; LOCATION D0-D3 TO ALLOW STORINGLSRA ; IT IN THE DYNAMIC ADDRESSLSRA ; 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. TABLESTA 13,Y ; STORE $D--- XLATION FACTOR AT $DFDDCLR 14,Y ; CLEAR $DFDELDA #$F0 ; DESTINED FOR IC8 AN MEM EXPANSION ?STA 15,Y ; STORE AT $DFDFLDA #$0C ; PRESET NUMBER OF BYTES TO CLEARCLRLRT CLR A,Y ; CLEAR $DFDC THRU $DFD0DECA ; SUB. 1 FROM BYTES LEFT TO CLEARBPL CLRLRT ; CONTINUE IF NOT DONE CLEARINGFNDRAM LEAX -$1000,X ; POINT TO NEXT LOWER 4K OF RAMCMPX #$F0A0 ; TEST FOR DECREMENT PAST ZEROBEQ FINTAB ; SKIP IF FINISHEDLDU ,X ; SAVE DATA AT CURRENT TEST LOCATIONLDY #TSTPAT ; LOAD TEST DATA PATTERN INTO Y REG.STY ,X ; STORE TEST PATT. INTO RAM TEST LOC.CMPY ,X ; VERIFY RAM AT TEST LOCATIONBNE FNDRAM ; IF NO RAM GO LOOK 4K LOWERSTU ,X ; ELSE RESTORE DATA TO TEST LOCATIONLDY #LRARAM ; POINT TO LOGICAL/REAL ADDR. TABLETFR X,D ; PUT ADDR. OF PRESENT 4K BLOCK IN DLSRA ; PUT MS 4 BITS OF ADDR. IN LOC. D0-D3LSRA ; TO ALLOW STORING IT IN THE DAT RAM.LSRALSRATFR A,B ; SAVE OFFSET INTO LRARAM TABLEEORA #$0F ; INVERT MSB OF ADDR. OF CURRENT 4K BLKSTA B,Y ; SAVE TRANSLATION FACTOR IN LRARAM TABLEBRA FNDRAM ; GO TRANSLATE ADDR. OF NEXT 4K BLKFINTAB LDA #$F1 ; DESTINED FOR IC8 AND MEM EXPANSION ?LDY #LRARAM ; POINT TO LRARAM TABLESTA 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 AN 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 TABLEBNE FOUNDC ; BRANCH IF RAM THIS PHYSICAL ADDR.DECA ; ELSE POINT 4K LOWERBPL FINDC ; GO TRY AGAINBRA XFERTFFOUNDC CLR A,Y ; CLR XLATION FACTOR OF 4K BLOCK FOUNDSTB $0C,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 ZEROTFR Y,X ; START POINTER "X" START OF "LRARAM" TABLE.COMPRS LDB A,Y ; GET ENTRY FROM "LRARAM" TABLEBEQ PNTNXT ; IF IT'S ZER0 SKIPCLR A,Y ; ELSE ERASE FROM TABLESTB ,X+ ; AND ENTER ABOVE LAST ENTRY- BUMPPNTNXT INCA ; GET OFFSET TO NEXT ENTRYCMPA #$0C ; LAST ENTRY YET ?BLT COMPRS** THE FOLLOWING CODE TRANSFER THE TRANSLATION* FACTORS FROM THE LRARAM TABLE TO IC11 ON* THE MP-09 CPU CARD.*XFERTF LDX #IC11 ; POINT TO DAT RAM IC11LDB #$10 ; GET NO. OF BYTES TO MOVEFETCH LDA ,Y+ ; GET BYTE AND POINT TO NEXTSTA ,X+ ; POKE XLATION FACTOR IN IC11DECB ; SUB 1 FROM BYTES TO MOVEBNE FETCH ; CONTINUE UNTIL 16 MOVED*ELSELRA RTSSTART LDS #STACK ; INITIALIZE STACK POINTERCLRBENDIF DATOPT*COMB ; SET "B" NON-ZEROSTB ECHO ; TURN ON ECHO FLAGLBRA MONITOR ; INITIALIZATION IS COMPLETE*** INTERRUPT JUMP VECTORS*V1 JMP [STACK]V2 JMP [SWI2]V3 JMP [FIRQ]V4 JMP [IRQ]V5 JMP [SWI]** SWI3 ENTRY POINT*SWI3E TFR S,ULDX 10,U *$FFC8LDB ,X+STX 10,UCLRAASLBROLALDX SVCVOCMPX #$FFFFBEQ SWI3ZLEAX D,XCMPX SVCVLBHI SWI3ZPSHS XLDD ,ULDX 4,UJMP [,S++]SWI3Z PULU A,B,X,CC,DPLDU 2,UJMP [SWI3]** 6809 VECTORS*ORG $FFF0FDB V1 USER-VFDB SWI3E SWI3-VFDB V2 SWI2-VFDB V3 FIRQ-VFDB V4 IRQ-VFDB V5 SWI-VFDB V1 NMI-VFDB START RESTART-VEND START
