mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-25 18:33:11 +00:00
12416 lines
435 KiB
Plaintext
12416 lines
435 KiB
Plaintext
mads 2.1.0
|
|
Source: source/main.xasm
|
|
1 ; Altirra - Atari 800/800XL emulator
|
|
2 ; Kernel ROM replacement
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11
|
|
12 .if _KERNEL_XLXE
|
|
13 = 0001 _KERNEL_PBI_SUPPORT = 1
|
|
14 = 0001 _KERNEL_USE_BOOT_SCREEN = 1
|
|
15 .macro _KERNELSTR_BIOS_NAME_INTERNAL
|
|
16 .ifdef _KERNEL_816
|
|
17 dta d" for 65C816"
|
|
18 .else
|
|
19 dta d" for XL/XE/XEGS"
|
|
20 .endif
|
|
21 .endm
|
|
22 .else
|
|
23 _KERNEL_PBI_SUPPORT = 0
|
|
24 _KERNEL_USE_BOOT_SCREEN = 0
|
|
25 .endif
|
|
26
|
|
27 = 0001 _KERNEL_PRINTER_SUPPORT = 1
|
|
28
|
|
29 ;==========================================================================
|
|
30
|
|
31 icl 'version.inc'
|
|
Source: source/Shared/version.inc
|
|
1 ; Altirra - Atari 800/800XL emulator
|
|
2 ; Kernel ROM replacement - version info
|
|
3 ; Copyright (C) 2008-2020 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 .macro _KERNELSTR_VERSION
|
|
11 dta '3.26'
|
|
12 .endm
|
|
13
|
|
14 .macro _KERNELSTR_VERSION_INTERNAL
|
|
15 dta "3.26"
|
|
16 .endm
|
|
32 icl 'hardware.inc'
|
|
Source: source/Shared/hardware.inc
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Hardware register definitions
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 .ifndef f_HARDWARE_INC
|
|
11 .def f_HARDWARE_INC
|
|
12
|
|
13 ;==========================================================================
|
|
14 ; GTIA
|
|
15 ;
|
|
16 m0pf equ $d000
|
|
17 m1pf equ $d001
|
|
18 m2pf equ $d002
|
|
19 m3pf equ $d003
|
|
20 p0pf equ $d004
|
|
21 p1pf equ $d005
|
|
22 p2pf equ $d006
|
|
23 p3pf equ $d007
|
|
24 m0pl equ $d008
|
|
25 m1pl equ $d009
|
|
26 m2pl equ $d00a
|
|
27 m3pl equ $d00b
|
|
28 p0pl equ $d00c
|
|
29 p1pl equ $d00d
|
|
30 p2pl equ $d00e
|
|
31 p3pl equ $d00f
|
|
32
|
|
33 hposp0 equ $d000
|
|
34 hposp1 equ $d001
|
|
35 hposp2 equ $d002
|
|
36 hposp3 equ $d003
|
|
37 hposm0 equ $d004
|
|
38 hposm1 equ $d005
|
|
39 hposm2 equ $d006
|
|
40 hposm3 equ $d007
|
|
41 sizep0 equ $d008
|
|
42 sizep1 equ $d009
|
|
43 sizep2 equ $d00a
|
|
44 sizep3 equ $d00b
|
|
45 sizem equ $d00c
|
|
46 grafp0 equ $d00d
|
|
47 grafp1 equ $d00e
|
|
48 grafp2 equ $d00f
|
|
49 grafp3 equ $d010
|
|
50 grafm equ $d011
|
|
51 trig0 equ $d010
|
|
52 trig1 equ $d011
|
|
53 trig2 equ $d012
|
|
54 colpm0 equ $d012
|
|
55 trig3 equ $d013
|
|
56 colpm1 equ $d013
|
|
57 pal equ $d014
|
|
58 colpm2 equ $d014
|
|
59 colpm3 equ $d015
|
|
60 colpf0 equ $d016
|
|
61 colpf1 equ $d017
|
|
62 colpf2 equ $d018
|
|
63 colpf3 equ $d019
|
|
64 colbk equ $d01a
|
|
65 prior equ $d01b
|
|
66 vdelay equ $d01c
|
|
67 gractl equ $d01d
|
|
68 hitclr equ $d01e
|
|
69 consol equ $d01f
|
|
70
|
|
71 ;==========================================================================
|
|
72 ; POKEY
|
|
73 ;
|
|
74 pot0 equ $d200
|
|
75 audf1 equ $d200
|
|
76 pot1 equ $d201
|
|
77 audc1 equ $d201
|
|
78 pot2 equ $d202
|
|
79 audf2 equ $d202
|
|
80 pot3 equ $d203
|
|
81 audc2 equ $d203
|
|
82 pot4 equ $d204
|
|
83 audf3 equ $d204
|
|
84 pot5 equ $d205
|
|
85 audc3 equ $d205
|
|
86 pot6 equ $d206
|
|
87 audf4 equ $d206
|
|
88 pot7 equ $d207
|
|
89 audc4 equ $d207
|
|
90 audctl equ $d208
|
|
91 kbcode equ $d209
|
|
92 skres equ $d20a
|
|
93 potgo equ $d20b
|
|
94 serin equ $d20d
|
|
95 serout equ $d20d
|
|
96 irqen equ $d20e
|
|
97 irqst equ $d20e
|
|
98 skctl equ $d20f
|
|
99 skstat equ $d20f
|
|
100
|
|
101 ;==========================================================================
|
|
102 ; PIA
|
|
103 ;
|
|
104 porta equ $d300
|
|
105 portb equ $d301
|
|
106 pactl equ $d302
|
|
107 pbctl equ $d303
|
|
108
|
|
109 ;==========================================================================
|
|
110 ; ANTIC
|
|
111 ;
|
|
112 dmactl equ $d400
|
|
113 chactl equ $d401
|
|
114 dlistl equ $d402
|
|
115 dlisth equ $d403
|
|
116 hscrol equ $d404
|
|
117 vscrol equ $d405
|
|
118 pmbase equ $d407
|
|
119 chbase equ $d409
|
|
120 wsync equ $d40a
|
|
121 vcount equ $d40b
|
|
122 penh equ $d40c
|
|
123 penv equ $d40d
|
|
124 nmien equ $d40e
|
|
125 nmist equ $d40f
|
|
126 nmires equ $d40f
|
|
127
|
|
128 ;==========================================================================
|
|
129 ; 6502
|
|
130 ;
|
|
131 nmivec equ $fffa
|
|
132 resvec equ $fffc
|
|
133 irqvec equ $fffe
|
|
134
|
|
135 .endif
|
|
33 icl 'kerneldb.inc'
|
|
Source: source/Shared/kerneldb.inc
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Kernel Database Definitions
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 .ifndef f_KERNELDB_INC
|
|
11 .def f_KERNELDB_INC
|
|
12
|
|
13 casini = $0002 ;cassette initialization vector
|
|
14 ramlo = $0004 ;
|
|
15 tramsz = $0006 ;temporary ram size / cart A flag
|
|
16 tstdat = $0007 ;RAM test data register / cart B flag
|
|
17 ;(also CMCMD for T:)
|
|
18 warmst = $0008 ;warmstart flag
|
|
19 boot? = $0009 ;boot flag; 0 if none, 1 for disk, 2 for cassette
|
|
20 dosvec = $000a
|
|
21 dosini = $000c
|
|
22 appmhi = $000e
|
|
23 pokmsk = $0010
|
|
24 brkkey = $0011 ;set on [BREAK]
|
|
25 rtclok = $0012
|
|
26 bufadr = $0015 ;indirect buffer address pointer (temp for disk buffer)
|
|
27 ; $0016
|
|
28 iccomt = $0017 ;CIO: command byte
|
|
29 ziocb = $0020 ;zero-page IOCB
|
|
30 ichidz = $0020 ;Zero page IOCB: device index ($FF = not open)
|
|
31 icdnoz = $0021 ;Zero page IOCB: device number
|
|
32 iccomz = $0022 ;Zero page IOCB: command byte
|
|
33 icstaz = $0023 ;Zero page IOCB: status byte
|
|
34 icbalz = $0024 ;Zero page IOCB: address of device/filename spec lo
|
|
35 icbahz = $0025 ;Zero page IOCB: address of device/filename spec hi
|
|
36 icptlz = $0026 ;Zero page IOCB: put byte address lo (-1)
|
|
37 icpthz = $0027 ;Zero page IOCB: put byte address hi (-1)
|
|
38 icbllz = $0028 ;Zero page IOCB: buffer length/byte count lo (-1)
|
|
39 icblhz = $0029 ;Zero page IOCB: buffer length/byte count hi (-1)
|
|
40 icax1z = $002a ;Zero page IOCB: device-specific information 1
|
|
41 icax2z = $002b ;Zero page IOCB: device-specific information 2
|
|
42 icax3z = $002c ;Zero page IOCB: device-specific information 3
|
|
43 icax4z = $002d ;Zero page IOCB: device-specific information 4
|
|
44 icax5z = $002e ;Zero page IOCB: device-specific information 5
|
|
45 icidno = $002e ;CIO: call X register save/restore
|
|
46 icax6z = $002f ;Zero page IOCB: device-specific information 6
|
|
47 ciochr = $002f ;CIO: call A register save/restore
|
|
48 status = $0030 ;SIO: temporay status byte
|
|
49 chksum = $0031 ;SIO: temporary checksum byte (used by IRQ routines)
|
|
50 bufrlo = $0032 ;SIO: buffer pointer lo (incremented by IRQ routines)
|
|
51 bufrhi = $0033 ;SIO: buffer pointer hi (incremented by IRQ routines)
|
|
52 bfenlo = $0034 ;SIO: buffer end lo
|
|
53 bfenhi = $0035 ;SIO: buffer end hi
|
|
54 ltemp = $0036 ;Relocating loader: loader temp address (XL/XE)
|
|
55 ; $0037
|
|
56 bufrfl = $0038 ;SIO: buffer full flag
|
|
57 recvdn = $0039 ;SIO: receive completed flag
|
|
58 xmtdon = $003a ;SIO: transmit completed flag
|
|
59 chksnt = $003b ;SIO: checksum sent flag
|
|
60 nocksm = $003c ;SIO: no-checksum flag
|
|
61 bptr = $003d ;Cassette: Buffer pointer
|
|
62 ftype = $003e ;Cassette: Interrecord gap (IRG) type; bit7=1 means continuous mode
|
|
63 feof = $003f ;Cassette: EOF flag
|
|
64 soundr = $0041 ;SIO: noisy audio flag
|
|
65 critic = $0042 ;critical flag for vbi
|
|
66 zchain = $004a ;Peripheral Handler: zero-page chain address
|
|
67 ; $004b
|
|
68 atract = $004d ;screen attract counter
|
|
69 drkmsk = $004e ;screen attract mask
|
|
70 colrsh = $004f ;screen attract color shift
|
|
71 tmpchr = $0050 ;Screen Editor
|
|
72 hold1 = $0051 ;Display/Editor: temporary storage
|
|
73 lmargn = $0052 ;left margin column
|
|
74 rmargn = $0053 ;right margin column
|
|
75 rowcrs = $0054 ;cursor row
|
|
76 colcrs = $0055 ;cursor column
|
|
77 ; $0056
|
|
78 dindex = $0057 ;display mode index
|
|
79 savmsc = $0058 ;lowest address of screen region
|
|
80 oldrow = $005a ;
|
|
81 oldcol = $005b ;
|
|
82 oldchr = $005d ;cursor character save/restore
|
|
83 oldadr = $005e ;cursor memory address
|
|
84 ; $005f
|
|
85 palnts = $0062 ;PAL/NTSC flag
|
|
86 logcol = $0063 ;Display/Editor: Logical column (0-119)
|
|
87 adress = $0064 ;temporary storage (display code)
|
|
88 ; $0065
|
|
89 toadr = $0066 ;temporary storage (display code)
|
|
90 a1 = toadr
|
|
91 ; $0067
|
|
92 frmadr = $0068 ;temporary storage (display code)
|
|
93 ; $0069
|
|
94 ramtop = $006a ;ram size
|
|
95 bufcnt = $006b
|
|
96 bufstr = $006c ;row/column of start of logical line
|
|
97 bitmsk = $006e ;Screen Editor
|
|
98 shfamt = $006f ;Screen Editor
|
|
99 rowac = $0070 ;Screen Editor: line drawing
|
|
100 ; $0071 ;
|
|
101 colac = $0072 ;Screen Editor: line drawing
|
|
102 ; $0073 ;
|
|
103 endpt = $0074 ;Screen Editor: line drawing
|
|
104 ; $0075 ;
|
|
105 deltar = $0076 ;Screen Editor: delta row (line drawing)
|
|
106 deltac = $0077 ;Screen Editor: delta column (line drawing)
|
|
107 ; $0078 ;
|
|
108 keydef = $0079 ;XL/XE: Keyboard definition table
|
|
109 ; $007a
|
|
110 swpflg = $007b ;current display var state ($00 = main, $FF = split screen)
|
|
111 holdch = $007c ;temporary key hold area prior to shift/control lock logic
|
|
112 countr = $007e ;Screen Editor: line length
|
|
113 ; $007f
|
|
114 fr0 = $00d4 ;FP: Accumulator 0
|
|
115 _fr3 = $00da ;FP: Accumulator 3 (officially FRE)
|
|
116 fr1 = $00e0 ;FP: Accumulator 1
|
|
117 fr2 = $00e6 ;FP: Accumulator 2
|
|
118 _fpcocnt= $00ec ;FP: temporary storage - polynomial coefficient counter
|
|
119 _fptemp0= $00ed ;FP: temporary storage - transcendental temporary (officially EEXP)
|
|
120 _fptemp1= $00ee ;FP: temporary storage - transcendental temporary (officially NSIGN)
|
|
121 ;esign $00ef ;BASIC: Used in sqr() routine -- must not be touched by FP elementary functions
|
|
122 ;fchrflg $00f0 ;BASIC: Used in sin() routine -- must not be touched by any FP functions
|
|
123 cix = $00f2 ;FP: Character index
|
|
124 inbuff = $00f3 ;FP: ASCII conversion buffer
|
|
125 ; $00f4
|
|
126 ; $00f5 ;FP: temporary storage -- also temporarily used by BASIC power routine
|
|
127 ; $00f6 ;FP: temporary storage
|
|
128 ztemp4 = $00f7 ;FP: temporary storage -- also temporarily used by BASIC power routine
|
|
129 ; $00f8 ;FP: temporary storage
|
|
130 ; $00f9 ;FP: temporary storage
|
|
131 ; $00fa ;FP: temporary storage
|
|
132 degflg = $00fb ;FP: degree/radian flag (0=radians, 6=degrees)
|
|
133 flptr = $00fc ;FP: pointer for floating-point loads and stores
|
|
134 fptr2 = $00fe ;FP: pointer for polynomial evaluation
|
|
135
|
|
136 vdslst = $0200 ;display list interrupt vector
|
|
137 vprced = $0202 ;serial bus proceed interrupt vector
|
|
138 vinter = $0204 ;serial bus interrupt vector
|
|
139 vbreak = $0206 ;BRK instruction vector
|
|
140 vkeybd = $0208 ;keyboard interrupt vector
|
|
141 vserin = $020a ;serial input ready interrupt vector
|
|
142 vseror = $020c ;serial output ready interrupt vector
|
|
143 vseroc = $020e ;serial output completed interrupt vector
|
|
144 vtimr1 = $0210 ;pokey timer 1 interrupt vector
|
|
145 vtimr2 = $0212 ;pokey timer 2 interrupt vector
|
|
146 vtimr4 = $0214 ;pokey timer 4 interrupt vector
|
|
147 vimirq = $0216 ;immediate IRQ vector
|
|
148 cdtmv1 = $0218 ;countdown timer 1
|
|
149 cdtmv2 = $021a ;countdown timer 2
|
|
150 cdtmv3 = $021c ;countdown timer 3
|
|
151 cdtmv4 = $021e ;countdown timer 4
|
|
152 cdtmv5 = $0220 ;countdown timer 5
|
|
153 vvblki = $0222 ;vertical blank immediate vector
|
|
154 vvblkd = $0224 ;vertical blank deferred vector
|
|
155 cdtma1 = $0226 ;timer 1 vector
|
|
156 cdtma2 = $0228 ;timer 2 vector
|
|
157 cdtmf3 = $022a ;timer 3 flag
|
|
158 srtimr = $022b ;autorepeat timer
|
|
159 cdtmf4 = $022c ;timer 4 flag
|
|
160 intemp = $022d ;temp value used by SETVBV
|
|
161 cdtmf5 = $022e ;timer 5 flag
|
|
162 sdmctl = $022f ;shadow for DMACTL ($D400)
|
|
163 sdlstl = $0230 ;shadow for DLISTL ($D402)
|
|
164 sdlsth = $0231 ;shadow for DLISTH ($D403)
|
|
165 sskctl = $0232 ;shadow for SKCTL ($D20F)
|
|
166 lcount = $0233 ;Relocating loader: (XL/XE)
|
|
167 lpenh = $0234 ;light pen horizontal pos
|
|
168 lpenv = $0235 ;light pen vertical pos
|
|
169 brkky = $0236 ;break key interrupt vector (OS B+ only)
|
|
170 vpirq = $0238 ;PBI device interrupt vector (XL/XE)
|
|
171 ; $0239
|
|
172 cdevic = $023a ;SIO: command frame device ID
|
|
173 ccomnd = $023b ;SIO: command frame command ID
|
|
174 caux1 = $023c ;SIO: command aux byte 1
|
|
175 caux2 = $023d ;SIO: command aux byte 2
|
|
176 temp = $023e ;SIO: temp space
|
|
177 errflg = $023f ;SIO: error flag
|
|
178 dflags = $0240 ;disk boot flags
|
|
179 dbsect = $0241 ;disk boot sector count
|
|
180 bootad = $0242 ;disk boot address
|
|
181 coldst = $0244 ;cold start flag
|
|
182 reclen = $0245 ;Relocating loader: record length (XL/XE)
|
|
183 dsktim = $0246 ;Disk Handler: Disk operation timeout
|
|
184 pdvmsk = $0247 ;PBI device mask (XL/XE)
|
|
185 shpdvs = $0248 ;PBI device selection register shadow ($D1FF) (XL/XE)
|
|
186 pdmsk = $0249 ;PBI device interrupt mask (XL/XE)
|
|
187 reladr = $024a ;Relocating loader: temp address (XL/XE)
|
|
188 ; $024b
|
|
189
|
|
190 .if _KERNEL_816
|
|
191 vabte = $024f ;(816) Emulation ABORT vector
|
|
192 ; $0250
|
|
193 vcope = $0251 ;(816) Emulation COP vector
|
|
194 ; $0252
|
|
195 vabtn = $0253 ;(816) Native ABORT vector
|
|
196 ; $0254
|
|
197 ; $0255
|
|
198 vcopn = $0256 ;(816) Native COP vector
|
|
199 ; $0257
|
|
200 ; $0258
|
|
201 vnmin = $0259 ;(816) Native NMI vector
|
|
202 ; $025a
|
|
203 ; $025b
|
|
204 virqn = $025c ;(816) Native IRQ vector
|
|
205 ; $025d
|
|
206 ; $025e
|
|
207 vbrkn = $025f ;(816) Native BREAK vector
|
|
208 ; $0260
|
|
209 ; $0261
|
|
210 vcop0 = $0262 ;(816) Native COP #0 vector
|
|
211 ; $0263
|
|
212 ; $0264
|
|
213 vcopu = $0265 ;(816) Native COP #1-127 vector
|
|
214 ; $0266
|
|
215 ; $0267
|
|
216 vcopc = $0268 ;(816) Native COP #128-255 vector
|
|
217 ; $0269
|
|
218 ; $026a
|
|
219 .endif
|
|
220
|
|
221 fine = $026e ;fine scrolling flag (XL/XE)
|
|
222 gprior = $026f ;shadow for PRIOR ($D01B)
|
|
223 paddl0 = $0270 ;shadow for POT0 ($D200)
|
|
224 paddl1 = $0271 ;shadow for POT1 ($D201)
|
|
225 paddl2 = $0272 ;shadow for POT2 ($D202)
|
|
226 paddl3 = $0273 ;shadow for POT3 ($D203)
|
|
227 paddl4 = $0274 ;shadow for POT4 ($D204)
|
|
228 paddl5 = $0275 ;shadow for POT5 ($D205)
|
|
229 paddl6 = $0276 ;shadow for POT6 ($D206)
|
|
230 paddl7 = $0277 ;shadow for POT7 ($D207)
|
|
231 stick0 = $0278 ;shadow for PORTA lo ($D300)
|
|
232 stick1 = $0279 ;shadow for PORTA hi ($D300)
|
|
233 stick2 = $027A ;shadow for PORTB lo ($D302)
|
|
234 stick3 = $027B ;shadow for PORTB hih ($D302)
|
|
235 ptrig0 = $027c ;paddle trigger 0
|
|
236 ptrig1 = $027d ;paddle trigger 1
|
|
237 ptrig2 = $027e ;paddle trigger 2
|
|
238 ptrig3 = $027f ;paddle trigger 3
|
|
239 ptrig4 = $0280 ;paddle trigger 4
|
|
240 ptrig5 = $0281 ;paddle trigger 5
|
|
241 ptrig6 = $0282 ;paddle trigger 6
|
|
242 ptrig7 = $0283 ;paddle trigger 7
|
|
243 strig0 = $0284 ;shadow for TRIG0 ($D001)
|
|
244 strig1 = $0285 ;shadow for TRIG1 ($D002)
|
|
245 strig2 = $0286 ;shadow for TRIG2 ($D003)
|
|
246 strig3 = $0287 ;shadow for TRIG3 ($D004)
|
|
247 hibyte = $0288 ;Relocating loader (XL/XE)
|
|
248 wmode = $0289 ;Cassette: Write mode (00 = read, 80 = write)
|
|
249 blim = $028a ;Cassette: Buffer limit
|
|
250 jveck = $028c ;XL/XE: IRQ jump vector
|
|
251 newadr = $028e ;Relocating loader (XL/XE)
|
|
252 txtrow = $0290
|
|
253 txtcol = $0291
|
|
254 ; $0292
|
|
255 tindex = $0293 ;text mode index
|
|
256 txtmsc = $0294 ;text window pointer
|
|
257 ; $0295
|
|
258 cretry = $029c ;SIO: command retries (XL/XE)
|
|
259 hold3 = $029d ;Screen Editor
|
|
260 hold2 = $029f ;Screen Editor
|
|
261 dmask = $02a0 ;Display/Editor: Graphics merge mask
|
|
262 tmplbt = $02a1
|
|
263 escflg = $02a2 ;Display/Editor: Escape next character
|
|
264 tabmap = $02a3 ;Display/Editor: Bitfield indicating tabs (note reversed bit positions)
|
|
265 logmap = $02b2 ;Display/Editor: Logical line start map (4 bytes)
|
|
266 invflg = $02b6 ;Keyboard Handler: inverse flag ($00/$80)
|
|
267 tmprow = $02b8 ;Screen Editor
|
|
268 tmpcol = $02b9 ;Screen Editor
|
|
269 ; $02ba
|
|
270 scrflg = $02bb ;Display/Editor: Scroll counter
|
|
271 hold4 = $02bc ;Screen Editor
|
|
272 dretry = $02bd ;SIO: device retries (XL/XE)
|
|
273 shflok = $02be ;shift/control lock flags
|
|
274 botscr = $02bf ;number of text rows in text window
|
|
275 pcolr0 = $02c0 ;shadow for COLPM0 ($D012)
|
|
276 pcolr1 = $02c1 ;shadow for COLPM1 ($D013)
|
|
277 pcolr2 = $02c2 ;shadow for COLPM2 ($D014)
|
|
278 pcolr3 = $02c3 ;shadow for COLPM3 ($D015)
|
|
279 color0 = $02c4 ;shadow for COLPF0 ($D016)
|
|
280 color1 = $02c5 ;shadow for COLPF1 ($D017)
|
|
281 color2 = $02c6 ;shadow for COLPF2 ($D018)
|
|
282 color3 = $02c7 ;shadow for COLPF3 ($D019)
|
|
283 color4 = $02c8 ;shadow for COLBK ($D01A)
|
|
284 runadr = $02c9 ;Relocating loader: run address (XL/XE)
|
|
285 ; $02ca
|
|
286 hiused = $02cb ;Relocating loader: Next available memory location (out) (XL/XE)
|
|
287 ; $02cc
|
|
288 zhiuse = $02cd ;Relocating loader: Next available zero-page address (out) (XL/XE)
|
|
289 ; $02ce
|
|
290 gbytea = $02cf ;Relocating loader: GET BYTE address (XL/XE)
|
|
291 ; $02d0
|
|
292 loadad = $02d1 ;Relocating loader: Load address (XL/XE)
|
|
293 ; $02d2
|
|
294 zloada = $02d3 ;Relocating loader: Zero-page load address (XL/XE)
|
|
295 ; $02d4
|
|
296 dsctln = $02d5 ;Disk sector size (XL/XE)
|
|
297 krpdel = $02d9 ;Keyboard repeat delay (XL/XE)
|
|
298 keyrep = $02da ;Keyboard repeat rate (XL/XE)
|
|
299 helpfg = $02dc ;Help flag (XL/XE)
|
|
300 pbpnt = $02de ;Printer: Buffer index (XL/XE location)
|
|
301 pbufsz = $02df ;Printer: Record size (XL/XE location)
|
|
302 ramsiz = $02e4 ;ram size in pages
|
|
303 memtop = $02e5 ;highest location for programs and data
|
|
304 memlo = $02e7 ;base of application memory
|
|
305 hndlod = $02e9 ;CIO: Handler load flag (XL/XE)
|
|
306 dvstat = $02ea ;DISK: Status request buffer area (4 bytes)
|
|
307 ; $02eb
|
|
308 ; $02ec
|
|
309 ; $02ed
|
|
310 cbaudl = $02ee ;Cassette baud rate as POKEY divisor. Set to nominal ($05CC) by C: init.
|
|
311 cbaudh = $02ef ;
|
|
312 crsinh = $02f0 ;Display/Editor: cursor inhibit flag
|
|
313 keydel = $02f1 ;keyboard debounce delay (set to 3 vblanks per key)
|
|
314 ch1 = $02f2 ;last keyboard code read
|
|
315 chact = $02f3 ;shadow for CHACTL ($D401)
|
|
316 chbas = $02f4 ;shadow for CHBASE ($D409)
|
|
317 rowinc = $02f8 ;Screen Editor: row direction (XL/XE location)
|
|
318 colinc = $02f9 ;Screen Editor: col direction (XL/XE location)
|
|
319 atachr = $02fb ;Screen Editor
|
|
320 ch = $02fc ;keyboard FIFO byte
|
|
321 fildat = $02fd ;Screen Editor: fill color
|
|
322 dspflg = $02fe ;enable/disable of control codes by screen editor (E:)
|
|
323 ssflag = $02ff ;display/screen editor suspend flag
|
|
324 ddevic = $0300 ;serial bus ID
|
|
325 dunit = $0301 ;device number
|
|
326 dcomnd = $0302 ;command byte
|
|
327 dstats = $0303 ;status byte
|
|
328 dbuflo = $0304 ;buffer address lo
|
|
329 dbufhi = $0305 ;buffer address hi
|
|
330 dtimlo = $0306 ;disk timeout value
|
|
331 dbytlo = $0308 ;byte count lo
|
|
332 dbythi = $0309 ;byte count hi
|
|
333 daux1 = $030a ;sector number lo
|
|
334 daux2 = $030b ;sector number hi
|
|
335 timer1 = $030c ;SIO: baud rate determination - first timer value
|
|
336 addcor = $030e ;SIO: baud rate determination - correction value
|
|
337 casflg = $030f ;SIO: cassette I/O flag (0=normal, nonzero=cassette)
|
|
338 timer2 = $0310 ;SIO: baud rate determination - second timer value
|
|
339 temp1 = $0312 ;SIO: baud rate determination - temp
|
|
340 ; $0313
|
|
341 ptimot = $0314 ;Printer: Timeout (XL/XE location)
|
|
342 temp3 = $0315 ;SIO: baud rate determination - temp
|
|
343 timflg = $0317 ;SIO: operation timeout flag (set by countdown timer 1 IRQ)
|
|
344 stackp = $0318 ;SIO: stack pointer save
|
|
345 hatabs = $031a ;handler table
|
|
346 pupbt1 = $033d ;(XL/XE) Power-up boot flag #1 - $5C
|
|
347 pupbt2 = $033e ;(XL/XE) Power-up boot flag #2 - $93
|
|
348 pupbt3 = $033f ;(XL/XE) Power-up boot flag #3 - $25
|
|
349 ichid = $0340 ;IOCB #0 handler ID
|
|
350 icdno = $0341 ;IOCB #0 device number
|
|
351 iccmd = $0342 ;IOCB #0 command byte
|
|
352 icsta = $0343 ;IOCB #0 status
|
|
353 icbal = $0344 ;IOCB #0 buffer address lo
|
|
354 icbah = $0345 ;IOCB #0 buffer address hi
|
|
355 icptl = $0346 ;IOCB #0 PUT address lo
|
|
356 icpth = $0347 ;IOCB #0 PUT address hi
|
|
357 icbll = $0348 ;IOCB #0 buffer length/byte count lo
|
|
358 icblh = $0349 ;IOCB #0 buffer length/byte count hi
|
|
359 icax1 = $034a ;IOCB #0 auxiliary information lo
|
|
360 icax2 = $034b ;IOCB #0 auxiliary information hi
|
|
361 icax3 = $034c ;
|
|
362 icax4 = $034d ;
|
|
363 icax5 = $034e ;
|
|
364 icax6 = $034f ;
|
|
365 prnbuf = $03c0 ;printer buffer
|
|
366 ckey = $03e9 ;cassette boot key
|
|
367 basicf = $03f8 ;XL/XE: ROM BASIC flag. 0 = enabled
|
|
368 gintlk = $03fa ;XL/XE: Cartridge interlock (clone of TRIG3).
|
|
369 chlink = $03fb ;XL/XE: Relocated loader chain
|
|
370 casbuf = $03fd ;Cassette buffer (03FD-047F)
|
|
371 lbuff = $0580 ;
|
|
372 plyarg = $05e0 ;FP: Polynomial evaluation temp register
|
|
373 fpscr = $05e6 ;FP: Temp evaluation register (used by LOG/LOG10)
|
|
374
|
|
375 .endif
|
|
34
|
|
35 opt h-o+f+
|
|
36
|
|
37 .ifdef _KERNEL_816
|
|
38 opt c+
|
|
39 .endif
|
|
40
|
|
41 .if _KERNEL_XLXE
|
|
42 org $c000
|
|
43
|
|
44 ;==============================================================================
|
|
45 ; lower ROM identification block (XL/XE)
|
|
46 ;==============================================================================
|
|
47
|
|
48 C000 00 00 dta a(0)
|
|
49 C002 01 01 13 dta $01,$01,$13
|
|
50 C005 02 dta $02
|
|
51 C006 43 58 00 00 00 dta 'CX',$00,$00,$00
|
|
52 C00B 00 dta $00
|
|
53
|
|
54 C00C _KERNEL_REPORT_MODULE_MARK
|
|
Macro: _KERNEL_REPORT_MODULE_MARK [Source: source/main.xasm]
|
|
1 = C00C .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
55
|
|
56 .ifdef _KERNEL_816
|
|
57 icl 'vbi816.s'
|
|
58 .else
|
|
59 C00C icl 'vbi.s'
|
|
Source: source/Shared/vbi.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Vertical Blank Interrupt Services
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11 ; VBIExit - Vertical Blank Interrupt Exit Routine
|
|
12 ;
|
|
13 ; This is a drop-in replacement for XITVBV.
|
|
14 ;
|
|
15 = C050 VBIExit = VBIProcess.xit
|
|
16
|
|
17 ;==========================================================================
|
|
18 ; VBIProcess - Vertical Blank Processor
|
|
19 ;
|
|
20 = C00C VBIStage1 = VBIProcess.stage_1
|
|
21 = C061 VBIStage2 = VBIProcess.stage_2
|
|
22 C00C .proc VBIProcess
|
|
23 C00C stage_1:
|
|
24 ;increment real-time clock and do attract processing
|
|
25 C00C E6 14 inc rtclok+2
|
|
26 C00E D0 08 bne clock_done
|
|
27 C010 E6 4D inc atract
|
|
28 C012 E6 13 inc rtclok+1
|
|
29 C014 D0 02 bne clock_done
|
|
30 C016 E6 12 inc rtclok
|
|
31 C018 clock_done:
|
|
32
|
|
33 ;Pole Position depends on DRKMSK and COLRSH being reset from VBI as it
|
|
34 ;clears kernel vars after startup.
|
|
35 C018 A2 FE ldx #$fe ;default to no mask
|
|
36 C01A A9 00 lda #$00 ;default to no color alteration
|
|
37 C01C A4 4D ldy atract ;check attract counter
|
|
38 C01E 10 06 bpl attract_off ;skip if attract is off
|
|
39 C020 86 4D stx atract ;lock the attract counter
|
|
40 C022 A2 F6 ldx #$f6 ;set mask to dim colors
|
|
41 C024 A5 13 lda rtclok+1 ;use clock to randomize colors
|
|
42 C026 attract_off:
|
|
43 C026 86 4E stx drkmsk ;set color mask
|
|
44 C028 85 4F sta colrsh ;set color modifier
|
|
45
|
|
46 ;atract color 1 only
|
|
47 C02A 4D C5 02 eor color1
|
|
48 C02D 25 4E and drkmsk
|
|
49 C02F 8D 17 D0 sta colpf1
|
|
50
|
|
51 ;decrement timer 1 and check for underflow
|
|
52 C032 AD 18 02 lda cdtmv1 ;check low byte
|
|
53 C035 D0 08 bne timer1_lobytezero ;if non-zero, decrement and check for fire
|
|
54 C037 AD 19 02 lda cdtmv1+1 ;check high byte
|
|
55 C03A F0 10 beq timer1_done ;if clear, timer's not running
|
|
56 C03C CE 19 02 dec cdtmv1+1 ;decrement high byte
|
|
57 C03F timer1_lobytezero:
|
|
58 C03F CE 18 02 dec cdtmv1 ;decrement low byte
|
|
59 C042 D0 08 bne timer1_done ;no underflow if non-zero
|
|
60 C044 AD 19 02 lda cdtmv1+1 ;low byte is zero... check if high byte is too
|
|
61 C047 D0 03 bne timer1_done ;if it's not, we're not done yet ($xx00 > 0)
|
|
62 C049 20 56 C0 jsr timer1_dispatch ;jump through timer vector
|
|
63 C04C timer1_done:
|
|
64
|
|
65 ;check for critical operation
|
|
66 C04C A5 42 lda critic
|
|
67 C04E F0 09 beq no_critic
|
|
68 C050 xit:
|
|
69 C050 68 pla
|
|
70 C051 A8 tay
|
|
71 C052 68 pla
|
|
72 C053 AA tax
|
|
73 C054 exit_a:
|
|
74 C054 68 pla
|
|
75 C055 exit_none:
|
|
76 C055 40 rti
|
|
77
|
|
78 C056 timer1_dispatch:
|
|
79 C056 6C 26 02 jmp (cdtma1)
|
|
80
|
|
81 C059 no_critic:
|
|
82 C059 A9 04 lda #$04 ;I flag
|
|
83 C05B BA tsx
|
|
84 C05C 3D 04 01 and $0104,x ;I flag set on pushed stack?
|
|
85 C05F D0 EF bne xit ;exit if so
|
|
86
|
|
87 ;======== stage 2 processing
|
|
88
|
|
89 C061 stage_2:
|
|
90 ;re-enable interrupts
|
|
91 C061 58 cli
|
|
92
|
|
93 ;update shadow registers
|
|
94 C062 AD 31 02 8D 03 D4 mva sdlsth dlisth
|
|
95 C068 AD 30 02 8D 02 D4 mva sdlstl dlistl
|
|
96 C06E AD 2F 02 8D 00 D4 mva sdmctl dmactl
|
|
97 C074 AD F4 02 8D 09 D4 mva chbas chbase
|
|
98 C07A AD F3 02 8D 01 D4 mva chact chactl
|
|
99 C080 AD 6F 02 8D 1B D0 mva gprior prior
|
|
100
|
|
101 C086 A2 08 ldx #8
|
|
102 C088 8E 1F D0 stx consol ;sneak in speaker reset while we have an 8
|
|
103 C08B ColorLoop
|
|
104 C08B BD C0 02 lda pcolr0,x
|
|
105 C08E 45 4F eor colrsh
|
|
106 C090 25 4E and drkmsk
|
|
107 C092 9D 12 D0 sta colpm0,x
|
|
108 C095 CA dex
|
|
109 C096 10 F3 bpl ColorLoop
|
|
110
|
|
111 ;decrement timer 2 and check for underflow
|
|
112 C098 A2 03 ldx #3
|
|
113 C09A 20 47 C1 jsr VBIDecrementTimer
|
|
114 C09D D0 03 20 44 C1 sne:jsr Timer2Dispatch
|
|
115
|
|
116 ;Decrement timers 3-5 and set flags
|
|
117 ;
|
|
118 ;[OS Manual] Appendix L, page 254 says that the OS never modifies CDTMF3-5
|
|
119 ;except to set them to zero on timeout at init. This is a LIE. It also sets
|
|
120 ;the flags to $FF when they are running. It does not write the flags when
|
|
121 ;the timer is idle. Spider Quake depends on this.
|
|
122 ;
|
|
123 C0A2 A2 09 ldx #9
|
|
124 C0A4 timer_n_loop:
|
|
125 C0A4 18 clc
|
|
126 C0A5 20 47 C1 jsr VBIDecrementTimer
|
|
127 C0A8 B0 07 bcs timer_n_not_running
|
|
128 C0AA F0 02 A9 FF seq:lda #$ff
|
|
129 C0AE timer_n_not_expired:
|
|
130 C0AE 9D 25 02 sta cdtmf3-5,x
|
|
131 C0B1 timer_n_not_running:
|
|
132 C0B1 CA dex
|
|
133 C0B2 CA dex
|
|
134 C0B3 E0 05 cpx #5
|
|
135 C0B5 B0 ED bcs timer_n_loop
|
|
136
|
|
137 ;Read POKEY keyboard register and handle auto-repeat
|
|
138 C0B7 AD 0F D2 lda skstat ;get key status
|
|
139 C0BA 29 04 and #$04 ;check if key is down
|
|
140 C0BC D0 13 bne no_repeat_key ;skip if not
|
|
141 C0BE CE 2B 02 dec srtimr ;decrement repeat timer
|
|
142 C0C1 D0 13 bne no_repeat ;skip if not time to repeat yet
|
|
143 C0C3 AD 09 D2 8D FC 02 mva kbcode ch ;repeat last key
|
|
144
|
|
145 .if _KERNEL_XLXE
|
|
146 C0C9 AD DA 02 8D 2B 02 mva keyrep srtimr ;reset repeat timer
|
|
147 .else
|
|
148 mva #$06 srtimr ;reset repeat timer
|
|
149 .endif
|
|
150
|
|
151 C0CF D0 0D bne no_keydel ;skip debounce counter decrement
|
|
152
|
|
153 C0D1 no_repeat_key:
|
|
154 C0D1 A9 00 lda #0
|
|
155 C0D3 8D 2B 02 sta srtimr
|
|
156 C0D6 no_repeat:
|
|
157 ;decrement keyboard debounce counter
|
|
158 C0D6 AD F1 02 lda keydel
|
|
159 C0D9 F0 03 CE F1 02 seq:dec keydel
|
|
160 C0DE no_keydel:
|
|
161
|
|
162 ;Update controller shadows.
|
|
163 ;
|
|
164 ;The PORTA/PORTB decoding is a bit complex:
|
|
165 ;
|
|
166 ; bits 0-3 -> STICK0/4 (and no, we cannot leave junk in the high bits)
|
|
167 ; bits 4-7 -> STICK1/5
|
|
168 ; bit 2 -> PTRIG0/4
|
|
169 ; bit 3 -> PTRIG1/5
|
|
170 ; bit 6 -> PTRIG2/6
|
|
171 ; bit 7 -> PTRIG3/7
|
|
172 ;
|
|
173 ;XL/XE machines only have two joystick ports, so the results of ports 0-1
|
|
174 ;are mapped onto ports 2-3.
|
|
175 ;
|
|
176
|
|
177 .if _KERNEL_XLXE
|
|
178 C0DE AD 00 D3 lda porta
|
|
179 C0E1 AA tax
|
|
180 C0E2 29 0F and #$0f
|
|
181 C0E4 8D 78 02 sta stick0
|
|
182 C0E7 8D 7A 02 sta stick2
|
|
183 C0EA 8A txa
|
|
184 C0EB 4A lsr ;shr1
|
|
185 C0EC 4A lsr ;shr2
|
|
186 C0ED AA tax
|
|
187 C0EE 4A lsr ;shr3
|
|
188 C0EF 4A lsr ;shr4
|
|
189 C0F0 8D 79 02 sta stick1
|
|
190 C0F3 8D 7B 02 sta stick3
|
|
191 C0F6 4A lsr ;shr5
|
|
192 C0F7 4A lsr ;shr6
|
|
193 C0F8 A8 tay
|
|
194 C0F9 29 01 and #$01
|
|
195 C0FB 8D 7E 02 sta ptrig2
|
|
196 C0FE 98 tya
|
|
197 C0FF 4A lsr
|
|
198 C100 8D 7F 02 sta ptrig3
|
|
199 C103 8A txa
|
|
200 C104 29 01 and #$01
|
|
201 C106 8D 7C 02 sta ptrig0
|
|
202 C109 8A txa
|
|
203 C10A 4A lsr
|
|
204 C10B 29 01 and #$01
|
|
205 C10D 8D 7D 02 sta ptrig1
|
|
206
|
|
207 C110 A2 03 ldx #3
|
|
208 C112 pot_loop:
|
|
209 C112 BD 00 D2 lda pot0,x
|
|
210 C115 9D 70 02 sta paddl0,x
|
|
211 C118 9D 74 02 sta paddl4,x
|
|
212 C11B BD 7C 02 lda ptrig0,x
|
|
213 C11E 9D 80 02 sta ptrig4,x
|
|
214 C121 CA dex
|
|
215 C122 10 EE bpl pot_loop
|
|
216
|
|
217 C124 A2 01 ldx #1
|
|
218 C126 port_loop:
|
|
219 C126 BD 10 D0 lda trig0,x
|
|
220 C129 9D 84 02 sta strig0,x
|
|
221 C12C 9D 86 02 sta strig2,x
|
|
222 C12F CA dex
|
|
223 C130 10 F4 bpl port_loop
|
|
224
|
|
225 .else
|
|
226 ldx #7
|
|
227 pot_loop:
|
|
228 lda pot0,x
|
|
229 sta paddl0,x
|
|
230 lda #0
|
|
231 sta ptrig0,x
|
|
232 dex
|
|
233 bpl pot_loop
|
|
234
|
|
235 ldx #3
|
|
236 trig_loop:
|
|
237 lda trig0,x
|
|
238 sta strig0,x
|
|
239 dex
|
|
240 bpl trig_loop
|
|
241
|
|
242 lda porta
|
|
243 ldx #0
|
|
244 ldy #0
|
|
245 jsr do_stick_ptrigs
|
|
246 lda portb
|
|
247 ldx #4
|
|
248 ldy #2
|
|
249 jsr do_stick_ptrigs
|
|
250 .endif
|
|
251
|
|
252 ;restart pots (required for SysInfo)
|
|
253 C132 8D 0B D2 sta potgo
|
|
254
|
|
255 ;update light pen
|
|
256 C135 AD 0C D4 8D 34 02 mva penh lpenh
|
|
257 C13B AD 0D D4 8D 35 02 mva penv lpenv
|
|
258
|
|
259 C141 6C 24 02 jmp (vvblkd) ;jump through vblank deferred vector
|
|
260
|
|
261 C144 Timer2Dispatch
|
|
262 C144 6C 28 02 jmp (cdtma2)
|
|
263
|
|
264 .if !_KERNEL_XLXE
|
|
265 do_stick_ptrigs:
|
|
266 pha
|
|
267 and #$0f
|
|
268 sta stick0,y
|
|
269 pla
|
|
270 lsr
|
|
271 lsr
|
|
272 lsr
|
|
273 rol ptrig0,x
|
|
274 lsr
|
|
275 rol ptrig1,x
|
|
276 sta stick1,y
|
|
277 lsr
|
|
278 lsr
|
|
279 lsr
|
|
280 rol ptrig2,x
|
|
281 lsr
|
|
282 rol ptrig3,x
|
|
283 rts
|
|
284 .endif
|
|
285
|
|
286 .endp
|
|
287
|
|
288 ;==========================================================================
|
|
289 ; VBIDecrementTimer
|
|
290 ;
|
|
291 ; Entry:
|
|
292 ; X = timer index *2+1 (1-9)
|
|
293 ;
|
|
294 ; Exit:
|
|
295 ; C=1, Z=0, A!0 timer not running
|
|
296 ; C=0/same, Z=1, A=0 timer just expired
|
|
297 ; C=0/same, Z=0, A=? timer still running
|
|
298 ;
|
|
299 C147 .proc VBIDecrementTimer
|
|
300 ;check low byte
|
|
301 C147 BD 17 02 lda cdtmv1-1,x
|
|
302 C14A D0 0A bne lononzero
|
|
303
|
|
304 ;check high byte; set C=1/Z=1 if zero, C=0/Z=0 otherwise
|
|
305 C14C DD 18 02 cmp cdtmv1,x
|
|
306 C14F D0 02 bne lozero_hinonzero
|
|
307
|
|
308 ;both bytes are zero, so timer's not running
|
|
309 C151 8A txa
|
|
310 C152 60 rts
|
|
311
|
|
312 C153 lozero_hinonzero:
|
|
313 ;decrement high byte
|
|
314 C153 DE 18 02 dec cdtmv1,x
|
|
315
|
|
316 C156 lononzero:
|
|
317 ;decrement low byte
|
|
318 C156 DE 17 02 dec cdtmv1-1,x
|
|
319 C159 D0 03 bne still_running
|
|
320
|
|
321 ;return high byte to set Z appropriately
|
|
322 C15B BD 18 02 lda cdtmv1,x
|
|
323 C15E still_running:
|
|
324 C15E 60 rts
|
|
325 .endp
|
|
326
|
|
327 ;==========================================================================
|
|
328 ; VBISetVector - set vertical blank vector or counter
|
|
329 ;
|
|
330 ; This is a drop-in replacement for SETVBV.
|
|
331 ;
|
|
332 ; A = item to update
|
|
333 ; 1-5 timer 1-5 counter value
|
|
334 ; 6 VVBLKI
|
|
335 ; 7 VVBLKD
|
|
336 ; X = MSB
|
|
337 ; Y = LSB
|
|
338 ;
|
|
339 C15F .proc VBISetVector
|
|
340 ;A = item to update
|
|
341 ; 1-5 timer 1-5 counter value
|
|
342 ; 6 VVBLKI
|
|
343 ; 7 VVBLKD
|
|
344 ;X = MSB
|
|
345 ;Y = LSB
|
|
346 ;
|
|
347 ;NOTE:
|
|
348 ;The Atari OS Manual says that DLIs will be disabled after SETVBV is called.
|
|
349 ;This is a lie -- neither the OS-B nor XL kernels do this, and the Bewesoft
|
|
350 ;8-players demo depends on it being left enabled.
|
|
351 ;
|
|
352 ;IRQ mask state must be saved across this proc. DOSDISKA.ATR breaks if IRQs
|
|
353 ;are unmasked.
|
|
354
|
|
355 C15F 0A asl
|
|
356 C160 8D 2D 02 sta intemp
|
|
357 C163 08 php
|
|
358 C164 78 sei
|
|
359 C165 98 tya
|
|
360 C166 AC 2D 02 ldy intemp
|
|
361
|
|
362 ;We're relying on a rather tight window here. We can't touch NMIEN, so we have
|
|
363 ;to wing it with DLIs enabled. Problem is, in certain conditions we can be under
|
|
364 ;very tight timing constraints. In order to do this safely we have to finish
|
|
365 ;before a DLI can execute. The worst case is a wide mode 2 line at the end of
|
|
366 ;a vertically scrolled region with P/M graphics enabled and an LMS on the next
|
|
367 ;mode line. In that case we only have 7 cycles before we hit the P/M graphics
|
|
368 ;and another two cycles after that until the DLI fires. The exact cycle timing
|
|
369 ;looks like this:
|
|
370 ;
|
|
371 ;* inc wsync
|
|
372 ;ANTIC halts CPU until cycle 105
|
|
373 ;105 playfield DMA
|
|
374 ;106 refresh DMA
|
|
375 ;107 sta abs,y (1/5)
|
|
376 ;108 sta abs,y (2/5)
|
|
377 ;109 sta abs,y (3/5)
|
|
378 ;110 sta abs,y (4/5)
|
|
379 ;111 sta abs,y (5/5)
|
|
380 ;112 txa (1/2)
|
|
381 ;113 txa (2/2)
|
|
382 ;0 missiles
|
|
383 ;1 display list
|
|
384 ;2 player 0
|
|
385 ;3 player 1
|
|
386 ;4 player 2
|
|
387 ;5 player 3
|
|
388 ;6 display list address low
|
|
389 ;7 display list address high
|
|
390 ;8 sta abs,y (1/5)
|
|
391 ;9 sta abs,y (2/5)
|
|
392 ;10 sta abs,y (3/5)
|
|
393 ;11 sta abs,y (4/5)
|
|
394 ;12 sta abs,y (5/5)
|
|
395 ;
|
|
396 ;We rely on the 6502 not being able to service interrupts until the end of an
|
|
397 ;instruction for this to work. The INC WSYNC is necessary to combat the case
|
|
398 ;where the NMI is triggered across the WSYNC wait; without it, the VBI could
|
|
399 ;fire immediately after the first STA.
|
|
400
|
|
401 C169 EE 0A D4 inc wsync
|
|
402 C16C 99 16 02 sta cdtmv1-2,y
|
|
403 C16F 8A txa
|
|
404 C170 99 17 02 sta cdtmv1-1,y
|
|
405 C173 28 plp
|
|
406 C174 60 rts
|
|
407 .endp
|
|
60 .endif
|
|
61
|
|
62 C175 _KERNEL_REPORT_MODULE_SIZE 'VBI routines', 0
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', 0, ')', ' ', 'VBI routines'
|
|
1 $C175 -> $0169($0000) VBI routines
|
|
3 = C175 .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
63
|
|
64 .ifdef _KERNEL_816
|
|
65 icl 'interrupt816.s'
|
|
66 .else
|
|
67 C175 icl 'interrupt.s'
|
|
Source: source/Shared/interrupt.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Interrupt Handlers
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11 ; Dispatched from INTINV. Used by SpartaDOS X.
|
|
12 ;
|
|
13 C175 .proc IntInitInterrupts
|
|
14 C175 A9 40 8D 0E D4 mva #$40 nmien
|
|
15
|
|
16 .if _KERNEL_XLXE
|
|
17 ;Required by XEGS carts to run since they have a clone of the XL/XE
|
|
18 ;OS in them.
|
|
19 C17A AD 13 D0 8D FA 03 mva trig3 gintlk
|
|
20 .endif
|
|
21
|
|
22 C180 60 rts
|
|
23 .endp
|
|
24
|
|
25 ;==========================================================================
|
|
26 C181 .proc IntDispatchNMI
|
|
27 C181 2C 0F D4 bit nmist ;check nmi status
|
|
28 C184 10 03 bpl not_dli ;skip if not a DLI
|
|
29 C186 6C 00 02 jmp (vdslst) ;jump to display list vector
|
|
30
|
|
31 .if !_KERNEL_XLXE
|
|
32 is_system_reset:
|
|
33 jmp warmsv
|
|
34 .endif
|
|
35
|
|
36 C189 not_dli:
|
|
37 C189 48 pha
|
|
38
|
|
39 .if _KERNEL_XLXE
|
|
40 ;Only XL/XE OSes cleared the decimal bit.
|
|
41 C18A D8 cld
|
|
42 .else
|
|
43 ;The stock OS treats 'not RNMI' as VBI. We'd best follow its example.
|
|
44 lda #$20
|
|
45 bit nmist
|
|
46 bne is_system_reset
|
|
47 .endif
|
|
48
|
|
49 C18B 8A txa
|
|
50 C18C 48 pha
|
|
51 C18D 98 tya
|
|
52 C18E 48 pha
|
|
53 C18F 8D 0F D4 sta nmires ;reset VBI interrupt
|
|
54 C192 6C 22 02 jmp (vvblki) ;jump through vblank immediate vector
|
|
55 .endp
|
|
56
|
|
57 C195 .proc IntDispatchIRQ
|
|
58 .if _KERNEL_XLXE
|
|
59 C195 D8 cld
|
|
60 .endif
|
|
61 C196 6C 16 02 jmp (vimirq)
|
|
62 .endp
|
|
63
|
|
64 ;==============================================================================
|
|
65 = C054 IntExitHandler_A = VBIProcess.exit_a
|
|
66 = C055 IntExitHandler_None = VBIProcess.exit_none
|
|
68 .endif
|
|
69
|
|
70 C199 _KERNEL_REPORT_MODULE_SIZE 'Base interrupt routines', 0
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', 0, ')', ' ', 'Base interrupt routines'
|
|
1 $C199 -> $0024($0000) Base interrupt routines
|
|
3 = C199 .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
71
|
|
72 .ifdef _KERNEL_816
|
|
73 icl 'irq816.s'
|
|
74 .else
|
|
75 C199 icl 'irq.s'
|
|
Source: source/Shared/irq.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - IRQ routines
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11 ; _KERNEL_FAST_IRQ
|
|
12 ;
|
|
13 ; If set, expands the IRQ module slightly to save 12 cycles when ack'ing
|
|
14 ; POKEY IRQs. This is still faster than the stock XL/XE OS. If cleared,
|
|
15 ; an additional subroutine call is used to reduce code size.
|
|
16 ;
|
|
17 .ifndef _KERNEL_FAST_IRQ
|
|
18 _KERNEL_FAST_IRQ = 0
|
|
19 .endif
|
|
20
|
|
21 ;==========================================================================
|
|
22 .if _KERNEL_FAST_IRQ
|
|
23 _ACK_IRQ .macro
|
|
24 sta irqen
|
|
25 lda pokmsk
|
|
26 sta irqen
|
|
27 .endm
|
|
28 .else
|
|
29 _ACK_IRQ .macro
|
|
30 jsr IrqAcknowledge
|
|
31 .endm
|
|
32 .endif
|
|
33
|
|
34 ;==========================================================================
|
|
35 ; The canonical IRQ priority order for the XL/XE is:
|
|
36 ; - Serial input ready ($20)
|
|
37 ; - PBI devices
|
|
38 ; - Serial output ready ($10)
|
|
39 ; - Serial output complete ($08)
|
|
40 ; - Timer 1 ($01)
|
|
41 ; - Timer 2 ($02)
|
|
42 ; - Timer 4 ($04)
|
|
43 ; - Keyboard ($80)
|
|
44 ; - Break ($40)
|
|
45 ; - PIA proceed
|
|
46 ; - PIA interrupt
|
|
47 ; - BRK instruction
|
|
48 ;
|
|
49 = C1D1 IRQHandler = _IRQHandler._entry
|
|
50 C199 .proc _IRQHandler
|
|
51 .if _KERNEL_PBI_SUPPORT
|
|
52 C199 check_pbi:
|
|
53 ;check if a device interrupt is active
|
|
54 C199 2D FF D1 and $d1ff
|
|
55 C19C F0 4D beq no_pbi_interrupt
|
|
56
|
|
57 ;save X
|
|
58 C19E 8D 8C 02 sta jveck
|
|
59 C1A1 8A txa
|
|
60 C1A2 48 pha
|
|
61
|
|
62 ;jump through PBI interrupt vector
|
|
63 C1A3 AD 8C 02 lda jveck
|
|
64 C1A6 6C 38 02 jmp (vpirq)
|
|
65 .endif
|
|
66
|
|
67 C1A9 dispatch_serout:
|
|
68 C1A9 A9 EF lda #$ef
|
|
69 C1AB _ACK_IRQ
|
|
Macro: _ACK_IRQ [Source: source/Shared/irq.s]
|
|
1 C1AB 20 45 C2 jsr IrqAcknowledge
|
|
Source: source/Shared/irq.s
|
|
70 C1AE 6C 0C 02 jmp (vseror)
|
|
71
|
|
72 C1B1 check_seroc:
|
|
73 C1B1 2C 0E D2 bit irqst
|
|
74 C1B4 D0 41 bne not_seroc
|
|
75 C1B6 dispatch_seroc:
|
|
76 C1B6 6C 0E 02 jmp (vseroc)
|
|
77
|
|
78 C1B9 dispatch_timer1:
|
|
79 C1B9 A9 FE lda #$fe
|
|
80 C1BB _ACK_IRQ
|
|
Macro: _ACK_IRQ [Source: source/Shared/irq.s]
|
|
1 C1BB 20 45 C2 jsr IrqAcknowledge
|
|
Source: source/Shared/irq.s
|
|
81 C1BE 6C 10 02 jmp (vtimr1)
|
|
82
|
|
83 C1C1 dispatch_timer2:
|
|
84 C1C1 A9 FD lda #$fd
|
|
85 C1C3 _ACK_IRQ
|
|
Macro: _ACK_IRQ [Source: source/Shared/irq.s]
|
|
1 C1C3 20 45 C2 jsr IrqAcknowledge
|
|
Source: source/Shared/irq.s
|
|
86 C1C6 6C 12 02 jmp (vtimr2)
|
|
87
|
|
88 C1C9 dispatch_timer4:
|
|
89 C1C9 A9 FB lda #$fb
|
|
90 C1CB _ACK_IRQ
|
|
Macro: _ACK_IRQ [Source: source/Shared/irq.s]
|
|
1 C1CB 20 45 C2 jsr IrqAcknowledge
|
|
Source: source/Shared/irq.s
|
|
91 C1CE 6C 14 02 jmp (vtimr4)
|
|
92
|
|
93 C1D1 _entry:
|
|
94 C1D1 48 pha
|
|
95
|
|
96 ;check for serial input ready IRQ
|
|
97 C1D2 A9 20 lda #$20
|
|
98 C1D4 2C 0E D2 bit irqst
|
|
99 C1D7 D0 0D bne not_serin
|
|
100 C1D9 A9 DF lda #$df
|
|
101 C1DB 8D 0E D2 sta irqen
|
|
102 C1DE A5 10 lda pokmsk
|
|
103 C1E0 8D 0E D2 sta irqen
|
|
104 C1E3 6C 0A 02 jmp (vserin)
|
|
105 C1E6 not_serin:
|
|
106
|
|
107 .if _KERNEL_PBI_SUPPORT
|
|
108 ;check for PBI devices requiring interrupt handling
|
|
109 C1E6 AD 49 02 lda pdmsk
|
|
110 C1E9 D0 AE bne check_pbi
|
|
111 C1EB no_pbi_interrupt:
|
|
112 .endif
|
|
113
|
|
114 ;check for serial output ready IRQ
|
|
115 C1EB A9 10 lda #$10
|
|
116 C1ED 2C 0E D2 bit irqst
|
|
117 C1F0 F0 B7 beq dispatch_serout
|
|
118
|
|
119 ;check for serial output complete (not a latch, so must mask)
|
|
120 C1F2 4A lsr
|
|
121 C1F3 24 10 bit pokmsk
|
|
122 C1F5 D0 BA bne check_seroc
|
|
123 C1F7 not_seroc:
|
|
124
|
|
125 C1F7 AD 0E D2 lda irqst
|
|
126 C1FA 4A lsr
|
|
127 C1FB 90 BC bcc dispatch_timer1
|
|
128 C1FD 4A lsr
|
|
129 C1FE 90 C1 bcc dispatch_timer2
|
|
130 C200 4A lsr
|
|
131 C201 90 C6 bcc dispatch_timer4
|
|
132 C203 2C 0E D2 bit irqst
|
|
133 C206 50 21 bvc dispatch_keyboard
|
|
134 C208 10 27 bpl dispatch_break
|
|
135
|
|
136 ;check for serial bus proceed line
|
|
137 C20A 2C 02 D3 bit pactl
|
|
138 C20D 30 2A bmi dispatch_pia_irqa
|
|
139
|
|
140 ;check for serial bus interrupt line
|
|
141 C20F 2C 03 D3 bit pbctl
|
|
142 C212 30 2B bmi dispatch_pia_irqb
|
|
143
|
|
144 ;check for break instruction
|
|
145 ;
|
|
146 ;we used to use TSX here, but this takes too many insns to
|
|
147 ;handle stack wrapping properly
|
|
148 C214 68 pla
|
|
149 C215 8D 8C 02 sta jveck
|
|
150 C218 68 pla
|
|
151 C219 48 pha
|
|
152 C21A 29 10 and #$10
|
|
153 C21C F0 07 beq not_brk
|
|
154 C21E AD 8C 02 lda jveck
|
|
155 C221 48 pha
|
|
156 C222 6C 06 02 jmp (vbreak)
|
|
157 C225 not_brk:
|
|
158 C225 AD 8C 02 lda jveck
|
|
159 C228 40 rti
|
|
160
|
|
161
|
|
162 C229 dispatch_keyboard:
|
|
163 C229 A9 BF lda #$bf
|
|
164 C22B _ACK_IRQ
|
|
Macro: _ACK_IRQ [Source: source/Shared/irq.s]
|
|
1 C22B 20 45 C2 jsr IrqAcknowledge
|
|
Source: source/Shared/irq.s
|
|
165 C22E 6C 08 02 jmp (vkeybd)
|
|
166
|
|
167 C231 dispatch_break:
|
|
168 C231 A9 7F lda #$7f
|
|
169 C233 _ACK_IRQ
|
|
Macro: _ACK_IRQ [Source: source/Shared/irq.s]
|
|
1 C233 20 45 C2 jsr IrqAcknowledge
|
|
Source: source/Shared/irq.s
|
|
170 C236 6C 36 02 jmp (brkky)
|
|
171
|
|
172 C239 dispatch_pia_irqa:
|
|
173 ;clear serial bus proceed interrupt
|
|
174 C239 AD 00 D3 lda porta
|
|
175 C23C 6C 02 02 jmp (vprced)
|
|
176
|
|
177 C23F dispatch_pia_irqb:
|
|
178 ;clear serial bus interrupt interrupt
|
|
179 C23F AD 01 D3 lda portb
|
|
180 C242 6C 04 02 jmp (vinter)
|
|
181
|
|
182 .endp
|
|
183
|
|
184 ;==========================================================================
|
|
185 .if !_KERNEL_FAST_IRQ
|
|
186 C245 .proc IrqAcknowledge
|
|
187 C245 8D 0E D2 sta irqen
|
|
188 C248 A5 10 lda pokmsk
|
|
189 C24A 8D 0E D2 sta irqen
|
|
190 C24D 60 rts
|
|
191 .endp
|
|
192 .endif
|
|
76 .endif
|
|
77
|
|
78 C24E _KERNEL_REPORT_MODULE_SIZE 'IRQ routines', 0
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', 0, ')', ' ', 'IRQ routines'
|
|
1 $C24E -> $00B5($0000) IRQ routines
|
|
3 = C24E .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
79
|
|
80 C24E icl 'pbi.s'
|
|
Source: source/Shared/pbi.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Parallel Bus Interface routines
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 .if _KERNEL_PBI_SUPPORT
|
|
11
|
|
12 C24E icl 'cio.inc'
|
|
Source: source/Shared/cio.inc
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Character Input/Output Definitions
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 .ifndef f_CIO_INC
|
|
11 .def f_CIO_INC
|
|
12
|
|
13 CIOStatBreak = $80 ;break key abort
|
|
14 CIOStatIOCBInUse = $81 ;IOCB in use
|
|
15 CIOStatUnkDevice = $82 ;unknown device
|
|
16 CIOStatWriteOnly = $83 ;opened for write only
|
|
17 CIOStatInvalidCmd = $84 ;invalid command
|
|
18 CIOStatNotOpen = $85 ;device or file not open
|
|
19 CIOStatInvalidIOCB = $86 ;invalid IOCB number
|
|
20 CIOStatReadOnly = $87 ;opened for read only
|
|
21 CIOStatEndOfFile = $88 ;end of file reached
|
|
22 CIOStatTruncRecord = $89 ;record truncated
|
|
23 CIOStatTimeout = $8A ;device timeout
|
|
24 CIOStatNAK = $8B ;device NAK
|
|
25 CIOStatSerFrameErr = $8C ;serial bus framing error
|
|
26 CIOStatCursorRange = $8D ;cursor out of range
|
|
27 CIOStatSerOverrun = $8E ;serial frame overrun error
|
|
28 CIOStatSerChecksum = $8F ;serial checksum error
|
|
29 CIOStatDeviceDone = $90 ;device done error
|
|
30 CIOStatBadScrnMode = $91 ;bad screen mode
|
|
31 CIOStatNotSupported = $92 ;function not supported by handler
|
|
32 CIOStatOutOfMemory = $93 ;not enough memory
|
|
33 CIOStatDriveNumErr = $A0 ;disk drive # error
|
|
34 CIOStatTooManyFiles = $A1 ;too many open disk files
|
|
35 CIOStatDiskFull = $A2 ;disk full
|
|
36 CIOStatFatalDiskIO = $A3 ;fatal disk I/O error
|
|
37 CIOStatFileNumDiff = $A4 ;internal file # mismatch
|
|
38 CIOStatFileNameErr = $A5 ;filename error
|
|
39 CIOStatPointDLen = $A6 ;point data length error
|
|
40 CIOStatFileLocked = $A7 ;file locked
|
|
41 CIOStatInvDiskCmd = $A8 ;invalid command for disk
|
|
42 CIOStatDirFull = $A9 ;directory full (64 files)
|
|
43 CIOStatFileNotFound = $AA ;file not found
|
|
44 CIOStatInvPoint = $AB ;invalid point
|
|
45
|
|
46 CIOCmdOpen = $03
|
|
47 CIOCmdGetRecord = $05
|
|
48 CIOCmdGetChars = $07
|
|
49 CIOCmdPutRecord = $09
|
|
50 ; $0A ;PUT CHARS alias (required by K-Razy Shoot Out)
|
|
51 CIOCmdPutChars = $0B
|
|
52 CIOCmdClose = $0C
|
|
53 CIOCmdGetStatus = $0D
|
|
54 CIOCmdSpecial = $0E ;$0E and up is escape
|
|
55
|
|
56 .endif
|
|
13
|
|
14 ;==========================================================================
|
|
15 ; PBI device ROM entry points:
|
|
16 ; $D800 Checksum low (unused)
|
|
17 ; $D801 Checksum high (unused)
|
|
18 ; $D802 Revision (unused)
|
|
19 ; $D803 ID byte; must be $80.
|
|
20 ; $D804 Device type (unused)
|
|
21 ; $D805 JMP sio_vector
|
|
22 ; $D806 (cont.)
|
|
23 ; $D807 (cont.)
|
|
24 ; $D808 JMP irq_vector
|
|
25 ; $D809 (cont.)
|
|
26 ; $D80A (cont.)
|
|
27 ; $D80B ID byte; must be $91
|
|
28 ; $D80C Device name (unused)
|
|
29 ; $D80D CIO open vector - 1
|
|
30 ; $D80E (cont.)
|
|
31 ; $D80F CIO close vector - 1
|
|
32 ; $D810 (cont.)
|
|
33 ; $D811 CIO get byte vector - 1
|
|
34 ; $D812 (cont.)
|
|
35 ; $D813 CIO put byte vector - 1
|
|
36 ; $D814 (cont.)
|
|
37 ; $D815 CIO get status vector - 1
|
|
38 ; $D816 (cont.)
|
|
39 ; $D817 CIO special vector - 1
|
|
40 ; $D818 (cont.)
|
|
41 ; $D819 JMP init_vector
|
|
42 ; $D81A (cont.)
|
|
43 ; $D81B (cont.)
|
|
44 ;
|
|
45
|
|
46 ;==========================================================================
|
|
47 ; Scan for PBI devices.
|
|
48 ;
|
|
49 ; The details:
|
|
50 ; - $D1FF is the PBI device select register; 1 selects a device.
|
|
51 ; - A selected device, if it exists, maps its ROM into $D800-DFFF, on
|
|
52 ; top of the math pack.
|
|
53 ; - ID bytes are checked to ensure that a device ROM is actually present.
|
|
54 ; (This means that the math pack must not match those bytes!)
|
|
55 ; - SHPDVS is the device selection shadow variable. It must match the
|
|
56 ; value written to $D1FF whenever the PBI ROM is invoked so that the
|
|
57 ; PBI device code can detect its ID.
|
|
58 ; - PDVMSK is the device enable mask and is used by SIO to call into
|
|
59 ; PBI devices. Each bit in this mask indicates that a PBI device is
|
|
60 ; available to possibly service requests. It is NOT set by this
|
|
61 ; routine, but by the PBI device init code.
|
|
62 ;
|
|
63 C24E .proc PBIScan
|
|
64 ;set up interrupt handler
|
|
65 C24E A9 7E 8D 38 02 A9 + mwa #PBIHandleIRQ vpirq
|
|
66
|
|
67 ;begin scan
|
|
68 C258 A9 01 lda #$01
|
|
69 C25A loop:
|
|
70 ;select next device
|
|
71 C25A 8D 48 02 sta shpdvs
|
|
72 C25D 8D FF D1 sta $d1ff
|
|
73
|
|
74 ;check ID bytes
|
|
75 C260 AC 03 D8 ldy $d803
|
|
76 C263 C0 80 cpy #$80
|
|
77 C265 D0 0A bne invalid
|
|
78
|
|
79 C267 AC 0B D8 ldy $d80b
|
|
80 C26A C0 91 cpy #$91
|
|
81 C26C D0 03 bne invalid
|
|
82
|
|
83 ;init PBI device
|
|
84 C26E 20 19 D8 jsr $d819
|
|
85 C271 invalid:
|
|
86
|
|
87 ;next device
|
|
88 C271 AD 48 02 lda shpdvs
|
|
89 C274 0A asl
|
|
90 C275 D0 E3 bne loop
|
|
91
|
|
92 ;deselect last device
|
|
93 C277 8D 48 02 sta shpdvs
|
|
94 C27A 8D FF D1 sta $d1ff
|
|
95 C27D 60 rts
|
|
96 .endp
|
|
97
|
|
98 ;==========================================================================
|
|
99 ; Entry:
|
|
100 ; A, X saved on stack
|
|
101 ; A = active PBI IRQ mask ($D1FF AND PDMSK)
|
|
102 ;
|
|
103 ; Exit:
|
|
104 ; A, X restored
|
|
105 ; Interrupt exit
|
|
106 ;
|
|
107 C27E .proc PBIHandleIRQ
|
|
108 ;isolate lowest bit (ID of highest priority device)
|
|
109 C27E 8D 8C 02 sta jveck
|
|
110 C281 49 FF eor #$ff
|
|
111 C283 18 clc
|
|
112 C284 69 01 adc #1
|
|
113 C286 2D 8C 02 and jveck
|
|
114
|
|
115 ;save off the current device mask and select interrupting device
|
|
116 C289 AE 48 02 ldx shpdvs
|
|
117 C28C 8D 48 02 sta shpdvs
|
|
118 C28F 8D FF D1 sta $d1ff
|
|
119 C292 8A txa
|
|
120 C293 48 pha
|
|
121
|
|
122 ;call through interrupt vector
|
|
123 C294 20 08 D8 jsr $d808
|
|
124
|
|
125 ;restore previously (un)selected device
|
|
126 C297 68 pla
|
|
127 C298 8D 48 02 sta shpdvs
|
|
128 C29B 8D FF D1 sta $d1ff
|
|
129
|
|
130 ;restore X, A and exit
|
|
131 C29E 68 pla
|
|
132 C29F AA tax
|
|
133 C2A0 68 pla
|
|
134 C2A1 40 rti
|
|
135 .endp
|
|
136
|
|
137 ;==========================================================================
|
|
138 C2A2 .proc PBIAttemptSIO
|
|
139 C2A2 AD 47 02 lda pdvmsk
|
|
140 C2A5 D0 08 bne begin_scan
|
|
141 C2A7 fail:
|
|
142 C2A7 8D 48 02 sta shpdvs
|
|
143 C2AA 8D FF D1 sta $d1ff
|
|
144 C2AD 18 clc
|
|
145 C2AE 60 rts
|
|
146
|
|
147 C2AF begin_scan:
|
|
148 C2AF A9 00 lda #0
|
|
149 C2B1 38 sec
|
|
150 C2B2 loop:
|
|
151 ;advance to next device bit
|
|
152 C2B2 2A rol
|
|
153
|
|
154 ;check if we've scanned all 8 IDs
|
|
155 C2B3 B0 F2 bcs fail
|
|
156
|
|
157 ;check if device exists
|
|
158 C2B5 2C 47 02 bit pdvmsk
|
|
159
|
|
160 ;keep scanning if not
|
|
161 C2B8 F0 F8 beq loop
|
|
162
|
|
163 ;select the device
|
|
164 C2BA 8D 48 02 sta shpdvs
|
|
165 C2BD 8D FF D1 sta $d1ff
|
|
166
|
|
167 ;attempt I/O
|
|
168 C2C0 48 pha
|
|
169 C2C1 20 05 D8 jsr $d805
|
|
170 C2C4 68 pla
|
|
171
|
|
172 ;loop back if PBI handler didn't claim the I/O
|
|
173 C2C5 90 EB bcc loop
|
|
174
|
|
175 ;deselect last device
|
|
176 C2C7 A9 00 lda #0
|
|
177 C2C9 8D 48 02 sta shpdvs
|
|
178 C2CC 8D FF D1 sta $d1ff
|
|
179
|
|
180 ;all done
|
|
181 C2CF 60 rts
|
|
182 .endp
|
|
183
|
|
184 ;==========================================================================
|
|
185 C2D0 .proc PBIGenericDeviceOpen
|
|
186 C2D0 A0 00 ldy #0
|
|
187 C2D2 10 0A bpl PBIGenericDevicePutByte.vector_entry
|
|
188 .endp
|
|
189
|
|
190 ;==========================================================================
|
|
191 C2D4 .proc PBIGenericDeviceClose
|
|
192 C2D4 A0 02 ldy #2
|
|
193 C2D6 10 06 bpl PBIGenericDevicePutByte.vector_entry
|
|
194 .endp
|
|
195
|
|
196 ;==========================================================================
|
|
197 C2D8 .proc PBIGenericDeviceGetByte
|
|
198 C2D8 A0 04 ldy #4
|
|
199 C2DA 10 02 bpl PBIGenericDevicePutByte.vector_entry
|
|
200 .endp
|
|
201
|
|
202 ;==========================================================================
|
|
203 C2DC .proc PBIGenericDevicePutByte
|
|
204 C2DC A0 06 ldy #6
|
|
205 C2DE vector_entry:
|
|
206 C2DE 8C 4A 02 sty reladr
|
|
207 C2E1 8D 4B 02 sta reladr+1
|
|
208 C2E4 A9 00 lda #0
|
|
209 C2E6 38 sec
|
|
210 C2E7 loop:
|
|
211 ;advance to next device bit
|
|
212 C2E7 2A rol
|
|
213
|
|
214 ;check if we've scanned all 8 IDs
|
|
215 C2E8 B0 1B bcs fail
|
|
216
|
|
217 ;check if device exists and keep scanning if not
|
|
218 C2EA 2C 47 02 bit pdvmsk
|
|
219 C2ED F0 F8 beq loop
|
|
220
|
|
221 ;select the device -- note that the write to SHPDVS *MUST* come
|
|
222 ;first, in case a PBI IRQ happens, since we do *NOT* have IRQs
|
|
223 ;masked here!
|
|
224 C2EF 8D 48 02 sta shpdvs
|
|
225 C2F2 8D FF D1 sta $d1ff
|
|
226
|
|
227 ;attempt I/O
|
|
228 C2F5 A5 2F lda ciochr
|
|
229 C2F7 20 09 C3 jsr dispatch
|
|
230
|
|
231 ;loop back if PBI handler didn't claim the I/O
|
|
232 C2FA 90 EB bcc loop
|
|
233
|
|
234 ;all done
|
|
235 C2FC done:
|
|
236 C2FC A2 00 ldx #0
|
|
237 C2FE 8E 48 02 stx shpdvs
|
|
238 C301 8E FF D1 stx $d1ff
|
|
239 C304 60 rts
|
|
240
|
|
241 C305 fail:
|
|
242 C305 A0 82 ldy #CIOStatUnkDevice
|
|
243 C307 D0 F3 bne done
|
|
244
|
|
245 C309 dispatch:
|
|
246 C309 AC 4A 02 ldy reladr
|
|
247 C30C B9 0E D8 lda $d80e,y
|
|
248 C30F 48 pha
|
|
249 C310 B9 0D D8 lda $d80d,y
|
|
250 C313 48 pha
|
|
251 C314 AD 4B 02 lda reladr+1
|
|
252 C317 A0 92 ldy #CIOStatNotSupported
|
|
253 C319 60 rts
|
|
254
|
|
255 .endp
|
|
256
|
|
257 ;==========================================================================
|
|
258 C31A .proc PBIGenericDeviceGetStatus
|
|
259 C31A A0 08 ldy #8
|
|
260 C31C 10 C0 bpl PBIGenericDevicePutByte.vector_entry
|
|
261 .endp
|
|
262
|
|
263 ;==========================================================================
|
|
264 C31E .proc PBIGenericDeviceSpecial
|
|
265 C31E A0 0A ldy #10
|
|
266 C320 10 BC bpl PBIGenericDevicePutByte.vector_entry
|
|
267 .endp
|
|
268
|
|
269 ;==========================================================================
|
|
270 .macro PBI_VECTOR_TABLE
|
|
271 dta a(PBIGenericDeviceOpen-1)
|
|
272 dta a(PBIGenericDeviceClose-1)
|
|
273 dta a(PBIGenericDeviceGetByte-1)
|
|
274 dta a(PBIGenericDevicePutByte-1)
|
|
275 dta a(PBIGenericDeviceGetStatus-1)
|
|
276 dta a(PBIGenericDeviceSpecial-1)
|
|
277 .endm
|
|
278
|
|
279 .endif
|
|
81 C322 _KERNEL_REPORT_MODULE_SIZE 'PBI routines', 0
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', 0, ')', ' ', 'PBI routines'
|
|
1 $C322 -> $00D4($0000) PBI routines
|
|
3 = C322 .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
82 C322 icl 'phandler.s'
|
|
Source: source/Shared/phandler.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Peripheral Handler routines
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11 ; Add handler to HATABS.
|
|
12 ;
|
|
13 ; Input:
|
|
14 ; X Name of device
|
|
15 ; A:Y CIO handler table address
|
|
16 ;
|
|
17 ; Returns:
|
|
18 ; N=1 HATABS is full.
|
|
19 ; C=0 Handler added successfully.
|
|
20 ; C=1 Handler already exists; X points to address entry
|
|
21 ; A:Y preserved (required by SDX 4.43rc)
|
|
22 ;
|
|
23 C322 .proc PHAddHandler
|
|
24 C322 48 pha
|
|
25 C323 98 tya
|
|
26 C324 48 pha
|
|
27 C325 8A txa
|
|
28 C326 A2 21 ldx #33
|
|
29 C328 search_loop:
|
|
30 C328 DD 1A 03 cmp hatabs,x
|
|
31 C32B F0 17 beq found_existing
|
|
32 C32D CA dex
|
|
33 C32E CA dex
|
|
34 C32F CA dex
|
|
35 C330 10 F6 bpl search_loop
|
|
36
|
|
37 C332 insert_loop:
|
|
38 C332 E8 inx
|
|
39 C333 E8 inx
|
|
40 C334 E8 inx
|
|
41 C335 BC 1A 03 ldy hatabs,x
|
|
42 C338 F0 10 beq found_empty
|
|
43 C33A E0 24 cpx #36
|
|
44 C33C D0 F4 bne insert_loop
|
|
45
|
|
46 ;oops... table is full!
|
|
47 C33E 68 pla
|
|
48 C33F 68 pla
|
|
49 C340 A9 FF lda #$ff
|
|
50 C342 38 sec
|
|
51 C343 60 rts
|
|
52
|
|
53 C344 found_existing:
|
|
54 C344 68 pla
|
|
55 C345 A8 tay
|
|
56 C346 68 pla
|
|
57 C347 E8 inx ;X=address offset, N=0 (not full)
|
|
58 C348 38 sec ;C=1 (already exists)
|
|
59 C349 60 rts
|
|
60
|
|
61 C34A found_empty:
|
|
62 C34A 9D 1A 03 sta hatabs,x
|
|
63 C34D 68 pla
|
|
64 C34E 9D 1B 03 sta hatabs+1,x
|
|
65 C351 68 pla
|
|
66 C352 9D 1C 03 sta hatabs+2,x
|
|
67 C355 0A asl ;N=0 (not full)
|
|
68 C356 18 clc ;C=0 (added successfully)
|
|
69 C357 60 rts
|
|
70 .endp
|
|
71
|
|
72 ;==========================================================================
|
|
73 ; Remove peripheral handler.
|
|
74 ;
|
|
75 ; Entry:
|
|
76 ; A:Y Address of handler to remove
|
|
77 ;
|
|
78 ; Exit:
|
|
79 ; C=0 Removal was successful
|
|
80 ; C=1 Removal failed (not found, broken chain or handler size was
|
|
81 ; non-zero)
|
|
82 ;
|
|
83 ; This routine unlinks a peripheral handler from the CHLINK chain. It fails
|
|
84 ; if the handler size in the handler table is non-zero, which means that it
|
|
85 ; was loaded on power-up.
|
|
86 ;
|
|
87 ; Note that this routine does NOT remove any handler entries in HATABS.
|
|
88 ;
|
|
89 C358 .proc PHRemoveHandler
|
|
90 ;stash handler address
|
|
91 C358 8C 4A 02 sty reladr
|
|
92 C35B 8D 4B 02 sta reladr+1
|
|
93
|
|
94 ;load "chain head" by pretending the chain address is in a handler
|
|
95 ;entry
|
|
96 C35E A2 E9 ldx #<(chlink-$12)
|
|
97 C360 A9 03 lda #>(chlink-$12)
|
|
98
|
|
99 C362 search_loop:
|
|
100 ;check if we're at the end
|
|
101 C362 A8 tay
|
|
102 C363 D0 04 bne not_end
|
|
103 C365 E0 00 cpx #0
|
|
104 C367 F0 23 beq epic_fail
|
|
105
|
|
106 C369 not_end:
|
|
107 ;save off the prev pointer
|
|
108 C369 86 36 stx ltemp
|
|
109 C36B 85 37 sta ltemp+1
|
|
110
|
|
111 ;load the next pointer
|
|
112 C36D A0 12 ldy #$12
|
|
113 C36F B1 36 lda (ltemp),y
|
|
114 C371 AA tax
|
|
115 C372 C8 iny
|
|
116 C373 B1 36 lda (ltemp),y
|
|
117 C375 CD 4B 02 cmp reladr+1
|
|
118 C378 D0 E8 bne search_loop
|
|
119 C37A EC 4A 02 cpx reladr
|
|
120 C37D D0 E3 bne search_loop
|
|
121
|
|
122 ;we've found it -- move it into a pointer var
|
|
123 C37F 86 4A stx zchain
|
|
124 C381 85 4B sta zchain+1
|
|
125
|
|
126 ;check if the handler size is zero
|
|
127 C383 A0 10 ldy #$10
|
|
128 C385 B1 4A lda (zchain),y
|
|
129 C387 C8 iny
|
|
130 C388 11 4A ora (zchain),y
|
|
131 C38A F0 02 beq size_ok
|
|
132
|
|
133 ;whoops... we can't remove this handler.
|
|
134 C38C epic_fail:
|
|
135 C38C 38 sec
|
|
136 C38D 60 rts
|
|
137
|
|
138 C38E size_ok:
|
|
139 ;unlink the handler
|
|
140 C38E A0 12 ldy #$12
|
|
141 C390 B1 4A lda (zchain),y ;load low byte
|
|
142 C392 AA tax ;stash it
|
|
143 C393 C8 iny
|
|
144 C394 B1 4A lda (zchain),y ;load high byte
|
|
145 C396 91 36 sta (ltemp),y ;prev->link_hi = next->link_hi
|
|
146 C398 88 dey
|
|
147 C399 8A txa
|
|
148 C39A 91 36 sta (ltemp),y ;prev->link_lo = next->link_lo
|
|
149
|
|
150 ;all done
|
|
151 C39C 18 clc
|
|
152 C39D 60 rts
|
|
153 .endp
|
|
154
|
|
155
|
|
156 ;==========================================================================
|
|
157 ; Init peripheral handler.
|
|
158 ;
|
|
159 ; Entry:
|
|
160 ; A:Y Address of handler table
|
|
161 ; C Set if MEMLO should be adjusted, cleared otherwise
|
|
162 ;
|
|
163 ; Exit:
|
|
164 ; C Cleared on success, set on failure
|
|
165 ;
|
|
166 ; Modified:
|
|
167 ; DVSTAT+2, DVSTAT+3
|
|
168 ;
|
|
169 ; See also: Sweet 16 OS Supplement part 3, Handler Loader
|
|
170 ;
|
|
171 C39E .proc PHInitHandler
|
|
172 ;save off the table pointer; we use DVSTAT+2/3 per the Sweet16 spec
|
|
173 C39E 8C EC 02 sty dvstat+2
|
|
174 C3A1 8D ED 02 sta dvstat+3
|
|
175
|
|
176 ;save off MEMLO adjust flag
|
|
177 C3A4 08 php
|
|
178
|
|
179 ;move chain to zero page pointer
|
|
180 C3A5 A2 E9 ldx #<(chlink-$12)
|
|
181 C3A7 A9 03 lda #>(chlink-$11)
|
|
182
|
|
183 ;find zero link
|
|
184 C3A9 end_search_loop:
|
|
185 ;move to next link
|
|
186 C3A9 86 4A stx zchain
|
|
187 C3AB 85 4B sta zchain+1
|
|
188
|
|
189 ;load low byte
|
|
190 C3AD A0 12 ldy #$12
|
|
191 C3AF B1 4A lda (zchain),y
|
|
192 C3B1 AA tax
|
|
193 C3B2 C8 iny
|
|
194
|
|
195 ;load high byte and check if it is zero
|
|
196 C3B3 B1 4A lda (zchain),y
|
|
197 C3B5 D0 F2 bne end_search_loop
|
|
198
|
|
199 ;check if low byte is zero too
|
|
200 C3B7 E0 00 cpx #0
|
|
201 C3B9 D0 EE bne end_search_loop
|
|
202
|
|
203 ;alright, we've found the end of the chain -- link in the table
|
|
204 C3BB AD ED 02 lda dvstat+3
|
|
205 C3BE 91 4A sta (zchain),y
|
|
206 C3C0 AA tax
|
|
207 C3C1 88 dey
|
|
208 C3C2 AD EC 02 lda dvstat+2
|
|
209 C3C5 91 4A sta (zchain),y
|
|
210
|
|
211 ;switch to the new link
|
|
212 C3C7 86 4B stx zchain+1
|
|
213 C3C9 85 4A sta zchain
|
|
214
|
|
215 ;zero the forward pointer
|
|
216 C3CB A0 13 ldy #$13
|
|
217 C3CD A9 00 lda #0
|
|
218 C3CF 91 4A sta (zchain),y
|
|
219 C3D1 88 dey
|
|
220 C3D2 91 4A sta (zchain),y
|
|
221
|
|
222 ;jump to handler init
|
|
223 C3D4 20 20 C4 jsr PHCallHandlerInit
|
|
224 C3D7 90 0A bcc init_ok
|
|
225
|
|
226 ;remove handler and return with error (C=1)
|
|
227 C3D9 A5 4A lda zchain
|
|
228 C3DB A4 4B ldy zchain+1
|
|
229 C3DD 20 58 C3 jsr PHRemoveHandler
|
|
230 C3E0 28 plp
|
|
231 C3E1 38 sec
|
|
232 C3E2 60 rts
|
|
233
|
|
234 C3E3 init_ok:
|
|
235 ;retrieve the MEMLO adjust flag
|
|
236 C3E3 28 plp
|
|
237
|
|
238 ;zero out the handler size if we aren't adjusting MEMLO
|
|
239 C3E4 B0 0A bcs adjust_memlo
|
|
240
|
|
241 C3E6 A0 10 ldy #$10
|
|
242 C3E8 A9 00 lda #0
|
|
243 C3EA AA tax
|
|
244 C3EB 91 4A sta (zchain),y
|
|
245 C3ED C8 iny
|
|
246 C3EE 91 4A sta (zchain),y
|
|
247
|
|
248 C3F0 adjust_memlo:
|
|
249 C3F0 20 09 C4 jsr PHAdjustMemlo
|
|
250
|
|
251 ;zero checksum
|
|
252 C3F3 A0 0F ldy #$0f
|
|
253 C3F5 A9 00 lda #0
|
|
254 C3F7 91 4A sta (zchain),y
|
|
255
|
|
256 ;compute checksum
|
|
257 C3F9 A0 11 ldy #$11
|
|
258 C3FB 18 clc
|
|
259 C3FC checksum_loop:
|
|
260 C3FC 71 4A adc (zchain),y
|
|
261 C3FE 88 dey
|
|
262 C3FF 10 FB bpl checksum_loop
|
|
263 C401 69 00 adc #0
|
|
264
|
|
265 ;store checksum
|
|
266 C403 A0 0F ldy #$0f
|
|
267 C405 91 4A sta (zchain),y
|
|
268
|
|
269 ;all done - return success
|
|
270 C407 18 clc
|
|
271 C408 60 rts
|
|
272 .endp
|
|
273
|
|
274 ;==========================================================================
|
|
275 C409 .proc PHAdjustMemlo
|
|
276 ;load handler size
|
|
277 C409 A0 11 ldy #$11
|
|
278 C40B B1 4A lda (zchain),y
|
|
279 C40D AA tax
|
|
280 C40E 88 dey
|
|
281 C40F B1 4A lda (zchain),y
|
|
282
|
|
283 ;adjust MEMLO by handler size
|
|
284 C411 18 clc
|
|
285 C412 6D E7 02 adc memlo
|
|
286 C415 8D E7 02 sta memlo
|
|
287 C418 8A txa
|
|
288 C419 6D E8 02 adc memlo+1
|
|
289 C41C 8D E8 02 sta memlo+1
|
|
290 C41F 60 rts
|
|
291 .endp
|
|
292
|
|
293 ;==========================================================================
|
|
294 ; Initializes a single handler pointed to by ZCHAIN.
|
|
295 ;
|
|
296 C420 .proc PHCallHandlerInit
|
|
297 C420 A5 4A lda zchain
|
|
298 C422 18 clc
|
|
299 C423 69 0B adc #$0b
|
|
300 C425 AA tax
|
|
301 C426 A5 4B lda zchain+1
|
|
302 C428 69 00 adc #0
|
|
303 C42A 48 pha
|
|
304 C42B 8A txa
|
|
305 C42C 48 pha
|
|
306 C42D 60 rts
|
|
307 .endp
|
|
308
|
|
309 ;==========================================================================
|
|
310 ; Reinitialize all handlers in the handler chain.
|
|
311 ;
|
|
312 C42E .proc PHReinitHandlers
|
|
313 ;move chain to zero page pointer
|
|
314 C42E AE FB 03 ldx chlink
|
|
315 C431 AD FC 03 lda chlink+1
|
|
316
|
|
317 ;find zero link
|
|
318 C434 init_loop:
|
|
319 ;move to next link
|
|
320 C434 86 4A stx zchain
|
|
321 C436 85 4B sta zchain+1
|
|
322 C438 05 4A ora zchain
|
|
323 C43A F0 2D beq init_done
|
|
324
|
|
325 ;recompute checksum (except for checksum byte)
|
|
326 C43C A0 11 ldy #$11
|
|
327 C43E 18 clc
|
|
328 C43F B1 4A 88 lda (zchain),y-
|
|
329 C442 71 4A 88 adc (zchain),y-
|
|
330 C445 88 dey
|
|
331 C446 71 4A 88 10 FB adc:rpl (zchain),y-
|
|
332 C44B 69 00 adc #0
|
|
333
|
|
334 ;check if the checksum matches
|
|
335 C44D A0 0F ldy #$0f
|
|
336 C44F D1 4A cmp (zchain),y
|
|
337 C451 D0 16 bne init_done
|
|
338
|
|
339 ;reinitialize the handler
|
|
340 C453 20 20 C4 jsr PHCallHandlerInit
|
|
341 C456 B0 11 bcs init_done
|
|
342
|
|
343 ;adjust MEMLO
|
|
344 C458 20 09 C4 jsr PHAdjustMemlo
|
|
345
|
|
346 ;check for a next link
|
|
347 C45B A0 13 ldy #$13
|
|
348 C45D B1 4A lda (zchain),y
|
|
349 C45F AA tax
|
|
350 C460 C8 iny
|
|
351 C461 B1 4A lda (zchain),y
|
|
352 C463 D0 CF bne init_loop
|
|
353
|
|
354 ;load high byte and check if it is zero
|
|
355 C465 E0 00 cpx #0
|
|
356 C467 D0 CB bne init_loop
|
|
357
|
|
358 C469 init_done:
|
|
359 C469 60 rts
|
|
360 .endp
|
|
361
|
|
362 ;==========================================================================
|
|
363 ; Startup poll for peripheral handlers.
|
|
364 ;
|
|
365 ; The protocol for initing handlers from the SIO bus is as follows:
|
|
366 ;
|
|
367 ; 1. Issue type 3 poll reset (4F/40/4F/4F).
|
|
368 ; 2. Issue type 3 poll (4F/40/00/00), reading 4 bytes.
|
|
369 ; 2a. If this poll fails with a timeout, we're done.
|
|
370 ; 2b. If the poll fails for any other reason, issue a type 3 null poll
|
|
371 ; (4F/40/4E/4E) and go back to step 2.
|
|
372 ; 3. Compare the size in DVSTAT+0/1 against the amount of memory between
|
|
373 ; MEMTOP and MEMLO. If there isn't enough, issue a type 3 null poll
|
|
374 ; and go to step 2.
|
|
375 ; 4. Call the relocating loader to load the handler. The handler is
|
|
376 ; loaded 128 bytes at a time using command $26 (&), AUX1=block, where
|
|
377 ; block 0 is the first block.
|
|
378 ; 5. Go back to step 2.
|
|
379 ;
|
|
380 C46A .proc PHStartupPoll
|
|
381 ;issue type 3 poll reset (address $4F, command $40, aux $4F4F, no data)
|
|
382 C46A A2 4F ldx #$4F
|
|
383 C46C 20 E4 C4 jsr do_simple_poll
|
|
384
|
|
385 ;issue type 3 poll (address $4F, command $40, aux $0000, read 4 bytes)
|
|
386 C46F poll_loop:
|
|
387 C46F A9 00 lda #$00
|
|
388 C471 8D 0A 03 sta daux1
|
|
389 C474 8D 0B 03 sta daux2
|
|
390 C477 8D 09 03 sta dbythi
|
|
391 C47A A9 EA 8D 04 03 A9 + mwa #dvstat dbuflo
|
|
392 C484 A9 04 8D 08 03 mva #4 dbytlo
|
|
393 C489 A9 40 8D 03 03 mva #$40 dstats
|
|
394 C48E 20 59 E4 jsr siov
|
|
395 C491 10 11 bpl poll_ok
|
|
396 C493 C0 8A cpy #SIOErrorTimeout
|
|
397 C495 D0 01 bne poll_fail
|
|
398 C497 exit:
|
|
399 C497 60 rts
|
|
400 C498 poll_fail:
|
|
401 ;!! - Black Box 2.16 firmware intercepts type 3 polls and forces
|
|
402 ;a user abort error (Y=$80), which we must exit on to avoid an infinite
|
|
403 ;loop.
|
|
404 C498 C0 80 cpy #$80
|
|
405 C49A F0 FB beq exit
|
|
406
|
|
407 ;we had a failure -- issue a null poll before trying another device
|
|
408 C49C A2 4E ldx #$4e
|
|
409 C49E 20 E4 C4 jsr do_simple_poll
|
|
410 C4A1 4C 6F C4 jmp poll_loop
|
|
411
|
|
412 C4A4 poll_ok:
|
|
413 ;DVSTAT now contains the following frame:
|
|
414 ;
|
|
415 ; DVSTAT+0 handler size, low byte (should be even)
|
|
416 ; DVSTAT+1 handler size, high byte
|
|
417 ; DVSTAT+2 device address
|
|
418 ; DVSTAT+3 peripheral revision number
|
|
419
|
|
420 ;Check whether we have enough room between MEMLO and MEMTOP to load
|
|
421 ;this handler -- remember that MEMTOP is inclusive. Also, we need to
|
|
422 ;alloc an additional byte if MEMLO is odd.
|
|
423 C4A4 AD E7 02 lda memlo
|
|
424 C4A7 AA tax
|
|
425 C4A8 6A ror
|
|
426 C4A9 8A txa
|
|
427 C4AA 6D EA 02 adc dvstat
|
|
428 C4AD AA tax
|
|
429 C4AE AD E8 02 lda memlo+1
|
|
430 C4B1 6D EB 02 adc dvstat+1
|
|
431 C4B4 CD E6 02 cmp memtop+1
|
|
432 C4B7 90 09 bcc mem_ok
|
|
433 C4B9 D0 DD bne poll_fail
|
|
434 C4BB EC E5 02 cpx memtop
|
|
435 C4BE B0 02 bcs mem_ok
|
|
436 C4C0 D0 D6 bne poll_fail
|
|
437 C4C2 mem_ok:
|
|
438
|
|
439 ;set up for handler load
|
|
440 C4C2 AD E7 02 lda memlo
|
|
441 C4C5 AA tax
|
|
442 C4C6 6A ror
|
|
443 C4C7 8A txa
|
|
444 C4C8 69 00 adc #0
|
|
445 C4CA 8D D1 02 sta loadad
|
|
446 C4CD AD E8 02 lda memlo+1
|
|
447 C4D0 69 00 adc #0
|
|
448 C4D2 8D D2 02 sta loadad+1
|
|
449
|
|
450 C4D5 AD EC 02 8D 00 03 mva dvstat+2 ddevic
|
|
451
|
|
452 C4DB 38 sec
|
|
453 C4DC 20 01 C5 jsr PHLoadHandler
|
|
454 C4DF B0 B7 bcs poll_fail
|
|
455
|
|
456 ;look for another device
|
|
457 C4E1 4C 6F C4 jmp poll_loop
|
|
458
|
|
459 ;--------------------------------------------------------------------------
|
|
460 C4E4 do_simple_poll:
|
|
461 C4E4 A9 4F lda #$4f
|
|
462 C4E6 8D 00 03 sta ddevic
|
|
463 C4E9 8E 0A 03 stx daux1
|
|
464 C4EC 8E 0B 03 stx daux2
|
|
465 C4EF A9 40 lda #$40
|
|
466 C4F1 8D 02 03 sta dcomnd
|
|
467 C4F4 A9 01 lda #$01
|
|
468 C4F6 8D 01 03 sta dunit
|
|
469 C4F9 A9 00 lda #$00
|
|
470 C4FB 8D 03 03 sta dstats
|
|
471 C4FE 4C 59 E4 jmp siov
|
|
472
|
|
473 .endp
|
|
474
|
|
475 ;==========================================================================
|
|
476 ; Load peripheral handler over the SIO bus.
|
|
477 ;
|
|
478 ; Entry:
|
|
479 ; C Set to adjust MEMLO, clear to not
|
|
480 ; DDEVIC SIO address to load for loading
|
|
481 ; LOADAD Handler load address
|
|
482 ;
|
|
483 ; Modified:
|
|
484 ; All relocatable handler variables
|
|
485 ; DCB
|
|
486 ; DVSTAT
|
|
487 ;
|
|
488 C501 .proc PHLoadHandler
|
|
489 ;save MEMLO adjustment flag
|
|
490 C501 08 php
|
|
491
|
|
492 ;set zero-page relocation destination to $80 (should never be used)
|
|
493 C502 A9 80 8D D3 02 mva #$80 zloada
|
|
494
|
|
495 ;set up relocator get byte handler
|
|
496 C507 A9 40 8D CF 02 A9 + mwa #PHGetByte gbytea
|
|
497
|
|
498 ;set up for get byte, using command $26 and the cassette buffer
|
|
499 C511 A9 26 8D 02 03 mva #$26 dcomnd
|
|
500 C516 A2 00 8E 0A 03 mvx #0 daux1
|
|
501 C51B 8E 09 03 stx dbythi
|
|
502 C51E 8E 04 03 stx dbuflo
|
|
503 C521 CA dex
|
|
504 C522 86 3D stx bptr
|
|
505 C524 A9 04 8D 05 03 mva #$04 dbufhi
|
|
506 C529 A9 80 8D 08 03 mva #$80 dbytlo
|
|
507
|
|
508 ;load the handler
|
|
509 C52E 20 5A C5 jsr PHRelocateHandler
|
|
510 C531 B0 0B bcs reloc_fail
|
|
511
|
|
512 ;try to init handler, adjusting MEMLO as necessary
|
|
513 C533 AC D1 02 ldy loadad
|
|
514 C536 AD D2 02 lda loadad+1
|
|
515 C539 28 plp
|
|
516 C53A 20 9E C3 jsr PHInitHandler
|
|
517 C53D failed:
|
|
518 C53D 60 rts
|
|
519 C53E reloc_fail:
|
|
520 C53E 68 pla
|
|
521 C53F 60 rts
|
|
522 .endp
|
|
523
|
|
524 ;==========================================================================
|
|
525 ; Get byte handler used with relocating loader when loading handlers over
|
|
526 ; the SIO bus.
|
|
527 ;
|
|
528 C540 .proc PHGetByte
|
|
529 ;try to grab a byte
|
|
530 C540 A6 3D ldx bptr
|
|
531 C542 10 0C bpl fetch
|
|
532
|
|
533 ;issue SIO call to fetch next block
|
|
534 C544 A9 40 8D 03 03 mva #$40 dstats
|
|
535 C549 20 59 E4 jsr siov
|
|
536 C54C 30 0A bmi get_byte_fail
|
|
537 C54E A2 00 ldx #0
|
|
538
|
|
539 C550 fetch:
|
|
540 ;read next byte from cassette buffer
|
|
541 C550 BD 00 04 lda $0400,x
|
|
542 C553 E8 inx
|
|
543 C554 86 3D stx bptr
|
|
544
|
|
545 ;all clear
|
|
546 C556 18 clc
|
|
547 C557 60 rts
|
|
548
|
|
549 C558 get_byte_fail:
|
|
550 C558 38 sec
|
|
551 C559 60 rts
|
|
552
|
|
553 .endp
|
|
554
|
|
555 ;==========================================================================
|
|
556 ; Relocating loader.
|
|
557 ;
|
|
558 ; Modified:
|
|
559 ; LTEMP (word)
|
|
560 ; LCOUNT
|
|
561 ; RELADR
|
|
562 ; RECLEN
|
|
563 ; HIBYTE
|
|
564 ; RUNADR (word)
|
|
565 ; HIUSED (word)
|
|
566 ; ZHIUSE
|
|
567 ;
|
|
568 ; Record types:
|
|
569 ; Non-zp text $00 len { offset-lo offset-hi data* }
|
|
570 ; Zero-page text $01 len { offset-lo offset-hi data* }
|
|
571 ; Non-zp <ref to non-zp $02 len { offset* }
|
|
572 ; Zp <ref to non-zp $03 len { offset* }
|
|
573 ; Non-zp ref to zp $04 len { offset* }
|
|
574 ; Zp ref to zp $05 len { offset* }
|
|
575 ; Non-zp ref to non-zp $06 len { offset* }
|
|
576 ; Zp ref to non-zp $07 len { offset* }
|
|
577 ; Non-zp >ref to non-zp $08 len { {offset lo-byte}* }
|
|
578 ; Zp >ref to non-zp $09 len { {offset lo-byte}* }
|
|
579 ; Absolute text $0A len { addr-lo addr-hi data* }
|
|
580 ; End record $0B self-start addr-lo addr-hi
|
|
581 ;
|
|
582 ; The references need some explanation:
|
|
583 ; - The program is split into two sections, a zero-page section and a
|
|
584 ; non-zero page section. The two sections are each contiguous.
|
|
585 ; - Both the zero-page and non-zero-page sections can reference each
|
|
586 ; other.
|
|
587 ; - Low-byte references include only the low byte of an address.
|
|
588 ; - High-byte references include only the high byte of an address. A
|
|
589 ; low byte offset is included in the relocation to enable this.
|
|
590 ; - Relocation records are always applied to the last text record
|
|
591 ; that was loaded.
|
|
592 ;
|
|
593 C55A .proc PHRelocateHandler
|
|
594 ;make the zero-page load address 16-bit
|
|
595 C55A A9 00 lda #0
|
|
596 C55C 8D D4 02 sta zloada+1
|
|
597
|
|
598 C55F reloc_loop:
|
|
599 ;get a control byte and stash it
|
|
600 C55F 20 58 C6 jsr PHRelocateGetByte
|
|
601 C562 8D 33 02 sta lcount
|
|
602
|
|
603 ;get the length or self-start byte
|
|
604 C565 20 58 C6 jsr PHRelocateGetByte
|
|
605 C568 8D 45 02 sta reclen
|
|
606
|
|
607 ;dispatch to handler
|
|
608 C56B 20 71 C5 jsr dispatch
|
|
609
|
|
610 ;process more records
|
|
611 C56E 4C 5F C5 jmp reloc_loop
|
|
612
|
|
613 C571 dispatch:
|
|
614 C571 AE 33 02 ldx lcount
|
|
615 C574 BC 80 C5 ldy cmd_table_ind_tab,x
|
|
616 C577 B9 90 C5 lda cmd_table_hi,y
|
|
617 C57A 48 pha
|
|
618 C57B B9 8C C5 lda cmd_table_lo,y
|
|
619 C57E 48 pha
|
|
620 C57F 60 rts
|
|
621
|
|
622 ;---------------------------------------------------------
|
|
623 C580 cmd_table_ind_tab:
|
|
624 C580 00 00 01 01 01 01 + dta 0,0,1,1,1,1,1,1,2,2,0,3
|
|
625
|
|
626 C58C cmd_table_lo:
|
|
627 C58C 93 dta <(PHRelocateLoadText-1)
|
|
628 C58D D0 dta <(PHRelocateApplyFixups-1)
|
|
629 C58E 01 dta <(PHRelocateApplyHiFixups-1)
|
|
630 C58F 1F dta <(PHRelocateEnd-1)
|
|
631
|
|
632 C590 cmd_table_hi:
|
|
633 C590 C5 dta >(PHRelocateLoadText-1)
|
|
634 C591 C5 dta >(PHRelocateApplyFixups-1)
|
|
635 C592 C6 dta >(PHRelocateApplyHiFixups-1)
|
|
636 C593 C6 dta >(PHRelocateEnd-1)
|
|
637 .endp
|
|
638
|
|
639 ;==========================================================================
|
|
640 C594 .proc PHRelocateLoadText
|
|
641 ;retrieve the address into LTEMP
|
|
642 C594 20 58 C6 jsr PHRelocateGetByte
|
|
643 C597 85 36 sta ltemp
|
|
644 C599 20 58 C6 jsr PHRelocateGetByte
|
|
645 C59C 85 37 sta ltemp+1
|
|
646
|
|
647 ;check if we are doing an absolute load ($0A)
|
|
648 C59E AD 33 02 lda lcount
|
|
649 C5A1 C9 0A cmp #$0a
|
|
650 C5A3 F0 11 beq is_absolute
|
|
651
|
|
652 ;check whether we should use zero-page ($01) or non-zero-page ($00),
|
|
653 ;and adjust LTEMP
|
|
654 C5A5 0A asl
|
|
655 C5A6 AA tax
|
|
656 C5A7 18 BD D1 02 65 36 + adw loadad,x ltemp ltemp
|
|
657
|
|
658 C5B6 is_absolute:
|
|
659 ;init counter
|
|
660 C5B6 A9 00 lda #0
|
|
661 C5B8 8D 33 02 sta lcount
|
|
662
|
|
663 ;load reclen-2 bytes
|
|
664 C5BB CE 45 02 dec reclen
|
|
665 C5BE D0 0B bne load_loop_start
|
|
666
|
|
667 C5C0 load_loop:
|
|
668 C5C0 20 58 C6 jsr PHRelocateGetByte
|
|
669 C5C3 AC 33 02 ldy lcount
|
|
670 C5C6 EE 33 02 inc lcount
|
|
671 C5C9 91 36 sta (ltemp),y
|
|
672 C5CB load_loop_start:
|
|
673 C5CB CE 45 02 dec reclen
|
|
674 C5CE D0 F0 bne load_loop
|
|
675 C5D0 60 rts
|
|
676 .endp
|
|
677
|
|
678 ;==========================================================================
|
|
679 C5D1 .proc PHRelocateApplyFixups
|
|
680 ;get command byte and copy the appropriate reloc target into zchain
|
|
681 C5D1 AD 33 02 lda lcount
|
|
682 C5D4 4A lsr
|
|
683 C5D5 AE D1 02 ldx loadad
|
|
684 C5D8 C9 02 cmp #2
|
|
685 C5DA D0 03 sne
|
|
686 C5DC AE D3 02 ldx zloada
|
|
687 C5DF 86 4A stx zchain
|
|
688
|
|
689 ;set flag if we are doing a word reloc (types $06, $07)
|
|
690 C5E1 C9 03 cmp #3
|
|
691 C5E3 66 4B ror zchain+1
|
|
692
|
|
693 C5E5 reloc_loop:
|
|
694 ;fetch offset byte
|
|
695 C5E5 20 58 C6 jsr PHRelocateGetByte
|
|
696 C5E8 A8 tay
|
|
697
|
|
698 ;fixup low byte
|
|
699 C5E9 B1 36 lda (ltemp),y
|
|
700 C5EB 18 clc
|
|
701 C5EC 65 4A adc zchain
|
|
702 C5EE 91 36 sta (ltemp),y
|
|
703
|
|
704 ;check if we're doing a high byte reloc
|
|
705 C5F0 24 4B bit zchain+1
|
|
706 C5F2 10 08 bpl low_byte_only
|
|
707
|
|
708 ;fixup high byte
|
|
709 C5F4 C8 iny
|
|
710 C5F5 B1 36 lda (ltemp),y
|
|
711 C5F7 6D D2 02 adc loadad+1
|
|
712 C5FA 91 36 sta (ltemp),y
|
|
713
|
|
714 C5FC low_byte_only:
|
|
715 ;loop back if there is more fixup data
|
|
716 C5FC CE 45 02 dec reclen
|
|
717 C5FF D0 E4 bne reloc_loop
|
|
718 C601 60 rts
|
|
719 .endp
|
|
720
|
|
721 ;==========================================================================
|
|
722 C602 .proc PHRelocateApplyHiFixups
|
|
723 C602 reloc_loop:
|
|
724 ;fetch offset byte
|
|
725 C602 20 58 C6 jsr PHRelocateGetByte
|
|
726 C605 85 4A sta zchain
|
|
727
|
|
728 ;fetch low fixup byte
|
|
729 C607 20 58 C6 jsr PHRelocateGetByte
|
|
730
|
|
731 ;add low byte to base
|
|
732 C60A 18 clc
|
|
733 C60B 6D D1 02 adc loadad
|
|
734
|
|
735 ;fixup high byte
|
|
736 C60E A4 4A ldy zchain
|
|
737 C610 AD D2 02 lda loadad+1
|
|
738 C613 71 36 adc (ltemp),y
|
|
739 C615 91 36 sta (ltemp),y
|
|
740
|
|
741 ;loop back if there is more fixup data
|
|
742 C617 CE 45 02 dec reclen
|
|
743 C61A CE 45 02 dec reclen
|
|
744 C61D D0 E3 bne reloc_loop
|
|
745 C61F 60 rts
|
|
746 .endp
|
|
747
|
|
748 ;==========================================================================
|
|
749 C620 .proc PHRelocateEnd
|
|
750 ;read in the address to RUNADR
|
|
751 C620 20 58 C6 jsr PHRelocateGetByte
|
|
752 C623 8D C9 02 sta runadr
|
|
753 C626 20 58 C6 jsr PHRelocateGetByte
|
|
754 C629 8D CA 02 sta runadr+1
|
|
755
|
|
756 ;check the self-start byte
|
|
757 C62C AE 33 02 ldx lcount
|
|
758 C62F D0 0E bne do_self_start
|
|
759
|
|
760 ;no self-start... zero the addr and exit
|
|
761 C631 A9 00 lda #0
|
|
762 C633 8D C9 02 sta runadr
|
|
763 C636 8D CA 02 sta runadr+1
|
|
764 C639 xit:
|
|
765 C639 18 clc
|
|
766 C63A 68 pla
|
|
767 C63B 68 pla
|
|
768 C63C A0 01 ldy #1
|
|
769 C63E 60 rts
|
|
770
|
|
771 C63F do_self_start:
|
|
772 ;check if we need to relocate the address... if it
|
|
773 ;is absolute ($01), we're done
|
|
774 C63F CA dex
|
|
775 C640 F0 F7 beq xit
|
|
776
|
|
777 ;add the non-zp base address and exit
|
|
778 C642 18 AD C9 02 6D D1 + adw runadr loadad runadr
|
|
779 C655 4C 39 C6 jmp xit
|
|
780 .endp
|
|
781
|
|
782 ;==========================================================================
|
|
783 C658 .proc PHRelocateGetByte
|
|
784 C658 20 60 C6 jsr call_get_byte
|
|
785 C65B 90 02 bcc get_byte_ok
|
|
786 C65D 68 pla
|
|
787 C65E 68 pla
|
|
788 C65F get_byte_ok:
|
|
789 C65F 60 rts
|
|
790
|
|
791 C660 call_get_byte:
|
|
792 C660 6C CF 02 jmp (gbytea)
|
|
793 .endp
|
|
83 C663 _KERNEL_REPORT_MODULE_SIZE 'Peripheral Handler routines', 0
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', 0, ')', ' ', 'Peripheral Handler routines'
|
|
1 $C663 -> $0341($0000) Peripheral Handler routines
|
|
3 = C663 .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
84
|
|
85 .ifdef _KERNEL_816
|
|
86 icl 'syscall816.s'
|
|
87 icl 'sysdev816.s'
|
|
88 .endif
|
|
89
|
|
90 C663 org $cc00
|
|
91 CC00 icl 'atariifont.inc'
|
|
Source: source/Shared/atariifont.inc
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Character Font
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 CC00 00 00 00 00 00 00 + ins 'atariifont.bin',$0,$400
|
|
92
|
|
93 D000 org $d000
|
|
94 D000 icl 'bootscreen.s'
|
|
Source: source/Shared/bootscreen.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Boot Screen
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
37 opt l+
|
|
38
|
|
39 009B org $5000,$d000
|
|
40 opt o+f+
|
|
41
|
|
42 5000 .proc BootScreen
|
|
43 D000 18 clc
|
|
44 5001 24 dta {bit $00}
|
|
45 5002 boot_entry:
|
|
46 5002 38 sec
|
|
47 5003 08 php
|
|
48
|
|
49 5004 20 6C 52 jsr BootClearRam
|
|
50
|
|
51 5007 28 plp
|
|
52 5008 66 80 ror canboot
|
|
53
|
|
54 ;relocate data down to RAM
|
|
55 500A A9 D0 85 8A A9 56 + mwa #[.adr BootRamDataStart]+$5000-$D000 scrnad1
|
|
56 5012 A9 00 85 8C A9 30 + mwa #BootRamDataStart scrnad2
|
|
57
|
|
58 .if >[BootRamDataEnd-BootRamDataStart]
|
|
59 ldx #>[BootRamDataEnd-BootRamDataStart]
|
|
60 ldy #0
|
|
61 page_copy:
|
|
62 mva:rne (scrnad1),y (scrnad2),y+
|
|
63 inc scrnad1+1
|
|
64 inc scrnad2+1
|
|
65 dex
|
|
66 bne page_copy
|
|
67 .endif
|
|
68
|
|
69 .if <[BootRamDataEnd-BootRamDataStart]
|
|
70 501A byte_copy:
|
|
71 501A B1 8A 91 8C C8 mva (scrnad1),y (scrnad2),y+
|
|
72 501F C0 7A cpy #<[BootRamDataEnd-BootRamDataStart]
|
|
73 5021 D0 F7 bne byte_copy
|
|
74 .endif
|
|
75
|
|
76 ;copy down bitmap graphics
|
|
77 5023 A9 13 85 8C A9 32 + mwa #playfield3+19 scrnad2
|
|
78 502B A9 C8 85 8A A9 54 + mwa #BootDriveImage scrnad1
|
|
79 5033 A2 28 ldx #40
|
|
80 5035 blit_loop:
|
|
81 5035 A0 0C ldy #12
|
|
82 5037 B1 8A 91 8C 88 10 + mva:rpl (scrnad1),y (scrnad2),y-
|
|
83 503E 18 clc
|
|
84 503F A5 8C lda scrnad2
|
|
85 5041 69 20 adc #$20
|
|
86 5043 85 8C sta scrnad2
|
|
87 5045 90 02 E6 8D scc:inc scrnad2+1
|
|
88 5049 A5 8A lda scrnad1
|
|
89 504B 18 clc
|
|
90 504C 69 0D adc #13
|
|
91 504E 85 8A sta scrnad1
|
|
92 5050 90 02 E6 8B scc:inc scrnad1+1
|
|
93 5054 CA dex
|
|
94 5055 D0 DE bne blit_loop
|
|
95
|
|
96 ;set up display and interrupts
|
|
97 5057 78 sei
|
|
98 5058 20 9D 54 jsr BootSwapVectors
|
|
99 505B A9 00 8D 0E D4 mva #0 nmien
|
|
100 5060 A9 C0 8D 0E D4 mva #$c0 nmien
|
|
101 5065 A9 2C 8D 07 D4 mva #>player0 pmbase
|
|
102
|
|
103 506A A2 0C ldx #$0c
|
|
104 506C BD 16 52 9D 00 D0 + mva:rpl gtia_data,x hposp0,x-
|
|
105
|
|
106 5075 A9 03 8D 1D D0 mva #$03 gractl
|
|
107 507A 58 cli
|
|
108
|
|
109 ;init sprites 0,1
|
|
110 507B A2 00 ldx #0
|
|
111 507D A0 20 ldy #32
|
|
112 507F sprinit:
|
|
113 507F BD 3F 54 99 00 2C mva spr0dat,x player0,y
|
|
114 5085 BD 47 54 99 00 2D + mva spr1dat,x player1,y+
|
|
115 508C 98 tya
|
|
116 508D 29 0F and #$0f
|
|
117 508F D0 EE bne sprinit
|
|
118 5091 E8 inx
|
|
119 5092 E0 08 cpx #8
|
|
120 5094 D0 E9 bne sprinit
|
|
121
|
|
122 5096 A9 00 lda #0
|
|
123 5098 85 88 sta char_x
|
|
124 509A 85 89 sta char_y
|
|
125
|
|
126 509C 85 8E sta msgadr
|
|
127 509E imloop:
|
|
128 509E A4 8E ldy msgadr
|
|
129 50A0 E6 8E inc msgadr
|
|
130 50A2 B9 D6 52 lda BootMessage,y
|
|
131 50A5 C9 FF cmp #$ff
|
|
132 50A7 F0 06 beq imdone
|
|
133 50A9 20 A9 53 jsr PlotChar
|
|
134 50AC 4C 9E 50 jmp imloop
|
|
135 50AF imdone:
|
|
136
|
|
137 50AF A9 00 lda #0
|
|
138 50B1 85 9A sta phase
|
|
139 50B3 loop1:
|
|
140 50B3 A2 00 ldx #0
|
|
141 50B5 8A txa
|
|
142 50B6 sprclr:
|
|
143 50B6 9D 00 2E sta player2,x
|
|
144 50B9 9D 00 2F sta player3,x
|
|
145 50BC CA dex
|
|
146 50BD D0 F7 bne sprclr
|
|
147
|
|
148 ;save off the current RTCLOK
|
|
149 50BF AD 0B D4 D0 FB lda:rne vcount
|
|
150 50C4 A2 02 ldx #2
|
|
151 50C6 B5 12 95 94 CA 10 + mva:rpl rtclok,x rtcsav,x-
|
|
152
|
|
153 ;clear the break key in case it was pressed to interrupt the last read
|
|
154 50CD 86 11 stx brkkey
|
|
155
|
|
156 ;issue status request to D1:
|
|
157 50CF A9 01 lda #1
|
|
158 50D1 8D 01 03 sta dunit
|
|
159 50D4 A9 53 8D 02 03 mva #$53 dcomnd
|
|
160 50D9 20 53 E4 jsr dskinv
|
|
161 50DC 30 21 bmi loop2
|
|
162
|
|
163 ;try to read sector #1 on D1:
|
|
164 50DE A9 52 8D 02 03 mva #$52 dcomnd
|
|
165 50E3 A9 00 8D 04 03 A9 + mwa #$0400 dbuflo
|
|
166 50ED A9 01 8D 0A 03 A9 + mwa #1 daux1
|
|
167 50F7 20 53 E4 jsr dskinv
|
|
168 50FA 30 03 bmi loop2
|
|
169 50FC 4C 23 52 jmp BootScreenExit
|
|
170 50FF loop2:
|
|
171 50FF A5 14 lda rtclok+2
|
|
172 5101 C5 14 F0 FC cmp:req rtclok+2
|
|
173 5105 A5 14 lda rtclok+2
|
|
174 5107 C5 14 F0 FC cmp:req rtclok+2
|
|
175
|
|
176 510B A6 9A ldx phase
|
|
177 510D BD 87 51 85 92 BD + mwa phasetab+1,x spricl
|
|
178
|
|
179 5117 BC 86 51 ldy phasetab,x
|
|
180 511A A9 00 lda #0
|
|
181 511C 85 90 sta spracl
|
|
182 511E 85 91 sta sprach
|
|
183 5120 clloop:
|
|
184 5120 99 00 2B sta missiles,y
|
|
185 5123 99 00 2E sta player2,y
|
|
186 5126 99 00 2F sta player3,y
|
|
187 5129 88 dey
|
|
188 512A 30 F4 bmi clloop
|
|
189
|
|
190 512C BC 86 51 ldy phasetab,x
|
|
191 512F A9 FF lda #$ff
|
|
192 5131 blitloop:
|
|
193 5131 A6 91 ldx sprach
|
|
194 5133 BD 4F 54 lda sprdat2,x
|
|
195 5136 99 00 2E sta player2,y
|
|
196 5139 BD 6F 54 lda sprdat3,x
|
|
197 513C 99 00 2F sta player3,y
|
|
198
|
|
199 513F C8 iny
|
|
200 5140 18 A5 90 65 92 85 + adw spracl spricl spracl
|
|
201 514D A5 91 lda sprach
|
|
202 514F C9 20 cmp #$20
|
|
203 5151 90 DE bcc blitloop
|
|
204 5153 A9 00 lda #0
|
|
205 5155 blitloop2:
|
|
206 5155 99 00 2B sta missiles,y
|
|
207 5158 99 00 2E sta player2,y
|
|
208 515B 99 00 2F sta player3,y
|
|
209 515E C8 iny
|
|
210 515F C0 40 cpy #$40
|
|
211 5161 D0 F2 bne blitloop2
|
|
212
|
|
213 ;if this is the first animation frame, wait a bit after it
|
|
214 5163 A5 9A lda phase
|
|
215 5165 D0 0C bne no_wait
|
|
216
|
|
217 5167 A2 19 ldx #25
|
|
218 5169 waitloop:
|
|
219 5169 A5 14 lda rtclok+2
|
|
220 516B C5 14 F0 FC cmp:req rtclok+2
|
|
221 516F CA dex
|
|
222 5170 D0 F7 bne waitloop
|
|
223 5172 8A txa
|
|
224
|
|
225 5173 no_wait:
|
|
226 5173 18 clc
|
|
227 5174 69 03 adc #3
|
|
228 5176 85 9A sta phase
|
|
229 5178 C9 90 cmp #phasetab_end-phasetab
|
|
230 517A B0 03 4C FF 50 scs:jmp loop2
|
|
231
|
|
232 517F A9 00 lda #0
|
|
233 5181 85 9A sta phase
|
|
234 5183 4C B3 50 jmp loop1
|
|
235
|
|
236 5186 phasetab:
|
|
237 5186 8A AA 00 89 AB 00 + :48 dta $7a+[48-#]/3, a([$200+#*#*3]/3)
|
|
238 5216 phasetab_end:
|
|
239
|
|
240 5216 gtia_data:
|
|
241 5216 40 60 A4 98 68 60 + dta $40,$60,$a4,$98,$68,$60,$00,$00
|
|
242 521E 03 03 00 03 0F dta $03,$03,$00,$03,$0f
|
|
243 .endp
|
|
244
|
|
245 ;==========================================================================
|
|
246 5223 .proc BootScreenExit
|
|
247 5223 78 sei
|
|
248 5224 A9 00 lda #0
|
|
249 5226 8D 0E D4 sta nmien
|
|
250
|
|
251 ;wait for vertical blank
|
|
252 5229 A2 7C ldx #248/2
|
|
253 522B EC 0B D4 D0 FB cpx:rne vcount
|
|
254
|
|
255 ;shut off display
|
|
256 5230 8D 00 D4 sta dmactl
|
|
257 5233 8D 2F 02 sta sdmctl
|
|
258
|
|
259 ;reset GTIA (but not VBXE)
|
|
260 5236 9D 00 D0 E8 10 FA sta:rpl $d000,x+
|
|
261
|
|
262 ;check if we can continue the initial boot process
|
|
263 523C 24 80 bit canboot
|
|
264 523E 30 03 bmi continue_boot
|
|
265
|
|
266 ;invoke cold start
|
|
267 5240 4C 77 E4 jmp coldsv
|
|
268
|
|
269 5243 continue_boot:
|
|
270 ;swap interrupt handler registers back
|
|
271 5243 20 9D 54 jsr BootSwapVectors
|
|
272
|
|
273 ;re-wipe RAM areas we used
|
|
274 5246 20 6C 52 jsr BootClearRam
|
|
275
|
|
276 ;re-enable IRQs (but VBI is still disabled)
|
|
277 5249 58 cli
|
|
278
|
|
279 ;print a clear screen character to clear any latent BOOT ERRORs
|
|
280 524A A9 7D lda #$7d
|
|
281 524C A2 00 ldx #0
|
|
282 524E 8E 48 03 stx icbll
|
|
283 5251 8E 49 03 stx icblh
|
|
284 5254 A0 0B ldy #CIOCmdPutChars
|
|
285 5256 8C 42 03 sty iccmd
|
|
286 5259 20 56 E4 jsr ciov
|
|
287
|
|
288 ;re-enable VBI and wait for VBI stage 2 to run once
|
|
289 525C A9 40 8D 0E D4 mva #$40 nmien
|
|
290
|
|
291 5261 A9 FF lda #$ff
|
|
292 5263 8D 83 02 sta ptrig7
|
|
293 5266 2C 83 02 30 FB bit:rmi ptrig7
|
|
294
|
|
295 ;all done, return to boot code with sector 1 loaded at $0400
|
|
296 526B 60 rts
|
|
297 .endp
|
|
298
|
|
299 ;==========================================================================
|
|
300 526C .proc BootClearRam
|
|
301 ;clear $2000-$37FF
|
|
302 526C A9 00 lda #0
|
|
303 526E A8 tay
|
|
304 526F 85 84 sta charadr
|
|
305 5271 A2 20 ldx #$20
|
|
306 5273 86 85 stx charadr+1
|
|
307 5275 A2 18 ldx #$18
|
|
308 5277 clear_loop:
|
|
309 5277 91 84 C8 D0 FB sta:rne (charadr),y+
|
|
310 527C E6 85 inc charadr+1
|
|
311 527E CA dex
|
|
312 527F D0 F6 bne clear_loop
|
|
313
|
|
314 ;clear user page zero
|
|
315 5281 95 80 E8 10 FB sta:rpl $80,x+
|
|
316
|
|
317 ;all done
|
|
318 5286 60 rts
|
|
319 .endp
|
|
320
|
|
321 ;==========================================================================
|
|
322 5287 .proc BootScreenVbi
|
|
323 5287 AD 4E 30 lda pfadr+1
|
|
324 528A 49 05 eor #$05
|
|
325 528C 8D 4E 30 sta pfadr+1
|
|
326 528F AD C5 02 lda color1
|
|
327 5292 8D 17 D0 sta colpf1
|
|
328 5295 AD C6 02 lda color2
|
|
329 5298 8D 18 D0 sta colpf2
|
|
330 529B 6C 00 30 jmp (BootVecVbi)
|
|
331 .endp
|
|
332
|
|
333 ;==========================================================================
|
|
334 529E .proc BootScreenIrq
|
|
335 529E 2C 0F D4 bit nmist
|
|
336 52A1 10 20 bpl do_irq
|
|
337 = 52A3 .def :BootScreenDli
|
|
338 52A3 48 pha
|
|
339 52A4 8A txa
|
|
340 52A5 48 pha
|
|
341 52A6 AD 0B D4 lda vcount
|
|
342 52A9 C9 48 cmp #72
|
|
343 52AB B0 19 bcs split
|
|
344 52AD 4A lsr
|
|
345 52AE 4A lsr
|
|
346 52AF AA tax
|
|
347 52B0 BD 8A 54 lda coltab-5,x
|
|
348 52B3 8D 0A D4 sta wsync
|
|
349 52B6 8D 12 D0 sta colpm0
|
|
350 52B9 8D 13 D0 sta colpm1
|
|
351 52BC xit:
|
|
352 52BC 8D 0F D4 sta nmires
|
|
353 52BF 68 pla
|
|
354 52C0 AA tax
|
|
355 52C1 68 pla
|
|
356 52C2 40 rti
|
|
357 52C3 do_irq:
|
|
358 52C3 6C 02 30 jmp (BootVecIrq)
|
|
359 52C6 split:
|
|
360 52C6 A9 50 lda #$50
|
|
361 52C8 A2 5C ldx #$5c
|
|
362 52CA 8D 0A D4 sta wsync
|
|
363 52CD 8D 18 D0 sta colpf2
|
|
364 52D0 8E 17 D0 stx colpf1
|
|
365
|
|
366 52D3 4C BC 52 jmp xit
|
|
367 .endp
|
|
368
|
|
369 ;==========================================================================
|
|
370 52D6 .local BootMessage
|
|
371 ; 0123456789012345678901234567890123456789012345678901234567890123
|
|
372 52D6 21 6C 74 69 72 72 + dta d"AltirraOS"
|
|
373 52DF _KERNELSTR_BIOS_NAME_INTERNAL
|
|
Macro: _KERNELSTR_BIOS_NAME_INTERNAL [Source: source/main.xasm]
|
|
4 52DF 00 66 6F 72 00 38 + dta d" for XL/XE/XEGS"
|
|
Source: source/Shared/bootscreen.s
|
|
374 52EE 00 dta d" "
|
|
375 52EF _KERNELSTR_VERSION_INTERNAL
|
|
Macro: _KERNELSTR_VERSION_INTERNAL [Source: source/Shared/version.inc]
|
|
1 52EF 13 0E 12 16 dta "3.26"
|
|
Source: source/Shared/bootscreen.s
|
|
376
|
|
377 52F3 9B dta $9b
|
|
378
|
|
379 .ifdef _KERNEL_816
|
|
380 dta d"Copyright (C) 2018-2019 Avery Lee",$9b
|
|
381 .else
|
|
382 52F4 23 6F 70 79 72 69 + dta d"Copyright (C) 2012-2019 Avery Lee",$9b
|
|
383 .endif
|
|
384
|
|
385 5316 21 6C 6C 00 32 69 + dta d"All Rights Reserved",$9b
|
|
386 532A 34 68 69 73 00 69 + dta d"This is a substitute for the standard OS ROM. See the help file",$9b
|
|
387 536A 66 6F 72 00 68 6F + dta d"for how to use real Atari ROM images for higher compatibility."
|
|
388 53A8 FF dta $ff
|
|
389 .endl
|
|
390
|
|
391 ;==========================================================================
|
|
392 53A9 plotchar:
|
|
393 53A9 C9 9B cmp #$9b
|
|
394 53AB D0 07 bne not_eol
|
|
395 53AD A9 00 85 88 mva #0 char_x
|
|
396 53B1 E6 89 inc char_y
|
|
397 53B3 60 rts
|
|
398 53B4 not_eol:
|
|
399 53B4 85 84 sta charadr
|
|
400
|
|
401 53B6 A9 00 lda #0
|
|
402 53B8 85 8A sta scrnad1
|
|
403 53BA 85 8C sta scrnad2
|
|
404 53BC A5 89 lda char_y
|
|
405 53BE 09 20 ora #>playfield
|
|
406 53C0 85 8B sta scrnad1+1
|
|
407 53C2 18 clc
|
|
408 53C3 69 05 adc #$05
|
|
409 53C5 85 8D sta scrnad2+1
|
|
410
|
|
411 53C7 A5 88 lda char_x
|
|
412 53C9 4A lsr
|
|
413 53CA 85 83 sta charpos
|
|
414 53CC 6A ror
|
|
415 53CD 85 87 sta charodd
|
|
416
|
|
417 53CF A9 1C lda #$e0/8
|
|
418 53D1 A2 03 ldx #3
|
|
419 53D3 shlloop:
|
|
420 53D3 06 84 asl charadr
|
|
421 53D5 2A rol
|
|
422 53D6 CA dex
|
|
423 53D7 D0 FA bne shlloop
|
|
424 53D9 85 85 sta charadr+1
|
|
425
|
|
426 53DB 18 clc
|
|
427 53DC rowloop:
|
|
428 53DC A2 04 ldx #4
|
|
429 53DE A0 00 ldy #0
|
|
430 53E0 B1 84 lda (charadr),y
|
|
431 53E2 4A lsr
|
|
432 53E3 bitloop:
|
|
433 53E3 4A lsr
|
|
434 53E4 66 81 ror chardt1
|
|
435 53E6 4A lsr
|
|
436 53E7 66 82 ror chardt2
|
|
437 53E9 CA dex
|
|
438 53EA D0 F7 bne bitloop
|
|
439
|
|
440 53EC A4 83 ldy charpos
|
|
441 53EE 24 87 bit charodd
|
|
442 53F0 30 12 bmi odd
|
|
443 53F2 A5 82 lda chardt2
|
|
444 53F4 51 8C eor (scrnad2),y
|
|
445 53F6 29 0F and #$0f
|
|
446 53F8 45 82 eor chardt2
|
|
447 53FA 91 8C sta (scrnad2),y
|
|
448
|
|
449 53FC A5 81 lda chardt1
|
|
450 53FE 51 8A eor (scrnad1),y
|
|
451 5400 29 0F and #$0f
|
|
452
|
|
453 5402 10 1E bpl even
|
|
454 5404 odd:
|
|
455 5404 A5 81 lda chardt1
|
|
456 5406 4A lsr
|
|
457 5407 4A lsr
|
|
458 5408 4A lsr
|
|
459 5409 4A lsr
|
|
460 540A 85 81 sta chardt1
|
|
461 540C A5 82 lda chardt2
|
|
462 540E 4A lsr
|
|
463 540F 4A lsr
|
|
464 5410 4A lsr
|
|
465 5411 4A lsr
|
|
466 5412 85 82 sta chardt2
|
|
467 5414 51 8C eor (scrnad2),y
|
|
468 5416 29 F0 and #$f0
|
|
469 5418 45 82 eor chardt2
|
|
470 541A 91 8C sta (scrnad2),y
|
|
471 541C A5 81 lda chardt1
|
|
472 541E 51 8A eor (scrnad1),y
|
|
473 5420 29 F0 and #$f0
|
|
474 5422 even:
|
|
475 5422 45 81 eor chardt1
|
|
476 5424 91 8A sta (scrnad1),y
|
|
477 5426 E6 84 inc charadr
|
|
478 5428 98 tya
|
|
479 5429 18 clc
|
|
480 542A 69 20 adc #$20
|
|
481 542C 85 83 sta charpos
|
|
482 542E 90 AC bcc rowloop
|
|
483
|
|
484 ;update position
|
|
485 5430 E6 88 inc char_x
|
|
486 5432 A6 88 ldx char_x
|
|
487 5434 E0 40 cpx #64
|
|
488 5436 90 06 bcc done
|
|
489 5438 A9 00 85 88 mva #0 char_x
|
|
490 543C E6 89 inc char_y
|
|
491 543E done:
|
|
492 543E 60 rts
|
|
493
|
|
494 ;==========================================================================
|
|
495 543F spr0dat:
|
|
496 543F 00 dta %00000000
|
|
497 5440 03 dta %00000011
|
|
498 5441 0F dta %00001111
|
|
499 5442 3C dta %00111100
|
|
500 5443 3C dta %00111100
|
|
501 5444 3F dta %00111111
|
|
502 5445 3C dta %00111100
|
|
503 5446 00 dta %00000000
|
|
504
|
|
505 5447 spr1dat:
|
|
506 5447 00 dta %00000000
|
|
507 5448 C0 dta %11000000
|
|
508 5449 F0 dta %11110000
|
|
509 544A 3C dta %00111100
|
|
510 544B 3C dta %00111100
|
|
511 544C FC dta %11111100
|
|
512 544D 3C dta %00111100
|
|
513 544E 00 dta %00000000
|
|
514
|
|
515 544F sprdat2:
|
|
516 544F 00 dta %00000000
|
|
517 5450 00 dta %00000000
|
|
518 5451 18 dta %00011000
|
|
519 5452 3C dta %00111100
|
|
520 5453 3C dta %00111100
|
|
521 5454 3C dta %00111100
|
|
522 5455 3C dta %00111100
|
|
523 5456 3C dta %00111100
|
|
524 5457 3C dta %00111100
|
|
525 5458 18 dta %00011000
|
|
526 5459 00 dta %00000000
|
|
527 545A 00 dta %00000000
|
|
528 545B E7 dta %11100111
|
|
529 545C 81 dta %10000001
|
|
530 545D 81 dta %10000001
|
|
531 545E 00 dta %00000000
|
|
532 545F 00 dta %00000000
|
|
533 5460 81 dta %10000001
|
|
534 5461 81 dta %10000001
|
|
535 5462 E7 dta %11100111
|
|
536 5463 00 dta %00000000
|
|
537 5464 00 dta %00000000
|
|
538 5465 00 dta %00000000
|
|
539 5466 00 dta %00000000
|
|
540 5467 00 dta %00000000
|
|
541 5468 00 dta %00000000
|
|
542 5469 00 dta %00000000
|
|
543 546A 00 dta %00000000
|
|
544 546B 00 dta %00000000
|
|
545 546C 00 dta %00000000
|
|
546 546D 00 dta %00000000
|
|
547 546E 00 dta %00000000
|
|
548
|
|
549 546F sprdat3:
|
|
550 546F FF dta %11111111
|
|
551 5470 FF dta %11111111
|
|
552 5471 FF dta %11111111
|
|
553 5472 FF dta %11111111
|
|
554 5473 FF dta %11111111
|
|
555 5474 FF dta %11111111
|
|
556 5475 FF dta %11111111
|
|
557 5476 FF dta %11111111
|
|
558 5477 FF dta %11111111
|
|
559 5478 FF dta %11111111
|
|
560 5479 FF dta %11111111
|
|
561 547A FF dta %11111111
|
|
562 547B E7 dta %11100111
|
|
563 547C E7 dta %11100111
|
|
564 547D E7 dta %11100111
|
|
565 547E E7 dta %11100111
|
|
566 547F E7 dta %11100111
|
|
567 5480 E7 dta %11100111
|
|
568 5481 E7 dta %11100111
|
|
569 5482 E7 dta %11100111
|
|
570 5483 FF dta %11111111
|
|
571 5484 FF dta %11111111
|
|
572 5485 FF dta %11111111
|
|
573 5486 FF dta %11111111
|
|
574 5487 FF dta %11111111
|
|
575 5488 FF dta %11111111
|
|
576 5489 7F dta %01111111
|
|
577 548A FF dta %11111111
|
|
578 548B FF dta %11111111
|
|
579 548C FF dta %11111111
|
|
580 548D FF dta %11111111
|
|
581 548E FF dta %11111111
|
|
582
|
|
583 ;==========================================================================
|
|
584
|
|
585 ;==========================================================================
|
|
586 548F coltab:
|
|
587 548F 1A dta $1a
|
|
588 5490 FA dta $fa
|
|
589 5491 EA dta $ea
|
|
590 5492 DA dta $da
|
|
591 5493 CA dta $ca
|
|
592 5494 BA dta $ba
|
|
593 5495 AA dta $aa
|
|
594 5496 9A dta $9a
|
|
595 5497 8A dta $8a
|
|
596 5498 7A dta $7a
|
|
597 5499 6A dta $6a
|
|
598 549A 5A dta $5a
|
|
599
|
|
600 549B 0E 50 dta $0E,$50
|
|
601
|
|
602 ;==========================================================================
|
|
603 549D .proc BootSwapVectors
|
|
604 549D A2 13 ldx #vec_offsets_end-vec_offsets-1
|
|
605 549F loop:
|
|
606 549F BC B4 54 ldy vec_offsets,x
|
|
607 54A2 B9 00 02 lda $0200,y
|
|
608 54A5 48 pha
|
|
609 54A6 BD 00 30 lda BootVectors,x
|
|
610 54A9 99 00 02 sta $0200,y
|
|
611 54AC 68 pla
|
|
612 54AD 9D 00 30 sta BootVectors,x
|
|
613 54B0 CA dex
|
|
614 54B1 10 EC bpl loop
|
|
615 54B3 60 rts
|
|
616
|
|
617 54B4 vec_offsets:
|
|
618 54B4 22 dta vvblki-$0200
|
|
619 54B5 23 dta vvblki-$0200+1
|
|
620 54B6 16 dta vimirq-$0200
|
|
621 54B7 17 dta vimirq-$0200+1
|
|
622 54B8 00 dta vdslst-$0200
|
|
623 54B9 01 dta vdslst-$0200+1
|
|
624 54BA 30 dta sdlstl-$0200
|
|
625 54BB 31 dta sdlsth-$0200
|
|
626 54BC C0 dta pcolr0-$0200
|
|
627 54BD C1 dta pcolr1-$0200
|
|
628 54BE C2 dta pcolr2-$0200
|
|
629 54BF C3 dta pcolr3-$0200
|
|
630 54C0 C4 dta color0-$0200
|
|
631 54C1 C5 dta color1-$0200
|
|
632 54C2 C6 dta color2-$0200
|
|
633 54C3 C7 dta color3-$0200
|
|
634 54C4 C8 dta color4-$0200
|
|
635 54C5 2F dta sdmctl-$0200
|
|
636 54C6 6F dta gprior-$0200
|
|
637 54C7 44 dta coldst-$0200
|
|
638 54C8 vec_offsets_end:
|
|
639 .endp
|
|
640
|
|
641 ;==========================================================================
|
|
642 54C8 .proc BootDriveImage
|
|
643 54C8 icl 'driveimage.inc'
|
|
Source: source/Shared/driveimage.inc
|
|
1 ;Made from driveimage.bmp using driveimageconv.cpp
|
|
2 54C8 00 00 00 0A AA AA + dta %00000000,%00000000,%00000000,%00001010,%10101010,%10101010,%10101010,%10101010,%10101010,%00000000,%00000000,%00000000,%00000000
|
|
3 54D5 02 AA AA AA AA AA + dta %00000010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101000,%00000000
|
|
4 54E2 0A AA AA AA AA AA + dta %00001010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%00000000
|
|
5 54EF 0A AA AA AA AA AA + dta %00001010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%00000000
|
|
6 54FC 0A AA AA AA AA AA + dta %00001010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%00000000
|
|
7 5509 0A 55 55 55 55 55 + dta %00001010,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01011010,%00000000
|
|
8 5516 2A 55 55 55 55 55 + dta %00101010,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01011010,%10000000
|
|
9 5523 29 55 55 55 55 55 + dta %00101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10000000
|
|
10 5530 29 55 55 55 55 55 + dta %00101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10000000
|
|
11 553D 29 55 55 55 55 55 + dta %00101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10000000
|
|
12 554A 29 55 55 55 55 55 + dta %00101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10000000
|
|
13 5557 A9 55 55 55 55 55 + dta %10101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10100000
|
|
14 5564 A9 55 55 55 55 55 + dta %10101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10100000
|
|
15 5571 A9 55 55 55 55 55 + dta %10101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10100000
|
|
16 557E A9 55 55 55 55 55 + dta %10101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10100000
|
|
17 558B A5 55 55 55 55 55 + dta %10100101,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010101,%10100000
|
|
18 5598 A5 55 55 55 55 55 + dta %10100101,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010101,%10100000
|
|
19 55A5 A5 55 57 FF FF FF + dta %10100101,%01010101,%01010111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11010101,%10100000
|
|
20 55B2 A5 55 57 FF FF FF + dta %10100101,%01010101,%01010111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11010101,%10100000
|
|
21 55BF A5 55 57 FF FF FF + dta %10100101,%01010101,%01010111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11010101,%10100000
|
|
22 55CC A5 55 55 55 55 55 + dta %10100101,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010101,%10100000
|
|
23 55D9 A5 55 55 55 55 55 + dta %10100101,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010101,%10100000
|
|
24 55E6 A5 55 55 55 55 55 + dta %10100101,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010101,%10100000
|
|
25 55F3 A9 55 55 55 55 55 + dta %10101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10100000
|
|
26 5600 A9 55 55 55 55 55 + dta %10101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10100000
|
|
27 560D A9 55 55 55 55 55 + dta %10101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10100000
|
|
28 561A A9 55 55 55 55 55 + dta %10101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10100000
|
|
29 5627 A9 55 55 55 55 55 + dta %10101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10100000
|
|
30 5634 A9 55 55 55 55 55 + dta %10101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10100000
|
|
31 5641 29 55 55 55 55 55 + dta %00101001,%01010101,%01010101,%01010101,%01010101,%01010101,%11111111,%11111111,%01010101,%01010101,%01010101,%01010110,%10000000
|
|
32 564E 29 55 55 55 55 55 + dta %00101001,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010110,%10000000
|
|
33 565B 29 55 55 55 55 55 + dta %00101001,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010110,%10000000
|
|
34 5668 29 55 55 55 55 55 + dta %00101001,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010110,%10000000
|
|
35 5675 2A 55 55 55 55 55 + dta %00101010,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01011010,%10000000
|
|
36 5682 0A 55 55 55 55 55 + dta %00001010,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01010101,%01011010,%00000000
|
|
37 568F 0A AA AA AA AA AA + dta %00001010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%00000000
|
|
38 569C 0A AA AA AA AA AA + dta %00001010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%00000000
|
|
39 56A9 0A AA AA AA AA AA + dta %00001010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%00000000
|
|
40 56B6 02 AA AA AA AA AA + dta %00000010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101010,%10101000,%00000000
|
|
41 56C3 00 00 00 0A AA AA + dta %00000000,%00000000,%00000000,%00001010,%10101010,%10101010,%10101010,%10101010,%10101010,%00000000,%00000000,%00000000,%00000000
|
|
644 .endp
|
|
645
|
|
646 ;==========================================================================
|
|
647 ; Data relocated to RAM
|
|
648 ;
|
|
649 56D0 org $3000,*-$5000+$d000
|
|
650
|
|
651 = 3000 BootRamDataStart = *
|
|
652
|
|
653 3000 BootVectors:
|
|
654 3000 87 52 BootVecVbi dta a(BootScreenVbi)
|
|
655 3002 9E 52 BootVecIrq dta a(BootScreenIrq)
|
|
656 3004 A3 52 BootVecDli dta a(BootScreenDli)
|
|
657 3006 14 30 BootVecDlist dta a(BootDlist)
|
|
658 3008 color_table:
|
|
659 3008 00 dta $00
|
|
660 3009 00 dta $00
|
|
661 300A 02 dta $02
|
|
662 300B 00 dta $00
|
|
663 300C 08 dta $08
|
|
664 300D 0C dta $0C
|
|
665 300E 02 dta $02
|
|
666 300F 14 dta $14
|
|
667 3010 50 dta $50
|
|
668 3011 3D dta $3d ;sdmctl
|
|
669 3012 01 dta $01 ;gprior
|
|
670 3013 FF dta $ff ;coldst, to force cold reboot if RESET pressed
|
|
671
|
|
672 3014 BootDlist:
|
|
673 3014 70 70 70 70 :4 dta $70
|
|
674 3018 F0 F0 F0 F0 F0 F0 + :8 dta $F0
|
|
675
|
|
676 ;drive image (40 lines x 32 bytes = $500 bytes
|
|
677 3020 4E 00 32 dta $4E,a(playfield3)
|
|
678 3023 0E 0E 0E 0E 0E 0E :6 dta $0E
|
|
679 3029 8E dta $8E
|
|
680 302A 0E 0E 0E 0E 0E 0E + :4 dta $0E,$0E,$0E,$0E,$0E,$0E,$0E,$8E
|
|
681
|
|
682 304A F0 dta $F0
|
|
683 304B 70 dta $70
|
|
684
|
|
685 ;80-col text screen (2x 40 rows)
|
|
686 304C 4F 00 20 dta $4F,a(playfield)
|
|
687 = 304D pfadr = *-2
|
|
688 304F 0F 0F 0F 0F 0F 0F + :7 dta $0F
|
|
689 3056 0F 0F 0F 0F 0F 0F + :8 dta $0F
|
|
690 305E 0F 0F 0F 0F 0F 0F + :8 dta $0F
|
|
691 3066 70 dta $70
|
|
692 3067 0F 0F 0F 0F 0F 0F + :8 dta $0F
|
|
693 306F 0F 0F 0F 0F 0F 0F + :8 dta $0F
|
|
694 3077 41 14 30 dta $41,a(BootDlist)
|
|
695
|
|
696 = 307A BootRamDataEnd = *
|
|
697
|
|
698 ;==========================================================================
|
|
699 ; Version block for emulator
|
|
700 ;
|
|
701 307A org $d7f8
|
|
702 D7F8 _KERNELSTR_VERSION
|
|
Macro: _KERNELSTR_VERSION [Source: source/Shared/version.inc]
|
|
1 D7F8 33 2E 32 36 dta '3.26'
|
|
Source: source/Shared/bootscreen.s
|
|
703 D7FC 00 dta 0
|
|
704
|
|
705
|
|
706 D7FD org $d7ff
|
|
707 D7FF 00 dta 0
|
|
708
|
|
729 opt l+
|
|
730 3200 org $d800
|
|
95
|
|
96 opt f+
|
|
97 .endif
|
|
98
|
|
99 D800 org $d800
|
|
100
|
|
101 D800 icl 'mathpack.s'
|
|
Source: source/Shared/mathpack.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Decimal Floating-Point Math Pack
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11 ;
|
|
12 ; Known problems:
|
|
13 ; Currently incompatible with BASIC XE due to it relying on $DE-DF not
|
|
14 ; being modified by FADD/FSUB.
|
|
15 ;
|
|
16 ;==========================================================================
|
|
17 ;
|
|
18 ; Notes
|
|
19 ;
|
|
20 ; AFP FMUL
|
|
21 ; |FASC.FDIV
|
|
22 ; |.IPF.|PLYEVL
|
|
23 ; |.|FPI|.EXP
|
|
24 ; |.|.FADD|REDRNG
|
|
25 ; |.|.|.|.|.LOG
|
|
26 ; vvvvvvvvvvv
|
|
27 ; $D4 FR0 M MMM.
|
|
28 ; $D5 | M MMM.
|
|
29 ; $D6 | M MMM.
|
|
30 ; $D7 | M MMM.
|
|
31 ; $D8 | M MMM.
|
|
32 ; $D9 v M MMM.
|
|
33 ; $DA FR2 {FRE} TTTTTTT.
|
|
34 ; $DB | TT TTTT.
|
|
35 ; $DC | TT TTTT.
|
|
36 ; $DD | TT TTTT.
|
|
37 ; $DE | T TTT. [1,2]
|
|
38 ; $DF v TTT. [1,2]
|
|
39 ; $E0 FR1 MM . [3]
|
|
40 ; $E1 | MM . [3]
|
|
41 ; $E2 | MM . [3]
|
|
42 ; $E3 | MM . [3]
|
|
43 ; $E4 | MM . [3]
|
|
44 ; $E5 v MM . [3]
|
|
45 ; $E6 FR3 {FR2} . .
|
|
46 ; $E7 . .
|
|
47 ; $E8 . .
|
|
48 ; $E9 . .
|
|
49 ; $EA . .
|
|
50 ; $EB . .
|
|
51 ; $EC {FRX} . .
|
|
52 ; $ED {EEXP} . .
|
|
53 ; $EE {NSIGN} . .
|
|
54 ; $EF {ESIGN} . .
|
|
55 ; $F0 {FCHRFLG} . .
|
|
56 ; $F1 {DIGRT} . .
|
|
57 ; $F2 CIX . .
|
|
58 ; $F3 INBUFF . .
|
|
59 ; $F4 v . .
|
|
60 ; $F5 {ZTEMP1} . .
|
|
61 ; $F6 v . .
|
|
62 ; $F7 {ZTEMP4} . .
|
|
63 ; $F8 v . .
|
|
64 ; $F9 {ZTEMP3} . .
|
|
65 ; $FA v . .
|
|
66 ; $FB DEGFLG/RADFLG . .
|
|
67 ; $FC FLPTR . .
|
|
68 ; $FD v . .
|
|
69 ; $FE FPTR2 . .
|
|
70 ; $FF v . .
|
|
71 ; $05E0 PLYARG T T
|
|
72 ; $05E1 | T T
|
|
73 ; $05E2 | T T
|
|
74 ; $05E3 | T T
|
|
75 ; $05E4 | T T
|
|
76 ; $05E5 v T T
|
|
77 ; $05E6 FPSCR TT
|
|
78 ; $05E7 | TT
|
|
79 ; $05E8 | TT
|
|
80 ; $05E9 | TT
|
|
81 ; $05EA | TT
|
|
82 ; $05EB v TT
|
|
83 ; $05EC FPSCR1
|
|
84 ; $05ED |
|
|
85 ; $05EE |
|
|
86 ; $05EF |
|
|
87 ; $05F0 |
|
|
88 ; $05F1 v
|
|
89 ;
|
|
90 ; Notes:
|
|
91 ; [1] BASIC XE relies on $DE/DF not being touched by FADD, or FOR/NEXT
|
|
92 ; breaks.
|
|
93 ; [2] MAC/65 relies on $DE/DF not being touched by IPF.
|
|
94 ; [3] DARG relies on FPI not touching FR1.
|
|
95 ; [4] ACTris 1.2 relies on FASC not touching lower parts of FR2.
|
|
96 ;
|
|
97
|
|
98 .macro ckaddr
|
|
99 .if * <> %%1
|
|
100 .error 'Incorrect address: ',*,' != ',%%1
|
|
101 .endif
|
|
102 .endm
|
|
103
|
|
104 .macro fixadr
|
|
105 .if * < %%1
|
|
106 .print (%%1-*),' bytes free before ',%%1
|
|
107 org %%1
|
|
108 .elif * > %%1
|
|
109 .error 'Out of space: ',*,' > ',%%1,' (',*-%%1,' bytes over)'
|
|
110 .endif
|
|
111 .endm
|
|
112
|
|
113 ;==========================================================================
|
|
114 ; AFP [D800] Convert ASCII string at INBUFF[CIX] to FR0
|
|
115 ;
|
|
116 D800 org $d800
|
|
117 = D800 _afp = afp
|
|
118 D800 .proc afp
|
|
119 = 00E6 dotflag = fr2
|
|
120 = 00E7 xinvert = fr2+1
|
|
121 = 00E8 cix0 = fr2+2
|
|
122 = 00E9 sign = fr2+3
|
|
123 = 00EA digit2 = fr2+4
|
|
124
|
|
125 ;skip initial spaces
|
|
126 D800 20 A1 DB jsr skpspc
|
|
127
|
|
128 ;init FR0 and one extra mantissa byte
|
|
129 D803 A9 7F lda #$7f
|
|
130 D805 85 D4 sta fr0
|
|
131 D807 85 EA sta digit2
|
|
132
|
|
133 D809 A2 D5 ldx #fr0+1
|
|
134 D80B 20 46 DA jsr zf1
|
|
135
|
|
136 ;clear decimal flag
|
|
137 D80E 85 E6 sta dotflag
|
|
138 D810 85 E9 sta sign
|
|
139
|
|
140 ;check for sign
|
|
141 D812 A4 F2 ldy cix
|
|
142 D814 B1 F3 lda (inbuff),y
|
|
143 D816 C9 2B cmp #'+'
|
|
144 D818 F0 06 beq isplus
|
|
145 D81A C9 2D cmp #'-'
|
|
146 D81C D0 03 bne postsign
|
|
147 D81E 66 E9 ror sign
|
|
148 D820 isplus:
|
|
149 D820 C8 iny
|
|
150 D821 postsign:
|
|
151 D821 84 E8 sty cix0
|
|
152
|
|
153 ;skip leading zeroes
|
|
154 D823 A9 30 lda #'0'
|
|
155 D825 20 A5 DB jsr fp_skipchar
|
|
156
|
|
157 ;check if next char is a dot, indicating mantissa <1
|
|
158 D828 B1 F3 lda (inbuff),y
|
|
159 D82A C9 2E cmp #'.'
|
|
160 D82C D0 10 bne not_tiny
|
|
161 D82E C8 iny
|
|
162
|
|
163 ;set dot flag
|
|
164 D82F 66 E6 ror dotflag
|
|
165
|
|
166 ;increment anchor so we don't count the dot as a digit for purposes
|
|
167 ;of seeing if we got any digits
|
|
168 D831 E6 E8 inc cix0
|
|
169
|
|
170 ;skip zeroes and adjust exponent
|
|
171 D833 A9 30 lda #'0'
|
|
172 D835 tiny_denorm_loop:
|
|
173 D835 D1 F3 cmp (inbuff),y
|
|
174 D837 D0 05 bne tiny_denorm_loop_exit
|
|
175 D839 C6 D4 dec fr0
|
|
176 D83B C8 iny
|
|
177 D83C D0 F7 bne tiny_denorm_loop
|
|
178 D83E tiny_denorm_loop_exit:
|
|
179
|
|
180 D83E not_tiny:
|
|
181
|
|
182 ;grab digits left of decimal point
|
|
183 D83E A2 01 ldx #1
|
|
184 D840 nextdigit:
|
|
185 D840 B1 F3 lda (inbuff),y
|
|
186 D842 C9 45 cmp #'E'
|
|
187 D844 F0 55 beq isexp
|
|
188 D846 C8 iny
|
|
189 D847 C9 2E cmp #'.'
|
|
190 D849 F0 28 beq isdot
|
|
191 D84B 49 30 eor #'0'
|
|
192 D84D C9 0A cmp #10
|
|
193 D84F B0 2A bcs termcheck
|
|
194
|
|
195 ;write digit if we haven't exceeded digit count
|
|
196 D851 E0 06 cpx #6
|
|
197 D853 B0 15 bcs afterwrite
|
|
198
|
|
199 D855 24 EA bit digit2
|
|
200 D857 10 09 bpl writehi
|
|
201
|
|
202 ;clear second digit flag
|
|
203 D859 C6 EA dec digit2
|
|
204
|
|
205 ;merge in low digit
|
|
206 D85B 15 D4 ora fr0,x
|
|
207 D85D 95 D4 sta fr0,x
|
|
208
|
|
209 ;advance to next byte
|
|
210 D85F E8 inx
|
|
211 D860 D0 08 bne afterwrite
|
|
212
|
|
213 D862 writehi:
|
|
214 ;set second digit flag
|
|
215 D862 E6 EA inc digit2
|
|
216
|
|
217 ;shift digit to high nibble and write
|
|
218 D864 0A asl
|
|
219 D865 0A asl
|
|
220 D866 0A asl
|
|
221 D867 0A asl
|
|
222 D868 95 D4 sta fr0,x
|
|
223
|
|
224 D86A afterwrite:
|
|
225 ;adjust digit exponent if we haven't seen a dot yet
|
|
226 D86A 24 E6 bit dotflag
|
|
227 D86C 30 02 E6 D4 smi:inc fr0
|
|
228
|
|
229 ;go back for more
|
|
230 D870 4C 40 D8 jmp nextdigit
|
|
231
|
|
232 D873 isdot:
|
|
233 D873 A5 E6 lda dotflag
|
|
234 D875 D0 04 bne termcheck
|
|
235
|
|
236 ;set the dot flag and loop back for more
|
|
237 D877 66 E6 ror dotflag
|
|
238 D879 D0 C5 bne nextdigit
|
|
239
|
|
240 D87B termcheck:
|
|
241 D87B 88 dey
|
|
242 D87C C4 E8 cpy cix0
|
|
243 D87E F0 1A beq err_carryset
|
|
244 D880 term:
|
|
245 ;stash offset
|
|
246 D880 84 F2 sty cix
|
|
247
|
|
248 D882 term_rollback_exp:
|
|
249 ;divide digit exponent by two and merge in sign
|
|
250 D882 26 E9 rol sign
|
|
251 D884 66 D4 ror fr0
|
|
252
|
|
253 ;check if we need a one digit shift
|
|
254 D886 B0 0F bcs nodigitshift
|
|
255
|
|
256 ;shift right one digit
|
|
257 D888 A2 04 ldx #4
|
|
258 D88A digitshift:
|
|
259 D88A 46 D5 lsr fr0+1
|
|
260 D88C 66 D6 ror fr0+2
|
|
261 D88E 66 D7 ror fr0+3
|
|
262 D890 66 D8 ror fr0+4
|
|
263 D892 66 D9 ror fr0+5
|
|
264 D894 CA dex
|
|
265 D895 D0 F3 bne digitshift
|
|
266
|
|
267 D897 nodigitshift:
|
|
268 D897 4C 00 DC jmp fp_normalize
|
|
269
|
|
270 D89A err_carryset:
|
|
271 D89A 60 rts
|
|
272
|
|
273 D89B isexp:
|
|
274 D89B C4 E8 cpy cix0
|
|
275 D89D F0 FB beq err_carryset
|
|
276
|
|
277 ;save off this point as a fallback in case we don't actually have
|
|
278 ;exponential notation
|
|
279 D89F 84 F2 sty cix
|
|
280
|
|
281 ;check for sign
|
|
282 D8A1 A2 00 ldx #0
|
|
283 D8A3 C8 iny
|
|
284 D8A4 B1 F3 lda (inbuff),y
|
|
285 D8A6 C9 2B cmp #'+'
|
|
286 D8A8 F0 05 beq isexpplus
|
|
287 D8AA C9 2D cmp #'-'
|
|
288 D8AC D0 02 bne postexpsign
|
|
289 D8AE CA dex ;x=$ff
|
|
290 D8AF isexpplus:
|
|
291 D8AF C8 iny
|
|
292 D8B0 postexpsign:
|
|
293 D8B0 86 E7 stx xinvert
|
|
294
|
|
295 ;pull up to two exponent digits -- check first digit
|
|
296 D8B2 20 B1 DB jsr fp_isdigit_y
|
|
297 D8B5 C8 iny
|
|
298 D8B6 B0 CA bcs term_rollback_exp
|
|
299
|
|
300 ;stash first digit
|
|
301 D8B8 AA tax
|
|
302
|
|
303 ;check for another digit
|
|
304 D8B9 20 B1 DB jsr fp_isdigit_y
|
|
305 D8BC B0 05 bcs notexpzero2
|
|
306 D8BE C8 iny
|
|
307
|
|
308 D8BF 7D 39 DA adc fp_mul10,x
|
|
309 D8C2 AA tax
|
|
310 D8C3 notexpzero2:
|
|
311 D8C3 8A txa
|
|
312
|
|
313 ;zero is not a valid exponent
|
|
314 D8C4 F0 BC beq term_rollback_exp
|
|
315
|
|
316 ;check if mantissa is zero -- if so, don't bias
|
|
317 ; ldx fr0+1
|
|
318 ; beq term
|
|
319
|
|
320 ;apply sign to exponent
|
|
321 D8C6 45 E7 eor xinvert
|
|
322 D8C8 26 E7 rol xinvert
|
|
323
|
|
324 ;bias digit exponent
|
|
325 D8CA 65 D4 adc fr0
|
|
326 D8CC 85 D4 sta fr0
|
|
327 D8CE expterm:
|
|
328 D8CE 4C 80 D8 jmp term
|
|
329
|
|
330 .endp
|
|
331
|
|
332 ;==========================================================================
|
|
333 D8D1 .proc fp_fmul_carryup
|
|
334 D8D1 round_loop:
|
|
335 D8D1 75 D4 adc fr0,x
|
|
336 D8D3 95 D4 sta fr0,x
|
|
337 D8D5 dec_entry:
|
|
338 D8D5 CA dex
|
|
339 D8D6 A9 00 lda #0
|
|
340 D8D8 B0 F7 bcs round_loop
|
|
341 D8DA 60 rts
|
|
342 .endp
|
|
343
|
|
344 ;==========================================================================
|
|
345 D8DB .proc fp_tab_lo_100
|
|
346 D8DB 00 64 C8 2C 90 F4 + :10 dta <[100*#]
|
|
347 .endp
|
|
348
|
|
349 ;==========================================================================
|
|
350 D8E5 fixadr $d8e6
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
2 .print ($D8E6-*),' bytes free before ',$D8E6
|
|
2 $0001 bytes free before $D8E6
|
|
3 D8E5 org $D8E6
|
|
Source: source/Shared/mathpack.s
|
|
351 = D8E6 _fasc = fasc
|
|
352 D8E6 .proc fasc
|
|
353 = 00F7 dotcntr = ztemp4
|
|
354 = 00F8 expval = ztemp4+1
|
|
355 = 00F9 trimbase = ztemp4+2
|
|
356 D8E6 20 51 DA jsr ldbufa
|
|
357 D8E9 A0 00 ldy #0
|
|
358
|
|
359 ;read exponent and check if number is zero
|
|
360 D8EB A5 D4 lda fr0
|
|
361 D8ED D0 05 bne notzero
|
|
362
|
|
363 D8EF A9 B0 lda #$b0
|
|
364 D8F1 91 F3 sta (inbuff),y
|
|
365 D8F3 60 rts
|
|
366
|
|
367 D8F4 notzero:
|
|
368 D8F4 84 F8 sty expval
|
|
369 D8F6 84 F9 sty trimbase
|
|
370
|
|
371 ;insert sixth mantissa byte
|
|
372 D8F8 84 D4 sty fr0
|
|
373
|
|
374 ;check if number is negative
|
|
375 D8FA 10 0A bpl ispos
|
|
376 D8FC A2 2D ldx #'-'
|
|
377 D8FE C6 F3 dec inbuff
|
|
378 D900 8E 7F 05 stx lbuff-1
|
|
379 D903 E6 F9 inc trimbase
|
|
380 D905 C8 iny
|
|
381 D906 ispos:
|
|
382
|
|
383 ;set up for 5 mantissa bytes
|
|
384 D906 A2 FB ldx #-5
|
|
385
|
|
386 ;compute digit offset to place dot
|
|
387 ; 0.001 (10.0E-04) = 3E 10 00 00 00 00 -> -1
|
|
388 ; 0.01 ( 1.0E-02) = 3F 01 00 00 00 00 -> 1
|
|
389 ; 0.1 (10.0E-02) = 3F 10 00 00 00 00 -> 1
|
|
390 ; 1.0 ( 1.0E+00) = 40 01 00 00 00 00 -> 3
|
|
391 ; 10.0 (10.0E+00) = 40 10 00 00 00 00 -> 3
|
|
392 ; 100.0 ( 1.0E+02) = 40 01 00 00 00 00 -> 5
|
|
393 ; 1000.0 (10.0E+02) = 40 10 00 00 00 00 -> 5
|
|
394
|
|
395 D908 0A asl
|
|
396 D909 38 sec
|
|
397 D90A E9 7D sbc #125
|
|
398
|
|
399 ;check if we should go to exponential form (exp >= 10 or <=-3)
|
|
400 D90C C9 0C cmp #12
|
|
401 D90E 90 0A bcc noexp
|
|
402
|
|
403 ;yes - compute and stash explicit exponent
|
|
404 D910 E9 02 sbc #2 ;!! - carry set from BCC fail
|
|
405 D912 85 F8 sta expval ;$0A <= expval < $FE
|
|
406
|
|
407 ;reset dot counter
|
|
408 D914 A9 02 lda #2
|
|
409
|
|
410 ;exclude first two digits from zero trim
|
|
411 D916 E6 F9 inc trimbase
|
|
412 D918 E6 F9 inc trimbase
|
|
413
|
|
414 D91A noexp:
|
|
415 ;check if number is less than 1.0 and init dot counter
|
|
416 D91A C9 02 cmp #2
|
|
417 D91C B0 03 bcs not_tiny
|
|
418
|
|
419 ;use sixth mantissa byte
|
|
420 D91E 69 02 adc #2
|
|
421 D920 CA dex
|
|
422 D921 not_tiny:
|
|
423 D921 85 F7 sta dotcntr ;$02 <= dotcntr < $0C
|
|
424
|
|
425 ;check if number begins with a leading zero
|
|
426 D923 B5 DA lda fr0+6,x
|
|
427 D925 C9 10 cmp #$10
|
|
428 D927 B0 0C bcs digitloop
|
|
429
|
|
430 D929 C6 F9 dec trimbase
|
|
431
|
|
432 ;yes - skip the high digit
|
|
433 D92B 46 F8 lsr expval
|
|
434 D92D 06 F8 asl expval
|
|
435 D92F D0 18 bne writelow
|
|
436 D931 C6 F7 dec dotcntr
|
|
437 D933 90 14 bcc writelow
|
|
438
|
|
439 ;write out mantissa digits
|
|
440 D935 digitloop:
|
|
441 D935 C6 F7 dec dotcntr
|
|
442 D937 D0 05 bne no_hidot
|
|
443 D939 A9 2E lda #'.'
|
|
444 D93B 91 F3 sta (inbuff),y
|
|
445 D93D C8 iny
|
|
446 D93E no_hidot:
|
|
447
|
|
448 ;write out high digit
|
|
449 D93E B5 DA lda fr0+6,x
|
|
450 D940 4A lsr
|
|
451 D941 4A lsr
|
|
452 D942 4A lsr
|
|
453 D943 4A lsr
|
|
454 D944 09 30 ora #$30
|
|
455 D946 91 F3 sta (inbuff),y
|
|
456 D948 C8 iny
|
|
457
|
|
458 D949 writelow:
|
|
459 ;write out low digit
|
|
460 D949 C6 F7 dec dotcntr
|
|
461 D94B D0 05 bne no_lodot
|
|
462 D94D A9 2E lda #'.'
|
|
463 D94F 91 F3 sta (inbuff),y
|
|
464 D951 C8 iny
|
|
465 D952 no_lodot:
|
|
466
|
|
467 D952 B5 DA lda fr0+6,x
|
|
468 D954 29 0F and #$0f
|
|
469 D956 09 30 ora #$30
|
|
470 D958 91 F3 sta (inbuff),y
|
|
471 D95A C8 iny
|
|
472
|
|
473 ;next digit
|
|
474 D95B E8 inx
|
|
475 D95C D0 D7 bne digitloop
|
|
476
|
|
477 ;skip trim if dot hasn't been written
|
|
478 D95E A5 F7 lda dotcntr
|
|
479 D960 10 11 bpl skip_zero_trim
|
|
480
|
|
481 ;trim off leading zeroes
|
|
482 D962 A9 30 lda #'0'
|
|
483 D964 lzloop:
|
|
484 D964 C4 F9 cpy trimbase
|
|
485 D966 F0 05 beq stop_zero_trim
|
|
486 D968 88 dey
|
|
487 D969 D1 F3 cmp (inbuff),y
|
|
488 D96B F0 F7 beq lzloop
|
|
489
|
|
490 ;trim off dot
|
|
491 D96D stop_zero_trim:
|
|
492 D96D B1 F3 lda (inbuff),y
|
|
493 D96F C9 2E cmp #'.'
|
|
494 D971 D0 03 bne no_trailing_dot
|
|
495
|
|
496 D973 skip_zero_trim:
|
|
497 D973 88 dey
|
|
498 D974 B1 F3 lda (inbuff),y
|
|
499 D976 no_trailing_dot:
|
|
500
|
|
501 ;check if we have an exponent to deal with
|
|
502 D976 A6 F8 ldx expval
|
|
503 D978 F0 26 beq noexp2
|
|
504
|
|
505 ;print an 'E'
|
|
506 D97A A9 45 lda #'E'
|
|
507 D97C C8 iny
|
|
508 D97D 91 F3 sta (inbuff),y
|
|
509
|
|
510 ;check for a negative exponent
|
|
511 D97F 8A txa
|
|
512 D980 10 07 bpl exppos
|
|
513 D982 49 FF eor #$ff
|
|
514 D984 AA tax
|
|
515 D985 E8 inx
|
|
516 D986 A9 2D lda #'-'
|
|
517 D988 2C dta {bit $0100}
|
|
518 D989 exppos:
|
|
519 D989 A9 2B lda #'+'
|
|
520 D98B expneg:
|
|
521 D98B C8 iny
|
|
522 D98C 91 F3 sta (inbuff),y
|
|
523
|
|
524 ;print tens digit, if any
|
|
525 D98E 8A txa
|
|
526 D98F 38 sec
|
|
527 D990 A2 2F ldx #$2f
|
|
528 D992 tensloop:
|
|
529 D992 E8 inx
|
|
530 D993 E9 0A sbc #10
|
|
531 D995 B0 FB bcs tensloop
|
|
532 D997 48 pha
|
|
533 D998 8A txa
|
|
534 D999 C8 iny
|
|
535 D99A 91 F3 sta (inbuff),y
|
|
536 D99C 68 pla
|
|
537 D99D 69 3A adc #$3a
|
|
538 D99F C8 iny
|
|
539 D9A0 noexp2:
|
|
540 ;set high bit on last char
|
|
541 D9A0 09 80 ora #$80
|
|
542 D9A2 91 F3 sta (inbuff),y
|
|
543 D9A4 60 rts
|
|
544 .endp
|
|
545
|
|
546 ;==========================================================================
|
|
547 ; IPF [D9AA] Convert 16-bit integer at FR0 to FP
|
|
548 ;
|
|
549 ; !NOTE! Cannot use FR2/FR3 -- MAC/65 requires that $DE-DF be preserved.
|
|
550 ;
|
|
551 D9A5 fixadr $d9aa
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
2 .print ($D9AA-*),' bytes free before ',$D9AA
|
|
2 $0005 bytes free before $D9AA
|
|
3 D9A5 org $D9AA
|
|
Source: source/Shared/mathpack.s
|
|
552 D9AA .proc ipf
|
|
553 D9AA F8 sed
|
|
554
|
|
555 D9AB A2 D6 ldx #fr0+2
|
|
556 D9AD A0 05 ldy #5
|
|
557 D9AF 20 48 DA jsr zfl
|
|
558
|
|
559 D9B2 A0 10 ldy #16
|
|
560 D9B4 byteloop:
|
|
561 ;shift out binary bit
|
|
562 D9B4 06 D4 asl fr0
|
|
563 D9B6 26 D5 rol fr0+1
|
|
564
|
|
565 ;shift in BCD bit
|
|
566 D9B8 A5 D8 lda fr0+4
|
|
567 D9BA 65 D8 adc fr0+4
|
|
568 D9BC 85 D8 sta fr0+4
|
|
569 D9BE A5 D7 lda fr0+3
|
|
570 D9C0 65 D7 adc fr0+3
|
|
571 D9C2 85 D7 sta fr0+3
|
|
572 D9C4 26 D6 rol fr0+2
|
|
573
|
|
574 D9C6 88 dey
|
|
575 D9C7 D0 EB bne byteloop
|
|
576
|
|
577 D9C9 A9 43 lda #$43
|
|
578 D9CB 85 D4 sta fr0
|
|
579
|
|
580 D9CD 4C FF DB jmp fp_normalize_cld
|
|
581 .endp
|
|
582
|
|
583 ;==========================================================================
|
|
584 ; FPI [D9D2] Convert FR0 to 16-bit integer at FR0 with rounding
|
|
585 ;
|
|
586 ; This cannot overwrite FR1. Darg relies on being able to stash a value
|
|
587 ; there across a call to FPI in its startup.
|
|
588 ;
|
|
589 D9D0 fixadr $d9d2
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
2 .print ($D9D2-*),' bytes free before ',$D9D2
|
|
2 $0002 bytes free before $D9D2
|
|
3 D9D0 org $D9D2
|
|
Source: source/Shared/mathpack.s
|
|
590 D9D2 .nowarn .proc fpi
|
|
591 = 00E6 _acc0 = fr2
|
|
592 = 00E7 _acc1 = fr2+1
|
|
593
|
|
594 ;error out if it's guaranteed to be too big or negative (>999999)
|
|
595 D9D2 A5 D4 lda fr0
|
|
596 D9D4 C9 43 cmp #$43
|
|
597 D9D6 B0 60 bcs err
|
|
598
|
|
599 ;zero number if it's guaranteed to be too small (<0.01)
|
|
600 D9D8 E9 3E sbc #$3f-1 ;!!- carry is clear
|
|
601 D9DA 90 68 bcc zfr0
|
|
602
|
|
603 D9DC AA tax
|
|
604
|
|
605 ;clear temp accum and set up rounding
|
|
606 D9DD A9 00 lda #0
|
|
607 D9DF B4 D5 ldy fr0+1,x
|
|
608 D9E1 C0 50 cpy #$50
|
|
609 D9E3 2A rol ;!! - clears carry too
|
|
610 D9E4 85 D4 sta fr0
|
|
611 D9E6 A9 00 lda #0
|
|
612
|
|
613 ;check for [0.01, 1)
|
|
614 D9E8 CA dex
|
|
615 D9E9 30 4B bmi done
|
|
616
|
|
617 ;convert ones/tens digit pair to binary (one result byte: 0-100)
|
|
618 D9EB B5 D5 lda fr0+1,x
|
|
619 D9ED 20 CD DA jsr fp_dectobin
|
|
620 D9F0 65 D4 adc fr0
|
|
621 D9F2 79 F6 DF adc fp_dectobin_tab,y
|
|
622 D9F5 18 clc
|
|
623 D9F6 85 D4 sta fr0
|
|
624 D9F8 A9 00 lda #0
|
|
625
|
|
626 ;check if we're done
|
|
627 D9FA CA dex
|
|
628 D9FB 30 39 bmi done
|
|
629
|
|
630 ;convert hundreds/thousands digit pair to binary (two result bytes: 0-10000)
|
|
631 D9FD B5 D5 lda fr0+1,x
|
|
632 D9FF 20 CD DA jsr fp_dectobin
|
|
633 DA02 A5 D4 lda fr0
|
|
634 DA04 79 48 DF adc fp_tab_lo_1000,y
|
|
635 DA07 85 D4 sta fr0
|
|
636 DA09 B9 52 DF lda fp_tab_hi_1000,y
|
|
637 DA0C 69 00 adc #0
|
|
638 DA0E 48 pha
|
|
639 DA0F B5 D5 lda fr0+1,x
|
|
640 DA11 29 0F and #$0f
|
|
641 DA13 A8 tay
|
|
642 DA14 A5 D4 lda fr0
|
|
643 DA16 79 DB D8 adc fp_tab_lo_100,y
|
|
644 DA19 85 D4 sta fr0
|
|
645 DA1B 68 pla
|
|
646 DA1C 79 5C DF adc fp_tab_hi_100,y
|
|
647
|
|
648 ;check if we're done
|
|
649 DA1F CA dex
|
|
650 DA20 30 14 bmi done
|
|
651
|
|
652 ;convert ten thousands digit pair to binary (two result bytes: 0-100000, overflow possible)
|
|
653 DA22 B4 D5 ldy fr0+1,x
|
|
654 DA24 C0 07 cpy #$07
|
|
655 DA26 B0 10 bcs err
|
|
656 DA28 AA tax
|
|
657 DA29 98 tya
|
|
658 DA2A 0A asl
|
|
659 DA2B 0A asl
|
|
660 DA2C 0A asl
|
|
661 DA2D 0A asl
|
|
662 DA2E 65 D4 adc fr0
|
|
663 DA30 85 D4 sta fr0
|
|
664 DA32 8A txa
|
|
665 DA33 79 65 DF adc fp_tab_hi_10000-1,y
|
|
666
|
|
667 DA36 done:
|
|
668 ;move result back to FR0, with rounding
|
|
669 DA36 85 D5 sta fr0+1
|
|
670 DA38 err:
|
|
671 DA38 60 rts
|
|
672 .endp
|
|
673
|
|
674 ;==========================================================================
|
|
675 DA39 fp_mul10:
|
|
676 DA39 00 0A 14 1E 28 32 + dta 0,10,20,30,40,50,60,70,80,90
|
|
677
|
|
678 ;==========================================================================
|
|
679 ; ZFR0 [DA44] Zero FR0
|
|
680 ; ZF1 [DA46] Zero float at (X)
|
|
681 ; ZFL [DA48] Zero float at (X) with length Y (UNDOCUMENTED)
|
|
682 ;
|
|
683 DA43 fixadr $da44
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
2 .print ($DA44-*),' bytes free before ',$DA44
|
|
2 $0001 bytes free before $DA44
|
|
3 DA43 org $DA44
|
|
Source: source/Shared/mathpack.s
|
|
684 DA44 zfr0:
|
|
685 DA44 A2 D4 ldx #fr0
|
|
686 DA46 ckaddr $da46
|
|
Macro: CKADDR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
687 DA46 zf1:
|
|
688 DA46 A0 06 ldy #6
|
|
689 DA48 ckaddr $da48
|
|
Macro: CKADDR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
690 DA48 zfl:
|
|
691 DA48 A9 00 lda #0
|
|
692 DA4A zflloop:
|
|
693 DA4A 95 00 sta 0,x
|
|
694 DA4C E8 inx
|
|
695 DA4D 88 dey
|
|
696 DA4E D0 FA bne zflloop
|
|
697 DA50 60 rts
|
|
698
|
|
699 ;==========================================================================
|
|
700 ; LDBUFA [DA51] Set LBUFF to #INBUFF (UNDOCUMENTED)
|
|
701 ;
|
|
702 DA51 fixadr $da51
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
703 DA51 ldbufa:
|
|
704 DA51 A9 80 85 F3 A9 05 + mwa #lbuff inbuff
|
|
705 DA59 60 rts
|
|
706
|
|
707 ;==========================================================================
|
|
708 ; FPILL_SHL16 [DA5A] Shift left 16-bit word at $F7:F8 (UNDOCUMENTED)
|
|
709 ;
|
|
710 ; Illegal entry point used by MAC/65 when doing hex conversion.
|
|
711 ;
|
|
712 ; Yes, even the byte ordering is wrong.
|
|
713 ;
|
|
714 DA5A fixadr $da5a
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
715
|
|
716 DA5A .nowarn .proc fpill_shl16
|
|
717 DA5A 06 F8 asl $f8
|
|
718 DA5C 26 F7 rol $f7
|
|
719 DA5E 60 rts
|
|
720 .endp
|
|
721
|
|
722 ;** 1 byte free**
|
|
723
|
|
724 ;==========================================================================
|
|
725 ; FSUB [DA60] Subtract FR1 from FR0; FR1 is altered
|
|
726 ; FADD [DA66] Add FR1 to FR0; FR1 is altered
|
|
727 DA5F fixadr $da60
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
2 .print ($DA60-*),' bytes free before ',$DA60
|
|
2 $0001 bytes free before $DA60
|
|
3 DA5F org $DA60
|
|
Source: source/Shared/mathpack.s
|
|
728 = DA66 fadd = fsub._fadd
|
|
729 DA60 .proc fsub
|
|
730
|
|
731 = 00E0 _diffmode = fr1
|
|
732
|
|
733 ;toggle sign on FR1
|
|
734 DA60 A5 E0 lda fr1
|
|
735 DA62 49 80 eor #$80
|
|
736 DA64 85 E0 sta fr1
|
|
737
|
|
738 ;fall through to FADD
|
|
739
|
|
740 DA66 ckaddr $da66
|
|
Macro: CKADDR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
741 DA66 _fadd:
|
|
742 ;if fr1 is zero, we're done
|
|
743 DA66 A5 E0 lda fr1
|
|
744 DA68 F0 4E beq sum_xit
|
|
745
|
|
746 ;if fr0 is zero, swap
|
|
747 DA6A A5 D4 lda fr0
|
|
748 DA6C F0 0E beq swap
|
|
749
|
|
750 ;compute difference in exponents, ignoring sign
|
|
751 DA6E A5 E0 lda fr1 ;load fr1 sign
|
|
752 DA70 45 D4 eor fr0 ;compute fr0 ^ fr1 signs
|
|
753 DA72 29 80 and #$80 ;mask to just sign
|
|
754 DA74 AA tax
|
|
755 DA75 45 E0 eor fr1 ;flip fr1 sign to match fr0
|
|
756 DA77 18 clc
|
|
757 DA78 E5 D4 sbc fr0 ;compute difference in exponents - 1
|
|
758 DA7A 90 05 bcc noswap
|
|
759
|
|
760 ;swap FR0 and FR1
|
|
761 DA7C swap:
|
|
762 DA7C 20 74 DD jsr fp_swap
|
|
763
|
|
764 ;loop back and retry
|
|
765 DA7F 30 E5 bmi _fadd
|
|
766
|
|
767 DA81 noswap:
|
|
768 ;A = FR1 - FR0 - 1
|
|
769 ;X = add/sub flag
|
|
770
|
|
771 ;compute positions for add/subtract
|
|
772 DA81 69 06 adc #6 ;A = (FR1) - (FR0) + 6 !! carry is clear coming in
|
|
773 DA83 A8 tay
|
|
774
|
|
775 ;check if FR1 is too small in magnitude to matter
|
|
776 DA84 30 32 bmi sum_xit
|
|
777
|
|
778 ;jump to decimal mode and prepare for add/sub loops
|
|
779 DA86 F8 sed
|
|
780
|
|
781 ;check if we are doing a sum or a difference
|
|
782 DA87 E0 80 cpx #$80
|
|
783 DA89 A2 05 ldx #5
|
|
784 DA8B B0 2E bcs do_subtract
|
|
785
|
|
786 ;set up rounding
|
|
787 DA8D A9 00 lda #0
|
|
788 DA8F C0 05 cpy #5
|
|
789 DA91 B0 03 bcs add_no_round
|
|
790 DA93 B9 E1 00 lda fr1+1,y
|
|
791 DA96 add_no_round:
|
|
792 DA96 C9 50 cmp #$50
|
|
793
|
|
794 ;add mantissas
|
|
795 DA98 98 tya
|
|
796 DA99 F0 0B beq post_add_loop
|
|
797 DA9B add_loop:
|
|
798 DA9B B9 E0 00 lda fr1,y
|
|
799 DA9E 75 D4 adc fr0,x
|
|
800 DAA0 95 D4 sta fr0,x
|
|
801 DAA2 CA dex
|
|
802 DAA3 88 dey
|
|
803 DAA4 D0 F5 bne add_loop
|
|
804 DAA6 post_add_loop:
|
|
805
|
|
806 ;check if we had a carry out
|
|
807 DAA6 90 10 bcc sum_xit
|
|
808
|
|
809 ;carry it up
|
|
810 DAA8 B0 08 bcs sum_carryloop_start
|
|
811 DAAA sum_carryloop:
|
|
812 DAAA B5 D5 lda fr0+1,x
|
|
813 DAAC 69 00 adc #0
|
|
814 DAAE 95 D5 sta fr0+1,x
|
|
815 DAB0 90 06 bcc sum_xit
|
|
816 DAB2 sum_carryloop_start:
|
|
817 DAB2 CA dex
|
|
818 DAB3 10 F5 bpl sum_carryloop
|
|
819
|
|
820 DAB5 20 6A DE jsr fp_carry_expup
|
|
821
|
|
822 DAB8 sum_xit:
|
|
823 ;exit decimal mode
|
|
824 ;normalize if necessary and exit (needed for borrow, as well to check over/underflow)
|
|
825 DAB8 4C FF DB jmp fp_normalize_cld
|
|
826
|
|
827 DABB do_subtract:
|
|
828 ;subtract FR0 and FR1 mantissas (!! carry is set coming in)
|
|
829 DABB 84 E0 sty fr1
|
|
830 DABD B0 08 bcs sub_loop_entry
|
|
831 DABF sub_loop:
|
|
832 DABF B5 D4 lda fr0,x
|
|
833 DAC1 F9 E1 00 sbc fr1+1,y
|
|
834 DAC4 95 D4 sta fr0,x
|
|
835 DAC6 CA dex
|
|
836 DAC7 sub_loop_entry:
|
|
837 DAC7 88 dey
|
|
838 DAC8 10 F5 bpl sub_loop
|
|
839 DACA 4C 5E DC jmp fp_fsub_cont
|
|
840 .endp
|
|
841
|
|
842 ;==========================================================================
|
|
843 ; Entry:
|
|
844 ; A = BCD value
|
|
845 ; P.D = clear
|
|
846 ;
|
|
847 ; Exit:
|
|
848 ; A = binary value
|
|
849 ; Y = modified
|
|
850 ;
|
|
851 DACD .proc fp_dectobin
|
|
852 DACD 48 pha
|
|
853 DACE 4A lsr
|
|
854 DACF 4A lsr
|
|
855 DAD0 4A lsr
|
|
856 DAD1 4A lsr
|
|
857 DAD2 A8 tay
|
|
858 DAD3 68 pla
|
|
859 = DAD4 .def :fp_exit_success
|
|
860 DAD4 18 clc
|
|
861 DAD5 60 rts
|
|
862 .endp
|
|
863
|
|
864 ;==========================================================================
|
|
865 ; FMUL [DADB]: Multiply FR0 * FR1 -> FR0
|
|
866 ;
|
|
867 DAD6 fixadr $dad6
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
868 DAD6 fp_fld1r_const_fmul:
|
|
869 DAD6 A0 DB ldy #>fpconst_ten
|
|
870 DAD8 fp_fld1r_fmul:
|
|
871 DAD8 20 98 DD jsr fld1r
|
|
872 DADB ckaddr $dadb
|
|
Macro: CKADDR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
873 DADB .proc fmul
|
|
874
|
|
875 ;We use FR0:FR3 as a double-precision accumulator, and copy the
|
|
876 ;original multiplicand value in FR0 to FR1. The multiplier in
|
|
877 ;FR1 is converted to binary digit pairs into FR2.
|
|
878
|
|
879 = 00DF _offset = _fr3+5
|
|
880 = 00E6 _offset2 = fr2
|
|
881
|
|
882 ;if FR0 is zero, we're done
|
|
883 DADB A5 D4 lda fr0
|
|
884 DADD F0 F5 beq fp_exit_success
|
|
885
|
|
886 ;if FR1 is zero, zero FR0 and exit
|
|
887 DADF A5 E0 lda fr1
|
|
888 DAE1 18 clc
|
|
889 DAE2 F0 17 beq fp_exit_zero
|
|
890
|
|
891 ;move fr0 to fr2
|
|
892 DAE4 20 79 DE jsr fp_fmul_fr0_to_binfr2
|
|
893
|
|
894 ;compute new exponent and stash
|
|
895 DAE7 A5 E0 lda fr1
|
|
896 DAE9 18 clc
|
|
897 DAEA 20 03 DB jsr fp_adjust_exponent.fmul_entry
|
|
898
|
|
899 DAED 85 D4 sta fr0
|
|
900 DAEF E6 D4 inc fr0
|
|
901
|
|
902 ;clear accumulator through to exponent byte of fr1
|
|
903 DAF1 A2 D5 ldx #fr0+1
|
|
904 DAF3 A0 0C ldy #12
|
|
905 DAF5 F8 sed
|
|
906
|
|
907 DAF6 4C C3 DC jmp fp_fmul_innerloop
|
|
908 .endp
|
|
909
|
|
910 DAF9 underflow_overflow:
|
|
911 DAF9 68 pla
|
|
912 DAFA 68 pla
|
|
913 DAFB fp_exit_zero:
|
|
914 DAFB 4C 44 DA jmp zfr0
|
|
915
|
|
916 DAFE .proc fp_adjust_exponent
|
|
917 DAFE fdiv_entry:
|
|
918 DAFE A5 E0 lda fr1
|
|
919 DB00 49 7F eor #$7f
|
|
920 DB02 38 sec
|
|
921 DB03 fmul_entry:
|
|
922 ;stash modified exp1
|
|
923 DB03 AA tax
|
|
924
|
|
925 ;compute new sign
|
|
926 DB04 45 D4 eor fr0
|
|
927 DB06 29 80 and #$80
|
|
928 DB08 85 E0 sta fr1
|
|
929
|
|
930 ;merge exponents
|
|
931 DB0A 8A txa
|
|
932 DB0B 65 D4 adc fr0
|
|
933 DB0D AA tax
|
|
934 DB0E 45 E0 eor fr1
|
|
935
|
|
936 ;check for underflow/overflow
|
|
937 DB10 C9 4F cmp #128-49
|
|
938 DB12 90 E5 bcc underflow_overflow
|
|
939
|
|
940 DB14 C9 B1 cmp #128+49
|
|
941 DB16 B0 E1 bcs underflow_overflow
|
|
942
|
|
943 ;rebias exponent
|
|
944 DB18 8A txa
|
|
945 DB19 E9 3F sbc #$40-1 ;!! - C=0 from bcs fail
|
|
946 DB1B 60 rts
|
|
947 .endp
|
|
948
|
|
949 ;==========================================================================
|
|
950 DB1C .pages 1 ;optimized by fp_fld1r_const_fmul
|
|
951
|
|
952 DB1C fpconst_ten:
|
|
953 DB1C 40 10 00 00 00 00 .fl 10
|
|
954
|
|
955 DB22 fpconst_ln10:
|
|
956 DB22 40 02 30 25 85 09 .fl 2.3025850929940456840179914546844
|
|
957
|
|
958 DB28 .endpg
|
|
959 ;==========================================================================
|
|
960 ; FDIV [DB28] Divide FR0 / FR1 -> FR0
|
|
961 ;
|
|
962 ; Compatibility:
|
|
963 ; - It is important that FDIV rounds if FADD/FMUL do. Otherwise, some
|
|
964 ; forms of square root computation can have a slight error on integers,
|
|
965 ; which breaks TICKTOCK.BAS.
|
|
966 ;
|
|
967 DB28 fixadr $db28
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
968 DB28 .proc fdiv
|
|
969 = 00DB _digit = _fr3+1
|
|
970 = 00DC _index = _fr3+2
|
|
971 ;check if divisor is zero
|
|
972 DB28 A5 E0 lda fr1
|
|
973 DB2A F0 72 beq err
|
|
974
|
|
975 ;check if dividend is zero
|
|
976 DB2C A5 D4 lda fr0
|
|
977 DB2E F0 6C beq ok
|
|
978
|
|
979 ;compute new exponent
|
|
980 DB30 20 FE DA jsr fp_adjust_exponent.fdiv_entry
|
|
981
|
|
982 DB33 20 2D DC jsr fp_fdiv_init
|
|
983
|
|
984 DB36 digitloop:
|
|
985 ;just keep going if we're accurate
|
|
986 DB36 A5 D4 lda fr0
|
|
987 DB38 05 D5 ora fr0+1
|
|
988 DB3A F0 3D beq nextdigit
|
|
989
|
|
990 ;check if we should either divide or add based on current sign (stored in carry)
|
|
991 DB3C 90 05 bcc incloop
|
|
992
|
|
993 DB3E 20 B9 DB jsr fp_fdiv_decloop
|
|
994 DB41 90 36 bcc nextdigit
|
|
995
|
|
996 DB43 incloop:
|
|
997 ;decrement quotient mantissa byte
|
|
998 DB43 A9 00 lda #0
|
|
999 DB45 E5 DB sbc _digit
|
|
1000 DB47 A6 DC ldx _index
|
|
1001 DB49 downloop:
|
|
1002 DB49 75 ED adc fr2+7,x
|
|
1003 DB4B 95 ED sta fr2+7,x
|
|
1004 DB4D A9 99 lda #$99
|
|
1005 DB4F CA dex
|
|
1006 DB50 90 F7 bcc downloop
|
|
1007
|
|
1008 ;add mantissas
|
|
1009 DB52 18 clc
|
|
1010 .rept 6
|
|
1011 LDA FR0+(5-#)
|
|
1012 ADC FR1+(5-#)
|
|
1013 STA FR0+(5-#)
|
|
1014 .ENDR
|
|
1014 .endr
|
|
Source: REPT
|
|
1011 DB53 A5 D9 LDA FR0+(5-#)
|
|
1011 DB55 65 E5 ADC FR1+(5-#)
|
|
1011 DB57 85 D9 STA FR0+(5-#)
|
|
1011 DB59 A5 D8 LDA FR0+(5-#)
|
|
1011 DB5B 65 E4 ADC FR1+(5-#)
|
|
1011 DB5D 85 D8 STA FR0+(5-#)
|
|
1011 DB5F A5 D7 LDA FR0+(5-#)
|
|
1011 DB61 65 E3 ADC FR1+(5-#)
|
|
1011 DB63 85 D7 STA FR0+(5-#)
|
|
1011 DB65 A5 D6 LDA FR0+(5-#)
|
|
1011 DB67 65 E2 ADC FR1+(5-#)
|
|
1011 DB69 85 D6 STA FR0+(5-#)
|
|
1011 DB6B A5 D5 LDA FR0+(5-#)
|
|
1011 DB6D 65 E1 ADC FR1+(5-#)
|
|
1011 DB6F 85 D5 STA FR0+(5-#)
|
|
1011 DB71 A5 D4 LDA FR0+(5-#)
|
|
1011 DB73 65 E0 ADC FR1+(5-#)
|
|
1011 DB75 85 D4 STA FR0+(5-#)
|
|
Source: source/Shared/mathpack.s
|
|
1015
|
|
1016 ;keep going until we overflow
|
|
1017 DB77 90 CA bcc incloop
|
|
1018
|
|
1019 DB79 nextdigit:
|
|
1020 ;shift dividend (make sure to save carry state)
|
|
1021 DB79 08 php
|
|
1022 DB7A A2 04 ldx #4
|
|
1023 DB7C bitloop:
|
|
1024 DB7C 06 D9 asl fr0+5
|
|
1025 DB7E 26 D8 rol fr0+4
|
|
1026 DB80 26 D7 rol fr0+3
|
|
1027 DB82 26 D6 rol fr0+2
|
|
1028 DB84 26 D5 rol fr0+1
|
|
1029 DB86 26 D4 rol fr0
|
|
1030 DB88 CA dex
|
|
1031 DB89 D0 F1 bne bitloop
|
|
1032 DB8B 28 plp
|
|
1033
|
|
1034 ;next digit
|
|
1035 DB8C A5 DB lda _digit
|
|
1036 DB8E 49 09 eor #$09
|
|
1037 DB90 85 DB sta _digit
|
|
1038 DB92 F0 A2 beq digitloop
|
|
1039
|
|
1040 ;next quo byte
|
|
1041 DB94 E6 DC inc _index
|
|
1042 DB96 D0 9E bne digitloop
|
|
1043
|
|
1044 ;move back to fr0
|
|
1045 DB98 20 EE DB jsr fp_fdiv_complete
|
|
1046 DB9B D8 cld
|
|
1047 DB9C ok:
|
|
1048 DB9C 18 clc
|
|
1049 DB9D 60 rts
|
|
1050 DB9E err:
|
|
1051 DB9E 38 sec
|
|
1052 DB9F 60 rts
|
|
1053 .endp
|
|
1054
|
|
1055 ;==========================================================================
|
|
1056 ; SKPSPC [DBA1] Increment CIX while INBUFF[CIX] is a space
|
|
1057 DBA0 fixadr $dba1
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
2 .print ($DBA1-*),' bytes free before ',$DBA1
|
|
2 $0001 bytes free before $DBA1
|
|
3 DBA0 org $DBA1
|
|
Source: source/Shared/mathpack.s
|
|
1058 DBA1 skpspc:
|
|
1059 DBA1 A9 20 lda #' '
|
|
1060 DBA3 A4 F2 ldy cix
|
|
1061 DBA5 fp_skipchar:
|
|
1062 DBA5 skpspc_loop:
|
|
1063 DBA5 D1 F3 cmp (inbuff),y
|
|
1064 DBA7 D0 03 bne skpspc_xit
|
|
1065 DBA9 C8 iny
|
|
1066 DBAA D0 F9 bne skpspc_loop
|
|
1067 DBAC skpspc_xit:
|
|
1068 DBAC 84 F2 sty cix
|
|
1069 DBAE 60 rts
|
|
1070
|
|
1071 ;==========================================================================
|
|
1072 ; ISDIGT [DBAF] Check if INBUFF[CIX] is a digit (UNDOCUMENTED)
|
|
1073 DBAF fixadr $dbaf
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1074 = DBAF isdigt = _isdigt
|
|
1075 DBAF .proc _isdigt
|
|
1076 DBAF A4 F2 ldy cix
|
|
1077 = DBB1 .def :fp_isdigit_y = *
|
|
1078 DBB1 B1 F3 lda (inbuff),y
|
|
1079 DBB3 38 sec
|
|
1080 DBB4 E9 30 sbc #'0'
|
|
1081 DBB6 C9 0A cmp #10
|
|
1082 DBB8 60 rts
|
|
1083 .endp
|
|
1084
|
|
1085 ;==========================================================================
|
|
1086 DBB9 .proc fp_fdiv_decloop
|
|
1087 DBB9 decloop:
|
|
1088 ;increment quotient mantissa byte
|
|
1089 DBB9 A5 DB lda fdiv._digit
|
|
1090 DBBB A6 DC ldx fdiv._index
|
|
1091 DBBD uploop:
|
|
1092 DBBD 75 ED adc fr2+7,x
|
|
1093 DBBF 95 ED sta fr2+7,x
|
|
1094 DBC1 A9 00 lda #0
|
|
1095 DBC3 CA dex
|
|
1096 DBC4 B0 F7 bcs uploop
|
|
1097
|
|
1098 ;subtract mantissas
|
|
1099 DBC6 38 sec
|
|
1100 DBC7 A5 D9 lda fr0+5
|
|
1101 DBC9 E5 E5 sbc fr1+5
|
|
1102 DBCB 85 D9 sta fr0+5
|
|
1103 DBCD A5 D8 lda fr0+4
|
|
1104 DBCF E5 E4 sbc fr1+4
|
|
1105 DBD1 85 D8 sta fr0+4
|
|
1106 DBD3 A5 D7 lda fr0+3
|
|
1107 DBD5 E5 E3 sbc fr1+3
|
|
1108 DBD7 85 D7 sta fr0+3
|
|
1109 DBD9 A5 D6 lda fr0+2
|
|
1110 DBDB E5 E2 sbc fr1+2
|
|
1111 DBDD 85 D6 sta fr0+2
|
|
1112 DBDF A5 D5 lda fr0+1
|
|
1113 DBE1 E5 E1 sbc fr1+1
|
|
1114 DBE3 85 D5 sta fr0+1
|
|
1115 DBE5 A5 D4 lda fr0
|
|
1116 DBE7 E9 00 sbc #0
|
|
1117 DBE9 85 D4 sta fr0
|
|
1118
|
|
1119 ;keep going until we underflow
|
|
1120 DBEB B0 CC bcs decloop
|
|
1121 DBED 60 rts
|
|
1122 .endp
|
|
1123
|
|
1124 DBEE .proc fp_fdiv_complete
|
|
1125 DBEE A2 E5 ldx #fr2-1
|
|
1126 DBF0 A4 DA ldy _fr3
|
|
1127 DBF2 A5 E6 lda fr2
|
|
1128 DBF4 D0 02 bne no_normstep
|
|
1129 DBF6 E8 inx
|
|
1130 DBF7 88 dey
|
|
1131 DBF8 no_normstep:
|
|
1132 DBF8 94 00 sty 0,x
|
|
1133 DBFA 4C 87 DD jmp fld0r_zp
|
|
1134 .endp
|
|
1135
|
|
1136 ;==========================================================================
|
|
1137 ; NORMALIZE [DC00] Normalize FR0 (UNDOCUMENTED)
|
|
1138 DBFD fixadr $dc00-1
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
2 .print ($DC00-1-*),' bytes free before ',$DC00-1
|
|
2 $0002 bytes free before $DBFF
|
|
3 DBFD org $DC00-1
|
|
Source: source/Shared/mathpack.s
|
|
1139 DBFF fp_normalize_cld:
|
|
1140 DBFF D8 cld
|
|
1141 DC00 ckaddr $dc00
|
|
Macro: CKADDR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1142 DC00 fp_normalize:
|
|
1143 DC00 .nowarn .proc normalize
|
|
1144 DC00 A0 05 ldy #5
|
|
1145 DC02 normloop:
|
|
1146 DC02 A5 D4 lda fr0
|
|
1147 DC04 29 7F and #$7f
|
|
1148 DC06 F0 21 beq underflow2
|
|
1149
|
|
1150 DC08 A6 D5 ldx fr0+1
|
|
1151 DC0A F0 07 beq need_norm
|
|
1152
|
|
1153 ;Okay, we're done normalizing... check if the exponent is in bounds.
|
|
1154 ;It needs to be within +/-48 to be valid. If the exponent is <-49,
|
|
1155 ;we set it to zero; otherwise, we mark overflow.
|
|
1156
|
|
1157 DC0C C9 0F cmp #64-49
|
|
1158 DC0E 90 1A bcc underflow
|
|
1159 DC10 C9 71 cmp #64+49
|
|
1160 DC12 60 rts
|
|
1161
|
|
1162 DC13 need_norm:
|
|
1163 DC13 C6 D4 dec fr0
|
|
1164 DC15 A2 FB ldx #-5
|
|
1165 DC17 normloop2:
|
|
1166 DC17 B5 DB 95 DA mva fr0+7,x fr0+6,x
|
|
1167 DC1B E8 inx
|
|
1168 DC1C D0 F9 bne normloop2
|
|
1169 DC1E 86 DA stx fr0+6
|
|
1170 DC20 88 dey
|
|
1171 DC21 D0 DF bne normloop
|
|
1172
|
|
1173 ;Hmm, we shifted out everything... must be zero; reset exponent. This
|
|
1174 ;is critical since Atari Basic depends on the exponent being zero for
|
|
1175 ;a zero result.
|
|
1176 DC23 84 D4 sty fr0
|
|
1177 DC25 84 D5 sty fr0+1
|
|
1178 DC27 xit:
|
|
1179 DC27 18 clc
|
|
1180 DC28 60 rts
|
|
1181
|
|
1182 DC29 underflow2:
|
|
1183 DC29 18 clc
|
|
1184 DC2A underflow:
|
|
1185 DC2A 4C 44 DA jmp zfr0
|
|
1186
|
|
1187 .endp
|
|
1188
|
|
1189 ;==========================================================================
|
|
1190 ; HELPER ROUTINES
|
|
1191 ;==========================================================================
|
|
1192
|
|
1193 DC2D .proc fp_fdiv_init
|
|
1194 DC2D 85 DA sta _fr3
|
|
1195
|
|
1196 DC2F A2 E6 ldx #fr2
|
|
1197 DC31 20 46 DA jsr zf1
|
|
1198 DC34 A9 50 lda #$50
|
|
1199 DC36 85 EC sta fr2+6
|
|
1200
|
|
1201 DC38 A2 00 ldx #0
|
|
1202 DC3A 86 D4 stx fr0
|
|
1203 DC3C 86 E0 stx fr1
|
|
1204
|
|
1205 ;check if dividend begins with a leading zero digit -- if so, shift it left 4
|
|
1206 ;and begin with the tens digit
|
|
1207 DC3E A5 E1 lda fr1+1
|
|
1208 DC40 C9 10 cmp #$10
|
|
1209 DC42 B0 11 bcs start_with_ones
|
|
1210
|
|
1211 DC44 A0 04 ldy #4
|
|
1212 DC46 bitloop:
|
|
1213 DC46 06 E5 asl fr1+5
|
|
1214 DC48 26 E4 rol fr1+4
|
|
1215 DC4A 26 E3 rol fr1+3
|
|
1216 DC4C 26 E2 rol fr1+2
|
|
1217 DC4E 26 E1 rol fr1+1
|
|
1218 DC50 88 dey
|
|
1219 DC51 D0 F3 bne bitloop
|
|
1220
|
|
1221 DC53 A2 09 ldx #$09
|
|
1222
|
|
1223 DC55 start_with_ones:
|
|
1224
|
|
1225 DC55 86 DB stx fdiv._digit
|
|
1226 DC57 F8 sed
|
|
1227
|
|
1228 DC58 A2 F9 ldx #0-7
|
|
1229 DC5A 86 DC stx fdiv._index
|
|
1230 DC5C 38 sec
|
|
1231 DC5D 60 rts
|
|
1232 .endp
|
|
1233
|
|
1234 ;--------------------------------------------------------------------------
|
|
1235 DC5E .proc fp_fsub_cont
|
|
1236 ;check if we had a borrow
|
|
1237 DC5E B0 1F bcs sub_xit
|
|
1238 DC60 90 08 bcc borrow_loop_start
|
|
1239
|
|
1240 ;propagate borrow up
|
|
1241 DC62 borrow_loop:
|
|
1242 DC62 B5 D5 lda fr0+1,x
|
|
1243 DC64 E9 00 sbc #0
|
|
1244 DC66 95 D5 sta fr0+1,x
|
|
1245 DC68 B0 15 bcs sub_xit
|
|
1246 DC6A borrow_loop_start:
|
|
1247 DC6A CA dex
|
|
1248 DC6B 10 F5 bpl borrow_loop
|
|
1249
|
|
1250 DC6D A2 05 ldx #5
|
|
1251 DC6F 38 sec
|
|
1252 DC70 diff_borrow:
|
|
1253 DC70 A9 00 lda #0
|
|
1254 DC72 F5 D4 sbc fr0,x
|
|
1255 DC74 95 D4 sta fr0,x
|
|
1256 DC76 CA dex
|
|
1257 DC77 D0 F7 bne diff_borrow
|
|
1258 DC79 A9 80 lda #$80
|
|
1259 DC7B 45 D4 eor fr0
|
|
1260 DC7D 85 D4 sta fr0
|
|
1261 DC7F sub_xit:
|
|
1262
|
|
1263 DC7F norm_loop:
|
|
1264 ;Check if the exponent is in bounds.
|
|
1265 ;It needs to be within +/-48 to be valid. If the exponent is <-49,
|
|
1266 ;we set it to zero. Overflow isn't possible as this is the mantissa
|
|
1267 ;subtraction path.
|
|
1268 DC7F A5 D4 lda fr0
|
|
1269 DC81 29 7F and #$7f
|
|
1270 DC83 C9 0F cmp #64-49
|
|
1271 DC85 90 1F bcc underflow
|
|
1272
|
|
1273 DC87 A6 D5 ldx fr0+1
|
|
1274 DC89 F0 0F beq need_norm
|
|
1275
|
|
1276 ;check if we need to round, i.e.:
|
|
1277 ; 2.00000000
|
|
1278 ;-0.000000005
|
|
1279 ;load rounding byte offset
|
|
1280 DC8B A6 E0 ldx fr1
|
|
1281 DC8D E0 04 cpx #4
|
|
1282 DC8F B0 06 bcs no_round
|
|
1283 DC91 B5 E2 lda fr1+2,x
|
|
1284 DC93 C9 50 cmp #$50
|
|
1285 DC95 B0 27 bcs round_up
|
|
1286 DC97 no_round:
|
|
1287
|
|
1288 DC97 18 clc
|
|
1289 DC98 D8 cld
|
|
1290 DC99 60 rts
|
|
1291
|
|
1292 DC9A need_norm:
|
|
1293 DC9A A2 FC ldx #-4
|
|
1294 DC9C scan_loop:
|
|
1295 DC9C C6 D4 dec fr0
|
|
1296 DC9E B4 DA ldy fr0+6,x
|
|
1297 DCA0 D0 08 bne found_pos
|
|
1298 DCA2 E8 inx
|
|
1299 DCA3 D0 F7 bne scan_loop
|
|
1300
|
|
1301 ;hmm... mantissa is all zero.
|
|
1302 DCA5 underflow2:
|
|
1303 DCA5 18 clc
|
|
1304 DCA6 underflow:
|
|
1305 DCA6 D8 cld
|
|
1306 DCA7 4C 44 DA jmp zfr0
|
|
1307
|
|
1308 DCAA found_pos:
|
|
1309 ;shift up mantissa
|
|
1310 DCAA A0 00 ldy #0
|
|
1311 DCAC shift_loop:
|
|
1312 DCAC B5 DA 99 D5 00 mva fr0+6,x fr0+1,y
|
|
1313 DCB1 C8 iny
|
|
1314 DCB2 E8 inx
|
|
1315 DCB3 D0 F7 bne shift_loop
|
|
1316
|
|
1317 ;clear remaining mantissa bytes
|
|
1318 DCB5 clear_loop:
|
|
1319 DCB5 96 D5 C8 stx fr0+1,y+
|
|
1320 DCB8 C0 06 cpy #6
|
|
1321 DCBA D0 F9 bne clear_loop
|
|
1322
|
|
1323 ;check if we need to round
|
|
1324
|
|
1325
|
|
1326 ;if not, loop back to check the exponent and exit
|
|
1327 ; bcc norm_loop
|
|
1328 DCBC F0 C1 beq norm_loop
|
|
1329
|
|
1330 DCBE round_up:
|
|
1331 ;jump back into fadd code to carry up and exit
|
|
1332 DCBE A2 05 ldx #5
|
|
1333 DCC0 4C AA DA jmp fsub.sum_carryloop
|
|
1334 .endp
|
|
1335
|
|
1336 ;--------------------------------------------------------------------------
|
|
1337 DCC3 .proc fp_fmul_innerloop
|
|
1338 = 00DF _offset = _fr3+5
|
|
1339 = 00E6 _offset2 = fr2
|
|
1340
|
|
1341 DCC3 20 48 DA jsr zfl
|
|
1342
|
|
1343 ;set up for 7 bits per digit pair (0-99 in 0-127)
|
|
1344 DCC6 A0 07 ldy #7
|
|
1345
|
|
1346 ;set rounding byte, assuming renormalize needed (fr0+2 through fr0+6)
|
|
1347 DCC8 A9 50 lda #$50
|
|
1348 DCCA 85 DB sta fr0+7
|
|
1349
|
|
1350 ;begin outer loop -- this is where we process one _bit_ out of each
|
|
1351 ;multiplier byte in FR2's mantissa (note that this is inverted in that
|
|
1352 ;it is bytes-in-bits instead of bits-in-bytes)
|
|
1353 DCCC offloop:
|
|
1354
|
|
1355 ;begin inner loop -- here we process the same bit in each multiplier
|
|
1356 ;byte, going from byte 5 down to byte 1
|
|
1357 DCCC A2 05 ldx #5
|
|
1358 DCCE offloop2:
|
|
1359 ;shift an inverted bit out of fr1 mantissa
|
|
1360 DCCE 56 E6 lsr fr2,x
|
|
1361 DCD0 B0 2D bcs noadd
|
|
1362
|
|
1363 ;add fr1 to fr0 at offset
|
|
1364 .rept 6
|
|
1365 LDA FR0+(5-#),X
|
|
1366 ADC FR1+(5-#)
|
|
1367 STA FR0+(5-#),X
|
|
1368 .ENDR
|
|
1368 .endr
|
|
Source: REPT
|
|
1365 DCD2 B5 D9 LDA FR0+(5-#),X
|
|
1365 DCD4 65 E5 ADC FR1+(5-#)
|
|
1365 DCD6 95 D9 STA FR0+(5-#),X
|
|
1365 DCD8 B5 D8 LDA FR0+(5-#),X
|
|
1365 DCDA 65 E4 ADC FR1+(5-#)
|
|
1365 DCDC 95 D8 STA FR0+(5-#),X
|
|
1365 DCDE B5 D7 LDA FR0+(5-#),X
|
|
1365 DCE0 65 E3 ADC FR1+(5-#)
|
|
1365 DCE2 95 D7 STA FR0+(5-#),X
|
|
1365 DCE4 B5 D6 LDA FR0+(5-#),X
|
|
1365 DCE6 65 E2 ADC FR1+(5-#)
|
|
1365 DCE8 95 D6 STA FR0+(5-#),X
|
|
1365 DCEA B5 D5 LDA FR0+(5-#),X
|
|
1365 DCEC 65 E1 ADC FR1+(5-#)
|
|
1365 DCEE 95 D5 STA FR0+(5-#),X
|
|
1365 DCF0 B5 D4 LDA FR0+(5-#),X
|
|
1365 DCF2 65 E0 ADC FR1+(5-#)
|
|
1365 DCF4 95 D4 STA FR0+(5-#),X
|
|
Source: source/Shared/mathpack.s
|
|
1369
|
|
1370 ;check if we have a carry out to the upper bytes
|
|
1371 DCF6 90 07 bcc no_carry
|
|
1372 DCF8 86 E6 stx _offset2
|
|
1373 DCFA 20 D5 D8 jsr fp_fmul_carryup.dec_entry
|
|
1374 DCFD A6 E6 ldx _offset2
|
|
1375 DCFF no_carry:
|
|
1376
|
|
1377 DCFF noadd:
|
|
1378 ;go back for next byte
|
|
1379 DCFF CA dex
|
|
1380 DD00 D0 CC bne offloop2
|
|
1381
|
|
1382 ;double fr1
|
|
1383 DD02 18 clc
|
|
1384 DD03 A5 E5 lda fr1+5
|
|
1385 DD05 65 E5 adc fr1+5
|
|
1386 DD07 85 E5 sta fr1+5
|
|
1387 DD09 A5 E4 lda fr1+4
|
|
1388 DD0B 65 E4 adc fr1+4
|
|
1389 DD0D 85 E4 sta fr1+4
|
|
1390 DD0F A5 E3 lda fr1+3
|
|
1391 DD11 65 E3 adc fr1+3
|
|
1392 DD13 85 E3 sta fr1+3
|
|
1393 DD15 A5 E2 lda fr1+2
|
|
1394 DD17 65 E2 adc fr1+2
|
|
1395 DD19 85 E2 sta fr1+2
|
|
1396 DD1B A5 E1 lda fr1+1
|
|
1397 DD1D 65 E1 adc fr1+1
|
|
1398 DD1F 85 E1 sta fr1+1
|
|
1399 DD21 A5 E0 lda fr1+0
|
|
1400 DD23 65 E0 adc fr1+0
|
|
1401 DD25 85 E0 sta fr1+0
|
|
1402
|
|
1403 ;loop back until all mantissa bytes finished
|
|
1404 DD27 88 dey
|
|
1405 DD28 D0 A2 bne offloop
|
|
1406
|
|
1407 ;check if no renormalize is needed, and if so, re-add new rounding
|
|
1408 DD2A A5 D5 lda fr0+1
|
|
1409 DD2C F0 07 beq renorm_needed
|
|
1410
|
|
1411 DD2E A9 50 lda #$50
|
|
1412 DD30 A2 06 ldx #6
|
|
1413 DD32 20 D1 D8 jsr fp_fmul_carryup
|
|
1414
|
|
1415 DD35 renorm_needed:
|
|
1416 ;all done
|
|
1417 DD35 4C FF DB jmp fp_normalize_cld
|
|
1418 .endp
|
|
1419
|
|
1420 ;==========================================================================
|
|
1421 ; PLYEVL [DD40] Eval polynomial at (X:Y) with A coefficients using FR0
|
|
1422 ;
|
|
1423 DD38 fixadr $dd3e
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
2 .print ($DD3E-*),' bytes free before ',$DD3E
|
|
2 $0006 bytes free before $DD3E
|
|
3 DD38 org $DD3E
|
|
Source: source/Shared/mathpack.s
|
|
1424 DD3E fp_plyevl_10:
|
|
1425 DD3E A9 0A lda #10
|
|
1426 DD40 .nowarn .proc plyevl
|
|
1427 ;stash arguments
|
|
1428 DD40 86 FE stx fptr2
|
|
1429 DD42 84 FF sty fptr2+1
|
|
1430 DD44 85 EC sta _fpcocnt
|
|
1431
|
|
1432 ;copy FR0 -> PLYARG
|
|
1433 DD46 A2 E0 ldx #<plyarg
|
|
1434 DD48 A0 05 ldy #>plyarg
|
|
1435 DD4A 20 A7 DD jsr fst0r
|
|
1436
|
|
1437 DD4D 20 44 DA jsr zfr0
|
|
1438
|
|
1439 DD50 loop:
|
|
1440 ;load next coefficient and increment coptr
|
|
1441 DD50 A5 FE lda fptr2
|
|
1442 DD52 AA tax
|
|
1443 DD53 18 clc
|
|
1444 DD54 69 06 adc #6
|
|
1445 DD56 85 FE sta fptr2
|
|
1446 DD58 A4 FF ldy fptr2+1
|
|
1447 DD5A 90 02 E6 FF scc:inc fptr2+1
|
|
1448 DD5E 20 98 DD jsr fld1r
|
|
1449
|
|
1450 ;add coefficient to acc
|
|
1451 DD61 20 66 DA jsr fadd
|
|
1452 DD64 B0 0D bcs xit
|
|
1453
|
|
1454 DD66 C6 EC dec _fpcocnt
|
|
1455 DD68 F0 09 beq xit
|
|
1456
|
|
1457 ;copy PLYARG -> FR1
|
|
1458 ;multiply accumulator by Z and continue
|
|
1459 DD6A A2 E0 ldx #<plyarg
|
|
1460 DD6C A0 05 ldy #>plyarg
|
|
1461 DD6E 20 D8 DA jsr fp_fld1r_fmul
|
|
1462 DD71 90 DD bcc loop
|
|
1463 DD73 xit:
|
|
1464 DD73 60 rts
|
|
1465 .endp
|
|
1466
|
|
1467 ;==========================================================================
|
|
1468 DD74 .proc fp_swap
|
|
1469 DD74 A2 05 ldx #5
|
|
1470 DD76 swaploop:
|
|
1471 DD76 B5 D4 lda fr0,x
|
|
1472 DD78 B4 E0 ldy fr1,x
|
|
1473 DD7A 95 E0 sta fr1,x
|
|
1474 DD7C 94 D4 sty fr0,x
|
|
1475 DD7E CA dex
|
|
1476 DD7F 10 F5 bpl swaploop
|
|
1477 DD81 60 rts
|
|
1478 .endp
|
|
1479
|
|
1480 ;==========================================================================
|
|
1481 ; FLD0R [DD89] Load FR0 from (X:Y)
|
|
1482 ; FLD0P [DD8D] Load FR0 from (FLPTR)
|
|
1483 ;
|
|
1484 DD82 fixadr $dd87
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
2 .print ($DD87-*),' bytes free before ',$DD87
|
|
2 $0005 bytes free before $DD87
|
|
3 DD82 org $DD87
|
|
Source: source/Shared/mathpack.s
|
|
1485 DD87 fld0r_zp:
|
|
1486 DD87 A0 00 ldy #0
|
|
1487 DD89 ckaddr $dd89
|
|
Macro: CKADDR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1488 DD89 fld0r:
|
|
1489 DD89 86 FC stx flptr
|
|
1490 DD8B 84 FD sty flptr+1
|
|
1491 DD8D ckaddr $dd8d
|
|
Macro: CKADDR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1492 DD8D fld0p:
|
|
1493 DD8D A0 05 ldy #5
|
|
1494 DD8F fld0ploop:
|
|
1495 DD8F B1 FC lda (flptr),y
|
|
1496 DD91 99 D4 00 sta fr0,y
|
|
1497 DD94 88 dey
|
|
1498 DD95 10 F8 bpl fld0ploop
|
|
1499 DD97 60 rts
|
|
1500
|
|
1501 ;==========================================================================
|
|
1502 ; FLD1R [DD98] Load FR1 from (X:Y)
|
|
1503 ; FLD1P [DD9C] Load FR1 from (FLPTR)
|
|
1504 ;
|
|
1505 DD98 fixadr $dd98
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1506 DD98 fld1r:
|
|
1507 DD98 86 FC stx flptr
|
|
1508 DD9A 84 FD sty flptr+1
|
|
1509 DD9C ckaddr $dd9c
|
|
Macro: CKADDR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1510 DD9C fld1p:
|
|
1511 DD9C A0 05 ldy #5
|
|
1512 DD9E fld1ploop:
|
|
1513 DD9E B1 FC lda (flptr),y
|
|
1514 DDA0 99 E0 00 sta fr1,y
|
|
1515 DDA3 88 dey
|
|
1516 DDA4 10 F8 bpl fld1ploop
|
|
1517 DDA6 60 rts
|
|
1518
|
|
1519 ;==========================================================================
|
|
1520 ; FST0R [DDA7] Store FR0 to (X:Y)
|
|
1521 ; FST0P [DDAB] Store FR0 to (FLPTR)
|
|
1522 ;
|
|
1523 DDA7 fixadr $dda7
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1524 DDA7 fst0r:
|
|
1525 DDA7 86 FC stx flptr
|
|
1526 DDA9 84 FD sty flptr+1
|
|
1527 DDAB ckaddr $ddab
|
|
Macro: CKADDR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1528 DDAB fst0p:
|
|
1529 DDAB A0 05 ldy #5
|
|
1530 DDAD fst0ploop:
|
|
1531 DDAD B9 D4 00 lda fr0,y
|
|
1532 DDB0 91 FC sta (flptr),y
|
|
1533 DDB2 88 dey
|
|
1534 DDB3 10 F8 bpl fst0ploop
|
|
1535 DDB5 60 rts
|
|
1536
|
|
1537 ;==========================================================================
|
|
1538 ; FMOVE [DDB6] Move FR0 to FR1
|
|
1539 ;
|
|
1540 DDB6 fixadr $ddb6
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1541 DDB6 fmove:
|
|
1542 DDB6 A2 05 ldx #5
|
|
1543 DDB8 fmoveloop:
|
|
1544 DDB8 B5 D4 lda fr0,x
|
|
1545 DDBA 95 E0 sta fr1,x
|
|
1546 DDBC CA dex
|
|
1547 DDBD 10 F9 bpl fmoveloop
|
|
1548 DDBF 60 rts
|
|
1549
|
|
1550 ;==========================================================================
|
|
1551 ; EXP [DDC0] Compute e^x
|
|
1552 ; EXP10 [DDCC] Compute 10^x
|
|
1553 ;
|
|
1554 DDC0 fixadr $ddc0
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1555 = DDCC exp10 = exp._exp10
|
|
1556 DDC0 .proc exp
|
|
1557 DDC0 A2 64 ldx #<fpconst_log10_e
|
|
1558 DDC2 A0 DE ldy #>fpconst_log10_e
|
|
1559 DDC4 20 98 DD jsr fld1r ;we could use fp_fld1r_fmul, but then we have a hole :(
|
|
1560 DDC7 20 DB DA jsr fmul
|
|
1561 DDCA B0 5B bcs err2
|
|
1562
|
|
1563 DDCC ckaddr $ddcc
|
|
Macro: CKADDR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1564 DDCC _exp10:
|
|
1565 ;stash sign and compute abs
|
|
1566 DDCC A5 D4 lda fr0
|
|
1567 DDCE 85 EE sta _fptemp1
|
|
1568 DDD0 29 7F and #$7f
|
|
1569 DDD2 85 D4 sta fr0
|
|
1570
|
|
1571 DDD4 A0 00 ldy #0
|
|
1572
|
|
1573 ;check for |exp| >= 100 which would guarantee over/underflow
|
|
1574 DDD6 C9 40 cmp #$40
|
|
1575 DDD8 90 1E bcc abs_ok
|
|
1576 DDDA F0 08 beq abs_large
|
|
1577
|
|
1578 DDDC abs_too_big:
|
|
1579 ;okay, the |x| is too big... check if the original was negative.
|
|
1580 ;if so, zero and exit, otherwise error.
|
|
1581 DDDC A5 EE lda _fptemp1
|
|
1582 DDDE 10 47 bpl err2
|
|
1583 DDE0 18 clc
|
|
1584 DDE1 4C 44 DA jmp zfr0
|
|
1585
|
|
1586 DDE4 abs_large:
|
|
1587 ;|exp|>=1, so split it into integer/fraction
|
|
1588 DDE4 A5 D5 lda fr0+1
|
|
1589 DDE6 20 CD DA jsr fp_dectobin
|
|
1590 DDE9 79 F6 DF adc fp_dectobin_tab,y
|
|
1591 DDEC 48 pha
|
|
1592 DDED A9 00 lda #0
|
|
1593 DDEF 85 D5 sta fr0+1
|
|
1594 DDF1 85 DA sta fr0+6
|
|
1595 DDF3 20 00 DC jsr fp_normalize
|
|
1596 DDF6 68 pla
|
|
1597 DDF7 A8 tay
|
|
1598
|
|
1599 DDF8 abs_ok:
|
|
1600 ;stash integer portion of exponent
|
|
1601 DDF8 84 ED sty _fptemp0
|
|
1602
|
|
1603 ;compute approximation z = 10^y
|
|
1604 DDFA A2 28 ldx #<coeff
|
|
1605 DDFC A0 DE ldy #>coeff
|
|
1606 DDFE 20 3E DD jsr fp_plyevl_10
|
|
1607
|
|
1608 ;tweak exponent
|
|
1609 DE01 46 ED lsr _fptemp0
|
|
1610
|
|
1611 ;scale by 10 if necessary
|
|
1612 DE03 90 07 bcc even
|
|
1613 DE05 A2 1C ldx #<fpconst_ten
|
|
1614 DE07 20 D6 DA jsr fp_fld1r_const_fmul
|
|
1615 DE0A B0 D0 bcs abs_too_big
|
|
1616 DE0C even:
|
|
1617
|
|
1618 ;bias exponent
|
|
1619 DE0C A5 ED lda _fptemp0
|
|
1620 DE0E 65 D4 adc fr0
|
|
1621 DE10 C9 71 cmp #64+49
|
|
1622 DE12 B0 C8 bcs abs_too_big
|
|
1623 DE14 85 D4 sta fr0
|
|
1624
|
|
1625 ;check if we should invert
|
|
1626 DE16 26 EE rol _fptemp1
|
|
1627 DE18 90 0D bcc xit2
|
|
1628
|
|
1629 DE1A 20 B6 DD jsr fmove
|
|
1630 DE1D A2 EA ldx #<fp_one
|
|
1631 DE1F A0 DF ldy #>fp_one
|
|
1632 DE21 20 89 DD jsr fld0r
|
|
1633 DE24 4C 28 DB jmp fdiv
|
|
1634
|
|
1635 DE27 err2:
|
|
1636 DE27 xit2:
|
|
1637 DE27 60 rts
|
|
1638
|
|
1639 DE28 coeff: ;Minimax polynomial for 10^x over 0 <= x < 1
|
|
1640 DE28 3F 01 46 90 83 08 .fl 0.0146908308
|
|
1641 DE2E BE 20 05 33 11 71 .fl -0.002005331171
|
|
1642 DE34 3F 09 19 45 20 45 .fl 0.0919452045
|
|
1643 DE3A 3F 19 21 38 38 84 .fl 0.1921383884
|
|
1644 DE40 3F 54 47 32 51 97 .fl 0.5447325197
|
|
1645 DE46 40 01 17 01 82 49 .fl 1.17018250
|
|
1646 DE4C 40 02 03 47 85 80 .fl 2.03478581
|
|
1647 DE52 40 02 65 09 44 94 .fl 2.65094494
|
|
1648 DE58 40 02 30 25 85 11 .fl 2.30258512
|
|
1649 DE5E 40 01 00 00 00 00 .fl 1
|
|
1650 .endp
|
|
1651
|
|
1652 ;==========================================================================
|
|
1653 DE64 fpconst_log10_e:
|
|
1654 DE64 3F 43 42 94 48 18 .fl 0.43429448190325182765112891891661
|
|
1655
|
|
1656 DE6A .proc fp_carry_expup
|
|
1657 ;adjust exponent
|
|
1658 DE6A E6 D4 inc fr0
|
|
1659
|
|
1660 ;shift down FR0
|
|
1661 DE6C A2 04 ldx #4
|
|
1662 DE6E sum_shiftloop:
|
|
1663 DE6E B5 D4 lda fr0,x
|
|
1664 DE70 95 D5 sta fr0+1,x
|
|
1665 DE72 CA dex
|
|
1666 DE73 D0 F9 bne sum_shiftloop
|
|
1667
|
|
1668 ;add a $01 at the top
|
|
1669 DE75 E8 inx
|
|
1670 DE76 86 D5 stx fr0+1
|
|
1671 DE78 60 rts
|
|
1672 .endp
|
|
1673
|
|
1674 ;==========================================================================
|
|
1675 DE79 .proc fp_fmul_fr0_to_binfr2 ;$15 bytes
|
|
1676 DE79 A2 04 ldx #4
|
|
1677 DE7B loop:
|
|
1678 DE7B B5 D5 lda fr0+1,x
|
|
1679 DE7D 4A lsr
|
|
1680 DE7E 4A lsr
|
|
1681 DE7F 4A lsr
|
|
1682 DE80 4A lsr
|
|
1683 DE81 A8 tay
|
|
1684 DE82 18 clc
|
|
1685 DE83 B5 D5 lda fr0+1,x
|
|
1686 DE85 79 F6 DF adc fp_dectobin_tab,y
|
|
1687 DE88 49 FF eor #$ff
|
|
1688 DE8A 95 E7 sta fr2+1,x
|
|
1689 DE8C CA dex
|
|
1690 DE8D 10 EC bpl loop
|
|
1691 = DE8F .def :fp_rts1
|
|
1692 DE8F 60 rts
|
|
1693 .endp
|
|
1694
|
|
1695 ;==========================================================================
|
|
1696 ; REDRNG [DE95] Reduce range via y = (x-C)/(x+C) (undocumented)
|
|
1697 ;
|
|
1698 ; X:Y = pointer to C argument
|
|
1699 ;
|
|
1700 DE90 fixadr $de95
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
2 .print ($DE95-*),' bytes free before ',$DE95
|
|
2 $0005 bytes free before $DE95
|
|
3 DE90 org $DE95
|
|
Source: source/Shared/mathpack.s
|
|
1701 = DE95 redrng = _redrng
|
|
1702 DE95 .proc _redrng
|
|
1703 DE95 86 FE stx fptr2
|
|
1704 DE97 84 FF sty fptr2+1
|
|
1705 DE99 20 98 DD jsr fld1r
|
|
1706 DE9C A2 E6 ldx #<fpscr
|
|
1707 DE9E A0 05 ldy #>fpscr
|
|
1708 DEA0 20 A7 DD jsr fst0r
|
|
1709 DEA3 20 66 DA jsr fadd
|
|
1710 DEA6 B0 E7 bcs fail
|
|
1711 DEA8 A2 E0 ldx #<plyarg
|
|
1712 DEAA A0 05 ldy #>plyarg
|
|
1713 DEAC 20 A7 DD jsr fst0r
|
|
1714 DEAF A2 E6 ldx #<fpscr
|
|
1715 DEB1 A0 05 ldy #>fpscr
|
|
1716 DEB3 20 89 DD jsr fld0r
|
|
1717 DEB6 A6 FE ldx fptr2
|
|
1718 DEB8 A4 FF ldy fptr2+1
|
|
1719 DEBA 20 98 DD jsr fld1r
|
|
1720 DEBD 20 60 DA jsr fsub
|
|
1721 DEC0 B0 CD bcs fail
|
|
1722 DEC2 A2 E0 ldx #<plyarg
|
|
1723 DEC4 A0 05 ldy #>plyarg
|
|
1724 DEC6 20 98 DD jsr fld1r
|
|
1725 DEC9 4C 28 DB jmp fdiv
|
|
1726
|
|
1727 = DE8F fail = fp_rts1
|
|
1728 .endp
|
|
1729
|
|
1730 ;==========================================================================
|
|
1731 ; LOG [DECD] Compute ln x
|
|
1732 ; LOG10 [DED1] Compute log10 x
|
|
1733 ;
|
|
1734 DECC fixadr $decd
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
2 .print ($DECD-*),' bytes free before ',$DECD
|
|
2 $0001 bytes free before $DECD
|
|
3 DECC org $DECD
|
|
Source: source/Shared/mathpack.s
|
|
1735 = DED1 log10 = log._log10
|
|
1736 DECD .proc log
|
|
1737 DECD 46 EE lsr _fptemp1
|
|
1738 DECF 10 03 bpl entry
|
|
1739 DED1 ckaddr $ded1
|
|
Macro: CKADDR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1740 DED1 _log10:
|
|
1741 DED1 38 sec
|
|
1742 DED2 66 EE ror _fptemp1
|
|
1743 DED4 entry:
|
|
1744 ;throw error on negative number
|
|
1745 DED4 A5 D4 lda fr0
|
|
1746 DED6 30 6E bmi err
|
|
1747
|
|
1748 ;stash exponentx2 - 128
|
|
1749 DED8 0A asl
|
|
1750 DED9 49 80 eor #$80
|
|
1751 DEDB 85 ED sta _fptemp0
|
|
1752
|
|
1753 ;raise error if argument is zero
|
|
1754 DEDD A5 D5 lda fr0+1
|
|
1755 DEDF F0 65 beq err
|
|
1756
|
|
1757 ;reset exponent so we are in 1 <= z < 100
|
|
1758 DEE1 A2 40 ldx #$40
|
|
1759 DEE3 86 D4 stx fr0
|
|
1760
|
|
1761 ;split into three ranges based on mantissa:
|
|
1762 ; 1/sqrt(10) <= x < 1: [31, 99] divide by 100
|
|
1763 ; sqrt(10)/100 <= x < 1/sqrt(10): [ 3, 30] divide by 10
|
|
1764 ; 0 < x < sqrt(10)/100: [ 1, 2] leave as-is
|
|
1765
|
|
1766 DEE5 C9 03 cmp #$03
|
|
1767 DEE7 90 13 bcc post_range_adjust
|
|
1768 DEE9 C9 31 cmp #$31
|
|
1769 DEEB 90 04 bcc mid_range
|
|
1770
|
|
1771 ;increase result by 1 (equivalent to *10 input)
|
|
1772 DEED E6 ED inc _fptemp0
|
|
1773 DEEF D0 07 bne adjust_exponent
|
|
1774
|
|
1775 DEF1 mid_range:
|
|
1776 ;multiply by 10
|
|
1777 DEF1 A2 1C ldx #<fpconst_ten
|
|
1778 DEF3 20 D6 DA jsr fp_fld1r_const_fmul
|
|
1779 DEF6 B0 4F bcs err2
|
|
1780
|
|
1781 DEF8 adjust_exponent:
|
|
1782 ;increase result by 1 (equivalent to *10 input)
|
|
1783 DEF8 E6 ED inc _fptemp0
|
|
1784
|
|
1785 ;divide fraction by 100
|
|
1786 DEFA C6 D4 dec fr0
|
|
1787
|
|
1788 DEFC post_range_adjust:
|
|
1789 ;at this point, we have 0.30 <= z <= 3; apply y = (z-1)/(z+1) transform
|
|
1790 ;so we can use a faster converging series... this reduces y to
|
|
1791 ;0 <= y < 0.81
|
|
1792 DEFC A2 EA ldx #<fp_one
|
|
1793 DEFE A0 DF ldy #>fp_one
|
|
1794 DF00 20 95 DE jsr redrng
|
|
1795
|
|
1796 ;stash y so we can later multiply it back in
|
|
1797 DF03 A2 E6 ldx #<fpscr
|
|
1798 DF05 A0 05 ldy #>fpscr
|
|
1799 DF07 20 A7 DD jsr fst0r
|
|
1800
|
|
1801 ;square the value so we compute a series on y^2n
|
|
1802 DF0A 20 B6 DD jsr fmove
|
|
1803 DF0D 20 DB DA jsr fmul
|
|
1804
|
|
1805 ;do polynomial expansion
|
|
1806 DF10 A2 72 ldx #<fpconst_log10coeff
|
|
1807 DF12 A0 DF ldy #>fpconst_log10coeff
|
|
1808 DF14 20 3E DD jsr fp_plyevl_10
|
|
1809 DF17 B0 2E bcs err2
|
|
1810
|
|
1811 ;multiply back in so we have series on y^(2n+1)
|
|
1812 DF19 A2 E6 ldx #<fpscr
|
|
1813 DF1B A0 05 ldy #>fpscr
|
|
1814 DF1D 20 D8 DA jsr fp_fld1r_fmul
|
|
1815
|
|
1816 ;stash
|
|
1817 DF20 20 B6 DD jsr fmove
|
|
1818
|
|
1819 ;convert exponent adjustment back to float (signed)
|
|
1820 DF23 A9 00 lda #0
|
|
1821 DF25 85 D5 sta fr0+1
|
|
1822 DF27 A6 ED ldx _fptemp0
|
|
1823 DF29 10 04 bpl expadj_positive
|
|
1824 DF2B 38 sec
|
|
1825 DF2C E5 ED sbc _fptemp0
|
|
1826 DF2E AA tax
|
|
1827 DF2F expadj_positive:
|
|
1828 DF2F 86 D4 stx fr0
|
|
1829 DF31 20 AA D9 jsr ipf
|
|
1830
|
|
1831 ;merge (cannot fail)
|
|
1832 DF34 06 D4 asl fr0
|
|
1833 DF36 06 ED asl _fptemp0
|
|
1834 DF38 66 D4 ror fr0
|
|
1835 DF3A 20 66 DA jsr fadd
|
|
1836
|
|
1837 ;scale if doing log
|
|
1838 DF3D 24 EE bit _fptemp1
|
|
1839 DF3F 30 06 bmi xit2
|
|
1840
|
|
1841 DF41 A2 22 ldx #<fpconst_ln10
|
|
1842 DF43 4C D6 DA jmp fp_fld1r_const_fmul
|
|
1843
|
|
1844 DF46 err:
|
|
1845 DF46 38 sec
|
|
1846 DF47 xit2:
|
|
1847 DF47 err2:
|
|
1848 DF47 60 rts
|
|
1849 .endp
|
|
1850
|
|
1851 ;==========================================================================
|
|
1852 DF48 .proc fp_tab_lo_1000
|
|
1853 DF48 00 E8 D0 B8 A0 88 + :10 dta <[1000*#]
|
|
1854 .endp
|
|
1855
|
|
1856 DF52 .proc fp_tab_hi_1000
|
|
1857 DF52 00 03 07 0B 0F 13 + :10 dta >[1000*#]
|
|
1858 .endp
|
|
1859
|
|
1860 DF5C .proc fp_tab_hi_100
|
|
1861 DF5C 00 00 00 01 01 01 + :10 dta >[100*#]
|
|
1862 .endp
|
|
1863
|
|
1864 DF66 .proc fp_tab_hi_10000
|
|
1865 DF66 27 4E 75 9C C3 EA :6 dta >[10000*[#+1]]
|
|
1866 .endp
|
|
1867
|
|
1868 ;==========================================================================
|
|
1869 ; HALF (used by Atari BASIC)
|
|
1870 ;
|
|
1871 DF6C fixadr $df6c
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1872 DF6C fpconst_half:
|
|
1873 DF6C 3F 50 00 00 00 00 .fl 0.5
|
|
1874
|
|
1875 ;==========================================================================
|
|
1876 ; log10(x) coefficients
|
|
1877 ;
|
|
1878 ; LOG10 computes:
|
|
1879 ; -0.30 <= z <= 3.0
|
|
1880 ; y = (z-1)/(z+1) -0.54 <= y <= 0.5
|
|
1881 ; x = y^2 0 <= x <= 0.29
|
|
1882 ; log10(z) = f(x)*y
|
|
1883 ;
|
|
1884 ; Therefore:
|
|
1885 ; f(x) = log10((1+y)/(1-y))/y
|
|
1886 ;
|
|
1887 DF72 fpconst_log10coeff: ;Maclaurin series expansion for log10((z-1)/(z+1))
|
|
1888 DF72 3F 20 26 22 71 53 .fl 0.2026227154
|
|
1889 DF78 BF 07 32 04 49 21 .fl -0.0732044921
|
|
1890 DF7E 3F 10 60 98 35 64 .fl 0.1060983564
|
|
1891 DF84 3F 05 60 41 73 29 .fl 0.0560417329
|
|
1892 DF8A 3F 08 04 18 84 06 .fl 0.0804188407
|
|
1893 DF90 3F 09 63 91 60 14 .fl 0.0963916015
|
|
1894 DF96 3F 12 40 89 61 35 .fl 0.1240896135
|
|
1895 DF9C 3F 17 37 17 66 45 .fl 0.1737176646
|
|
1896 DFA2 3F 28 95 29 65 58 .fl 0.2895296558
|
|
1897 DFA8 3F 86 85 88 96 37 .fl 0.8685889638
|
|
1898
|
|
1899 ;==========================================================================
|
|
1900 ; Arctangent coefficients
|
|
1901 ;
|
|
1902 ; The 11 coefficients here form a power series approximation
|
|
1903 ; f(x^2) ~= atn(x)/x. This is not an official feature of the math pack but
|
|
1904 ; is relied upon by BASIC.
|
|
1905 ;
|
|
1906 ; We used to use the coefficients from Abramowitz & Stegun 4.4.49 here, but
|
|
1907 ; there seems to be an error there such that the result falls far short
|
|
1908 ; of the specified 2x10^-8 accuracy over 0<=x<=1 at x=1. Instead, we now
|
|
1909 ; use a custom minimax polynomial for f(y)=atn(sqrt(y))/sqrt(y) where y=x^2.
|
|
1910 ;
|
|
1911 DFAE fixadr $dfae
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1912 DFAE atncoef: ;coefficients for atn(x)/x ~= f(x^2)
|
|
1913 ;see Abramowitz & Stegun 4.4.49
|
|
1914
|
|
1915 DFAE 3E 11 12 07 58 81 .fl 0.001112075881 ;x**10*1.11207588057982e-3
|
|
1916 DFB4 BE 73 04 08 75 20 .fl -0.007304087520 ;x**9*-7.30408751951452e-3
|
|
1917 DFBA 3F 02 24 96 55 73 .fl 0.0224965573 ;x**8*2.24965572957342e-2
|
|
1918 DFC0 BF 04 46 18 51 71 .fl -0.0446185172 ;x**7*-4.46185172165888e-2
|
|
1919 DFC6 3F 06 73 46 32 44 .fl 0.0673463245 ;x**6*6.73463245104305e-2
|
|
1920 DFCC BF 08 80 69 06 64 .fl -0.0880690664 ;x**5*-8.80690663570546e-2
|
|
1921 DFD2 3F 11 05 66 74 99 .fl 0.1105667499 ;x**4*1.10566749879313e-1
|
|
1922 DFD8 BF 14 27 94 93 12 .fl -0.1427949312 ;x**3*-1.42794931245212e-1
|
|
1923 DFDE 3F 19 99 96 30 60 .fl 0.1999963060 ;x**2*1.99996306023439e-1
|
|
1924 DFE4 BF 33 33 33 24 72 .fl -0.3333332472 ;x**1*-3.33333247188074e-1
|
|
1925 ;x**0*9.99999999667198e-1
|
|
1926 DFEA fp_one:
|
|
1927 DFEA 40 01 00 00 00 00 .fl 1.0 ;also an arctan coeff
|
|
1928 DFF0 fixadr $dff0
|
|
Macro: FIXADR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
1929 DFF0 fp_pi4: ;pi/4 - needed by Atari Basic ATN()
|
|
1930 DFF0 3F 78 53 98 16 34 .fl 0.78539816339744830961566084581988
|
|
1931
|
|
1932 DFF6 fp_dectobin_tab:
|
|
1933 DFF6 00 FA F4 EE E8 E2 + :10 dta <[-6*#]
|
|
1934
|
|
1935 E000 ckaddr $e000
|
|
Macro: CKADDR [Source: source/Shared/mathpack.s]
|
|
Source: source/Shared/mathpack.s
|
|
102
|
|
103 E000 org $e000
|
|
104 E000 icl 'atarifont.inc'
|
|
Source: source/Shared/atarifont.inc
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Character Font
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 E000 00 00 00 00 00 00 + ins 'atarifont.bin',$0,$400
|
|
105
|
|
106 E400 org $e400
|
|
107 E400 F9 F9 editrv dta a(EditorOpen-1)
|
|
108 E402 27 FE dta a(EditorClose-1)
|
|
109 E404 05 FA dta a(EditorGetByte-1)
|
|
110 E406 B7 FA dta a(EditorPutByte-1)
|
|
111 E408 C8 E4 dta a(EditorGetStatus-1)
|
|
112 E40A CA E4 dta a(EditorSpecial-1)
|
|
113 E40C 4C CB E4 jmp EditorInit
|
|
114 E40F 00 dta $00
|
|
115
|
|
116 E410 F5 F3 screnv dta a(ScreenOpen-1)
|
|
117 E412 27 FE dta a(ScreenClose-1)
|
|
118 E414 D1 F5 dta a(ScreenGetByte-1)
|
|
119 E416 11 F6 dta a(ScreenPutByte-1)
|
|
120 E418 C8 E4 dta a(ScreenGetStatus-1)
|
|
121 E41A F5 F6 dta a(ScreenSpecial-1)
|
|
122 E41C 20 C4 F5 jsr ScreenInit
|
|
123 E41F 00 dta $00
|
|
124
|
|
125 E420 C8 E4 keybdv dta a(KeyboardOpen-1)
|
|
126 E422 C8 E4 dta a(KeyboardClose-1)
|
|
127 E424 68 FE dta a(KeyboardGetByte-1)
|
|
128 E426 CA E4 dta a(KeyboardPutByte-1)
|
|
129 E428 C8 E4 dta a(KeyboardGetStatus-1)
|
|
130 E42A CA E4 dta a(KeyboardSpecial-1)
|
|
131 E42C 4C 3F FE jmp KeyboardInit
|
|
132 E42F 00 dta $00
|
|
133
|
|
134 E430 83 EC printv dta a(PrinterOpen-1)
|
|
135 E432 98 EC dta a(PrinterClose-1)
|
|
136 E434 CA E4 dta a(PrinterGetByte-1)
|
|
137 E436 9F EC dta a(PrinterPutByte-1)
|
|
138 E438 ED EC dta a(PrinterGetStatus-1)
|
|
139 E43A CA E4 dta a(PrinterSpecial-1)
|
|
140 E43C 20 7E EC jsr PrinterInit
|
|
141 E43F 00 dta $00
|
|
142
|
|
143 E440 19 ED casetv dta a(CassetteOpen-1)
|
|
144 E442 6E ED dta a(CassetteClose-1)
|
|
145 E444 8F ED dta a(CassetteGetByte-1)
|
|
146 E446 CF ED dta a(CassettePutByte-1)
|
|
147 E448 C8 E4 dta a(CassetteGetStatus-1)
|
|
148 E44A CA E4 dta a(CassetteSpecial-1)
|
|
149 E44C 4C 0F ED jmp CassetteInit
|
|
150 E44F 00 dta $00
|
|
151
|
|
152 ;vector table
|
|
153 E450 org $e450
|
|
154 E450 4C 0E EC diskiv jmp DiskInit ;$E450
|
|
155 E453 4C 19 EC dskinv jmp DiskHandler ;$E453
|
|
156 E456 4C FC E4 ciov jmp CIO ;$E456
|
|
157 E459 4C F6 E7 siov jmp SIO ;$E459
|
|
158 E45C 4C 5F C1 setvbv jmp VBISetVector ;$E45C
|
|
159 E45F 4C 0C C0 sysvbv jmp VBIStage1 ;$E45F
|
|
160 E462 4C 50 C0 xitvbv jmp VBIExit ;$E462
|
|
161 E465 4C EB E7 sioinv jmp SIOInit ;$E465
|
|
162 E468 4C 47 E9 sendev jmp SIOSendEnable ;$E468
|
|
163 E46B 4C 75 C1 intinv jmp IntInitInterrupts ;$E46B
|
|
164 E46E 4C EA E4 cioinv jmp CIOInit ;$E46E
|
|
165
|
|
166 .if _KERNEL_XLXE
|
|
167 E471 4C 9B E4 blkbdv jmp SelfTestEntry ;$E471
|
|
168 .else
|
|
169 blkbdv jmp Blackboard ;$E471
|
|
170 .endif
|
|
171
|
|
172 E474 4C 4F EF warmsv jmp InitWarmStart ;$E474
|
|
173 E477 4C D6 EE coldsv jmp InitColdStart ;$E477
|
|
174 E47A 4C 10 EE rblokv jmp CassetteReadBlock ;$E47A
|
|
175 E47D 4C 2D ED csopiv jmp CassetteOpenRead ;$E47D
|
|
176
|
|
177 .if _KERNEL_XLXE
|
|
178 E480 4C 9B E4 pupdiv jmp SelfTestEntry ;$E480 XL/XE: power-up display
|
|
179 E483 4C 00 50 slftsv jmp $5000 ;$E483 XL/XE: self-test entry
|
|
180 E486 4C 22 C3 pentv jmp PHAddHandler ;$E486 XL/XE: peripheral handler add
|
|
181 E489 4C 58 C3 phunlv jmp PHRemoveHandler ;$E489 XL/XE: peripheral handler remove
|
|
182 E48C 4C 9E C3 phiniv jmp PHInitHandler ;$E48C XL/XE: peripheral handler init
|
|
183 E48F gpdvv PBI_VECTOR_TABLE ;$E48F XL/XE: Generic device vector
|
|
Macro: PBI_VECTOR_TABLE [Source: source/Shared/pbi.s]
|
|
1 E48F CF C2 dta a(PBIGenericDeviceOpen-1)
|
|
2 E491 D3 C2 dta a(PBIGenericDeviceClose-1)
|
|
3 E493 D7 C2 dta a(PBIGenericDeviceGetByte-1)
|
|
4 E495 DB C2 dta a(PBIGenericDevicePutByte-1)
|
|
5 E497 19 C3 dta a(PBIGenericDeviceGetStatus-1)
|
|
6 E499 1D C3 dta a(PBIGenericDeviceSpecial-1)
|
|
Source: source/main.xasm
|
|
184 .endif
|
|
185
|
|
186 .if _KERNEL_XLXE
|
|
187 E49B icl 'selftestentry.s'
|
|
Source: source/Shared/selftestentry.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Self Test Entry Trampoline
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 E49B .proc SelfTestEntry
|
|
11 E49B AD 01 D3 lda portb
|
|
12 E49E 29 7F and #$7f
|
|
13 E4A0 8D 01 D3 sta portb
|
|
14 E4A3 4C 00 50 jmp BootScreen
|
|
15 .endp
|
|
188 .else
|
|
189 icl 'blackboard.s'
|
|
190 .endif
|
|
191
|
|
192 ;==============================================================================
|
|
193 ; $E4C0 Known RTS instruction
|
|
194 ;
|
|
195 ; The Atari 850 handler uses this as a "known RTS" instruction, as does
|
|
196 ; Altirra's internal R: handler emulation.
|
|
197 ;
|
|
198 E4A6 org $e4c0
|
|
199
|
|
200 E4C0 .nowarn .proc KnownRTS
|
|
201 E4C0 60 rts
|
|
202 .endp
|
|
203
|
|
204 ;==============================================================================
|
|
205 ; Main modules.
|
|
206 ;
|
|
207 ; We report the sizes here as well as reference sizes. The reference sizes for
|
|
208 ; OS-B come from Mapping the Atari.
|
|
209 ;
|
|
210
|
|
211 .echo 'Module sizes:'
|
|
211 Module sizes:
|
|
212
|
|
213 .macro _KERNEL_REPORT_MODULE_MARK
|
|
214 .def ?@_kernel_lastpt = *
|
|
215 .endm
|
|
216
|
|
217 .macro _KERNEL_REPORT_MODULE_PAD_ADJUST
|
|
218 .def ?@_kernel_lastpt = ?@_kernel_lastpt + :1
|
|
219 .endm
|
|
220
|
|
221 .macro _KERNEL_REPORT_MODULE_SIZE
|
|
222 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', :2, ')', ' ', :1
|
|
223
|
|
224 .def ?@_kernel_lastpt = *
|
|
225 .endm
|
|
226
|
|
227 E4C1 icl 'misc.s'
|
|
Source: source/Shared/misc.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Miscellaneous data
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11 ;Used by PBI and display/editor.
|
|
12 ;
|
|
13 E4C1 .proc ReversedBitMasks
|
|
14 E4C1 80 40 20 10 08 04 + dta $80,$40,$20,$10,$08,$04,$02,$01
|
|
15 .endp
|
|
16
|
|
17 ;==========================================================================
|
|
18 ;Used by CIO devices
|
|
19 E4C9 .proc CIOExitSuccess
|
|
20 E4C9 A0 01 ldy #1
|
|
21 E4CB exit_not_supported:
|
|
22 E4CB 60 rts
|
|
23 .endp
|
|
24
|
|
25 = E4CB CIOExitNotSupported = CIOExitSuccess.exit_not_supported
|
|
26
|
|
27 ;==========================================================================
|
|
28 ; Sound a bell using the console speaker.
|
|
29 ;
|
|
30 ; Entry:
|
|
31 ; Y = duration
|
|
32 ;
|
|
33 ; Modified:
|
|
34 ; X
|
|
35 ;
|
|
36 ; Preserved:
|
|
37 ; A
|
|
38 ;
|
|
39 E4CC .proc Bell
|
|
40 E4CC 48 pha
|
|
41 E4CD A9 08 lda #$08
|
|
42 E4CF soundloop:
|
|
43 E4CF A2 04 ldx #4
|
|
44 E4D1 48 pha
|
|
45 E4D2 delay:
|
|
46 E4D2 AD 0B D4 lda vcount
|
|
47 E4D5 CD 0B D4 F0 FB cmp:req vcount
|
|
48 E4DA CA dex
|
|
49 E4DB D0 F5 bne delay
|
|
50 E4DD 68 pla
|
|
51 E4DE 49 08 eor #$08
|
|
52 E4E0 8D 1F D0 sta consol
|
|
53 E4E3 D0 EA bne soundloop
|
|
54 E4E5 88 dey
|
|
55 E4E6 D0 E7 bne soundloop
|
|
56 E4E8 68 pla
|
|
57 E4E9 60 rts
|
|
58 .endp
|
|
228 E4EA _KERNEL_REPORT_MODULE_MARK
|
|
Macro: _KERNEL_REPORT_MODULE_MARK [Source: source/main.xasm]
|
|
1 = E4EA .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
229
|
|
230 E4EA icl 'cio.inc'
|
|
Source: source/Shared/cio.inc
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Character Input/Output Definitions
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 .ifndef f_CIO_INC
|
|
11 .def f_CIO_INC
|
|
12
|
|
13 CIOStatBreak = $80 ;break key abort
|
|
14 CIOStatIOCBInUse = $81 ;IOCB in use
|
|
15 CIOStatUnkDevice = $82 ;unknown device
|
|
16 CIOStatWriteOnly = $83 ;opened for write only
|
|
17 CIOStatInvalidCmd = $84 ;invalid command
|
|
18 CIOStatNotOpen = $85 ;device or file not open
|
|
19 CIOStatInvalidIOCB = $86 ;invalid IOCB number
|
|
20 CIOStatReadOnly = $87 ;opened for read only
|
|
21 CIOStatEndOfFile = $88 ;end of file reached
|
|
22 CIOStatTruncRecord = $89 ;record truncated
|
|
23 CIOStatTimeout = $8A ;device timeout
|
|
24 CIOStatNAK = $8B ;device NAK
|
|
25 CIOStatSerFrameErr = $8C ;serial bus framing error
|
|
26 CIOStatCursorRange = $8D ;cursor out of range
|
|
27 CIOStatSerOverrun = $8E ;serial frame overrun error
|
|
28 CIOStatSerChecksum = $8F ;serial checksum error
|
|
29 CIOStatDeviceDone = $90 ;device done error
|
|
30 CIOStatBadScrnMode = $91 ;bad screen mode
|
|
31 CIOStatNotSupported = $92 ;function not supported by handler
|
|
32 CIOStatOutOfMemory = $93 ;not enough memory
|
|
33 CIOStatDriveNumErr = $A0 ;disk drive # error
|
|
34 CIOStatTooManyFiles = $A1 ;too many open disk files
|
|
35 CIOStatDiskFull = $A2 ;disk full
|
|
36 CIOStatFatalDiskIO = $A3 ;fatal disk I/O error
|
|
37 CIOStatFileNumDiff = $A4 ;internal file # mismatch
|
|
38 CIOStatFileNameErr = $A5 ;filename error
|
|
39 CIOStatPointDLen = $A6 ;point data length error
|
|
40 CIOStatFileLocked = $A7 ;file locked
|
|
41 CIOStatInvDiskCmd = $A8 ;invalid command for disk
|
|
42 CIOStatDirFull = $A9 ;directory full (64 files)
|
|
43 CIOStatFileNotFound = $AA ;file not found
|
|
44 CIOStatInvPoint = $AB ;invalid point
|
|
45
|
|
46 CIOCmdOpen = $03
|
|
47 CIOCmdGetRecord = $05
|
|
48 CIOCmdGetChars = $07
|
|
49 CIOCmdPutRecord = $09
|
|
50 ; $0A ;PUT CHARS alias (required by K-Razy Shoot Out)
|
|
51 CIOCmdPutChars = $0B
|
|
52 CIOCmdClose = $0C
|
|
53 CIOCmdGetStatus = $0D
|
|
54 CIOCmdSpecial = $0E ;$0E and up is escape
|
|
55
|
|
56 .endif
|
|
231
|
|
232 .ifdef _KERNEL_816
|
|
233 icl 'cio816.s'
|
|
234 .else
|
|
235 E4EA icl 'cio.s'
|
|
Source: source/Shared/cio.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Character Input/Output Facility
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 E4EA .proc CIOInit
|
|
11 E4EA 38 sec
|
|
12 E4EB A2 70 ldx #$70
|
|
13 E4ED iocb_loop:
|
|
14 E4ED A9 FF lda #$ff
|
|
15 E4EF 9D 40 03 sta ichid,x
|
|
16 E4F2 20 5E E7 jsr CIOSetPutByteClosed
|
|
17 E4F5 8A txa
|
|
18 E4F6 E9 10 sbc #$10
|
|
19 E4F8 AA tax
|
|
20 E4F9 10 F2 bpl iocb_loop
|
|
21 E4FB 60 rts
|
|
22 .endp
|
|
23
|
|
24 ;==============================================================================
|
|
25 ; Character I/O entry vector
|
|
26 ;
|
|
27 ; On entry:
|
|
28 ; X = IOCB offset (# x 16)
|
|
29 ;
|
|
30 ; Returns:
|
|
31 ; A = depends on operation
|
|
32 ; X = IOCB offset (# x 16)
|
|
33 ; Y = status (reflected in P)
|
|
34 ;
|
|
35 ; Notes:
|
|
36 ; BUFADR must not be touched from CIO. DOS XE relies on this for
|
|
37 ; temporary storage and breaks if it is modified.
|
|
38 ;
|
|
39 ; XL/XE mode notes:
|
|
40 ; HNDLOD is always set to $00 afterward, per Sweet 16 supplement 3.
|
|
41 ;
|
|
42 ; CIO can optionally attempt a provisional open by doing a type 4 poll
|
|
43 ; over the SIO bus. This happens unconditionally if HNDLOD is non-zero
|
|
44 ; and only after the device is not found in HATABS if HNDLOD is zero.
|
|
45 ; If this succeeds, the IOCB is provisionally opened. Type 4 polling
|
|
46 ; ONLY happens for direct opens -- it does not happen for a soft open.
|
|
47 ;
|
|
48 E4FC .proc CIO
|
|
49 ;stash IOCB offset (X) and acc (A)
|
|
50 E4FC 85 2F sta ciochr
|
|
51 E4FE 86 2E stx icidno
|
|
52 E500 20 13 E5 jsr process
|
|
53 E503 xit:
|
|
54 ;copy status back to IOCB
|
|
55 E503 A6 2E ldx icidno
|
|
56 E505 98 tya
|
|
57 E506 9D 43 03 sta icsta,x
|
|
58 E509 08 php
|
|
59
|
|
60 .if _KERNEL_XLXE
|
|
61 E50A A9 00 8D E9 02 mva #0 hndlod
|
|
62 .endif
|
|
63
|
|
64 E50F A5 2F lda ciochr
|
|
65 E511 28 plp
|
|
66 E512 60 rts
|
|
67
|
|
68 E513 process:
|
|
69 ;validate IOCB offset
|
|
70 E513 8A txa
|
|
71 E514 29 8F and #$8f
|
|
72 E516 F0 06 beq validIOCB
|
|
73
|
|
74 ;return invalid IOCB error
|
|
75 E518 A0 86 ldy #CIOStatInvalidIOCB
|
|
76 E51A 60 rts
|
|
77
|
|
78 E51B cmdInvalid:
|
|
79 ;invalid command <$03
|
|
80 E51B A0 84 ldy #CIOStatInvalidCmd
|
|
81 E51D 60 rts
|
|
82
|
|
83 E51E validIOCB:
|
|
84 E51E 20 EB E6 jsr CIOLoadZIOCB
|
|
85
|
|
86 ;check if we're handling the OPEN command
|
|
87 E521 A5 22 lda iccomz
|
|
88 E523 C9 03 cmp #CIOCmdOpen
|
|
89 E525 F0 7B beq cmdOpen
|
|
90 E527 90 F2 bcc cmdInvalid
|
|
91
|
|
92 ;check if the IOCB is open
|
|
93 E529 A4 20 ldy ichidz
|
|
94
|
|
95 .if !_KERNEL_XLXE
|
|
96 bpl isOpen
|
|
97 .else
|
|
98 E52B 30 15 bmi not_open
|
|
99
|
|
100 ;check for a provisionally open IOCB
|
|
101 E52D C8 iny
|
|
102 E52E 10 2E bpl isOpen
|
|
103
|
|
104 ;okay, it's provisionally open... check if it's a close
|
|
105 E530 C9 0C cmp #CIOCmdClose
|
|
106 E532 D0 03 4C A2 E6 sne:jmp cmdCloseProvisional
|
|
107
|
|
108 ;check if we're allowed to load a handler
|
|
109 E537 AD E9 02 lda hndlod
|
|
110 E53A F0 06 beq not_open
|
|
111
|
|
112 ;try to load the handler
|
|
113 E53C 20 9C E7 jsr CIOLoadHandler
|
|
114 E53F 10 1D bpl isOpen
|
|
115 E541 60 rts
|
|
116 .endif
|
|
117
|
|
118 E542 not_open:
|
|
119 ;IOCB isn't open - issue error
|
|
120 ;
|
|
121 ;Special cases;
|
|
122 ; - No error issued for close ($0C). This is needed so that extra CLOSE
|
|
123 ; commands from BASIC don't trip errors.
|
|
124 ; - Get status ($0D) and special ($0E+) do soft open and close if needed.
|
|
125 ; $0D case is required for Top Dos 1.5a to boot; $0E+ case is encountered
|
|
126 ; with R: device XIO commands.
|
|
127 ;
|
|
128 E542 A0 01 ldy #1
|
|
129 E544 A5 22 lda iccomz
|
|
130 E546 C9 0C cmp #CIOCmdClose
|
|
131 E548 F0 06 beq ignoreOpen
|
|
132 E54A C9 0D cmp #CIOCmdGetStatus
|
|
133 E54C B0 03 bcs preOpen ;closed IOCB is OK for get status and special
|
|
134 E54E not_open_handler:
|
|
135 E54E A0 85 ldy #CIOStatNotOpen
|
|
136 E550 ignoreOpen:
|
|
137 E550 60 rts
|
|
138
|
|
139 E551 preOpen:
|
|
140 ;If the device is not open when a SPECIAL command is issued, parse the path
|
|
141 ;and soft-open the device in the zero page IOCB.
|
|
142 E551 20 FA E6 jsr CIOParsePath
|
|
143
|
|
144 ;check for special command
|
|
145 E554 A5 22 lda iccomz
|
|
146 E556 C9 0D cmp #CIOCmdGetStatus
|
|
147 E558 F0 40 beq cmdGetStatusSoftOpen
|
|
148 E55A C9 0E cmp #CIOCmdSpecial
|
|
149 E55C B0 3F bcs cmdSpecialSoftOpen
|
|
150
|
|
151 E55E isOpen:
|
|
152 E55E A6 22 ldx iccomz
|
|
153 E560 E0 0E cpx #CIOCmdSpecial
|
|
154 E562 90 02 A2 0E scc:ldx #$0e
|
|
155
|
|
156 ;do permissions check
|
|
157 E566 BD A9 E6 lda perm_check_table-4,x
|
|
158 E569 30 04 bmi skip_perm_check
|
|
159 E56B 24 2A bit icax1z
|
|
160 E56D F0 26 beq perm_check_fail
|
|
161 E56F skip_perm_check:
|
|
162
|
|
163 ;load command table vector
|
|
164 E56F BD CA E6 lda command_table_hi-4,x
|
|
165 E572 48 pha
|
|
166 E573 BD BF E6 lda command_table_lo-4,x
|
|
167 E576 48 pha
|
|
168
|
|
169 ;preload dispatch vector and dispatch to command
|
|
170 E577 BC B4 E6 ldy vector_preload_table-4,x
|
|
171 E57A load_vector:
|
|
172 E57A A6 20 ldx ichidz
|
|
173 E57C BD 1B 03 85 2C BD + mwa hatabs+1,x icax3z
|
|
174 E586 B1 2C lda (icax3z),y
|
|
175 E588 AA tax
|
|
176 E589 88 dey
|
|
177 E58A B1 2C lda (icax3z),y
|
|
178 E58C 85 2C sta icax3z
|
|
179 E58E 86 2D stx icax3z+1
|
|
180
|
|
181 ;many commands want to check length=0 on entry
|
|
182 E590 A5 28 lda icbllz
|
|
183 E592 05 29 ora icblhz
|
|
184 E594 60 rts
|
|
185
|
|
186 E595 perm_check_fail:
|
|
187 ;at this point we have A=$04 if we failed a get perm check, and A=$08
|
|
188 ;if we failed a put perm check -- these need to be translated to Y=$83
|
|
189 ;and Y=$87.
|
|
190 E595 18 clc
|
|
191 E596 69 7F adc #$7f
|
|
192 E598 A8 tay
|
|
193 E599 60 rts
|
|
194
|
|
195 ;--------------------------------------------------------------------------
|
|
196 E59A cmdGetStatusSoftOpen:
|
|
197 E59A A0 09 ldy #9
|
|
198 E59C 2C dta {bit $0100}
|
|
199 E59D cmdSpecialSoftOpen:
|
|
200 E59D A0 0B ldy #11
|
|
201 E59F invoke_and_soft_close_xit:
|
|
202 E59F 4C D9 E6 jmp CIOInvoke
|
|
203
|
|
204 ;--------------------------------------------------------------------------
|
|
205 ; Open command ($03).
|
|
206 ;
|
|
207 E5A2 cmdOpen:
|
|
208 ;check if the IOCB is already open
|
|
209 E5A2 A4 20 ldy ichidz
|
|
210 E5A4 C8 iny
|
|
211 E5A5 F0 03 beq notAlreadyOpen
|
|
212
|
|
213 ;IOCB is already open - error
|
|
214 E5A7 A0 81 ldy #CIOStatIOCBInUse
|
|
215 E5A9 60 rts
|
|
216
|
|
217 E5AA notAlreadyOpen:
|
|
218 ;attempt to parse and open -- note that this will fail out directly
|
|
219 ;on an unknown device or provisional open
|
|
220 E5AA 20 FA E6 jsr CIOParsePath
|
|
221
|
|
222 E5AD open_entry:
|
|
223 ;request open
|
|
224 E5AD A0 01 ldy #1
|
|
225 E5AF 20 D9 E6 jsr CIOInvoke
|
|
226
|
|
227 ;move handler ID and device number to IOCB
|
|
228 E5B2 A6 2E ldx icidno
|
|
229 E5B4 A5 20 9D 40 03 mva ichidz ichid,x
|
|
230 E5B9 A5 21 9D 41 03 mva icdnoz icdno,x
|
|
231
|
|
232 E5BE 98 tya
|
|
233 E5BF 10 01 bpl openOK
|
|
234 E5C1 60 rts
|
|
235
|
|
236 E5C2 openOK:
|
|
237
|
|
238 ;copy PUT BYTE vector for Atari Basic
|
|
239 E5C2 A6 20 ldx ichidz
|
|
240 E5C4 BD 1B 03 85 2C BD + mwa hatabs+1,x icax3z
|
|
241 E5CE A0 06 ldy #6
|
|
242 E5D0 B1 2C lda (icax3z),y
|
|
243 E5D2 A6 2E ldx icidno
|
|
244 E5D4 9D 46 03 sta icptl,x
|
|
245 E5D7 C8 iny
|
|
246 E5D8 B1 2C lda (icax3z),y
|
|
247 E5DA 9D 47 03 sta icpth,x
|
|
248 E5DD A0 01 ldy #1
|
|
249 E5DF 60 rts
|
|
250
|
|
251 = E6DC cmdGetStatus = CIOInvoke.invoke_vector
|
|
252 E5E0 cmdSpecial:
|
|
253 E5E0 20 DC E6 jsr CIOInvoke.invoke_vector
|
|
254
|
|
255 ;need to copy AUX1/2 back for R:
|
|
256 E5E3 A6 2E ldx icidno
|
|
257 E5E5 A5 2A 9D 4A 03 mva icax1z icax1,x
|
|
258 E5EA A5 2B 9D 4B 03 mva icax2z icax2,x
|
|
259 E5EF 60 rts
|
|
260
|
|
261 ;--------------------------------------------------------------------------
|
|
262 E5F0 cmdGetRecord:
|
|
263 ;check if buffer is full on entry
|
|
264 E5F0 F0 16 beq cmdGetRecordBufferFull
|
|
265 E5F2 cmdGetRecordLoop:
|
|
266 E5F2 cmdGetRecordGetByte:
|
|
267 ;fetch byte
|
|
268 E5F2 20 DC E6 jsr CIOInvoke.invoke_vector
|
|
269 E5F5 C0 00 cpy #0
|
|
270 E5F7 30 1C bmi cmdGetRecordXit
|
|
271
|
|
272 ;store byte (even if EOL)
|
|
273 E5F9 A2 00 ldx #0
|
|
274 E5FB 81 24 sta (icbalz,x)
|
|
275
|
|
276 ;check for EOL
|
|
277 E5FD 49 9B eor #$9b
|
|
278 E5FF C9 01 cmp #1
|
|
279
|
|
280 ;increment buffer pointer and decrement length
|
|
281 E601 20 8C E6 jsr advance_pointers
|
|
282
|
|
283 ;skip buffer full check if we had an EOL
|
|
284 E604 90 0F bcc cmdGetRecordXit
|
|
285
|
|
286 ;loop back for more bytes if buffer not full
|
|
287 E606 D0 EA bne cmdGetRecordLoop
|
|
288
|
|
289 E608 cmdGetRecordBufferFull:
|
|
290 ;read byte to discard
|
|
291 E608 20 DC E6 jsr CIOInvoke.invoke_vector
|
|
292 E60B C0 00 cpy #0
|
|
293 E60D 30 06 bmi cmdGetRecordXit
|
|
294
|
|
295 ;continue if not EOL
|
|
296 E60F C9 9B cmp #$9b
|
|
297 E611 D0 F5 bne cmdGetRecordBufferFull
|
|
298
|
|
299 ;return truncated record
|
|
300 E613 A0 89 ldy #CIOStatTruncRecord
|
|
301
|
|
302 E615 cmdGetRecordXit:
|
|
303 E615 cmdGetPutDone:
|
|
304 ;update byte count in IOCB
|
|
305 E615 A6 2E ldx icidno
|
|
306 E617 38 sec
|
|
307 E618 BD 48 03 lda icbll,x
|
|
308 E61B E5 28 sbc icbllz
|
|
309 E61D 85 28 sta icbllz ;required by Lightspeed DOS
|
|
310 E61F 9D 48 03 sta icbll,x
|
|
311 E622 BD 49 03 lda icblh,x
|
|
312 E625 E5 29 sbc icblhz
|
|
313 E627 85 29 sta icblhz
|
|
314 E629 9D 49 03 sta icblh,x
|
|
315
|
|
316 ;NOMAM 2013 BASIC Ten-Liners disk requires ICBALZ to be untouched :P
|
|
317 E62C BD 44 03 85 24 BD + mwa icbal,x icbalz
|
|
318
|
|
319 ;Pacem in Terris requires Y=1 exit.
|
|
320 ;DOS 3.0 with 128K/XE mode requires Y=3 for EOF imminent.
|
|
321 E636 60 rts
|
|
322
|
|
323 ;--------------------------------------------------------------------------
|
|
324 E637 cmdGetChars:
|
|
325 E637 F0 15 beq cmdGetCharsSingle
|
|
326 E639 cmdGetCharsLoop:
|
|
327 E639 20 DC E6 jsr CIOInvoke.invoke_vector
|
|
328 E63C C0 00 cpy #0
|
|
329 E63E 30 0B bmi cmdGetCharsError
|
|
330 E640 A2 00 ldx #0
|
|
331 E642 85 2F sta ciochr ;required by HOTEL title screen
|
|
332 E644 81 24 sta (icbalz,x)
|
|
333 E646 20 8C E6 jsr advance_pointers
|
|
334 E649 D0 EE bne cmdGetCharsLoop
|
|
335 E64B cmdGetCharsError:
|
|
336 E64B 4C 15 E6 jmp cmdGetPutDone
|
|
337
|
|
338 E64E cmdGetCharsSingle:
|
|
339 E64E 20 DC E6 jsr CIOInvoke.invoke_vector
|
|
340 E651 85 2F sta ciochr
|
|
341 E653 60 rts
|
|
342
|
|
343 ;--------------------------------------------------------------------------
|
|
344 ; PUT RECORD handler ($09)
|
|
345 ;
|
|
346 ; Exit:
|
|
347 ; ICBAL/ICBAH: Not changed
|
|
348 ; ICBLL/ICBLH: Number of bytes processed
|
|
349 ;
|
|
350 ; If the string does not contain an EOL character, one is printed at the
|
|
351 ; end. Also, in this case CIOCHR must reflect the last character in the
|
|
352 ; buffer and not the EOL. (Required by Atari DOS 2.5 RAMDISK banner)
|
|
353 ;
|
|
354 ; If length=0, the character in the A register is output without an EOL.
|
|
355 ; This behavior is required by the graphics library for Mad Pascal.
|
|
356 ;
|
|
357 E654 cmdPutRecord:
|
|
358 E654 F0 33 beq cmdPutCharsSingle
|
|
359 E656 cmdPutRecordLoop:
|
|
360 E656 A0 00 ldy #0
|
|
361 E658 B1 24 lda (icbalz),y
|
|
362 E65A 20 DC E6 jsr CIOInvoke.invoke_vector
|
|
363 E65D 98 tya
|
|
364 E65E 30 12 bmi cmdPutRecordError
|
|
365 E660 20 8C E6 jsr advance_pointers
|
|
366 E663 F0 08 beq cmdPutRecordEOL
|
|
367 E665 A9 9B lda #$9b
|
|
368 E667 C5 2F cmp ciochr
|
|
369 E669 F0 07 beq cmdPutRecordDone
|
|
370 E66B D0 E7 bne cmdPutRecord
|
|
371
|
|
372 E66D cmdPutRecordEOL:
|
|
373 E66D A9 9B lda #$9b
|
|
374 E66F 20 DC E6 jsr CIOInvoke.invoke_vector
|
|
375 E672 cmdPutRecordError:
|
|
376 E672 cmdPutRecordDone:
|
|
377 E672 4C 15 E6 jmp cmdGetPutDone
|
|
378
|
|
379 ;--------------------------------------------------------------------------
|
|
380 E675 cmdPutChars:
|
|
381 E675 F0 12 beq cmdPutCharsSingle
|
|
382 E677 cmdPutCharsLoop:
|
|
383 E677 A0 00 ldy #0
|
|
384 E679 B1 24 lda (icbalz),y
|
|
385 E67B 20 DC E6 jsr CIOInvoke.invoke_vector
|
|
386 E67E 98 tya
|
|
387 E67F 30 F1 bmi cmdPutRecordError
|
|
388 E681 20 8C E6 jsr advance_pointers
|
|
389 E684 D0 F1 bne cmdPutCharsLoop
|
|
390 E686 4C 15 E6 jmp cmdGetPutDone
|
|
391 E689 cmdPutCharsSingle:
|
|
392 E689 4C DE E6 jmp CIOInvoke.invoke_vector_ciochr
|
|
393
|
|
394 ;--------------------------------------------------------------------------
|
|
395
|
|
396 E68C advance_pointers:
|
|
397 E68C E6 24 D0 02 E6 25 inw icbalz
|
|
398 E692 A5 28 D0 02 C6 29 + dew icbllz
|
|
399 E69A D0 02 A5 29 sne:lda icblhz
|
|
400 E69E 60 rts
|
|
401
|
|
402 ;--------------------------------------------------------------------------
|
|
403 E69F cmdClose:
|
|
404 E69F 20 DC E6 jsr CIOInvoke.invoke_vector
|
|
405 E6A2 cmdCloseProvisional:
|
|
406 E6A2 A6 2E ldx icidno
|
|
407 E6A4 20 5E E7 jsr CIOSetPutByteClosed
|
|
408 E6A7 A9 FF 9D 40 03 mva #$ff ichid,x
|
|
409 E6AC 60 rts
|
|
410
|
|
411 E6AD perm_check_table:
|
|
412 E6AD 04 dta $04 ;$04 (get record)
|
|
413 E6AE 04 dta $04 ;$05 (get record)
|
|
414 E6AF 04 dta $04 ;$06 (get chars)
|
|
415 E6B0 04 dta $04 ;$07 (get chars)
|
|
416 E6B1 08 dta $08 ;$08 (put record)
|
|
417 E6B2 08 dta $08 ;$09 (put record)
|
|
418 E6B3 08 dta $08 ;$0A (put chars)
|
|
419 E6B4 08 dta $08 ;$0B (put chars)
|
|
420 E6B5 FF dta $ff ;$0C (close)
|
|
421 E6B6 FF dta $ff ;$0D (get status)
|
|
422 E6B7 FF dta $ff ;$0E (special)
|
|
423
|
|
424 E6B8 vector_preload_table:
|
|
425 E6B8 05 dta $05 ;$04 (get record)
|
|
426 E6B9 05 dta $05 ;$05 (get record)
|
|
427 E6BA 05 dta $05 ;$06 (get chars)
|
|
428 E6BB 05 dta $05 ;$07 (get chars)
|
|
429 E6BC 07 dta $07 ;$08 (put record)
|
|
430 E6BD 07 dta $07 ;$09 (put record)
|
|
431 E6BE 07 dta $07 ;$0A (put chars)
|
|
432 E6BF 07 dta $07 ;$0B (put chars)
|
|
433 E6C0 03 dta $03 ;$0C (close)
|
|
434 E6C1 09 dta $09 ;$0D (get status)
|
|
435 E6C2 0B dta $0b ;$0E (special)
|
|
436
|
|
437 E6C3 command_table_lo:
|
|
438 E6C3 EF dta <(cmdGetRecord-1) ;$04
|
|
439 E6C4 EF dta <(cmdGetRecord-1) ;$05
|
|
440 E6C5 36 dta <(cmdGetChars-1) ;$06
|
|
441 E6C6 36 dta <(cmdGetChars-1) ;$07
|
|
442 E6C7 53 dta <(cmdPutRecord-1) ;$08
|
|
443 E6C8 53 dta <(cmdPutRecord-1) ;$09
|
|
444 E6C9 74 dta <(cmdPutChars-1) ;$0A
|
|
445 E6CA 74 dta <(cmdPutChars-1) ;$0B
|
|
446 E6CB 9E dta <(cmdClose-1) ;$0C
|
|
447 E6CC DB dta <(cmdGetStatus-1) ;$0D
|
|
448 E6CD DF dta <(cmdSpecial-1) ;$0E
|
|
449
|
|
450 E6CE command_table_hi:
|
|
451 E6CE E5 dta >(cmdGetRecord-1) ;$04
|
|
452 E6CF E5 dta >(cmdGetRecord-1) ;$05
|
|
453 E6D0 E6 dta >(cmdGetChars-1) ;$06
|
|
454 E6D1 E6 dta >(cmdGetChars-1) ;$07
|
|
455 E6D2 E6 dta >(cmdPutRecord-1) ;$08
|
|
456 E6D3 E6 dta >(cmdPutRecord-1) ;$09
|
|
457 E6D4 E6 dta >(cmdPutChars-1) ;$0A
|
|
458 E6D5 E6 dta >(cmdPutChars-1) ;$0B
|
|
459 E6D6 E6 dta >(cmdClose-1) ;$0C
|
|
460 E6D7 E6 dta >(cmdGetStatus-1) ;$0D
|
|
461 E6D8 E5 dta >(cmdSpecial-1) ;$0E
|
|
462 .endp
|
|
463
|
|
464 ;==========================================================================
|
|
465 ; Invoke device vector.
|
|
466 ;
|
|
467 ; Entry (standard):
|
|
468 ; A, X = ignored
|
|
469 ; Y = offset to high vector byte in device table
|
|
470 ;
|
|
471 ; Entry (invoke_vector):
|
|
472 ; A = byte to pass to PUT CHAR vector
|
|
473 ; X, Y = ignored
|
|
474 ;
|
|
475 ; Exit:
|
|
476 ; A = byte returned from GET CHAR vector
|
|
477 ; Y = status
|
|
478 ;
|
|
479 E6D9 .proc CIOInvoke
|
|
480 E6D9 20 7A E5 jsr CIO.load_vector
|
|
481 E6DC invoke_vector:
|
|
482 E6DC 85 2F sta ciochr
|
|
483 E6DE invoke_vector_ciochr:
|
|
484 E6DE A5 2D lda icax3z+1
|
|
485 E6E0 48 pha
|
|
486 E6E1 A5 2C lda icax3z
|
|
487 E6E3 48 pha
|
|
488 E6E4 A0 92 ldy #CIOStatNotSupported
|
|
489 E6E6 A6 2E ldx icidno
|
|
490 E6E8 A5 2F lda ciochr
|
|
491 E6EA 60 rts
|
|
492 .endp
|
|
493
|
|
494 ;==========================================================================
|
|
495 ; Copy IOCB to ZIOCB.
|
|
496 ;
|
|
497 ; Entry:
|
|
498 ; X = IOCB
|
|
499 ;
|
|
500 ; [OSManual p236] "Although both the outer level IOCB and the Zero-page
|
|
501 ; IOCB are defined to be 16 bytes in size, only the first 12 bytes are
|
|
502 ; moved by CIO."
|
|
503 ;
|
|
504 E6EB .proc CIOLoadZIOCB
|
|
505 ;We used to do a trick here where we would count Y from $F4 to $00...
|
|
506 ;but we can't do that because the 65C816 doesn't wrap abs,Y within
|
|
507 ;bank 0 even in emulation mode. Argh!
|
|
508
|
|
509 E6EB A0 00 ldy #0
|
|
510 E6ED copyToZIOCB:
|
|
511 E6ED BD 40 03 lda ichid,x
|
|
512 E6F0 99 20 00 sta ziocb,y
|
|
513 E6F3 E8 inx
|
|
514 E6F4 C8 iny
|
|
515 E6F5 C0 0C cpy #12
|
|
516 E6F7 D0 F4 bne copyToZIOCB
|
|
517 E6F9 60 rts
|
|
518 .endp
|
|
519
|
|
520 ;==========================================================================
|
|
521 E6FA .proc CIOParsePath
|
|
522 ;default to device #1
|
|
523 E6FA A2 01 ldx #1
|
|
524
|
|
525 ;pull first character of filename and stash it
|
|
526 E6FC A1 23 lda (icbalz-1,x)
|
|
527 E6FE 85 2D sta icax4z
|
|
528
|
|
529 ;Check for a device number.
|
|
530 ;
|
|
531 ; - D1:-D9: is supported. D0: also gives unit 1, and any digits beyond
|
|
532 ; the first are ignored.
|
|
533 ;
|
|
534 ; We don't validate the colon anymore -- Atari OS allows opening just "C" to get
|
|
535 ; to the cassette.
|
|
536 ;
|
|
537 E700 A0 01 ldy #1
|
|
538 E702 B1 24 lda (icbalz),y
|
|
539 E704 38 sec
|
|
540 E705 E9 30 sbc #'0'
|
|
541 E707 F0 06 beq nodevnum
|
|
542 E709 C9 0A cmp #10
|
|
543 E70B B0 02 bcs nodevnum
|
|
544 E70D AA tax
|
|
545
|
|
546 E70E C8 iny
|
|
547
|
|
548 E70F nodevnum:
|
|
549 E70F 86 21 stx icdnoz
|
|
550
|
|
551 .if _KERNEL_XLXE
|
|
552 ;check if we are doing a true open and if we should do a type 4 poll
|
|
553 E711 A5 22 lda iccomz
|
|
554 E713 C9 03 cmp #CIOCmdOpen
|
|
555 E715 D0 3D bne skip_poll
|
|
556
|
|
557 ;clear DVSTAT+0/+1 to indicate no poll
|
|
558 E717 A9 00 lda #0
|
|
559 E719 8D EA 02 sta dvstat
|
|
560 E71C 8D EB 02 sta dvstat+1
|
|
561
|
|
562 ;check if we should do an unconditional poll (HNDLOD nonzero).
|
|
563 E71F AD E9 02 lda hndlod
|
|
564 E722 D0 05 bne unconditional_poll
|
|
565
|
|
566 ;search handler table
|
|
567 E724 20 69 E7 jsr CIOFindHandler
|
|
568 E727 F0 34 beq found
|
|
569
|
|
570 E729 unconditional_poll:
|
|
571 ;do type 4 poll
|
|
572 E729 20 7A E7 jsr CIOPollForDevice
|
|
573 E72C 30 2B bmi unknown_device
|
|
574
|
|
575 ;mark provisionally open
|
|
576 E72E A6 2E ldx icidno
|
|
577 E730 A9 7F 9D 40 03 mva #$7f ichid,x
|
|
578 E735 A5 2D 9D 4C 03 mva icax4z icax3,x
|
|
579 E73A AD EC 02 9D 4D 03 mva dvstat+2 icax4,x
|
|
580 E740 A9 C8 9D 46 03 A9 + mwa #CIOPutByteLoadHandler-1 icptl,x
|
|
581 E74A A5 21 9D 41 03 mva icdnoz icdno,x
|
|
582
|
|
583 ;do direct exit, bypassing regular open path
|
|
584 E74F 68 pla
|
|
585 E750 68 pla
|
|
586 E751 A0 01 ldy #1
|
|
587 E753 60 rts
|
|
588
|
|
589 E754 skip_poll:
|
|
590 .endif
|
|
591
|
|
592 ;search handler table
|
|
593 E754 20 69 E7 jsr CIOFindHandler
|
|
594 E757 F0 04 beq found
|
|
595
|
|
596 E759 unknown_device:
|
|
597 ;return unknown device error
|
|
598 E759 A0 82 ldy #CIOStatUnkDevice
|
|
599 E75B 68 pla
|
|
600 E75C 68 pla
|
|
601 E75D found:
|
|
602 E75D 60 rts
|
|
603 .endp
|
|
604
|
|
605 ;==========================================================================
|
|
606 E75E .proc CIOSetPutByteClosed
|
|
607 E75E A9 4D lda #<[CIO.not_open_handler-1]
|
|
608 E760 9D 46 03 sta icptl,x
|
|
609 E763 A9 E5 lda #>[CIO.not_open_handler-1]
|
|
610 E765 9D 47 03 sta icpth,x
|
|
611 E768 60 rts
|
|
612 .endp
|
|
613
|
|
614 ;==========================================================================
|
|
615 ; Attempt to find a handler entry in HATABS.
|
|
616 ;
|
|
617 E769 .proc CIOFindHandler
|
|
618 ;search for handler
|
|
619 E769 A5 2D lda icax4z
|
|
620 E76B A2 21 ldx #11*3
|
|
621 E76D findHandler:
|
|
622 E76D DD 1A 03 cmp hatabs,x
|
|
623 E770 F0 05 beq foundHandler
|
|
624 E772 CA dex
|
|
625 E773 CA dex
|
|
626 E774 CA dex
|
|
627 E775 10 F6 bpl findHandler
|
|
628 E777 foundHandler:
|
|
629 ;store handler ID
|
|
630 E777 86 20 stx ichidz
|
|
631 E779 60 rts
|
|
632 .endp
|
|
633
|
|
634 ;==========================================================================
|
|
635 ; Poll SIO bus for CIO device
|
|
636 ;
|
|
637 ; Issues a type 4 poll ($4F/$40/devname/devnumber).
|
|
638 ;
|
|
639 .if _KERNEL_XLXE
|
|
640 E77A .proc CIOPollForDevice
|
|
641 E77A A5 2D lda icax4z
|
|
642 E77C 8D 0A 03 sta daux1
|
|
643 E77F A5 21 lda icdnoz
|
|
644 E781 8D 0B 03 sta daux2
|
|
645
|
|
646 E784 A2 09 ldx #9
|
|
647 E786 BD 92 E7 9D 00 03 + mva:rpl cmd_tab,x ddevic,x-
|
|
648
|
|
649 E78F 4C 59 E4 jmp siov
|
|
650
|
|
651 E792 cmd_tab:
|
|
652 E792 4F dta $4f ;device
|
|
653 E793 01 dta $01 ;unit
|
|
654 E794 40 dta $40 ;command
|
|
655 E795 40 dta $40 ;status (transfer flags)
|
|
656 E796 EA dta <dvstat ;dbuflo
|
|
657 E797 02 dta >dvstat ;dbufhi
|
|
658 E798 40 dta $40 ;dtimlo
|
|
659 E799 00 dta $00 ;unused
|
|
660 E79A 04 dta $04 ;dbytlo
|
|
661 E79B 00 dta $00 ;dbythi
|
|
662 .endp
|
|
663 .endif
|
|
664
|
|
665 ;==========================================================================
|
|
666 ; Load handler for a provisionally open IOCB.
|
|
667 ;
|
|
668 .if _KERNEL_XLXE
|
|
669 E79C .proc CIOLoadHandler
|
|
670 ;load handler over SIO bus
|
|
671 E79C AD EC 02 8D D1 02 + mwa dvstat+2 loadad
|
|
672 E7A8 A6 2E ldx icidno
|
|
673 E7AA BD 4D 03 8D 00 03 mva icax4,x ddevic
|
|
674 E7B0 20 01 C5 jsr PHLoadHandler
|
|
675 E7B3 B0 11 bcs fail
|
|
676
|
|
677 ;let's see if we can look up the handler now
|
|
678 E7B5 A6 2E ldx icidno
|
|
679 E7B7 BD 4C 03 85 2D mva icax3,x icax4z
|
|
680 E7BC 20 69 E7 jsr CIOFindHandler
|
|
681 E7BF D0 05 bne fail
|
|
682
|
|
683 ;follow through with open
|
|
684 E7C1 20 AD E5 jsr CIO.open_entry
|
|
685 E7C4 10 02 bpl ok
|
|
686 E7C6 fail:
|
|
687 E7C6 A0 82 ldy #CIOStatUnkDevice
|
|
688 E7C8 ok:
|
|
689 E7C8 60 rts
|
|
690 .endp
|
|
691 .endif
|
|
692
|
|
693 ;==========================================================================
|
|
694 ; PUT BYTE handler for provisionally open IOCBs.
|
|
695 ;
|
|
696 ; This handler is used when an IOCB has been provisionally opened pending
|
|
697 ; a handler load over the SIO bus. It is used when a direct call is made
|
|
698 ; through ICPTL/ICPTH. If HNDLOD=0, the call fails as handler loading is
|
|
699 ; not set up; if it is nonzero, the handler is loaded over the SIO bus and
|
|
700 ; then the PUT BYTE call continues if everything is good.
|
|
701 ;
|
|
702 .if _KERNEL_XLXE
|
|
703 E7C9 .proc CIOPutByteLoadHandler
|
|
704 ;save off A/X
|
|
705 E7C9 85 2F sta ciochr
|
|
706 E7CB 86 2E stx icidno
|
|
707
|
|
708 ;check if we're allowed to load a handler and bail if not
|
|
709 E7CD AD E9 02 lda hndlod
|
|
710 E7D0 F0 10 beq load_error
|
|
711
|
|
712 ;copy IOCB to ZIOCB
|
|
713 E7D2 20 EB E6 jsr CIOLoadZIOCB
|
|
714
|
|
715 ;try to load the handler
|
|
716 E7D5 20 9C E7 jsr CIOLoadHandler
|
|
717 E7D8 30 08 bmi load_error
|
|
718
|
|
719 ;all good... let's invoke the standard handler
|
|
720 E7DA A0 07 ldy #7
|
|
721 E7DC 20 D9 E6 jsr CIOInvoke
|
|
722 E7DF 4C E4 E7 jmp xit
|
|
723
|
|
724 E7E2 load_error:
|
|
725 E7E2 A0 82 ldy #CIOStatUnkDevice
|
|
726 E7E4 xit:
|
|
727 E7E4 08 php
|
|
728 E7E5 A5 2F lda ciochr
|
|
729 E7E7 A6 2E ldx icidno
|
|
730 E7E9 28 plp
|
|
731 E7EA 60 rts
|
|
732 .endp
|
|
733 .endif
|
|
236 .endif
|
|
237
|
|
238 E7EB _KERNEL_REPORT_MODULE_SIZE 'Central Input/Output (CIO)', $E6D5-$E4A6
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', $E6D5-$E4A6, ')', ' ', 'Central Input/Output (CIO)'
|
|
1 $E7EB -> $0301($022F) Central Input/Output (CIO)
|
|
3 = E7EB .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
239
|
|
240 .if !_KERNEL_XLXE
|
|
241 icl 'vbi.s'
|
|
242 icl 'interrupt.s'
|
|
243 icl 'irq.s'
|
|
244 .endif
|
|
245 E7EB _KERNEL_REPORT_MODULE_SIZE 'Interrupt routines', $E944-$E6D5
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', $E944-$E6D5, ')', ' ', 'Interrupt routines'
|
|
1 $E7EB -> $0000($026F) Interrupt routines
|
|
3 = E7EB .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
246
|
|
247 E7EB icl 'sio.inc'
|
|
Source: source/Shared/sio.inc
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - SIO definitions
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 .ifndef f_SIO_INC
|
|
11 .def f_SIO_INC
|
|
12
|
|
13 SIOSuccess = $01
|
|
14 SIOErrorTimeout = $8A
|
|
15 SIOErrorNAK = $8B
|
|
16 SIOErrorBadFrame = $8C
|
|
17 SIOErrorOverrun = $8E
|
|
18 SIOErrorChecksum = $8F
|
|
19 SIOErrorDeviceError = $90
|
|
20
|
|
21 .endif
|
|
248 E7EB icl 'sio.s'
|
|
Source: source/Shared/sio.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; AltirraOS modular Kernel ROM - Serial Input/Output (SIO) routines
|
|
3 ; Copyright (C) 2008-2019 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 E7EB .proc SIOInit
|
|
11 ;turn off POKEY init mode so polynomial counters and audio run
|
|
12 E7EB A9 03 8D 0F D2 mva #3 skctl
|
|
13 E7F0 8D 32 02 sta sskctl
|
|
14
|
|
15 ;enable noisy sound (yes, this is actually documented as being inited to
|
|
16 ;3)
|
|
17 E7F3 85 41 sta soundr
|
|
18 E7F5 60 rts
|
|
19 .endp
|
|
20
|
|
21 ;==============================================================================
|
|
22 E7F6 .proc SIO
|
|
23 ;set retry counters
|
|
24 E7F6 A9 01 8D BD 02 mva #$01 dretry
|
|
25
|
|
26 ;enter critical section
|
|
27 E7FB 85 42 sta critic
|
|
28
|
|
29 .if _KERNEL_PBI_SUPPORT
|
|
30 ;attempt PBI transfer
|
|
31 E7FD 20 A2 C2 jsr PBIAttemptSIO
|
|
32 E800 90 03 4C EC E8 scc:jmp xit_pbi
|
|
33 .endif
|
|
34
|
|
35 ;we must not save STACKP until after PBI devices are polled -- the
|
|
36 ;BlackBox PBI routines depend on being able to reuse this location
|
|
37 E805 BA tsx
|
|
38 E806 8E 18 03 stx stackp
|
|
39
|
|
40 ;Set timeout timer address -- MUST be done on each call to SIO, or
|
|
41 ;Cross-Town Crazy Eight hangs on load due to taking over this vector
|
|
42 ;previously. This is guaranteed by the OS Manual in Appendix L, H27.
|
|
43 E809 20 13 E9 jsr SIOSetTimeoutVector
|
|
44
|
|
45 ;check for cassette -- needs to match $60 or else Prisma: Alien Ambush
|
|
46 ;fails to load.
|
|
47 E80C A2 00 ldx #0
|
|
48 E80E AD 00 03 lda ddevic
|
|
49 E811 C9 60 cmp #$60
|
|
50 E813 D0 01 CA sne:dex
|
|
51 E816 8E 0F 03 stx casflg
|
|
52
|
|
53 ;init POKEY hardware
|
|
54 E819 20 66 E9 jsr SIOInitHardware
|
|
55
|
|
56 ;go do cassette now
|
|
57 E81C 2C 0F 03 bit casflg
|
|
58 E81F 10 03 bpl retry_command
|
|
59 E821 4C DC EA jmp SIOCassette
|
|
60
|
|
61 E824 retry_command:
|
|
62 ;We try 13 times to get a command accepted by a device; after that it
|
|
63 ;counts as a device failure and we try one more round of 13 tries.
|
|
64 E824 A9 0D 8D 9C 02 mva #$0d cretry
|
|
65
|
|
66 E829 retry_command_2:
|
|
67 ;init command buffer
|
|
68 E829 AD 00 03 lda ddevic
|
|
69 E82C 18 clc
|
|
70 E82D 6D 01 03 adc dunit
|
|
71 E830 38 sec
|
|
72 E831 E9 01 sbc #1
|
|
73 E833 8D 3A 02 sta cdevic
|
|
74
|
|
75 E836 AD 02 03 8D 3B 02 mva dcomnd ccomnd
|
|
76 E83C AD 0A 03 8D 3C 02 mva daux1 caux1
|
|
77 E842 AD 0B 03 8D 3D 02 mva daux2 caux2
|
|
78
|
|
79 ;assert command line
|
|
80 E848 A9 34 8D 03 D3 mva #$34 pbctl
|
|
81
|
|
82 ;wait ~600us to ensure 750us minimum delay (~1k cycles or ~10 scanlines)
|
|
83 E84D A2 05 ldx #5
|
|
84 E84F AC 0B D4 ldy vcount
|
|
85 E852 cmddelay:
|
|
86 E852 CC 0B D4 F0 FB cpy:req vcount
|
|
87 E857 C8 iny
|
|
88 E858 CA dex
|
|
89 E859 D0 F7 bne cmddelay
|
|
90
|
|
91 ;send command frame
|
|
92 E85B A9 00 85 3C mva #0 nocksm
|
|
93 E85F A9 02 lda #>cdevic
|
|
94 E861 85 33 sta bufrhi
|
|
95 E863 85 35 sta bfenhi
|
|
96 E865 A9 3A 85 32 mva #<cdevic bufrlo
|
|
97 E869 A9 3E 85 34 mva #<caux2+1 bfenlo
|
|
98 E86D 20 CB E9 jsr SIOSend
|
|
99 E870 30 65 bmi xit
|
|
100
|
|
101 ;wait for the ACK
|
|
102 E872 20 1E E9 jsr SIOWaitForACK
|
|
103 E875 10 0A bpl ackOK
|
|
104
|
|
105 E877 command_error:
|
|
106 E877 20 38 EA jsr SIOReceiveStop
|
|
107 E87A CE 9C 02 dec cretry
|
|
108 E87D 10 AA bpl retry_command_2
|
|
109 E87F 30 4B bmi transfer_error
|
|
110
|
|
111 E881 ackOK:
|
|
112
|
|
113 ;check if we should send a data frame
|
|
114 E881 2C 03 03 bit dstats
|
|
115 E884 10 0D bpl no_send_frame
|
|
116
|
|
117 ;setup buffer pointers
|
|
118 E886 20 B5 E9 jsr SIOSetupBufferPointers
|
|
119
|
|
120 ;send data frame
|
|
121 E889 20 CB E9 jsr SIOSend
|
|
122 E88C 30 49 bmi xit
|
|
123
|
|
124 ;wait for ACK
|
|
125 E88E 20 1E E9 jsr SIOWaitForACK
|
|
126 E891 30 E4 bmi command_error
|
|
127
|
|
128 E893 no_send_frame:
|
|
129
|
|
130 ;setup for receiving complete
|
|
131 E893 A2 FF ldx #$ff
|
|
132 E895 8E 17 03 stx timflg
|
|
133 E898 86 3C stx nocksm
|
|
134
|
|
135 ;setup frame delay for complete
|
|
136 E89A AD 06 03 lda dtimlo
|
|
137 E89D 6A ror
|
|
138 E89E 6A ror
|
|
139 E89F 48 pha
|
|
140 E8A0 6A ror
|
|
141 E8A1 29 C0 and #$c0
|
|
142 E8A3 A8 tay
|
|
143 E8A4 68 pla
|
|
144 E8A5 29 3F and #$3f
|
|
145 E8A7 AA tax
|
|
146
|
|
147 E8A8 A9 01 lda #1
|
|
148 E8AA 20 5C E4 jsr setvbv
|
|
149
|
|
150 E8AD A2 3E ldx #<temp
|
|
151 E8AF 86 32 stx bufrlo
|
|
152 E8B1 E8 inx
|
|
153 E8B2 86 34 stx bfenlo
|
|
154 E8B4 A2 02 ldx #>temp
|
|
155 E8B6 86 33 stx bufrhi
|
|
156 E8B8 86 35 stx bfenhi
|
|
157 E8BA 20 FA E9 jsr SIOReceive
|
|
158 E8BD 30 0D bmi transfer_error
|
|
159
|
|
160 ;Check if we received a C ($43) or E ($45) -- we must NOT abort immediately
|
|
161 ;on a device error, as the device still sends back data we need to read, and
|
|
162 ;Music Studio relies on the data coming back from a CRC error.
|
|
163 E8BF AD 3E 02 lda temp
|
|
164 E8C2 C9 43 cmp #$43
|
|
165 E8C4 F0 32 beq completeOK
|
|
166 E8C6 C9 45 cmp #$45
|
|
167 E8C8 F0 2E beq completeOK
|
|
168
|
|
169 ;we received crap... fail it now
|
|
170 E8CA device_error:
|
|
171 E8CA A0 90 ldy #SIOErrorDeviceError
|
|
172
|
|
173 E8CC transfer_error:
|
|
174 E8CC 20 38 EA jsr SIOReceiveStop
|
|
175
|
|
176 E8CF CE BD 02 dec dretry
|
|
177 E8D2 30 03 bmi device_retries_exhausted
|
|
178 E8D4 4C 24 E8 jmp retry_command
|
|
179
|
|
180 E8D7 device_retries_exhausted:
|
|
181 E8D7 xit:
|
|
182 E8D7 AE 0F 03 ldx casflg
|
|
183 E8DA D0 0C bne leave_cassette_audio_on
|
|
184 E8DC 8E 01 D2 stx audc1
|
|
185 E8DF 8E 03 D2 stx audc2
|
|
186 E8E2 8E 05 D2 stx audc3
|
|
187 E8E5 8E 07 D2 stx audc4
|
|
188 E8E8 leave_cassette_audio_on:
|
|
189
|
|
190 .ifdef _KERNEL_816
|
|
191 ;we may be in native mode, so we can't f-up the high byte of the stack pointer
|
|
192 lda #1
|
|
193 xba
|
|
194 lda stackp
|
|
195 tcs
|
|
196 .else
|
|
197 E8E8 AE 18 03 ldx stackp
|
|
198 E8EB 9A txs
|
|
199 .endif
|
|
200
|
|
201 E8EC xit_pbi:
|
|
202 E8EC A9 00 lda #0
|
|
203 E8EE 85 42 sta critic
|
|
204
|
|
205 E8F0 C0 00 cpy #0 ;!! - A=0 must be preserved for LiteDOS
|
|
206 E8F2 8C 03 03 sty dstats
|
|
207 E8F5 84 30 sty status
|
|
208 E8F7 60 rts
|
|
209
|
|
210 E8F8 completeOK:
|
|
211 ;check if we should read a data frame
|
|
212 E8F8 2C 03 03 bit dstats
|
|
213 E8FB 50 08 bvc no_receive_frame
|
|
214
|
|
215 ;setup buffer pointers
|
|
216 E8FD 20 B5 E9 jsr SIOSetupBufferPointers
|
|
217
|
|
218 ;receive the rest of the frame
|
|
219 E900 20 FA E9 jsr SIOReceive
|
|
220 E903 30 C7 bmi transfer_error
|
|
221
|
|
222 E905 no_receive_frame:
|
|
223 ;now we can finally shut off the receive IRQ
|
|
224 E905 20 38 EA jsr SIOReceiveStop
|
|
225
|
|
226 ;Now check whether we got a device error earlier. If we did, return
|
|
227 ;that instead of success.
|
|
228 E908 AD 3E 02 lda temp
|
|
229 E90B C9 43 cmp #'C'
|
|
230 E90D D0 BB bne device_error
|
|
231
|
|
232 ;nope, we're good... exit OK.
|
|
233 E90F A0 01 ldy #SIOSuccess
|
|
234 E911 D0 C4 bne xit
|
|
235 .endp
|
|
236
|
|
237 ;==============================================================================
|
|
238 E913 .proc SIOSetTimeoutVector
|
|
239 E913 A9 D6 8D 26 02 A9 + mwa #SIOCountdown1Handler cdtma1
|
|
240 E91D 60 rts
|
|
241 .endp
|
|
242
|
|
243 ;==============================================================================
|
|
244 E91E .proc SIOWaitForACK
|
|
245 ;setup 2 frame delay for ack
|
|
246 E91E A2 FF ldx #$ff
|
|
247 E920 8E 17 03 stx timflg
|
|
248 E923 86 3C stx nocksm
|
|
249 E925 E8 inx ;X=0
|
|
250 E926 A9 01 lda #1
|
|
251 E928 A0 02 ldy #2
|
|
252 E92A 84 33 sty bufrhi ;>temp = 2
|
|
253 E92C 84 35 sty bfenhi ;>temp+1 = 2
|
|
254 E92E 20 5C E4 jsr setvbv
|
|
255
|
|
256 ;setup for receiving ACK
|
|
257 E931 A2 3E ldx #<temp
|
|
258 E933 86 32 stx bufrlo
|
|
259 E935 E8 inx
|
|
260 E936 86 34 stx bfenlo ;#<[temp+1]
|
|
261
|
|
262 E938 20 FA E9 jsr SIOReceive
|
|
263
|
|
264 ;check if we had a receive error
|
|
265 E93B 30 09 bmi xit
|
|
266
|
|
267 ;check if we got an ACK
|
|
268 E93D AD 3E 02 lda temp
|
|
269 E940 C9 41 cmp #'A'
|
|
270 E942 F0 02 beq xit
|
|
271
|
|
272 ;doh
|
|
273 E944 A0 8B ldy #SIOErrorNAK
|
|
274 E946 xit:
|
|
275 E946 60 rts
|
|
276 .endp
|
|
277
|
|
278 ;==============================================================================
|
|
279 ;SIO send enable routine
|
|
280 ;
|
|
281 ; This is one of those routines that Atari inadvisably exposed in the OS jump
|
|
282 ; table even though they shouldn't. Responsibilities of this routine are:
|
|
283 ;
|
|
284 ; - Hit SKCTL to reset serial hardware and init for sending
|
|
285 ; - Hit SKRES to clear status
|
|
286 ; - Enable send interrupts
|
|
287 ; - Configure AUDF3/AUDF4 frequency (19200 baud or 600 baud)
|
|
288 ; - Set AUDC3/AUDC4 for noisy or non-noisy audio
|
|
289 ; - Set AUDCTL
|
|
290 ;
|
|
291 ; It does not init any of the SIO variables, only hardware/shadow state.
|
|
292 ;
|
|
293 = E966 SIOInitHardware = SIOSendEnable.init_hardware
|
|
294 E947 .proc SIOSendEnable
|
|
295 ;enable serial output ready IRQ and suppress serial output complete IRQ
|
|
296 E947 A5 10 lda pokmsk
|
|
297 E949 09 10 ora #$10
|
|
298 E94B 29 F7 and #$f7
|
|
299 E94D 85 10 sta pokmsk
|
|
300 E94F 8D 0E D2 sta irqen
|
|
301
|
|
302 E952 no_irq_setup:
|
|
303 ;clear forced break mode and reset serial clocking mode to timer 4
|
|
304 ;synchronous; also enable two-tone mode if in cassette mode
|
|
305 E952 AD 32 02 lda sskctl
|
|
306 E955 29 0F and #$0f
|
|
307 E957 09 20 ora #$20
|
|
308 E959 AE 0F 03 ldx casflg
|
|
309 E95C F0 02 09 08 seq:ora #$08
|
|
310 E960 8D 32 02 sta sskctl
|
|
311 E963 8D 0F D2 sta skctl
|
|
312
|
|
313 E966 init_hardware:
|
|
314 ;clock channel 3 and 4 together at 1.79MHz
|
|
315 ;configure pokey timers 3 and 4 for 19200 baud (1789773/(2*40+7) = 19040)
|
|
316 E966 A2 08 ldx #8
|
|
317
|
|
318 ;check if we are doing a cassette transfer; if so, use the cassette
|
|
319 ;register table instead
|
|
320 E968 AD 0F 03 lda casflg
|
|
321 E96B F0 02 beq not_cassette
|
|
322
|
|
323 E96D A2 11 ldx #17
|
|
324
|
|
325 E96F not_cassette:
|
|
326
|
|
327 = E96F .def :SIOInitPOKEYWithRegOffsetX
|
|
328 ;load POKEY audio registers
|
|
329 E96F A0 08 ldy #8
|
|
330 E971 BD 9A E9 CA 99 00 + mva:rpl regdata_normal,x- audf1,y-
|
|
331
|
|
332 ;go noisy audio if requested
|
|
333 E97B A5 41 lda soundr
|
|
334 E97D F0 17 beq no_noise
|
|
335
|
|
336 E97F A9 A8 lda #$a8
|
|
337 E981 8D 07 D2 sta audc4
|
|
338 E984 AE 0F 03 ldx casflg
|
|
339 E987 F0 0D beq no_noise
|
|
340 E989 A9 10 lda #$10
|
|
341 E98B 2C 32 02 bit sskctl
|
|
342 E98E D0 06 bne no_noise
|
|
343 E990 8D 01 D2 sta audc1
|
|
344 E993 8D 03 D2 sta audc2
|
|
345
|
|
346 E996 no_noise:
|
|
347
|
|
348 ;reset serial status
|
|
349 E996 8D 0A D2 sta skres
|
|
350 E999 60 rts
|
|
351
|
|
352 E99A regdata:
|
|
353 E99A regdata_normal:
|
|
354 E99A 00 dta $00 ;audf1
|
|
355 E99B A0 dta $a0 ;audc1
|
|
356 E99C 00 dta $00 ;audf2
|
|
357 E99D A0 dta $a0 ;audc2
|
|
358 E99E 28 dta $28 ;audf3
|
|
359 E99F A0 dta $a0 ;audc3
|
|
360 E9A0 00 dta $00 ;audf4
|
|
361 E9A1 A0 dta $a0 ;audc4
|
|
362 E9A2 28 dta $28 ;audctl
|
|
363
|
|
364 E9A3 regdata_cassette_write:
|
|
365 E9A3 05 dta $05 ;audf1
|
|
366 E9A4 A0 dta $a0 ;audc1
|
|
367 E9A5 07 dta $07 ;audf2
|
|
368 E9A6 A0 dta $a0 ;audc2
|
|
369 E9A7 CC dta $cc ;audf3
|
|
370 E9A8 A0 dta $a0 ;audc3
|
|
371 E9A9 05 dta $05 ;audf4
|
|
372 E9AA A0 dta $a0 ;audc4
|
|
373 E9AB 28 dta $28 ;audctl
|
|
374
|
|
375 E9AC regdata_cassette_read:
|
|
376 E9AC 00 dta $00 ;audf1
|
|
377 E9AD A0 dta $a0 ;audc1
|
|
378 E9AE 00 dta $00 ;audf2
|
|
379 E9AF A0 dta $a0 ;audc2
|
|
380 E9B0 CC dta $cc ;audf3
|
|
381 E9B1 A0 dta $a0 ;audc3
|
|
382 E9B2 05 dta $05 ;audf4
|
|
383 E9B3 A0 dta $a0 ;audc4
|
|
384 E9B4 28 dta $28 ;audctl
|
|
385 .endp
|
|
386
|
|
387 ;==============================================================================
|
|
388 E9B5 .proc SIOSetupBufferPointers
|
|
389 E9B5 18 clc
|
|
390 E9B6 AD 04 03 lda dbuflo
|
|
391 E9B9 85 32 sta bufrlo
|
|
392 E9BB 6D 08 03 adc dbytlo
|
|
393 E9BE 85 34 sta bfenlo
|
|
394 E9C0 AD 05 03 lda dbufhi
|
|
395 E9C3 85 33 sta bufrhi
|
|
396 E9C5 6D 09 03 adc dbythi
|
|
397 E9C8 85 35 sta bfenhi
|
|
398 E9CA 60 rts
|
|
399 .endp
|
|
400
|
|
401 ;==============================================================================
|
|
402 ;SIO send routine
|
|
403 ;
|
|
404 E9CB .proc SIOSend
|
|
405 ;configure serial port for synchronous transmission
|
|
406 ;enable transmission IRQs
|
|
407 E9CB 78 sei
|
|
408 E9CC 20 47 E9 jsr SIOSendEnable
|
|
409
|
|
410 E9CF A0 00 ldy #0
|
|
411 E9D1 84 3A sty xmtdon
|
|
412 E9D3 84 30 sty status
|
|
413 E9D5 84 3B sty chksnt
|
|
414
|
|
415 ;send first byte and set checksum (must be atomic)
|
|
416 E9D7 B1 32 lda (bufrlo),y
|
|
417 E9D9 8D 0D D2 sta serout
|
|
418 E9DC 85 31 sta chksum
|
|
419
|
|
420 ;unmask IRQs
|
|
421 E9DE 58 cli
|
|
422
|
|
423 ;wait for transmit to complete or Break to be pressed
|
|
424 E9DF wait:
|
|
425 E9DF A5 11 lda brkkey
|
|
426 E9E1 F0 06 beq break_detected
|
|
427 E9E3 A5 3A lda xmtdon
|
|
428 E9E5 F0 F8 beq wait
|
|
429 E9E7 D0 04 bne send_completed
|
|
430
|
|
431 E9E9 break_detected:
|
|
432 E9E9 A0 80 ldy #$80
|
|
433 E9EB 84 30 sty status
|
|
434
|
|
435 E9ED send_completed:
|
|
436 ;shut off transmission IRQs
|
|
437 E9ED 78 sei
|
|
438 E9EE A5 10 lda pokmsk
|
|
439 E9F0 29 E7 and #$e7
|
|
440 E9F2 85 10 sta pokmsk
|
|
441 E9F4 8D 0E D2 sta irqen
|
|
442 E9F7 58 cli
|
|
443
|
|
444 ;we're done
|
|
445 E9F8 98 tya
|
|
446 E9F9 60 rts
|
|
447 .endp
|
|
448
|
|
449 ;==============================================================================
|
|
450 ; SIO receive routine
|
|
451 ;
|
|
452 ; The exit and entry paths of this routine are time critical when receiving
|
|
453 ; the Complete/Error byte and data frame since there may be no delay at all
|
|
454 ; in between. The exit path needs to exit with the receive IRQ hot but IRQs
|
|
455 ; masked; the entry path in turn needs to keep the IRQ enabled but not unmask
|
|
456 ; IRQs until ready to receive.
|
|
457 ;
|
|
458 E9FA .proc SIOReceive
|
|
459 E9FA A9 00 lda #0
|
|
460 E9FC use_checksum:
|
|
461 E9FC 85 31 sta chksum
|
|
462 E9FE A2 00 ldx #0
|
|
463 EA00 86 39 stx recvdn ;receive done flag = false
|
|
464 EA02 86 38 stx bufrfl ;buffer full flag = false
|
|
465 EA04 E8 inx
|
|
466 EA05 86 30 stx status ;set status to success (1)
|
|
467
|
|
468 ;configure serial port for asynchronous receive
|
|
469 ;enable receive IRQ
|
|
470 EA07 78 sei
|
|
471 EA08 AD 32 02 lda sskctl
|
|
472 EA0B 29 8F and #$8f
|
|
473 EA0D 09 10 ora #$10
|
|
474 EA0F 8D 32 02 sta sskctl
|
|
475 EA12 8D 0F D2 sta skctl
|
|
476 EA15 A5 10 lda pokmsk
|
|
477 EA17 09 20 ora #$20
|
|
478 EA19 85 10 sta pokmsk
|
|
479 EA1B 8D 0E D2 sta irqen
|
|
480 EA1E 58 cli
|
|
481
|
|
482 ;Negate command line (if it isn't already negated).
|
|
483 ;
|
|
484 ;Note that we DON'T do this until we are entirely ready to receive,
|
|
485 ;because as soon as we do this we can get data.
|
|
486 EA1F A9 3C 8D 03 D3 mva #$3c pbctl
|
|
487
|
|
488 ;wait for receive to complete
|
|
489 EA24 wait:
|
|
490 EA24 AD 17 03 lda timflg ;check for timeout
|
|
491 EA27 F0 0B beq timeout ;bail if so
|
|
492 EA29 A4 30 ldy status ;check for another error code
|
|
493 EA2B 30 05 bmi error ;bail if so
|
|
494 EA2D A5 39 lda recvdn ;check for receive complete
|
|
495 EA2F F0 F3 beq wait ;keep waiting if not
|
|
496 EA31 98 tya ;set flags from status
|
|
497
|
|
498 EA32 error:
|
|
499 ;Mask interrupts, but exit with them masked. We do this in order to
|
|
500 ;handle the transition from Complete to data frame during receive. There
|
|
501 ;is no guaranteed device delay in between these and some disk drives
|
|
502 ;send back-to-back bytes. In addition, there are demos that have DLIs
|
|
503 ;active during SIO loads. Therefore, we avoid turning off the receive
|
|
504 ;interrupt and instead hold it off to give us the best chance of snagging
|
|
505 ;the first and second bytes successfully, even if delayed.
|
|
506 EA32 78 sei
|
|
507 EA33 60 rts
|
|
508
|
|
509 EA34 timeout:
|
|
510 EA34 A0 8A ldy #SIOErrorTimeout
|
|
511 EA36 78 sei
|
|
512 EA37 60 rts
|
|
513 .endp
|
|
514
|
|
515 ;==============================================================================
|
|
516 EA38 .proc SIOReceiveStop
|
|
517 ;shut off receive IRQs
|
|
518 EA38 A5 10 lda pokmsk
|
|
519 EA3A 29 D7 and #$d7
|
|
520 EA3C 85 10 sta pokmsk
|
|
521 EA3E 8D 0E D2 sta irqen
|
|
522 EA41 58 cli
|
|
523 EA42 60 rts
|
|
524 .endp
|
|
525
|
|
526 ;==============================================================================
|
|
527 ; SIO serial input routine
|
|
528 ;
|
|
529 ; DOS 2.0S replaces (VSERIN), so it's critical that this routine follow the
|
|
530 ; rules compatible with DOS. The rules are as follows:
|
|
531 ;
|
|
532 ; BUFRLO/BUFRHI: Points to next byte to read. Note that this is different
|
|
533 ; from (VSEROR)!
|
|
534 ; BFENLO/BFENHI: Points one after last byte in buffer.
|
|
535 ; BUFRFL: Set when all data bytes have been read.
|
|
536 ; NOCKSM: Set if no checksum byte is expected. Cleared after checked.
|
|
537 ; RECVDN: Set when receive is complete, including any checksum.
|
|
538 ;
|
|
539 EA43 .proc SIOInputReadyHandler
|
|
540 EA43 A5 38 lda bufrfl
|
|
541 EA45 D0 2A bne receiveChecksum
|
|
542
|
|
543 ;receive data byte
|
|
544 EA47 98 tya
|
|
545 EA48 48 pha
|
|
546 EA49 AD 0D D2 lda serin
|
|
547 EA4C A0 00 ldy #$00
|
|
548 EA4E 91 32 sta (bufrlo),y
|
|
549 EA50 18 clc
|
|
550 EA51 65 31 adc chksum
|
|
551 EA53 69 00 adc #$00
|
|
552 EA55 85 31 sta chksum
|
|
553
|
|
554 ;restore Y now
|
|
555 EA57 68 pla
|
|
556 EA58 A8 tay
|
|
557
|
|
558 ;bump buffer pointer
|
|
559 EA59 E6 32 D0 02 E6 33 inw bufrlo
|
|
560
|
|
561 ;check for EOB
|
|
562 EA5F A5 32 lda bufrlo
|
|
563 EA61 C5 34 cmp bfenlo
|
|
564 EA63 A5 33 lda bufrhi
|
|
565 EA65 E5 35 sbc bfenhi
|
|
566 EA67 90 06 bcc xit
|
|
567
|
|
568 EA69 C6 38 dec bufrfl ;!! - this was $00 coming in
|
|
569
|
|
570 ;should there be a checksum?
|
|
571 EA6B A5 3C lda nocksm
|
|
572 EA6D D0 15 bne skipChecksum
|
|
573 EA6F xit:
|
|
574 EA6F 68 pla
|
|
575 EA70 40 rti
|
|
576
|
|
577 EA71 receiveChecksum:
|
|
578 ;read and compare checksum
|
|
579 EA71 AD 0D D2 lda serin
|
|
580 EA74 C5 31 cmp chksum
|
|
581 EA76 D0 06 bne checksum_fail
|
|
582
|
|
583 EA78 signal_end:
|
|
584 ;set receive done flag
|
|
585 EA78 A9 FF 85 39 mva #$ff recvdn
|
|
586
|
|
587 ;exit
|
|
588 EA7C 68 pla
|
|
589 EA7D 40 rti
|
|
590
|
|
591 EA7E checksum_fail:
|
|
592 EA7E A9 8F lda #SIOErrorChecksum
|
|
593 EA80 85 30 sta status
|
|
594 EA82 D0 F4 bne signal_end ;!! - unconditional
|
|
595
|
|
596 EA84 skipChecksum:
|
|
597 ;set receive done flag
|
|
598 EA84 85 39 sta recvdn
|
|
599
|
|
600 ;clear no checksum flag
|
|
601 EA86 A9 00 lda #0
|
|
602 EA88 85 3C sta nocksm
|
|
603 EA8A 68 pla
|
|
604 EA8B 40 rti
|
|
605 .endp
|
|
606
|
|
607 ;==============================================================================
|
|
608 ; SIO serial output ready routine
|
|
609 ;
|
|
610 ; DOS 2.0S replaces (VSEROR), so it's critical that this routine follow the
|
|
611 ; rules compatible with DOS. The rules are as follows:
|
|
612 ;
|
|
613 ; BUFRLO/BUFRHI: On entry, points to one LESS than the next byte to write.
|
|
614 ; BFENLO/BFENHI: Points to byte immediately after buffer.
|
|
615 ; CHKSUM: Holds running checksum as bytes are output.
|
|
616 ; CHKSNT: $00 if checksum not yet sent, $FF if checksum sent.
|
|
617 ; POKMSK: Used to enable the serial output complete IRQ after sending
|
|
618 ; checksum.
|
|
619 ;
|
|
620 EA8C .proc SIOOutputReadyHandler
|
|
621 ;increment buffer pointer
|
|
622 EA8C E6 32 inc bufrlo
|
|
623 EA8E D0 02 bne addrcc
|
|
624 EA90 E6 33 inc bufrhi
|
|
625 EA92 addrcc:
|
|
626
|
|
627 ;compare against buffer end
|
|
628 EA92 A5 32 lda bufrlo
|
|
629 EA94 C5 34 cmp bfenlo
|
|
630 EA96 A5 33 lda bufrhi
|
|
631 EA98 E5 35 sbc bfenhi ;set flags according to (dst - end)
|
|
632 EA9A B0 13 bcs doChecksum
|
|
633
|
|
634 ;save Y
|
|
635 EA9C 98 tya
|
|
636 EA9D 48 pha
|
|
637
|
|
638 ;send out next byte
|
|
639 EA9E A0 00 ldy #0
|
|
640 EAA0 B1 32 lda (bufrlo),y
|
|
641 EAA2 8D 0D D2 sta serout
|
|
642
|
|
643 ;update checksum
|
|
644 EAA5 65 31 adc chksum
|
|
645 EAA7 69 00 adc #0
|
|
646 EAA9 85 31 sta chksum
|
|
647
|
|
648 ;restore registers and exit
|
|
649 EAAB 68 pla
|
|
650 EAAC A8 tay
|
|
651 EAAD 68 pla
|
|
652 EAAE 40 rti
|
|
653
|
|
654 EAAF doChecksum:
|
|
655 ;send checksum
|
|
656 EAAF A5 31 lda chksum
|
|
657 EAB1 8D 0D D2 sta serout
|
|
658
|
|
659 ;set checksum sent flag
|
|
660 EAB4 A9 FF 85 3B mva #$ff chksnt
|
|
661
|
|
662 ;enable output complete IRQ and disable serial output IRQ
|
|
663 EAB8 A5 10 lda pokmsk
|
|
664 EABA 09 08 ora #$08
|
|
665 EABC 29 EF and #$ef
|
|
666 EABE 85 10 sta pokmsk
|
|
667 EAC0 8D 0E D2 sta irqen
|
|
668
|
|
669 EAC3 68 pla
|
|
670 EAC4 40 rti
|
|
671 .endp
|
|
672
|
|
673 ;==============================================================================
|
|
674 EAC5 .proc SIOOutputCompleteHandler
|
|
675 ;check that we've sent the checksum
|
|
676 EAC5 A5 3B lda chksnt
|
|
677 EAC7 F0 0B beq xit
|
|
678
|
|
679 ;we're done sending the checksum
|
|
680 EAC9 85 3A sta xmtdon
|
|
681
|
|
682 ;need to shut off this interrupt as it is not latched
|
|
683 EACB A5 10 lda pokmsk
|
|
684 EACD 29 F7 and #$f7
|
|
685 EACF 85 10 sta pokmsk
|
|
686 EAD1 8D 0E D2 sta irqen
|
|
687
|
|
688 EAD4 xit:
|
|
689 EAD4 68 pla
|
|
690 EAD5 40 rti
|
|
691 .endp
|
|
692
|
|
693 ;==============================================================================
|
|
694 EAD6 .proc SIOCountdown1Handler
|
|
695 ;signal operation timeout
|
|
696 EAD6 A9 00 8D 17 03 mva #0 timflg
|
|
697 EADB 60 rts
|
|
698 .endp
|
|
699
|
|
700 ;==============================================================================
|
|
701 EADC .proc SIOCassette
|
|
702 ;check if it's read sector
|
|
703 EADC AD 02 03 lda dcomnd
|
|
704 EADF C9 52 cmp #$52
|
|
705 EAE1 F0 0F beq isread
|
|
706
|
|
707 ;check if it's put sector
|
|
708 EAE3 C9 50 cmp #$50
|
|
709 EAE5 F0 05 beq iswrite
|
|
710
|
|
711 ;nope, bail
|
|
712 EAE7 A0 8B ldy #SIOErrorNAK
|
|
713 EAE9 4C D7 E8 jmp SIO.xit
|
|
714
|
|
715 EAEC iswrite:
|
|
716 EAEC 20 F8 EA jsr SIOCassetteWriteFrame
|
|
717 EAEF 4C D7 E8 jmp SIO.xit
|
|
718
|
|
719 EAF2 isread:
|
|
720 EAF2 20 09 EB jsr SIOCassetteReadFrame
|
|
721 EAF5 4C D7 E8 jmp SIO.xit
|
|
722 .endp
|
|
723
|
|
724 ;==============================================================================
|
|
725 EAF8 .proc SIOCassetteWriteFrame
|
|
726 ;wait for pre-record write tone or IRG read delay
|
|
727 EAF8 A2 02 ldx #2
|
|
728 EAFA 20 5B EE jsr CassetteWaitLongShortCheck
|
|
729
|
|
730 ;set up to transmit
|
|
731 EAFD 20 47 E9 jsr SIOSendEnable
|
|
732
|
|
733 ;setup buffer pointers
|
|
734 EB00 20 B5 E9 jsr SIOSetupBufferPointers
|
|
735
|
|
736 ;send data frame
|
|
737 EB03 20 CB E9 jsr SIOSend
|
|
738
|
|
739 ;all done
|
|
740 EB06 4C D7 E8 jmp SIO.xit
|
|
741 .endp
|
|
742
|
|
743 ;==============================================================================
|
|
744 ; Read cassette frame
|
|
745 ;
|
|
746 ; Wait for long/short IRG, measure baud rate from sync mark, and read frame.
|
|
747 ;
|
|
748 ; When reading a cassette frame, the audio configuration is expected to be
|
|
749 ; as follows:
|
|
750 ;
|
|
751 ; Channel 1: Inaudible (31.5KHz)
|
|
752 ; Channel 2: Inaudible (31.5KHz)
|
|
753 ; Channel 3: Silent
|
|
754 ; Channel 4: Audible if enabled in SOUNDR (600Hz modulated by async read)
|
|
755 ;
|
|
756 ; This is necessary for proper tape loading sounds.
|
|
757 ;
|
|
758 EB09 .proc SIOCassetteReadFrame
|
|
759 ;wait for pre-record write tone or IRG read delay
|
|
760 EB09 A2 04 ldx #4
|
|
761 EB0B 20 5B EE jsr CassetteWaitLongShortCheck
|
|
762
|
|
763 ;set to 600 baud, turn on async read to shut off annoying tone
|
|
764 EB0E A2 1A ldx #SIOSendEnable.regdata_cassette_read-SIOSendEnable.regdata+8
|
|
765 EB10 20 6F E9 jsr SIOInitPOKEYWithRegOffsetX
|
|
766
|
|
767 EB13 AD 32 02 lda sskctl
|
|
768 EB16 29 8F and #$8f
|
|
769 EB18 09 10 ora #$10
|
|
770 EB1A 8D 32 02 sta sskctl
|
|
771
|
|
772 ;set timeout (approx; no NTSC/PAL switching yet)
|
|
773 EB1D A9 FF 8D 17 03 mva #$ff timflg
|
|
774 EB22 A9 01 lda #1
|
|
775 EB24 A2 0E ldx #>3600
|
|
776 EB26 A0 10 ldy #<3600
|
|
777 EB28 20 5F C1 jsr VBISetVector
|
|
778
|
|
779 ;wait for beginning of frame
|
|
780 EB2B A9 10 lda #$10 ;test bit 4 of SKSTAT
|
|
781 EB2D waitzerostart:
|
|
782 EB2D 2C 17 03 bit timflg
|
|
783 EB30 10 2B bpl timeout
|
|
784 EB32 2C 0F D2 bit skstat
|
|
785 EB35 D0 F6 bne waitzerostart
|
|
786
|
|
787 ;take first time measurement
|
|
788 EB37 20 F7 EB jsr readtimer
|
|
789 EB3A 8C 0D 03 sty timer1+1
|
|
790 EB3D 8D 0C 03 sta timer1
|
|
791
|
|
792 ;wait for 19 bit transitions
|
|
793 EB40 A9 10 lda #$10 ;test bit 4 of SKSTAT
|
|
794 EB42 A2 0A ldx #10 ;test 10 pairs of bits
|
|
795 EB44 waitone:
|
|
796 EB44 2C 17 03 bit timflg
|
|
797 EB47 10 14 bpl timeout
|
|
798 EB49 2C 0F D2 bit skstat
|
|
799 EB4C F0 F6 beq waitone
|
|
800 EB4E CA dex
|
|
801 EB4F F0 11 beq waitdone
|
|
802 EB51 waitzero:
|
|
803 EB51 2C 17 03 bit timflg
|
|
804 EB54 10 07 bpl timeout
|
|
805 EB56 2C 0F D2 bit skstat
|
|
806 EB59 D0 F6 bne waitzero
|
|
807 EB5B F0 E7 beq waitone
|
|
808
|
|
809 EB5D timeout:
|
|
810 EB5D A0 8A ldy #SIOErrorTimeout
|
|
811 EB5F 4C D7 E8 jmp SIO.xit
|
|
812
|
|
813 EB62 waitdone:
|
|
814
|
|
815 ;take second time measurement
|
|
816 EB62 20 F7 EB jsr readtimer
|
|
817 EB65 8D 10 03 sta timer2
|
|
818 EB68 8C 11 03 sty timer2+1
|
|
819
|
|
820 ;compute baud rate and adjust pokey divisor
|
|
821 ;
|
|
822 ; counts = (pal ? 156 : 131)*rtdelta + vdelta;
|
|
823 ; lines = counts * 2
|
|
824 ; lines_per_bit = lines / 19
|
|
825 ; cycles_per_bit = lines_per_bit * 114
|
|
826 ; pokey_divisor = cycles_per_bit / 2 - 7
|
|
827 ;
|
|
828 ; -or-
|
|
829 ;
|
|
830 ; pokey_divisor = counts * 2 * 114 / 19 / 2 - 7
|
|
831 ; = counts * 6 - 7
|
|
832 ;
|
|
833 ;16 bits at 600 baud is nominally 209 scanline pairs. This means that we
|
|
834 ;don't have to worry about more than two frames, which is at least 262
|
|
835 ;scanline pairs or less than 480 baud.
|
|
836
|
|
837 ;set frame height - 262 scanlines for NTSC, 312 for PAL
|
|
838 EB6B A2 83 ldx #131
|
|
839 EB6D AD 14 D0 lda pal
|
|
840 EB70 4A lsr
|
|
841 EB71 D0 02 A2 9C sne:ldx #156
|
|
842 EB75 8E 15 03 stx temp3
|
|
843
|
|
844 ;compute line difference
|
|
845 EB78 AD 0C 03 lda timer1
|
|
846 EB7B 20 05 EC jsr correct_time
|
|
847 EB7E 85 34 sta bfenlo
|
|
848
|
|
849 EB80 AD 10 03 lda timer2
|
|
850 EB83 20 05 EC jsr correct_time
|
|
851 EB86 18 clc ;!! this decrements one line from the line delta
|
|
852 EB87 E5 34 sbc bfenlo
|
|
853 EB89 85 34 sta bfenlo
|
|
854 EB8B A0 00 ldy #0
|
|
855 EB8D B0 01 88 scs:dey
|
|
856
|
|
857 ;compute frame difference
|
|
858 EB90 AD 11 03 lda timer2+1
|
|
859 EB93 38 ED 0D 03 sub timer1+1
|
|
860 EB97 AA tax
|
|
861
|
|
862 ;accumulate frame difference
|
|
863 EB98 F0 0C beq no_frames
|
|
864 EB9A A5 34 lda bfenlo
|
|
865 EB9C add_frame_loop:
|
|
866 EB9C 18 clc
|
|
867 EB9D 6D 15 03 adc temp3
|
|
868 EBA0 90 01 C8 scc:iny
|
|
869 EBA3 CA dex
|
|
870 EBA4 D0 F6 bne add_frame_loop
|
|
871 EBA6 no_frames:
|
|
872 EBA6 84 35 sty bfenhi
|
|
873
|
|
874 ;compute lines*6 - 7 = (lines-1)*6 - 1
|
|
875 EBA8 0A asl ;(lines-1)*2 (lo)
|
|
876 EBA9 26 35 rol bfenhi ;(lines-1)*2 (hi)
|
|
877 EBAB 85 34 sta bfenlo
|
|
878 EBAD A4 35 ldy bfenhi ;
|
|
879 EBAF 06 34 asl bfenlo ;(lines-1)*4 (lo)
|
|
880 EBB1 26 35 rol bfenhi ;(lines-1)*4 (hi)
|
|
881 EBB3 65 34 adc bfenlo ;(lines-1)*6 (lo)
|
|
882 EBB5 AA tax ;
|
|
883 EBB6 98 tya ;
|
|
884 EBB7 65 35 adc bfenhi ;(lines-1)*6 (hi) (and c=0)
|
|
885 EBB9 CA dex ;-1 line, bringing us to -7
|
|
886 EBBA 8E 04 D2 stx audf3
|
|
887 EBBD 8E EE 02 stx cbaudl
|
|
888 EBC0 E8 inx
|
|
889 EBC1 D0 02 E9 00 sne:sbc #0
|
|
890 EBC5 8D 06 D2 sta audf4
|
|
891 EBC8 8D EF 02 sta cbaudh
|
|
892
|
|
893 ;kick pokey into init mode to reset serial input shift hw
|
|
894 EBCB AE 32 02 ldx sskctl
|
|
895 EBCE 8A txa
|
|
896 EBCF 29 FC and #$fc
|
|
897 EBD1 8D 0F D2 sta skctl
|
|
898
|
|
899 ;reset serial port status
|
|
900 EBD4 8D 0A D2 sta skres
|
|
901
|
|
902 ;re-enable serial input hw
|
|
903 EBD7 8E 0F D2 stx skctl
|
|
904
|
|
905 EBDA 20 B5 E9 jsr SIOSetupBufferPointers
|
|
906
|
|
907 ;stuff two $55 bytes into the buffer, which we "read" above
|
|
908 EBDD A9 55 lda #$55
|
|
909 EBDF A0 00 ldy #0
|
|
910 EBE1 A2 02 ldx #2
|
|
911 EBE3 aaloop:
|
|
912 EBE3 91 32 sta (bufrlo),y
|
|
913 EBE5 E6 32 D0 02 E6 33 inw bufrlo
|
|
914 EBEB CA D0 F5 dex:bne aaloop
|
|
915
|
|
916 ;reset checksum for two $55 bytes and receive frame
|
|
917 EBEE 0A asl
|
|
918 EBEF 85 31 sta chksum
|
|
919
|
|
920 EBF1 20 FC E9 jsr SIOReceive.use_checksum
|
|
921 EBF4 4C 38 EA jmp SIOReceiveStop
|
|
922
|
|
923 ;-------------------------------------------------------------------------
|
|
924 ; We have to be VERY careful when reading (RTCLOK+2, VCOUNT), because
|
|
925 ; the VBI can strike in between. First, we double-check RTCLOK+2 to see
|
|
926 ; if it has changed. If so, we retry the read. Second, we check if
|
|
927 ; VCOUNT=124, which corresponds to lines 248/249. This can correspond to
|
|
928 ; either before or after the VBI -- with CRITIC off the VBI ends around
|
|
929 ; (249, 20-50) -- so we don't know which side of the frame boundary we're
|
|
930 ; on.
|
|
931 ;
|
|
932 EBF7 readtimer:
|
|
933 EBF7 A4 14 ldy rtclok+2
|
|
934 EBF9 AD 0B D4 lda vcount
|
|
935 EBFC C4 14 cpy rtclok+2
|
|
936 EBFE D0 F7 bne readtimer
|
|
937 EC00 C9 7C cmp #124
|
|
938 EC02 F0 F3 beq readtimer
|
|
939 EC04 60 rts
|
|
940
|
|
941 EC05 correct_time:
|
|
942 EC05 38 sec
|
|
943 EC06 E9 7C sbc #124
|
|
944 EC08 B0 03 bcs time_ok
|
|
945 EC0A 6D 15 03 adc temp3
|
|
946 EC0D time_ok:
|
|
947 EC0D 60 rts
|
|
948
|
|
949 .endp
|
|
950
|
|
249 EC0E _KERNEL_REPORT_MODULE_SIZE 'Serial Input/Output (SIO)', $EDEA-$E944
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', $EDEA-$E944, ')', ' ', 'Serial Input/Output (SIO)'
|
|
1 $EC0E -> $0423($04A6) Serial Input/Output (SIO)
|
|
3 = EC0E .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
250
|
|
251 EC0E icl 'disk.s'
|
|
Source: source/Shared/disk.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Disk Routines
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 EC0E .proc DiskInit
|
|
11 .if _KERNEL_XLXE
|
|
12 ;set disk sector size to 128 bytes
|
|
13 EC0E A9 80 8D D5 02 A9 + mwa #$80 dsctln
|
|
14 .endif
|
|
15 EC18 60 rts
|
|
16 .endp
|
|
17
|
|
18 ;==========================================================================
|
|
19 ; Disk handler routine (pointed to by DSKINV)
|
|
20 ;
|
|
21 ; Exit:
|
|
22 ; A = command byte (undocumented; required by Pooyan)
|
|
23 ; Y = status
|
|
24 ; N = 1 if error, 0 if success (high bit of Y)
|
|
25 ; C = 1 if command is >=$21 (undocumented; required by Arcade Machine)
|
|
26 ;
|
|
27 EC19 .proc DiskHandler
|
|
28 EC19 A9 31 8D 00 03 mva #$31 ddevic
|
|
29 EC1E A9 0F 8D 06 03 mva #$0f dtimlo
|
|
30
|
|
31 ;check for status command
|
|
32 EC23 AD 02 03 lda dcomnd
|
|
33 EC26 8D 3B 02 sta ccomnd
|
|
34 EC29 C9 53 cmp #$53
|
|
35 EC2B D0 20 bne notStatus
|
|
36
|
|
37 EC2D A9 EA lda #<dvstat
|
|
38 EC2F 8D 04 03 sta dbuflo
|
|
39 EC32 A9 02 lda #>dvstat
|
|
40 EC34 8D 05 03 sta dbufhi
|
|
41 EC37 0A asl ;hack to save a byte to get $04 since >dvstat is $02
|
|
42 EC38 8D 08 03 sta dbytlo
|
|
43 EC3B A9 00 lda #0
|
|
44 EC3D 8D 09 03 sta dbythi
|
|
45
|
|
46 EC40 20 6B EC jsr do_read
|
|
47 EC43 30 07 bmi xit
|
|
48
|
|
49 ;update format timeout
|
|
50 EC45 AE EC 02 8E 46 02 mvx dvstat+2 dsktim
|
|
51 EC4B AA tax
|
|
52 EC4C xit:
|
|
53 EC4C 60 rts
|
|
54
|
|
55 EC4D notStatus:
|
|
56
|
|
57 ;set disk sector length
|
|
58 .if _KERNEL_XLXE
|
|
59 EC4D AC D5 02 8C 08 03 + mwy dsctln dbytlo
|
|
60 .else
|
|
61 mwy #$80 dbytlo
|
|
62 .endif
|
|
63
|
|
64 ;check for put/write
|
|
65 .if _KERNEL_XLXE
|
|
66 EC59 C9 50 cmp #$50
|
|
67 EC5B F0 1D beq do_write
|
|
68 .endif
|
|
69 EC5D C9 57 cmp #$57
|
|
70 EC5F F0 19 beq do_write
|
|
71
|
|
72 ;check for format, or else assume it's a read command ($52) or similar
|
|
73 EC61 C9 21 cmp #$21
|
|
74 EC63 D0 06 bne do_read
|
|
75
|
|
76 ;it's format... use the format timeout
|
|
77 EC65 AD 46 02 8D 06 03 mva dsktim dtimlo
|
|
78
|
|
79 EC6B do_read:
|
|
80 EC6B A9 40 lda #$40
|
|
81 EC6D do_io:
|
|
82 EC6D 8D 03 03 sta dstats
|
|
83 EC70 20 59 E4 jsr siov
|
|
84
|
|
85 ;load disk command back into A (required by Pooyan)
|
|
86 ;emulate compare against format command (required by Arcade Machine)
|
|
87 ;sort-of emulate compare against status (required by Micropainter)
|
|
88 EC73 AD 02 03 lda dcomnd
|
|
89 EC76 C0 00 cpy #0 ;!! Atari800WinPlus's SIO patch doesn't set STATUS
|
|
90 EC78 38 sec
|
|
91 EC79 60 rts
|
|
92
|
|
93 EC7A do_write:
|
|
94 EC7A A9 80 lda #$80
|
|
95 EC7C D0 EF bne do_io
|
|
96 .endp
|
|
252 EC7E _KERNEL_REPORT_MODULE_SIZE 'Disk Handler', $EE78-$EDEA
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', $EE78-$EDEA, ')', ' ', 'Disk Handler'
|
|
1 $EC7E -> $0070($008E) Disk Handler
|
|
3 = EC7E .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
253
|
|
254 EC7E icl 'printer.s'
|
|
Source: source/Shared/printer.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Printer Handler
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11 EC7E .proc PrinterInit
|
|
12 ;set printer timeout to default
|
|
13 EC7E A9 1E 8D 14 03 mva #30 ptimot
|
|
14 EC83 60 rts
|
|
15 .endp
|
|
16
|
|
17 ;==========================================================================
|
|
18 EC84 .proc PrinterOpen
|
|
19 ;check for sideways mode and compute line size
|
|
20 EC84 A2 28 ldx #40
|
|
21 EC86 A5 2B lda icax2z
|
|
22 EC88 C9 53 cmp #$53
|
|
23 EC8A D0 02 A2 1D sne:ldx #29
|
|
24 EC8E 8E DF 02 stx pbufsz
|
|
25
|
|
26 EC91 A9 00 lda #0
|
|
27 EC93 8D DE 02 sta pbpnt
|
|
28
|
|
29 EC96 xit:
|
|
30 EC96 A0 01 ldy #1
|
|
31 EC98 60 rts
|
|
32 .endp
|
|
33
|
|
34 ;==========================================================================
|
|
35 = EC99 PrinterClose = _PrinterPutByte.close_entry
|
|
36 = ECA0 PrinterPutByte = _PrinterPutByte.put_entry
|
|
37
|
|
38 EC99 .proc _PrinterPutByte
|
|
39 EC99 close_entry:
|
|
40 ;check if we have anything in the buffer
|
|
41 EC99 AD DE 02 lda pbpnt
|
|
42
|
|
43 ;exit if buffer is empty
|
|
44 EC9C F0 F8 beq PrinterOpen.xit
|
|
45
|
|
46 ;fall through to put with EOL
|
|
47 EC9E A9 9B lda #$9b
|
|
48
|
|
49 ECA0 put_entry:
|
|
50 ;preload buffer index (useful later)
|
|
51 ECA0 AE DE 02 ldx pbpnt
|
|
52
|
|
53 ;check for EOL
|
|
54 ECA3 C9 9B cmp #$9b
|
|
55 ECA5 F0 0E beq do_eol
|
|
56
|
|
57 ;mask off MSB
|
|
58 ECA7 29 7F and #$7f
|
|
59
|
|
60 ;put char and advance
|
|
61 ECA9 9D C0 03 sta prnbuf,x
|
|
62 ECAC E8 inx
|
|
63 ECAD 8E DE 02 stx pbpnt
|
|
64
|
|
65 ;check for end of line and exit if not
|
|
66 ECB0 EC DF 02 cpx pbufsz
|
|
67 ECB3 90 E1 bcc PrinterOpen.xit
|
|
68
|
|
69 ;fall through to EOL
|
|
70
|
|
71 ECB5 do_eol:
|
|
72 ;fill remainder of buffer with spaces
|
|
73 ECB5 A9 20 lda #$20
|
|
74 ECB7 fill_loop:
|
|
75 ECB7 EC DF 02 cpx pbufsz
|
|
76 ECBA B0 06 bcs fill_done
|
|
77 ECBC 9D C0 03 sta prnbuf,x
|
|
78 ECBF E8 inx
|
|
79 ECC0 90 F5 bcc fill_loop
|
|
80 ECC2 fill_done:
|
|
81
|
|
82 ;send line to printer
|
|
83 ECC2 A0 0A ldy #10
|
|
84 ECC4 B9 E3 EC 99 FF 02 + mva:rne iocbdat-1,y ddevic-1,y-
|
|
85
|
|
86 ;empty buffer
|
|
87 ECCD 8C DE 02 sty pbpnt
|
|
88
|
|
89 ;set line length
|
|
90 ECD0 8E 08 03 stx dbytlo
|
|
91
|
|
92 ;Compute AUX1 byte from length.
|
|
93 ;
|
|
94 ;Note that the OS manual is wrong -- this byte needs to go into AUX1 and
|
|
95 ;not AUX2 as the manual says.
|
|
96 ;
|
|
97 ; normal (40): 00101000 -> 01001110 ($4E 'N')
|
|
98 ; sideways (29): 00011101 -> 01010011 ($53 'S')
|
|
99 ; 010_1I1_
|
|
100 ECD3 8A txa
|
|
101 ECD4 29 15 and #%00010101
|
|
102 ECD6 49 4E eor #%01001110
|
|
103 ECD8 8D 0A 03 sta daux1 ;set AUX1 to indicate width to device
|
|
104
|
|
105 ;send to printer and exit
|
|
106 ECDB do_io:
|
|
107 ECDB AD 14 03 8D 06 03 mva ptimot dtimlo
|
|
108 ECE1 4C 59 E4 jmp siov
|
|
109
|
|
110 ECE4 iocbdat:
|
|
111 ECE4 40 dta $40 ;device
|
|
112 ECE5 01 dta $01 ;unit
|
|
113 ECE6 57 dta $57 ;command 'W'
|
|
114 ECE7 80 dta $80 ;input/output mode (write)
|
|
115 ECE8 C0 03 dta a(prnbuf) ;buffer address
|
|
116 ECEA 00 00 dta a(0) ;timeout
|
|
117 ECEC 00 00 dta a(0) ;buffer length
|
|
118 .endp
|
|
119
|
|
120 ;==============================================================================
|
|
121 ECEE .proc PrinterGetStatus
|
|
122 ;setup parameter block
|
|
123 ECEE A2 09 ldx #9
|
|
124 ECF0 BD 05 ED 9D 00 03 + mva:rpl iocbdat,x ddevic,x-
|
|
125
|
|
126 ;issue status call
|
|
127 ECF9 20 DB EC jsr _PrinterPutByte.do_io
|
|
128 ECFC 30 06 bmi error
|
|
129
|
|
130 ;update timeout
|
|
131 ECFE AD EC 02 8D 14 03 mva dvstat+2 ptimot
|
|
132
|
|
133 ED04 error:
|
|
134 ED04 60 rts
|
|
135
|
|
136 ED05 iocbdat:
|
|
137 ED05 40 dta $40 ;device
|
|
138 ED06 01 dta $01 ;unit
|
|
139 ED07 53 dta $53 ;command 'S'
|
|
140 ED08 40 dta $40 ;input/output mode (read)
|
|
141 ED09 EA 02 dta a(dvstat) ;buffer address
|
|
142 ED0B 00 00 dta a(0) ;timeout
|
|
143 ED0D 04 00 dta a(4) ;buffer length
|
|
144 .endp
|
|
145
|
|
146 ;==============================================================================
|
|
147 = E4CB PrinterGetByte = CIOExitNotSupported
|
|
148 = E4CB PrinterSpecial = CIOExitNotSupported
|
|
255 ED0F _KERNEL_REPORT_MODULE_SIZE 'Printer Handler', $EF41-$EE78
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', $EF41-$EE78, ')', ' ', 'Printer Handler'
|
|
1 $ED0F -> $0091($00C9) Printer Handler
|
|
3 = ED0F .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
256
|
|
257 ED0F icl 'cassette.s'
|
|
Source: source/Shared/cassette.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Cassette tape support
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11 ED0F .proc CassetteInit
|
|
12 ;Set CBAUDL/CBAUDH to $05CC, the nominal POKEY divisor for 600
|
|
13 ;baud. We don't care about this, but it's documented in the OS
|
|
14 ;Manual.
|
|
15 ED0F A9 CC 8D EE 02 A9 + mwa #$05CC cbaudl
|
|
16 ED19 60 rts
|
|
17 .endp
|
|
18
|
|
19 ;==========================================================================
|
|
20 ; Cassette open routine.
|
|
21 ;
|
|
22 ; XL/XE OS behavior notes:
|
|
23 ; - Attempting to open for none (AUX1=$00) or read/write (AUX1=$0C)
|
|
24 ; results in a Not Supported error (146).
|
|
25 ; - Open for read gives one beep, while open for write gives two beeps.
|
|
26 ; - Break will break out of the wait.
|
|
27 ; - Ctrl+3 during the keypress causes an EOF error (!). This is a side
|
|
28 ; effect of reusing the keyboard handler.
|
|
29 ;
|
|
30 ; CSOPIV behavior:
|
|
31 ; - Does NOT set FTYPE (continuous mode flag).
|
|
32 ; - Sets read mode (WMODE).
|
|
33 ; - Does NOT require ICAX1Z or ICAX2Z to be set.
|
|
34 ;
|
|
35 = ED2D CassetteOpenRead = CassetteOpen.do_open_read
|
|
36 ED1A .proc CassetteOpen
|
|
37 ;stash continuous mode flag
|
|
38 ED1A A5 2B lda icax2z ;!! FIRST TWO BYTES CHECKED BY ARCHON
|
|
39 ED1C 85 3E sta ftype
|
|
40
|
|
41 ;check mode byte for read/write modes
|
|
42 ED1E A2 80 ldx #$80
|
|
43 ED20 A5 2A lda icax1z
|
|
44 ED22 29 0C and #$0c
|
|
45 ED24 C9 04 cmp #$04 ;read?
|
|
46 ED26 F0 05 beq found_read_mode
|
|
47 ED28 C9 08 cmp #$08 ;write?
|
|
48 ED2A F0 03 beq found_write_mode
|
|
49
|
|
50 ;invalid mode -- return not supported
|
|
51 ED2C 60 rts
|
|
52
|
|
53 ED2D do_open_read:
|
|
54 ED2D found_read_mode:
|
|
55 ED2D A2 00 ldx #$00
|
|
56 ED2F found_write_mode:
|
|
57 ED2F 8E 89 02 stx wmode
|
|
58
|
|
59 ;set cassette buffer size to 128 bytes and mark it empty
|
|
60 ED32 A9 80 lda #$80
|
|
61 ED34 85 3D sta bptr
|
|
62 ED36 8D 8A 02 sta blim
|
|
63
|
|
64 ;clear EOF flag
|
|
65 ED39 0A asl
|
|
66 ED3A 85 3F sta feof
|
|
67
|
|
68 ;request one beep for read, or two for write
|
|
69 ED3C 2C 89 02 bit wmode
|
|
70 ED3F 10 05 bpl one_ping_only
|
|
71
|
|
72 ED41 06 3D asl bptr ;!! - set bptr=0 when starting write
|
|
73
|
|
74 ED43 20 87 EE jsr CassetteBell
|
|
75
|
|
76 ED46 one_ping_only:
|
|
77 ED46 20 87 EE jsr CassetteBell
|
|
78
|
|
79 ;wait for a key press
|
|
80 ED49 20 69 FE jsr KeyboardGetByte
|
|
81 ED4C 30 20 bmi aborted
|
|
82
|
|
83 ;need to set up POKEY for writes now to write leader
|
|
84 ED4E 2C 89 02 bit wmode
|
|
85 ED51 10 08 bpl no_write_init
|
|
86 ED53 A9 FF lda #$ff
|
|
87 ED55 8D 0F 03 sta casflg
|
|
88 ED58 20 52 E9 jsr SIOSendEnable.no_irq_setup
|
|
89 ED5B no_write_init:
|
|
90
|
|
91 ;turn on motor (continuous mode or not)
|
|
92 ED5B A9 34 lda #$34
|
|
93 ED5D 8D 02 D3 sta pactl
|
|
94
|
|
95 ;wait for leader (9.6 seconds read, 19.2s write)
|
|
96 ED60 A2 00 ldx #0
|
|
97 ED62 2C 89 02 bit wmode
|
|
98 ED65 30 02 A2 01 smi:ldx #1
|
|
99 ED69 20 61 EE jsr CassetteWait
|
|
100
|
|
101 ;all done
|
|
102 ED6C A0 01 ldy #1
|
|
103 ED6E aborted:
|
|
104 ED6E 60 rts
|
|
105 .endp
|
|
106
|
|
107 ;==========================================================================
|
|
108 ED6F .proc CassetteClose
|
|
109 ;check if we are in write mode
|
|
110 ED6F AD 89 02 lda wmode ;!! FIRST TWO BYTES CHECKED BY ARCHON
|
|
111 ED72 10 0A bpl notwrite
|
|
112
|
|
113 ;check if we have data to write
|
|
114 ED74 A5 3D lda bptr
|
|
115 ED76 F0 03 beq nopartial
|
|
116
|
|
117 ;flush partial record ($FA)
|
|
118 ED78 20 E0 ED jsr CassetteFlush
|
|
119
|
|
120 ED7B nopartial:
|
|
121 ;write EOF record ($FE)
|
|
122 ED7B 20 E0 ED jsr CassetteFlush
|
|
123
|
|
124 ED7E notwrite:
|
|
125 ;stop the motor
|
|
126 ED7E A9 3C lda #$3c
|
|
127 ED80 8D 02 D3 sta pactl
|
|
128
|
|
129 ;kill audio
|
|
130 ED83 A0 00 ldy #0
|
|
131 ED85 8C 01 D2 sty audc1
|
|
132 ED88 8C 03 D2 sty audc2
|
|
133 ED8B 8C 07 D2 sty audc4
|
|
134
|
|
135 ;all done
|
|
136 ED8E C8 iny
|
|
137 ED8F 60 rts
|
|
138 .endp
|
|
139
|
|
140 ;==========================================================================
|
|
141 ED90 .proc CassetteGetByte
|
|
142 ;check if we have an EOF condition
|
|
143 ED90 A5 3F lda feof ;!! FIRST TWO BYTES CHECKED BY ARCHON
|
|
144 ED92 D0 1D bne xit_eof
|
|
145
|
|
146 ED94 fetchbyte:
|
|
147 ;check if we can still fetch a byte
|
|
148 ED94 A6 3D ldx bptr
|
|
149 ED96 EC 8A 02 cpx blim
|
|
150 ED99 F0 08 beq nobytes
|
|
151
|
|
152 ED9B BD 00 04 lda casbuf+3,x
|
|
153 ED9E E6 3D inc bptr
|
|
154 EDA0 A0 01 ldy #1
|
|
155 EDA2 60 rts
|
|
156
|
|
157 EDA3 nobytes:
|
|
158 ;fetch more bytes
|
|
159 EDA3 20 10 EE jsr CassetteReadBlock
|
|
160 EDA6 30 0B bmi error
|
|
161
|
|
162 ;check control byte
|
|
163 EDA8 AD FF 03 lda casbuf+2
|
|
164 EDAB C9 FE cmp #$fe
|
|
165 EDAD D0 05 bne noteofbyte
|
|
166
|
|
167 ;found $FE (EOF) - set flag and return EOF
|
|
168 EDAF 85 3F sta feof
|
|
169 EDB1 xit_eof:
|
|
170 EDB1 A0 88 ldy #CIOStatEndOfFile
|
|
171 EDB3 error:
|
|
172 EDB3 60 rts
|
|
173
|
|
174 EDB4 noteofbyte:
|
|
175 ;reset buffer ptr
|
|
176 EDB4 A2 00 86 3D mvx #0 bptr
|
|
177
|
|
178 ;assume full block first (128 bytes)
|
|
179 EDB8 A2 80 ldx #$80
|
|
180
|
|
181 ;check if it actually is one
|
|
182 EDBA C9 FC cmp #$fc
|
|
183 EDBC D0 06 bne not_full_block
|
|
184
|
|
185 EDBE init_new_block:
|
|
186 ;reset block length and loop back
|
|
187 EDBE 8E 8A 02 stx blim
|
|
188 EDC1 4C 94 ED jmp fetchbyte
|
|
189
|
|
190 EDC4 not_full_block:
|
|
191 ;check if we have a partial block
|
|
192 EDC4 C9 FA cmp #$fa
|
|
193 EDC6 D0 05 bne not_partial_block
|
|
194
|
|
195 ;set length of partial block and the jump to init+loop
|
|
196 EDC8 AE 7F 04 ldx casbuf+130
|
|
197 EDCB B0 F1 bcs init_new_block
|
|
198
|
|
199 EDCD not_partial_block:
|
|
200 ;uh oh... bad control byte.
|
|
201 EDCD A0 A3 ldy #CIOStatFatalDiskIO
|
|
202 EDCF 60 rts
|
|
203 .endp
|
|
204
|
|
205 ;==========================================================================
|
|
206 EDD0 .proc CassettePutByte
|
|
207 ;put a byte into the buffer
|
|
208 EDD0 A6 3D ldx bptr ;!! FIRST TWO BYTES CHECKED BY ARCHON
|
|
209 EDD2 9D 00 04 sta casbuf+3,x
|
|
210
|
|
211 ;bump and check if it's time to write
|
|
212 EDD5 E8 inx
|
|
213 EDD6 86 3D stx bptr
|
|
214 EDD8 EC 8A 02 cpx blim
|
|
215 EDDB B0 03 bcs CassetteFlush
|
|
216
|
|
217 ;all done
|
|
218 EDDD A0 01 ldy #1
|
|
219 EDDF 60 rts
|
|
220 .endp
|
|
221
|
|
222 ;==========================================================================
|
|
223 EDE0 .proc CassetteFlush
|
|
224 EDE0 A9 00 lda #0
|
|
225
|
|
226 ;set control byte based on buffer level
|
|
227 EDE2 A2 FE ldx #$fe ;empty -> EOF
|
|
228 EDE4 A4 3D ldy bptr ;get buffer level
|
|
229 EDE6 D0 08 bne not_empty ;skip not empty
|
|
230
|
|
231 ;clear buffer for EOF
|
|
232 EDE8 99 00 04 C8 10 FA sta:rpl casbuf+3,y+
|
|
233 EDEE 30 0C bmi is_empty ;!! - unconditional
|
|
234
|
|
235 EDF0 not_empty:
|
|
236 EDF0 A2 FC ldx #$fc ;load complete code
|
|
237 EDF2 CC 8A 02 cpy blim ;check if buffer is full
|
|
238 EDF5 B0 05 bcs is_complete ;skip if so
|
|
239 EDF7 A2 FA ldx #$fa ;load partial code
|
|
240 EDF9 8C 7F 04 sty casbuf+130 ;store level in last byte
|
|
241 EDFC is_complete:
|
|
242 EDFC is_empty:
|
|
243
|
|
244 ;store code
|
|
245 EDFC 8E FF 03 stx casbuf+2
|
|
246
|
|
247 ;reset buffer level
|
|
248 EDFF 85 3D sta bptr
|
|
249
|
|
250 ;setup sync bytes
|
|
251 EE01 A9 55 lda #$55
|
|
252 EE03 8D FD 03 sta casbuf
|
|
253 EE06 8D FE 03 sta casbuf+1
|
|
254
|
|
255 ;issue write request and exit
|
|
256 EE09 A2 80 ldx #$80
|
|
257 EE0B A0 50 ldy #'P'
|
|
258 EE0D 4C 14 EE jmp CassetteDoIO
|
|
259 .endp
|
|
260
|
|
261 ;==========================================================================
|
|
262 = E4C9 CassetteGetStatus = CIOExitSuccess
|
|
263 = E4CB CassetteSpecial = CIOExitNotSupported
|
|
264
|
|
265 ;==========================================================================
|
|
266 ; CassetteDoIO
|
|
267 ;
|
|
268 ; X = DSTATS value
|
|
269 ; Y = SIO command byte
|
|
270 ;
|
|
271 ; Note that SOUNDR must take effect each time a cassette I/O operation
|
|
272 ; occurs.
|
|
273 ;
|
|
274 = EE14 CassetteDoIO = _CassetteDoIO.do_io
|
|
275 = EE10 CassetteReadBlock = _CassetteDoIO.read_block
|
|
276
|
|
277 EE10 .proc _CassetteDoIO
|
|
278 EE10 read_block:
|
|
279 EE10 A2 40 ldx #$40
|
|
280 EE12 A0 52 ldy #'R'
|
|
281 EE14 do_io:
|
|
282 ;start the motor if not already running
|
|
283 EE14 A9 34 lda #$34
|
|
284 EE16 8D 02 D3 sta pactl
|
|
285
|
|
286 ;set up SIO read/write
|
|
287 EE19 8E 03 03 stx dstats
|
|
288 EE1C 8C 02 03 sty dcomnd
|
|
289 EE1F A9 FD 8D 04 03 A9 + mwa #casbuf dbuflo
|
|
290 EE29 A9 83 8D 08 03 A9 + mwa #131 dbytlo
|
|
291 EE33 A9 60 8D 00 03 mva #$60 ddevic
|
|
292 EE38 A9 00 8D 01 03 mva #0 dunit
|
|
293 EE3D A5 3E 8D 0B 03 mva ftype daux2
|
|
294
|
|
295 ;do it
|
|
296 EE42 20 59 E4 jsr siov
|
|
297
|
|
298 ;check if we are in continuous mode (again)
|
|
299 EE45 A5 3E lda ftype
|
|
300 EE47 30 0F bmi rolling_stop
|
|
301
|
|
302 ;not in continuous mode -- wait for post-write tone if writing
|
|
303 EE49 2C 89 02 bit wmode
|
|
304 EE4C 10 05 bpl no_pwt
|
|
305 EE4E A2 06 ldx #6
|
|
306 EE50 20 61 EE jsr CassetteWait
|
|
307 EE53 no_pwt:
|
|
308
|
|
309 ;stop the motor
|
|
310 EE53 A9 3C lda #$3c
|
|
311 EE55 8D 02 D3 sta pactl
|
|
312
|
|
313 EE58 rolling_stop:
|
|
314 EE58 A4 30 ldy status
|
|
315 EE5A 60 rts
|
|
316 .endp
|
|
317
|
|
318 ;==========================================================================
|
|
319 ;Entry:
|
|
320 ; X = delay type
|
|
321 ;
|
|
322 = EE61 CassetteWait = CassetteWaitLongShortCheck.normal_entry
|
|
323 EE5B .proc CassetteWaitLongShortCheck
|
|
324 EE5B 2C 0B 03 bit daux2
|
|
325 EE5E 10 01 E8 spl:inx
|
|
326 EE61 normal_entry:
|
|
327 EE61 20 13 E9 jsr SIOSetTimeoutVector
|
|
328 EE64 BC 79 EE ldy wait_table_lo,x
|
|
329 EE67 BD 80 EE lda wait_table_hi,x
|
|
330 EE6A AA tax
|
|
331 EE6B A9 01 lda #1
|
|
332 EE6D 8D 17 03 sta timflg
|
|
333 EE70 20 5F C1 jsr VBISetVector
|
|
334 EE73 AD 17 03 D0 FB lda:rne timflg
|
|
335 EE78 60 rts
|
|
336
|
|
337 EE79 wait_table_lo:
|
|
338 EE79 80 dta <$0480 ;$00 - write file leader (19.2 seconds NTSC)
|
|
339 EE7A 40 dta <$0240 ;$01 - read leader delay (9.6 seconds NTSC)
|
|
340 EE7B B4 dta <$00B4 ;$02 - long pre-record write tone (3.0s NTSC)
|
|
341 EE7C 0F dta <$000F ;$03 - short pre-record write tone (0.25s NTSC)
|
|
342 EE7D 78 dta <$0078 ;$04 - long read IRG (2.0s NTSC)
|
|
343 EE7E 0A dta <$000A ;$05 - short read IRG (0.16s NTSC)
|
|
344 EE7F 3C dta <$003C ;$06 - post record gap (1s NTSC)
|
|
345
|
|
346 EE80 wait_table_hi:
|
|
347 EE80 04 dta >$0480 ;$00 - write file leader (19.2 seconds NTSC)
|
|
348 EE81 02 dta >$0240 ;$01 - read leader delay (9.6 seconds NTSC)
|
|
349 EE82 00 dta >$00B4 ;$02 - long pre-record write tone (3.0s NTSC)
|
|
350 EE83 00 dta >$000F ;$03 - short pre-record write tone (0.25s NTSC)
|
|
351 EE84 00 dta >$0078 ;$04 - long read IRG (2.0s NTSC)
|
|
352 EE85 00 dta >$000A ;$05 - short read IRG (0.16s NTSC)
|
|
353 EE86 00 dta >$003C ;$06 - post record gap (1s NTSC)
|
|
354 .endp
|
|
355
|
|
356 ;==========================================================================
|
|
357 ; Sound a bell using the console speaker (cassette version)
|
|
358 ;
|
|
359 ; Modified:
|
|
360 ; A, X, Y
|
|
361 ;
|
|
362 EE87 .proc CassetteBell
|
|
363 EE87 A0 00 ldy #0
|
|
364 EE89 98 tya
|
|
365 EE8A soundloop:
|
|
366 EE8A A2 0A ldx #10
|
|
367 EE8C 48 pha
|
|
368 EE8D delay:
|
|
369 EE8D AD 0B D4 lda vcount
|
|
370 EE90 CD 0B D4 F0 FB cmp:req vcount
|
|
371 EE95 CA dex
|
|
372 EE96 D0 F5 bne delay
|
|
373 EE98 68 pla
|
|
374 EE99 49 08 eor #$08
|
|
375 EE9B 8D 1F D0 sta consol
|
|
376 EE9E D0 EA bne soundloop
|
|
377 EEA0 88 dey
|
|
378 EEA1 D0 E7 bne soundloop
|
|
379 EEA3 60 rts
|
|
380 .endp
|
|
258 EEA4 _KERNEL_REPORT_MODULE_SIZE 'Cassette Handler', $F0E3-$EF41
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', $F0E3-$EF41, ')', ' ', 'Cassette Handler'
|
|
1 $EEA4 -> $0195($01A2) Cassette Handler
|
|
3 = EEA4 .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
259
|
|
260 .ifdef _KERNEL_816
|
|
261 icl 'init816.s'
|
|
262 .else
|
|
263 EEA4 icl 'init.s'
|
|
Source: source/Shared/init.s
|
|
1 ; Altirra - Atari 800/800XL emulator
|
|
2 ; Kernel ROM replacement - Initialization
|
|
3 ; Copyright (C) 2008-2019 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 .if _KERNEL_XLXE
|
|
11 EEA4 .proc InitBootSignature
|
|
12 EEA4 5C 93 25 dta $5C,$93,$25
|
|
13 .endp
|
|
14 .endif
|
|
15
|
|
16 EEA7 .proc InitHandlerTable
|
|
17 EEA7 50 30 E4 dta c'P',a(printv)
|
|
18 EEAA 43 40 E4 dta c'C',a(casetv)
|
|
19 EEAD 45 00 E4 dta c'E',a(editrv)
|
|
20 EEB0 53 10 E4 dta c'S',a(screnv)
|
|
21 EEB3 4B 20 E4 dta c'K',a(keybdv)
|
|
22 .endp
|
|
23
|
|
24 EEB6 .nowarn .proc _InitReset
|
|
25 EEB6 run_diag:
|
|
26 ; start diagnostic cartridge
|
|
27 EEB6 6C FE BF jmp ($bffe)
|
|
28
|
|
29 = EEB9 .def :InitReset
|
|
30 ;mask interrupts and initialize CPU
|
|
31 EEB9 78 sei
|
|
32 EEBA D8 cld
|
|
33 EEBB A2 FF ldx #$ff
|
|
34 EEBD 9A txs
|
|
35
|
|
36 .if _KERNEL_XLXE
|
|
37 ;wait for everything to stabilize (0.1s) (XL/XE only)
|
|
38 EEBE A0 8C ldy #140
|
|
39 EEC0 stabilize_loop:
|
|
40 EEC0 CA D0 FD dex:rne
|
|
41 EEC3 88 dey
|
|
42 EEC4 D0 FA bne stabilize_loop
|
|
43
|
|
44 ;check for warmstart signature (XL/XE)
|
|
45 EEC6 A2 02 ldx #2
|
|
46 EEC8 warm_check:
|
|
47 EEC8 BD 3D 03 lda pupbt1,x
|
|
48 EECB DD A4 EE cmp InitBootSignature,x
|
|
49 EECE D0 06 bne cold_boot
|
|
50 EED0 CA dex
|
|
51 EED1 10 F5 bpl warm_check
|
|
52
|
|
53 EED3 4C 4F EF jmp InitWarmStart
|
|
54 .endif
|
|
55
|
|
56 = EED6 .def :InitColdStart
|
|
57 EED6 cold_boot:
|
|
58 ; 1. initialize CPU
|
|
59 EED6 78 sei
|
|
60 EED7 D8 cld
|
|
61 EED8 A2 FF ldx #$ff
|
|
62 EEDA 9A txs
|
|
63
|
|
64 ; 2. clear warmstart flag
|
|
65 EEDB E8 inx
|
|
66 EEDC 86 08 stx warmst
|
|
67
|
|
68 ; 3. test for diagnostic cartridge
|
|
69 EEDE AD FC BF lda $bffc
|
|
70 EEE1 D0 17 bne not_diag
|
|
71 EEE3 A2 FF ldx #$ff
|
|
72 EEE5 EC FF BF cpx $bfff ;prevent diagnostic cart from activating if addr is $FFxx
|
|
73 EEE8 F0 10 beq not_diag
|
|
74 EEEA 8E FC BF stx $bffc
|
|
75 EEED CD FC BF cmp $bffc
|
|
76 EEF0 8D FC BF sta $bffc
|
|
77 EEF3 D0 05 bne not_diag
|
|
78
|
|
79 ; is it enabled?
|
|
80 EEF5 2C FD BF bit $bffd
|
|
81 EEF8 30 BC bmi run_diag
|
|
82
|
|
83 EEFA not_diag:
|
|
84
|
|
85 EEFA 20 80 EF jsr InitHardwareReset
|
|
86
|
|
87 .if _KERNEL_XLXE
|
|
88 ;check for OPTION and enable BASIC (note that we do NOT set BASICF just yet)
|
|
89 EEFD A9 04 lda #4
|
|
90 EEFF 2C 1F D0 bit consol
|
|
91 EF02 F0 12 beq no_basic
|
|
92
|
|
93 .ifdef _KERNEL_SOFTKICK
|
|
94 ldx #$fc
|
|
95 .else
|
|
96 EF04 A2 FD ldx #$fd
|
|
97 .endif
|
|
98
|
|
99 ;check for keyboard present + SELECT or no keyboard + no SELECT and enable game if so
|
|
100 EF06 AD 12 D0 lda trig2 ;check keyboard present (1 = present)
|
|
101 EF09 0A asl
|
|
102 EF0A 4D 1F D0 eor consol ;XOR against select (0 = pressed)
|
|
103 EF0D 29 02 and #$02
|
|
104
|
|
105 .ifdef _KERNEL_SOFTKICK
|
|
106 seq:ldx #$be
|
|
107 .else
|
|
108 EF0F F0 02 A2 BF seq:ldx #$bf
|
|
109 .endif
|
|
110
|
|
111 EF13 8E 01 D3 stx portb ;enable GAME or BASIC
|
|
112
|
|
113 EF16 no_basic:
|
|
114 .endif
|
|
115
|
|
116 ; 4. measure memory -> tramsz
|
|
117 EF16 20 B0 EF jsr InitMemory
|
|
118
|
|
119 ; 6. clear memory from $0008 up to [tramsz,0]
|
|
120 .ifdef _KERNEL_SOFTKICK
|
|
121 ldx #$50
|
|
122 .else
|
|
123 EF19 A6 06 ldx tramsz
|
|
124 .endif
|
|
125 EF1B A0 08 ldy #8
|
|
126 EF1D A9 00 85 66 mva #0 a1
|
|
127 EF21 85 67 sta a1+1
|
|
128 EF23 clearloop:
|
|
129 EF23 91 66 C8 D0 FB sta:rne (a1),y+
|
|
130 EF28 E6 67 inc a1+1
|
|
131 EF2A CA dex
|
|
132 EF2B D0 F6 bne clearloop
|
|
133
|
|
134 .if _KERNEL_XLXE
|
|
135 ;Blip the self test ROM for a second -- this is one way that Altirra detects
|
|
136 ;that Option has been used by the OS. The XL/XE OS does this as part of its
|
|
137 ;ROM checksum routine (which we don't bother with).
|
|
138 EF2D AE 01 D3 ldx portb
|
|
139 EF30 8A txa
|
|
140 EF31 29 7F and #$7f
|
|
141 EF33 8D 01 D3 sta portb
|
|
142 EF36 8E 01 D3 stx portb
|
|
143 .endif
|
|
144
|
|
145 ; 7. set dosvec to blackboard routine
|
|
146 .if _KERNEL_USE_BOOT_SCREEN
|
|
147 EF39 A9 9B 85 0A A9 E4 + mwa #SelfTestEntry dosvec
|
|
148 .else
|
|
149 mwa #Blackboard dosvec
|
|
150 .endif
|
|
151
|
|
152 ; 8. set coldstart flag
|
|
153 EF41 CE 44 02 dec coldst ;!! coldst=0 from clear loop above, now $ff
|
|
154
|
|
155 .if _KERNEL_XLXE
|
|
156 ; set BASIC flag
|
|
157 EF44 AD 01 D3 lda portb
|
|
158 EF47 29 02 and #$02
|
|
159 EF49 8D F8 03 sta basicf
|
|
160 .endif
|
|
161
|
|
162 ; 9. set screen margins
|
|
163 ; 10. initialize RAM vectors
|
|
164 ; 11. set misc database values
|
|
165 ; 12. enable IRQ interrupts
|
|
166 ; 13. initialize device table
|
|
167 ; 14. initialize cartridges
|
|
168 ; 15. use IOCB #0 to open screen editor (E)
|
|
169 ; 16. wait for VBLANK so screen is initialized
|
|
170 ; 17. do cassette boot, if it was requested
|
|
171 ; 18. do disk boot
|
|
172 ; 19. reset coldstart flag
|
|
173 ; 20. run cartridges or blackboard
|
|
174 EF4C 4C EE EF jmp InitEnvironment
|
|
175 .endp
|
|
176
|
|
177 ;==============================================================================
|
|
178 EF4F .proc InitWarmStart
|
|
179 ; A. initialize CPU
|
|
180 ;
|
|
181 ; Undocumented: Check if cold start completed (COLDST=0); if not, force
|
|
182 ; a cold start. ACTris 2.1 relies on this since its boot doesn't reset
|
|
183 ; COLDST. This is also required to work on Atari800WinPLus, which doesn't
|
|
184 ; clear memory on a cold start.
|
|
185 ;
|
|
186 EF4F 78 sei ;!! FIRST TWO BYTES CHECKED BY ARCHON
|
|
187 EF50 AD 44 02 lda coldst
|
|
188 EF53 D0 81 bne InitColdStart
|
|
189 EF55 D8 cld
|
|
190 EF56 A2 FF ldx #$ff
|
|
191 EF58 9A txs
|
|
192
|
|
193 ; B. set warmstart flag
|
|
194 EF59 86 08 stx warmst
|
|
195
|
|
196 ; reinitialize hardware without doing a full clear
|
|
197 EF5B 20 80 EF jsr InitHardwareReset
|
|
198
|
|
199 .if _KERNEL_XLXE
|
|
200 ; reinitialize BASIC
|
|
201 EF5E AD F8 03 lda basicf
|
|
202 EF61 D0 05 A9 FD 8D 01 + sne:mva #$fd portb
|
|
203 .endif
|
|
204
|
|
205 ; C. check for diag, measure memory, clear hw registers
|
|
206 EF68 20 B0 EF jsr InitMemory
|
|
207
|
|
208 ; D. zero 0010-007F and 0200-03EC (must not clear BASICF).
|
|
209 EF6B A2 60 ldx #$60
|
|
210 EF6D A9 00 lda #0
|
|
211 EF6F 95 0F CA D0 FB sta:rne $0f,x-
|
|
212
|
|
213 EF74 dbclear:
|
|
214 EF74 9D 00 02 sta $0200,x
|
|
215 EF77 9D ED 02 sta $02ed,x
|
|
216 EF7A E8 inx
|
|
217 EF7B D0 F7 bne dbclear
|
|
218
|
|
219 ; E. steps 9-16 above
|
|
220 ; F. if cassette boot was successful on cold boot, execute cassette init
|
|
221 ; G. if disk boot was successful on cold boot, execute disk init
|
|
222 ; H. same as steps 19 and 20
|
|
223 EF7D 4C EE EF jmp InitEnvironment
|
|
224 .endp
|
|
225
|
|
226 ;==============================================================================
|
|
227 EF80 .proc InitHardwareReset
|
|
228 ; clear all hardware registers
|
|
229 EF80 A0 00 ldy #0
|
|
230 EF82 98 tya
|
|
231 EF83 hwclear:
|
|
232 EF83 99 00 D0 sta $d000,y
|
|
233 EF86 99 00 D2 sta $d200,y
|
|
234 EF89 99 00 D4 sta $d400,y
|
|
235 EF8C C8 iny
|
|
236 EF8D D0 F4 bne hwclear
|
|
237
|
|
238 ;initialize PIA
|
|
239 EF8F A9 3C lda #$3c
|
|
240 EF91 A2 38 ldx #$38
|
|
241
|
|
242 .ifdef _KERNEL_SOFTKICK
|
|
243 stx pactl ;switch to DDRA
|
|
244 sty porta ;portA -> input
|
|
245 sta pactl ;switch to IORA
|
|
246 sty porta ;portA -> $00
|
|
247 sta pbctl ;switch to IORB
|
|
248 dey
|
|
249 dey
|
|
250 sty portb ;portB -> $FE
|
|
251 stx pbctl ;switch to DDRB
|
|
252 iny
|
|
253 sty portb ;portB -> all output
|
|
254 sta pbctl ;switch to IORB
|
|
255 .elseif _KERNEL_XLXE
|
|
256 EF93 8E 02 D3 stx pactl ;switch to DDRA
|
|
257 EF96 8C 00 D3 sty porta ;portA -> input
|
|
258 EF99 8D 02 D3 sta pactl ;switch to IORA
|
|
259 EF9C 8C 00 D3 sty porta ;portA -> $00
|
|
260 EF9F 8D 03 D3 sta pbctl ;switch to IORB
|
|
261 EFA2 88 dey
|
|
262 EFA3 8C 01 D3 sty portb ;portB -> $FF
|
|
263 EFA6 8E 03 D3 stx pbctl ;switch to DDRB
|
|
264 EFA9 8C 01 D3 sty portb ;portB -> all output
|
|
265 EFAC 8D 03 D3 sta pbctl ;switch to IORB
|
|
266 .else
|
|
267 stx pactl ;switch to DDRA
|
|
268 stx pbctl ;switch to DDRB
|
|
269 sty porta ;portA -> input
|
|
270 sty portb ;portB -> input
|
|
271 sta pactl ;switch to IORA
|
|
272 sta pbctl ;switch to IORB
|
|
273 sty porta ;portA -> $00
|
|
274 sty portb ;portB -> $00
|
|
275 .endif
|
|
276 EFAF 60 rts
|
|
277 .endp
|
|
278
|
|
279 ;==============================================================================
|
|
280 EFB0 .proc InitMemory
|
|
281 ; 4. measure memory -> tramsz
|
|
282 EFB0 A0 00 ldy #$00
|
|
283 EFB2 84 64 sty adress
|
|
284 EFB4 A2 02 ldx #$02
|
|
285 EFB6 pageloop:
|
|
286 EFB6 86 65 stx adress+1
|
|
287 EFB8 B1 64 lda (adress),y
|
|
288 EFBA 49 FF eor #$ff
|
|
289 EFBC 91 64 sta (adress),y
|
|
290 EFBE D1 64 cmp (adress),y
|
|
291 EFC0 D0 09 bne notRAM
|
|
292 EFC2 49 FF eor #$ff
|
|
293 EFC4 91 64 sta (adress),y
|
|
294 EFC6 E8 inx
|
|
295
|
|
296 .if _KERNEL_XLXE
|
|
297 EFC7 E0 C0 cpx #$c0
|
|
298 .else
|
|
299 cpx #$d0
|
|
300 .endif
|
|
301
|
|
302 EFC9 D0 EB bne pageloop
|
|
303 EFCB notRAM:
|
|
304 EFCB 86 06 stx tramsz
|
|
305
|
|
306 EFCD 60 rts
|
|
307 .endp
|
|
308
|
|
309 ;==============================================================================
|
|
310 EFCE .proc InitVectorTable1
|
|
311 EFCE 55 C0 dta a(IntExitHandler_None) ;$0200 VDSLST
|
|
312 EFD0 54 C0 dta a(IntExitHandler_A) ;$0202 VPRCED
|
|
313 EFD2 54 C0 dta a(IntExitHandler_A) ;$0204 VINTER
|
|
314 EFD4 54 C0 dta a(IntExitHandler_A) ;$0206 VBREAK
|
|
315 EFD6 CE FE dta a(KeyboardIRQ) ;$0208 VKEYBD
|
|
316 EFD8 43 EA dta a(SIOInputReadyHandler) ;$020A VSERIN
|
|
317 EFDA 8C EA dta a(SIOOutputReadyHandler) ;$020C VSEROR
|
|
318 EFDC C5 EA dta a(SIOOutputCompleteHandler) ;$020E VSEROC
|
|
319 EFDE 54 C0 dta a(IntExitHandler_A) ;$0210 VTIMR1
|
|
320 EFE0 54 C0 dta a(IntExitHandler_A) ;$0212 VTIMR2
|
|
321 EFE2 54 C0 dta a(IntExitHandler_A) ;$0214 VTIMR4
|
|
322 EFE4 D1 C1 dta a(IrqHandler) ;$0216 VIMIRQ
|
|
323 EFE6 end:
|
|
324 .endp
|
|
325
|
|
326 EFE6 .proc InitVectorTable2
|
|
327 EFE6 0C C0 dta a(VBIStage1) ;$0222 VVBLKI
|
|
328 EFE8 50 C0 dta a(VBIExit) ;$0224 VVBLKD
|
|
329 EFEA 00 00 dta a(0) ;$0226 CDTMA1
|
|
330 .endp
|
|
331
|
|
332 EFEC krpdel_table:
|
|
333 EFEC 30 28 dta 48,40
|
|
334
|
|
335 ;==============================================================================
|
|
336 EFEE .proc InitEnvironment
|
|
337 EFEE A5 06 8D E4 02 mva tramsz ramsiz
|
|
338
|
|
339 .if _KERNEL_XLXE
|
|
340 ; set warmstart signature -- must be done before cart init, because
|
|
341 ; SDX doesn't return.
|
|
342 EFF3 A2 03 ldx #3
|
|
343 EFF5 BD A3 EE 9D 3C 03 + mva:rne InitBootSignature-1,x pupbt1-1,x-
|
|
344 .endif
|
|
345
|
|
346 ; 9. set screen margins
|
|
347 EFFE A9 02 85 52 mva #2 lmargn
|
|
348 F002 A9 27 85 53 mva #39 rmargn
|
|
349
|
|
350 ;set PAL/NTSC flag (XL/XE only)
|
|
351 .if _KERNEL_XLXE
|
|
352 F006 A2 00 ldx #0
|
|
353 F008 AD 14 D0 lda pal
|
|
354 F00B A0 06 ldy #6
|
|
355 F00D 29 0E and #$0e
|
|
356 F00F D0 04 bne is_ntsc
|
|
357 F011 D0 01 E8 sne:inx
|
|
358 F014 88 dey
|
|
359 F015 is_ntsc:
|
|
360 F015 86 62 stx palnts
|
|
361 F017 8C DA 02 sty keyrep
|
|
362 F01A BD EC EF 8D D9 02 mva krpdel_table,x krpdel
|
|
363 .endif
|
|
364
|
|
365 ; 10. initialize RAM vectors
|
|
366
|
|
367 ;VDSLST-VIMIRQ
|
|
368 F020 A2 17 ldx #[.len InitVectorTable1]-1
|
|
369 F022 BD CE EF 9D 00 02 + mva:rpl InitVectorTable1,x vdslst,x-
|
|
370
|
|
371 ;VVBLKI-CDTMA1
|
|
372 F02B A2 05 ldx #[.len InitVectorTable2]-1
|
|
373 F02D BD E6 EF 9D 22 02 + mva:rpl InitVectorTable2,x vvblki,x-
|
|
374
|
|
375 F036 A9 11 8D 36 02 A9 + mwa #KeyboardBreakIRQ brkky
|
|
376
|
|
377 ; 11. set misc database values
|
|
378 F040 A2 FF ldx #$ff
|
|
379 F042 86 11 stx brkkey
|
|
380 F044 E8 inx
|
|
381 F045 8E E5 02 stx memtop
|
|
382 F048 8E E7 02 stx memlo
|
|
383 F04B A5 06 8D E6 02 mva tramsz memtop+1
|
|
384 F050 A2 07 8E E8 02 mvx #$07 memlo+1
|
|
385
|
|
386 F055 20 0E EC jsr DiskInit
|
|
387 F058 20 C4 F5 jsr ScreenInit
|
|
388 ;jsr DisplayInit
|
|
389 F05B 20 3F FE jsr KeyboardInit
|
|
390
|
|
391 .if _KERNEL_PRINTER_SUPPORT
|
|
392 F05E 20 7E EC jsr PrinterInit
|
|
393 .endif
|
|
394
|
|
395 ; 13. initialize device table (HATABS has already been cleared)
|
|
396 ; NOTE: The R: emulation relies on this being before CIOINV is invoked.
|
|
397 F061 A2 0E ldx #14
|
|
398 F063 BD A7 EE 9D 1A 03 + mva:rpl InitHandlerTable,x hatabs,x-
|
|
399
|
|
400 ;jsr CassetteInit
|
|
401 F06C 20 6E E4 jsr cioinv
|
|
402 F06F 20 EB E7 jsr SIOInit
|
|
403 F072 20 75 C1 jsr IntInitInterrupts
|
|
404
|
|
405 ; check for START key, and if so, set cassette boot flag
|
|
406 F075 AD 1F D0 lda consol
|
|
407 F078 29 01 and #1
|
|
408 F07A 49 01 eor #1
|
|
409 F07C 8D E9 03 sta ckey
|
|
410
|
|
411 .if _KERNEL_PBI_SUPPORT
|
|
412 F07F 20 4E C2 jsr PBIScan
|
|
413 .endif
|
|
414
|
|
415 ; 12. enable IRQ interrupts
|
|
416 ;
|
|
417 ; We do this later than the original OS specification because the PBI scan needs
|
|
418 ; to happen with IRQs disabled (a PBI device with interrupts may not have been
|
|
419 ; inited yet) and that PBI scan in turn needs to happen after HATABS has been
|
|
420 ; set up. There's no harm in initing HATABS with interrupts masked, so we do so.
|
|
421
|
|
422 F082 58 cli
|
|
423
|
|
424 ; 14. initialize cartridges
|
|
425 F083 A9 00 85 07 mva #0 tstdat
|
|
426
|
|
427 .if !_KERNEL_XLXE
|
|
428 lda $9ffc
|
|
429 bne skipCartBInit
|
|
430 lda $9ffb
|
|
431 tax
|
|
432 eor #$ff
|
|
433 sta $9ffb
|
|
434 cmp $9ffb
|
|
435 stx $9ffb
|
|
436 beq skipCartBInit
|
|
437 jsr InitCartB
|
|
438 mva #1 tstdat
|
|
439 skipCartBInit:
|
|
440 .endif
|
|
441
|
|
442 F087 A9 00 85 06 mva #0 tramsz
|
|
443 F08B AD FC BF lda $bffc
|
|
444 F08E D0 18 bne skipCartAInit
|
|
445 F090 AD FB BF lda $bffb
|
|
446 F093 AA tax
|
|
447 F094 49 FF eor #$ff
|
|
448 F096 8D FB BF sta $bffb
|
|
449 F099 CD FB BF cmp $bffb
|
|
450 F09C 8E FB BF stx $bffb
|
|
451 F09F F0 07 beq skipCartAInit
|
|
452 F0A1 20 2D F1 jsr InitCartA
|
|
453 F0A4 A9 01 85 06 mva #1 tramsz
|
|
454 F0A8 skipCartAInit:
|
|
455
|
|
456 ; 15. use IOCB #0 ($0340) to open screen editor (E)
|
|
457 ;
|
|
458 ; NOTE: We _must_ leave $0C in the A register when invoking CIO. Pooyan
|
|
459 ; relies on $0C being left in CIOCHR after the last call to CIO before
|
|
460 ; disk boot!
|
|
461
|
|
462 F0A8 A9 03 8D 42 03 mva #$03 iccmd ;OPEN
|
|
463 F0AD A9 33 8D 44 03 A9 + mwa #ScreenEditorName icbal
|
|
464 F0B7 A9 0C 8D 4A 03 mva #$0c icax1 ;read/write, no forced read
|
|
465 F0BC A2 00 ldx #0
|
|
466 F0BE 8E 4B 03 stx icax2 ;mode 0
|
|
467 F0C1 20 56 E4 jsr ciov
|
|
468
|
|
469 ; 16. wait for VBLANK so screen is initialized
|
|
470 F0C4 A5 14 lda rtclok+2
|
|
471 F0C6 waitvbl:
|
|
472 F0C6 C5 14 cmp rtclok+2
|
|
473 F0C8 F0 FC beq waitvbl
|
|
474
|
|
475 ;-------------------------------------------------------------------------
|
|
476 ; Pre-boot hook (AltirraOS-specific)
|
|
477 ;
|
|
478
|
|
479 .ifdef _KERNEL_PRE_BOOT_HOOK
|
|
480 jsr InitPreBootHook
|
|
481 .endif
|
|
482
|
|
483 ;-------------------------------------------------------------------------
|
|
484 ; Run cartridge/cassette/disk
|
|
485 ;
|
|
486
|
|
487 ; 17. do cassette boot, if it was requested
|
|
488 ; F. if cassette boot was successful on cold boot, execute cassette init
|
|
489
|
|
490 ; The cold boot path must check the warm start flag and switch paths if
|
|
491 ; necessary. SpartaDOS X relies on being able to set the warm start
|
|
492 ; flag from its cart init handler.
|
|
493 ;
|
|
494 ; Disk boot must be attempted after cassette boot. Besides support for
|
|
495 ; using DOS from tape-based software, this is also required by the tape
|
|
496 ; version of Fun With Spelling (featuring Heathcliff), which depends on
|
|
497 ; the SIO request causing the tape start vector to be invoked shortly
|
|
498 ; after VBI so it can do an unsafe screen swap.
|
|
499 ;
|
|
500
|
|
501 F0CA A5 08 lda warmst
|
|
502 F0CC D0 0B bne reinitcas
|
|
503
|
|
504 F0CE AD E9 03 lda ckey
|
|
505 F0D1 F0 0F beq postcasboot
|
|
506 F0D3 20 A4 F1 jsr BootCassette
|
|
507 F0D6 4C E2 F0 jmp postcasboot
|
|
508
|
|
509 F0D9 reinitcas:
|
|
510 F0D9 A9 02 lda #2
|
|
511 F0DB 24 09 bit boot?
|
|
512 F0DD F0 03 beq postcasboot
|
|
513 F0DF 20 37 F1 jsr InitCassetteBoot
|
|
514 F0E2 postcasboot:
|
|
515
|
|
516 ;-------------------------------------------------------------------------
|
|
517 ; 18. do disk boot
|
|
518 ; G. if disk boot was successful on cold boot, execute disk init
|
|
519 ;
|
|
520 ; For 800 mode, we must check if either cart A or cart B is present,
|
|
521 ; doing a disk boot if either there are no carts or one of the carts
|
|
522 ; requests disk boot. For the XL/XE case, cart B doesn't exist and we
|
|
523 ; can simplify the logic.
|
|
524 ;
|
|
525
|
|
526 F0E2 A5 08 lda warmst
|
|
527 F0E4 D0 10 bne reinitDisk
|
|
528
|
|
529 .if !_KERNEL_XLXE
|
|
530
|
|
531 ;check if we have cart B
|
|
532 lda tstdat
|
|
533 bne have_cart_b
|
|
534
|
|
535 ;no cart B -- if no cart A either, do disk boot
|
|
536 ldx tramsz ;cart A
|
|
537 beq boot_disk
|
|
538 bne have_cart_a
|
|
539
|
|
540 have_cart_b:
|
|
541 ;have cart B - grab boot disk flag (bit 0)
|
|
542 lda $9ffd
|
|
543
|
|
544 ;merge cart A's flags if it is present
|
|
545 ldx tramsz
|
|
546 beq no_cart_a
|
|
547
|
|
548 have_cart_a:
|
|
549 ora $bffd
|
|
550
|
|
551 no_cart_a:
|
|
552 ;skip disk boot if neither cart requested it
|
|
553 lsr
|
|
554 bcc skip_disk_boot
|
|
555
|
|
556 .else
|
|
557
|
|
558 ;check for cart A requesting boot
|
|
559 F0E6 A5 06 lda tramsz
|
|
560 F0E8 F0 06 beq boot_disk
|
|
561
|
|
562 ;have cart A - boot disk if requested
|
|
563 F0EA AD FD BF lda $bffd
|
|
564 F0ED 4A lsr
|
|
565 F0EE 90 1B bcc skip_disk_boot
|
|
566
|
|
567 .endif
|
|
568
|
|
569 F0F0 boot_disk:
|
|
570 F0F0 20 3B F1 jsr BootDisk
|
|
571 F0F3 4C FE F0 jmp post_disk_boot
|
|
572
|
|
573 F0F6 reinitDisk:
|
|
574 F0F6 A5 09 lda boot?
|
|
575 F0F8 4A lsr
|
|
576 F0F9 90 10 bcc skip_disk_boot
|
|
577 F0FB 20 34 F1 jsr InitDiskBoot
|
|
578
|
|
579 F0FE post_disk_boot:
|
|
580 .if _KERNEL_XLXE
|
|
581 ; (XL/XE only) do type 3 poll or reinit handlers
|
|
582 ; !! - must only do this if a disk boot occurs; Pole Position audio breaks if
|
|
583 ; we do this and hit SKCTL before booting the cart
|
|
584 F0FE A5 08 lda warmst
|
|
585 F100 D0 06 bne reinit_handlers
|
|
586 F102 20 6A C4 jsr PHStartupPoll
|
|
587 F105 4C 0B F1 jmp post_reinit
|
|
588 F108 reinit_handlers:
|
|
589 F108 20 2E C4 jsr PHReinitHandlers
|
|
590 F10B post_reinit:
|
|
591 .endif
|
|
592
|
|
593 F10B skip_disk_boot:
|
|
594
|
|
595 ;-------------------------------------------------------------------------
|
|
596 ; H. same as steps 19 and 20
|
|
597 ; 19. reset coldstart flag
|
|
598
|
|
599 F10B A2 00 ldx #0
|
|
600 F10D 8E 44 02 stx coldst
|
|
601
|
|
602 ;-------------------------------------------------------------------------
|
|
603 ; 20. run cartridges or blackboard
|
|
604 ;
|
|
605 ; Weird quirk here: if the left cart is absent or doesn't request
|
|
606 ; cart start, and the right cart is present and also doesn't request
|
|
607 ; cart start, OS-B endlessly does disk boots instead of running (DOSVEC).
|
|
608 ; We don't emulate this behavior for now since in practice it just seems
|
|
609 ; useless, boot looping until DOS crashes. It is moot starting with the
|
|
610 ; 1200XL DOS due to support for cart B being dropped.
|
|
611 ;
|
|
612
|
|
613 ; try to boot cart A
|
|
614 F110 A9 04 lda #$04
|
|
615 F112 A6 06 ldx tramsz
|
|
616 F114 F0 08 beq NoBootCartA
|
|
617 F116 2C FD BF bit $bffd
|
|
618 F119 F0 03 6C FA BF seq:jmp ($bffa)
|
|
619 F11E NoBootCartA:
|
|
620
|
|
621 ; try to boot cart B
|
|
622 F11E A6 07 ldx tstdat
|
|
623 F120 F0 08 beq NoBootCartB
|
|
624 F122 2C FD 9F bit $9ffd
|
|
625 F125 F0 03 6C FA 9F seq:jmp ($9ffa)
|
|
626 F12A NoBootCartB:
|
|
627
|
|
628 ; run blackboard
|
|
629 F12A 6C 0A 00 jmp (dosvec)
|
|
630
|
|
631 F12D InitCartA:
|
|
632 F12D 6C FE BF jmp ($bffe)
|
|
633
|
|
634 F130 InitCartB:
|
|
635 F130 6C FE 9F jmp ($9ffe)
|
|
636
|
|
637 F133 ScreenEditorName:
|
|
638 F133 45 dta c"E"
|
|
639
|
|
640 .endp
|
|
641
|
|
642 ;==============================================================================
|
|
643 F134 .proc InitDiskBoot
|
|
644 F134 6C 0C 00 jmp (dosini)
|
|
645 .endp
|
|
646
|
|
647 F137 .proc InitCassetteBoot
|
|
648 .endp
|
|
649 F137 6C 02 00 jmp (casini)
|
|
650
|
|
651 ;==============================================================================
|
|
652
|
|
653 F13A EA nop
|
|
264 .endif
|
|
265
|
|
266 F13B icl 'boot.s'
|
|
Source: source/Shared/boot.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Boot Code
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11 ; Disk boot routine.
|
|
12 ;
|
|
13 ; Exit:
|
|
14 ; DBUFLO/DBUFHI = $0400 (Undoc; required by Ankh and the 1.atr SMB demo)
|
|
15 ; Last sector in $0400 (Undoc; required by Ankh)
|
|
16 ;
|
|
17 F13B .proc BootDisk
|
|
18 ;issue a status request first to see if the disk is active; if this
|
|
19 ;doesn't come back, don't bother trying to read
|
|
20 F13B A9 53 lda #$53
|
|
21 F13D 8D 02 03 sta dcomnd
|
|
22 F140 A2 01 ldx #1
|
|
23 F142 8E 01 03 stx dunit
|
|
24 F145 20 53 E4 jsr dskinv
|
|
25 F148 30 3C bmi xit
|
|
26
|
|
27 ;read first sector to $0400
|
|
28 F14A A2 01 ldx #1
|
|
29 F14C 8E 01 03 stx dunit
|
|
30 F14F 8E 0A 03 stx daux1
|
|
31 F152 CA dex
|
|
32 F153 8E 04 03 stx dbuflo
|
|
33 F156 8E 0B 03 stx daux2
|
|
34 F159 A9 52 8D 02 03 mva #$52 dcomnd
|
|
35 F15E A9 04 8D 05 03 mva #$04 dbufhi
|
|
36 F163 20 53 E4 jsr dskinv
|
|
37 F166 30 1A bmi fail
|
|
38
|
|
39 F168 sector1_ok:
|
|
40 F168 A2 0C ldx #dosini
|
|
41 F16A 20 DF F1 jsr BootInitHeaders
|
|
42
|
|
43 ;load remaining sectors
|
|
44 F16D sectorloop:
|
|
45 ;copy sector from $0400 to destination (required by Ankh; see above)
|
|
46 ;bump destination address for next sector copy
|
|
47 F16D 20 0C F2 jsr BootCopyBlock
|
|
48
|
|
49 ;exit if this was the last sector (note that 0 means to load 256 sectors!)
|
|
50 F170 CE 41 02 dec dbsect
|
|
51 F173 F0 22 beq loaddone
|
|
52
|
|
53 ;increment sector (yes, this can overflow to 256)
|
|
54 F175 EE 0A 03 D0 03 EE + inw daux1
|
|
55
|
|
56 ;read next sector
|
|
57 F17D 20 53 E4 jsr dskinv
|
|
58
|
|
59 ;keep going if we succeeded
|
|
60 F180 10 EB bpl sectorloop
|
|
61
|
|
62 ;read failed
|
|
63 F182 fail:
|
|
64 F182 C0 8A cpy #SIOErrorTimeout
|
|
65 F184 D0 01 bne failmsg
|
|
66 F186 xit:
|
|
67 F186 60 rts
|
|
68
|
|
69 F187 failmsg:
|
|
70 .if _KERNEL_USE_BOOT_SCREEN
|
|
71 F187 st_loop:
|
|
72 F187 AD 01 D3 lda portb
|
|
73 F18A 49 80 eor #$80
|
|
74 F18C 8D 01 D3 sta portb
|
|
75 F18F 30 D7 bmi sector1_ok
|
|
76 F191 20 02 50 jsr BootScreen.boot_entry
|
|
77 F194 4C 87 F1 jmp st_loop
|
|
78 .else
|
|
79 jsr BootShowError
|
|
80 jmp BootDisk
|
|
81 .endif
|
|
82
|
|
83 F197 loaddone:
|
|
84 F197 20 FC F1 jsr BootRunLoader
|
|
85 F19A B0 EB bcs failmsg
|
|
86
|
|
87 ;Diskette Boot Process, step 7 (p.161 of the OS Manual) is misleading. It
|
|
88 ;says that DOSVEC is invoked after DOSINI, but actually that should NOT
|
|
89 ;happen here -- it happens AFTER cartridges have had a chance to run.
|
|
90 ;This is necessary for BASIC to gain control before DOS goes to load
|
|
91 ;DUP.SYS.
|
|
92 F19C 20 34 F1 jsr InitDiskBoot
|
|
93
|
|
94 ;Must not occur until after init routine is called -- SpartaDOS 3.2 does
|
|
95 ;an INC on this flag and never exits.
|
|
96 F19F A9 01 85 09 mva #1 boot?
|
|
97 F1A3 60 rts
|
|
98 .endp
|
|
99
|
|
100
|
|
101 ;============================================================================
|
|
102
|
|
103 F1A4 .proc BootCassette
|
|
104 ;set continuous mode -- must do this as CSOPIV doesn't
|
|
105 F1A4 A9 80 lda #$80
|
|
106 F1A6 85 3E sta ftype
|
|
107
|
|
108 ;open cassette device
|
|
109 F1A8 20 7D E4 jsr csopiv
|
|
110
|
|
111 ;read first block
|
|
112 F1AB 20 7A E4 jsr rblokv
|
|
113 F1AE 30 24 bmi load_failure
|
|
114
|
|
115 F1B0 A2 02 ldx #casini
|
|
116 F1B2 20 DF F1 jsr BootInitHeaders
|
|
117
|
|
118 F1B5 block_loop:
|
|
119 ;copy 128 bytes from CASBUF+3 ($0400) to destination
|
|
120 ;update destination pointer
|
|
121 F1B5 20 0C F2 jsr BootCopyBlock
|
|
122
|
|
123 ;read next block
|
|
124 ;we always need to do one more to catch the EOF block, which is
|
|
125 ;required by STDBLOAD2
|
|
126 F1B8 20 7A E4 jsr rblokv
|
|
127 F1BB 30 17 bmi load_failure
|
|
128
|
|
129 F1BD CE 41 02 dec dbsect
|
|
130 F1C0 D0 F3 bne block_loop
|
|
131
|
|
132 ;run loader
|
|
133 F1C2 20 FC F1 jsr BootRunLoader
|
|
134
|
|
135 ;run cassette init routine
|
|
136 F1C5 20 37 F1 jsr InitCassetteBoot
|
|
137
|
|
138 ;clear cassette boot key flag
|
|
139 F1C8 A9 00 lda #0
|
|
140 F1CA 8D E9 03 sta ckey
|
|
141
|
|
142 ;set cassette boot flag
|
|
143 F1CD A9 02 85 09 mva #2 boot?
|
|
144
|
|
145 ;run application
|
|
146 F1D1 6C 0A 00 jmp (dosvec)
|
|
147
|
|
148 F1D4 load_failure:
|
|
149 F1D4 A9 00 lda #0
|
|
150 F1D6 8D E9 03 sta ckey
|
|
151 F1D9 20 6F ED jsr CassetteClose
|
|
152 F1DC 4C 21 F2 jmp BootShowError
|
|
153 .endp
|
|
154
|
|
155 ;============================================================================
|
|
156 F1DF .proc BootInitHeaders
|
|
157 ;copy the first four bytes to DFLAGS, DBSECT, and BOOTAD
|
|
158 F1DF A0 FC ldy #$fc
|
|
159 F1E1 B9 04 03 99 44 01 + mva:rne $0400-$fc,y dflags-$fc,y+
|
|
160
|
|
161 ;copy boot address in BOOTAD to BUFADR
|
|
162 F1EA 85 16 sta bufadr+1
|
|
163 F1EC AD 42 02 lda bootad
|
|
164 F1EF 85 15 sta bufadr
|
|
165
|
|
166 ;copy init vector
|
|
167 F1F1 AD 04 04 95 00 AD + mwa $0404 0,x
|
|
168 F1FB 60 rts
|
|
169 .endp
|
|
170
|
|
171 ;============================================================================
|
|
172 F1FC .proc BootRunLoader
|
|
173 ;loader is at load address + 6
|
|
174 F1FC AD 42 02 lda bootad
|
|
175 F1FF 18 69 05 add #$05
|
|
176 F202 AA tax
|
|
177 F203 AD 43 02 lda bootad+1
|
|
178 F206 69 00 adc #0
|
|
179 F208 48 pha
|
|
180 F209 8A txa
|
|
181 F20A 48 pha
|
|
182 F20B 60 rts
|
|
183 .endp
|
|
184
|
|
185 ;============================================================================
|
|
186 F20C .proc BootCopyBlock
|
|
187 F20C A0 7F ldy #$7f
|
|
188 F20E B9 00 04 91 15 88 + mva:rpl $0400,y (bufadr),y-
|
|
189
|
|
190 F216 A5 15 lda bufadr
|
|
191 F218 49 80 eor #$80
|
|
192 F21A 85 15 sta bufadr
|
|
193 F21C 30 02 E6 16 smi:inc bufadr+1
|
|
194 F220 60 rts
|
|
195 .endp
|
|
196
|
|
197 ;============================================================================
|
|
198
|
|
199 F221 .proc BootShowError
|
|
200 F221 A2 F5 ldx #$f5
|
|
201 F223 msgloop:
|
|
202 F223 8A txa
|
|
203 F224 48 pha
|
|
204 F225 BD 3C F1 lda errormsg-$f5,x
|
|
205 F228 20 B8 FA jsr EditorPutByte
|
|
206 F22B 68 pla
|
|
207 F22C AA tax
|
|
208 F22D E8 inx
|
|
209 F22E D0 F3 bne msgloop
|
|
210 F230 60 rts
|
|
211
|
|
212 F231 errormsg:
|
|
213 F231 42 4F 4F 54 20 45 + dta 'BOOT ERROR',$9B
|
|
214 .endp
|
|
267 F23C _KERNEL_REPORT_MODULE_SIZE 'Monitor routines', $F3E4-$F0E3
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', $F3E4-$F0E3, ')', ' ', 'Monitor routines'
|
|
1 $F23C -> $0398($0301) Monitor routines
|
|
3 = F23C .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
268
|
|
269 F23C icl 'screen.s'
|
|
Source: source/Shared/screen.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Screen Handler
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;Display list:
|
|
11 ; 24 blank lines (3 bytes)
|
|
12 ; initial mode line with LMS (3 bytes)
|
|
13 ; mode lines
|
|
14 ; LMS for modes >4 pages
|
|
15 ; wait VBL (3 bytes)
|
|
16 ;
|
|
17 ; total is 8-10 bytes + mode lines
|
|
18
|
|
19 ; These are the addresses produced by the normal XL/XE OS:
|
|
20 ;
|
|
21 ; Normal Split, coarse Split, fine
|
|
22 ; Mode DL PF TX DL PF TX DL PF TX
|
|
23 ; 0 9C20 9C40 9F60 9C20 9C40 9F60 9C1F 9C40 9F60
|
|
24 ; 1 9D60 9D80 9F60 9D5E 9D80 9F60 9D5D 9D80 9F60
|
|
25 ; 2 9E5C 9E70 9F60 9E58 9E70 9F60 9E57 9E70 9F60
|
|
26 ; 3 9E50 9E70 9F60 9E4E 9E70 9F60 9E4D 9E70 9F60
|
|
27 ; 4 9D48 9D80 9F60 9D4A 9D80 9F60 9D49 9D80 9F60
|
|
28 ; 5 9B68 9BA0 9F60 9B6A 9BA0 9F60 9B69 9BA0 9F60
|
|
29 ; 6 9778 97E0 9F60 9782 97E0 9F60 9781 97E0 9F60
|
|
30 ; 7 8F98 9060 9F60 8FA2 9060 9F60 8FA1 9060 9F60
|
|
31 ; 8 8036 8150 9F60 8050 8150 9F60 804F 8150 9F60
|
|
32 ; 9 8036 8150 9F60 8036 8150 9F60 8036 8150 9F60
|
|
33 ; 10 8036 8150 9F60 8036 8150 9F60 8036 8150 9F60
|
|
34 ; 11 8036 8150 9F60 8036 8150 9F60 8036 8150 9F60
|
|
35 ; 12 9B80 9BA0 9F60 9B7E 9BA0 9F60 9B7D 9BA0 9F60
|
|
36 ; 13 9D6C 9D80 9F60 9D68 9D80 9F60 9D67 9D80 9F60
|
|
37 ; 14 8F38 9060 9F60 8F52 9060 9F60 8F51 9060 9F60
|
|
38 ; 15 8036 8150 9F60 8050 8150 9F60 804F 8150 9F60
|
|
39 ;
|
|
40 ; *DL = display list (SDLSTL/SDLSTH)
|
|
41 ; *PF = playfield (SAVMSC)
|
|
42 ; *TX = text window (TXTMSC)
|
|
43 ;
|
|
44 ; From this, we can derive a few things:
|
|
45 ; - The text window is always 160 ($A0) bytes below the ceiling.
|
|
46 ; - The playfield is always positioned to have enough room for
|
|
47 ; the text window, even though this wastes a little bit of
|
|
48 ; memory for modes 1, 2, 3, 4, and 13. This means that the
|
|
49 ; PF address does not have to be adjusted for split mode.
|
|
50 ; - The display list and playfield addresses are sometimes
|
|
51 ; adjusted in order to avoid crossing 1K boundaries for the
|
|
52 ; display list (gr.7) and 4K boundaries for the playfield (gr.8).
|
|
53 ; However, these are fixed offsets -- adjusting RAMTOP to $9F
|
|
54 ; does not remove the DL padding in GR.7 and breaks GR.7/8.
|
|
55 ; - Fine-scrolled modes take one additional byte for the extra
|
|
56 ; mode 2 line. In fact, it displays garbage that is masked by
|
|
57 ; a DLI that sets COLPF1 equal to COLPF2. (!)
|
|
58 ;
|
|
59 ; You might ask, why bother replicating these? Well, there are a
|
|
60 ; number of programs that rely on the layout of the default screen
|
|
61 ; and break if the memory addressing is different, such as ForemXEP.
|
|
62
|
|
63 .macro _SCREEN_TABLES_2
|
|
64
|
|
65 ;Mode Type Res Colors ANTIC Mem(unsplit) Mem(split)
|
|
66 ; 0 Text 40x24 1.5 2 960+32 (4) 960+32 (4)
|
|
67 ; 1 Text 20x24 5 6 480+32 (2) 560+32 (3)
|
|
68 ; 2 Text 20x12 5 7 240+20 (2) 360+22 (2)
|
|
69 ; 3 Bitmap 40x24 4 8 240+32 (2) 360+32 (2)
|
|
70 ; 4 Bitmap 80x48 2 9 480+56 (3) 560+52 (3)
|
|
71 ; 5 Bitmap 80x48 4 A 960+56 (4) 960+52 (4)
|
|
72 ; 6 Bitmap 160x96 2 B 1920+104 (8) 1760+92 (8)
|
|
73 ; 7 Bitmap 160x96 4 D 3840+104 (16) 3360+92 (14)
|
|
74 ; 8 Bitmap 320x192 1.5 F 7680+202 (32) 6560+174 (27)
|
|
75 ; 9 Bitmap 80x192 16 F 7680+202 (32) 6560+174 (27)
|
|
76 ; 10 Bitmap 80x192 9 F 7680+202 (32) 6560+174 (27)
|
|
77 ; 11 Bitmap 80x192 16 F 7680+202 (32) 6560+174 (27)
|
|
78 ; 12 Text 40x24 5 4 960+32 (4) 960+32 (4)
|
|
79 ; 13 Text 40x12 5 5 480+20 (2) 560+24 (3)
|
|
80 ; 14 Bitmap 160x192 2 C 3840+200 (16) 3360+172 (14)
|
|
81 ; 15 Bitmap 160x192 4 E 7680+202 (32) 6560+172 (27)
|
|
82
|
|
83 ;==========================================================================
|
|
84 ;
|
|
85 .proc ScreenPlayfieldSizesLo
|
|
86 dta <($10000-$03C0) ;gr.0 960 bytes = 40*24 = 40*24
|
|
87 dta <($10000-$0280) ;gr.1 640 bytes = 20*24 + 40*4 = 40*12 + 40*4
|
|
88 dta <($10000-$0190) ;gr.2 400 bytes = 10*24 + 40*4 = 40*6 + 40*4
|
|
89 dta <($10000-$0190) ;gr.3 400 bytes = 10*24 + 40*4 = 40*6 + 40*4
|
|
90 dta <($10000-$0280) ;gr.4 640 bytes = 10*48 + 40*4 = 40*12 + 40*4
|
|
91 dta <($10000-$0460) ;gr.5 1120 bytes = 20*48 + 40*4 = 40*24 + 40*4
|
|
92 dta <($10000-$0820) ;gr.6 2080 bytes = 20*96 + 40*4 = 40*48 + 40*4
|
|
93 dta <($10000-$0FA0) ;gr.7 4000 bytes = 40*96 + 40*4 = 40*96 + 40*4
|
|
94 dta <($10000-$1EB0) ;gr.8 7856 bytes = 40*192 + 40*4 + 16 = 40*192 + 40*4 + 16
|
|
95 dta <($10000-$1EB0) ;gr.9 7856 bytes = 40*192 + 40*4 + 16 = 40*192 + 40*4 + 16
|
|
96 dta <($10000-$1EB0) ;gr.10 7856 bytes = 40*192 + 40*4 + 16 = 40*192 + 40*4 + 16
|
|
97 dta <($10000-$1EB0) ;gr.11 7856 bytes = 40*192 + 40*4 + 16 = 40*192 + 40*4 + 16
|
|
98 dta <($10000-$0460) ;gr.12 1120 bytes = 40*24 + 40*4 = 40*24 + 40*4
|
|
99 dta <($10000-$0280) ;gr.13 640 bytes = 40*12 + 40*4 = 40*12 + 40*4
|
|
100 dta <($10000-$0FA0) ;gr.14 4000 bytes = 20*192 + 40*4 = 40*96 + 40*4
|
|
101 dta <($10000-$1EB0) ;gr.15 7856 bytes = 40*192 + 40*4 + 16 = 40*192 + 40*4 + 16
|
|
102 .endp
|
|
103
|
|
104 .proc ScreenPlayfieldSizesHi
|
|
105 dta >($10000-$03C0) ;gr.0
|
|
106 dta >($10000-$0280) ;gr.1
|
|
107 dta >($10000-$0190) ;gr.2
|
|
108 dta >($10000-$0190) ;gr.3
|
|
109 dta >($10000-$0280) ;gr.4
|
|
110 dta >($10000-$0460) ;gr.5
|
|
111 dta >($10000-$0820) ;gr.6
|
|
112 dta >($10000-$0FA0) ;gr.7
|
|
113 dta >($10000-$1EB0) ;gr.8
|
|
114 dta >($10000-$1EB0) ;gr.9
|
|
115 dta >($10000-$1EB0) ;gr.10
|
|
116 dta >($10000-$1EB0) ;gr.11
|
|
117 dta >($10000-$0460) ;gr.12
|
|
118 dta >($10000-$0280) ;gr.13
|
|
119 dta >($10000-$0FA0) ;gr.14
|
|
120 dta >($10000-$1EB0) ;gr.15
|
|
121 .endp
|
|
122
|
|
123 ;==========================================================================
|
|
124 ; ANTIC mode is in bits 0-3, PRIOR bits in 6-7.
|
|
125 ; DL 1K hop: bit 4
|
|
126 ; playfield 4K hop: bit 5
|
|
127 ;
|
|
128 .proc ScreenModeTable
|
|
129 dta $02,$06,$07,$08,$09,$0A,$0B,$1D,$3F,$7F,$BF,$FF,$04,$05,$1C,$3E
|
|
130 .endp
|
|
131
|
|
132 ;==========================================================================
|
|
133 ;
|
|
134 .proc ScreenHeightShifts
|
|
135 dta 1
|
|
136 dta 1
|
|
137 dta 0
|
|
138 dta 1
|
|
139 dta 2
|
|
140 dta 2
|
|
141 dta 3
|
|
142 dta 3
|
|
143 dta 4
|
|
144 dta 4
|
|
145 dta 4
|
|
146 dta 4
|
|
147 dta 1
|
|
148 dta 0
|
|
149 dta 4
|
|
150 dta 4
|
|
151 .endp
|
|
152
|
|
153 .proc ScreenHeights
|
|
154 dta 12, 24, 48, 96, 192
|
|
155 .endp
|
|
156
|
|
157 .proc ScreenPixelWidthIds
|
|
158 dta 1 ;gr.0 40 pixels
|
|
159 dta 0 ;gr.1 20 pixels
|
|
160 dta 0 ;gr.2 20 pixels
|
|
161 dta 1 ;gr.3 40 pixels
|
|
162 dta 2 ;gr.4 80 pixels
|
|
163 dta 2 ;gr.5 80 pixels
|
|
164 dta 3 ;gr.6 160 pixels
|
|
165 dta 3 ;gr.7 160 pixels
|
|
166 dta 4 ;gr.8 320 pixels
|
|
167 dta 2 ;gr.9 80 pixels
|
|
168 dta 2 ;gr.10 80 pixels
|
|
169 dta 2 ;gr.11 80 pixels
|
|
170 dta 1 ;gr.12 40 pixels
|
|
171 dta 1 ;gr.13 40 pixels
|
|
172 dta 3 ;gr.14 160 pixels
|
|
173 dta 3 ;gr.15 160 pixels
|
|
174 .endp
|
|
175 .endm
|
|
176
|
|
177 = F2A7 ScreenHeightsSplit = ScreenWidths
|
|
178 ; dta 10, 20, 40, 80, 160
|
|
179
|
|
180 = F2A8 ScreenPixelWidthsLo = ScreenWidths + 1
|
|
181
|
|
182 .macro _SCREEN_TABLES_1
|
|
183
|
|
184 .proc ScreenWidths
|
|
185 dta <10
|
|
186 dta <20
|
|
187 dta <40
|
|
188 dta <80
|
|
189 dta <160
|
|
190 dta <320
|
|
191 .endp
|
|
192
|
|
193 .proc ScreenPixelWidthsHi
|
|
194 dta >20
|
|
195 dta >40
|
|
196 dta >80
|
|
197 dta >160
|
|
198 dta >320
|
|
199 .endp
|
|
200
|
|
201 .proc ScreenEncodingTab
|
|
202 dta 0 ;gr.0 direct bytes
|
|
203 dta 0 ;gr.1 direct bytes
|
|
204 dta 0 ;gr.2 direct bytes
|
|
205 dta 2 ;gr.3 two bits per pixel
|
|
206 dta 3 ;gr.4 one bit per pixel
|
|
207 dta 2 ;gr.5 two bits per pixel
|
|
208 dta 3 ;gr.6 one bit per pixel
|
|
209 dta 2 ;gr.7 two bits per pixel
|
|
210 dta 3 ;gr.8 one bit per pixel
|
|
211 dta 1 ;gr.9 four bits per pixel
|
|
212 dta 1 ;gr.10 four bits per pixel
|
|
213 dta 1 ;gr.11 four bits per pixel
|
|
214 dta 0 ;gr.12 direct bytes
|
|
215 dta 0 ;gr.13 direct bytes
|
|
216 dta 3 ;gr.14 one bit per pixel
|
|
217 dta 2 ;gr.15 two bits per pixel
|
|
218 .endp
|
|
219
|
|
220 .proc ScreenPixelMasks
|
|
221 dta $ff, $0f, $03, $01, $ff, $f0, $c0, $80
|
|
222 .endp
|
|
223 .endm
|
|
224
|
|
225 .macro _SCREEN_TABLES_3
|
|
226 .proc ScreenEncodingTable
|
|
227 dta $00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff
|
|
228 dta $00,$55,$aa,$ff
|
|
229 dta $00,$ff
|
|
230 .endp
|
|
231 .endm
|
|
232
|
|
233 .if _KERNEL_XLXE
|
|
234 F23C _SCREEN_TABLES_3
|
|
Macro: _SCREEN_TABLES_3 [Source: source/Shared/screen.s]
|
|
2 F23C 00 11 22 33 44 55 + dta $00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff
|
|
3 F24C 00 55 AA FF dta $00,$55,$aa,$ff
|
|
4 F250 00 FF dta $00,$ff
|
|
Source: source/Shared/screen.s
|
|
235 F252 _SCREEN_TABLES_2
|
|
Macro: _SCREEN_TABLES_2 [Source: source/Shared/screen.s]
|
|
23 F252 40 dta <($10000-$03C0) ;gr.0 960 bytes = 40*24 = 40*24
|
|
24 F253 80 dta <($10000-$0280) ;gr.1 640 bytes = 20*24 + 40*4 = 40*12 + 40*4
|
|
25 F254 70 dta <($10000-$0190) ;gr.2 400 bytes = 10*24 + 40*4 = 40*6 + 40*4
|
|
26 F255 70 dta <($10000-$0190) ;gr.3 400 bytes = 10*24 + 40*4 = 40*6 + 40*4
|
|
27 F256 80 dta <($10000-$0280) ;gr.4 640 bytes = 10*48 + 40*4 = 40*12 + 40*4
|
|
28 F257 A0 dta <($10000-$0460) ;gr.5 1120 bytes = 20*48 + 40*4 = 40*24 + 40*4
|
|
29 F258 E0 dta <($10000-$0820) ;gr.6 2080 bytes = 20*96 + 40*4 = 40*48 + 40*4
|
|
30 F259 60 dta <($10000-$0FA0) ;gr.7 4000 bytes = 40*96 + 40*4 = 40*96 + 40*4
|
|
31 F25A 50 dta <($10000-$1EB0) ;gr.8 7856 bytes = 40*192 + 40*4 + 16 = 40*192 + 40*4 + 16
|
|
32 F25B 50 dta <($10000-$1EB0) ;gr.9 7856 bytes = 40*192 + 40*4 + 16 = 40*192 + 40*4 + 16
|
|
33 F25C 50 dta <($10000-$1EB0) ;gr.10 7856 bytes = 40*192 + 40*4 + 16 = 40*192 + 40*4 + 16
|
|
34 F25D 50 dta <($10000-$1EB0) ;gr.11 7856 bytes = 40*192 + 40*4 + 16 = 40*192 + 40*4 + 16
|
|
35 F25E A0 dta <($10000-$0460) ;gr.12 1120 bytes = 40*24 + 40*4 = 40*24 + 40*4
|
|
36 F25F 80 dta <($10000-$0280) ;gr.13 640 bytes = 40*12 + 40*4 = 40*12 + 40*4
|
|
37 F260 60 dta <($10000-$0FA0) ;gr.14 4000 bytes = 20*192 + 40*4 = 40*96 + 40*4
|
|
38 F261 50 dta <($10000-$1EB0) ;gr.15 7856 bytes = 40*192 + 40*4 + 16 = 40*192 + 40*4 + 16
|
|
42 F262 FC dta >($10000-$03C0) ;gr.0
|
|
43 F263 FD dta >($10000-$0280) ;gr.1
|
|
44 F264 FE dta >($10000-$0190) ;gr.2
|
|
45 F265 FE dta >($10000-$0190) ;gr.3
|
|
46 F266 FD dta >($10000-$0280) ;gr.4
|
|
47 F267 FB dta >($10000-$0460) ;gr.5
|
|
48 F268 F7 dta >($10000-$0820) ;gr.6
|
|
49 F269 F0 dta >($10000-$0FA0) ;gr.7
|
|
50 F26A E1 dta >($10000-$1EB0) ;gr.8
|
|
51 F26B E1 dta >($10000-$1EB0) ;gr.9
|
|
52 F26C E1 dta >($10000-$1EB0) ;gr.10
|
|
53 F26D E1 dta >($10000-$1EB0) ;gr.11
|
|
54 F26E FB dta >($10000-$0460) ;gr.12
|
|
55 F26F FD dta >($10000-$0280) ;gr.13
|
|
56 F270 F0 dta >($10000-$0FA0) ;gr.14
|
|
57 F271 E1 dta >($10000-$1EB0) ;gr.15
|
|
66 F272 02 06 07 08 09 0A + dta $02,$06,$07,$08,$09,$0A,$0B,$1D,$3F,$7F,$BF,$FF,$04,$05,$1C,$3E
|
|
72 F282 01 dta 1
|
|
73 F283 01 dta 1
|
|
74 F284 00 dta 0
|
|
75 F285 01 dta 1
|
|
76 F286 02 dta 2
|
|
77 F287 02 dta 2
|
|
78 F288 03 dta 3
|
|
79 F289 03 dta 3
|
|
80 F28A 04 dta 4
|
|
81 F28B 04 dta 4
|
|
82 F28C 04 dta 4
|
|
83 F28D 04 dta 4
|
|
84 F28E 01 dta 1
|
|
85 F28F 00 dta 0
|
|
86 F290 04 dta 4
|
|
87 F291 04 dta 4
|
|
91 F292 0C 18 30 60 C0 dta 12, 24, 48, 96, 192
|
|
95 F297 01 dta 1 ;gr.0 40 pixels
|
|
96 F298 00 dta 0 ;gr.1 20 pixels
|
|
97 F299 00 dta 0 ;gr.2 20 pixels
|
|
98 F29A 01 dta 1 ;gr.3 40 pixels
|
|
99 F29B 02 dta 2 ;gr.4 80 pixels
|
|
100 F29C 02 dta 2 ;gr.5 80 pixels
|
|
101 F29D 03 dta 3 ;gr.6 160 pixels
|
|
102 F29E 03 dta 3 ;gr.7 160 pixels
|
|
103 F29F 04 dta 4 ;gr.8 320 pixels
|
|
104 F2A0 02 dta 2 ;gr.9 80 pixels
|
|
105 F2A1 02 dta 2 ;gr.10 80 pixels
|
|
106 F2A2 02 dta 2 ;gr.11 80 pixels
|
|
107 F2A3 01 dta 1 ;gr.12 40 pixels
|
|
108 F2A4 01 dta 1 ;gr.13 40 pixels
|
|
109 F2A5 03 dta 3 ;gr.14 160 pixels
|
|
110 F2A6 03 dta 3 ;gr.15 160 pixels
|
|
Source: source/Shared/screen.s
|
|
236 F2A7 _SCREEN_TABLES_1
|
|
Macro: _SCREEN_TABLES_1 [Source: source/Shared/screen.s]
|
|
3 F2A7 0A dta <10
|
|
4 F2A8 14 dta <20
|
|
5 F2A9 28 dta <40
|
|
6 F2AA 50 dta <80
|
|
7 F2AB A0 dta <160
|
|
8 F2AC 40 dta <320
|
|
12 F2AD 00 dta >20
|
|
13 F2AE 00 dta >40
|
|
14 F2AF 00 dta >80
|
|
15 F2B0 00 dta >160
|
|
16 F2B1 01 dta >320
|
|
20 F2B2 00 dta 0 ;gr.0 direct bytes
|
|
21 F2B3 00 dta 0 ;gr.1 direct bytes
|
|
22 F2B4 00 dta 0 ;gr.2 direct bytes
|
|
23 F2B5 02 dta 2 ;gr.3 two bits per pixel
|
|
24 F2B6 03 dta 3 ;gr.4 one bit per pixel
|
|
25 F2B7 02 dta 2 ;gr.5 two bits per pixel
|
|
26 F2B8 03 dta 3 ;gr.6 one bit per pixel
|
|
27 F2B9 02 dta 2 ;gr.7 two bits per pixel
|
|
28 F2BA 03 dta 3 ;gr.8 one bit per pixel
|
|
29 F2BB 01 dta 1 ;gr.9 four bits per pixel
|
|
30 F2BC 01 dta 1 ;gr.10 four bits per pixel
|
|
31 F2BD 01 dta 1 ;gr.11 four bits per pixel
|
|
32 F2BE 00 dta 0 ;gr.12 direct bytes
|
|
33 F2BF 00 dta 0 ;gr.13 direct bytes
|
|
34 F2C0 03 dta 3 ;gr.14 one bit per pixel
|
|
35 F2C1 02 dta 2 ;gr.15 two bits per pixel
|
|
39 F2C2 FF 0F 03 01 FF F0 + dta $ff, $0f, $03, $01, $ff, $f0, $c0, $80
|
|
Source: source/Shared/screen.s
|
|
237 .endif
|
|
238
|
|
239 ;==========================================================================
|
|
240 ;==========================================================================
|
|
241
|
|
242 ;Many compilation disks rely on ScreenOpen being at $F3F6.
|
|
243
|
|
244 .if *>$f3f6-8
|
|
245 .error 'ROM overflow into Screen Handler region: ',*,' > $F3EE.'
|
|
246 .endif
|
|
247
|
|
248 .ifdef _KERNEL_REPORT_MODULE_PAD_ADJUST
|
|
249 F2CA _KERNEL_REPORT_MODULE_PAD_ADJUST [$f3f6-8]-*
|
|
Macro: _KERNEL_REPORT_MODULE_PAD_ADJUST [Source: source/main.xasm]
|
|
1 = F360 .def ?@_kernel_lastpt = ?@_kernel_lastpt + [$F3F6-8]-*
|
|
Source: source/Shared/screen.s
|
|
250 .endif
|
|
251
|
|
252 F2CA org $f3f6-8
|
|
253
|
|
254 ;==========================================================================
|
|
255 ;==========================================================================
|
|
256
|
|
257 ;==========================================================================
|
|
258 ;
|
|
259 ; Return:
|
|
260 ; MEMTOP = first byte used by display
|
|
261 ;
|
|
262 ; Errors:
|
|
263 ; - If there is not enough memory (MEMTOP > APPMHI), GR.0 is reopened
|
|
264 ; automatically and an error is returned.
|
|
265 ;
|
|
266 ; Notes:
|
|
267 ; - Resets character base (CHBAS).
|
|
268 ; - Resets character attributes (CHACT).
|
|
269 ; - Resets playfield colors (COLOR0-COLOR4).
|
|
270 ; - Resets tab map, even if the mode does not have a text window.
|
|
271 ; - Resets logical line map, even if the mode does not have a text window.
|
|
272 ; - Does NOT reset P/M colors (PCOLR0-PCOLR3).
|
|
273 ; - Does NOT reset margins (LMARGN/RMARGN).
|
|
274 ; - Sets up fine scrolling if FINE bit 7 is set. Note that this is
|
|
275 ; different than the scroll logic itself, which tests the whole byte.
|
|
276 ; - Returns error $80 if BREAK has been pressed.
|
|
277 ; - If clear is bypassed, ROWCRS and COLCRS are preserved.
|
|
278 ;
|
|
279 ; Modified:
|
|
280 ; - FRMADR: used for bitflags
|
|
281 ; bit 7 = skip clear
|
|
282 ; bit 6 = split screen
|
|
283 ; bit 0 = fine scrolling (XL/XE only)
|
|
284 ; - ADRESS: temporary addressing
|
|
285 ;
|
|
286 = F3F6 ScreenOpen = ScreenOpenGr0.use_iocb
|
|
287 = F3F2 ScreenOpenMode0 = ScreenOpenGr0.use_mode0
|
|
288 F3EE .proc ScreenOpenGr0
|
|
289 F3EE A9 0C 85 2A mva #12 icax1z
|
|
290 F3F2 use_mode0:
|
|
291 F3F2 A9 00 85 2B mva #0 icax2z
|
|
292 F3F6 use_iocb:
|
|
293 ;shut off ANTIC playfield and instruction DMA
|
|
294 F3F6 AD 2F 02 lda sdmctl
|
|
295 F3F9 29 DC and #$dc
|
|
296 F3FB 8D 2F 02 sta sdmctl
|
|
297 F3FE 8D 00 D4 sta dmactl
|
|
298
|
|
299 ;reset cursor parameters
|
|
300 F401 A2 0B ldx #11
|
|
301 F403 A9 00 lda #0
|
|
302 F405 clear_parms:
|
|
303 F405 95 54 sta rowcrs,x
|
|
304 F407 9D 90 02 sta txtrow,x
|
|
305 F40A CA dex
|
|
306 F40B D0 F8 bne clear_parms
|
|
307
|
|
308 ;mark us as being in main screen context
|
|
309 F40D 86 7B stx swpflg
|
|
310
|
|
311 ;copy mode value to dindex
|
|
312 F40F A5 2B lda icax2z
|
|
313 F411 29 0F and #15
|
|
314 F413 85 57 sta dindex
|
|
315 F415 AA tax
|
|
316
|
|
317 ;poke PRIOR value (saves us some time to do it now)
|
|
318 ;note that we must preserve bits 0-5 of GPRIOR or else Wayout shows logo artifacts
|
|
319 F416 BD 72 F2 lda ScreenModeTable,x
|
|
320 F419 4D 6F 02 eor gprior
|
|
321 F41C 29 C0 and #$c0
|
|
322 F41E 4D 6F 02 eor gprior
|
|
323 F421 8D 6F 02 sta gprior
|
|
324
|
|
325 ;if a GTIA mode is active or we're in mode 0, force off split mode
|
|
326 F424 C9 40 cmp #$40
|
|
327 F426 A5 2A lda icax1z
|
|
328 F428 B0 04 bcs kill_split
|
|
329 F42A E0 00 cpx #0
|
|
330 F42C D0 02 bne not_gtia_mode_or_gr0
|
|
331 F42E kill_split:
|
|
332 F42E 29 EF and #$ef
|
|
333 F430 not_gtia_mode_or_gr0:
|
|
334
|
|
335 ;save off the split screen and clear flags in a more convenient form
|
|
336 F430 0A asl
|
|
337 F431 0A asl
|
|
338 F432 85 68 sta frmadr
|
|
339
|
|
340 ;compute number of mode lines that we're going to have and save it off
|
|
341 F434 BC 82 F2 ldy ScreenHeightShifts,x
|
|
342 F437 BE 92 F2 ldx ScreenHeights,y
|
|
343 F43A 0A asl
|
|
344 F43B 10 03 BE A7 F2 spl:ldx ScreenHeightsSplit,y
|
|
345 F440 86 69 stx frmadr+1
|
|
346
|
|
347 ;attempt to allocate playfield memory
|
|
348 F442 A5 6A lda ramtop
|
|
349 F444 A6 57 ldx dindex
|
|
350 F446 18 clc
|
|
351 F447 7D 62 F2 adc ScreenPlayfieldSizesHi,x
|
|
352 F44A B0 09 bcs pf_alloc_ok
|
|
353
|
|
354 F44C alloc_fail:
|
|
355 ;we ran out of memory -- attempt to reopen with gr.0 if we aren't
|
|
356 ;already (to prevent recursion), and exit with an error
|
|
357 F44C 8A txa
|
|
358 F44D F0 03 beq cant_reopen_gr0
|
|
359
|
|
360 F44F 20 EE F3 jsr ScreenOpenGr0
|
|
361 F452 cant_reopen_gr0:
|
|
362 F452 A0 93 ldy #CIOStatOutOfMemory
|
|
363 F454 60 rts
|
|
364
|
|
365 F455 pf_alloc_ok:
|
|
366 F455 85 59 sta savmsc+1
|
|
367 F457 BC 52 F2 ldy ScreenPlayfieldSizesLo,x
|
|
368 F45A 84 58 sty savmsc
|
|
369
|
|
370 ;Gr. modes 7 and 14 consume enough space for the playfield that there
|
|
371 ;is not enough space left between the playfield and the next 1K
|
|
372 ;boundary to contain the display list. In these cases, we preallocate
|
|
373 ;to the 1K boundary to prevent a DL crossing error. Gr.8-11 and 15
|
|
374 ;do this too -- I have no idea why, as it's not like the OS correctly
|
|
375 ;handles moving the 4K page split for those modes if RAMTOP is
|
|
376 ;misaligned.
|
|
377 F45C BD 72 F2 lda ScreenModeTable,x
|
|
378 F45F A6 59 ldx savmsc+1
|
|
379 F461 29 30 and #$30
|
|
380 F463 F0 03 beq no_dlist_page_crossing
|
|
381 F465 A0 00 ldy #0
|
|
382 F467 CA dex
|
|
383 F468 no_dlist_page_crossing:
|
|
384 F468 84 70 sty rowac
|
|
385 F46A 8E E6 02 stx memtop+1
|
|
386 F46D 86 71 stx rowac+1
|
|
387 F46F 8E 31 02 stx sdlsth
|
|
388
|
|
389 ;Compute display list size.
|
|
390 ;
|
|
391 ; We need:
|
|
392 ; - 8 fixed bytes (24 blank lines, LMS address, JVB)
|
|
393 ; - N bytes for mode lines
|
|
394 ; - 2 bytes for LMS split address (ANTIC modes E-F only)
|
|
395 ; - 6 bytes for split
|
|
396 ;
|
|
397 ;Note that the display list never crosses a page boundary. This is
|
|
398 ;conservative, as the display list only can't cross 1K boundaries.
|
|
399
|
|
400 F472 C9 20 cmp #$20 ;test 4K hop bit (bit 5)
|
|
401 F474 A9 F8 lda #$f8 ;start with -8 (if carry is clear after test)
|
|
402 F476 90 02 A9 F5 scc:lda #$f5 ;use -11 if so (carry is set)
|
|
403 F47A E5 69 sbc frmadr+1 ;subtract mode line count
|
|
404 F47C 24 68 bit frmadr
|
|
405 F47E 50 02 E9 06 svc:sbc #6 ;subtract 6 bytes for a split
|
|
406
|
|
407 .if _KERNEL_XLXE
|
|
408 F482 A0 01 ldy #1
|
|
409 F484 CC 6E 02 cpy fine ;clear carry to alloc +1 byte if fine scrolling is enabled
|
|
410 .endif
|
|
411
|
|
412 F487 65 70 adc rowac ;allocate dl bytes (note that carry is set!)
|
|
413 F489 8D E5 02 sta memtop
|
|
414 F48C 85 70 sta rowac
|
|
415 F48E 8D 30 02 sta sdlstl
|
|
416
|
|
417 ;check if we're below APPMHI
|
|
418 F491 E4 0F cpx appmhi+1
|
|
419 F493 90 B7 bcc alloc_fail
|
|
420 F495 D0 04 bne alloc_ok
|
|
421 F497 C5 0E cmp appmhi
|
|
422 F499 90 B1 bcc alloc_fail
|
|
423
|
|
424 F49B alloc_ok:
|
|
425 ;MEMTOP is -1 from first used byte; we cheat here with the knowledge that
|
|
426 ;the low byte of MEMTOP is never $00
|
|
427 F49B CE E5 02 dec memtop
|
|
428
|
|
429 ;set up text window address (-160 from top)
|
|
430 F49E A6 6A ldx ramtop
|
|
431 F4A0 CA dex
|
|
432 F4A1 8E 95 02 stx txtmsc+1
|
|
433 F4A4 A9 60 8D 94 02 mva #$60 txtmsc
|
|
434
|
|
435 ;Turn on keyboard and break interrupts; note that this is done both for S:
|
|
436 ;and E: opens. Close does not do this.
|
|
437 F4A9 08 php
|
|
438 F4AA 78 sei
|
|
439 F4AB 0A asl ;!! - A = $C0
|
|
440 F4AC 05 10 ora pokmsk
|
|
441 F4AE 85 10 sta pokmsk
|
|
442 F4B0 8D 0E D2 sta irqen
|
|
443 F4B3 28 plp
|
|
444
|
|
445 ;Set row count: 24 for full-screen. We will fix up the split case to 4 later
|
|
446 ;while we are writing the display list. Mapping the Atari incorrectly states
|
|
447 ;that this value is set to 0 when no text window is present; this is wrong
|
|
448 ;and in fact BAYPILOT.BAS relies on this being set to 24 for a GR.7+16
|
|
449 ;screen since it later aliases it to GR.0.
|
|
450 F4B4 A0 18 ldy #24
|
|
451 F4B6 8C BF 02 sty botscr
|
|
452
|
|
453 ;init colors -- note that we do NOT overwrite pcolr0-3!
|
|
454 F4B9 A0 05 ldy #5
|
|
455 F4BB B9 BB F5 99 C3 02 + mva:rne standard_colors-1,y color0-1,y-
|
|
456
|
|
457 F4C4 8C F0 02 sty crsinh ;!! - Y=0 for this and for write index
|
|
458
|
|
459 ;add 24 blank lines
|
|
460 F4C7 A9 70 lda #$70
|
|
461 F4C9 A2 03 ldx #3
|
|
462 F4CB 20 85 F5 jsr write_repeat
|
|
463
|
|
464 ;override COLOR4 (background) to $06 for GR.11 so it isn't dark
|
|
465 F4CE A5 57 lda dindex
|
|
466 F4D0 C9 0B cmp #11
|
|
467 F4D2 D0 05 bne not_gr11
|
|
468 F4D4 A9 06 lda #$06
|
|
469 F4D6 8D C8 02 sta color4
|
|
470 F4D9 not_gr11:
|
|
471
|
|
472 ;add in the main screen
|
|
473 F4D9 20 3B F5 jsr setup_display
|
|
474
|
|
475 ;save off the DL ptr
|
|
476 F4DC 84 7E sty countr
|
|
477
|
|
478 ;clear it if necessary
|
|
479 F4DE 20 B5 F5 jsr try_clear
|
|
480
|
|
481 ;check if we are doing a split
|
|
482 F4E1 24 68 bit frmadr
|
|
483 F4E3 50 12 bvc nosplit
|
|
484
|
|
485 ;change text screen height to four lines
|
|
486 F4E5 A2 04 ldx #4
|
|
487 F4E7 8E BF 02 stx botscr
|
|
488
|
|
489 ;swap to the text screen
|
|
490 F4EA 20 3D F9 jsr EditorSwapToText
|
|
491
|
|
492 ;add text screen dlist
|
|
493 F4ED A4 7E ldy countr
|
|
494 F4EF 20 3B F5 jsr setup_display
|
|
495 F4F2 84 7E sty countr
|
|
496
|
|
497 ;clear the split screen
|
|
498 F4F4 20 B5 F5 jsr try_clear
|
|
499
|
|
500 F4F7 nosplit:
|
|
501 F4F7 A9 02 8D F3 02 mva #2 chact
|
|
502
|
|
503 ;init tab map to every 8 columns
|
|
504 F4FC A2 0F ldx #15
|
|
505 F4FE 4A lsr ;!! A=1
|
|
506 F4FF 9D A2 02 CA D0 FA sta:rne tabmap-1,x-
|
|
507
|
|
508 ;reset line status
|
|
509 F505 86 6B stx bufcnt
|
|
510
|
|
511 ;init character set
|
|
512 F507 A2 E0 8E F4 02 mvx #$e0 chbas ;!! - also used for NMIEN
|
|
513
|
|
514 ;enable VBI; note that we have not yet enabled display DMA
|
|
515 .if _KERNEL_XLXE
|
|
516 F50C 24 68 bit frmadr
|
|
517 F50E D0 02 A2 40 sne:ldx #$40
|
|
518 .else
|
|
519 ldx #$40
|
|
520 .endif
|
|
521 F512 8E 0E D4 stx nmien
|
|
522
|
|
523 ;terminate display list with jvb
|
|
524 F515 A4 7E ldy countr
|
|
525 F517 A2 70 ldx #rowac
|
|
526 F519 A9 41 lda #$41
|
|
527 F51B 20 A7 F5 jsr write_with_zp_address
|
|
528
|
|
529 ;init display list and playfield dma
|
|
530 F51E AD 2F 02 lda sdmctl
|
|
531 F521 09 22 ora #$22
|
|
532 F523 8D 2F 02 sta sdmctl
|
|
533
|
|
534 ;wait for screen to establish (necessary for Timewise splash screen to render)
|
|
535 F526 A5 14 lda rtclok+2
|
|
536 F528 C5 14 F0 FC cmp:req rtclok+2
|
|
537
|
|
538 ;If we're in screen mode 0, show the cursor; otherwise, skip it and wait for
|
|
539 ;E: to do so. We need to skip this even if a split screen is present, or else
|
|
540 ;ACTris 2.1 displays a bogus cursor. Unfortunately we may have swapped to the
|
|
541 ;split screen, so the mode we need may be in either DINDEX or TINDEX; it's
|
|
542 ;easier for us just to re-check AUX2 bits 0-3.
|
|
543 F52C A5 2B lda icax2z
|
|
544 F52E 29 0F and #$0f
|
|
545 F530 D0 03 bne no_cursor
|
|
546
|
|
547 ;show cursor
|
|
548 F532 20 B5 F6 jsr ScreenPutByte.recompute_show_cursor_exit
|
|
549 F535 no_cursor:
|
|
550 ;swap back to main context
|
|
551 F535 20 9C FD jsr EditorSwapToScreen_Y1
|
|
552
|
|
553 ;exit
|
|
554 F538 A2 00 ldx #0 ;required by Qix (v3)
|
|
555 F53A 60 rts
|
|
556
|
|
557
|
|
558 ;--------------------------------------------------------
|
|
559 F53B setup_display:
|
|
560 ;Add initial mode line with LMS, and check if we need to do an LMS
|
|
561 ;split (playfield exceeds 4K). As it turns out, this only happens if
|
|
562 ;we're using ANTIC mode E or F.
|
|
563 F53B A6 57 ldx dindex
|
|
564 F53D BD 72 F2 lda ScreenModeTable,x
|
|
565 F540 29 0F and #$0f
|
|
566
|
|
567 .if _KERNEL_XLXE
|
|
568 ;check if we are doing fine scrolling and set the vscrol bit if so
|
|
569 F542 A6 57 ldx dindex
|
|
570 F544 D0 07 bne nofine
|
|
571 F546 AE 6E 02 ldx fine
|
|
572 F549 F0 02 beq nofine
|
|
573 F54B 09 20 ora #$20
|
|
574 F54D nofine:
|
|
575 .endif
|
|
576
|
|
577 F54D 48 pha
|
|
578 F54E 09 40 ora #$40
|
|
579 F550 A2 58 ldx #savmsc
|
|
580 F552 20 A7 F5 jsr write_with_zp_address
|
|
581
|
|
582 ;retrieve row count
|
|
583 F555 A6 69 ldx frmadr+1
|
|
584 F557 A5 57 lda dindex
|
|
585 F559 D0 03 AE BF 02 sne:ldx botscr
|
|
586
|
|
587 ;dec row count since we already did the LMS
|
|
588 F55E CA dex
|
|
589 F55F 68 pla
|
|
590
|
|
591 .if _KERNEL_XLXE
|
|
592 ;subtract two rows if we are fine scrolling, as we need to do DLI
|
|
593 ;and non-vscrolled row
|
|
594 F560 C9 22 cmp #$22
|
|
595 F562 F0 28 beq dofine
|
|
596 .endif
|
|
597
|
|
598 ;check if this is a split mode
|
|
599 F564 C9 0E cmp #$0e
|
|
600 F566 90 1D bcc no_lms_split
|
|
601
|
|
602 ;yes it is -- write 93 lines
|
|
603 F568 A2 5D ldx #93
|
|
604 F56A 20 85 F5 jsr write_repeat
|
|
605
|
|
606 ;write LMS to jump over 4K boundary
|
|
607 F56D 48 pha
|
|
608 F56E 09 40 ora #$40
|
|
609 F570 91 70 C8 sta (rowac),y+
|
|
610 F573 A9 00 lda #0
|
|
611 F575 91 70 C8 sta (rowac),y+
|
|
612 F578 A5 59 lda savmsc+1
|
|
613 F57A 69 0E adc #$0f-1 ;!! - C=1 from bcc above
|
|
614 F57C 91 70 C8 sta (rowac),y+
|
|
615
|
|
616 ;set up to write 95 fewer lines (note that carry is cleared)
|
|
617 F57F A5 69 lda frmadr+1
|
|
618 F581 E9 5E sbc #94
|
|
619 F583 AA tax
|
|
620 F584 68 pla
|
|
621
|
|
622 ;write mode lines and return
|
|
623 F585 no_lms_split:
|
|
624 F585 write_repeat:
|
|
625 F585 91 70 C8 sta (rowac),y+
|
|
626 F588 CA dex
|
|
627 F589 D0 FA bne write_repeat
|
|
628 F58B no_clear:
|
|
629 F58B 60 rts
|
|
630
|
|
631 .if _KERNEL_XLXE
|
|
632 F58C dofine:
|
|
633 ;write the regular lines (22 or 2)
|
|
634 F58C CA dex
|
|
635 F58D 20 85 F5 jsr write_repeat
|
|
636
|
|
637 ;write DLI line
|
|
638 F590 09 80 ora #$80
|
|
639 F592 91 70 C8 sta (rowac),y+
|
|
640
|
|
641 ;write non-scrolled line
|
|
642 F595 29 5F and #$5f
|
|
643 F597 91 70 C8 sta (rowac),y+
|
|
644
|
|
645 ;indicate to mainline that DLIs should be turned on
|
|
646 F59A E6 68 inc frmadr
|
|
647
|
|
648 ;set up DLI routine
|
|
649 F59C A2 DE ldx #<ScreenFineScrollDLI
|
|
650 F59E A9 FD lda #>ScreenFineScrollDLI
|
|
651 F5A0 write_vdslst:
|
|
652 F5A0 8E 00 02 stx vdslst
|
|
653 F5A3 8D 01 02 sta vdslst+1
|
|
654 F5A6 60 rts
|
|
655 .endif
|
|
656
|
|
657 ;--------------------------------------------------------
|
|
658 F5A7 write_with_zp_address:
|
|
659 F5A7 91 70 C8 sta (rowac),y+
|
|
660 F5AA B5 00 lda 0,x
|
|
661 F5AC 91 70 C8 sta (rowac),y+
|
|
662 F5AF B5 01 lda 1,x
|
|
663 F5B1 A2 01 ldx #1
|
|
664 F5B3 D0 D0 bne write_repeat ;!! - unconditional
|
|
665
|
|
666 F5B5 try_clear:
|
|
667 F5B5 24 68 bit frmadr
|
|
668 F5B7 30 D2 bmi no_clear
|
|
669 F5B9 4C 4A F8 jmp ScreenClear
|
|
670
|
|
671 ;--------------------------------------------------------
|
|
672 F5BC standard_colors:
|
|
673 F5BC 28 dta $28
|
|
674 F5BD CA dta $ca
|
|
675 F5BE 94 dta $94
|
|
676 F5BF 46 dta $46
|
|
677 = F5C0 .def :ScreenBitposFlipTab
|
|
678 F5C0 00 dta $00 ;!! - shared value between tables
|
|
679 F5C1 01 dta $01
|
|
680 F5C2 03 dta $03
|
|
681 F5C3 07 dta $07
|
|
682
|
|
683 .endp
|
|
684
|
|
685 ;==========================================================================
|
|
686 F5C4 .proc ScreenInit
|
|
687 F5C4 AD E6 02 85 6A mva memtop+1 ramtop
|
|
688
|
|
689 .ifdef _KERNEL_816
|
|
690 stz colrsh
|
|
691 .else
|
|
692 F5C9 A9 00 85 4F mva #0 colrsh
|
|
693 .endif
|
|
694
|
|
695 F5CD A9 FE 85 4E mva #$FE drkmsk
|
|
696 F5D1 60 rts
|
|
697 .endp
|
|
698
|
|
699 ;==========================================================================
|
|
700 ; Behavior in gr.0:
|
|
701 ; - Reading char advances to next position, but cursor is not moved
|
|
702 ; - Cursor is picked up ($A0)
|
|
703 ; - Wrapping from end goes to left margin on next row
|
|
704 ; - Cursor may be outside of horizontal margins
|
|
705 ; - Error 141 (cursor out of range) if out of range
|
|
706 ; - Cursor will wrap to out of range if at end of screen (no automatic
|
|
707 ; vertical wrap)
|
|
708 ; - Does NOT update OLDROW/OLDCOL
|
|
709 ;
|
|
710 F5D2 .proc ScreenGetByte
|
|
711 F5D2 20 FA F8 jsr ScreenCheckPosition
|
|
712 F5D5 30 3A bmi xit
|
|
713
|
|
714 ;compute addressing
|
|
715 F5D7 A4 54 ldy rowcrs
|
|
716 F5D9 20 75 F9 jsr ScreenComputeToAddrX0
|
|
717 F5DC A5 55 lda colcrs
|
|
718 F5DE A6 57 ldx dindex
|
|
719 F5E0 BC B2 F2 ldy ScreenEncodingTab,x
|
|
720 F5E3 59 C0 F5 eor ScreenBitposFlipTab,y
|
|
721 F5E6 AA tax
|
|
722 F5E7 A5 56 lda colcrs+1
|
|
723 F5E9 20 BE F9 jsr ScreenSetupPixelAddr.phase2
|
|
724
|
|
725 ;retrieve byte containing pixel
|
|
726 F5EC A4 6F ldy shfamt
|
|
727 F5EE B1 66 lda (toadr),y
|
|
728
|
|
729 ;shift down
|
|
730 F5F0 20 AB F9 jsr ScreenAlignPixel
|
|
731
|
|
732 ;convert from Internal to ATASCII - must be done before we mask
|
|
733 ;Internal ATASCII
|
|
734 ;00-1F 20-3F
|
|
735 ;20-3F 40-5F
|
|
736 ;40-5F 00-1F
|
|
737 ;60-7F 60-7F
|
|
738 F5F3 0A asl
|
|
739 F5F4 08 php
|
|
740 F5F5 10 02 49 40 spl:eor #$40 ;00>20, 20>40, 40>60, 60>40
|
|
741 F5F9 69 40 adc #$40 ;00>20, 20>40, 40>00, 60>60
|
|
742 F5FB 28 plp
|
|
743 F5FC 6A ror
|
|
744
|
|
745 ;mask using right-justified pixel mask for mode
|
|
746 F5FD A6 57 ldx dindex
|
|
747 F5FF BC B2 F2 ldy ScreenEncodingTab,x
|
|
748 F602 39 C2 F2 and ScreenPixelMasks,y
|
|
749
|
|
750 ;advance to next position
|
|
751 F605 A6 57 ldx dindex
|
|
752 F607 F0 03 beq mode0
|
|
753 F609 4C D6 F9 jmp ScreenAdvancePosNonMode0
|
|
754 F60C mode0:
|
|
755 F60C 20 08 FE jsr ScreenAdvancePosMode0
|
|
756 F60F A0 01 ldy #1
|
|
757 F611 xit:
|
|
758 F611 60 rts
|
|
759 .endp
|
|
760
|
|
761 ;==========================================================================
|
|
762 ; Common behavior:
|
|
763 ; - Output is suspended if SSFLAG is set for non-clear and non-EOL chars
|
|
764 ; - Clear screen ($7D) and EOL ($9B) are always handled
|
|
765 ; - ESCFLG and DSPFLG are ignored (they are E: features)
|
|
766 ;
|
|
767 ; Behavior in gr.0:
|
|
768 ; - Logical lines are extended
|
|
769 ; - Scrolling occurs if bottom is hit
|
|
770 ; - Control chars other than clear and EOL are NOT handled by S:
|
|
771 ; - ROWCRS or COLCRS out of range results in an error.
|
|
772 ; - COLCRS in left margin is ignored and prints within margin.
|
|
773 ; - COLCRS in right margin prints one char and then does EOL.
|
|
774 ; - Previous cursor is not erased by S:, regardless of CRSINH state
|
|
775 ; - New cursor is drawn if CRSINH=0
|
|
776 ;
|
|
777 ; Behavior in gr.1+:
|
|
778 ; - No cursor is displayed
|
|
779 ; - LMARGN/RMARGN are ignored
|
|
780 ; - Cursor wraps from right side to next line
|
|
781 ; - ROWCRS may be below split screen boundary as long as it is within the
|
|
782 ; full screen size.
|
|
783 ;
|
|
784 F612 .proc ScreenPutByte
|
|
785 F612 8D FB 02 sta atachr
|
|
786 F615 20 FA F8 jsr ScreenCheckPosition
|
|
787 F618 30 0C bmi error
|
|
788
|
|
789 ;check for screen clear
|
|
790 F61A AD FB 02 lda atachr
|
|
791 F61D C9 7D cmp #$7d
|
|
792 F61F D0 0E bne not_clear_2
|
|
793 F621 20 4A F8 jsr ScreenClear
|
|
794 F624 A0 01 ldy #1
|
|
795 F626 error:
|
|
796 F626 60 rts
|
|
797
|
|
798 F627 graphics_eol:
|
|
799 F627 4C EF F9 jmp ScreenAdvancePosNonMode0.graphics_eol
|
|
800
|
|
801 ;*** ENTRY POINT FROM EDITOR FOR ESC HANDLING ***
|
|
802 F62A not_clear:
|
|
803 F62A 20 FA F8 jsr ScreenCheckPosition
|
|
804 F62D 30 F7 bmi error
|
|
805
|
|
806 F62F not_clear_2:
|
|
807 ;set old position now (used by setup code for plot pixel)
|
|
808 F62F 20 FE FD jsr ScreenSetLastPosition
|
|
809
|
|
810 ;restore char
|
|
811 F632 AD FB 02 lda atachr
|
|
812
|
|
813 ;check if we're in gr.0
|
|
814 F635 A6 57 ldx dindex
|
|
815 F637 F0 1E beq mode_0
|
|
816
|
|
817 ;nope, we're in a graphics mode... that makes this easier.
|
|
818 ;check if it's an EOL
|
|
819 F639 C9 9B cmp #$9b
|
|
820 F63B F0 EA beq graphics_eol
|
|
821
|
|
822 ;check for display suspend (ctrl+1) and wait until it is cleared
|
|
823 F63D AE FF 02 D0 FB ldx:rne ssflag
|
|
824
|
|
825 ;fold the pixel, compute masks, and convert ATASCII to Internal
|
|
826 F642 20 CE F6 jsr ScreenFoldColor
|
|
827 F645 48 pha
|
|
828
|
|
829 ;compute addressing and shift mask
|
|
830 F646 20 A6 F9 jsr ScreenSetupPlotPixel
|
|
831
|
|
832 F649 68 pla
|
|
833 F64A A4 6F ldy shfamt
|
|
834 F64C 51 66 eor (toadr),y
|
|
835 F64E 25 6E and bitmsk
|
|
836 F650 51 66 eor (toadr),y
|
|
837 F652 91 66 sta (toadr),y
|
|
838
|
|
839 ;advance cursor position and exit
|
|
840 F654 4C D6 F9 jmp ScreenAdvancePosNonMode0
|
|
841
|
|
842 F657 mode_0:
|
|
843 ;check for EOL, which bypasses the ESC check
|
|
844 F657 C9 9B cmp #$9b
|
|
845 F659 D0 18 bne not_eol
|
|
846
|
|
847 ;it's an EOL
|
|
848 F65B A5 52 lda lmargn
|
|
849 F65D 85 55 sta colcrs
|
|
850 F65F E6 54 inc rowcrs
|
|
851 F661 A5 54 lda rowcrs
|
|
852 F663 CD BF 02 cmp botscr
|
|
853 F666 90 08 bcc noywrap
|
|
854
|
|
855 ;We've gone over -- delete logical line 0 to make room.
|
|
856 ;Note that we need to set ROWCRS here first because the scroll may
|
|
857 ;delete more than one physical line.
|
|
858 F668 AE BF 02 ldx botscr
|
|
859 F66B 86 54 stx rowcrs
|
|
860
|
|
861 F66D 20 CC FC jsr EditorDeleteLine0
|
|
862 F670 noywrap:
|
|
863 F670 4C B5 F6 jmp recompute_show_cursor_exit
|
|
864
|
|
865 F673 not_eol:
|
|
866 ;check for display suspend (ctrl+1) and wait until it is cleared
|
|
867 F673 AE FF 02 D0 FB ldx:rne ssflag
|
|
868
|
|
869 F678 48 pha
|
|
870 F679 20 C0 FC jsr EditorRecomputeCursorAddr
|
|
871 F67C 68 pla
|
|
872 F67D 20 EB F6 jsr ScreenConvertATASCIIToInternal
|
|
873
|
|
874 ;plot character
|
|
875 F680 A0 00 ldy #0
|
|
876 F682 91 5E sta (oldadr),y
|
|
877
|
|
878 ;inc pos
|
|
879 F684 E6 5E D0 02 E6 5F inw oldadr
|
|
880 F68A 20 08 FE jsr ScreenAdvancePosMode0
|
|
881
|
|
882 ;check if we've gone beyond the right margin
|
|
883 F68D B0 29 bcs nowrap
|
|
884
|
|
885 ;check if we're beyond the bottom of the screen
|
|
886 F68F A5 54 lda rowcrs
|
|
887 F691 CD BF 02 cmp botscr
|
|
888 F694 90 12 bcc no_scroll
|
|
889
|
|
890 ;yes -- scroll up
|
|
891 F696 20 CC FC jsr EditorDeleteLine0
|
|
892
|
|
893 ;check if we can extend the current logical line -- 3 rows max.
|
|
894 F699 20 BB F6 jsr check_extend
|
|
895
|
|
896 ;Mark the current physical line as part of the last logical line.
|
|
897 ;
|
|
898 ;NOTE: There is a subtlety here in that we may delete multiple physical
|
|
899 ; lines if the top logical line is more than one line long, but we
|
|
900 ; only want to add one physical line onto our current logical line.
|
|
901 F69C 20 6F FD jsr EditorGetCurLogicalLineInfo
|
|
902 F69F 59 B2 02 eor logmap,y
|
|
903 F6A2 99 B2 02 sta logmap,y
|
|
904
|
|
905 F6A5 4C B5 F6 jmp post_scroll
|
|
906
|
|
907 F6A8 no_scroll:
|
|
908 ;check if we can extend the current logical line -- 3 rows max.
|
|
909 F6A8 20 BB F6 jsr check_extend
|
|
910
|
|
911 ;okay, here's the fun part -- we didn't scroll beyond, but we might
|
|
912 ;be on another logical line, in which case we need to scroll everything
|
|
913 ;down to extend it.
|
|
914 F6AB A5 54 lda rowcrs
|
|
915 F6AD 20 7E FD jsr EditorTestLogicalLineBit
|
|
916 F6B0 F0 03 beq post_scroll
|
|
917
|
|
918 ;yup, insert a physical line
|
|
919 F6B2 20 8D F8 jsr ScreenInsertPhysLine
|
|
920
|
|
921 F6B5 recompute_show_cursor_exit:
|
|
922 F6B5 post_scroll:
|
|
923 F6B5 20 C0 FC jsr EditorRecomputeCursorAddr
|
|
924 F6B8 nowrap:
|
|
925 F6B8 4C 17 FE jmp ScreenShowCursorAndXitOK
|
|
926
|
|
927 F6BB check_extend:
|
|
928 F6BB A6 54 ldx rowcrs
|
|
929 F6BD CA dex
|
|
930 F6BE 8A txa
|
|
931 F6BF 20 87 FD jsr EditorPhysToLogicalRow
|
|
932
|
|
933 .ifdef _KERNEL_816
|
|
934 inc
|
|
935 inc
|
|
936 .else
|
|
937 F6C2 18 clc
|
|
938 F6C3 69 02 adc #2
|
|
939 .endif
|
|
940
|
|
941 F6C5 C5 54 cmp rowcrs
|
|
942 F6C7 90 01 60 scc:rts
|
|
943 F6CA 68 pla
|
|
944 F6CB 68 pla
|
|
945 F6CC 90 E7 bcc post_scroll
|
|
946 .endp
|
|
947
|
|
948 ;==========================================================================
|
|
949 = E4C9 ScreenGetStatus = CIOExitSuccess
|
|
950
|
|
951 ;==========================================================================
|
|
952 ; Given a color byte, mask it off to the pertinent bits and reflect it
|
|
953 ; throughout a byte. The byte is converted from ATASCII to Internal
|
|
954 ; if the mode uses byte encoding.
|
|
955 ;
|
|
956 ; Entry:
|
|
957 ; A = color value
|
|
958 ;
|
|
959 ; Exit:
|
|
960 ; A = folded color byte
|
|
961 ; Y = encoding mode
|
|
962 ; DMASK = right-justified bit mask
|
|
963 ; DELTAC = left-justified bit mask
|
|
964 ;
|
|
965 ; Modified:
|
|
966 ; HOLD1, ADRESS
|
|
967 ;
|
|
968 F6CE .proc ScreenFoldColor
|
|
969 F6CE A6 57 ldx dindex
|
|
970 F6D0 BC B2 F2 ldy ScreenEncodingTab,x ;0 = 8-bit, 1 = 4-bit, 2 = 2-bit, 3 = 1-bit
|
|
971 F6D3 BE C6 F2 86 77 mvx ScreenPixelMasks+4,y deltac
|
|
972 F6D8 BE C2 F2 8E A0 02 mvx ScreenPixelMasks,y dmask
|
|
973 F6DE 30 0B bmi fold_byte
|
|
974 F6E0 2D A0 02 and dmask
|
|
975 F6E3 19 DA FD ora ScreenEncodingOffsetTable-1,y
|
|
976 F6E6 AA tax
|
|
977 F6E7 BD 3C F2 lda ScreenEncodingTable,x
|
|
978 F6EA 60 rts
|
|
979
|
|
980 F6EB fold_byte:
|
|
981 ;convert byte from ATASCII to Internal -- this is required for gr.1
|
|
982 ;and gr.2 to work correctly, and harmless for other modes
|
|
983
|
|
984 ;==========================================================================
|
|
985 ; Convert an ATASCII character to displayable INTERNAL format.
|
|
986 ;
|
|
987 ; Entry:
|
|
988 ; A = ATASCII char
|
|
989 ;
|
|
990 ; Exit:
|
|
991 ; A = INTERNAL char
|
|
992 ;
|
|
993 = F6EB .def :ScreenConvertATASCIIToInternal
|
|
994 ;ATASCII Internal
|
|
995 ;00-1F 40-5F
|
|
996 ;20-3F 00-1F
|
|
997 ;40-5F 20-3F
|
|
998 ;60-7F 60-7F
|
|
999
|
|
1000 F6EB 0A asl
|
|
1001 F6EC 08 php
|
|
1002 F6ED E9 3F sbc #$3f ;00>60, 20>00, 40>20, 60>40
|
|
1003 F6EF 10 02 49 40 spl:eor #$40 ;00>40, 20>00, 40>20, 60>60
|
|
1004 F6F3 28 plp
|
|
1005 F6F4 6A ror
|
|
1006 F6F5 60 rts
|
|
1007 .endp
|
|
1008
|
|
1009
|
|
1010 ;==========================================================================
|
|
1011 F6F6 .proc ScreenSpecial
|
|
1012 F6F6 A5 22 lda iccomz
|
|
1013 F6F8 C9 11 cmp #$11
|
|
1014 F6FA F0 05 beq ScreenDrawLineFill ;draw line
|
|
1015 F6FC C9 12 cmp #$12
|
|
1016 F6FE F0 01 beq ScreenDrawLineFill ;fill
|
|
1017 F700 60 rts
|
|
1018 .endp
|
|
1019
|
|
1020 ;==========================================================================
|
|
1021 ;
|
|
1022 ; Inputs:
|
|
1023 ; COLCRS,ROWCRS = next point
|
|
1024 ; OLDCOL,OLDROW = previous point
|
|
1025 ; ATACHR = color/character to use
|
|
1026 ;
|
|
1027 ; Outputs:
|
|
1028 ; OLDCOL,OLDROW = next point
|
|
1029 ;
|
|
1030 ; Behavior:
|
|
1031 ; - In GR.0:
|
|
1032 ; - Cursor is not drawn, even with CRSINH=0
|
|
1033 ; - OLDADR is updated to ending location, but not OLDCHR. If CRSINH=0,
|
|
1034 ; this can lead to a subsequent E: write stomping the last line draw
|
|
1035 ; cell with the under-cursor char from the last time the cursor was
|
|
1036 ; drawn elsewhere.
|
|
1037 ;
|
|
1038 ; Some test cases:
|
|
1039 ; - Ryba Pila
|
|
1040 ; - SPACEWAY.BAS
|
|
1041 ; - Worm of Bemer
|
|
1042 ;
|
|
1043 ; The Bresenham algorithm we use (from Wikipedia):
|
|
1044 ; dx = |x2 - x1|
|
|
1045 ; dy = |y2 - y1|
|
|
1046 ; e = dx - dy
|
|
1047 ;
|
|
1048 ; loop
|
|
1049 ; plot(x1, y1)
|
|
1050 ; if x1 == x2 and y1 == y2 then exit
|
|
1051 ; e2 = 2*e
|
|
1052 ; if e2 + dy > 0 then
|
|
1053 ; err = err - dy
|
|
1054 ; x0 = x0 + sign(dx)
|
|
1055 ; endif
|
|
1056 ; if e2 < dx then
|
|
1057 ; err = err + dx
|
|
1058 ; y0 = y0 + sign(dy)
|
|
1059 ; endif
|
|
1060 ; end
|
|
1061 ;
|
|
1062 F701 .proc ScreenDrawLineFill
|
|
1063 ;;##TRACE "Drawing line (%d,%d)-(%d,%d) in mode %d" dw(oldcol) db(oldrow) dw(colcrs) db(rowcrs) db(dindex)
|
|
1064
|
|
1065 ;initialize bit mask and repeat pertinent pixel bits throughout byte
|
|
1066 F701 AD FD 02 lda fildat
|
|
1067 F704 20 CE F6 jsr ScreenFoldColor
|
|
1068 F707 8D BC 02 sta hold4
|
|
1069 F70A AD FB 02 lda atachr
|
|
1070 F70D 20 CE F6 jsr ScreenFoldColor
|
|
1071 F710 85 51 sta hold1
|
|
1072
|
|
1073 F712 20 A6 F9 jsr ScreenSetupPlotPixel
|
|
1074
|
|
1075 ;compute screen pitch
|
|
1076 F715 A0 01 ldy #1
|
|
1077 F717 20 7F F9 jsr ScreenComputeRangeSize
|
|
1078 F71A 85 78 sta deltac+1
|
|
1079 F71C AA tax
|
|
1080 F71D A0 00 ldy #0
|
|
1081
|
|
1082 ;compute abs(dy) and sign(dy)
|
|
1083 F71F A5 54 lda rowcrs
|
|
1084 F721 38 E5 5A sub oldrow
|
|
1085 F724 B0 0C bcs going_down
|
|
1086 F726 49 FF eor #$ff ;take abs(dy)
|
|
1087 F728 69 01 adc #1 ;
|
|
1088 ;negate screen pitch
|
|
1089 F72A 48 pha
|
|
1090 F72B 8A txa
|
|
1091 F72C 49 FF eor #$ff
|
|
1092 F72E AA tax
|
|
1093 F72F E8 inx
|
|
1094 F730 88 dey
|
|
1095 F731 68 pla
|
|
1096 F732 going_down:
|
|
1097 F732 86 70 stx rowac
|
|
1098 F734 85 76 sta deltar
|
|
1099 F736 84 71 sty rowac+1
|
|
1100
|
|
1101 ;;##TRACE "dy = %d" db(deltar)
|
|
1102
|
|
1103 ;compute abs(dx) and sign(dx)
|
|
1104 F738 A2 00 ldx #0
|
|
1105 F73A A5 55 lda colcrs
|
|
1106 F73C 38 E5 5B sub oldcol
|
|
1107 F73F 85 72 sta colac
|
|
1108 F741 A5 56 lda colcrs+1
|
|
1109 F743 E5 5C sbc oldcol+1
|
|
1110 F745 B0 10 bcs going_right
|
|
1111 F747 49 FF eor #$ff
|
|
1112 F749 A8 tay
|
|
1113 F74A A5 72 lda colac
|
|
1114 F74C 49 FF eor #$ff
|
|
1115 F74E 69 01 adc #1
|
|
1116 F750 85 72 sta colac
|
|
1117 F752 98 tya
|
|
1118 F753 69 00 adc #0
|
|
1119 F755 A2 CC ldx #left_shift_8-right_shift_8
|
|
1120 F757 going_right:
|
|
1121 F757 85 73 sta colac+1
|
|
1122
|
|
1123 ;;##TRACE "dx = %d" dw(colac)
|
|
1124
|
|
1125 ;set up x shift routine
|
|
1126 F759 8A txa
|
|
1127 F75A A6 57 ldx dindex
|
|
1128 F75C BC B2 F2 ldy ScreenEncodingTab,x
|
|
1129 F75F 18 clc
|
|
1130 F760 79 AD F7 adc shift_lo_tab,y
|
|
1131 F763 85 64 sta adress
|
|
1132 F765 A9 F7 lda #>left_shift_8
|
|
1133 F767 85 65 sta adress+1
|
|
1134 F769 85 75 sta endpt+1
|
|
1135
|
|
1136 ;set up x fill shift routine
|
|
1137 F76B B9 AD F7 lda shift_lo_tab,y
|
|
1138 F76E 18 clc
|
|
1139 F76F 69 D9 adc #fill_right_8-right_shift_8
|
|
1140 F771 85 74 sta endpt
|
|
1141
|
|
1142 ;compute initial error accumulator in frmadr (dx-dy)
|
|
1143 F773 A6 72 ldx colac
|
|
1144 F775 8A txa
|
|
1145 F776 38 E5 76 sub deltar
|
|
1146 F779 85 68 sta frmadr
|
|
1147 F77B A4 73 ldy colac+1 ;leave dx in y:x for max() below
|
|
1148 F77D 98 tya
|
|
1149 F77E E9 00 sbc #0
|
|
1150 F780 85 69 sta frmadr+1
|
|
1151
|
|
1152 ;compute max(dx, dy) based on sign of (dx - dy)
|
|
1153 F782 B0 04 bcs dx_larger
|
|
1154 F784 A0 00 ldy #0
|
|
1155 F786 A6 76 ldx deltar
|
|
1156 F788 dx_larger:
|
|
1157 F788 86 7E stx countr
|
|
1158 F78A 84 7F sty countr+1
|
|
1159
|
|
1160 F78C 98 tya
|
|
1161 F78D D0 03 bne not_empty
|
|
1162 F78F 8A txa
|
|
1163 F790 F0 0D beq skip_showcursor
|
|
1164 F792 not_empty:
|
|
1165
|
|
1166 ;;##TRACE "Pixel count = %d" dw(countr)
|
|
1167
|
|
1168 ;enter pixel loop (this will do a decrement for us)
|
|
1169 F792 4C 02 F8 jmp next_pixel
|
|
1170
|
|
1171 ;----------------------------------------------
|
|
1172 F795 done:
|
|
1173 F795 20 FE FD jsr ScreenSetLastPosition
|
|
1174
|
|
1175 ;RYBA PILA requires the quirky behavior of the last character of a non-zero length
|
|
1176 ;DRAWTO being stomped by the character saved from the cursor draw of the last PLOT
|
|
1177 ;(write to S:). Note that we must NOT do this for length 0 or it breaks SPACEWAY.
|
|
1178 F798 A4 57 ldy dindex
|
|
1179 F79A D0 03 bne skip_showcursor
|
|
1180 F79C 20 C0 FC jsr EditorRecomputeCursorAddr
|
|
1181 F79F skip_showcursor:
|
|
1182 F79F A0 01 ldy #1
|
|
1183 F7A1 60 rts
|
|
1184
|
|
1185 ;----------------------------------------------
|
|
1186 F7A2 fill_done:
|
|
1187 F7A2 86 6E stx bitmsk
|
|
1188 F7A4 4C 02 F8 jmp next_pixel
|
|
1189
|
|
1190 ;----------------------------------------------
|
|
1191 F7A7 do_fill:
|
|
1192 F7A7 A4 6F ldy shfamt ;load current byte offset
|
|
1193 F7A9 A6 6E ldx bitmsk ;save current bitmask
|
|
1194 F7AB D0 33 bne fill_start ;!! - unconditional
|
|
1195
|
|
1196 ;----------------------------------------------
|
|
1197 F7AD shift_lo_tab:
|
|
1198 F7AD EB dta <right_shift_8
|
|
1199 F7AE E5 dta <right_shift_4
|
|
1200 F7AF E7 dta <right_shift_2
|
|
1201 F7B0 E8 dta <right_shift_1
|
|
1202
|
|
1203 ;----------------------------------------------
|
|
1204 F7B1 left_shift_4:
|
|
1205 F7B1 0A asl
|
|
1206 F7B2 0A asl
|
|
1207 F7B3 left_shift_2:
|
|
1208 F7B3 0A asl
|
|
1209 F7B4 left_shift_1:
|
|
1210 F7B4 0A asl
|
|
1211 F7B5 90 05 bcc left_shift_ok
|
|
1212 F7B7 left_shift_8:
|
|
1213 F7B7 C6 6F dec shfamt
|
|
1214 F7B9 AD A0 02 lda dmask
|
|
1215 F7BC left_shift_ok:
|
|
1216 F7BC D0 31 bne post_xinc ;!! - unconditional
|
|
1217
|
|
1218 ;----------------------------------------------
|
|
1219 F7BE fill_right_4:
|
|
1220 F7BE 4A lsr
|
|
1221 F7BF 4A lsr
|
|
1222 F7C0 fill_right_2:
|
|
1223 F7C0 4A lsr
|
|
1224 F7C1 fill_right_1:
|
|
1225 F7C1 4A lsr
|
|
1226 F7C2 90 09 bcc fill_right_ok
|
|
1227 F7C4 fill_right_8:
|
|
1228 F7C4 A5 77 lda deltac
|
|
1229 F7C6 C8 iny
|
|
1230 F7C7 C4 78 cpy deltac+1
|
|
1231 F7C9 90 02 A0 00 scc:ldy #0
|
|
1232 F7CD fill_right_ok:
|
|
1233 F7CD 85 6E sta bitmsk
|
|
1234 F7CF F0 D1 beq fill_done
|
|
1235 F7D1 fill_loop:
|
|
1236 F7D1 B1 66 lda (toadr),y ;load screen byte
|
|
1237 F7D3 24 6E bit bitmsk ;mask to current pixel
|
|
1238 F7D5 D0 CB bne fill_done ;exit loop if non-zero
|
|
1239 F7D7 4D BC 02 eor hold4 ;XOR with fill color
|
|
1240 F7DA 25 6E and bitmsk ;mask change bits to current pixel
|
|
1241 F7DC 51 66 eor (toadr),y ;merge with screen byte
|
|
1242 F7DE 91 66 sta (toadr),y ;save screen byte
|
|
1243 F7E0 fill_start:
|
|
1244 F7E0 A5 6E lda bitmsk
|
|
1245 F7E2 6C 74 00 jmp (endpt)
|
|
1246
|
|
1247 ;----------------------------------------------
|
|
1248 F7E5 right_shift_4:
|
|
1249 F7E5 4A lsr
|
|
1250 F7E6 4A lsr
|
|
1251 F7E7 right_shift_2:
|
|
1252 F7E7 4A lsr
|
|
1253 F7E8 right_shift_1:
|
|
1254 F7E8 4A lsr
|
|
1255 F7E9 90 04 bcc right_shift_ok
|
|
1256 F7EB right_shift_8:
|
|
1257 F7EB E6 6F inc shfamt
|
|
1258 F7ED A5 77 lda deltac
|
|
1259 F7EF right_shift_ok:
|
|
1260 ;fall through to post_xinc
|
|
1261 F7EF post_xinc:
|
|
1262 F7EF 85 6E sta bitmsk
|
|
1263 F7F1 no_xinc:
|
|
1264
|
|
1265 ;plot pixel
|
|
1266 ;;##TRACE "Plotting at $%04X+%d with mask $%02X" dw(toadr) db(shfamt) db(bitmsk)
|
|
1267 F7F1 A4 6F ldy shfamt
|
|
1268 F7F3 A5 51 lda hold1
|
|
1269 F7F5 51 66 eor (toadr),y
|
|
1270 F7F7 25 6E and bitmsk
|
|
1271 F7F9 51 66 eor (toadr),y
|
|
1272 F7FB 91 66 sta (toadr),y
|
|
1273
|
|
1274 ;do fill if needed
|
|
1275 F7FD A5 22 lda iccomz
|
|
1276 F7FF 4A lsr
|
|
1277 F800 90 A5 bcc do_fill
|
|
1278
|
|
1279 F802 next_pixel:
|
|
1280 ;loop back for next pixel
|
|
1281 F802 A5 7E lda countr
|
|
1282 F804 D0 04 bne next_pixel_2
|
|
1283 F806 C6 7F dec countr+1
|
|
1284 F808 30 8B bmi done
|
|
1285 F80A next_pixel_2:
|
|
1286 F80A C6 7E dec countr
|
|
1287
|
|
1288 ;!! - fall through to pixel loop
|
|
1289
|
|
1290 ;------- pixel loop state -------
|
|
1291 ; (zp) frmadr error accumulator
|
|
1292 ; (zp) toadr current row address
|
|
1293 ; (abs) dmask right-justified bit mask
|
|
1294 ; (zp) deltac left-justified bit mask
|
|
1295 ; (zp) bitmsk current bit mask
|
|
1296 ; (zp) shfamt current byte offset within row
|
|
1297 ; (zp) rowac y step address increment/decrement (note different from Atari OS)
|
|
1298 ; (zp) adress left/right shift routine
|
|
1299 ; (zp) deltac+1 screen pitch, in bytes (for fill)
|
|
1300 ; (zp) endpt right shift routine
|
|
1301 ; (zp) colac dy
|
|
1302 F80C pixel_loop:
|
|
1303 ;compute 2*err
|
|
1304 ;;##TRACE "Error accum = %d (dx=%d, dy=%d(%d))" dsw(frmadr) dw(colac) db(deltar) dsw(rowac)
|
|
1305 F80C A5 68 lda frmadr
|
|
1306 F80E 0A asl
|
|
1307 F80F A8 tay
|
|
1308 F810 A5 69 lda frmadr+1
|
|
1309 F812 2A rol
|
|
1310 F813 AA tax
|
|
1311
|
|
1312 ;check for y increment (2*e < dx, or A:Y < colac)
|
|
1313 F814 98 tya
|
|
1314 F815 18 clc
|
|
1315 F816 E5 72 sbc colac
|
|
1316 F818 8A txa
|
|
1317 F819 48 pha
|
|
1318 F81A E5 73 sbc colac+1
|
|
1319 F81C 10 13 bpl no_yinc
|
|
1320
|
|
1321 F81E do_yinc:
|
|
1322 ;bump y (add/subtract pitch, e += dx)
|
|
1323 F81E A2 02 ldx #2
|
|
1324 F820 yinc_loop:
|
|
1325 F820 B5 70 lda rowac,x
|
|
1326 F822 18 clc
|
|
1327 F823 75 66 adc toadr,x
|
|
1328 F825 95 66 sta toadr,x
|
|
1329 F827 B5 71 lda rowac+1,x
|
|
1330 F829 75 67 adc toadr+1,x
|
|
1331 F82B 95 67 sta toadr+1,x
|
|
1332 F82D CA dex
|
|
1333 F82E CA dex
|
|
1334 F82F 10 EF bpl yinc_loop
|
|
1335 F831 no_yinc:
|
|
1336
|
|
1337 ;check for x increment (2*e + dy > 0, or Y:[S] + deltar > 0)
|
|
1338 F831 98 tya
|
|
1339 F832 18 clc
|
|
1340 F833 65 76 adc deltar
|
|
1341 F835 68 pla
|
|
1342 F836 69 00 adc #0
|
|
1343 F838 30 B7 bmi no_xinc
|
|
1344
|
|
1345 ;update error accumulator
|
|
1346 F83A A5 68 lda frmadr
|
|
1347 F83C 38 E5 76 sub deltar
|
|
1348 F83F 85 68 sta frmadr
|
|
1349 F841 B0 02 C6 69 scs:dec frmadr+1
|
|
1350
|
|
1351 ;bump x
|
|
1352 F845 A5 6E lda bitmsk
|
|
1353 F847 6C 64 00 jmp (adress)
|
|
1354
|
|
1355 .if [right_shift_4 ^ right_shift_8]&$ff00
|
|
1356 .error "Right draw routines cross page: ",right_shift_4,"-",right_shift_8
|
|
1357 .endif
|
|
1358 .if [left_shift_4 ^ left_shift_8]&$ff00
|
|
1359 .error "Left draw routines cross page: ",left_shift_4,"-",left_shift_8
|
|
1360 .endif
|
|
1361 .if [fill_right_4 ^ fill_right_8]&$ff00
|
|
1362 .error "Fill routines cross page: ",fill_right_4,"-",fill_right_8
|
|
1363 .endif
|
|
1364 .if [[right_shift_4^left_shift_4]|[left_shift_4^fill_right_4]]&$ff00
|
|
1365 .error "Line/fill routines cross page: ",left_shift_4,',',right_shift_4,',',fill_right_4
|
|
1366 .endif
|
|
1367
|
|
1368 .endp
|
|
1369
|
|
1370 ;==========================================================================
|
|
1371 ; Clear the screen.
|
|
1372 ;
|
|
1373 ; Used:
|
|
1374 ; ADRESS
|
|
1375 ; TOADR
|
|
1376 ;
|
|
1377 ; Quirks:
|
|
1378 ; Clears the split-screen text area even if the main screen (S:) receives
|
|
1379 ; the clear. The In-Store Demonstration Cart depends on this. The cursor
|
|
1380 ; state of the split screen is NOT reset, so if the cursor was over a
|
|
1381 ; non-blank character, that character will be restored when the cursor
|
|
1382 ; moves.
|
|
1383 ;
|
|
1384 ; The logical line map is always reset.
|
|
1385 ;
|
|
1386 F84A .proc ScreenClear
|
|
1387 ;first, set up for clearing the split-screen window (4*40 bytes main)
|
|
1388 F84A A0 04 ldy #4
|
|
1389
|
|
1390 ;check if we are in the split screen text window
|
|
1391 F84C A6 7B ldx swpflg
|
|
1392 F84E D0 08 bne is_text_window
|
|
1393
|
|
1394 ;nope, it's the main screen... compute size
|
|
1395 F850 A4 57 ldy dindex
|
|
1396 F852 BE 82 F2 ldx ScreenHeightShifts,y
|
|
1397 F855 BC 92 F2 ldy ScreenHeights,x
|
|
1398 F858 is_text_window:
|
|
1399 F858 20 7F F9 jsr ScreenComputeRangeSize
|
|
1400
|
|
1401 ;add 160 bytes to size if not GR.0 -- important to avoid clearing
|
|
1402 ;beyond GR.0 screen (the font breaks in BIKERDAV.BAS otherwise!)
|
|
1403 F85B 18 clc
|
|
1404 F85C A6 57 ldx dindex
|
|
1405 F85E F0 02 beq is_gr0
|
|
1406 F860 69 A0 adc #160
|
|
1407 F862 is_gr0:
|
|
1408 F862 A8 tay
|
|
1409 F863 A5 65 lda adress+1
|
|
1410 F865 69 00 adc #0
|
|
1411
|
|
1412 F867 AA tax
|
|
1413 F868 65 59 adc savmsc+1
|
|
1414 F86A 85 67 sta toadr+1
|
|
1415 F86C A5 58 85 66 mva savmsc toadr
|
|
1416
|
|
1417 ;As it turns out, there are no cases where the main screen
|
|
1418 ;is an exact number of pages... so we can simply plow into
|
|
1419 ;the clear loop.
|
|
1420 F870 A9 00 lda #0
|
|
1421 F872 loop:
|
|
1422 F872 88 dey
|
|
1423 F873 91 66 sta (toadr),y
|
|
1424 F875 D0 FB bne loop
|
|
1425 F877 C6 67 dec toadr+1
|
|
1426 F879 CA dex
|
|
1427 F87A 10 F6 bpl loop
|
|
1428
|
|
1429 ;reset coordinates and cursor (we're going to wipe the cursor)
|
|
1430 F87C 85 56 sta colcrs+1
|
|
1431 F87E 85 54 sta rowcrs
|
|
1432 F880 85 5D sta oldchr
|
|
1433
|
|
1434 ;always reset the logical line map
|
|
1435 F882 A6 57 ldx dindex
|
|
1436 F884 D0 02 bne is_graphic_screen
|
|
1437 F886 A5 52 lda lmargn
|
|
1438 F888 is_graphic_screen:
|
|
1439 F888 85 55 sta colcrs
|
|
1440
|
|
1441 ;always reset the logical line map and exit
|
|
1442 F88A 4C EB FD jmp ScreenResetLogicalLineMap
|
|
1443 .endp
|
|
1444
|
|
1445 ;==========================================================================
|
|
1446 ; Insert a physical line at the current location.
|
|
1447 ;
|
|
1448 ; Entry:
|
|
1449 ; ROWCRS = row before which to insert new line
|
|
1450 ; C = 0 if physical line only, C = 1 if should start new logical line
|
|
1451 ;
|
|
1452 ; Modified:
|
|
1453 ; HOLD1, ADRESS
|
|
1454 ;
|
|
1455 = F88E ScreenInsertLine = ScreenInsertPhysLine.use_c
|
|
1456 F88D .proc ScreenInsertPhysLine
|
|
1457 F88D 18 clc
|
|
1458 F88E use_c:
|
|
1459 ;save new logline flag
|
|
1460 F88E 08 php
|
|
1461
|
|
1462 ;compute addresses
|
|
1463 F88F AC BF 02 ldy botscr
|
|
1464 F892 88 dey
|
|
1465 F893 20 75 F9 jsr ScreenComputeToAddrX0
|
|
1466 F896 20 C5 FD jsr EditorNextLineAddr
|
|
1467
|
|
1468 ;copy lines
|
|
1469 F899 AE BF 02 ldx botscr
|
|
1470 F89C D0 09 bne line_loop_start
|
|
1471 F89E line_loop:
|
|
1472 F89E A0 27 ldy #39
|
|
1473 F8A0 char_loop:
|
|
1474 F8A0 B1 68 lda (frmadr),y
|
|
1475 F8A2 91 66 sta (toadr),y
|
|
1476 F8A4 88 dey
|
|
1477 F8A5 10 F9 bpl char_loop
|
|
1478 F8A7 line_loop_start:
|
|
1479 F8A7 A5 68 lda frmadr
|
|
1480 F8A9 85 66 sta toadr
|
|
1481 F8AB 38 sec
|
|
1482 F8AC E9 28 sbc #40
|
|
1483 F8AE 85 68 sta frmadr
|
|
1484 F8B0 A5 69 lda frmadr+1
|
|
1485 F8B2 85 67 sta toadr+1
|
|
1486 F8B4 E9 00 sbc #0
|
|
1487 F8B6 85 69 sta frmadr+1
|
|
1488
|
|
1489 F8B8 CA dex
|
|
1490 F8B9 E4 54 cpx rowcrs
|
|
1491 F8BB D0 E1 bne line_loop
|
|
1492
|
|
1493 F8BD no_copy:
|
|
1494 ;clear the current line
|
|
1495 F8BD A0 27 ldy #39
|
|
1496 F8BF A9 00 lda #0
|
|
1497 F8C1 clear_loop:
|
|
1498 F8C1 91 66 sta (toadr),y
|
|
1499 F8C3 88 dey
|
|
1500 F8C4 10 FB bpl clear_loop
|
|
1501
|
|
1502 ;insert bit into logical line mask
|
|
1503 F8C6 20 6F FD jsr EditorGetCurLogicalLineInfo
|
|
1504
|
|
1505 F8C9 28 plp
|
|
1506 F8CA B0 02 A9 00 scs:lda #0
|
|
1507 F8CE 85 51 sta hold1
|
|
1508
|
|
1509 F8D0 A9 00 lda #0
|
|
1510 F8D2 38 sec
|
|
1511 F8D3 FD C1 E4 sbc ReversedBitMasks,x ;-bit
|
|
1512 F8D6 0A asl
|
|
1513 F8D7 39 B2 02 and logmap,y
|
|
1514 F8DA 18 clc
|
|
1515 F8DB 79 B2 02 adc logmap,y
|
|
1516 F8DE 6A ror
|
|
1517 F8DF 05 51 ora hold1
|
|
1518 F8E1 99 B2 02 sta logmap,y
|
|
1519
|
|
1520 F8E4 88 dey
|
|
1521 F8E5 10 03 6E B3 02 spl:ror logmap+1
|
|
1522 F8EA 88 dey
|
|
1523 F8EB 10 03 6E B4 02 spl:ror logmap+2
|
|
1524 F8F0 60 rts
|
|
1525 .endp
|
|
1526
|
|
1527 ;==========================================================================
|
|
1528 ; Hide the screen cursor, if it is present.
|
|
1529 ;
|
|
1530 ; Modified:
|
|
1531 ; Y
|
|
1532 ;
|
|
1533 ; Preserved:
|
|
1534 ; A
|
|
1535 ;
|
|
1536 F8F1 .proc ScreenHideCursor
|
|
1537 ;erase the cursor
|
|
1538 F8F1 48 pha
|
|
1539 F8F2 A0 00 ldy #0
|
|
1540 F8F4 A5 5D lda oldchr
|
|
1541 F8F6 91 5E sta (oldadr),y
|
|
1542 F8F8 68 pla
|
|
1543 F8F9 no_cursor:
|
|
1544 F8F9 60 rts
|
|
1545 .endp
|
|
1546
|
|
1547 ;==========================================================================
|
|
1548 F8FA .proc ScreenCheckPosition
|
|
1549 ;Check for ROWCRS out of range. Note that for split screen modes we still
|
|
1550 ;check against the full height!
|
|
1551 F8FA AD BF 02 lda botscr
|
|
1552 F8FD A6 57 ldx dindex
|
|
1553 F8FF F0 06 beq rowcheck_gr0
|
|
1554 F901 BC 82 F2 ldy ScreenHeightShifts,x
|
|
1555 F904 B9 92 F2 lda ScreenHeights,y
|
|
1556 F907 rowcheck_gr0:
|
|
1557 ;while we know it's GR.0, clamp RMARGN to 39 (required for ARTILLERY.BAS)
|
|
1558 F907 A0 27 ldy #39
|
|
1559 F909 C4 53 cpy rmargn
|
|
1560 F90B B0 02 bcs rmargn_ok
|
|
1561 F90D 84 53 sty rmargn
|
|
1562 F90F rmargn_ok:
|
|
1563 F90F 18 clc
|
|
1564 F910 E5 54 sbc rowcrs
|
|
1565 F912 B0 0E bcs rowcheck_pass
|
|
1566 F914 invalid_position:
|
|
1567
|
|
1568 ;If the cursor is out of range, reset it within bounds.
|
|
1569 F914 A0 00 ldy #0
|
|
1570 F916 84 56 sty colcrs+1 ;X high = 0
|
|
1571 F918 8A txa
|
|
1572 F919 D0 02 A4 52 sne:ldy lmargn
|
|
1573 F91D 84 55 sty colcrs ;X low = X origin
|
|
1574
|
|
1575 F91F A0 8D ldy #CIOStatCursorRange
|
|
1576 F921 60 rts
|
|
1577
|
|
1578 F922 rowcheck_pass:
|
|
1579 ;check width
|
|
1580 F922 BC 97 F2 ldy ScreenPixelWidthIds,x
|
|
1581 F925 A5 55 lda colcrs
|
|
1582 F927 D9 A8 F2 cmp ScreenPixelWidthsLo,y
|
|
1583 F92A A5 56 lda colcrs+1
|
|
1584 F92C F9 AD F2 sbc ScreenPixelWidthsHi,y
|
|
1585 F92F B0 E3 bcs invalid_position
|
|
1586
|
|
1587 ;check for BREAK
|
|
1588 F931 A0 FF ldy #$ff
|
|
1589 F933 A5 11 lda brkkey
|
|
1590 F935 D0 04 bne no_break
|
|
1591 F937 84 11 sty brkkey
|
|
1592 F939 A0 7F ldy #CIOStatBreak-1
|
|
1593 F93B no_break:
|
|
1594 F93B C8 iny
|
|
1595 F93C 60 rts
|
|
1596 .endp
|
|
1597
|
|
1598 ;==========================================================================
|
|
1599 ; Swap between the main screen and the split screen.
|
|
1600 ;
|
|
1601 ; Conventionally, the main screen is left as the selected context when
|
|
1602 ; the display handler is not active.
|
|
1603 ;
|
|
1604 ; Inputs:
|
|
1605 ; C = 0 for main screen
|
|
1606 ; C = 1 for split screen
|
|
1607 ;
|
|
1608 ; Modified:
|
|
1609 ; X
|
|
1610 ;
|
|
1611 ; Preserved:
|
|
1612 ; A
|
|
1613 ;
|
|
1614 ;==========================================================================
|
|
1615 ; Swap in the text screen (main if gr.0, split otherwise).
|
|
1616 ;
|
|
1617 F93D .proc EditorSwapToText
|
|
1618 ;set C=0 (main) if gr.0, C=1 (split) otherwise
|
|
1619 F93D A0 17 ldy #23
|
|
1620 F93F CC BF 02 cpy botscr
|
|
1621
|
|
1622 = F942 .def :ScreenSwap = *
|
|
1623 ;check if the correct set is in place
|
|
1624 F942 48 pha
|
|
1625 F943 A9 00 lda #0
|
|
1626 F945 65 7B adc swpflg
|
|
1627 F947 F0 14 beq already_there
|
|
1628
|
|
1629 ;Nope, we need to swap. Conveniently, the data to be swapped
|
|
1630 ;is in a 12 byte block:
|
|
1631 ;
|
|
1632 ; ROWCRS ($0054) TXTROW ($0290)
|
|
1633 ; COLCRS ($0055) TXTCOL ($0291)
|
|
1634 ; DINDEX ($0057) TINDEX ($0293)
|
|
1635 ; SAVMSC ($0058) TXTMSC ($0294)
|
|
1636 ; OLDROW ($005A) TXTOLD ($0296)
|
|
1637 ; OLDCOL ($005B) TXTOLD ($0297)
|
|
1638 ; OLDCHR ($005D) TXTOLD ($0299)
|
|
1639 ; OLDADR ($005E) TXTOLD ($029A)
|
|
1640
|
|
1641 F949 A2 0B ldx #11
|
|
1642 F94B swap_loop:
|
|
1643 F94B B5 54 lda rowcrs,x
|
|
1644 F94D BC 90 02 ldy txtrow,x
|
|
1645 F950 94 54 sty rowcrs,x
|
|
1646 F952 9D 90 02 sta txtrow,x
|
|
1647 F955 CA dex
|
|
1648 F956 10 F3 bpl swap_loop
|
|
1649
|
|
1650 ;invert swap flag
|
|
1651 F958 8A txa
|
|
1652 F959 45 7B eor swpflg
|
|
1653 F95B 85 7B sta swpflg
|
|
1654
|
|
1655 F95D already_there:
|
|
1656 F95D 68 pla
|
|
1657 F95E 60 rts
|
|
1658 .endp
|
|
1659
|
|
1660 ;==========================================================================
|
|
1661 ; Compute character address.
|
|
1662 ;
|
|
1663 ; Entry:
|
|
1664 ; X = byte index
|
|
1665 ; Y = line index
|
|
1666 ;
|
|
1667 ; Exit:
|
|
1668 ; A:X = address
|
|
1669 ;
|
|
1670 ; Used:
|
|
1671 ; ADRESS
|
|
1672 ;
|
|
1673 F95F .proc ScreenComputeAddr
|
|
1674 F95F 20 7F F9 jsr ScreenComputeRangeSize
|
|
1675 F962 85 64 sta adress
|
|
1676 F964 8A txa
|
|
1677 F965 18 clc
|
|
1678 F966 65 64 adc adress ;row*10,20,40+col
|
|
1679 F968 90 02 E6 65 scc:inc adress+1
|
|
1680 F96C 18 clc
|
|
1681 F96D 65 58 adc savmsc
|
|
1682 F96F AA tax
|
|
1683 F970 A5 65 lda adress+1
|
|
1684 F972 65 59 adc savmsc+1
|
|
1685 F974 60 rts
|
|
1686 .endp
|
|
1687
|
|
1688 ;==========================================================================
|
|
1689 = F977 ScreenComputeToAddr = ScreenComputeToAddrX0.with_x
|
|
1690 F975 .proc ScreenComputeToAddrX0
|
|
1691 F975 A2 00 ldx #0
|
|
1692 F977 with_x:
|
|
1693 F977 20 5F F9 jsr ScreenComputeAddr
|
|
1694 F97A 86 66 stx toadr
|
|
1695 F97C 85 67 sta toadr+1
|
|
1696 F97E 60 rts
|
|
1697 .endp
|
|
1698
|
|
1699 ;==========================================================================
|
|
1700 ; Compute size, in bytes, of a series of lines.
|
|
1701 ;
|
|
1702 ; Entry:
|
|
1703 ; Y = line count
|
|
1704 ;
|
|
1705 ; Exit:
|
|
1706 ; ADRESS+1 High byte of size
|
|
1707 ; A Low byte of size
|
|
1708 ;
|
|
1709 ; Preserved:
|
|
1710 ; X
|
|
1711 ;
|
|
1712 ; Modified:
|
|
1713 ; Y
|
|
1714 ;
|
|
1715 F97F .proc ScreenComputeRangeSize
|
|
1716 F97F A9 00 85 65 mva #0 adress+1
|
|
1717 F983 84 64 sty adress
|
|
1718 F985 A4 57 ldy dindex
|
|
1719 F987 B9 97 F2 lda ScreenPixelWidthIds,y
|
|
1720 F98A 38 sec
|
|
1721 F98B F9 B2 F2 sbc ScreenEncodingTab,y
|
|
1722 F98E A8 tay
|
|
1723 F98F C8 iny
|
|
1724 F990 A5 64 lda adress
|
|
1725 F992 0A asl
|
|
1726 F993 26 65 rol adress+1 ;row*2
|
|
1727 F995 0A asl
|
|
1728 F996 26 65 rol adress+1 ;row*4
|
|
1729 F998 18 clc
|
|
1730 F999 65 64 adc adress ;row*5
|
|
1731 F99B 90 02 E6 65 scc:inc adress+1
|
|
1732 F99F shift_loop:
|
|
1733 F99F 0A asl
|
|
1734 F9A0 26 65 rol adress+1 ;row*10,20,40
|
|
1735 F9A2 88 dey
|
|
1736 F9A3 10 FA bpl shift_loop
|
|
1737 F9A5 60 rts
|
|
1738 .endp
|
|
1739
|
|
1740 ;==========================================================================
|
|
1741 ; Setup for pixel plot.
|
|
1742 ;
|
|
1743 ; Entry:
|
|
1744 ; OLDCOL, OLDROW = position
|
|
1745 ; DELTAC = left-justified pixel mask
|
|
1746 ;
|
|
1747 ; Exit:
|
|
1748 ; TOADR = screen row
|
|
1749 ; SHFAMT = byte offset within row
|
|
1750 ; BITMSK = shifted bit mask for pixel
|
|
1751 ;
|
|
1752 ; Modified:
|
|
1753 ; ADRESS
|
|
1754 ;
|
|
1755 = F9AB ScreenAlignPixel = ScreenSetupPlotPixel.rshift_mask
|
|
1756 F9A6 .proc ScreenSetupPlotPixel
|
|
1757 ;;##TRACE "Folded pixel = $%02X" db(hold1)
|
|
1758 F9A6 20 B5 F9 jsr ScreenSetupPixelAddr
|
|
1759
|
|
1760 ;preshift bit mask
|
|
1761 F9A9 A5 77 lda deltac
|
|
1762 F9AB rshift_mask:
|
|
1763 F9AB CA dex
|
|
1764 F9AC 30 04 bmi xmaskshift_done
|
|
1765 F9AE xmaskshift_loop:
|
|
1766 F9AE 4A lsr
|
|
1767 F9AF CA dex
|
|
1768 F9B0 10 FC bpl xmaskshift_loop
|
|
1769 F9B2 xmaskshift_done:
|
|
1770 F9B2 85 6E sta bitmsk
|
|
1771
|
|
1772 ;;##TRACE "Initial bitmasks = $%02X $%02X" db(bitmsk) db(dmask)
|
|
1773 F9B4 60 rts
|
|
1774 .endp
|
|
1775
|
|
1776 ;==========================================================================
|
|
1777 ; Setup for pixel addressing.
|
|
1778 ;
|
|
1779 ; Entry:
|
|
1780 ; COLCRS, ROWCRS = position (ScreenSetupPixelAddr)
|
|
1781 ; OLDCOL, OLDROW = position (ScreenSetupPixelAddrOld)
|
|
1782 ;
|
|
1783 ; Exit:
|
|
1784 ; TOADR = screen row
|
|
1785 ; SHFAMT = byte offset within row
|
|
1786 ; X = number of bits from left side of byte to left side of pixel
|
|
1787 ;
|
|
1788 F9B5 .proc ScreenSetupPixelAddr
|
|
1789 ;compute initial address
|
|
1790 F9B5 A4 5A ldy oldrow
|
|
1791 F9B7 20 75 F9 jsr ScreenComputeToAddrX0
|
|
1792
|
|
1793 ;;##TRACE "Initial row address = $%04X" dw(toadr)
|
|
1794
|
|
1795 ;compute initial byte offset
|
|
1796 F9BA A5 5C lda oldcol+1
|
|
1797 F9BC A6 5B ldx oldcol
|
|
1798 F9BE phase2:
|
|
1799 F9BE 6A ror
|
|
1800 F9BF 86 6F stx shfamt
|
|
1801 F9C1 A9 00 lda #0
|
|
1802 F9C3 A6 57 ldx dindex
|
|
1803 F9C5 BC B2 F2 ldy ScreenEncodingTab,x
|
|
1804 F9C8 F0 06 beq no_xshift
|
|
1805 F9CA xshift_loop:
|
|
1806 F9CA 66 6F ror shfamt
|
|
1807 F9CC 6A ror
|
|
1808 F9CD 88 dey
|
|
1809 F9CE D0 FA bne xshift_loop
|
|
1810 F9D0 no_xshift:
|
|
1811 F9D0 2A rol
|
|
1812 F9D1 2A rol
|
|
1813 F9D2 2A rol
|
|
1814 F9D3 2A rol
|
|
1815 F9D4 AA tax
|
|
1816
|
|
1817 ;;##TRACE "Initial row offset = $%02X" db(shfamt)
|
|
1818 F9D5 60 rts
|
|
1819 .endp
|
|
1820
|
|
1821 ;==========================================================================
|
|
1822 ; ScreenAdvancePosNonMode0
|
|
1823 ;
|
|
1824 F9D6 .proc ScreenAdvancePosNonMode0
|
|
1825 ;advance position
|
|
1826 F9D6 E6 55 inc colcrs
|
|
1827 F9D8 D0 02 E6 56 sne:inc colcrs+1
|
|
1828 F9DC A6 57 ldx dindex
|
|
1829 F9DE BC 97 F2 ldy ScreenPixelWidthIds,x
|
|
1830 F9E1 BE AD F2 ldx ScreenPixelWidthsHi,y
|
|
1831 F9E4 E4 56 cpx colcrs+1
|
|
1832 F9E6 D0 0F bne graphics_no_wrap
|
|
1833 F9E8 BE A8 F2 ldx ScreenPixelWidthsLo,y
|
|
1834 F9EB E4 55 cpx colcrs
|
|
1835 F9ED D0 08 bne graphics_no_wrap
|
|
1836
|
|
1837 F9EF graphics_eol:
|
|
1838 ;move to left side and then one row down -- note that this may
|
|
1839 ;push us into an invalid coordinate, which will result on an error
|
|
1840 ;on the next call if not corrected
|
|
1841 F9EF A0 00 ldy #0
|
|
1842 F9F1 84 55 sty colcrs
|
|
1843 F9F3 84 56 sty colcrs+1
|
|
1844 F9F5 E6 54 inc rowcrs
|
|
1845 F9F7 graphics_no_wrap:
|
|
1846 F9F7 A0 01 ldy #1
|
|
1847 F9F9 60 rts
|
|
1848 .endp
|
|
1849
|
|
1850 ;==========================================================================
|
|
1851 .if !_KERNEL_XLXE
|
|
1852 _SCREEN_TABLES_1
|
|
1853 .endif
|
|
270 F9FA icl 'editor.s'
|
|
Source: source/Shared/editor.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Editor Handler
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11 F9FA .proc EditorOpen
|
|
12 F9FA 20 EB FD jsr ScreenResetLogicalLineMap
|
|
13 F9FD 8E FE 02 stx dspflg ;!! relies on X=0 from ScreenResetLogicalLineMap
|
|
14 FA00 8E A2 02 stx escflg
|
|
15
|
|
16 ;we must force mode 0 here -- ACTION calls this with $0C in AUX2 and
|
|
17 ;expects mode 0 to be set
|
|
18 FA03 4C F2 F3 jmp ScreenOpenMode0
|
|
19 .endp
|
|
20
|
|
21 ;==========================================================================
|
|
22 = FE28 EditorClose = ScreenClose
|
|
23
|
|
24 ;==========================================================================
|
|
25 ;
|
|
26 ; === Forced read mode ===
|
|
27 ;
|
|
28 ; If bit 0 if AUX1 is set on the IOCB, it means to read in forced read
|
|
29 ; mode. In forced read mode, no keyboard input is fetched and instead
|
|
30 ; line read immediately commences, as if ENTER were pressed.
|
|
31 ;
|
|
32 ; Note that since AUX1 is tested on the IOCB used, it is possible to have
|
|
33 ; E: open on more than one IOCB with different forced read modes.
|
|
34 ;
|
|
35 FA06 .proc EditorGetByte
|
|
36 ;check if we have anything left in the current line
|
|
37 FA06 A5 6B lda bufcnt
|
|
38 FA08 D0 06 bne have_line
|
|
39
|
|
40 ;nope, fetch a line
|
|
41 FA0A 20 26 FA jsr EditorGetLine
|
|
42 FA0D 10 01 bpl have_line
|
|
43 FA0F 60 rts
|
|
44
|
|
45 FA10 have_line:
|
|
46 ;swap to text context
|
|
47 FA10 20 3D F9 jsr EditorSwapToText
|
|
48
|
|
49 ;subtract off a char
|
|
50 FA13 C6 6B dec bufcnt
|
|
51
|
|
52 ;check if we're at the EOL
|
|
53 FA15 D0 09 bne have_char
|
|
54
|
|
55 ;yes, we're at the EOL -- print it and return it (this will re-enable
|
|
56 ;the cursor, too)
|
|
57 FA17 A9 9B lda #$9b
|
|
58 FA19 20 12 F6 jsr ScreenPutByte
|
|
59
|
|
60 FA1C A9 9B lda #$9b
|
|
61 FA1E D0 03 bne done
|
|
62
|
|
63 FA20 have_char:
|
|
64 ;read a char from the screen
|
|
65 FA20 20 D2 F5 jsr ScreenGetByte
|
|
66 FA23 done:
|
|
67 FA23 4C 9E FD jmp EditorSwapToScreen
|
|
68 .endp
|
|
69
|
|
70 ;==========================================================================
|
|
71 ; This behavior is quite complex:
|
|
72 ; - The editor remembers the cursor position within the initial logical
|
|
73 ; line. Only contents beyond the initial position are returned. This
|
|
74 ; is true even if the cursor is moved out of the logical line and back
|
|
75 ; in again.
|
|
76 ; - Margins are not included.
|
|
77 ; - Trailing spaces at the end of a logical line are not returned even
|
|
78 ; if the cursor is after them.
|
|
79 ; - If the cursor is moved to another logical line, that logical line is
|
|
80 ; read instead. There is no memory of the line start for previous
|
|
81 ; logical lines, so if there was a prompt on that line it will be
|
|
82 ; picked up too.
|
|
83 ; - If the logical line length is exceeded, a beep sounds near the end
|
|
84 ; and after three lines (120ch) the logical line is terminated and a
|
|
85 ; new logical line is started. However, the previous logical line that
|
|
86 ; was overflowed is still returned. This still happens if the new
|
|
87 ; logical line extends to more than one physical line or even if
|
|
88 ; itself overflows (!). If the physical line is changed with up/down,
|
|
89 ; this memory is lost, but left/right don't do this.
|
|
90 ; - If a logical line extends exactly to the end of a physical line, an
|
|
91 ; extra blank line is printed on EOL.
|
|
92 ; - If a logical line extends exactly to the end of the screen, a cursor
|
|
93 ; out of bounds error results. (We currently do not implement this...
|
|
94 ; feature.)
|
|
95 ;
|
|
96 ; === The BUFSTR variable ===
|
|
97 ;
|
|
98 ; The BUFSTR variable is critical to the way that the get line algorithm
|
|
99 ; works. It actually consists of two bytes, the row followed by the column
|
|
100 ; of the origin of the line to be read. This is updated whenever a read
|
|
101 ; request arrives that starts a new line or whenever the cursor is moved
|
|
102 ; to a different logical line. This is how the screen editor knows to
|
|
103 ; read at the end of a prompt or from a different line that you have moved
|
|
104 ; to, and how it tracks that when scrolling occurs. It does not, however,
|
|
105 ; get updated when regular characters are typed, even when spilling to a
|
|
106 ; new logical line.
|
|
107 ;
|
|
108 ; === BUFCNT ===
|
|
109 ;
|
|
110 ; BUFCNT contains the number of characters left to return before we have
|
|
111 ; to get a new line: $00 means we will wait for keys, $01 is the EOL, and
|
|
112 ; >$01 returns a typed character. We need to follow this convention or
|
|
113 ; else the combination of S_VBXE.SYS + CON.SYS /E from SDX 4.46 acts
|
|
114 ; strangely on launch.
|
|
115 ;
|
|
116 FA26 .proc EditorGetLine
|
|
117 = 006D _start_x equ bufstr+1
|
|
118 = 006C _start_y equ bufstr
|
|
119
|
|
120 ;Set line buffer start to current position (NOT the start of the logical
|
|
121 ;line -- this is a special case).
|
|
122 FA26 20 3D F9 jsr EditorSwapToText
|
|
123 FA29 A5 55 85 6D mva colcrs _start_x
|
|
124 FA2D A5 54 85 6C mva rowcrs _start_y
|
|
125 FA31 20 9E FD jsr EditorSwapToScreen
|
|
126
|
|
127 ;check if forced read is enabled on the IOCB -- if so, assume we've gotten
|
|
128 ;an EOL
|
|
129 FA34 A5 2A lda icax1z
|
|
130 FA36 4A lsr
|
|
131 FA37 B0 25 bcs do_eol
|
|
132
|
|
133 FA39 read_loop:
|
|
134 ;get a character
|
|
135 FA39 20 69 FE jsr KeyboardGetByte
|
|
136 FA3C 10 01 bpl read_ok
|
|
137 FA3E read_error:
|
|
138 FA3E 60 rts
|
|
139
|
|
140 FA3F read_ok:
|
|
141 FA3F C9 9B cmp #$9b
|
|
142 FA41 F0 1D beq is_eol
|
|
143
|
|
144 ;echo the character
|
|
145 FA43 20 B8 FA jsr EditorPutByte
|
|
146 FA46 30 F6 bmi read_error
|
|
147
|
|
148 ;check if we've hit the warning point (logical pos 113)
|
|
149 FA48 A5 55 lda colcrs
|
|
150 FA4A C9 21 cmp #33
|
|
151 FA4C D0 EB bne read_loop
|
|
152
|
|
153 ;convert current row to logical start row
|
|
154 FA4E 20 85 FD jsr EditorGetCurLogicalRow
|
|
155
|
|
156 ;check if we're on the third row
|
|
157 FA51 18 clc
|
|
158 FA52 69 02 adc #2
|
|
159 FA54 C5 54 cmp rowcrs
|
|
160
|
|
161 ;if so, sound the bell
|
|
162 FA56 D0 E1 bne read_loop
|
|
163 FA58 20 97 FD jsr EditorBell
|
|
164
|
|
165 FA5B 4C 39 FA jmp read_loop
|
|
166
|
|
167 FA5E do_eol:
|
|
168 FA5E A9 9B lda #$9b
|
|
169 FA60 is_eol:
|
|
170 ;echo the character
|
|
171 FA60 20 B8 FA jsr EditorPutByte
|
|
172 FA63 30 D9 bmi read_error
|
|
173
|
|
174 ;swap to text screen context
|
|
175 FA65 20 3D F9 jsr EditorSwapToText
|
|
176
|
|
177 ;hide the cursor so we can scan text properly
|
|
178 FA68 20 F1 F8 jsr ScreenHideCursor
|
|
179
|
|
180 ;compute address
|
|
181 FA6B A2 00 ldx #0
|
|
182 FA6D 86 63 stx logcol
|
|
183 FA6F A4 6C ldy _start_y
|
|
184 FA71 84 54 sty rowcrs
|
|
185 FA73 20 77 F9 jsr ScreenComputeToAddr
|
|
186
|
|
187 FA76 A4 6D ldy _start_x
|
|
188 FA78 char_loop:
|
|
189 FA78 E6 63 inc logcol
|
|
190 FA7A B1 66 lda (toadr),y
|
|
191 FA7C F0 04 beq blank
|
|
192 FA7E A5 63 85 6B mva logcol bufcnt
|
|
193 FA82 blank:
|
|
194 FA82 C4 53 cpy rmargn
|
|
195 FA84 C8 iny
|
|
196 FA85 90 F1 bcc char_loop
|
|
197 FA87 20 C5 FD jsr EditorNextLineAddr
|
|
198
|
|
199 ;check if we're at the bottom of the screen
|
|
200 FA8A E6 54 inc rowcrs
|
|
201 FA8C A5 54 lda rowcrs
|
|
202 FA8E CD BF 02 cmp botscr
|
|
203 FA91 B0 0A bcs scan_scroll
|
|
204
|
|
205 ;check if we're at the end of the logical line
|
|
206 FA93 20 7E FD jsr EditorTestLogicalLineBit
|
|
207 FA96 D0 08 bne scan_done
|
|
208
|
|
209 FA98 A4 52 ldy lmargn
|
|
210 FA9A 4C 78 FA jmp char_loop
|
|
211
|
|
212 FA9D scan_scroll:
|
|
213 ;we're below the screen... need to scroll up
|
|
214 FA9D 20 CC FC jsr EditorDeleteLine0
|
|
215
|
|
216 FAA0 scan_done:
|
|
217 ;adjust BUFCNT so it is the number of chars to read (scanned + EOL)
|
|
218 FAA0 E6 6B inc bufcnt
|
|
219
|
|
220 ;mark this as the start of a new logical line, trimming off any extra
|
|
221 ;blank lines
|
|
222 FAA2 A5 54 lda rowcrs
|
|
223 FAA4 20 71 FD jsr EditorGetLogicalLineInfo
|
|
224 FAA7 19 B2 02 ora logmap,y
|
|
225 FAAA 99 B2 02 sta logmap,y
|
|
226
|
|
227 ;reset cursor to line start, but leave the cursor off
|
|
228 FAAD A6 6D 86 55 mvx _start_x colcrs
|
|
229 FAB1 A4 6C 84 54 mvy _start_y rowcrs
|
|
230
|
|
231 ;swap back to main context and exit successfully
|
|
232 FAB5 4C 9C FD jmp EditorSwapToScreen_Y1
|
|
233 .endp
|
|
234
|
|
235 ;==========================================================================
|
|
236 ; This routine must NOT write BUFADR -- doing so breaks the DLT flasher.
|
|
237 ;
|
|
238 ; Behavior notes:
|
|
239 ; - Ctrl+1 (suspend display) does not affect control codes handled only
|
|
240 ; by E:. In particular, EOL, move up/down/left/right, ESC, insert, and
|
|
241 ; delete are not affected by it. CLEAR on the other hand, is, because
|
|
242 ; it's handled by S:.
|
|
243 ;
|
|
244 FAB8 .proc EditorPutByte
|
|
245 ;open the text screen if it is not open already
|
|
246 FAB8 A4 57 ldy dindex
|
|
247 FABA F0 0C beq screenok
|
|
248 FABC AC BF 02 ldy botscr
|
|
249 FABF C0 04 cpy #4
|
|
250 FAC1 F0 05 beq screenok
|
|
251
|
|
252 FAC3 48 pha
|
|
253 FAC4 20 EE F3 jsr ScreenOpenGr0
|
|
254 FAC7 68 pla
|
|
255 FAC8 screenok:
|
|
256
|
|
257 ;swap to text context
|
|
258 FAC8 20 3D F9 jsr EditorSwapToText
|
|
259
|
|
260 ;hide the cursor -- this must be done before we suspend display on
|
|
261 ;Ctrl+1.
|
|
262 FACB 20 F1 F8 jsr ScreenHideCursor
|
|
263
|
|
264 ;save off character to free up acc
|
|
265 FACE A8 tay
|
|
266
|
|
267 ;Check if [esc] is active
|
|
268 ;
|
|
269 ;Note that the ASL trick relies on ESCFLG being $80 when set; this
|
|
270 ;is in fact guaranteed by the spec in the OS Manual, Appendix L, B26.
|
|
271 ;
|
|
272 FACF 0E A2 02 asl escflg ;test and clear escape flag
|
|
273 FAD2 B0 1E bcs not_special
|
|
274
|
|
275 ;check if this might be a special character
|
|
276 FAD4 29 1F and #$1f
|
|
277 FAD6 C9 1B cmp #$1b
|
|
278 FAD8 90 18 bcc not_special
|
|
279
|
|
280 ;might be special, but not EOL... search the special char table
|
|
281 FADA A2 0E ldx #special_code_tab_end-special_code_tab-1
|
|
282 FADC 98 tya
|
|
283 FADD 20 B7 FC jsr EditorIsSpecial
|
|
284 FAE0 D0 10 bne not_special
|
|
285
|
|
286 FAE2 special_found:
|
|
287 ;check if display of control codes is desired; if so, we need to ignore this
|
|
288 FAE2 AD FE 02 lda dspflg
|
|
289 FAE5 D0 0B bne not_special
|
|
290
|
|
291 ;jump to routine
|
|
292 FAE7 20 63 FC jsr dispatch
|
|
293 FAEA 20 C0 FC jsr EditorRecomputeCursorAddr
|
|
294 FAED 20 17 FE jsr ScreenShowCursorAndXitOK
|
|
295 FAF0 10 06 bpl xit2 ;!! - unconditional jump
|
|
296
|
|
297 FAF2 not_special:
|
|
298 ;ok, just put the char to the screen
|
|
299 FAF2 8C FB 02 sty atachr
|
|
300 FAF5 20 2A F6 jsr ScreenPutByte.not_clear
|
|
301 FAF8 xit2:
|
|
302 ;swap back to main context and exit
|
|
303 FAF8 4C 9E FD jmp EditorSwapToScreen
|
|
304
|
|
305 ;---------------
|
|
306 FAFB special_code_tab:
|
|
307 FAFB 1B dta $1b
|
|
308 FAFC 1C dta $1c
|
|
309 FAFD 1D dta $1d
|
|
310 FAFE 1E dta $1e
|
|
311 FAFF 1F dta $1f
|
|
312 FB00 7D dta $7d
|
|
313 FB01 7E dta $7e
|
|
314 FB02 7F dta $7f
|
|
315 FB03 9C dta $9c
|
|
316 FB04 9D dta $9d
|
|
317 FB05 9E dta $9e
|
|
318 FB06 9F dta $9f
|
|
319 FB07 FD dta $fd
|
|
320 FB08 FE dta $fe
|
|
321 FB09 FF dta $ff
|
|
322 FB0A special_code_tab_end:
|
|
323 FB0A 9B dta $9b ;these are only for the K: check
|
|
324 FB0B 7C dta $7c
|
|
325 FB0C special_code_tab_end_2:
|
|
326
|
|
327 ;----------------
|
|
328
|
|
329 FB0C special_dispatch_lo_tab:
|
|
330 FB0C 1A dta <(special_escape-1)
|
|
331 FB0D 23 dta <(special_up-1)
|
|
332 FB0E 2D dta <(special_down-1)
|
|
333 FB0F C1 dta <(special_left-1)
|
|
334 FB10 CE dta <(special_right-1)
|
|
335 FB11 20 dta <(special_clear-1)
|
|
336 FB12 48 dta <(special_backspace-1)
|
|
337 FB13 87 dta <(special_tab-1)
|
|
338 FB14 D7 dta <(special_delete_line-1)
|
|
339 FB15 DD dta <(special_insert_line-1)
|
|
340 FB16 74 dta <(special_clear_tab-1)
|
|
341 FB17 6C dta <(special_set_tab-1)
|
|
342 FB18 69 dta <(special_bell-1)
|
|
343 FB19 E4 dta <(special_delete_char-1)
|
|
344 FB1A F0 dta <(special_insert_char-1)
|
|
345
|
|
346 .if [((special_escape-1)^(special_insert_char-1))&$ff00]
|
|
347 .error 'Special character routines cross a page boundary: ',special_escape,'-',special_insert_char
|
|
348 .endif
|
|
349
|
|
350 ;---------------
|
|
351 FB1B special_escape:
|
|
352 FB1B A9 80 8D A2 02 mva #$80 escflg
|
|
353 FB20 60 rts
|
|
354
|
|
355 ;---------------
|
|
356 FB21 special_clear:
|
|
357 FB21 4C 4A F8 jmp ScreenClear
|
|
358
|
|
359 ;---------------
|
|
360 FB24 special_up:
|
|
361 FB24 A6 54 ldx rowcrs
|
|
362 FB26 D0 03 bne isup2
|
|
363 FB28 AE BF 02 ldx botscr
|
|
364 FB2B isup2:
|
|
365 FB2B CA dex
|
|
366 FB2C 10 0A bpl vmoveexit
|
|
367
|
|
368 ;---------------
|
|
369 FB2E special_down:
|
|
370 FB2E A6 54 ldx rowcrs
|
|
371 FB30 E8 inx
|
|
372 FB31 EC BF 02 cpx botscr
|
|
373 FB34 90 02 A2 00 scc:ldx #0
|
|
374
|
|
375 FB38 vmoveexit:
|
|
376 FB38 86 54 stx rowcrs
|
|
377
|
|
378 ;check if we have moved into a different logical line -- if so,
|
|
379 ;we need to reset the read row
|
|
380 FB3A 8A txa
|
|
381 FB3B 20 87 FD jsr EditorPhysToLogicalRow
|
|
382 FB3E C5 6C cmp bufstr
|
|
383 FB40 F0 06 beq moveexit
|
|
384
|
|
385 ;we switched rows -- reset read row
|
|
386 FB42 85 6C sta bufstr
|
|
387 FB44 A5 52 85 6D mva lmargn bufstr+1
|
|
388
|
|
389 FB48 moveexit:
|
|
390 FB48 60 rts
|
|
391
|
|
392 ;---------------
|
|
393 FB49 special_backspace:
|
|
394 ;check if we are at the left column
|
|
395 FB49 A5 52 lda lmargn
|
|
396 FB4B C5 55 cmp colcrs
|
|
397 FB4D B0 0B bcs sbks_wrap
|
|
398
|
|
399 ;nope, we can just back up
|
|
400 FB4F C6 55 dec colcrs
|
|
401
|
|
402 ;recompute pos and clear character
|
|
403 FB51 sbks_recomp:
|
|
404 FB51 20 C0 FC jsr EditorRecomputeCursorAddr
|
|
405 FB54 A0 00 ldy #0
|
|
406 FB56 98 tya
|
|
407 FB57 91 5E sta (oldadr),y
|
|
408 FB59 sbks_xit:
|
|
409 FB59 60 rts
|
|
410
|
|
411 FB5A sbks_wrap:
|
|
412 ;check if we're at the start of the logical line
|
|
413 FB5A A5 54 lda rowcrs
|
|
414 FB5C 20 7E FD jsr EditorTestLogicalLineBit
|
|
415 FB5F D0 F8 bne sbks_xit
|
|
416
|
|
417 ;no, so we need to wrap to the right column of the prev line...
|
|
418 FB61 C6 54 dec rowcrs
|
|
419 FB63 A5 53 lda rmargn
|
|
420 FB65 85 55 sta colcrs
|
|
421
|
|
422 ;recompute everything and exit
|
|
423 FB67 4C 51 FB jmp sbks_recomp
|
|
424
|
|
425 ;----------------
|
|
426 FB6A special_bell:
|
|
427 FB6A 4C 97 FD jmp EditorBell
|
|
428
|
|
429 ;----------------
|
|
430 FB6D special_set_tab:
|
|
431 FB6D 20 81 FB jsr special_common_tab
|
|
432 FB70 1D A3 02 ora tabmap,x
|
|
433 FB73 D0 08 bne special_common_exit_tab
|
|
434
|
|
435 FB75 special_clear_tab:
|
|
436 FB75 20 81 FB jsr special_common_tab
|
|
437 FB78 49 FF eor #$ff
|
|
438 FB7A 3D A3 02 and tabmap,x
|
|
439 FB7D special_common_exit_tab:
|
|
440 FB7D 9D A3 02 sta tabmap,x
|
|
441 FB80 60 rts
|
|
442
|
|
443 FB81 special_common_tab:
|
|
444 FB81 20 A7 FD jsr EditorGetLogicalColumn
|
|
445 FB84 A8 tay
|
|
446 FB85 4C B6 FD jmp EditorSetupTabIndex
|
|
447
|
|
448 ;--------------------------------------------------------------------------
|
|
449 ; Tab behavior:
|
|
450 ; - Moves cursor to the next tab position within the logical line.
|
|
451 ; - If there are no more tabs, moves cursor to beginning of next line.
|
|
452 ; This may cause a scroll.
|
|
453 ; - Tab does NOT adjust the read row.
|
|
454 ;
|
|
455 FB88 special_tab:
|
|
456 FB88 20 A7 FD jsr EditorGetLogicalColumn
|
|
457 FB8B A8 tay
|
|
458 FB8C 8A txa
|
|
459 FB8D 38 sec
|
|
460 FB8E 65 54 adc rowcrs
|
|
461 FB90 85 54 sta rowcrs
|
|
462
|
|
463 ;scan forward until we find the next bit set, or we hit position 120
|
|
464 FB92 tab_scan_loop:
|
|
465 FB92 C8 iny
|
|
466 FB93 C0 78 cpy #120
|
|
467 FB95 B0 08 bcs tab_found
|
|
468 FB97 20 B6 FD jsr EditorSetupTabIndex
|
|
469 FB9A 3D A3 02 and tabmap,x
|
|
470 FB9D F0 F3 beq tab_scan_loop
|
|
471 FB9F tab_found:
|
|
472 FB9F 84 55 sty colcrs
|
|
473 FBA1 tab_adjust_row:
|
|
474 FBA1 A5 55 lda colcrs
|
|
475 FBA3 38 sec
|
|
476 FBA4 E9 28 sbc #40 ;subtract a row worth of columns
|
|
477 FBA6 90 19 bcc tab_adjust_done ;exit if <40
|
|
478 FBA8 85 55 sta colcrs
|
|
479 FBAA E6 54 inc rowcrs ;next row
|
|
480 FBAC A5 54 lda rowcrs ;
|
|
481 FBAE CD BF 02 cmp botscr ;check if we're below the screen
|
|
482 FBB1 B0 07 bcs tab_adjust_scroll ;if so, do a scroll
|
|
483 FBB3 20 7E FD jsr EditorTestLogicalLineBit ;check if we're on a new log line
|
|
484 FBB6 F0 E9 beq tab_adjust_row ;if not, keep adjusting
|
|
485 FBB8 10 03 bpl tab_adjust_left ;position at beginning of new line
|
|
486
|
|
487 FBBA tab_adjust_scroll:
|
|
488 FBBA 20 CC FC jsr EditorDeleteLine0
|
|
489 FBBD tab_adjust_left:
|
|
490 FBBD hmove_to_lmargn:
|
|
491 ;move to left margin
|
|
492 FBBD A6 52 ldx lmargn
|
|
493 FBBF hmove_to_x:
|
|
494 FBBF 86 55 stx colcrs
|
|
495 FBC1 tab_adjust_done:
|
|
496 FBC1 60 rts
|
|
497
|
|
498 ;--------------------------------------------------------------------------
|
|
499 FBC2 special_left:
|
|
500 FBC2 A6 55 ldx colcrs
|
|
501 FBC4 F0 05 beq slft_to_right
|
|
502 FBC6 CA dex
|
|
503 FBC7 E4 52 cpx lmargn
|
|
504 FBC9 B0 F4 bcs hmove_to_x
|
|
505
|
|
506 ;move to right margin
|
|
507 FBCB slft_to_right:
|
|
508 FBCB A6 53 ldx rmargn
|
|
509 FBCD 90 F0 bcc hmove_to_x
|
|
510
|
|
511 ;--------------------------------------------------------------------------
|
|
512 FBCF special_right:
|
|
513 FBCF A6 55 ldx colcrs
|
|
514 FBD1 E4 53 cpx rmargn
|
|
515 FBD3 B0 E8 bcs hmove_to_lmargn
|
|
516
|
|
517 ;right one char
|
|
518 FBD5 E6 55 inc colcrs
|
|
519 FBD7 60 rts
|
|
520
|
|
521 ;--------------------------------------------------------------------------
|
|
522 ; Delete line behavior:
|
|
523 ; - The entire logical line that the cursor is in is deleted.
|
|
524 ; - The cursor is positioned at the beginning of the next logical line.
|
|
525 ;
|
|
526 FBD8 special_delete_line:
|
|
527 ;delete current logical line
|
|
528 FBD8 20 85 FD jsr EditorGetCurLogicalRow
|
|
529 FBDB 4C CE FC jmp EditorDeleteLine
|
|
530
|
|
531 ;----------------
|
|
532 FBDE special_insert_line:
|
|
533 ;insert a new logical line at this point; note that this may split
|
|
534 ;the current line
|
|
535 FBDE 38 sec
|
|
536 FBDF 20 8E F8 jsr ScreenInsertLine
|
|
537 FBE2 4C BD FB jmp tab_adjust_left
|
|
538
|
|
539 ;--------------------------------------------------------------------------
|
|
540 ; Delete character behavior:
|
|
541 ; - Erases the current character and drags in characters from the
|
|
542 ; remainder of the logical line, excluding the margins.
|
|
543 ; - If the last physical line is blank and not the only physical line in
|
|
544 ; the logical line, it is deleted and the logical line is shortened.
|
|
545 ; Only one line is removed even if the last two lines are blank. The
|
|
546 ; cursor does not move when this happens and may be shifted into the
|
|
547 ; next logical line. This also does not change the input line!
|
|
548 ;
|
|
549 FBE5 special_delete_char:
|
|
550 ;compute base address of current row (not char)
|
|
551 FBE5 A4 54 ldy rowcrs
|
|
552 FBE7 84 51 sty hold1
|
|
553 FBE9 20 75 F9 jsr ScreenComputeToAddrX0
|
|
554
|
|
555 ;begin shifting in the first column at the current pos
|
|
556 FBEC A4 55 ldy colcrs
|
|
557
|
|
558 ;delete chars to end
|
|
559 FBEE 4C 7C FC jmp delete_shift_loop_entry
|
|
560
|
|
561 ;--------------------------------------------------------------------------
|
|
562 ; Insert character behavior:
|
|
563 ; - Inserts a blank at the current position and shifts characters forward
|
|
564 ; within the margins.
|
|
565 ; - If the character shifted out of the end of the logical line is non-
|
|
566 ; blank, the logical line will be extended if possible. This can cause
|
|
567 ; a scroll. If the logical line is already three rows, the last
|
|
568 ; character is lost.
|
|
569 ;
|
|
570 FBF1 special_insert_char:
|
|
571 ;get logical line start
|
|
572 FBF1 20 85 FD jsr EditorGetCurLogicalRow
|
|
573
|
|
574 ;compute line at which we cannot add another physical line
|
|
575 FBF4 18 69 03 add #3
|
|
576 FBF7 85 76 sta deltar
|
|
577
|
|
578 ;compute address of row
|
|
579 FBF9 A4 54 ldy rowcrs
|
|
580 FBFB 84 51 sty hold1
|
|
581 FBFD 20 75 F9 jsr ScreenComputeToAddrX0
|
|
582
|
|
583 FC00 A4 55 ldy colcrs ;end shift at current column
|
|
584 FC02 A2 00 ldx #0 ;insert blank character at start
|
|
585 FC04 F0 04 beq insert_line_loop_entry
|
|
586
|
|
587 FC06 insert_line_loop:
|
|
588 FC06 A4 52 ldy lmargn ;end shift at left column
|
|
589 FC08 A6 50 ldx tmpchr ;character to shift in (from last line)
|
|
590
|
|
591 FC0A insert_line_loop_entry:
|
|
592 FC0A 84 65 sty adress+1 ;stash shift origin
|
|
593 FC0C A4 53 ldy rmargn ;begin shift at right column
|
|
594 FC0E B1 66 lda (toadr),y ;get character being shifted out
|
|
595 FC10 85 50 sta tmpchr ;save it off to later shift in on the next row
|
|
596 FC12 insert_shift_loop:
|
|
597 FC12 88 dey
|
|
598 FC13 B1 66 lda (toadr),y
|
|
599 FC15 C8 iny
|
|
600 FC16 91 66 sta (toadr),y
|
|
601 FC18 88 dey
|
|
602 FC19 C4 65 cpy adress+1
|
|
603 FC1B D0 F5 bne insert_shift_loop
|
|
604
|
|
605 ;put character shifted out from previous line into beginning of this one
|
|
606 FC1D 8A txa
|
|
607 FC1E 91 66 sta (toadr),y
|
|
608
|
|
609 ;next row
|
|
610 FC20 E6 51 inc hold1
|
|
611
|
|
612 FC22 20 C5 FD jsr EditorNextLineAddr
|
|
613
|
|
614 ;check if we're at the end of the logical line
|
|
615 FC25 A5 51 lda hold1
|
|
616 FC27 CD BF 02 cmp botscr
|
|
617 FC2A B0 05 bcs insert_crossed_lline
|
|
618 FC2C 20 7E FD jsr EditorTestLogicalLineBit
|
|
619 FC2F F0 D5 beq insert_line_loop
|
|
620 FC31 insert_crossed_lline:
|
|
621
|
|
622 ;check if we shifted out a non-blank character
|
|
623 FC31 A5 50 lda tmpchr
|
|
624 FC33 F0 2D beq insert_done
|
|
625
|
|
626 ;save current row
|
|
627 FC35 A5 54 lda rowcrs
|
|
628 FC37 48 pha
|
|
629
|
|
630 ;check if the logical line is already 3 rows -- if so, we cannot extend and
|
|
631 ;the last char goes into the bit bucket, but we still must scroll (!)
|
|
632 FC38 A6 51 ldx hold1
|
|
633 FC3A E4 76 cpx deltar
|
|
634 FC3C 08 php
|
|
635
|
|
636 ;move to the bottom line +1; we use ROWCRS so it stays updated with the scrolling
|
|
637 FC3D 86 54 stx rowcrs
|
|
638
|
|
639 ;check if we are at the bottom of the screen; if so we must scroll
|
|
640 FC3F A9 00 lda #0
|
|
641 FC41 85 76 sta deltar
|
|
642
|
|
643 FC43 EC BF 02 cpx botscr
|
|
644 FC46 90 03 bcc insert_no_scroll
|
|
645
|
|
646 ;scroll the screen
|
|
647 FC48 20 CC FC jsr EditorDeleteLine0
|
|
648
|
|
649 FC4B insert_no_scroll:
|
|
650 ;if we can't extend, we are done
|
|
651 FC4B 28 plp
|
|
652 FC4C B0 0E bcs insert_cant_extend
|
|
653
|
|
654 ;just insert a blank line at the end of this logical row to extend it
|
|
655 FC4E 20 8D F8 jsr ScreenInsertPhysLine
|
|
656
|
|
657 ;restore shifted character and put it in place
|
|
658 FC51 A4 54 ldy rowcrs
|
|
659 FC53 20 75 F9 jsr ScreenComputeToAddrX0
|
|
660 FC56 A5 50 lda tmpchr
|
|
661 FC58 A4 52 ldy lmargn
|
|
662 FC5A 91 66 sta (toadr),y
|
|
663 FC5C insert_cant_extend:
|
|
664
|
|
665 ;restore cursor row, adjusting for any scroll
|
|
666 FC5C 68 pla
|
|
667 FC5D 38 sec
|
|
668 FC5E E5 76 sbc deltar
|
|
669 FC60 85 54 sta rowcrs
|
|
670
|
|
671 FC62 insert_done:
|
|
672 FC62 60 rts
|
|
673
|
|
674 ;---------------------------------
|
|
675 FC63 dispatch:
|
|
676 FC63 A9 FB lda #>special_escape
|
|
677 FC65 48 pha
|
|
678 FC66 BD 0C FB lda special_dispatch_lo_tab,x
|
|
679 FC69 48 pha
|
|
680 FC6A 60 rts
|
|
681
|
|
682 ;---------------------------------
|
|
683 FC6B delete_line_loop:
|
|
684 ;copy first character into right margin of previous row
|
|
685 FC6B A4 52 ldy lmargn
|
|
686 FC6D B1 66 lda (toadr),y
|
|
687 FC6F A4 53 ldy rmargn
|
|
688 FC71 91 68 sta (frmadr),y
|
|
689
|
|
690 ;start shifting new row at left margin
|
|
691 FC73 A4 52 ldy lmargn
|
|
692 FC75 delete_shift_loop:
|
|
693 FC75 C8 iny
|
|
694 FC76 B1 66 lda (toadr),y
|
|
695 FC78 88 dey
|
|
696 FC79 91 66 sta (toadr),y
|
|
697 FC7B C8 iny
|
|
698 FC7C delete_shift_loop_entry:
|
|
699 FC7C C4 53 cpy rmargn
|
|
700 FC7E D0 F5 bne delete_shift_loop
|
|
701
|
|
702 ;next line
|
|
703 FC80 20 C5 FD jsr EditorNextLineAddr
|
|
704
|
|
705 ;check if the next row is a logical line start
|
|
706 FC83 A6 51 ldx hold1
|
|
707 FC85 E8 inx
|
|
708 FC86 EC BF 02 cpx botscr
|
|
709 FC89 B0 08 bcs delete_stop_shifting
|
|
710 FC8B 86 51 stx hold1
|
|
711 FC8D 8A txa
|
|
712 FC8E 20 7E FD jsr EditorTestLogicalLineBit
|
|
713
|
|
714 ;keep going if not
|
|
715 FC91 F0 D8 beq delete_line_loop
|
|
716
|
|
717 FC93 delete_stop_shifting:
|
|
718 ;blank the last character of the last line
|
|
719 FC93 A4 53 ldy rmargn
|
|
720 FC95 A9 00 lda #0
|
|
721 FC97 91 68 sta (frmadr),y
|
|
722
|
|
723 ;check if the last line is blank
|
|
724 FC99 delete_blank_test_loop:
|
|
725 FC99 B1 68 lda (frmadr),y
|
|
726 FC9B D0 19 bne delete_not_blank
|
|
727 FC9D 88 dey
|
|
728 FC9E C4 52 cpy lmargn
|
|
729 FCA0 B0 F7 bcs delete_blank_test_loop
|
|
730
|
|
731 ;the last line is blank... check if it is a logical line start
|
|
732 FCA2 C6 51 dec hold1
|
|
733 FCA4 A5 51 lda hold1
|
|
734 FCA6 20 7E FD jsr EditorTestLogicalLineBit
|
|
735
|
|
736 ;skip if so -- we can't delete the entire logical line
|
|
737 FCA9 D0 0B bne delete_not_blank
|
|
738
|
|
739 ;delete this physical line... however, do not move the cursor and
|
|
740 ;do not change the read line even if the cursor hops to a new one
|
|
741 FCAB A5 55 lda colcrs
|
|
742 FCAD 48 pha
|
|
743 FCAE A5 51 lda hold1
|
|
744 FCB0 20 CE FC jsr EditorDeleteLine
|
|
745 FCB3 68 pla
|
|
746 FCB4 85 55 sta colcrs
|
|
747
|
|
748 FCB6 delete_not_blank:
|
|
749 ;re-show cursor and exit
|
|
750 FCB6 60 rts
|
|
751
|
|
752 .endp
|
|
753
|
|
754 ;==========================================================================
|
|
755 FCB7 .proc EditorIsSpecial
|
|
756 FCB7 special_binsearch:
|
|
757 FCB7 DD FB FA cmp EditorPutByte.special_code_tab,x
|
|
758 FCBA F0 03 beq special_found
|
|
759 FCBC CA dex
|
|
760 FCBD 10 F8 bpl special_binsearch
|
|
761 FCBF special_found:
|
|
762 FCBF 60 rts
|
|
763 .endp
|
|
764
|
|
765 ;==========================================================================
|
|
766 FCC0 .proc EditorRecomputeCursorAddr
|
|
767 FCC0 A6 55 ldx colcrs
|
|
768 FCC2 A4 54 ldy rowcrs
|
|
769 FCC4 20 5F F9 jsr ScreenComputeAddr
|
|
770 FCC7 86 5E stx oldadr
|
|
771 FCC9 85 5F sta oldadr+1
|
|
772 FCCB 60 rts
|
|
773 .endp
|
|
774
|
|
775 ;==========================================================================
|
|
776 ; Delete a logical line on screen, and scroll the remainder of the screen
|
|
777 ; upward.
|
|
778 ;
|
|
779 ; Inputs:
|
|
780 ; A = physical line row to delete
|
|
781 ;
|
|
782 ; Outputs:
|
|
783 ; DELTAR = number of lines scrolled
|
|
784 ;
|
|
785 = FCCE EditorDeleteLine = EditorDeleteLine0.use_line
|
|
786 FCCC .proc EditorDeleteLine0
|
|
787 FCCC A9 00 lda #0
|
|
788 FCCE use_line:
|
|
789 FCCE 85 51 sta hold1
|
|
790 FCD0 A2 00 ldx #0
|
|
791 FCD2 86 76 stx deltar
|
|
792
|
|
793 FCD4 scroll_loop:
|
|
794 ;compute base address and set that as destination
|
|
795 FCD4 A4 51 ldy hold1
|
|
796
|
|
797 .if _KERNEL_XLXE
|
|
798 FCD6 38 sec
|
|
799 FCD7 D0 21 bne nofine
|
|
800 FCD9 AE 6E 02 ldx fine
|
|
801 FCDC F0 1C beq nofine
|
|
802 FCDE A2 00 ldx #0
|
|
803 FCE0 xloop:
|
|
804 FCE0 A5 14 lda rtclok+2
|
|
805 FCE2 C5 14 F0 FC cmp:req rtclok+2
|
|
806 FCE6 E8 inx
|
|
807 FCE7 8E 05 D4 stx vscrol
|
|
808 FCEA E0 07 cpx #7
|
|
809 FCEC D0 F2 bne xloop
|
|
810 FCEE A9 10 lda #32/2
|
|
811 FCF0 CD 0B D4 90 FB cmp:rcc vcount
|
|
812 FCF5 CD 0B D4 B0 FB cmp:rcs vcount
|
|
813 FCFA nofine:
|
|
814 FCFA 08 php ;C=0 for fine scroll, C=1 for coarse scroll
|
|
815 .endif
|
|
816
|
|
817 ;set TOADR to the line to be deleted
|
|
818 FCFB 20 75 F9 jsr ScreenComputeToAddrX0
|
|
819
|
|
820 FCFE A6 51 ldx hold1
|
|
821 FD00 10 0C bpl line_loop_start
|
|
822
|
|
823 FD02 line_loop:
|
|
824 ;bump line: FRMADR <- TOADR, TOADR += 40
|
|
825 FD02 20 C5 FD jsr EditorNextLineAddr
|
|
826
|
|
827 ;move line -- note that we are copying backwards (TOADR to FRMADR)!
|
|
828 FD05 A0 27 ldy #39
|
|
829 FD07 B1 66 91 68 88 10 + mva:rpl (toadr),y (frmadr),y-
|
|
830
|
|
831 FD0E line_loop_start:
|
|
832 FD0E E8 inx
|
|
833 FD0F EC BF 02 cpx botscr
|
|
834 FD12 D0 EE bne line_loop
|
|
835
|
|
836 ;clear the last line
|
|
837 FD14 A0 27 ldy #39
|
|
838 FD16 A9 00 lda #0
|
|
839 FD18 91 66 88 10 FB sta:rpl (toadr),y-
|
|
840
|
|
841 .if _KERNEL_XLXE
|
|
842 FD1D 28 plp
|
|
843 FD1E B0 03 bcs nofinescroll2
|
|
844 FD20 8D 05 D4 sta vscrol
|
|
845 FD23 nofinescroll2:
|
|
846 .endif
|
|
847
|
|
848 FD23 20 58 FD jsr adjust_lines
|
|
849
|
|
850 ;delete bits out of the logical mask until we get to the next
|
|
851 ;logical line, computing the number of lines to scroll
|
|
852 FD26 A5 51 lda hold1
|
|
853 FD28 20 71 FD jsr EditorGetLogicalLineInfo
|
|
854 FD2B BE 55 FD ldx update_table,y ;get number of masks to shift
|
|
855 FD2E 38 sec ;setup to add a new logical line at the end
|
|
856 FD2F F0 09 beq do_mask ;jump to masking if we're on byte 2
|
|
857 FD31 2E B4 02 rol logmap+2 ;shift byte 2
|
|
858 FD34 CA dex ;
|
|
859 FD35 F0 03 beq do_mask ;jump to masking if we're on byte 1
|
|
860 FD37 2E B3 02 rol logmap+1 ;shift byte 1
|
|
861 FD3A do_mask:
|
|
862 FD3A 85 64 sta adress ;stash mask
|
|
863 FD3C 49 FF eor #$ff ;invert mask
|
|
864 FD3E 39 B2 02 and logmap,y ;kill target bit
|
|
865 FD41 85 65 sta adress+1 ;stash modified mask
|
|
866 FD43 C6 64 dec adress ;form mask for LSBs below bit
|
|
867 FD45 25 64 and adress ;isolate those bits
|
|
868 FD47 65 65 adc adress+1 ;shift those up and the bit from the next byte in
|
|
869 FD49 99 B2 02 sta logmap,y ;write to logmap
|
|
870
|
|
871 FD4C E6 76 inc deltar ;increment line count
|
|
872 FD4E E6 64 inc adress ;revert mask
|
|
873 FD50 24 64 bit adress ;test if we still have a logical line
|
|
874
|
|
875 ;loop back if we need to delete more physical lines
|
|
876 FD52 F0 80 beq scroll_loop
|
|
877
|
|
878 ;all done
|
|
879 FD54 60 rts
|
|
880
|
|
881 FD55 update_table:
|
|
882 FD55 02 01 00 dta 2,1,0
|
|
883
|
|
884 FD58 adjust_lines:
|
|
885 FD58 A5 52 lda lmargn ;prep for line adjustments
|
|
886
|
|
887 ;adjust the read row if it is affected by the deletion
|
|
888 FD5A A2 6C ldx #<bufstr
|
|
889 FD5C 20 61 FD jsr adjust_line
|
|
890
|
|
891 ;adjust the cursor row if it is affected by the deletion
|
|
892 FD5F A2 54 ldx #<rowcrs
|
|
893 FD61 adjust_line:
|
|
894 FD61 B4 00 ldy 0,x ;get row
|
|
895 FD63 C4 51 cpy hold1 ;compare against deletion pos
|
|
896 FD65 90 07 bcc adjust_line_above ;nothing to do if it's above del range
|
|
897 FD67 D0 03 bne adjust_line_below ;skip col adjust if it's below del range
|
|
898 FD69 95 01 sta 1,x ;within range - move cursor to left mgn
|
|
899 FD6B 60 rts
|
|
900 FD6C adjust_line_below:
|
|
901 FD6C D6 00 dec 0,x
|
|
902 FD6E adjust_line_above:
|
|
903 FD6E 60 rts
|
|
904 .endp
|
|
905
|
|
906 ;==========================================================================
|
|
907 = E4C9 EditorGetStatus = CIOExitSuccess
|
|
908 = E4CB EditorSpecial = CIOExitNotSupported
|
|
909 = E4CB EditorInit = CIOExitNotSupported
|
|
910
|
|
911 ;==========================================================================
|
|
912 ; Entry:
|
|
913 ; A = line
|
|
914 ;
|
|
915 ; Exit:
|
|
916 ; P = bit test status
|
|
917 ; A = bit mask
|
|
918 ; X = bit index
|
|
919 ; Y = mask index
|
|
920 ;
|
|
921 = FD6F EditorGetCurLogicalLineInfo = _EditorGetLogicalLineInfo
|
|
922 = FD71 EditorGetLogicalLineInfo = _EditorGetLogicalLineInfo.use_a
|
|
923 FD6F .proc _EditorGetLogicalLineInfo
|
|
924 FD6F A5 54 lda rowcrs
|
|
925 FD71 use_a:
|
|
926 FD71 48 pha
|
|
927 FD72 4A lsr
|
|
928 FD73 4A lsr
|
|
929 FD74 4A lsr
|
|
930 FD75 A8 tay
|
|
931 FD76 68 pla
|
|
932 FD77 29 07 and #7
|
|
933 FD79 AA tax
|
|
934 FD7A BD C1 E4 lda ReversedBitMasks,x
|
|
935 FD7D 60 rts
|
|
936 .endp
|
|
937
|
|
938 ;==========================================================================
|
|
939 ; Test whether a physical line is the start of a logical line.
|
|
940 ;
|
|
941 ; Entry:
|
|
942 ; A = line
|
|
943 ;
|
|
944 ; Exit:
|
|
945 ; Z = 1 if so, 0 if not
|
|
946 ;
|
|
947 ; Modified:
|
|
948 ; all registers
|
|
949 ;
|
|
950 FD7E .proc EditorTestLogicalLineBit
|
|
951 FD7E 20 71 FD jsr EditorGetLogicalLineInfo
|
|
952 FD81 39 B2 02 and logmap,y
|
|
953 FD84 60 rts
|
|
954 .endp
|
|
955
|
|
956 ;==========================================================================
|
|
957 ; Get the starting physical line for a logical line.
|
|
958 ;
|
|
959 ; Entry:
|
|
960 ; A = physical line
|
|
961 ;
|
|
962 ; Exit:
|
|
963 ; A = logical line start
|
|
964 ;
|
|
965 ; Modified:
|
|
966 ; ADRESS
|
|
967 ;
|
|
968 = FD87 EditorPhysToLogicalRow = EditorGetCurLogicalRow.use_line
|
|
969 FD85 .proc EditorGetCurLogicalRow
|
|
970 FD85 A5 54 lda rowcrs
|
|
971 FD87 use_line:
|
|
972 FD87 85 64 sta adress
|
|
973 FD89 test_loop:
|
|
974 FD89 A5 64 lda adress
|
|
975 FD8B 20 7E FD jsr EditorTestLogicalLineBit
|
|
976 FD8E D0 04 bne found
|
|
977 FD90 C6 64 dec adress
|
|
978 FD92 D0 F5 bne test_loop
|
|
979 FD94 found:
|
|
980 FD94 A5 64 lda adress
|
|
981 FD96 60 rts
|
|
982 .endp
|
|
983
|
|
984 ;==========================================================================
|
|
985 FD97 .proc EditorBell
|
|
986 FD97 A0 00 ldy #0
|
|
987 FD99 4C CC E4 jmp Bell
|
|
988 .endp
|
|
989
|
|
990 ;==========================================================================
|
|
991 FD9C .proc EditorSwapToScreen_Y1
|
|
992 FD9C A0 01 ldy #1
|
|
993 = FD9E .def :EditorSwapToScreen = *
|
|
994 FD9E 84 64 sty adress
|
|
995 FDA0 18 clc
|
|
996 FDA1 20 42 F9 jsr ScreenSwap
|
|
997 FDA4 A4 64 ldy adress
|
|
998 FDA6 60 rts
|
|
999 .endp
|
|
1000
|
|
1001 ;==========================================================================
|
|
1002 ; Compute the current logical column.
|
|
1003 ;
|
|
1004 ; Exit:
|
|
1005 ; A = column
|
|
1006 ; X = inverted row index (0-2 => $ff-$fd)
|
|
1007 ;
|
|
1008 FDA7 .proc EditorGetLogicalColumn
|
|
1009 ;get starting row of logical line
|
|
1010 FDA7 A5 54 lda rowcrs
|
|
1011 FDA9 20 87 FD jsr EditorPhysToLogicalRow
|
|
1012
|
|
1013 ;subtract off current row
|
|
1014 FDAC 18 clc
|
|
1015 FDAD E5 54 sbc rowcrs
|
|
1016 FDAF AA tax
|
|
1017
|
|
1018 ;multiply negated difference by 40
|
|
1019 FDB0 BD DB FC lda EditorLineLengthTab-$fc,x
|
|
1020
|
|
1021 ;add in physical column
|
|
1022 FDB3 65 55 adc colcrs
|
|
1023 FDB5 60 rts
|
|
1024 .endp
|
|
1025
|
|
1026 ;==========================================================================
|
|
1027 FDB6 .proc EditorSetupTabIndex
|
|
1028 FDB6 98 tya
|
|
1029 FDB7 29 07 and #7
|
|
1030 FDB9 AA tax
|
|
1031 FDBA BD C1 E4 lda ReversedBitMasks,x
|
|
1032 FDBD 48 pha
|
|
1033 FDBE 98 tya
|
|
1034 FDBF 4A lsr
|
|
1035 FDC0 4A lsr
|
|
1036 FDC1 4A lsr
|
|
1037 FDC2 AA tax
|
|
1038 FDC3 68 pla
|
|
1039 FDC4 60 rts
|
|
1040 .endp
|
|
1041
|
|
1042 ;==========================================================================
|
|
1043 ; Copy TOADR to FRMADR and add 40 to TOADR.
|
|
1044 ;
|
|
1045 FDC5 .proc EditorNextLineAddr
|
|
1046 FDC5 A5 66 lda toadr
|
|
1047 FDC7 85 68 sta frmadr
|
|
1048 FDC9 18 69 28 add #40
|
|
1049 FDCC 85 66 sta toadr
|
|
1050 FDCE A5 67 lda toadr+1
|
|
1051 FDD0 85 69 sta frmadr+1
|
|
1052 FDD2 69 00 adc #0
|
|
1053 FDD4 85 67 sta toadr+1
|
|
1054 FDD6 60 rts
|
|
1055 .endp
|
|
1056
|
|
1057 ;==========================================================================
|
|
1058 FDD7 .proc EditorLineLengthTab
|
|
1059 FDD7 78 50 28 00 dta 120, 80, 40, 0
|
|
1060 .endp
|
|
1061
|
|
271
|
|
272 .ifdef _KERNEL_816
|
|
273 icl 'screenext816.s'
|
|
274 .else
|
|
275 FDDB icl 'screenext.s'
|
|
Source: source/Shared/screenext.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Screen Handler extension routines
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11 FDDB ScreenEncodingOffsetTable:
|
|
12 FDDB 00 dta $00 ;4-bit
|
|
13 FDDC 10 dta $10 ;2-bit
|
|
14 FDDD 14 dta $14 ;1-bit
|
|
15
|
|
16 .if !_KERNEL_XLXE
|
|
17 _SCREEN_TABLES_3
|
|
18 .endif
|
|
19
|
|
20 ;==========================================================================
|
|
21 ; ScreenFineScrollDLI
|
|
22 ;
|
|
23 ; This DLI routine is used to set the PF1 color to PF2 to kill junk that
|
|
24 ; would appear on the extra line added with vertical scrolling.
|
|
25 ;
|
|
26 .if _KERNEL_XLXE
|
|
27 FDDE .proc ScreenFineScrollDLI
|
|
28 FDDE 48 pha
|
|
29 FDDF AD C6 02 lda color2
|
|
30 FDE2 45 4F eor colrsh
|
|
31 FDE4 25 4E and drkmsk
|
|
32 FDE6 8D 17 D0 sta colpf1
|
|
33 FDE9 68 pla
|
|
34 FDEA 40 rti
|
|
35 .endp
|
|
36 .endif
|
|
37
|
|
38 ;==========================================================================
|
|
39 ; ScreenResetLogicalLineMap
|
|
40 ;
|
|
41 ; Marks all lines as the start of logical lines.
|
|
42 ;
|
|
43 ; Exit:
|
|
44 ; X = 0
|
|
45 ;
|
|
46 FDEB .proc ScreenResetLogicalLineMap
|
|
47 FDEB A2 FF ldx #$ff
|
|
48 FDED 8E B2 02 stx logmap
|
|
49 FDF0 8E B3 02 stx logmap+1
|
|
50 FDF3 8E B4 02 stx logmap+2
|
|
51
|
|
52 ;reset line read position
|
|
53 FDF6 E8 inx
|
|
54 FDF7 86 6C stx bufstr
|
|
55 FDF9 A5 52 lda lmargn
|
|
56 FDFB 85 6D sta bufstr+1
|
|
57
|
|
58 ;note - X=0 relied on here by EditorOpen
|
|
59 FDFD 60 rts
|
|
60 .endp
|
|
61
|
|
62 ;==========================================================================
|
|
63 ; ScreenSetLastPosition
|
|
64 ;
|
|
65 ; Copies COLCRS/ROWCRS to OLDCOL/OLDROW.
|
|
66 ;
|
|
67 FDFE .proc ScreenSetLastPosition
|
|
68 FDFE A2 02 ldx #2
|
|
69 FE00 loop:
|
|
70 FE00 B5 54 lda rowcrs,x
|
|
71 FE02 95 5A sta oldrow,x
|
|
72 FE04 CA dex
|
|
73 FE05 10 F9 bpl loop
|
|
74 FE07 60 rts
|
|
75 .endp
|
|
76
|
|
77 ;==========================================================================
|
|
78 ; ScreenAdvancePosMode0
|
|
79 ;
|
|
80 ; Advance to the next cursor position in reading order, for mode 0.
|
|
81 ;
|
|
82 ; Exit:
|
|
83 ; C = 1 if no wrap, 0 if wrapped
|
|
84 ;
|
|
85 ; Modified:
|
|
86 ; X
|
|
87 ;
|
|
88 ; Preserved:
|
|
89 ; A
|
|
90 ;
|
|
91 FE08 .proc ScreenAdvancePosMode0
|
|
92 FE08 E6 55 inc colcrs
|
|
93 FE0A A6 53 ldx rmargn
|
|
94 FE0C E4 55 cpx colcrs
|
|
95 FE0E B0 06 bcs post_wrap
|
|
96 FE10 A6 52 ldx lmargn
|
|
97 FE12 86 55 stx colcrs
|
|
98 FE14 E6 54 inc rowcrs
|
|
99 FE16 post_wrap:
|
|
100 FE16 60 rts
|
|
101 .endp
|
|
102
|
|
103
|
|
104 ;==========================================================================
|
|
105 ; Output:
|
|
106 ; Y=1 for convenience
|
|
107 ;
|
|
108 ; (OLDADR) must point to the cursor location with OLDCHR even if the cursor
|
|
109 ; is hidden. This is required by SDX QUICKED.SYS, which always restores the
|
|
110 ; cursor.
|
|
111 ;
|
|
112 FE17 .proc ScreenShowCursorAndXitOK
|
|
113 ;;##ASSERT dw(oldadr) >= dw(savmsc)
|
|
114 ;check if the cursor is enabled
|
|
115 FE17 A0 00 ldy #0
|
|
116 FE19 B1 5E lda (oldadr),y
|
|
117 FE1B 85 5D sta oldchr
|
|
118 FE1D AC F0 02 ldy crsinh
|
|
119 FE20 D0 04 bne cursor_inhibited
|
|
120 FE22 49 80 eor #$80
|
|
121 FE24 91 5E sta (oldadr),y
|
|
122 FE26 cursor_inhibited:
|
|
123 FE26 C8 iny
|
|
124 FE27 60 rts
|
|
125 .endp
|
|
126
|
|
127 ;==========================================================================
|
|
128 ; Close screen (S:).
|
|
129 ;
|
|
130 ; This is a no-op in OS-B mode. In XL/XE mode, it reopens the device in
|
|
131 ; Gr.0 if fine scrolling is on, since this is necessary to clear the DLI.
|
|
132 ; This happens even if S: doesn't correspond to the text window. Only
|
|
133 ; the high bit of FINE is checked.
|
|
134 ;
|
|
135 .if !_KERNEL_XLXE
|
|
136 ScreenClose = CIOExitSuccess
|
|
137 .else
|
|
138 FE28 .proc ScreenClose
|
|
139 FE28 2C 6E 02 bit fine
|
|
140 FE2B 30 03 bmi disable_fine_scrolling
|
|
141
|
|
142 FE2D A0 01 ldy #1
|
|
143 FE2F 60 rts
|
|
144
|
|
145 FE30 disable_fine_scrolling:
|
|
146 ;turn off DLI
|
|
147 FE30 A9 40 8D 0E D4 mva #$40 nmien
|
|
148
|
|
149 ;restore vdslst
|
|
150 FE35 A2 55 ldx #<IntExitHandler_None
|
|
151 FE37 A9 C0 lda #>IntExitHandler_None
|
|
152 FE39 20 A0 F5 jsr ScreenOpenGr0.write_vdslst
|
|
153
|
|
154 FE3C 4C EE F3 jmp ScreenOpenGr0
|
|
155 .endp
|
|
156 .endif
|
|
157
|
|
158 ;==========================================================================
|
|
159 .if !_KERNEL_XLXE
|
|
160 _SCREEN_TABLES_2
|
|
161 .endif
|
|
276 .endif
|
|
277
|
|
278 FE3F _KERNEL_REPORT_MODULE_SIZE 'Display routines', 0
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', 0, ')', ' ', 'Display routines'
|
|
1 $FE3F -> $0ADF($0000) Display routines
|
|
3 = FE3F .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
279
|
|
280 .ifdef _KERNEL_816
|
|
281 icl 'keyboard816.s'
|
|
282 .else
|
|
283 FE3F icl 'keyboard.s'
|
|
Source: source/Shared/keyboard.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Keyboard Handler
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 ;==========================================================================
|
|
11 ; Oddly, the keyboard IRQs are not enabled from the keyboard init
|
|
12 ; routine. It's done by the Display Handler instead on open.
|
|
13 ;
|
|
14 FE3F .proc KeyboardInit
|
|
15 FE3F A2 FF ldx #$ff
|
|
16 FE41 8E FC 02 stx ch
|
|
17 FE44 8E F2 02 stx ch1
|
|
18 FE47 E8 inx
|
|
19 FE48 8E F1 02 stx keydel
|
|
20 FE4B 8E B6 02 stx invflg
|
|
21
|
|
22 ;turn on shift lock
|
|
23 FE4E A9 40 8D BE 02 mva #$40 shflok
|
|
24
|
|
25 ;set keyboard definition table pointer
|
|
26 .if _KERNEL_XLXE
|
|
27 FE53 A9 1D 85 79 A9 FF + mwa #KeyCodeToATASCIITable keydef
|
|
28 .endif
|
|
29 FE5B 60 rts
|
|
30 .endp
|
|
31
|
|
32 = E4C9 KeyboardOpen = CIOExitSuccess
|
|
33 = E4C9 KeyboardClose = CIOExitSuccess
|
|
34
|
|
35 ;==========================================================================
|
|
36 ; K: GET BYTE handler.
|
|
37 ;
|
|
38 ; Behavior:
|
|
39 ; - Exits with a Break error when break key is pressed.
|
|
40 ; - Ctrl-1 does not suspend input here (it is handled by S:/E:).
|
|
41 ; - Ctrl-3 returns an EOF error.
|
|
42 ; - Caps Lock sets caps mode on OS-A/B depending on Ctrl and Shift key
|
|
43 ; state. On the XL/XE OS, pressing Caps Lock alone will enable shift
|
|
44 ; lock if no lock is enabled and disable it otherwise.
|
|
45 ; - Shift/Control lock is applied by K:, but only on alpha keys.
|
|
46 ; - Inverse mode is also applied by K:. Control characters are excluded:
|
|
47 ; 1B-1F/7C-7F/9B-9F/FD-FF.
|
|
48 ; - Any Ctrl+Shift key code (>=$C0) produces a key click but is otherwise
|
|
49 ; ignored.
|
|
50 ;
|
|
51 FE5C .nowarn .proc _KeyboardGetByte
|
|
52 FE5C toggle_shift:
|
|
53 .if _KERNEL_XLXE
|
|
54 ;Caps Lock without Shift or Control is a toggle on the XL/XE line:
|
|
55 ; None -> Shifted
|
|
56 ; Shifted, Control -> None
|
|
57 FE5C AE BE 02 ldx shflok
|
|
58 FE5F D0 02 bne caps_off
|
|
59 FE61 A0 40 ldy #$40
|
|
60 .endif
|
|
61 FE63 shift_ctrl_on:
|
|
62 FE63 caps_off:
|
|
63 FE63 98 tya
|
|
64 FE64 29 C0 and #$c0
|
|
65 FE66 write_shflok:
|
|
66 FE66 8D BE 02 sta shflok
|
|
67
|
|
68 = FE69 .def :KeyboardGetByte
|
|
69 FE69 waitForChar:
|
|
70 FE69 A2 FF ldx #$ff
|
|
71 FE6B waitForChar2:
|
|
72 FE6B A5 11 lda brkkey
|
|
73 FE6D F0 57 beq isBreak
|
|
74 FE6F AD FC 02 lda ch
|
|
75 FE72 C9 FF cmp #$ff
|
|
76 FE74 F0 F5 beq waitForChar2
|
|
77
|
|
78 ;invalidate char
|
|
79 FE76 8E FC 02 stx ch
|
|
80
|
|
81 ;do keyboard click (we do this even for ignored ctrl+shift+keys)
|
|
82 FE79 A0 0C ldy #12
|
|
83 FE7B 20 CC E4 jsr Bell
|
|
84
|
|
85 ;ignore char if both ctrl and shift are pressed
|
|
86 FE7E C9 C0 cmp #$c0
|
|
87 FE80 B0 E7 bcs waitForChar
|
|
88
|
|
89 ;trap Ctrl-3 and return EOF
|
|
90 FE82 C9 9A cmp #$9a
|
|
91 FE84 F0 45 beq isCtrl3
|
|
92
|
|
93 ;translate char
|
|
94 FE86 A8 tay
|
|
95
|
|
96 .if _KERNEL_XLXE
|
|
97 FE87 B1 79 lda (keydef),y
|
|
98 .else
|
|
99 lda KeyCodeToATASCIITable,y
|
|
100 .endif
|
|
101
|
|
102 ;handle special keys (see keytable.s)
|
|
103 FE89 10 0E bpl valid_key
|
|
104 FE8B C9 81 cmp #$81
|
|
105 FE8D 90 DA bcc waitForChar ;$80 - invalid
|
|
106 FE8F F0 2B beq isInverse ;$81 - inverse video
|
|
107 FE91 C9 83 cmp #$83
|
|
108 FE93 90 C7 bcc toggle_shift ;$82 - caps lock
|
|
109 FE95 C9 85 cmp #$85
|
|
110 FE97 90 CA bcc shift_ctrl_on ;$83 - shift caps lock / $84 - ctrl caps lock
|
|
111
|
|
112 FE99 valid_key:
|
|
113 ;check for alpha key
|
|
114 FE99 C9 61 cmp #'a'
|
|
115 FE9B 90 0F bcc notAlpha
|
|
116 FE9D C9 7B cmp #'z'+1
|
|
117 FE9F B0 0B bcs notAlpha
|
|
118
|
|
119 ;check for shift/control lock
|
|
120 FEA1 2C BE 02 bit shflok
|
|
121 FEA4 70 04 bvs doShiftLock
|
|
122 FEA6 10 04 bpl notAlpha
|
|
123
|
|
124 ;do control lock logic
|
|
125 FEA8 29 1F and #$1f
|
|
126
|
|
127 FEAA doShiftLock:
|
|
128 FEAA 29 DF and #$df
|
|
129
|
|
130 FEAC notAlpha:
|
|
131 ;check if we should apply inverse flag -- special characters are excluded
|
|
132 FEAC A2 10 ldx #EditorPutByte.special_code_tab_end_2-EditorPutByte.special_code_tab-1
|
|
133 FEAE 20 B7 FC jsr EditorIsSpecial
|
|
134 FEB1 F0 03 beq skip_inverse
|
|
135
|
|
136 ;apply inverse flag
|
|
137 FEB3 4D B6 02 eor invflg
|
|
138 FEB6 skip_inverse:
|
|
139
|
|
140 ;return char
|
|
141 FEB6 8D FB 02 sta atachr ;required or CON.SYS (SDX 4.46) breaks
|
|
142 FEB9 A0 01 ldy #1
|
|
143 FEBB 60 rts
|
|
144
|
|
145 FEBC isInverse:
|
|
146 FEBC AD B6 02 lda invflg
|
|
147 FEBF 49 80 eor #$80
|
|
148 FEC1 8D B6 02 sta invflg
|
|
149 FEC4 B0 A3 bcs waitForChar ;!! - unconditional
|
|
150
|
|
151 FEC6 isBreak:
|
|
152 FEC6 86 11 stx brkkey
|
|
153 FEC8 A0 80 ldy #CIOStatBreak
|
|
154 FECA 60 rts
|
|
155
|
|
156 FECB isCtrl3:
|
|
157 FECB A0 88 ldy #CIOStatEndOfFile
|
|
158 FECD 60 rts
|
|
159 .endp
|
|
160
|
|
161 ;==============================================================================
|
|
162 = E4CB KeyboardPutByte = CIOExitNotSupported
|
|
163 = E4C9 KeyboardGetStatus = CIOExitSuccess
|
|
164 = E4CB KeyboardSpecial = CIOExitNotSupported
|
|
165
|
|
166 ;==============================================================================
|
|
167 ; Keyboard IRQ
|
|
168 ;
|
|
169 ; HELP button ($11, $51, and $91):
|
|
170 ; - Affects SRTIMR, ATRACT, KEYDEL, and HELPFG
|
|
171 ; - Does NOT affect CH, CH1
|
|
172 ;
|
|
173 FECE .proc KeyboardIRQ
|
|
174 ;reset software repeat timer
|
|
175 .if _KERNEL_XLXE
|
|
176 FECE AD D9 02 8D 2B 02 mva krpdel srtimr
|
|
177 .else
|
|
178 mva #$30 srtimr
|
|
179 .endif
|
|
180
|
|
181 ;read new key
|
|
182 FED4 AD 09 D2 lda kbcode
|
|
183
|
|
184 .if _KERNEL_XLXE
|
|
185 ;check for HELP
|
|
186 FED7 29 3F and #$3f
|
|
187 FED9 C9 11 cmp #$11
|
|
188 FEDB D0 05 bne not_help
|
|
189 FEDD 8D DC 02 sta helpfg
|
|
190 FEE0 F0 1E beq xit2
|
|
191
|
|
192 FEE2 not_help:
|
|
193 FEE2 AD 09 D2 lda kbcode
|
|
194 .endif
|
|
195
|
|
196 ;check if it is the same as the prev key
|
|
197 FEE5 CD F2 02 cmp ch1
|
|
198 FEE8 D0 08 bne debounced
|
|
199
|
|
200 ;reject key if debounce timer is still running
|
|
201 FEEA AD F1 02 lda keydel
|
|
202 FEED D0 16 bne xit
|
|
203 FEEF AD F2 02 lda ch1
|
|
204 FEF2 debounced:
|
|
205
|
|
206 ;check for Ctrl+1 to toggle display activity
|
|
207 FEF2 C9 9F cmp #$9f
|
|
208 FEF4 F0 11 beq is_suspend
|
|
209
|
|
210 ;store key
|
|
211 FEF6 8D FC 02 sta ch
|
|
212 FEF9 8D F2 02 sta ch1
|
|
213
|
|
214 ;reset attract
|
|
215 FEFC A9 00 85 4D mva #0 atract
|
|
216
|
|
217 FF00 xit2:
|
|
218 ;reset key delay
|
|
219 FF00 A9 03 8D F1 02 mva #3 keydel
|
|
220
|
|
221 FF05 xit:
|
|
222 ;all done
|
|
223 FF05 68 pla
|
|
224 FF06 40 rti
|
|
225
|
|
226 FF07 is_suspend:
|
|
227 ;toggle stop/start flag
|
|
228 FF07 AD FF 02 lda ssflag
|
|
229 FF0A 49 FF eor #$ff
|
|
230 FF0C 8D FF 02 sta ssflag
|
|
231 FF0F B0 EF bcs xit2 ;!! carry set from cmp #$9f!
|
|
232 .endp
|
|
233
|
|
234 ;==============================================================================
|
|
235 FF11 .proc KeyboardBreakIRQ
|
|
236 FF11 A9 00 85 11 mva #0 brkkey
|
|
237
|
|
238 ;need to clear the suspend flag as BREAK automatically nukes a pending Ctrl+1
|
|
239 FF15 8D FF 02 sta ssflag
|
|
240
|
|
241 ;interestingly, the default break handler forces the cursor back on.
|
|
242 FF18 8D F0 02 sta crsinh
|
|
243
|
|
244 FF1B 68 pla
|
|
245 FF1C 40 rti
|
|
246 .endp
|
|
284 .endif
|
|
285
|
|
286 FF1D icl 'keytable.s'
|
|
Source: source/Shared/keytable.s
|
|
1 ; Altirra - Atari 800/800XL/5200 emulator
|
|
2 ; Modular Kernel ROM - Keyboard Scan Code Table
|
|
3 ; Copyright (C) 2008-2016 Avery Lee
|
|
4 ;
|
|
5 ; Copying and distribution of this file, with or without modification,
|
|
6 ; are permitted in any medium without royalty provided the copyright
|
|
7 ; notice and this notice are preserved. This file is offered as-is,
|
|
8 ; without any warranty.
|
|
9
|
|
10 FF1D KeyCodeToATASCIITable:
|
|
11 ;Special codes in this table (values important for compat):
|
|
12 ; $80 - invalid key
|
|
13 ; $81 - inverse video
|
|
14 ; $82 - caps lock
|
|
15 ; $83 - shift caps lock
|
|
16 ; $84 - control caps lock
|
|
17
|
|
18 ;lowercase
|
|
19 FF1D 6C 6A 3B 80 80 6B + dta $6C, $6A, $3B, $80, $80, $6B, $2B, $2A
|
|
20 FF25 6F 80 70 75 9B 69 + dta $6F, $80, $70, $75, $9B, $69, $2D, $3D
|
|
21 FF2D 76 80 63 80 80 62 + dta $76, $80, $63, $80, $80, $62, $78, $7A
|
|
22 FF35 34 80 33 36 1B 35 + dta $34, $80, $33, $36, $1B, $35, $32, $31
|
|
23 FF3D 2C 20 2E 6E 80 6D + dta $2C, $20, $2E, $6E, $80, $6D, $2F, $81
|
|
24 FF45 72 80 65 79 7F 74 + dta $72, $80, $65, $79, $7F, $74, $77, $71
|
|
25 FF4D 39 80 30 37 7E 38 + dta $39, $80, $30, $37, $7E, $38, $3C, $3E
|
|
26 FF55 66 68 64 80 82 67 + dta $66, $68, $64, $80, $82, $67, $73, $61
|
|
27
|
|
28 ;SHIFT
|
|
29 FF5D 4C 4A 3A 80 80 4B + dta $4C, $4A, $3A, $80, $80, $4B, $5C, $5E
|
|
30 FF65 4F 80 50 55 9B 49 + dta $4F, $80, $50, $55, $9B, $49, $5F, $7C
|
|
31 FF6D 56 80 43 80 80 42 + dta $56, $80, $43, $80, $80, $42, $58, $5A
|
|
32 FF75 24 80 23 26 1B 25 + dta $24, $80, $23, $26, $1B, $25, $22, $21
|
|
33 FF7D 5B 20 5D 4E 80 4D + dta $5B, $20, $5D, $4E, $80, $4D, $3F, $80
|
|
34 FF85 52 80 45 59 9F 54 + dta $52, $80, $45, $59, $9F, $54, $57, $51
|
|
35 FF8D 28 80 29 27 9C 40 + dta $28, $80, $29, $27, $9C, $40, $7D, $9D
|
|
36 FF95 46 48 44 80 83 47 + dta $46, $48, $44, $80, $83, $47, $53, $41
|
|
37
|
|
38 ;CTRL
|
|
39 FF9D 0C 0A 7B 80 80 0B + dta $0C, $0A, $7B, $80, $80, $0B, $1E, $1F
|
|
40 FFA5 0F 80 10 15 9B 09 + dta $0F, $80, $10, $15, $9B, $09, $1C, $1D
|
|
41 FFAD 16 80 03 80 80 02 + dta $16, $80, $03, $80, $80, $02, $18, $1A
|
|
42 FFB5 80 80 9B 80 1B 80 + dta $80, $80, $9B, $80, $1B, $80, $FD, $80
|
|
43 FFBD 00 20 60 0E 80 0D + dta $00, $20, $60, $0E, $80, $0D, $80, $80
|
|
44 FFC5 12 80 05 19 9E 14 + dta $12, $80, $05, $19, $9E, $14, $17, $11
|
|
45 FFCD 80 80 80 80 FE 80 + dta $80, $80, $80, $80, $FE, $80, $7D, $FF
|
|
46 FFD5 06 08 04 80 84 07 + dta $06, $08, $04, $80, $84, $07, $13, $01
|
|
287 FFDD _KERNEL_REPORT_MODULE_SIZE 'Keyboard routines', 0
|
|
Macro: _KERNEL_REPORT_MODULE_SIZE [Source: source/main.xasm]
|
|
1 .echo ' ', *, ' -> ', *-?@_kernel_lastpt, '(', 0, ')', ' ', 'Keyboard routines'
|
|
1 $FFDD -> $019E($0000) Keyboard routines
|
|
3 = FFDD .def ?@_kernel_lastpt = *
|
|
Source: source/main.xasm
|
|
288
|
|
289 .if _KERNEL_XLXE
|
|
290 .echo 'Free space: ', $FFEE-*, ' bytes'
|
|
290 Free space: $0011 bytes
|
|
291 .else
|
|
292 .echo 'Free space: ', $FFFA-*, ' bytes'
|
|
293 .endif
|
|
294
|
|
295 ;==============================================================================
|
|
296 ; version block (XL/XE)
|
|
297 ;==============================================================================
|
|
298
|
|
299 .ifdef _KERNEL_816
|
|
300 org $ffe4
|
|
301 dta a(IntDispatchNativeCop) ;$FFE4
|
|
302 dta a(IntDispatchNativeBreak) ;$FFE6
|
|
303 dta a(IntDispatchNativeAbort) ;$FFE8
|
|
304 dta a(IntDispatchNativeNmi) ;$FFEA
|
|
305 dta a(0) ;$FFEC
|
|
306 dta a(IntDispatchNativeIrq) ;$FFEE
|
|
307 dta $13 ;$FFF0
|
|
308 dta $02 ;$FFF1 option byte - !!CHECKED BY ARCHON
|
|
309 dta 'CX' ;$FFF2
|
|
310 dta a(IntDispatchCop) ;$FFF4
|
|
311 dta a(0) ;$FFF6
|
|
312 dta a(IntDispatchAbort) ;$FFF8
|
|
313 .elif _KERNEL_XLXE
|
|
314 FFDD org $ffee
|
|
315 FFEE 01 01 13 dta $01,$01,$13
|
|
316 FFF1 02 dta $02 ;option byte - !!CHECKED BY ARCHON
|
|
317 FFF2 43 58 00 00 00 dta 'CX',$00,$00,$00
|
|
318 FFF7 00 dta $00
|
|
319 FFF8 00 00 dta a(0)
|
|
320 .endif
|
|
321
|
|
322 ;==============================================================================
|
|
323 ; reset vectors
|
|
324 ;==============================================================================
|
|
325 FFFA org $fffa
|
|
326 FFFA 81 C1 dta a(IntDispatchNMI)
|
|
327 FFFC B9 EE dta a(InitReset)
|
|
328 FFFE 95 C1 dta a(IntDispatchIRQ)
|
|
329
|
|
330 end
|