-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwozmon.s
178 lines (167 loc) · 7.83 KB
/
wozmon.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
; The WOZ Monitor for the Apple 1
; Written by Steve Wozniak in 1976
; Adapted for R8 by Andreas J. Reichel in 2017
; Page 0 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
; Other Variables
IN = $0200 ; Input buffer to $027F
;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
; .org $F00
.SEGMENT "WOZMON" ; starts at 0xF800
; .export RESET
.export wozmon_start
.import serial_getc
.import serial_putc
wozmon_start:
RESET: CLD ; Clear decimal arithmetic mode.
;CLI
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
;STA DSPCR ; positive edge sense/output mode.
NOTCR:
;CMP #'_'+$80 ; "_"?
CMP #$DF ; AJR: Backspace
BEQ BACKSPACE ; Yes.
CMP #$9B ; ESC?
BEQ ESCAPE ; Yes.
INY ; Advance text index.
BPL NEXTCHAR ; Auto ESC if > 127.
ESCAPE: LDA #'\'+$80 ; "\".
JSR ECHO ; Output it.
GETLINE: LDA #$8A
JSR ECHO ; AJR
LDA #$8D ; CR.
JSR ECHO ; Output it.
LDY #$01 ; Initialize text index.
BACKSPACE: DEY ; Back up text index.
BMI GETLINE ; Beyond start of line, reinitialize.
NEXTCHAR: ;LDA KBDCR ; Key ready?
;BPL NEXTCHAR ; Loop until ready.
;LDA KBD ; Load character. B7 should be ‘1’.
JSR serial_getc
ORA #$80 ; AJR: emulate B7 from KBD
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 ; Leaves $7B if setting STOR mode.
SETMODE: STA MODE ; $00=XAM $7B=STOR $AE=BLOK XAM
BLSKIP: INY ; Advance text index.
NEXTITEM: LDA IN,Y ; Get character.
CMP #$8D ; CR?
BEQ GETLINE ; Yes, done this line.
CMP #'.'+$80 ; "."?
BCC BLSKIP ; Skip delimiter.
BEQ SETMODE ; Yes. Set STOR mode.
CMP #':'+$80 ; ":"?
BEQ SETSTOR ; Yes. Set STOR mode.
CMP #'R'+$80 ; "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 NOTHEX ; No, character not hex.
DIG: ASL
ASL ; Hex digit to MSD of A.
ASL
ASL
LDX #$04 ; 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. Check next char 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 STOR 1 for XAM & 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 #$8A
JSR ECHO ; AJR
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 #':'+$80 ; ":".
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 ; Compare ‘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: CLC
PHA ; Save A for LSD.
LSR
LSR
LSR ; MSD to LSD position.
LSR
JSR PRHEX ; Output hex digit.
PLA ; Restore A.
PRHEX: AND #$0F ; Mask LSD for hex print.
ORA #'0'+$80 ; Add "0".
CMP #$BA ; Digit?
BCC ECHO ; Yes, output it.
ADC #$06 ; Add offset for letter.
ECHO: ;BIT DSP ; bit (B7) cleared yet?
;BMI ECHO ; No, wait for display.
;STA DSP ; Output character. Sets DA.
PHA
AND #$7F
JSR serial_putc
PLA
RTS ; Return.
NOP
; Interrupt Vectors
;.WORD $0F00 ; NMI
;.WORD RESET ; RESET
;.WORD $0000 ; BRK/IRQ