From 9352ad04fd20c0f96a2dd3324f452591a64919cf Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 18 Jul 2011 14:34:00 -0600 Subject: [PATCH] Initial commit. --- a1mon68.asm | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 a1mon68.asm diff --git a/a1mon68.asm b/a1mon68.asm new file mode 100644 index 0000000..1aaff7f --- /dev/null +++ b/a1mon68.asm @@ -0,0 +1,214 @@ +; This is a rewrite of the Apple 1 monitor to run on an MC6800 +; microprocessor, rather than the MCS6502 microprocessor that +; was standard. This source code will assemble with the +; AS Macro Assembler; with minor changes it should assemble +; with any MC6800 assembler. + +; Copyright 2011 Eric Smith +; +; This program is free software; you can redistribute and/or modify it +; under the terms of the GNU General Public License version 3 as +; published by the Free Software Foundation. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; The text of the license may be found online at: +; http://www.brouhaha.com/~eric/software/GPLv3 +; or: +; http://www.gnu.org/licenses/gpl-3.0.txt + + cpu 6800 + +xam equ $0024 ; two bytes +st equ $0026 ; two bytes +h equ $0028 +l equ $0029 + +mode equ $002b +ysav equ $002c ; two bytes +inptr equ $002e ; two bytes + +in equ $0200 + +kbd equ $d010 +kbd_cr equ $d011 +dsp equ $d012 +dsp_cr equ $d013 + + org $ff00 + +reset: ; cld ; No decimal mode on 6800, so we don't need + ; need to clear it. + ; cli ; Disable interrupts - not actually needed on reset. + ldab #$7f ; Mask for DSP data direction register. + stab dsp ; Set it up. + ldab #$a7 ; KBD and DSP control register mask. + stab kbd_cr ; Enable interrupts, set CA1, CB1, for + stab dsp_cr ; positive edge sense/output mode. + lds #$01ff ; On the 6502, the monitor didn't initialize the + ; stack pointer, which was OK because it was + ; guaranteed to be somewhere in page 1. Not so + ; on the 6800! + ; Ideally, I'd take advantage of the stack + ; starting right before the input buffer to + ; save a few bytes, but I haven't yet figured + ; out how to do it. + +; Note that B contains $a7 here, which means that the incb below will +; set the negative flag, causing the bpl to fall through into escape. +; This saves us a "bra escape" instruction here. + +; Get a line of input from the keyboard, echoing to display. +; Normally enter at escape or getline. + +notcr: cmpa #$df ; "_"? [NB back arrow] + beq backspace ; Yes. + cmpa #$9b ; ESC? + beq escape ; Yes. + inx ; Advance text index. + incb + bpl nextchar ; Auto ESC if > 127. + +escape: ldaa #$dc ; "\". + jsr echo ; Output it. + +getline: ldaa #$8d ; CR. + jsr echo ; Output it. + ldx #in+1 ; Initiallize [sic] text index. + ldab #1 +backspace: dex ; Back up text index. + decb + bmi getline ; Beyond start of line, reinitialize. + +nextchar: ldaa kbd_cr ; Key ready? + bpl nextchar ; Loop until ready. + ldaa kbd ; Load character. B7 should be '1'. + staa ,x ; Add to text buffer. + bsr echo ; Display character. + cmpa #$8d ; CR? + bne notcr ; No. + +; Process an input line. + +cr: ldx #in+256-1 ; Reset text index to in-1, +256 so that + ; 'inc inptr+1' will result in $0200. + stx inptr + clra ; For XAM mode. 0->B. + +setblok: asl a ; Leaves $56 if setting BLOCK XAM mode. +setmode: staa mode ; $00 = XAM, $BA = STOR, $56 = BLOK XAM. +blskip: inc inptr+1 ; Advance text index. +nextitem: ldx inptr + ldaa ,x ; Get character. + cmpa #$8d ; CR? + beq getline ; Yes, done this line. + cmpa #$ae ; "."? + beq setblok ; Set BLOCK XAM mode. + bls blskip ; Skip delimiter. + cmpa #$ba ; ":"? + beq setmode ; Yes, set STOR mode. + cmpa #$d2 ; "R"? + beq run ; Yes, run user program. + clr l ; $00->L. + clr h ; and H. + stx ysav ; Save Y for comparison. + +nexthex: ldx inptr + ldaa ,x ; Get character for hex test. + eora #$b0 ; Map digits to $0-9. + cmpa #$09 ; Digit? + bls dig ; Yes. + adda #$89 ; Map letter "A"-"F" to $FA-FF. + cmpa #$f9 ; Hex letter? + bls nothex ; No, character not hex. + +dig: asla ; Hex digit to MSD of A. + asla + asla + asla + + ldab #$04 ; Shift count. +hexshift: asla ; Hex digit left, MSB to carry. + rol l ; Rotate into LSD. + rol h ; Rotate into MSD's. + decb ; Done 4 shifts? + bne hexshift ; No, loop. + + inc inptr+1 ; Advance text index. + bra nexthex ; Always taken. Check next character for hex. + +nothex: cpx ysav ; Check if L, H empty (no hex digits). + beq escape ; Yes, generate ESC sequence. + tst mode ; Test MODE byte. + bpl notstor ; B6=0 for STOR, 1 for XAM and BLOCK XAM + +; STOR mode + ldx st + ldaa l ; LSD's of hex data. + staa ,x ; Store at current 'store index'. + inx + stx st +tonextitem: bra nextitem ; Get next command item. + +prbyte: psh a ; Save A for LSD. + lsra + lsra + lsra ; MSD to LSD position. + lsra + bsr prhex ; Output hex digit. + pul a ; Restore A. +prhex: anda #$0f ; Mask LSD for hex print. + oraa #$b0 ; Add "0". + cmpa #$b9 ; Digit? + bls echo ; Yes, output it. + adda #$07 ; Add offset for letter. +echo: tst dsp ; DA bit (B7) cleared yet? + bmi echo ; No, wait for display. + staa dsp ; Output character. Sets DA. + rts ; Return. + +run: ldx xam + jmp ,x ; Run at current XAM index. + +notstor: bne xamnext ; mode = $00 for XAM, $56 for BLOCK XAM. + + ldx h ; Copy hex data to + stx st ; 'store index'. + stx xam ; And to 'XAM index'. + clra ; set Z flag to force following branch. + +nxtprnt: bne prdata ; NE means no address to print. + ldaa #$8d ; CR. + bsr echo ; Output it. + ldaa xam ; 'Examine index' high-order byte. + bsr prbyte ; Output it in hex format. + ldaa xam+1 ; Low-order 'Examine index' byte. + bsr prbyte ; Output it in hex format. + ldaa #$ba ; ":". + bsr echo ; Output it. + +prdata: ldaa #$a0 ; Blank. + bsr echo ; Output it. + + ldx xam + ldaa ,x ; Get data byte at 'examine index'. + bsr prbyte ; Output it in hex format. + +xamnext: clr mode ; 0->MODE (XAM mode). + ldx xam ; Compare 'examine index' to hex data. + cpx h + beq tonextitem ; Not less, so more data to output. + inx + stx xam + ldaa xam+1 ; Check low-order 'examine index' byte + anda #$07 ; For MOD 8 = 0 + bra nxtprnt ; always taken + + org $fff8 ; vector table + fdb $0000 ; IRQ + fdb $0000 ; SWI + fdb $f000 ; NMI + fdb $ff00 ; RESET \ No newline at end of file