mirror of
https://github.com/RyuKojiro/apple1.git
synced 2024-11-19 18:32:12 +00:00
Replaced source with source that is actually just transcribed from the original Apple 1 manual
git-svn-id: svn+ssh://svn.phoenixbox.net/svn/apple1/trunk@48 64f78de7-aa59-e511-a0e8-0002a5492df0
This commit is contained in:
parent
1ecbc0e47e
commit
de7debbf8e
393
apple1/wozmon.s
393
apple1/wozmon.s
@ -1,259 +1,158 @@
|
||||
;-------------------------------------------------------------------------
|
||||
;
|
||||
; The WOZ Monitor for the Apple 1
|
||||
; Written by Steve Wozniak 1976
|
||||
;
|
||||
;-------------------------------------------------------------------------
|
||||
; Wozniak Apple1 Monitor
|
||||
|
||||
; .CR 6502
|
||||
; .OR $FF00
|
||||
; .TF WOZMON.HEX,HEX,8
|
||||
.org $FF00 ; Rom Start
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Memory declaration
|
||||
;-------------------------------------------------------------------------
|
||||
;******* Hardware Variables ************
|
||||
|
||||
XAML = $24 ; Last "opened" location Low
|
||||
XAMH = $25 ; Last "opened" location High
|
||||
STL = $26 ; Store address Low
|
||||
STH = $27 ; Store address High
|
||||
L = $28 ; Hex value parsing Low
|
||||
H = $29 ; Hex value parsing High
|
||||
YSAV = $2A ; Used to see if hex value is given
|
||||
MODE = $2B ; $00=XAM, $7F=STOR, $AE=BLOCK XAM
|
||||
DSP = $D012 ; Video I/O
|
||||
DSPCR = $D013
|
||||
|
||||
IN = $0200,$027F ; Input buffer
|
||||
KBD = $D010 ; Keyboard I/O
|
||||
KBDCR = $D011
|
||||
|
||||
KBD = $D010 ; PIA.A keyboard input
|
||||
KBDCR = $D011 ; PIA.A keyboard control register
|
||||
DSP = $D012 ; PIA.B display output register
|
||||
DSPCR = $D013 ; PIA.B display control register
|
||||
;********* Zero Page Variables *********
|
||||
|
||||
; KBD b7..b0 are inputs, b6..b0 is ASCII input, b7 is constant high
|
||||
; Programmed to respond to low to high KBD strobe
|
||||
; DSP b6..b0 are outputs, b7 is input
|
||||
; CB2 goes low when data is written, returns high when CB1 goes high
|
||||
; Interrupts are enabled, though not used. KBD can be jumpered to IRQ,
|
||||
; whereas DSP can be jumpered to NMI.
|
||||
XAML = $24
|
||||
XAMH = $25
|
||||
STL = $26
|
||||
STH = $27
|
||||
L = $28
|
||||
H = $29
|
||||
YSAV = $2A
|
||||
MODE = $2B
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Constants
|
||||
;-------------------------------------------------------------------------
|
||||
;******** $200-$27F Text Buffer *********
|
||||
|
||||
BS = $DF ; Backspace key, arrow left key
|
||||
CR = $8D ; Carriage Return
|
||||
ESC = $9B ; ESC key
|
||||
PROMPT = $DC ; Prompt character
|
||||
IN = $0200
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Let's get started
|
||||
;
|
||||
; Remark the RESET routine is only to be entered by asserting the RESET
|
||||
; line of the system. This ensures that the data direction registers
|
||||
; are selected.
|
||||
;-------------------------------------------------------------------------
|
||||
;******** Listing *************
|
||||
|
||||
RESET: CLD ; Clear decimal arithmetic mode
|
||||
RESET: CLD ; Clear decimal arithmetic mode.
|
||||
CLI
|
||||
LDY #%0111.1111 ; Mask for DSP data direction reg
|
||||
STY DSP ; (DDR mode is assumed after reset)
|
||||
LDA #%1010.0111 ; KBD and DSP control register mask
|
||||
STA KBDCR ; Enable interrupts, set CA1, CB1 for
|
||||
STA DSPCR ; positive edge sense/output mode.
|
||||
LDY #$7F ; Mask for DSP data direction register
|
||||
STY DSP ; Set it up.
|
||||
LDA #$A7 ; KBD and DSP control register mask.
|
||||
STA KBDCR ; Enable interrupts, set CA1, CB1, for
|
||||
STY DSPCR ; postitive edge sense/output mode.
|
||||
NOTCR: CMP #$DF ; "<-"?
|
||||
BEQ BACKSAPCE ; Yes.
|
||||
CMP #$9B ; ESC?
|
||||
BEQ ESCAPE ; Yes.
|
||||
INY ; Advance text index.
|
||||
BPL NEXTCHAR ; Auto ESC if > 127.
|
||||
ESCAPE: LDA #$DC ; "\".
|
||||
JSR ECHO ; Output it.
|
||||
GETLINE: LDA #$8D ; CR.
|
||||
JSR ECHO ; Output it.
|
||||
LDY #$01 ; Initiallize text index.
|
||||
BACKSPACE: DEY ; Backup text index.
|
||||
BMI GETLINE ; Beyond start of line, reinitialize
|
||||
NEXTCHAR: LDA KBDCR ; Key ready?
|
||||
BPL NEXTCHAR ; Loop until ready.
|
||||
LDA KBD ; Load character. B7 shoul be '1'
|
||||
STA IN,Y ; Add to text buffer.
|
||||
JSR ECHO ; Display character.
|
||||
CMP #$8D ; CR?
|
||||
BNE NOTCR ; No.
|
||||
LDY #$FF ; Reset text index.
|
||||
LDA #$00 ; For XAM mode.
|
||||
TAX ; 0->X.
|
||||
SETSTOR: ASL A ; Leaves $7B if setting STOR mode.
|
||||
SETMODE: STA MODE ; $00 = XAM, $7B = STOR, $A3 = BLOK XAM
|
||||
BLSKIP: INY ; Advance text index.
|
||||
NEXTITEM: LDA IN,Y ; Get character.
|
||||
CMP #$8D ; CR?
|
||||
BEQ GETLINE ; Yes, done this line.
|
||||
CMP #$A3 ; "."?
|
||||
BCC BLSKIP ; Skip delimiter.
|
||||
BEQ SETMODE ; Set BLOCK XAM mode.
|
||||
CMP #$BA ; ":"?
|
||||
BEQ SETSTOR ; Yes, set STOR mode.
|
||||
CMP #$D2 ; "R"?
|
||||
BEQ RUN ; Yes, run user program.
|
||||
STX L ; $00->L.
|
||||
STX H ; and H.
|
||||
STY YSAV ; Save Y for comparison.
|
||||
NEXTHEX: LDA IN,Y ; Get character for hex test.
|
||||
EOR #$B0 ; Map digits to $0-9.
|
||||
CMP #$0A ; Digit?
|
||||
BCC DIG ; Yes.
|
||||
ADC #$88 ; Map letter "A"-"F" to $FA-FF.
|
||||
CMP #$FA ; Hex letter?
|
||||
BCC NOHEX ; No, character not hex.
|
||||
DIG: ASL A
|
||||
ASL A ; Hex digit to MSD of A.
|
||||
ASL A ;
|
||||
ASL A ;
|
||||
LDX #$04 ; Shift count.
|
||||
HEXSHIFT: ASL A ; Hex digit left, MSDB to carry.
|
||||
ROL L ; Rotate into LSD.
|
||||
ROL H ; Rotate into MSD's.
|
||||
DEX ; Done 4 shifts?
|
||||
BNE HEXSHIFT ; No, loop.
|
||||
INY ; Advance text index.
|
||||
BNE NEXTHEX ; Always taken. Check next character for hex.
|
||||
NOTHEX: CPY YSAV ; Check if L, H empty (no hex digits)
|
||||
BEQ ESCAPE ; Yes, generate ESC sequence.
|
||||
BIT MODE ; Test MODE byte.
|
||||
BVC NOTSTOR ; B6 = 0 for STOR, 1 for XAM and BLOCK XAM
|
||||
LDA L ; LSD's of hex data.
|
||||
STA (STL,X) ; Store at current 'store index'.
|
||||
INC STL ; Increment store index.
|
||||
BNE NEXTITEM ; Get next item. (no carry).
|
||||
INC STH ; Add carry to 'store index' high order.
|
||||
TONEXTITEM: JMP NEXTITEM ; Get next command item.
|
||||
RUN: JMP (XAML) ; Run at current XAM index.
|
||||
NOTSTOR: BMI XAMNEXT ; B7 = 0 for XAM, 1 for BLOCK XAM.
|
||||
LDX #$02 ; Byte count.
|
||||
SETADR: LDA L-1,X ; Copy hex data to
|
||||
STA STL-1,X ; 'store index'.
|
||||
STA XAML-1,X ; And to 'XAM index'.
|
||||
DEX ; Next of 2 bytes.
|
||||
BNE SETADR ; Loop unless X = 0.
|
||||
NXTPRNT: BNE PRDATA ; NE means no address to print.
|
||||
LDA #$8D ; CR.
|
||||
JSR ECHO ; Output it.
|
||||
LDA XAMH ; 'Examine index' high-order byte.
|
||||
JSR PRBYTE ; Output it in hex format.
|
||||
LDA XAML ; Low-order 'examine index' byte.
|
||||
JSR PRBYTE ; Output it in hex format.
|
||||
LDA #$BA ; ":".
|
||||
JSR ECHO ; Output it.
|
||||
PRDATA: LDA #$A0 ; Blank.
|
||||
JSR ECHO ; Output it.
|
||||
LDA (XAML,X) ; Get data byte at 'examine index'
|
||||
JSR PRBYTE ; Output it in hex format.
|
||||
XAMNEXT: STX MODE ; 0->MODE (XAM mode).
|
||||
LDA XAML
|
||||
CMP L ; Comapre 'examine index' to hex data.
|
||||
LDA XAMH ;
|
||||
SBC H
|
||||
BCS TONEXTITEM ; Not less, so no more data to output.
|
||||
INC XAML ;
|
||||
BNE MOD8CHK ; Increment 'examine index'.
|
||||
INC XAMH ;
|
||||
MOD8CHK: LDA XAML ; Check low-order 'examine index' byte
|
||||
AND #$07 ; For MOD 8=0
|
||||
BPL NXTPRNT ; Always taken.
|
||||
PRBYTE: PHA ; Save A for LSD.
|
||||
LSR A
|
||||
LSR A
|
||||
LSR A ; MSD to LSD position.
|
||||
LSR A
|
||||
JSR PRHEX ; Output hex digit.
|
||||
PLA ; Restore A.
|
||||
PRHEX: AND #$0F ; Make LSD for hex print.
|
||||
ORA #$B0 ; Add "0".
|
||||
CMP #$BA ; Digit?
|
||||
BCC ECHO ; Yes, output it.
|
||||
ADC #$06 ; Add offset for letter.
|
||||
ECHO: BIT DSP ; DA bit (B7) cleared yet?
|
||||
BMI ECHO ; No, wait for display
|
||||
STA DSP ; Output character. Sets DA.
|
||||
RTS ; Return.
|
||||
|
||||
; Program falls through to the GETLINE routine to save some program bytes
|
||||
; Please note that Y still holds $7F, which will cause an automatic Escape
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; The GETLINE process
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
NOTCR: CMP #BS ; Backspace key?
|
||||
BEQ BACKSPACE ; Yes
|
||||
CMP #ESC ; ESC?
|
||||
BEQ ESCAPE ; Yes
|
||||
INY ; Advance text index
|
||||
BPL NEXTCHAR ; Auto ESC if line longer than 127
|
||||
|
||||
ESCAPE: LDA #PROMPT ; Print prompt character
|
||||
JSR ECHO ; Output it.
|
||||
|
||||
GETLINE: LDA #CR ; Send CR
|
||||
JSR ECHO
|
||||
|
||||
LDY #0+1 ; Start a new input line
|
||||
BACKSPACE: DEY ; Backup text index
|
||||
BMI GETLINE ; Oops, line's empty, reinitialize
|
||||
|
||||
NEXTCHAR: LDA KBDCR ; Wait for key press
|
||||
BPL NEXTCHAR ; No key yet!
|
||||
LDA KBD ; Load character. B7 should be '1'
|
||||
STA IN,Y ; Add to text buffer
|
||||
JSR ECHO ; Display character
|
||||
CMP #CR
|
||||
BNE NOTCR ; It's not CR!
|
||||
|
||||
; Line received, now let's parse it
|
||||
|
||||
LDY #-1 ; Reset text index
|
||||
LDA #0 ; Default mode is XAM
|
||||
TAX ; X=0
|
||||
|
||||
SETSTOR: ASL A ; Leaves $7B if setting STOR mode
|
||||
|
||||
SETMODE: STA MODE ; Set mode flags
|
||||
|
||||
BLSKIP: INY ; Advance text index
|
||||
|
||||
NEXTITEM: LDA IN,Y ; Get character
|
||||
CMP #CR
|
||||
BEQ GETLINE ; We're done if it's CR!
|
||||
CMP #"."
|
||||
BCC BLSKIP ; Ignore everything below "."!
|
||||
BEQ SETMODE ; Set BLOCK XAM mode ("." = $AE)
|
||||
CMP #":"
|
||||
BEQ SETSTOR ; Set STOR mode! $BA will become $7B
|
||||
CMP #"R"
|
||||
BEQ RUN ; Run the program! Forget the rest
|
||||
STX L ; Clear input value (X=0)
|
||||
STX H
|
||||
STY YSAV ; Save Y for comparison
|
||||
|
||||
; Here we're trying to parse a new hex value
|
||||
|
||||
NEXTHEX: LDA IN,Y ; Get character for hex test
|
||||
EOR #$B0 ; Map digits to 0-9
|
||||
CMP #9+1 ; Is it a decimal digit?
|
||||
BCC DIG ; Yes!
|
||||
ADC #$88 ; Map letter "A"-"F" to $FA-FF
|
||||
CMP #$FA ; Hex letter?
|
||||
BCC NOTHEX ; No! Character not hex
|
||||
|
||||
DIG: ASL A
|
||||
ASL A ; Hex digit to MSD of A
|
||||
ASL A
|
||||
ASL A
|
||||
|
||||
LDX #4 ; Shift count
|
||||
HEXSHIFT: ASL A ; Hex digit left, MSB to carry
|
||||
ROL L ; Rotate into LSD
|
||||
ROL H ; Rotate into MSD's
|
||||
DEX ; Done 4 shifts?
|
||||
BNE HEXSHIFT ; No, loop
|
||||
INY ; Advance text index
|
||||
BNE NEXTHEX ; Always taken
|
||||
|
||||
NOTHEX: CPY YSAV ; Was at least 1 hex digit given?
|
||||
BEQ ESCAPE ; No! Ignore all, start from scratch
|
||||
|
||||
BIT MODE ; Test MODE byte
|
||||
BVC NOTSTOR ; B6=0 is STOR, 1 is XAM or BLOCK XAM
|
||||
|
||||
; STOR mode, save LSD of new hex byte
|
||||
|
||||
LDA L ; LSD's of hex data
|
||||
STA (STL,X) ; Store current 'store index'(X=0)
|
||||
INC STL ; Increment store index.
|
||||
BNE NEXTITEM ; No carry!
|
||||
INC STH ; Add carry to 'store index' high
|
||||
TONEXTITEM: JMP NEXTITEM ; Get next command item.
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; RUN user's program from last opened location
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
RUN: JMP (XAML) ; Run user's program
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; We're not in Store mode
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
NOTSTOR: BMI XAMNEXT ; B7 = 0 for XAM, 1 for BLOCK XAM
|
||||
|
||||
; We're in XAM mode now
|
||||
|
||||
LDX #2 ; Copy 2 bytes
|
||||
SETADR: LDA L-1,X ; Copy hex data to
|
||||
STA STL-1,X ; 'store index'
|
||||
STA XAML-1,X ; and to 'XAM index'
|
||||
DEX ; Next of 2 bytes
|
||||
BNE SETADR ; Loop unless X = 0
|
||||
|
||||
; Print address and data from this address, fall through next BNE.
|
||||
|
||||
NXTPRNT: BNE PRDATA ; NE means no address to print
|
||||
LDA #CR ; Print CR first
|
||||
JSR ECHO
|
||||
LDA XAMH ; Output high-order byte of address
|
||||
JSR PRBYTE
|
||||
LDA XAML ; Output low-order byte of address
|
||||
JSR PRBYTE
|
||||
LDA #":" ; Print colon
|
||||
JSR ECHO
|
||||
|
||||
PRDATA: LDA #" " ; Print space
|
||||
JSR ECHO
|
||||
LDA (XAML,X) ; Get data from address (X=0)
|
||||
JSR PRBYTE ; Output it in hex format
|
||||
XAMNEXT: STX MODE ; 0 -> MODE (XAM mode).
|
||||
LDA XAML ; See if there's more to print
|
||||
CMP L
|
||||
LDA XAMH
|
||||
SBC H
|
||||
BCS TONEXTITEM ; Not less! No more data to output
|
||||
|
||||
INC XAML ; Increment 'examine index'
|
||||
BNE MOD8CHK ; No carry!
|
||||
INC XAMH
|
||||
|
||||
MOD8CHK: LDA XAML ; If address MOD 8 = 0 start new line
|
||||
AND #%0000.0111
|
||||
BPL NXTPRNT ; Always taken.
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Subroutine to print a byte in A in hex form (destructive)
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
PRBYTE: PHA ; Save A for LSD
|
||||
LSR A
|
||||
LSR A
|
||||
LSR A ; MSD to LSD position
|
||||
LSR A
|
||||
JSR PRHEX ; Output hex digit
|
||||
PLA ; Restore A
|
||||
|
||||
; Fall through to print hex routine
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Subroutine to print a hexadecimal digit
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
PRHEX: AND #%0000.1111 ; Mask LSD for hex print
|
||||
ORA #"0" ; Add "0"
|
||||
CMP #"9"+1 ; Is it a decimal digit?
|
||||
BCC ECHO ; Yes! output it
|
||||
ADC #6 ; Add offset for letter A-F
|
||||
|
||||
; Fall through to print routine
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Subroutine to print a character to the terminal
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
ECHO: BIT DSP ; DA bit (B7) cleared yet?
|
||||
BMI ECHO ; No! Wait for display ready
|
||||
STA DSP ; Output character. Sets DA
|
||||
RTS
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Vector area
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
.DA $0000 ; Unused, what a pity
|
||||
NMI_VEC .DA $0F00 ; NMI vector
|
||||
RESET_VEC .DA RESET ; RESET vector
|
||||
IRQ_VEC .DA $0000 ; IRQ vector
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
.LI OFF
|
||||
.byte $0000
|
||||
.byte $F000 NMI
|
||||
.byte $FF00 RESET
|
||||
.byte $0000 IRQ
|
||||
|
Loading…
Reference in New Issue
Block a user