-
Notifications
You must be signed in to change notification settings - Fork 8
/
auxmem.init.s
227 lines (203 loc) · 8.52 KB
/
auxmem.init.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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
* AUXMEM.INIT.S
* (c) Bobbi 2021 GPL v3
*
* Initialization code running in Apple //e aux memory
* 08-Nov-2022 ResetType OSBYTE set
* 09-Nov-2022 Current language re-entered, reset on Power/Hard Reset
* 12-Dec-2022 Copy loop uses OSvars, single byte for MODBRA jump.
* 15-Dec-2022 Added check for *FX200,2/3 force PowerOn reset.
* BUG: If Ctrl-Break pressed during a service call, wrong ROM gets paged in
***********************************************************
* BBC Micro 'virtual machine' in Apple //e aux memory
***********************************************************
MAXROM EQU $F9 ; Max sideways ROM number
FXLANG EQU BYTEVARBASE+$FC ; Current language
FXRESET EQU BYTEVARBASE+$FD ; Last Reset type
FXOPTIONS EQU BYTEVARBASE+$FF ; Startup options
ZP1 EQU $90 ; $90-$9f are spare Econet space
; so safe to use
ZP2 EQU $92
ZP3 EQU $94
MOSSHIM
ORG AUXMOS ; MOS shim implementation
*
* Shim code to service Acorn MOS entry points using
* Apple II monitor routines
* This code is initially loaded into aux mem at AUXMOS1
* Then relocated into aux LC at AUXMOS by MOSINIT
*
* Initially executing at $2000 until copied to $D000
*
* When first run from loading from disk:
* Code will be at $2000-$4FFF, then copied to $D000-$FFFF
* When Ctrl-Reset pressed:
* AUX RESET code jumps to MAIN $D000
*
MOSINIT SEI ; Ensure IRQs disabled
LDX #$FF ; Initialize Alt SP to $1FF
TXS
* Ensure memory map set up:
STA WRCARDRAM ; Make sure we are writing aux
STA 80STOREOFF ; Make sure 80STORE is off
STA SET80VID ; 80 col on
STA CLRALTCHAR ; Alt charset off
STA PAGE2 ; PAGE2
LDA LCBANK1 ; LC RAM Rd/Wt, 1st 4K bank
LDA LCBANK1
* (Move these later to prevent brief glimpse of screen with code in it?)
LDY #$00 ; $00=Soft Reset
:MODBRA SEC ; Changed to CLC after first run
BCC :NORELOC ; Subsequent run, skip to code
* Copy code to high memory, (OSCTRL)=>source, (OSLPTR)=>dest
:RELOC LDA #<AUXMOS1 ; Source
STA OSCTRL+0
LDA #>AUXMOS1
STA OSCTRL+1
STY OSLPTR+0 ; Y=0 from earlier
LDA #>AUXMOS ; AUXMOS is always &xx00
STA OSLPTR+1
:L1 LDA (OSCTRL),Y ; Copy from source
STA (OSLPTR),Y ; to dest
INY
BNE :L1 ; Do 256 bytes
INC OSCTRL+1 ; Update source
INC OSLPTR+1 ; Update dest
BMI :L1 ; Loop until wrap past &FFFF
*
:L2 LDA MOSVEND-AUXMOS+AUXMOS1-256,Y
STA $FF00,Y ; Copy MOS API and vectors
INY ; to proper place
BNE :L2
LDA #$18 ; CLC opcode, next time around, we're
STA :MODBRA ; already in high memory
LDY #$02 ; $02=PowerOn
* We only change one byte to protect against a RESET happening halfway between
* two bytes being changed, leaving the code inconsistant.
:NORELOC JMP MOSHIGH ; Ensure executing in high memory from here
* From here onwards we are always executing at $D000 onwards
* Y=ResetType
MOSHIGH SEI ; Ensure IRQs disabled
LDX #$FF
TXS ; Initialise stack
LDA FX200VAR ; Check *FX200
AND #$02 ; Check if bit 1 set
BEQ :SCLR0 ; No, keep existing ResetType
TAY ; Otherwise, force to PowerOn reset
:SCLR0 PHY ; Stack ResetType
LDA FXLANG ; A=Language
LDY FXSOFTOK ; Y=Soft Keys Ok
INX ; X=$00
:SCLR STZ $0000,X ; Clear Kernel memory
STZ $0200,X
STZ $0300,X
INX
BNE :SCLR
STA FXLANG ; Current language
STY FXSOFTOK ; Soft key validity
PLA
STA FXRESET ; Set ResetType
BEQ :INITPG2 ; Soft Reset, preserve settings
DEX ; X=$FF
STX FXLANG ; Current language=none
STX FXSOFTOK ; Invalidate soft keys
:INITPG2 LDX #ENDVEC-DEFVEC-1
:INITPG2LP LDA DEFVEC,X ; Set up vectors
STA $200,X
DEX
BPL :INITPG2LP
LDA CYAREG ; GS speed register
AND #$80 ; Speed bit only
STA GSSPEED ; In Alt LC for IRQ/BRK hdlr
JSR ROMINIT ; Build list of sideways ROMs
JSR KBDINIT ; Returns A=startup MODE
JSR VDUINIT ; Initialise VDU driver
JSR PRHELLO
JSR OSNEWL
LDA FXRESET ; Get ResetType
BEQ :INITSOFT ; Soft reset, skip past
LDA #7 ; Beep on HardReset/PowerReset
JSR OSWRCH
*
* AppleII MOS beeps anyway, so we always get a Beep
* APPLECORN startup -> BBC Beep
* Press Ctrl-Reset -> AppleII Beep
*
* Find a language to enter
:INITSOFT LDX FXLANG ; Get current language
BPL INITLANG ; b7=ok, use it
LDX ROMMAX ; Look for a language
:FINDLANG JSR ROMSELECT ; Bring ROM X into memory
BIT $8006 ; Check ROM type
BVS INITLANG ; b6=set, use it
DEX ; Step down to next ROM
BPL :FINDLANG ; Loop until all tested
ERRNOLANG BRK ; No language found
DB $F9
ASC 'No Language'
BRK
*
INITLANG CLC ; CLC=Entering from RESET
* OSBYTE $8E - Enter language ROM
*********************************
* X=ROM number to select, CC=RESET, CS=*COMMAND/OSBYTE
*
BYTE8E PHP ; Save CLC=RESET, SEC=Not RESET
JSR ROMSELECT ; Bring ROM X into memory
BIT $8006
BVC ERRNOLANG ; No language in this ROM
LDA #$00
STA FAULT+0
LDA #$80
STA FAULT+1
LDY #$09
JSR PRERRLP ; Print ROM name with PRERR to set
STY FAULT+0 ; FAULT pointing to version string
JSR OSNEWL
JSR OSNEWL
STX FXLANG ; Set as current language ROM
PLP ; Get entry type back
LDA #$01 ; $01=Entering code with a header
JMP ROMAUXADDR
* OSBYTE $8F - Issue service call
*********************************
* X=service call, Y=parameter
*
* SERVICE TAX ; Enter here with A=Service Num
SERVICEX
BYTE8F LDA $F4 ; Enter here with X=Service Number
PHA ; Save current ROM
*DEBUG
LDA $E0
AND #$20 ; Test debug *OPT255,32
BEQ :SERVDEBUG
CPX #$06
BEQ :SERVDONE ; If debug on, ignore SERV06
:SERVDEBUG
*DEBUG
TXA ; A=service number
LDX ROMMAX ; Start at highest ROM
:SERVLP JSR ROMSELECT ; Bring it into memory
BIT $8006
BPL :SERVSKIP ; No service entry
JSR $8003 ; Call service entry
TAX
BEQ :SERVDONE
:SERVSKIP LDX $F4 ; Restore X=current ROM
DEX ; Step down to next
BPL :SERVLP ; Loop until ROM 0 done
:SERVDONE PLA ; Get caller's ROM back
PHX ; Save return from service call
TAX
JSR ROMSELECT ; Restore caller's ROM
PLX ; Get return value back
TXA ; Return in A and X and set EQ/NE
RTS
PRHELLO LDX #<HELLO
LDY #>HELLO
JSR OSPRSTR
JMP OSNEWL
BYTE00 BEQ BYTE00A ; OSBYTE 0,0 - generate error
LDX #$0A ; Identify Host
RTS ; %000x1xxx host type, 'A'pple
BYTE00A BRK
DB $F7