Close
0%
0%

MIKBUG on Multicomp

Get MIKBUG on running on Multicomp

Similar projects worth following
Starting from
$15.00
land_boards has 379 orders / 14 reviews
Ships from United States of America
Grant Searle's Multicomp has ROM images for Z80 (CP/M and BASIC), 6502 (BASIC) and 6809 (BASIC) CPUs. Grant also has support for the 6800 but doesn't have a standard software image to run. Source code for the classic MIKBUG exists and makes a nice early retro computer.

MIKBUG was the classic Motorola ROM for the MC6800 CPU.  Engineering Note 100 has the original source code. The downside of the original code is that it used bit-banging of a Parallel port for serial I/O. 

There is some recent work on MIKBUG.  Mike Lee has a MC6802 build which  has a MC6850 ACIA (UART) instead of the parallel I/O port. This fits nicely with Multicomp which provides two versions of the ACIA. One of the versions is brought to a serial port. The other implements the UART as a VGA output with PS/2 keyboard. This allows the FPGA card to emulate an external terminal without extra hardware.

Mike Lee's board has the following hardware:

  • MC6802 CPU
  • SRAM at $0000-$7FFF (32KB)
  • EPROM at $F000-$FFFF (16KB)
  • (2) MC6821 Dual 8-bit Parallel I/O devices for 32 bits of I/O at $8000/1 and $8008/9
  • MC6850 ACIA at $8018/9

Mike has source code for the SMITHBUGS version of MIKBUG which uses the ACIA for I/O. The code has defines for the PIA but doesn't have any initialization code so it should be possible to build the FPGA without including PIA hardware.

MIKBUG is fairly small and only uses space from $C000-$C8FF.  The "Operating System" scratch space RAM is at $7F00-$7FFF so there will need to be RAM at the top of the 32KB SRAM range - should be no problem for the EP4CE15 FPGA. 

Our Implementation

