NAM MC6809 DISK-BUG DS VER 3.5 OPT PAG * Floppy Disk Controller Debug Monitor * Written 27 Aug 1980 * Michael Holley * * Record of modifications * 18 OCT 1981 Disk routines DC-1 * 23 JAN 1982 Command Table * 8 MAY 1982 DDC-16 Disk Controller * 27 JUN 2001 Double Sided Disks * 3 JUN 2003 Help Text * * This version requires a Disk Controller with * a DRQ/IRQ status register as found in the * DC-3, DC-4 and DC5 cards * *************************************** * Commands * J xxxx Jump to location xxxx * * M xxxx Examine and alter memory location * N Examine next memory location * V Examine same memory location * B Examine previous memory location * * Z xx Select and restore drive xx to track 0 * * T ttss Read sector ss on track tt into BUFFER * and display it * * L ttss Load binary file starting at track tt * and sector ss. Display transfer address. * * W ttss Write BUFFER into sector ss on track tt * * $ Return to SWTBUG or SBUG-E * PAG *************************************** * VECTORS * For programming into ROM * * ORG $FFF8 *IRQA FDB START *SWI FDB CTRL *NMI FDB START *RESET FDB START *************************************** * System Locations ROM EQU $F000 $E400 after SWTBUG RAM EQU $0000 ACIA EQU $E004 6800=$8004, 6809=$E004 FDC EQU $E018 6800=$8018, 6809=$E018 SWTBUG EQU $F800 6800=$E0D0, 6809=$F800 DRVREG EQU FDC-4 FDC DRIVE SELECT REG DRQREG EQU FDC-4 FDC DRQ IRQ COMREG EQU FDC FDC COMMAND REG TRKREG EQU FDC+1 FDC TRACK REG SECREG EQU FDC+2 FDC SECTOR REG DATREG EQU FDC+3 FDC DATA REG * RAM VARIABLES STACK EQU RAM+$0070 ORG RAM+$0071 SAVSTK RMB 2 TEMP FOR STACK POINTER TEMP1 RMB 1 TEMP FOR INHEX AND OUTHEX TEMP2 RMB 1 GENERAL TEMP XTEMP1 RMB 2 INDEX REG TEMP XTEMP2 RMB 2 INDEX REG TEMP XHI RMB 1 INDEX HIGH BYTE XLOW RMB 1 INDEX LOW BYTE CURDRV RMB 1 LAST USED DRIVE * Buffer location is shown in sign-on message BUFFER EQU RAM+$0100 PAG ORG ROM+$0000 BEGIN MONITOR START LDS #STACK *************************************** * FUNCTION: INITA - Initialize ACIA * INPUT: none * OUTPUT: none * CALLS: none * DESTROYS: acc A RESETA EQU %00010011 CTLREG EQU %00010001 INITA LDA A #RESETA RESET ACIA STA A ACIA LDA A #CTLREG SET 8 BITS AND 2 STOP STA A ACIA JMP SIGNON GO TO START OF MONITOR *************************************** * FUNCTION: INCH - Input character * INPUT: none * OUTPUT: char in acc A * DESTROYS: acc A * CALLS: none * DESCRIPTION: Gets 1 character from terminal INCH LDA A ACIA GET STATUS ASR A SHIFT RDRF FLAG INTO CARRY BCC INCH RECIEVE NOT READY LDA A ACIA+1 GET CHAR AND A #$7F MASK PARITY JMP OUTCH ECHO & RTS *************************************** * FUNCTION: INHEX - INPUT HEX DIGIT * INPUT: none * OUTPUT: Digit in acc A * CALLS: INCH * DESTROYS: acc A * Returns to monitor if not HEX input INHEX BSR INCH GET A CHAR CMP A #'0 ZERO BMI HEXERR NOT HEX CMP A #'9 NINE BLE HEXRTS GOOD HEX CMP A #'A BMI HEXERR NOT HEX CMP A #'F BGT HEXERR SUB A #7 FIX A-F HEXRTS AND A #$0F CONVERT ASCII TO DIGIT RTS HEXERR JMP CTRL RETURN TO CONTROL LOOP *************************************** * FUNCTION: BADDR - Build Address * INPUT: none * OUTPUT: Address in INDEX and XHI & XLOW * CALLS: BYTE * DESTROYS: INDEX, acc A * RAM: XHI, XLOW BADDR BSR BYTE GET HIGH ORDER ADDRESS STA A XHI STORE IT BSR BYTE GET LOW ORDER ADDRESS STA A XLOW STORE IT LDX XHI LOAD ADDRESS INTO INDEX RTS *************************************** * FUNCTION: BYTE - Read BYTE 2 hex digits * INPUT: none * OUTPUT: BYTE in acc A * CALLS: INHEX * DESTROYS: acc A * RAM: TEMP1 BYTE BSR INHEX GET FIRST DIGIT ASL A SHIFT TO HIGH ORDER 4 BITS ASL A ASL A ASL A STA A TEMP1 SAVE FIRST DIGIT BSR INHEX GET SECOND DIGIT ADD A TEMP1 COMBINE 2 DIGITS INTO BYTE RTS *************************************** * FUNCTION: MEMORY - Memory Examine and Change * INPUT: none * OUTPUT: none * CALLS: BADDR * DESTROYS: acc A,acc B, INDEX * RAM: XHI, XLOW MEMORY BSR BADDR BUILD ADDRESS * BRA CHANGE *************************************** * FUNCTION: CHANGE - Memory Examine and Change * INPUT: none * OUTPUT: none * CALLS: BADDR, OUTS, OUT2H, BYTE * DESTROYS: acc A,acc B, INDEX * RAM: XHI, XLOW CHANGE BSR OUTS SPACE LDA A 0,X BSR OUT2H PRINT BYTE BSR OUTS SPACE BSR BYTE GET NEW BYTE STA A 0,X BRA CTRL RETURN TO LOOP *************************************** * FUNCTION: VIEW - Memory Examine and Change * INPUT: acc B - N, B, or S * OUTPUT: none * CALLS: OUT2H, CHANGE * DESTROYS: acc A,acc B, INDEX * RAM: XHI, XLOW * S = VIEW SAME MEMORY, N = VIEW NEXT MEMORY * B = BACK ONE MEMORY VIEW LDX XHI CMP B #'V VIEW SAME LOCATION BEQ VIEW1 DEX CMP B #'B BACK ONE LOCATION BEQ VIEW1 INX UNDO BACK INX INCREMENT MEMORY POINTER VIEW1 STX XHI PUT IT BACK LDA A XHI BSR OUT2H PRINT ADDRESS LDA A XLOW BSR OUT2H BRA CHANGE ENTER CHANGE FUNCTION *************************************** * FUNCTION: OUTCH - Output a char to ACIA * INPUT: char in A * OUTPUT: none * CALLS: none * DESTROYS: none OUTCH PSH B SAVE ACC B OUTCH1 LDA B ACIA GET STATUS ASR B ASR B SHIFT TDR TO CARRY BCC OUTCH1 STA A ACIA+1 SEND CHAR PUL B RESTORE ACC B RTS *************************************** * FUNCTION: OUT2H - Output 2 hex digits * INPUT: BYTE in acc A * OUTPUT: none * CALLS: OUTCH * DESTROYS: none * RAM: TEMP1 OUT2H STA A TEMP1 LSR A SHIFT HIGH DIGIT OVER LSR A LSR A LSR A BSR OUTHR OUTPUT FIRST DIGIT OUTHR AND A #$0F MASK LEFT DIGIT ADD A #$30 MAKE ASCII CMP A #'9 IS IT 0-9 BLS OUT21 ADD A #$7 MAKE IT A-F OUT21 BSR OUTCH PRINT IT LDA A TEMP1 GET BYTE BACK RTS *************************************** * FUNCTION: OUTS - Output a space * INPUT: none * OUTPUT: none * CALLS: OUTCH * DESTROYS: acc A OUTS LDA A #$20 SPACE BRA OUTCH (BSR & RTS) *************************************** * FUNCTION: PDATA - Print data string * INPUT: Start of string in INDEX * OUTPUT: none * CALLS: OUTCH * DESTROYS: acc A, INDEX * The character string must be terminated * with a End Of Text $04. PDATA2 BSR OUTCH INX VIEW CHAR PDATA LDA A X CMP A #4 END OF TEXT BNE PDATA2 RTS *************************************** * FUNCTION: JUMP * INPUT: none * OUTPUT: none * CALLS: BADDR * DESTROYS: INDEX JUMP BSR BADDR GET ADDRESS JMP 0,X JUMP TO IT *************************************** * MONITOR CONTROL LOOP CTRL LDS #STACK BSR PCRLF LDA A #'+ BSR OUTCH JSR INCH GET COMMAND TAB SAVE COMMAND BSR OUTS PRINT SPACE LDX #CMMD COMMAND TABLE CTRL1 CMP B 0,X MATCH COMMAND BEQ CTRL3 FOUND MATCH INX INX INX SKIP OVER COMMAND TST 0,X TABLE ENDS WITH $00 BNE CTRL1 BRA CTRL CTRL3 LDX 1,X LOAD XFER ADDRESS JMP 0,X CMMD FCC /J/ FDB JUMP FCC /M/ FDB MEMORY FCC /N/ FDB VIEW FCC /V/ FDB VIEW FCC /B/ FDB VIEW FCC /Z/ FDB TRK00 FCC /T/ FDB SECTR FCC /L/ FDB LOAD FCC /$/ FDB SWTBUG FCC /W/ FDB WRTSEC FCB $00 END OF TABLE *************************************** * FUCTION: SIGNON * INPUT: none * OUTPUT: none * CALLS: PDATA * DESTROYS: acc A, INDEX SIGNON BSR PCRLF LDX #HELLO BSR PDATA LDX #HELP BSR PDATA BRA CTRL *************************************** * FUCTION: PCRLF Print CR and LF * INPUT: none * OUTPUT: none * CALLS: PDATA * DESTROYS: acc A * RAM: XTEMP1 PCRLF STX XTEMP1 LDX #CRLF BSR PDATA LDX XTEMP1 RESTORE INDEX RTS *************************************** * STRINGS HELLO FCC / MC6800 DISK-BUG - VER 3.5/ CRLF FCB $0D,$0A,00,00,00,04 HELP FCC /J xxxx Jump to xxxx/ FCB $0D,$0A,00 * HELP01 FCC /M xxxx Examine and alter memory/ FCB $0D,$0A,00 HELP02 FCC /N Next memory/ FCB $0D,$0A,00 HELP03 FCC /V Same memory/ FCB $0D,$0A,00 HELP04 FCC /B Previous memory/ FCB $0D,$0A,00 * HELP05 FCC /Z xx Select & restore drive xx/ FCB $0D,$0A,00 * HELP06 FCC /T ttss Read sector ss on track tt into buffer/ FCB $0D,$0A,00 * HELP07 FCC /L ttss Load file. Show transfer address./ FCB $0D,$0A,00 * HELP08 FCC /W ttss Write buffer at $0100 / FCB $0D,$0A,00 * HELP09 FCC /$ Go to SWTBUG/ FCB $0D,$0A,04 *************************************** * FUCTION: TRK00 RESTORE TO TRACK 00 * INPUT: none * OUTPUT: none * CALLS: BYTE * DESTROYS: TRK00 JSR BYTE GET DRIVE SELECT CODE STA A DRVREG STA A CURDRV LDA A #$0B STA A COMREG JMP CTRL *************************************** * FUCTION: SECTR SECTOR READ * INPUT: none * OUTPUT: none * CALLS: BADDR, CTRL, PCRLF, OUTCH, OUTS, OUTHEX * EXTERNAL: READ * DESTROYS: acc A acc B INDEX * RAM: SECTR JSR BADDR GET TRK & SEC LDX #BUFFER LDA A XHI GET TRACK LDA B XLOW GET SECTOR JSR READ READ SECTOR BEQ DUMP NO ERROR ERROR JSR PCRLF LDA A #'E JSR OUTCH JSR OUTS PRINT E & SPACE TBA GET ERROR NUMBER JSR OUT2H JMP CTRL *************************************** * FUCTION: WRTSEC SECTOR WRITE * INPUT: none * OUTPUT: none * CALLS: BADDR, CTRL, PCRLF, OUTCH, OUTS, OUTHEX * EXTERNAL: WRITE * DESTROYS: acc A acc B INDEX * RAM: WRTSEC JSR BADDR GET TRK & SEC LDX #BUFFER LDA A XHI GET TRACK LDA B XLOW GET SECTOR JSR WRITE WRITE SECTOR BNE ERROR JSR PCRLF LDA A #'O JSR OUTCH LDA A #'K JSR OUTCH WRTSC9 JMP CTRL *************************************** DUMP LDX #BUFFER LDA A #16 NUMBER OF LINES DUMP1 PSH A JSR PCRLF LDA B #16 NUMBER OF BYTES STX XTEMP2 DUMP2 LDA A 0,X JSR OUT2H PRINT 2 HEX JSR OUTS PRINT SPACE INX DEC B DONE WITH LINE BNE DUMP2 LDA B #16 NUMBER OF BYTES LDX XTEMP2 DUMP3 LDA A 0,X GET CHARACTER AND A #$7F MASK MSB CMP A #$7D BGT DUMP31 CMP A #$1F IS IT CONTROL BGT DUMP32 DUMP31 LDA A #'_ DUMMY DUMP32 JSR OUTCH INX DEC B DONE WITH LINE BNE DUMP3 PUL A DEC A DONE WITH DUMP BNE DUMP1 DUMP9 JMP CTRL *************************************** * FUCTION: LOAD * INPUT: none * OUTPUT: none * CALLS: LOADER LOAD JSR BADDR GET TRACK AND SECTOR STX BUFFER JSR LOADER LOAD BINARY FILE JSR OUTS LDA A XHI JSR OUT2H PRINT XFER ADDRESS LDA A XLOW JSR OUT2H JMP CTRL **************************************** * FUNCTION: LOADER - Binary file loader * INPUT: Track and sector in BUFFER 0&1 * OUTPUT: Transfer Address in XHI & XLOW * CALLS: READ LOADER LDX #BUFFER+256 STX XTEMP1 STS SAVSTK SAVE STACK FOR RETURN * DO UNTIL END OF FILE LOAD1 BSR GETCH GET A CHAR FROM BUFFER CMPA #$02 DATA RECORD HEADER BEQ LOAD2 BR IF SO CMPA #$16 XFR ADDRESS HEADER BNE LOAD1 LOOP IF NEITHER BSR GETCH TRANSFER ADDRESS STA A XHI BSR GETCH STA A XLOW BRA LOAD1 LOAD2 BSR GETCH GET LOAD ADDRESS STA A XTEMP2 BSR GETCH STA A XTEMP2+1 BSR GETCH GET BYTE COUNT TAB SAVE BEQ LOAD1 BR IF COUNT=0 LOAD3 PSH B BSR GETCH GET NEXT BYTE PUL B LDX XTEMP2 GET LOAD ADDRESS STA A 0,X INX STX XTEMP2 DEC B END OF DATA RECORD? BNE LOAD3 BRA LOAD1 GET ANOTHER RECORD * GET CHARACTER ROUTINE - READS SECTOR IF NECESSARY GETCH LDX XTEMP1 CPX #BUFFER+256 OUT OF DATA BNE GETCH4 GO READ CHARACTER GETCH2 LDX #BUFFER LDA A 0,X GET NEXT TRACK LDA B 1,X GET NEXT SECTOR BEQ GETCH6 0 SECTOR ENDS LOAD GETCH3 JSR READ NEXT SECTOR BNE GETCH5 READ ERROR LDX #BUFFER+4 POINT PAST LINK GETCH4 LDA A 0,X GET CHAR FROM BUFFER INX STX XTEMP1 RTS GETCH5 JMP CTRL ERROR RETURN GETCH6 LDS SAVSTK CLEAR SUBROUTINES RTS PAG ****************************************** * FLEX 2 I/O DRIVERS FOR 5/8 CONTROLLER * COMMENTS FROM FLEX 6809 GUIDE * 02 DEC 1981 MICHAEL HOLLEY * EQUATES DRQ EQU $02 DRQ BIT MASK BUSY EQU $01 BUSY MASK RDMSK EQU $1C READ ERROR MASK VERMSK EQU $18 VERIFY ERROR MASK WTMSK EQU $5C WRITE ERROR MASK RDCMND EQU $8C READ COMMAND WTCMND EQU $AC WRITE COMMAND RSCMND EQU $18 RESTORE COMMAND SKCMND EQU $1B SEEK COMMAND ****************************************** * READ * Entry - (X) = FCB Sector Buffer Address * (A) = Track Number * (B) = Sector Number * The sector referenced by the track and sector * number is to be read into the Sector Buffer * area of the indicated FCB. READ BSR SEEK SET TRACK AND SECTOR LDA A #RDCMND SEI NO INTERRUPTS ALLOWED STA A COMREG READ SECTOR 10mS DELAY JSR DELAY READ2 LDA A DRQREG SET STATUS BMI READ3 BRANCH IF DATA PRESENT BEQ READ2 LOOP IF BUSY LDA B COMREG GET ERROR BRA READ6 REPORT ERROR READ3 LDA A DATREG READ SECTOR LOOP STA A 0,X INX JMP READ2 BSR WAIT WAIT UNTIL 1771 IS DONE READ6 BIT B #RDMSK NOP CLI ENABLE INTURRUPTS RTS WAIT LDA B COMREG GET STATUS BIT B #BUSY BNE WAIT RTS * SEEK THE SPECIFIED TRACK SEEK STA B SECREG SET SECTOR CMP B #10 BHI SIDE1 LDA B CURDRV BRA SEEK2 SIDE1 LDA B CURDRV ORA B #$40 SIDE 1 SEEK2 STA B DRVREG CMP A TRKREG BEQ SEEK4 TRACK IS CORRECT STA A DATREG CHANGE TRACK JSR DELAY LDA A #SKCMND STA A COMREG ISSUE SEEK COMMAND JSR DELAY BSR WAIT SEEK4 JMP DELAY JUMP AND RETURN DELAY JSR DELAY1 DELAY1 JSR DELAY2 DELAY2 RTS ****************************************** * WRITE * Entry - (X) = FCB Sector Buffer Address * (A) = Track Number * (B) = Sector Number * The sector referenced by the track and sector * number is to be written from the Sector Buffer * area of the indicated FCB. WRITE BSR SEEK SET TRACK AND SECTOR LDA A #WTCMND SEI NO INTERRUPTS ALLOWED STA A COMREG ISSUE WRITE COMMAND JSR DELAY LDA B 0,X WRITE2 LDA A DRQREG SET STATUS BMI WRITE3 BRANCH IF READY BEQ WRITE2 LOOP IF BUSY LDA B COMREG GET STATUS BRA WRITE6 DONE WRITE3 STA B DATREG SEND TO DISK INX LDA B 0,X GET NEXT BYTE JMP WRITE2 WRITE6 BIT B #WTMSK MASK ERRORS NOP CLI ENABLE INTERRUPTS RTS END START