MC3 monitor 1.4
Summer has been good in Sweden and besides spending time in the sun or repairing overheated RAID arrays I've had some time left over over lately to tie up the loose ends of my latest version of the MC3 monitor program. It's been a low paced on-and-off work since spring and now I've finally put together what I had and made a proper release. Changes from version 1.3 - Streamlining of static texts and user error handling for all commands - Added single step function - Interrupt vectors are now properly initialized on reset - Added ability to move stack pointer - Added I/O access helper routines - Added memory write function for more intuitive machine code input Complete list of available commands. G Go (RTI) J Jump to address L Load S19 from console MC Memory change MD Memory dump MF Memory fill MW Memory write RR Print contents of stack RC Change stack CC RA Change stack A RB Change stack B RX Change stack X RP Change stack PC RS Change stack pointer RM Reset stack pointer P Select I/O page S Single step X Enter extended ROM Single stepping using timed interrupts The single step function is rather unusual. Most single step routines I've seen has been relying on replacing op-codes with SWI (software interrupt) op-codes for halting the program flow. The major problem is how to handle forks in the program flow (conditional branches etc) and to ensure that the code is not destroyed by the single step routine itself. To avoid all of this I've used the built-in timer of the 6303. This timer is clocked by the same clock as the CPU core and therefore keeping it synchronous to the code execution and it also has it's own interrupt vectors differentiating the timer interrupts from other interrupts. Performing a single step is done by setting up the 6303 built-in timer to trigger an interrupt just after the CPU fetches the next op-code. The CPU finishes the op-code and then follows the timer interrupt vector back to the monitor where the contents of the stack is visualized and can be altered before another step can be performed. Using the timer in this way gets rid of all uncertainty of altering the code on the fly or simulating conditional branches. It also makes it possible to single step code in ROM! The single step routine can distinguish from user code and code from the monitor itself so routines in monitor ROM are simply skipped over for convenience (the monitor routines should be... ehm... thoroughly debugged anyway). This single stepping feature as proven quite useful as I was debugging FLEX2 for the MC3. I have actually used my MC3 to run and develop 6809 code using the Micro Works 6809 emulator for 6800. That way I can run FLEX9 but still use my 6303 hardware and mass storage driver code. That emulator is some crazy stuff written in 1978 and it was easily adapted to my MC3. Nice coding Micro Works! The goal is to get FLEX9 going on Tom LeMense's HD6309 SBC. Tom is another devoted 68xx enthusiast with some serious skills and a more modern approach to his designs compared to my ancient VHDL-less circuits. You should really check out his HD6309SBC project page at Hackaday! Below is the entire single step routine as included in monitor 1.4. *************** * DO SINGLE STEP SSTEP JSR PCRLF STEP LDS SP RESTORE PROGRAM STACK POINTER LDAB #$1F STPWAI DECB WAIT FOR EVENTUAL SCI XFER CMPB #$00 BEFORE TIMER INIT BNE STPWAI LDX #STOP SET INTERRUPT VECTOR STX TMOFVEC+1 LDX #$FFEC RESET COUNTER VALUE STX COUNTHI LDX TIMECON CLEAR INTERRUPT BIT IN TIMER CTRL REG LDAA #$04 ENABLE TIMER OVERFLOW INTERRUPT STAA TIMECON CLI CLEAR INTERRUPT BIT IN CC RTI *************** * SINGLE STEP INTERRUPT ENTRY STOP STS SP SAVE PROGRAM STACK POINTER LDX #INTSEQ RESTORE INTERRUPT VECTOR STX TMOFVEC+1 LDX TIMECON CLEARS INTERRUPT BIT IN TIMER CTRL REG LDAA #$00 DISABLE TIMER INTERRUPT STAA TIMECON LDX SP EXTRACT PROGRAM STOP ADDRESS LDAB #6 ABX LDX ,X CPX #$C000 BHI STEP NO STOP IN ROM STX XTEMP LDAB XTEMP CMPB #$7F BEQ STEP NO STOP IN PAGE $7F LDX #STOPTX JSR PDATA JMP PRTREG PRINT REGS AND GO TO PROMPT There is an extra dummy loop at the beginning since altering the timer while the serial interface is active can (and will) corrupt an ongoing transmission. The data sheet is clear about this and it is caused by the fact that some circuitry is shared between the timer and the serial interface. I/O helper routines Since the external memory bus of the MC3 is paged there are occasions where programs running from external memory needs to access memory or I/O devices in another page. That causes problems since swapping out a page with active code will crash the system. Therefore I have included two I/O access functions in the monitor ROM to handle this. One for reading a paged byte (IORD) and one for writing a paged byte (IOWR). The two functions, when called, transfers control to the monitor ROM which swaps the I/O page and accesses the byte needed and then swaps the page back again and returns to the calling program. A severe performance degradation but very simple to manage. Source of IORD and IOWR below. *************** * I/O READ FUNCTION * IN: X = ADDRESS * B = I/O PAGE * OUT: A = DATA IORD LDAA PIA1DAT PSHA SAVE PAGE REG STAB PIA1DAT SET NEW I/O PAGE LDAA ,X ACCESS I/O PAGE PULB STAB PIA1DAT RESTORE PAGE REG RTS *************** * I/O WRITE FUNCTION * IN: X = ADDRESS * B = I/O PAGE * A = DATA IOWR PSHA SAVE DATA LDAA PIA1DAT PSHA SAVE PAGE REG STAB PIA1DAT SET NEW I/O PAGE PULB RESTORE PAGE REG VALUE PULA RESORE DATA VALUE STAA ,X ACCESS I/O PAGE STAB PIA1DAT RESTORE PAGE REG RTS Jumptable at beginning of monitor. RETURN EQU $C000 RETURN TO MONITOR OUTCHAR EQU $C003 OUTPUT CHAR ON CONSOLE INCHAR EQU $C006 INPUT CHAR FROM CONSOLE AND ECHO PDATA EQU $C009 PRINT TEXT STRING @ X ENDED BY $04 OUTHR EQU $C00C PRINT RIGHT HEX CHAR @ X OUTHL EQU $C00F PRINT LEFT HEX CHAR @ X OUT2HS EQU $C012 PRINT 2 HEX CHARS @ X OUT4HS EQU $C015 PRINT 4 HEX CHARS @ X INHEX EQU $C018 INPUT 1 HEX CHAR TO A. CARRY SET = OK INBYTE EQU $C01B INPUT 1 BYTE TO A. CARRY SET = OK BADDR EQU $C01E INPUT ADDRESS TO X. CARRY SET = OK PCRLF EQU $C021 PRINT CRLF OUTS EQU $C024 PRINT SPACE IORD EQU $C027 I/O READ IOWR EQU $C02A I/O WRITE Source Below is the source for the new MC3 monitor. Monitor 1.4 - source listing s19 ($C000-$C7DC) Quickfile 1.0 - source listing s19 ($D000 - $DA3C) I have included the Quickfile source as well even though it's unchanged since previous version.
by Steve 2015-02-22 06:28 UTC
Hi, Thanks for creating and sharing this informative web site. I though I was the only person still messing around and learning about these old 8bit processors... I've loaded your monitor in a 6301 simulator that I wrote(on going project) and it works well.. but now I have a few questions... With your 'monitor', is there a way to display the PC counter position and maybe other register values? I can change it to a known value but wanted to know where I was after running some code.... and next question... what is the best way to load a program from the monitor (tinybasic for example)? My simulator loads s19,hex or bin images so maybe I could create a ROM image with the program I require and the monitor though this would be a nusence to then change programs for something else.... Just out of interest, what is the assembler you use for your 6303 code? Life would be simpler if Hitachi's 6301/6303 C compiler was available on the net... or HiTech's Thanks Steve...

