-
Notifications
You must be signed in to change notification settings - Fork 8
/
auxmem.misc.s
539 lines (495 loc) · 18.4 KB
/
auxmem.misc.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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
* AUXMEM.MISC.S
* (c) Bobbi 2021 GPLv3
*
* Misc functions and API entry block
* 02-Sep-2021 Written GSINIT/GSREAD
* 11-Sep-2021 PR16DEC uses OS workspace, added rest of default vectors/etc.
* 20-Sep-2021 Updated PRDECIMAL routine, prints up to 32 bits.
* 25-Oct-2021 Initial pseudo-sideways ROM selection code.
* 26-Oct-2021 Corrected entry parameters to OSRDRM.
* 03-Nov-2021 Temp'y fix, if can't find SROM, ignores it.
* 13-Nov-2021 ROMSELECT calls mainmem to load ROM.
* 08-Oct-2022 ROMSEL doesn't call loader if already paged in.
* OSBYTE $80 - ADVAL
************************************
* Read input device or buffer status
BYTE80 LDY #$00 ; Prepare return=&00xx
TXA ; X<0 - info about buffers
BMI ADVALBUF ; X>=0 - read input devices
CPX #$7F
BNE ADVALNONE
ADVALWAIT JSR KBDREAD
BCS ADVALWAIT
TAX
BPL ADVALOK1 ; &00xx for normal keys
INY ; &01xx for function/edit keys
ADVALOK1 RTS
ADVALNONE LDX #$00 ; Input, just return 0
RTS
ADVALBUF INX
BEQ :ADVALKBD ; Fake keyboard buffer
INX
BEQ :ADVALOK ; Serial input, return 0
LDX #$01 ; For outputs, return 1 char free
RTS
:ADVALKBD BIT KBDDATA ; Test keyboard data/strobe
BPL :ADVALOK ; No Strobe, return 0
INX ; Strobe, return 1
:ADVALOK RTS
* Beep
******
* Sound measurement shows the tone formula is:
* 1.230 MHz
* ------------- = cycles
* 8 * frequency
*
* cycles = BEEPX*5+10
*
* So:
* BEEPX = (cycles-10)/5
* So:
* BEEPX = ( 1.230 MHz )
* (------------- - 10 ) / 5
* (8 * frequency )
* BEEPX EQU #57 ; note=C5
BEEPX EQU #116 ; note=C4
BEEP PHA
PHX
PHY
LDY #$00 ; duration
:L1 LDX #BEEPX ; 2cy pitch 2cy
*------------------------------------------------------
:L2 DEX ; 2cy BEEPX * 2cy
BNE :L2 ; 3cy/2cy (BEEPX-1) * 3cy + 1 * 2cy
*------------------------------------------------------
* BEEPX*5-1cy
LDA SPKR ; 4cy BEEPX*5+5
DEY ; 2cy BEEPX*5+7
BNE :L1 ; 3cy/2cy BEEPX*5+10
PLY ;
PLX
PLA
PRSTROK RTS
* OSPRSTR - Print string at XY
******************************
* On exit, X,Y preserved, A=$00
OUTSTR TXA
* Print string pointed to by A,Y to the screen
PRSTR STA OSTEXT+0 ; String in A,Y
STY OSTEXT+1
:L1 LDA (OSTEXT) ; Ptr to string in OSTEXT
PHP ; Save EQ
INC OSTEXT
BNE :L2
INC OSTEXT+1
:L2 PLP ; Get EQ back
BEQ PRSTROK ; End of string
JSR OSASCI
BRA :L1
* Print NL if not already at column 0
FORCENL LDA #$86
JSR OSBYTE
TXA
BEQ PRSTROK
JMP OSNEWL
* PR2HEX - Print XY in hex
**************************
OUT2HEX TYA
JSR OUTHEX
TXA ; Continue into OUTHEX
* PR1HEX - Print hex byte in A
******************************
OUTHEX PHA
LSR
LSR
LSR
LSR
AND #$0F
JSR PRNIB
PLA
AND #$0F ; Continue into PRNIB
* Print hex nibble in A
PRNIB CMP #$0A
BCC :S1
CLC ; >= $0A
ADC #'A'-$0A
JSR OSWRCH
RTS
:S1 ADC #'0' ; < $0A
JMP OSWRCH
* OSPRDEC - Print up to 32-bit decimal number
*********************************************
* See forum.6502.org/viewtopic.php?f=2&t=4894
* and groups.google.com/g/comp.sys.apple2/c/_y27d_TxDHA
*
* X=>four byte zero page locations
* Y= number of digits to pad to, 0 for no padding
*
PRINTDEC STY OSPAD ; Number of padding+digits
LDY #0 ; Digit counter
PRDECDIGIT LDA #32 ; 32-bit divide
STA OSTEMP
LDA #0 ; Remainder=0
CLV ; V=0 means div result = 0
PRDECDIV10 CMP #10/2 ; Calculate OSNUM/10
BCC PRDEC10
SBC #10/2+$80 ; Remove digit & set V=1 to show div result > 0
SEC ; Shift 1 into div result
PRDEC10 ROL 0,X ; Shift /10 result into OSNUM
ROL 1,X
ROL 2,X
ROL 3,X
ROL A ; Shift bits of input into acc (input mod 10)
DEC OSTEMP
BNE PRDECDIV10 ; Continue 32-bit divide
ORA #48
PHA ; Push low digit 0-9 to print
INY
BVS PRDECDIGIT ; If V=1, result of /10 was > 0 & do next digit
LDA #32
PRDECLP1 CPY OSPAD
BCS PRDECLP2 ; Enough padding pushed
PHA ; Push leading space characters
INY
BNE PRDECLP1
PRDECLP2 PLA ; Pop character left to right
JSR OSWRCH ; Print it
DEY
BNE PRDECLP2
RTS
* GSINIT - Initialise for GSTRANS string parsing
************************************************
* On entry,
* (OSLPTR),Y=>start of string (spaces will be skipped)
* CLC = filename style parsing
* SEC = *KEY style parsing
* On exit,
* X = preserved
* Y = prepared for future calls to GSREAD
* EQ = end of line (nb: not "" null string)
* NE = not end of line
*
* Very difficult to write this without it being a direct clone
* from the BBC MOS. ;)
*
GSINTGO ROR GSFLAG ; CY initially into bit 7
JSR SKIPSPC ; Skip any spaces
INY ; Step past in case it's a quote
CMP #$22 ; Is it a quote?
BEQ GSINTGO1
DEY ; Wasn't a quote, step back
CLC ; Prepare CC=no leading quote
GSINTGO1 ROR GSFLAG ; Rotate 'leading-quote' into flags
CMP #$0D
RTS ; Return EQ if end of line
* GSFLAG set to:
* bit7: leading quote found
* bit6: CC=filename CS=*KEY
* GSREAD - Read a character from a GSTRANS parsed string
********************************************************
* On entry,
* (OSLPTR),Y=>current string pointer
* On exit,
* A = parsed character
* X = preserved
* CS = end of string (space or <cr> or ")
* Y =updated to start of next word or end of line
* EQ=end of line after this string
* NE=not end of line, more words follow
* CC = not end of string
* Y =updated for future calls to GSREAD
* VS=7-bit control character, (char AND $7F)<$20
* VC=not 7-bit control character (char AND $7F)>$1F
* EQ= char=$00, NE= char>$00
* PL= char<$80, MI= char>$7F
*
* No string present is checked for with:
* JSR GSINIT:BEQ missingstring
*
* A null string is checked for with:
* JSR GSINIT:JSR GSREAD:BCS nullstring
*
* A string is skipped with:
* JSR GSINIT
* loop
* JSR GSREAD:BCC loop
*
* A string is copied with:
* JSR GSINIT
* LDX #0
* loop
* JSR GSREAD:BCS done
* STA data,X
* INX:BNE loop
* done
*
GSRDGO LDA #$00 ; Prepare to clear accumulator
GSREADLP STA GSCHAR ; Update accumulator
LDA (OSLPTR),Y ; Get current character
CMP #$0D ; End of line?
BNE GSREAD2 ; No, check character
BIT GSFLAG
BPL GSREADEND ; We aren't waiting for a closing quote
* ; End of line before closing quote
ERRBADSTR BRK
DB $FD
ASC 'Bad string'
BRK
GSREAD2 CMP #' '
BCC ERRBADSTR ; Embedded control char
BNE GSREAD3 ; Not a space, process it
BIT GSFLAG ; Can space terminate string?
BMI GSREADCHAR ; We're waiting for a terminating quote
* ; so return the space character
BVC GSREADEND ; Space is a terminator, finish
GSREAD3 CMP #$22 ; Is it a quote?
BNE GSREADESC ; Not quote, check for escapes
BIT GSFLAG ; Was there an opening quote?
BPL GSREADCHAR ; Not waiting for a closing quote
INY ; Waiting for quote, check next character
LDA (OSLPTR),Y
CMP #$22 ; Is it another quote?
BEQ GSREADCHAR ; Quote-Quote, expand to single quote
* End of string
* Either closing quote, or a space seperator, or end of line
GSREADEND JSR SKIPSPC ; Skip any spaces to next word
SEC ; SEC=end of string
RTS ; and (OSLPTR),Y=>next word or end of line
* CS=end of string
* EQ=end of line
* NE=not end of line, more words follow
GSREADESC CMP #$7C ; Is it '|' escape character
BNE GSREADCHAR ; No, return as character
INY ; Step to next character
LDA (OSLPTR),Y
CMP #$7C
BEQ GSREADCHAR ; bar-bar expands to bar
CMP #$22
BEQ GSREADCHAR ; bar-quote expands to quote
CMP #'!' ; Is it bar-pling?
BNE GSREAD5 ; No, check for bar-letter
INY ; Step past it
LDA #$80 ; Set bit 7 in accumulator
BNE GSREADLP ; Loop back to check next character(s)
GSREAD5 CMP #'?' ; Check for '?'
BCC ERRBADSTR ; <'?', bad character
BEQ GSREADDEL ; bar-query -> DEL
AND #$1F ; Convert bar-letter to control code
BIT SETV ; SEV=control character
BVS GSREADOK
GSREADDEL LDA #$7F
GSREADCHAR CLV ; CLV=not control character
GSREADOK INY ; Step to next character
ORA GSCHAR ; Add in any bit 7 from |! prefix
CLC ; CLC=not end of string
RTS
* CC=not end of string
* VS=control character
* VC=not control character
* OSRDROM - Read a byte from sideways ROM
*****************************************
* On entry, Y=ROM to read from
* (ROMPTR)=>byte to read
* On exit, A=byte read, X=current ROM, Y=$00
RDROM LDA ROMID
PHA ; Save current ROM
TYA
TAX ; X=ROM to read from
JSR ROMSELECT ; Page in the required ROM
LDY #$00 ; NOTE BBC sets Y=0, Master preserves
LDA (ROMPTR),Y ; Read the byte
PLX
* ROMSELECT - Select a sideways ROM
***********************************
* On entry, X=ROM to select
* On exit, All registers must be preserved
*
ROMSELECT
* Insert code here for faking sideways ROMs by loading or otherwise
* fetching code to $8000. All registers must be preserved.
PHP
CPX ROMID ; Speed up by checking if
BEQ ROMSELOK ; already paged in
PHA
PHX
PHY
* LDA $FF
* JSR PR1HEX
SEI
TXA ; A=ROM to select
>>> XF2MAIN,SELECTROM
ROMSELDONE >>> ENTAUX
PLY
PLX
PLA
STX ROMID ; Set Current ROM number
ROMSELOK PLP
RTS
* Initialize ROMTAB according to user selection in menu
ROMINIT STZ MAXROM ; One sideways ROM only
>>> RDMAIN ; Read main mem
LDA USERSEL ; *TO DO* Should be actual number of ROMs
>>> RDAUX ; Read aux mem
CMP #6
BNE :X1
INC MAXROM
:X1 CMP #7
BNE :X2
STA MAXROM
:X2 LDA #$FF
STA ROMID ; Ensure set to invalid value
EVENT RTS
**********************************************************
* Interrupt Handlers, MOS redirection vectors etc.
**********************************************************
* Invoked from GSBRK in main memory. On IIgs only.
GSBRKAUX >>> IENTAUX ; IENTAUX does not do CLI
* Continue into IRQBRKHDLR
* TO DO: Check, IENTAUX modifies X
* IRQ/BRK handler
*****************
IRQBRKHDLR PHA
* Mustn't enable IRQs within the IRQ handler
* Do not use WRTMAIN/WRTAUX macros
PHX
CLD
TSX
LDA $103,X ; Get PSW from stack
AND #$10
BEQ :IRQ ; IRQ
SEC
LDA $0104,X
SBC #$01
STA FAULT+0 ; FAULT=>error block after BRK
LDA $0105,X
SBC #$00
STA FAULT+1
LDA ROMID ; Get current ROM
STA BYTEVARBASE+$BA ; Set ROM at last BRK
STX OSXREG ; Pass stack pointer
LDX #$06 ; Service Call 6 = BRK occured
JSR SERVICEX
LDX BYTEVARBASE+$FC ; Get current language
JSR ROMSELECT ; Bring it into memory
PLX
PLA
CLI
JMP (BRKV) ; Pass on to BRK handler
:IRQ PHY
>>> XF2MAIN,A2IRQ ; Bounce to Apple IRQ handler
IRQBRKRET
>>> IENTAUX ; IENTAUX does not do CLI
PLY
*:S4 ; TODO: Pass on to IRQ1V
PLX
PLA
NULLRTI RTI
* Default BRK handler
*********************
MOSBRKHDLR LDX #<MSGBRK
LDY #>MSGBRK
JSR OSPRSTR
JSR PRERR
* JSR OSNEWL
* JSR OSNEWL
STOP JMP STOP ; Cannot return from a BRK
MSGBRK DB $0D
ASC 'ERROR: '
DB $00
PRERR LDY #$01
PRERRLP LDA (FAULT),Y
BEQ PRERR1
JSR OSWRCH
INY
BNE PRERRLP
PRERR1
NULLRTS RTS
* Default page 2 contents
*************************
DEFVEC DW NULLRTS ; $200 USERV
DW MOSBRKHDLR ; $202 BRKV
DW NULLRTI ; $204 IRQ1V
DW NULLRTI ; $206 IRQ2V
DW CLIHND ; $208 CLIV
DW BYTEHND ; $20A BYTEV
DW WORDHND ; $20C WORDV
DW WRCHHND ; $20E WRCHV
DW RDCHHND ; $210 RDCHV
DW FILEHND ; $212 FILEV
DW ARGSHND ; $214 ARGSV
DW BGETHND ; $216 BGETV
DW BPUTHND ; $218 BPUTV
DW GBPBHND ; $21A GBPBV
DW FINDHND ; $21C FINDV
DW FSCHND ; $21E FSCV
DW NULLRTS ; $220 EVENTV
DW NULLRTS ; $222
DW NULLRTS ; $224
DW NULLRTS ; $226
DW NULLRTS ; $228
DW NULLRTS ; $22A
DW NULLRTS ; $22C
DW NULLRTS ; $22E
DW NULLRTS ; $230 SPARE1V
DW NULLRTS ; $232 SPARE2V
DW NULLRTS ; $234 SPARE3V
ENDVEC
*
* Acorn MOS entry points at the top of RAM
* Copied from loaded code to high memory
*
* Base of API entries here in loaded code
MOSVEC
* Real base of API entries in real memory
MOSAPI EQU $FF95
ORG MOSAPI
* OPTIONAL ENTRIES
* ----------------
OSSERV JMP SERVICEX ; FF95 OSSERV
OSCOLD JMP NULLRTS ; FF98 OSCOLD
OSPRSTR JMP OUTSTR ; FF9B OSPRSTR
OSSCANDEC JMP SCANDEC ; FF9E SCANDEC
OSSCANHEX JMP SCANHEX ; FFA1 SCANHEX
OSFFA4 JMP NULLRTS ; FFA4 (DISKACC)
OSFFA7 JMP NULLRTS ; FFA7 (DISKCCP)
PRHEX
PR1HEX JMP OUTHEX ; FFAA PRHEX
PR2HEX JMP OUT2HEX ; FFAD PR2HEX
OSFFB0 JMP PRINTDEC ; FFB0 (USERINT)
OSWRRM JMP NULLRTS ; FFB3 OSWRRM
* COMPULSARY ENTRIES
* ------------------
VECSIZE DB ENDVEC-DEFVEC ; FFB6 VECSIZE Size of vectors
VECBASE DW DEFVEC ; FFB7 VECBASE Base of default vectors
OSRDRM JMP RDROM ; FFB9 OSRDRM Read byte from paged ROM
OSCHROUT JMP OUTCHAR ; FFBC CHROUT Send char to VDU driver
OSEVEN JMP EVENT ; FFBF OSEVEN Signal an event
GSINIT JMP GSINTGO ; FFC2 GSINIT Init string reading
GSREAD JMP GSRDGO ; FFC5 GSREAD Parse general string
NVWRCH JMP WRCHHND ; FFC8 NVWRCH Nonvectored WRCH
NVRDCH JMP RDCHHND ; FFCB NVRDCH Nonvectored RDCH
OSFIND JMP (FINDV) ; FFCE OSFIND
OSGBPB JMP (GBPBV) ; FFD1 OSGBPB
OSBPUT JMP (BPUTV) ; FFD4 OSBPUT
OSBGET JMP (BGETV) ; FFD7 OSBGET
OSARGS JMP (ARGSV) ; FFDA OSARGS
OSFILE JMP (FILEV) ; FFDD OSFILE
OSRDCH JMP (RDCHV) ; FFE0 OSRDCH
OSASCI CMP #$0D ; FFE3 OSASCI
BNE OSWRCH
OSNEWL LDA #$0A ; FFE7 OSNEWL
JSR OSWRCH
OSWRCR LDA #$0D ; FFEC OSWRCR
OSWRCH JMP (WRCHV) ; FFEE OSWRCH
OSWORD JMP (WORDV) ; FFF1 OSWORD
OSBYTE JMP (BYTEV) ; FFF4 OSBYTE
OSCLI JMP (CLIV) ; FFF7 OSCLI
NMIVEC DW NULLRTI ; FFFA NMIVEC
RSTVEC DW STOP ; FFFC RSTVEC
IRQVEC
* Assembler doesn't like running up to $FFFF, so we bodge a bit
MOSEND
ORG MOSEND-MOSAPI+MOSVEC
DW IRQBRKHDLR ; FFFE IRQVEC
MOSVEND
* ASC '**ENDOFCODE**'