* NAM SYS09BUG12 SYSTEM09 MONITOR OPT l PAGE * * 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 * FOR: SYSTEM09 FPGA SYSTEM * 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 * FOR: SYSTEM09 FPGA SYSTEM * 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 * FOR: SYSTEM09 FPGA SYSTEM * BY: JOHN KENT * DATE: 8TH JAN 2008 * ADDED: CONDITIONALS FOR SPARTAN3E STARTER BOARD * WITH ONLY 32K OF RAM * * Modified to SYS09BUG VER 1.4 * FOR: SYSTEM09 FPGA SYSTEM * 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 * FOR: SYSTEM09 FPGA SYSTEM * BY: JOHN KENT * DATE: 7TH SEP 2008 * ADDED: ADDED "B3-S2+" STRING * * Modified to SYS09BUG VER 1.6 * FOR: SYSTEM09 FPGA SYSTEM * BY: JOHN KENT * DATE: 2ND DEC 2008 * ADDED: ADDED HARDWARE FLOW CONTROL * * CHANGED: SEPARARTED OPTIONS EQUATES AND BODY INTO SEPARATE FILES * * *** 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 MONRAM STACK EQU * ; TOP OF INTERNAL STACK NMI RMB 2 ; USER NMI 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 IFD DATOPT LRARAM RMB 16 ; LRA ADDRESSES ENDIF DATOPT CPORT RMB 2 ; RE-VECTORABLE CONTROL PORT ECHO RMB 1 ; ECHO FLAG BPTBL RMB 24 ; BREAKPOINT TABLE BASE ADDR IFD TRAOPT NMISAV RMB 2 ; NMI Jump Vector Backup TRACNT RMB 2 ; Trace Count ENDIF TRAOPT IFD VDUOPT * ************************************************** * VDU8 DISPLAY DRIVER VARIABLES * ************************************************** * **** ALWAYS KEEP COLADX AND ROWADX TOGETHER ****** COLADX RMB 1 ; CURSOR COLUMN ROWADX RMB 1 ; CURSOR ROW ************************************************** * NEWROW RMB 1 ; NEW ROW TEMP FOR ESCAPE ESCFLG RMB 1 ; ESCAPE SEQUENCE ACTIVE ENDIF VDUOPT IFD DG640OPT * *************************************************** * DG640 MEMORY MAPPED DISPLAY DRIVER VARIABLES * *************************************************** * ***** ALWAYS KEEP THESE TWO BYTES TOGETHER ***** COLADX RMB 1 ; CURSOR COLUMN ROWADX RMB 1 ; CURSOR ROW ************************************************* CURSOR RMB 2 ; ABSOLUTE SCREEN ADDRESS NEWROW RMB 1 ; NEW ROW TEMP FOR ESCAPE ESCFLG RMB 1 ; ESCAPE SEQUENCE ACTIVE ENDIF DG640OPT * * *************************************************** * START OF ROM * *************************************************** * ORG MONROM FDB MONITOR FDB NEXTCMD FDB INCH FDB INCHE FDB INCHEK FDB OUTCH FDB PDATA FDB PCRLF FDB PSTRNG FDB LRA * IFD ADSOPT FDB PCHK ; CHECK FOR PRINTER INPUT FDB PINIZ ; INITIATE PRINTER FDB POUTCH ; OUTPUT CH. TO PRINTER FDB VINIZ FDB VOUTCH FDB ACINIZ FDB AOUTCH ENDIF ADSOPT * * 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 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 IOINIZ ; INITIALIZE CONTROL PORT LDX #MSG1 ; POINT TO MONITOR MESSAGE LBSR PDATA ; PRINT MSG * IFD DATOPT 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 ENDIF DATOPT * IFD TRAOPT LBSR TRAINZ ENDIF TRAOPT * ***** 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 * ***** "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 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 ; 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 * ***** "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 * IFD TRAOPT LDX #0 STX TRACNT ENDIF TRAOPT * 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 * IFD TRAOPT * ** TRACE from address AAAA BB bytes * TRACE LBSR ALTPC1 ; SET UP NEW PC BVS TREXIT ; ADDRESS ERROR, EXIT LBSR OUT1S LBSR IN1ADR ; Fetch Byte Count BVS TREXIT ; Byte Count error, EXIT STX TRACNT * LDX NMI ; Save NMI Vector STX NMISAV LDX #NMIE ; Set up NMI for Tracing STX NMI LBSR TRAINZ ; Initialise Hardware BRA TRACEG ; Start Trace TREXIT 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,U LDA #$36 ; Disable Interrupt, CA2 Low STA TACTRL LDA TADATA ; Clear Interrupt flag by reading data port * LBSR REGSTR ; DUMP REGISTERS * LDX 10,U ; TEST IF NEXT INSTRUCTION IS A SWI LDA ,X CMPA #$3F BEQ TRACEX ; EXIT ON SWI * LDX TRACNT ; CHECK IF TRACE COUNT EXPIRED BEQ TRACEX ; YES, GO BACK TO THE MONITOR LEAX -1,X ; ECREMENT TRACE COUNT STX TRACNT * ** TRACE GO (RESUME SINGLE STEP) * TRACEG TFR U,S ; SET UP PROGRAM STACK POINTER LDA #TRADEL ; SET UP TIMER DELAY (NUMB CYCLES FOR RTI+1) STA TADATA LDA #$36 ; LOAD STROBE LOW STA TACTRL LDA TADATA ; CLEAR INTERRUPT LDA #$36 ; RELEASE RESET STA TBCTRL LDA #$3F ; RELEASE LOAD, ENABLE CA1 NMI, CA1 RISING EDGE STA TACTRL RTI ; GO EXECUTE INSTRUCTION * TRACEX LDX NMISAV ; Restore NMI vector STX NMI LBRA NEXTCMD ; Jump back to the command loop. * ** TRACE HARDWARE INITIALISATION * TRAINZ LDA #$32 ; SELECT DDRA, CA2 LOW, NMI DISABLED STA TACTRL LDA #$3A ; SELECT DDRB, CB2 HIGH, FIRQ DISABLED STA TBCTRL LDA #$FF ; PORTA = OUTPUT STA TADATA LDA #$00 ; PORTB = INPUT STA TBDATA LDA #$36 ; SELECT OUTPUT REGISTER A, CA2 LOW STA TACTRL LDA #$3E ; SELECT OUTPUT REGISTER B, CB2 HIGH STA TBCTRL RTS * ENDIF TRAOPT IFD MFDCOPT * ** "U" MINI DISK BOOT * MINBOOT TST CMDFDC CLR DRVFDC LDX #$0000 LOOP LEAX $01,X CMPX #$0000 BNE LOOP LDA #$0F STA CMDFDC BSR DELAY LOOP1 LDB CMDFDC BITB #$01 BNE LOOP1 LDA #$01 STA SECFDC BSR DELAY LDA #$8C STA CMDFDC BSR DELAY LDX #$C000 BRA LOOP3 LOOP2 BITB #$02 BEQ LOOP3 LDA DATFDC STA ,X+ LOOP3 LDB CMDFDC BITB #$01 BNE LOOP2 BITB #$2C BEQ LOOP4 RTS * LOOP4 LDX #$C000 STX $0A,U TFR U,S RTI * DELAY LDB #$04 LOOP5 DECB BNE LOOP5 RTS ENDIF MFDCOPT * IFD DMAFOPT * *** "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 ; ENDIF DMAFOPT * IFD CF8OPT * * COMPACT FLASH BOOT * CFBOOT BSR WAITRDY LDA #HEADLBA STA CF_HEAD BSR WAITRDY LDA #FEAT8BIT STA CF_FEATURE LDA #CMDFEATURE STA CF_COMAND BSR WAITRDY * * READ SECTORS FROM CF * CFREAD LDA #$01 STA CF_SECCNT CLRA STA CF_SECNUM STA CF_CYLLO STA CF_CYLHI * LDA #CMDREAD ; IDE READ MULTIPLE STA CF_COMAND BSR WAITRDY LDX #$C000 * * READ LOOP * RDLOOP BSR WAITDRQ LDA CF_DATA STA ,X+ CMPX #$C200 BNE RDLOOP * LDX #$C000 STX $0A,U TFR U,S RTI * * WAIT UNTIL READY * WAITRDY LDA CF_STATUS BITA #BUSY BNE WAITRDY LDA CF_STATUS BITA #DRDY BEQ WAITRDY RTS * * WAIT FOR DATA REQUEST * WAITDRQ LDA CF_STATUS BITA #DRQ BEQ WAITDRQ RTS ENDIF CF8OPT * IFD IDEOPT * * XESS 16 BIT IDE BOOT * IDEBOOT LDD #AUXRESET STD CF_AUX LDD #AUXRSTREL STD CF_AUX LDD #HEADLBA STD CF_HEAD BSR WAITRDY * * READ SECTORS FROM CF * LDD #$01 STD CF_SECCNT CLRB STD CF_SECNUM STD CF_CYLLO STD CF_CYLHI * LDB #CMDREAD ; IDE READ MULTIPLE STD CF_COMAND BSR WAITRDY LDX #$C000 * * READ LOOP * RDLOOP BSR WAITDRQ LDD CF_DATA STB ,X+ CMPX #$C100 BNE RDLOOP * LDX #$C000 STX $0A,U TFR U,S RTI * * WAIT UNTIL READY * WAITRDY LDD CF_STATUS BITB #BUSY BNE WAITRDY LDD CF_STATUS BITB #DRDY BEQ WAITRDY RTS * * WAIT FOR DATA REQUEST * WAITDRQ LDD CF_STATUS BITB #DRQ BEQ WAITDRQ RTS ENDIF IDEOPT * IFD RTCOPT * * CLOCK INTER FACE UTILITY * * TIME * 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 CLKSTA BNE RDCLK RDCLK1 LDA 0,X TST CLKSTA BNE RDCLK1 RTS * * MAIN PROGRAM: * TIMSET LDX #COUNTR ; POINT TO TIMER LBSR BYTE ; READ HOURS BVS SHOWTM ; NO ARG, DISP TIME STA HOUR,X LBSR OUT1S LBSR BYTE ; READ MINUITES BVS SHOWTM STA MINUIT,X LBSR OUT1S LBSR BYTE ; SECONDS. BVS SHOWTM STA SECOND,X * * DISPLAY CURRENT TIME * SHOWTM LBSR PCRLF LDX #COUNTR+HOUR LDB #3 SHOWLP BSR RDCLK LBSR OUT2H LDA #': LBSR OUTCH LEAX -1,X DECB BNE SHOWLP RTS * * INITIATE CLOCK. * MASK INTERRUPTS. * CLKINZ CLR CINTCR ; MASK ALL INTERRUPTS TST CINTSR ; CLEAR ANY INTERRUPTS RTS ENDIF RTCOPT IFD 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 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,PC ; POP REGS. FROM STACK ENDIF DATOPT * * 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,PC ; RESTORE CONTENTS OF "B" * RTS ; * ***** "L" LOAD MIKBUG TAPE ***** * LOAD JSR ACINIZ 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 LOAD1 ; 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 JSR ACINIZ 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 ; * * 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 LBSR PDATA ; PRINT MSG PULS X,PC ; RESTORE IX & RETURN * * LONG BRANCHES TO COMMON ROUTINES * JOUT1S LBRA OUT1S JBYTE LBRA BYTE JIN1ADR LBRA IN1ADR * * ALTER "PC" PROGRAM COUNTER * ALTRPC LBSR PRTPC ; $FCF5 PRINT MSG " PC = " ALTPC1 BSR JOUT1S ; OUTPUT SPACE BSR JIN1ADR ; 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 BSR PRTUS ; $FCCA PRINT MSG " US = " BSR JOUT1S ; OUTPUT SPACE BSR JIN1ADR ; GET NEW CONTENTS FOR "US" BVS ALTUD ; EXIT IF INVALID HEX STX 8,U ; POKE IN NEW CONTENTS ALTUD RTS ; * * ALTER "Y" INDEX REGISTER * ALTRY BSR PRTIY ; PRINT MSG " IY = " BSR JOUT1S ; OUTPUT SPACE BSR JIN1ADR ; GET NEW CONTENTS FOR "IY" BVS ALTYD ; EXIT IF INVALID HEX STX 6,U ; $F8F0 POKE IN NEW CONTENTS ALTYD RTS ; * * ALTER "X" INDEX REGISTER * ALTRX BSR PRTIX ; $FCE0 PRINT MSG " IX = " BSR JOUT1S ; OUTPUT SPACE BSR JIN1ADR BVS ALTXD STX 4,U ALTXD RTS ; * * ALTER "DP" DIRECT PAGE REGISTER * ALTRDP BSR PRTDP ; $FCD5 PRINT MSG " DP = " BSR JOUT1S ; OUTPUT SPACE BSR JBYTE ; INPUT BYTE (2 HEX CHAR) BVS ALTDPD STA 3,U ALTDPD RTS ; * * ALTER "B" ACCUMULATOR * ALTRB BSR PRTB ; $FD09 PRINT MSG " B = " BSR JOUT1S ; OUTPUT SPACE BSR JBYTE ; INPUT BYTE (2 HEX CHAR) BVS ALTBD STA 2,U ALTBD RTS ; $F91C * * ALTER "A" ACCUMULATOR * ALTRA BSR PRTA ; $FCFF RINT MSG " A = " BSR JOUT1S ; OUTPUT SPACE BSR JBYTE ; INPUT BYTE (2 HEX CHAR) BVS ALTAD STA 1,U ALTAD RTS ; * * ALTER "CC" REGISTER * ALTRCC BSR PRTCC ; $FD13 PRINT MSG " CC: " BSR JOUT1S ; OUTPUT SPACE BSR JBYTE ; INPUT BYTE (2 HEX CHAR) BVS ALTCCD ORA #$80 ; SETS "E" FLAG IN PRINT LIST STA ,U ALTCCD RTS ; * * PDATA * PRINT LBSR OUTCH PDATA LDA ,X+ ; GET 1st CHAR. TO PRINT CMPA #4 ; IS IT EOT? BNE PRINT ; IF NOT EOT PRINT IT RTS ; * * PRINT REGISTERS * PRTSP LDX #MSG10 ; POINT TO MSG "SP=" BSR PDATA ; PRINT MSG TFR U,X JOUT4H LBRA OUT4H * PRTUS LDX #MSG12 ; POINT TO MSG "US=" BSR PDATA ; PRINT MSG LDX 8,U BRA JOUT4H * PRTDP LDX #MSG15 ; POINT TO MSG "DP=" BSR PDATA ; PRINT MSG LDA 3,U JOUT2H LBRA OUT2H ; OUTPUT HEX BYTE AS ASCII * PRTIX LDX #MSG14 ; POINT TO MSG "IX=" BSR PDATA ; PRINT MSG LDX 4,U ; $FCE6 BRA JOUT4H * PRTIY LDX #MSG13 ; POINT TO MSG "IY=" BSR PDATA ; PRINT MSG LDX 6,U BRA JOUT4H * PRTPC LDX #MSG11 ; POINT TO MSG "PC=" BSR PDATA ; PRINT MSG LDX 10,U BRA JOUT4H * PRTA LDX #MSG16 ; POINT TO MSG "A=" BSR PDATA ; PRINT MSG LDA 1,U BRA JOUT2H ; OUTPUT HEX BYTE AS ASCII * PRTB LDX #MSG17 ; POINT TO MSG "B=" BSR PDATA ; PRINT MSG LDA 2,U BRA JOUT2H ; OUTPUT HEX BYTE AS ASCII * PRTCC LDX #MSG18 ; POINT TO MSG "CC:" BSR PDATA ; PRINT MSG LDA ,U LDX #MSG19 ; POINT TO MSG "EFHINZVC" LBRA BIASCI ; OUTPUT IN BINARY/ASCII FORMAT * * "R" DISPLAY REGISTERS * REGSTR LDX #MSG5 ; POINT TO MSG " - " LBSR PSTRNG ; PRINT MSG BSR PRTSP ; $FCBF BSR PRTUS ; $FCCA BSR PRTDP ; $FCD5 BSR PRTIX ; $FCE0 BSR PRTIY ; $FCEB LDX #MSG5 ; POINT TO MSG " - " LBSR PSTRNG ; PRINT MSG BSR PRTPC ; $FCF5 BSR PRTA ; $FCFF BSR PRTB ; $FD09 BRA 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 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,PC * ***** 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 #'A-10 ; ($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 #'a-10 ; ($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,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 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 IFD HFCOPT LDA #$11 ; SET RTS* LOW, REQUEST FAR END TO TX STA [CPORT] ENDIF HFCOPT GETSTA LDX CPORT ; POINT TO TERMINAL PORT LDA ,X ; FETCH PORT STATUS BITA #1 ; TEST READY BIT, RDRF ? IFD PS2OPT BNE GETST1 LDX #PS2KBD LDA ,X BITA #1 ENDIF PS2OPT BEQ GETSTA ; IF NOT RDY, THEN TRY AGAIN GETST1 EQU * IFD HFCOPT LDA #$51 ; SET RTS* HIGH, STOP FAR END FROM TXING, UNTIL NEXT INPUT STA [CPORT] ENDIF HFCOPT LDA 1,X ; FETCH CHAR PULS 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 ACCUM IFD HFCOPT LDA #$11 ; SET RTS* LOW, REQUEST FAR END TO TX STA [CPORT] ENDIF HFCOPT LDA [CPORT] ; FETCH PORT STATUS BITA #1 ; TEST READY BIT, RDRF ? IFD PS2OPT BNE INCHEK1 LDA PS2KBD BITA #1 ; TEST READY BIT< RDRF ? ENDIF PS2OPT INCHEK1 PULS A,PC ; RESTORE A ACCUM. * 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 IFD VDUOPT BSR VOUTCH ENDIF VDUOPT IFD DG640OPT BSR VOUTCH ENDIF DG640OPT AOUTCH 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 BITA #8 ; CLEAR TO SEND ? BNE FETSTA ; NO, LOOP UNTIL CLEAR PULS A ; GET CHAR. FOR XMIT STA 1,X ; XMIT CHAR. PULS X,PC ; RESTORE IX * * IO INITIALIZATION * IOINIZ EQU * IFD VDUOPT BSR VINIZ ENDIF VDUOPT IFD DG640OPT BSR VINIZ ENDIF DG640OPT ACINIZ LDX CPORT ; POINT TO CONTROL PORT ADDRESS LDA #3 ; RESET ACIA PORT CODE STA ,X ; STORE IN CONTROL REGISTER LDA #$51 ; SET 8 DATA, 2 STOP AN 0 PARITY RTS* HIGH STA ,X ; STORE IN CONTROL REGISTER TST 1,X ; ANYTHING IN DATA REGISTER? LDA #$FF ; TURN ON ECHO FLAG STA ECHO RTS * IFD VDUOPT * *************************************************** * VDU8 ADM3A REGISTER-MAPPED EMULATOR * * * * 80 x 25 Characters * *************************************************** * *************************************************** * INITIALIZE EMULATOR * *************************************************** * VINIZ LDX #VDU LDD #0 STD COLADX ; AND ROWADX STA VDUCOL,X STB VDUROW,X STB VDUOFF,X STD NEWROW ; AND ESCFLG LDB #$02 STB VDUATT,X CLR ESCFLG LDA #$1B ; SEND ESCAPE BSR VOUTCH LDA #'Y ; CLEAR TO END OF SCREEN * ** VIDEO OUTPUT ROUTINE * VOUTCH PSHS A,B,X ; SAVE REGISTERS LDX #VDU ; POINT TO VDU REGISTERS * ** CHECK FOR ESCAPE SEQUENCE * TST ESCFLG ; ESCAPE ACTIVE? BEQ SOROU1 ; BRANCH IF NOT BSR ESCAPE ; ELSE DO ESCAPE BRA RETURN ; AND RETURN * ** CHECK FOR CONTROL CHARACTERS * SOROU1 CMPA #$20 ; CONTROL CODES? BHS SOROU2 BSR CONTRL ; BRANCH IF SO BRA RETURN * ** OUTPUT TEXT CHARACTER * SOROU2 STA VDUCHR,X ; DISPLAY CHARACTER LBSR 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 BACKSP CMPA #$1B ; ESCAPE SEQUENCE? BEQ SETESC CMPA #$1A ; CTRL Z - Clear Screen LBEQ CLRSCR CMPA #$16 ; CTRL ^ - Home BEQ HOME CMPA #$0D ; CTRL M - RETURN? LBEQ CRETN CMPA #$0C ; CTRL L - CHAR RIGHT BEQ CHRIGHT CMPA #$0B ; CTRL K - MOVE UP ONE LINE BEQ LINEUP CMPA #$0A ; CTRL J - LINE FEED BNE RETESC ; NONE OF THESE, RETURN * ***************************************** LINE FEED * LINEFD LDD COLADX ; GET CURRENT COLUMN AND ROW INCB ; BUMP ROW CMPB #NUMLIN ; SCROLL TIME? BNE NEWCUR ; POSITION CURSOR IF NOT LBRA SCROLL ; ELSE SCROLL IT * ***************************************** LINE FEED * LINEUP LDD COLADX ; GET CURRENT COLUMN AND ROW TSTB ; AT TOP OF SCREEN ? BEQ RETESC ; Yes, Ignore DECB ; No, Decrement ROW BRA NEWCUR ; POSITION CURSOR * *********************************** BACK SPACE * BACKSP LDA COLADX BEQ RETESC ; RETURN DECA BRA POSCOL ; POSITION CURSOR * *********************************** CURSOR RIGHT * CHRIGHT LDA COLADX INCA CMPA #LINLEN BEQ RETESC BRA POSCOL * *********************************** CURSOR RIGHT * HOME LDD #0 ; HOME - POSITION TOP OF SCREEN BRA NEWCUR * *************************************************** * ESCAPE HANDLERS * *************************************************** * ESCAPE LDB ESCFLG ; GET FLAG CMPB #'= ; SETTING CURSOR? BEQ ESCCUR ; BRANCH IF SO CMPA #'Y ; CLEAR TO END OF SCREEN? BEQ ESCCLS CMPA #'T ; CLEAR TO END OF LINE? BEQ ESCCLL CMPA #'= ; STARTING CURSOR SET? BNE CLRESC ; BRANCH IF NOT * ***************************** START ESCAPE SEQUENCE * SETESC STA ESCFLG ; ELSE START CURSORING RTS ; AND RETURN * CLRESC CLR ESCFLG ; NO OTHERS SUPPORTED RETESC RTS ; SO RETURN * ********************************* SET SCREEN CURSOR * ESCCUR TST NEWROW ; ROW SET? BNE ESCCU1 ; BRANCH IF SO STA NEWROW ; ELSE SET NEW ROW RTS ; AND RETURN * ESCCU1 CLR ESCFLG SUBA #$20 ; ADJUST COLUMN ADDRESS CMPA #LINLEN-1 ;CHECK FOR ACCEPTABLE COLUM BHI RETESC ; NOT OK, DO NOTHING * ESCCU2 LDB NEWROW CLR NEWROW SUBB #$20 ; ADJUST TO ROW ADDRESS CMPB #NUMLIN-1 ; CHECK FOR ACCEPTABLE ROW BHI RETESC ; ELSE RETURN DOING NOTHING BRA NEWCUR ; GO SET NEW CURSOR IF SO * ****************** CLEAR FROM CURSOR TO END OF LINE * CLRSCR LDD #0 ; CLEAR FROM TOP OF SCREEN BSR NEWCUR ESCCLL LDA COLADX LDB #$20 ; AND CLEAR CHAR ESCCL1 STB VDUCHR,X ; DISPLAY TEXT INCA STA VDUCOL,X CMPA #LINLEN ; UNTIL END OF LINE BNE ESCCL1 CLR ESCFLG RTS * *********************************** CARRIAGE RETURN * CRETN CLRA ; SET COLUMN ZERO POSCOL LDB ROWADX ; GET CURRENT ROW * *********** GENERATE NEW CURSOR POSITION AND RETURN * NEWCUR STD COLADX ; SAVE NEW ROW AND COLUMN STA VDUCOL,X ; SET NEW COLUMN STB VDUROW,X ; SET NEW ROW RTS ; AND RETURN * ********************* UPDATE CURRENT COLUMN AND ROW * NEWCOL LDD COLADX ; GET ROW AND COLUMN INCA ; BUMP COLUMN CMPA #LINLEN ; ROLL? BNE NEWCUR ; BRANCH IF NOT CLRA ; ELSE RESET TO ZERO INCB ; AND BUMP ROW CMPB #NUMLIN BNE NEWCUR DECB ; BOTTOM ROW BSR NEWCUR * ********************************* SCROLL THE SCREEN * SCROLL LDB VDUOFF,X INCB CMPB #NUMLIN BLO SCROL1 CLRB SCROL1 STB VDUOFF,X * **************** CLEAR FROM CURSOR TO END OF SCREEN * ESCCLS LDB COLADX ; GET CURSOR LDA #$20 ; GET A SPACE ESCCLS1 STB COLADX STB VDUCOL,X STA VDUCHR,X INCB CMPB #LINLEN BNE ESCCLS1 * LDB ROWADX INCB CMPB #NUMLIN BEQ ESCCLS2 STB ROWADX STB VDUROW,X CLRB BRA ESCCLS1 * ESCCLS2 CLRB STB COLADX STB VDUCOL,X STB ESCFLG RTS ENDIF 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 #0 STX COLADX ; AND ROWADX STX NEWROW ; AND ESCFLG LDX #SCREEN ; POINT TO SCREEN STX CURSOR ; SET PROGRAM CURSOR LDA #$1B ; SEND ESCAPE BSR VOUTCH LDA #'Y ; CLEAR TO END OF SCREEN * ** VIDEO OUTPUT ROUTINE * VOUTCH PSHS A,B,X ; SAVE REGISTERS * ** CLEAR CURSOR * LDX CURSOR LDB 0,X ANDB #$7F STB 0,X * ** CHECK FOR ESCAPE SEQUENCE * TST ESCFLG ; ESCAPE ACTIVE? BEQ SOROU1 ; BRANCH IF NOT BSR ESCAPE ; ELSE DO ESCAPE BRA RETURN ; AND RETURN * ** CHECK FOR CONTROL CHARACTERS * SOROU1 CMPA #$20 ; CONTROL CODES? BHS SOROU2 BSR CONTRL ; BRANCH IF SO BRA RETURN * ** OUTPUT TEXT CHARACTER * SOROU2 LDX CURSOR ; ELSE GET CURSOR STA 0,X ; DISPLAY CHARACTER LBSR NEWCOL ; UPDATE COLUMN * ** DISPLAY CURSOR AND RETURN * RETURN LDX CURSOR ; AND DISPLAY IT LDB ,X ORB #$80 ; WITH REVID STB ,X PULS A,B,X,PC ; RESTORE REGISTERS AND RETURN * *************************************************** * CONTROL CODE HANDLERS * *************************************************** * CONTRL CMPA #$08 ; CTRL H - BACKSPACE ? LBEQ BACKSP CMPA #$1B ; ESCAPE SEQUENCE? LBEQ SETESC CMPA #$D ; CTRL M - RETURN? LBEQ CRETN CMPA #$0A ; CTRL J - LINE FEED BNE RETESC ; NONE OF THESE, RETURN * ***************************************** LINE FEED * LINEFD LDD COLADX ; GET CURRENT COLUMN AND ROW INCB ; BUMP ROW CMPB #NUMLIN ; SCROLL TIME? LBNE NEWCUR ; POSITION CURSOR IF NOT LBRA SCROLL ; ELSE SCROLL IT * ***************************************** LINE FEED * LINEUP LDD COLADX ; GET CURRENT COLUMN AND ROW TSTB ; AT TOP OF SCREEN ? BEQ RETESC ; YES, RETURN DECB ; NO, DECREMENT ROW LBRA NEWCUR ; POSITION CURSOR * *********************************** BACK SPACE * BACKSP LDA COLADX ; GET CURRENT COLUMN AND ROW BEQ RETESC ; IF AT TOP LEFT CORNER RETURN DECA ; OTHERWISE BACK STEP ONE CHARACTER LBRA POSCOL ; POSITION CURSOR * *********************************** CURSOR RIGHT * CHRIGHT LDA COLADX ; GET CURRENT COLUMN AND ROW INCA ; MOVE RIGHT ONE CHARACTER CMPA #LINLEN ; ARE WE AT THE END OF THE LINE ? BEQ RETESC ; YES, RETURN LBRA 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 CURSOR CMPA #'Y ; CLEAR TO END OF SCREEN? LBEQ ESCCLS ; YES, CLEAR SCREEN CMPA #'T ; CLEAR TO END OF LINE? BEQ ESCCLL ; YES, CLEAR LINE CMPA #'E ; INSERT LINE? BEQ ESCINL CMPA #'R ; DELETE LINE? BEQ ESCDLL CMPA #'= ; STARTING CURSOR SET? BNE CLRESC ; BRANCH IF NOT * ***************************** START ESCAPE SEQUENCE * SETESC STA ESCFLG ; ELSE START CURSORING RTS ; AND RETURN * CLRESC CLR ESCFLG ; NO OTHERS SUPPORTED RETESC RTS ; SO RETURN * ********************************* SET SCREEN CURSOR * ESCCUR TST NEWROW ; ROW SET? BNE ESCCU1 ; BRANCH IF SO STA NEWROW ; ELSE SET NEW ROW RTS ; AND RETURN * ESCCU1 CLR ESCFLG SUBA #$20 ; ADJUST COLUMN ADDRESS CMPA #LINLEN-1 ; CHECK FOR ACCEPTABLE COLUM BHI RETESC ; NOT OK, DO NOTHING * ESCCU2 LDB NEWROW CLR NEWROW SUBB #$20 ; ADJUST TO ROW ADDRESS CMPB #NUMLIN-1 ; CHECK FOR ACCEPTABLE ROW BHI RETESC ; ELSE RETURN DOING NOTHING BRA NEWCUR ; GO SET NEW CURSOR IF SO * *************************** DELETE LINE FROM SCREEN * ESCDLL BSR CRETN ; GO COL. ZERO LDB ROWADX CMPB #NUMLIN-1 BEQ SCROL3 BRA SCROL1 ; AND DELETE THIS LINE * *************************** INSERT LINE INTO SCREEN * ESCINL BSR CRETN ; GO TO COL. ZERO LDB ROWADX CMPB #NUMLIN-1 BEQ ESCCLL * ** SCROLL SCREEN DOWN FROM CURSOR * LDX #SCREEN+SCNLEN-LINLEN ESCIN0 LDA ,-X STA LINLEN,X LDA SCNLEN,X STA SCNLEN+LINLEN,X CMPX CURSOR BNE ESCIN0 * ****************** CLEAR FROM CURSOR TO END OF LINE * ESCCLL LDA COLADX ; GET CURRENT COLUMN LDX CURSOR ; GET CURSOR LDB #$20 ; AND CLEAR CHAR ESCLL1 STB SCNLEN,X ; CLEAR ATTRIBUTE STB ,X+ ; CLEAR TEXT INCA CMPA #LINLEN ; UNTIL END OF LINE BNE ESCLL1 CLR ESCFLG RTS * *********************************** CARRIAGE RETURN * CRETN CLRA ; SET COLUMN ZERO POSCOL LDB ROWADX ; GET CURRENT ROW * *********** GENERATE NEW CURSOR POSITION AND RETURN * NEWCUR STD COLADX ; SAVE NEW ROW AND COLUMN LDA #LINLEN ; ELSE ADD A LINE MUL ; LINLEN * ROWADX ADDB COLADX ADCA #0 ADDD #SCREEN ; ADD SCREEN BASE. STD CURSOR ; SAVE NEW CURSOR TFR D,X ; GET CURSOR IN X RTS ; AND RETURN * ********************* UPDATE CURRENT COLUMN AND ROW * NEWCOL LDD COLADX ; GET ROW AND COLUMN INCA ; BUMP COLUMN CMPA #LINLEN ; ROLL? BNE NEWCUR ; BRANCH IF NOT CLRA ; ELSE RESET TO ZERO INCB ; AND BUMP ROW CMPB #NUMLIN BNE NEWCUR DECB ; BOTTOM ROW BSR NEWCUR * ********************************* SCROLL THE SCREEN * SCROLL LDX #SCREEN ; POINT TO SCREEN SCROL1 LDA SCNLEN+LINLEN,X STA SCNLEN,X LDA LINLEN,X ; MOVE TWO BYTES STA ,X+ ; UP ONE LINE CMPX #SCREEN+SCNLEN-LINLEN BNE SCROL1 ; LOOP UNTIL DONE BRA SCROL3 * **************** CLEAR FROM CURSOR TO END OF SCREEN * ESCCLS LDX CURSOR ; GET CURSOR SCROL3 LDA #$20 ; GET A SPACE SCROL2 STA SCNLEN,X ; CLEAR ATTRIBUTES STA ,X+ ; AND TEXT CMPX #SCREEN+SCNLEN BNE SCROL2 ; UNTIL DONE CLR ESCFLG RTS ENDIF DG640OPT * IFD PRTOPT ************************************* * ** PRINTER DRIVER ROUTINES * ************************************* * ** PINIZ - INITIATE PRINTER PORT * PINIZ PSHS B LDD #DIRMSK*256+$04 ; ACCA=DIRMSK ACCB=$04 STD PADATA ; SET DDR AND SELECT DATA * ** RESET PRINTER * LDB #PRESET STB PADATA RESTLP INCB ; DELAY FOR RESET BNE RESTLP STA PADATA ; ACCA=DIRMSK * ** INITALIZE PORT B (DATA PORT) * LDA #$2A STA PBCTRL LDD #$FF2E ; ACCA=$FF ACCB =%00101110 STD PBDATA ; PBDREG PBCTRL * ** SELECT 66 LINES/PAGE * LDA #$1B BSR POUTCH LDA #'C BSR POUTCH LDA #66 PULS B ************************************* * ** OUTPUT A CHARACTER TO THE PRINTER * ************************************* POUTCH PSHS B LDB PBDATA ; CLEAR INTERRUPT BIT * ** WAIT TILL NOT BUSY * BUSYLP LDB PADATA BITB #PERROR BEQ PEXIT TSTB BMI BUSYLP * ** NOW OUTPUT CHARACTER * STA PBDATA PEXIT PULS B,PC ************************************* * ** PCHK TEST IFD PRINTER READY * ************************************* PCHK TST PBCTRL ; TEST STATE OF CRB7 RTS ; SET ON ACKNOWLEDGE ENDIF PRTOPT ************************************* * * MONITOR KEYBOARD COMMAND JUMP TABLE * ************************************* * JMPTAB EQU * FCB 1 " ^A " FDB ALTRA FCB 2 " ^B " FDB ALTRB FCB 3 " ^C " FDB ALTRCC FCB 4 " ^D " FDB ALTRDP FCB $10 " ^P " FDB ALTRPC FCB $15 " ^U " FDB ALTRU FCB $18 " ^X " FDB ALTRX FCB $19 " ^Y " FDB ALTRY * FCC 'B' FDB BRKPNT FCC 'E' FDB MEMDUMP FCC 'G' FDB GO FCC 'L' FDB LOAD FCC 'P' FDB PUNCH FCC 'M' FDB MEMCHG FCC 'R' FDB REGSTR FCC 'S' FDB DISSTK FCC 'X' FDB XBKPNT IFD MFDCOPT FCC 'D' ; *** SWTPC USES 'U' FOR MINIBOOT FDB MINBOOT ENDIF MFDCOPT IFD CF8OPT FCC 'D' ; *** FPGA 8 BIT USES 'D' FOR CFBOOT FDB CFBOOT ENDIF CF8OPT IFD IDEOPT FCC 'D' ; *** XESS FPGA 16 BIT IDE USES 'D' FOR IDEBOOT FDB IDEBOOT ENDIF IDEOPT IFD DMAFOPT FCC 'U' ; *** SWTPC USES 'D' FOR DMAF2 BOOT FDB DBOOT ENDIF DMAFOPT IFD EXTOPT FCC 'U' ; *** IF FPGA, 'U' IS FOR USER FDB USRCMD ENDIF EXTOPT IFD RTCOPT FCC 'T' FDB TIMSET ENDIF RTCOPT IFD TRAOPT FCC "T" FDB TRACE ENDIF 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-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 $D,$A,$0,$0,$0 * 0, CR/LF, 0 FCC 'SYS09BUG 1.6 FOR ' IFD SWTOPT` FCC 'SWTPC ' ENDIF SWTOPT IFD ADSOPT FCC 'ADS6809 ' ENDIF ADSOPT IFD B3SOPT FCC 'B3-S2+ ' ENDIF B3SOPT IFD B5XOPT FCC 'B5-X300 ' ENDIF B5XOPT IFD S3SOPT FCC 'S3STARTER ' ENDIF S3SOPT IFD S3EOPT FCC 'S3E ' ENDIF S3EOPT IFD XESOPT` FCC 'XESS ' ENDIF XESOPT FCC ' - ' FCB 4 MSG2 FCB 'K,$0D,$0A,$00,$00,$00,$04 ; K,,,3 NULS, MSG3 FCC '>' FCB 4 MSG4 FCC 'WHAT?' FCB 4 MSG5 FCC ' - ' FCB 4' 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 IFD DATOPT * * POWER UP/ RESET/ NMI ENTRY POINT * ORG $FF00 * * START LDX #IC11 ; POINT TO DAT RAM IC11 LDA #$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 LOCATION DECA ; GET COMP. VALUE FOR NEXT LOCATION BNE DATLP ; ALL 16 LOCATIONS INITIALIZED ? * * NOTE: IX NOW CONTAINS $0000, 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 AN 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 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 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 $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 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 TRANSFER 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 * ELSE LRA RTS START LDS #STACK ; INITIALIZE STACK POINTER CLRB ENDIF DATOPT * COMB ; SET "B" NON-ZERO STB ECHO ; TURN ON ECHO FLAG LBRA 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,U LDX 10,U *$FFC8 LDB ,X+ STX 10,U CLRA ASLB ROLA LDX SVCVO CMPX #$FFFF BEQ SWI3Z LEAX D,X CMPX SVCVL BHI SWI3Z PSHS X LDD ,U LDX 4,U JMP [,S++] SWI3Z PULU A,B,X,CC,DP LDU 2,U JMP [SWI3] * * 6809 VECTORS * ORG $FFF0 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 START

Error running this command: diff -w -U 5 "" "/tmp/8ngRqh"

diff: : No such file or directory