by Daniel 2015-02-24 19:47 UTC
Cool project Steve! I'm glad you found my site useful. Your simulator sounds very interesting! My monitor is basically an improved version of the Motorola MIKBUG design (look for "Motorola engineering note 100"). If you want to display the CPU registers I think the best way is to simply execute an SWI op-code. That will return you to the monitor and from there you can use the register print command ("RR") to display the contents on the stack showing the registers as they were before the SWI occurred. You can use the other Rx commands to alter registers and then press "G" to continue execution using the new values. My single step routine depends on the internal timer of the 6303 so I'm unsure how that would behave in an emulated environment but by using single stepping it's possible to trace your program and watch the register changes. The monitor can load programs into memory using the serial console. The "L" command puts the monitor in load mode and it waits for Motorola S19-records (try pressing "L" and then "S9<enter>" to get back). Again this is basically the same design as the Motorola MIKBUG uses. In an emulator I suspect there may be other ways of simply loading programs directly into memory at a specific address and then use the "J" command from the monitor to begin execution. That's may be the quickest way. The assembler I'm using is an old and very simple assembler but I've been using it for quite a while and really like it's simplicity. I can send over to you if you like. Keep up the good work! Please share if you feel it's OK :) Daniel

Write a comment


E-mail (not visible)


Code from above