mirror of
https://github.com/stid/APPLE-1-ReplicaDue.git
synced 2024-06-04 22:29:29 +00:00
259 lines
11 KiB
NASM
259 lines
11 KiB
NASM
; dasm woz_monitor_masm.asm -orom.o -lrom.lst -srom.sym
|
|
|
|
;-------------------------------------------------------------------------
|
|
;
|
|
; The WOZ Monitor for the Apple 1
|
|
; Written by Steve Wozniak 1976
|
|
;
|
|
;-------------------------------------------------------------------------
|
|
|
|
processor 6502
|
|
org $FF00
|
|
|
|
;-------------------------------------------------------------------------
|
|
; Memory declaration
|
|
;-------------------------------------------------------------------------
|
|
|
|
XAML equ $24 ;Last "opened" location Low
|
|
XAMH equ $25 ;Last "opened" location High
|
|
STL equ $26 ;Store address Low
|
|
STH equ $27 ;Store address High
|
|
L equ $28 ;Hex value parsing Low
|
|
H equ $29 ;Hex value parsing High
|
|
YSAV equ $2A ;Used to see if hex value is given
|
|
MODE equ $2B ;$00=XAM, $7F=STOR, $AE=BLOCK XAM
|
|
|
|
IN equ $0200,$027F ;Input buffer
|
|
|
|
KBD equ $D010 ;PIA.A keyboard input
|
|
KBDCR equ $D011 ;PIA.A keyboard control register
|
|
DSP equ $D012 ;PIA.B display output register
|
|
DSPCR equ $D013 ;PIA.B display control register
|
|
|
|
; 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.
|
|
|
|
;-------------------------------------------------------------------------
|
|
; Constants
|
|
;-------------------------------------------------------------------------
|
|
|
|
BS equ $DF ;Backspace key, arrow left key
|
|
CR equ $8D ;Carriage Return
|
|
ESC equ $9B ;ESC key
|
|
PROMPT equ $5C ;Prompt character \
|
|
|
|
;-------------------------------------------------------------------------
|
|
; 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.
|
|
;-------------------------------------------------------------------------
|
|
|
|
RESET cld ;Clear decimal arithmetic mode
|
|
cli
|
|
ldy #%01111111 ;Mask for DSP data direction reg
|
|
sty DSP ;(DDR mode is assumed after reset)
|
|
lda #%10100111 ;KBD and DSP control register mask
|
|
sta KBDCR ;Enable interrupts, set CA1, CB1 for
|
|
sta DSPCR ;positive edge sense/output mode.
|
|
|
|
; 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 ;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
|
|
asl ;Hex digit to MSD of A
|
|
asl
|
|
asl
|
|
|
|
ldx #4 ;Shift count
|
|
HEXSHIFT asl ;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 #%00000111
|
|
bpl NXTPRNT ;Always taken.
|
|
|
|
;-------------------------------------------------------------------------
|
|
; Subroutine to print a byte in A in hex form (destructive)
|
|
;-------------------------------------------------------------------------
|
|
|
|
PRBYTE pha ;Save A for LSD
|
|
lsr
|
|
lsr
|
|
lsr ;MSD to LSD position
|
|
lsr
|
|
jsr PRHEX ;Output hex digit
|
|
pla ;Restore A
|
|
|
|
; Fall through to print hex routine
|
|
|
|
;-------------------------------------------------------------------------
|
|
; Subroutine to print a hexadecimal digit
|
|
;-------------------------------------------------------------------------
|
|
|
|
PRHEX and #%00001111 ;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
|
|
;-------------------------------------------------------------------------
|
|
|
|
dc.w $0000 ;Unused, what a pity
|
|
NMI_VEC dc.w $0F00 ;NMI vector
|
|
RESET_VEC dc.w RESET ;RESET vector
|
|
IRQ_VEC dc.w $0000 ;IRQ vector
|
|
|
|
;-------------------------------------------------------------------------
|