We relocated MIKBUG to $F000-$FFFF and opened an I/O space from $FC00-$FCFF for the built-in Video Display Unit (ANSI terminal) and ACIA (Serial Port). That leaves a potential for 60KB of SRAM (if the card has enough SRAM) and plenty of other I/O.

  • 60KB of SRAM

    land-boards.com06/29/2020 at 11:03 0 comments

    Earlier we moved MIKBUG to $F000-$FFFF. We also opened a window for I/O from $FC00-$FCFF. 

    The entire space from $0000-$EFFF can be now used for SRAM. 

    Works well on EP2C5-DB card.

  • Loading Test Program

    land-boards.com06/29/2020 at 10:18 0 comments

    Wrote a small test program to get a character from the serial port and write it back to the serial port. Uses the MIKBUG serial in and out routines.

    ; TESTCODE.ASM
    ; DOS command line to assemble source
    ;     a68 TESTCODE.ASM -l TESTCODE.LST -s TESTCODE.s
    ; & to download S-record to card
    ; Copy/paste into PuTTY terminal
    
    ACIACS	EQU	$FC18
    ACIADA	EQU	$FC19
    
    START	
    			ORG	$0000
    LBACK
    		BSR		GETCHAR
    		BSR		OUTPUTA
    		JMP		LBACK
    ;
    GETCHAR	PSHB
    WAITIN	LDAB	ACIACS	; LOAD ACIA CONTROL REGISTER
    	ASRB	        ; SHIFT RIGHT  ACIADA
    	BCC 	WAITIN	; IF CARRY NOT SET THEN AGAIN
    	LDAA 	ACIADA	; LOAD DATA REGISTER
    	PULB		; RESTORE B REGISTER
    	RTS
    ;
    OUTPUTA	PSHB		; SAVE B
    WAITOUT	LDAB	ACIACS	; LOAD ACIA CONTROL REGISTER
    	ASRB		; SHIFT RIGHT
    	ASRB		; SHIFT RIGHT
    	BCC 	WAITOUT	; IF CARRY NOT SET DO AGAIN
    	STAA 	ACIADA	; SEND CHARACTOR TO ACIA
    	PULB		; RESTORE B
    	RTS		; RETURN FROM ROUTINE
    
    	END
    		

     Assembles to:

                            ; TESTCODE.ASM
                            ; DOS command line to assemble source
                            ;     a68 TESTCODE.ASM -l TESTCODE.LST -s TESTCODE.s
                            ; & to download S-record to card
                            ; Copy/paste into PuTTY terminal
                            
       fc18                 ACIACS	EQU	$FC18
       fc19                 ACIADA	EQU	$FC19
                            ;
       0000                 START	
       0000                 			ORG	$0000
       0000                 LBACK
       0000   8d 05         	BSR		GETCHAR
       0002   8d 0f         	BSR		OUTPUTA
       0004   7e 00 00      	JMP		LBACK
                            ;
       0007   37            GETCHAR	PSHB
       0008   f6 fc 18      WAITIN	LDAB	ACIACS	; LOAD ACIA CONTROL REGISTER
       000b   57            	ASRB	        ; SHIFT RIGHT  ACIADA
       000c   24 fa         	BCC 	WAITIN	; IF CARRY NOT SET THEN AGAIN
       000e   b6 fc 19      	LDAA 	ACIADA	; LOAD DATA REGISTER
       0011   33            	PULB		; RESTORE B REGISTER
       0012   39            	RTS
                            ;
       0013   37            OUTPUTA	PSHB		; SAVE B
       0014   f6 fc 18      WAITOUT	LDAB	ACIACS	; LOAD ACIA CONTROL REGISTER
       0017   57            	ASRB		; SHIFT RIGHT
       0018   57            	ASRB		; SHIFT RIGHT
       0019   24 f9         	BCC 	WAITOUT	; IF CARRY NOT SET DO AGAIN
       001b   b7 fc 19      	STAA 	ACIADA	; SEND CHARACTOR TO ACIA
       001e   33            	PULB		; RESTORE B
       001f   39            	RTS		; RETURN FROM ROUTINE
    
       0020                 	END
    fc18  ACIACS        fc19  ACIADA        0007  GETCHAR       0000  LBACK     
    0013  OUTPUTA       0000  START         0008  WAITIN        0014  WAITOUT   
    

    S-Record file:

    S11300008D058D0F7E000037F6FC185724FAB6FCD8
    S113001019333937F6FC18575724F9B7FC19333913
    S9030020DC
    

    Downloaded to the card.

    Works! 

  • MIKBUG S-Record Load Dropping Characters

    land-boards.com06/28/2020 at 13:30 0 comments

    MIKBUG is dropping a character during s-record-loads. Dropped baud rate from 115,200 to 9600 and it still drops character. RTS is not being de-asserted even when changing RTS buffer assertion levels so I don;t think it's an overrun. I have seen RTS deassert on larger transfers. 

    Trace is using DS Logic Plus on Tx, Rx, RTS_N lines.

    Load works OK at 2400 baud. Strange behavior.

    6800 assembly code

    S1STRING    FCC    "This S1 load has entered system scratch area"
            FCB    $0D,$0A,$04
    ; DGG - S Record loader
    SLOAD        EQU     *
            PSHA                ; Save A register
            STX    TEMPX1       ; Save X register
            ; DGG - Next line was BSR but fixing the CPX VAR lines made it too far away
    GOAGAIN JSR    GETCHAR      ; Get first charactor from ACIA
            ;  Wait for an S
            CMPA   #$53         ; Is it "S"
            BNE    GOAGAIN      ; If not go read again
            BSR    GETCHAR      ; Get second charactor in frame
            CMPA   #$39         ; Is it "9"
            BEQ    RECOVER      ; If "9" go and end read
            CMPA   #$31         ; Is it a "1"
            BNE    GOAGAIN      ; If no then go start again
            CLR    TEMPA        ; Clear Frame length
            BSR    GETHEX       ; Get frame length from input stream
            SUBA   #$02         ; Subtract the checksum
            STAA   BYTESTORE    ; Save frame length
            BSR    GETADD       ; Read next two bytes for dest address
    GETCOUNT BSR   GETHEX       ; Get the byte number
            DEC    BYTESTORE    ; decrement counter
            BEQ    INCOUNT      ; If zero go to increment byte count
            STAA   0,X          ; Store read byte into memory
            CMPA   0,X          ; Test if RAM OK
            BNE    QUESTION     ; If write failed send Question and abort
            INX                 ; Increment address pointer
    ; DGG - CPX was CMPX which did not compile and was commented out
    ; DGG- Changed branch from BGE to BLE (I think the compare worked the other way)
            CPX    VAR          ; Is it the system scratch area
            BGE    S1EXIT       ; Abort if close to system scratch
            BRA    GETCOUNT     ; go get another byte
    ;
    S1EXIT  LDX    #S1STRING    ; Protect System Scratch Abort S1
            BSR    OUTSTR       ; Print abort string
            BRA    RECOVER      ; Back to console prompt
    ;
    INCOUNT INC    TEMPA        ; Increment tempa 
            BEQ    GOAGAIN      ; If zero go for another frame
    QUESTION LDAA  #$3F         ; Load question mark
            JSR    OUTPUTA      ; Send to console
    RECOVER LDX    TEMPX1       ; Restore "X"
            PULA                ; Restore A
            JMP    CONTRL       ; Jump to exit
    ; 
    ;
    GETADD  BSR    GETHEX       ; Read in byte
            STAA   ADDRESS      ; store in first part of address
            BSR    GETHEX       ; Get another byte of data
            STAA   ADDRESS1     ; store in second address register
            LDX    ADDRESS      ; Load X register both bytes of address
            RTS                 ; Return from sub routine
    ;
    ;    ADD IN THE ADDRESS OFFSET
    ;
    GETHEX  BSR    CONVHEX  ; Go get byte of data and convert to binary 
            ASLA            ; Shift the the 4 bits into msb
            ASLA            ; Shift the the 4 bits into msb    
            ASLA            ; Shift the the 4 bits into msb    
            ASLA            ; Shift the the 4 bits into msb    
            TAB             ; Transfer "A" to "B"
            BSR    CONVHEX  ; Go get byte of data and convert to binary
            ABA             ; Add 4 bits in "A" and "B" into "B"
            TAB             ; Transfer "A" to "B"
            ADDB   TEMPA    ; Add into checksum
            STAB   TEMPA    ; Add into checksum
            RTS             ; Return from sub routine
    ;     
    CONVHEX JSR    GETCHAR  ; Get HEX charactor from ACIA
            SUBA   #$30     ; Convert to binary
            BMI    QUESTION ; Convert to binary
            CMPA   #$09     ; Convert to binary
            BLE    RETURN2  ; Convert to binary
            CMPA   #$11     ; Convert to binary
            BMI    INCSTACK ; Convert to binary
            CMPA   #$16     ; Convert to binary
            BGT    INCSTACK ; Convert to binary
            SUBA   #$07     ; Convert to binary
    RETURN2 RTS             ; Return from sub routine
    

    Shut off the echo and it works even at 115,200 baud:

  • Maxed Out SRAM

    land-boards.com06/26/2020 at 13:49 0 comments

    Couldn't resist tweeking the 6800/MIKBUG files. Opened up a window of the ROM from 0xFC00-0xFCFF and relocated the I/O up to that range. Had to do more mods to the MIKBUG source file.

    Now MIKBUG has a phenomenal 60KB of SRAM.

    Notes when altering MIKBUG source code

    Need to set the start of the 128 bytes scratchpad SRAM

    VAR EQU $EF00 ; TOP OF USER MEMORY

    Need to set the I/O addresses

    ;
    ACIACS    EQU    $FC18        ;V1 has $8000, $8001
    ACIADA    EQU    $FC19
    ;
    PIAD1A    EQU    $FC00        ;V2 has PIA support
    PIAS1A    EQU    $FC01
    PIAD1B    EQU    $FC02
    PIAS1B    EQU    $FC03
    ;
    PIAD2A    EQU    $FC08
    PIAS2A    EQU    $FC09
    PIAD2B    EQU    $FC0A
    

    PIAS2B EQU $FC0B

    Need to set the start of the code
    ;
    ;    OPT    MEMORY
    ;
        ORG    $F000            ;V1 has $F800H

  • Hand Jamming Code

    land-boards.com06/25/2020 at 22:49 0 comments

    MIKBUG provides support routines. The listing file has the addresses of the routines.

    INEEE is the input routine which gets a character from the current port.

    OUTEEE is the output routine which sends a character to the current port.

    Port loopback code:

    ; INEEE    EQU    $F1F3
    ; OUTEEE   EQU    $F20A
    
    LOOP4VR    
        JSR    $F1F3
        JSR    $F20A    
        BRA    LOOP4VR

    Code assembles to:

    0000 LOOP4VR   
    0000   bd F1 f3 JSR $F1F3   
    0003   bd F2 0a JSR $C20A   
    0006   20 f8    BRA LOOP4VR

    E to change memory:

    >E 0000
    >0000 55 BD
    >0001 55 F1
    >0002 55 F3
    >0003 55 BD
    >0004 55 F2
    >0005 55 0A
    >0006 55 40
    >0007 55 F8
    >0008 55 <ENTER>
    

     V to dump memory:

    >V
    FROM ADDR 0000
    0000 BD F1 F4 BD  F2 0A 40 F8  55 55 55 55  55 55 55 55
         ......@.UUUUUUUU
    

    Type N to turn off echo.

    J to jump to program:

    >J TO ADDR 0000 

    Type chars and they get echoed.

    ITTEESSTTIINNGG  TTHHIISS  WWOORRKKZZ  LLOOLLOOLLOOLLOOOOLL
    

  • MIKBUG with 56K of SRAM

    land-boards.com06/25/2020 at 19:56 0 comments

    The EP2C5-DB card has 128KB of SRAM external to the FPGA. I wanted to get access to more of that SRAM. There were a couple of things in the way. Getting to 32KB was easy. To get past the 32KB limit I needed to move the MIKBUG I/O up in the memory space. I also needed to move the ROM up to the top of RAM. 

    M6800_MIKBUG - Tested/Works

    • MC6800 CPU
    • Running MIKBUG from back in the day (SmithBug ACIA version)
    • 12.5 MHz
    • 56K (external) RAM version
    • MC6850 ACIA UART
    • Video Display Unit (VDU)
      • Color attributes
      • XGA 80x25 ANSI character display
      • Extended (256) character set
    • PS/2 keyboard

    Memory Map

    • $0000-$DFFF - 56KB external sRAM
      • $0000-$DEFF - User RAM area
      • $DF00-$DFFF - scratchpad used by MIKBUG
    • I/O Map
      • $E018-$E019 - VDU
      • $E028-$E029 - ACIA
          • Pin_60 of the FPGA swaps addresses of VDU and ACIA port
          • Installed (Pin_60 to Ground) uses Serial port
          • Removed uses VDU
    • $F000-$FFFF - MIKBUG ROM

    Changing MIKBUG ROM Location

    I am using the a68 assembler to assemble code to a S-record file and the S-Record utilities to re-shift the address of the assembled S-Record down to the state of the ROM as well as create the HEX file needed by Quartus. The ROM monitor source code is V2_DIS_corrected.ASM.

    The commands are:

    a68 V2_DIS_corrected.ASM -l V2_DIS_corrected.LST -s smithbug.s
    srec_cat smithbug.s -offset - -minimum-addr smithbug.s -o smithbug.hex -Intel

    The output file, smithbug.hex is then copied into the Multicomp ROMs location. Next run Multicomp and select Processing then Update Memory Initialization File. If you get a warning at this point of when you build the FPGA programming file double click the end delete the highlighted (next to the last line) in the hex file and save. Re-build at that point and the error will go away.

    Note than any code you have which relies on fixed locations for the MIKBUG ROM routines will need to be updated to use the new addresses. The listing file, V2_DIS_corrected.LST, contains the listing from the assembler output.

  • MIKBUG with 9KB SRAM

    land-boards.com06/25/2020 at 13:49 0 comments

    Made a new build of MIKBUG. It runs serial only but gives 9KB of SRAM internal to the SRAM.

    M6800_MIKBUG _Serial- Tested/Works

    • MC6800 CPU
    • Running MIKBUG from back in the day (SmithBug ACIA version)
    • 12.5 MHz
    • 9K (internal) RAM version
      • 8.5K User SRAM
      • 0.5K Scratchpad SRAM
    • MC6850 ACIA UART
      • No VDU

    Memory Map

    • $0000-$21FF - 8.5KB SRAM (internal RAM in the EPCE15)
      • User program SRAM
    • $7E00-$7FFF - 512B SRAM (internal RAM in the EPCE15)
      • 0x7E00-0x7EFF available for user
      • 0x7F00-0x7FFF are used as scratchpad RAM by MIKBUG
    • $8018-$8019 - ACIA
    • $C000-$CFFF - MIKBUG ROM (repeats 4 times from 0xC000-0xFFFF)

    The GitHub repository is here.

  • MIKBUG on Low End FPGA

    land-boards.com06/25/2020 at 11:39 0 comments

    Earlier, I got MIKBUG running on one of the inexpensive FPGA cards mounted to my EP2C5-DB

    The board has 128KB of SRAM (only 32 KB are usable by MIKBUG). While I was waiting for SRAM chips I wondered if I could get MIKBUG working on the FPGA without external SRAM.  Of course the capabilities would be limited to the Internal SRAM in the FPGA. Ther EP2C5 FPGA has are 26 blocks of 512 bytes for a total of 13K of SRAM. 

    MIKBUG goes from 0xC000-0xC8D5 which is 4KB of SRAM or 8 blocks of 512 bytes.

    I still wanted to keep the internal ANSI terminal for convenience but that can be reduced in size by eliminating the extended character set. Even with that, the ANSI terminal uses 10 of the 26 memory blocks of 512 bytes. The top of this has the vectors at 0xFFF8-0xFFFF. Th space is replicate 4 times by ignoring address bits A12 and A13 in the memory decoder.

    The SMITHSBUG version of MIKBUG needs 128 bytes of SRAM from 0x7F00 to 0x7FFF. Since the smallest block is 512 bytes that would means there will need to be 512 bytes of SRAM from 0x7E00-0x7FFF. The equation for the address select is:

    w_SP_RAM_CS <= (not w_cpuAddress(15)) and w_cpuAddress(14) and w_cpuAddress(13) and w_cpuAddress(12) and w_cpuAddress(11)  and   w_cpuAddress(10) and w_cpuAddress(9);
    

     This leaves 7 blocks for SRAM or 3.5KB. This gives SRAm from 0x0000-0x0BFF. The equations for the chip selects are:

        w_RAM_CS_1    <= (not w_cpuAddress(15)) and (not w_cpuAddress(14)) and (not w_cpuAddress(13)) and (not w_cpuAddress(12)) and (not w_cpuAddress(11));
        w_RAM_CS_2    <= (not w_cpuAddress(15)) and (not w_cpuAddress(14)) and (not w_cpuAddress(13)) and (not w_cpuAddress(12)) and      w_cpuAddress(11)  and (not w_cpuAddress(10));
        w_RAM_CS_3    <= (not w_cpuAddress(15)) and (not w_cpuAddress(14)) and (not w_cpuAddress(13)) and (not w_cpuAddress(12)) and (not w_cpuAddress(11)) and w_cpuAddress(10) and (not w_cpuAddress(9));
    

    The data multiplexer into the CPU is:

        -- ____________________________________________________________________________________
        -- CPU Read Data multiplexer
        w_cpuDataIn <=
            w_romData        when (w_cpuAddress(15) = '1') and (w_cpuAddress(14) = '1')    else
            w_ramData1        when w_RAM_CS_1    = '1'    else
            w_ramData2        when w_RAM_CS_2    = '1'    else
            w_ramData3        when w_RAM_CS_3    = '1'    else
            w_SPRamData        when w_SP_RAM_CS    = '1'    else
            w_if1DataOut    when w_n_if1CS     = '0'    else
            w_if2DataOut    when w_n_if2CS        = '0'    else
            x"FF";
    

    Dumping memory shows it worked.

    0BF0 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00
         ................
    0C00 FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF
         ................
    

     The GitHub repository is here.

  • Running on "original" Multicomp Hardware

    land-boards.com04/04/2020 at 15:52 0 comments

    Got MIKBUG up and running on the EP2C5-DB card which implements Grant's original Multicomp hardware design (defines which pins of the FPGA go to which I/O in a "standardized" way).  The GitHub code is here.  Running with external SRAM (32KB used out of the 128KB SRAM part). 

    A jumper on J8 provides port selection between the Serial port (on J5) and the VDU (VGA output and PS/2 input). Installing the jumper to the adjacent ground pin routes I/O to the Serial port. Removing the jumper routes I/O to the VDU. In the picture below the Serial port is wired to an external FTDI card.

  • Running on Rev 2 FPGA card

    land-boards.com03/08/2020 at 11:09 0 comments

    Built up a rev 2 RETRO-EP4CE15 card. The Rev 2 card replaces the USB C connector with a USB Micro connector. It also changes the VGA HD15 connector to the more usual footprint.

    Re-compiled all of the Multicomp examples and got them working (GitHub repositories). Also, got my 32-bit RISC CPU (R32V2020) running.

View all 24 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates