/[projet1]/public/oric/demos/SlideShowDemo/code/loader.asm
Defence Force logotype

Contents of /public/oric/demos/SlideShowDemo/code/loader.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1071 - (show annotations)
Mon Jan 6 20:20:59 2014 UTC (5 years, 10 months ago) by dbug
File size: 10507 byte(s)
More work on the code:
- The switch to HIRES is now more optimal and in the boot sector, so the loader code itself is more compact which leaves more room for the file info tables.
- Reorganized all the buffers in a new file, in order to avoid wasting room with the alignment
- There's now a small intro before the main slide
- The music player now cleanly stops after the end of a music has been reached and informed the main code so it can load the next track
- Removed a lot of redundant code in the scroller code
1 #define MICRODISC_LOADER
2 #include "disk_info.h"
3
4 #define COLOR(color) pha:lda #16+(color&7):sta $bb80+40*27:pla
5 #define STOP(color) pha:lda #16+(color&7):sta $bb80+40*27:jmp *:pla
6
7 .zero
8
9 *=$00
10
11 retry_counter .dsb 1 ; Number of attempts at loading data (ie: not quite clear what happens when this fails...)
12 sectors_to_go .dsb 1 ; How many sectors do we still need to load for this file
13 current_track .dsb 1 ; Index of the track being loaded
14 current_sector .dsb 1 ; Index of the sector being loaded
15 current_side .dsb 1 ; Has the bit 4 set to 0 or 1 to be used as a mask on the Microdisc control register (other bits have to be set to zero)
16 irq_save_a .dsb 1 ; To preserve the accumulator value in the IRQ code
17
18 ; Unpack test
19 ptr_source .dsb 2 ; Packed source data adress
20 ptr_destination .dsb 2 ; Destination adress where we depack
21 ptr_destination_end .dsb 2 ; Point on the end of the depacked stuff
22 ptr_source_back .dsb 2 ; Temporary used to hold a pointer on depacked stuff
23 offset .dsb 2
24 mask_value .dsb 1
25 nb_dst .dsb 1
26
27 .text
28
29 *=location_loader
30
31 ;
32 ; This is called from the bootsectors with the X register containing the fdc offset;
33 ; +$00 = Microdisc
34 ; +$e4 = Jasmin
35 ;
36 Initialize
37 jmp StartUp
38
39 #define LOADER
40
41 ; This file is generated by the floppy builder
42 #include "floppy_description.h"
43
44 ; Some local variables we need
45 fdc_register_offset .dsb 1
46
47 StartUp
48 stx fdc_register_offset ; Store the FDC offset value
49
50 ; Load the slideshow
51 ldx #LOADER_SLIDESHOW
52 jsr LoadData
53
54 ; Give control to the application and hope it knows what to do
55 __auto_execute_address
56 jmp $a000
57
58
59 IrqHandler
60 sta irq_save_a
61 pla
62 pha
63 and #%00010000 ; Check the saved B flag to detect a BRK
64 bne from_brk
65
66 from_irq
67 #ifdef LOADER_SHOW_DEBUGINFO
68 lda $bfdf
69 eor #1
70 ora #16
71 sta $bfdf
72 #endif
73 lda irq_save_a
74 bit $304
75 IrqDoNothing
76 rti
77
78 from_brk
79 lda #16+1
80 sta $bb80+40*27
81 nop
82 nop
83 nop
84 lda #16+2
85 sta $bb80+40*27
86 jmp from_brk
87
88
89
90
91 ; X=File index
92 ; A=Low
93 ; Y=High
94 SetLoadAddress
95 sta FileLoadAdressLow,x
96 tya
97 sta FileLoadAdressHigh,x
98 rts
99
100
101 ; X=File index
102 LoadData
103 ;STOP(2)
104
105 ; We have to start somewhere no matter what, compressed or not
106 jsr StartReadOperation
107
108 ; Now at this stage we have to check if the data is compressed or not
109 lda FileStoredSizeLow,x
110 cmp FileSizeLow,x
111 bne LoadCompressedData
112
113 lda FileStoredSizeHigh,x
114 cmp FileSizeHigh,x
115 bne LoadCompressedData
116
117 LoadUncompressedData
118
119 ;
120 ; Loop to read all the sectors
121 ;
122 read_sectors_loop
123 jsr ReadNextSector
124
125 ; Try to let time to an IRQ to play, and during that time copy the sector to the final location
126 cli
127
128 ldy #0
129 loop_copy
130 lda $200,y ; Load the byte from page 2
131 __auto_write_address
132 sta $c000,y ; Store it to the final location
133 iny
134 bne loop_copy
135
136 nop
137 nop
138 sei
139
140 ; Next sector
141 inc __auto_write_address+2
142 dec sectors_to_go
143 bne read_sectors_loop
144
145 ; Data successfully loaded (we hope), so we restore the interrupts
146 cli
147 rts
148
149
150 LoadCompressedData
151 clc
152 lda FileLoadAdressLow,x
153 sta ptr_destination+0
154 adc FileSizeLow,x
155 sta ptr_destination_end+0
156
157 lda FileLoadAdressHigh,x
158 sta ptr_destination+1
159 adc FileSizeHigh,x
160 sta ptr_destination_end+1
161
162 ;STOP(2)
163
164 jsr UnpackData
165 cli
166 rts
167
168
169 StartReadOperation
170 sei
171
172 ldy fdc_register_offset
173
174 ; Make sure the microdisc IRQ is disabled
175 jsr WaitCompletion
176
177 lda #%10000100 ; Disable the FDC (Eprom select + FDC Interrupt request)
178 sta FDC_flags,y
179
180 ;jsr WaitCompletion
181
182 ;
183 ; Setup, we use the table to find out where the file is located on the floppy,
184 ; where to write it in memory, and how large it is.
185 ;
186 lda FileLoadAdressHigh,x
187 sta __auto_execute_address+2
188 sta __auto_write_address+2
189
190 lda FileLoadAdressLow,x
191 sta __auto_execute_address+1
192 sta __auto_write_address+1
193
194 ; Starting track
195 ldy #%00000000 ; Side 0
196 lda FileStartTrack,x ; If the track id is larger than 128, it means it is on the other side of the floppy
197 bpl first_side
198 ; The file starts on the second side
199 ldy #FDC_Flag_DiscSide ; Side 1
200 and #%01111111 ; Mask out the extra bit
201 first_side
202 sty current_side
203 sta current_track
204
205 ldy fdc_register_offset
206
207 ; First sector
208 lda FileStartSector,x
209 sta current_sector
210
211 ; FileSizeLow/FileSizeHigh
212 ; Number of sectors to load
213 .(
214 lda FileStoredSizeHigh,x
215 sta sectors_to_go
216 lda FileStoredSizeLow,x
217 beq skip
218 inc sectors_to_go
219 skip
220 .)
221 rts
222
223
224 ReadNextSector
225 cli
226
227 ldy fdc_register_offset
228
229 ; Check if we have reached the end of the track
230 lda current_sector
231 cmp #FLOPPY_SECTOR_PER_TRACK+1
232 bne same_track
233
234 ; Next track
235 inc current_track
236 lda current_track
237 cmp #FLOPPY_TRACK_NUMBER
238 bne stay_on_same_side
239
240 ; Reset to the first track on the other side
241 lda #0
242 sta current_track
243
244 sei
245
246 lda #FDC_Flag_DiscSide
247 sta current_side
248 stay_on_same_side
249
250
251 ; Reset the sector position
252 lda #1
253 sta current_sector
254 same_track
255
256 #ifdef LOADER_SHOW_DEBUGINFO
257 ; Display debug info
258 cli
259 jsr DisplayPosition
260 sei
261 #endif
262
263 lda current_sector
264 sta FDC_sector_register,y
265 inc current_sector
266
267 ; Check if the drive is on the correct track
268 lda current_track
269 cmp FDC_track_register,y
270 beq stay_on_the_track
271
272 ; Set the new track
273 sta FDC_data,y
274
275 lda #CMD_Seek
276 sta FDC_command_register,y
277 jsr WaitCompletion
278
279 stay_on_the_track
280 lda #%10000100 ; on force les le Microdisk en side0, drive A ... Set le bit de données !!!
281 ora current_side
282 sta FDC_flags,y
283
284 lda #CMD_ReadSector
285 sta FDC_command_register,y
286
287
288 ldx #wait_status_floppy
289 waitcommand
290 nop
291 nop
292 dex
293 bne waitcommand
294
295 ;
296 ; Read the sector data
297 ;
298 ldx #0
299 microdisc_read_data
300 lda $0318
301 bmi microdisc_read_data
302
303 lda FDC_data,y
304 sta $200,x ; Store the byte in page 2
305 inx
306
307 bne microdisc_read_data
308
309 lda FDC_status_register,y
310 and #$1C
311
312 jsr WaitCompletion
313 cli
314 rts
315
316
317 WaitCompletion
318 txa
319 pha
320
321 ldx #4
322 r_wait_completion
323 dex
324 bne r_wait_completion
325 r2_wait_completion
326 lda FDC_status_register,y
327 lsr
328 bcs r2_wait_completion
329 asl
330 pla
331 tax
332 rts
333
334 #ifdef LOADER_SHOW_DEBUGINFO
335 HexData .byt "0123456789ABCDEF"
336
337 DisplayPosition
338 .(
339 lda current_side
340 lsr
341 lsr
342 lsr
343 lsr
344 tax
345 lda HexData,x
346 sta $bb80+40*27+0
347
348 lda #3
349 sta $bb80+40*27+1
350
351 lda current_track
352 lsr
353 lsr
354 lsr
355 lsr
356 tax
357 lda HexData,x
358 sta $bb80+40*27+2
359
360 lda current_track
361 and #15
362 tax
363 lda HexData,x
364 sta $bb80+40*27+3
365
366 lda #2
367 sta $bb80+40*27+4
368
369 lda current_sector
370 lsr
371 lsr
372 lsr
373 lsr
374 tax
375 lda HexData,x
376 sta $bb80+40*27+5
377
378 lda current_sector
379 and #15
380 tax
381 lda HexData,x
382 sta $bb80+40*27+6
383
384 ;jsr WaitLoop
385 rts
386 .)
387 #endif
388
389
390 GetNextByte
391 php
392 lda __fetchByte+1
393 bne __fetchByte
394 nop
395 nop
396 nop
397 nop
398 sei
399 jsr ReadNextSector
400 nop
401 nop
402 nop
403 nop
404 cli
405 ldx #0
406 ldy #0
407 __fetchByte
408 lda $200
409 inc __fetchByte+1
410 plp
411 rts
412
413
414
415 ; void file_unpack(void *ptr_dst,void *ptr_src)
416
417 ; Need to be called with valid values in:
418 ; ptr_destination
419 ; ptr_source
420 ; ptr_destination_end (Destination + size)
421 UnpackData
422 ;jmp UnpackData
423 .(
424 cli
425
426 ; Initialise variables
427 ; We try to keep "y" null during all the code,
428 ; so the block copy routine has to be sure that
429 ; y is null on exit
430 ldy #0
431 sty __fetchByte+1
432 lda #1
433 sta mask_value
434
435 unpack_loop
436 ; Handle bit mask
437 lsr mask_value
438 bne end_reload_mask
439
440 jsr GetNextByte ; Read from source stream
441
442 ror
443 sta mask_value
444 end_reload_mask
445 bcc back_copy
446
447 write_byte
448 ; Copy one byte from the source stream
449 jsr GetNextByte ; Read from source stream
450 sta (ptr_destination),y
451
452 lda #1
453 sta nb_dst
454
455
456
457 _UnpackEndLoop
458 ;// We increase the current destination pointer,
459 ;// by a given value, white checking if we reach
460 ;// the end of the buffer.
461 clc
462 lda ptr_destination
463 adc nb_dst
464 sta ptr_destination
465
466 .(
467 bcc skip
468 inc ptr_destination+1
469 skip
470 .)
471 cmp ptr_destination_end
472 lda ptr_destination+1
473 sbc ptr_destination_end+1
474 bcc unpack_loop
475 rts
476
477
478 back_copy
479 ;BreakPoint jmp BreakPoint
480 ; Copy a number of bytes from the already unpacked stream
481 ; Here we know that y is null. So no need for clearing it.
482 ; Just be sure it's still null at the end.
483 ; At this point, the source pointer points to a two byte value that actually contains a 4 bits counter, and a 12 bit offset to point back into the depacked stream.
484 ; The counter is in the 4 high order bits.
485 ;clc <== No need, since we access this routie from a BCC
486 jsr GetNextByte ; Read from source stream
487 adc #1
488 sta offset
489 jsr GetNextByte ; Read from source stream
490 tax
491 and #$0f
492 adc #0
493 sta offset+1
494
495 txa
496 lsr
497 lsr
498 lsr
499 lsr
500 clc
501 adc #3
502 sta nb_dst
503
504 sec
505 lda ptr_destination
506 sbc offset
507 sta ptr_source_back
508 lda ptr_destination+1
509 sbc offset+1
510 sta ptr_source_back+1
511
512 ; Beware, in that loop, the direction is important
513 ; since RLE like depacking is done by recopying the
514 ; very same byte just copied... Do not make it a
515 ; reverse loop to achieve some speed gain...
516 .(
517 copy_loop
518 lda (ptr_source_back),y ; Read from already unpacked stream
519 sta (ptr_destination),y ; Write to destination buffer
520 iny
521 cpy nb_dst
522 bne copy_loop
523 .)
524 ldy #0
525 beq _UnpackEndLoop
526 rts
527 .)
528
529 _EndLoaderCode
530
531 ;
532 ; This is free memory that can be used, when it reaches zero then the loader start address should be changed
533 ;
534
535 .dsb $FFF4 - _EndLoaderCode
536
537 _Vectors
538
539 #if ( _Vectors <> $FFF4 )
540 #error - Vector address is incorrect, loader will crash
541 #else
542
543 ;
544 ; Here are the functions that the user can call from his own application
545 ;
546 _ApiSetLoadAddress .byt $4c,<SetLoadAddress,>SetLoadAddress ; $FFF4
547 _ApiSetLoadData .byt $4c,<LoadData,>LoadData ; $FFF7
548
549 ;
550 ; These three HAVE to be at these precise adresses, they map to hardware registers
551 ;
552 _VectorNMI .word IrqDoNothing ; FFFA-FFFB - NMI Vector (Usually points to $0247)
553 _VectorReset .word IrqDoNothing ; FFFC-FFFD - RESET Vector (Usually points to $F88F)
554 _VectorIRQ .word IrqHandler ; FFFE-FFFF - IRQ Vector (Normally points to $0244)
555
556 #echo Remaining space in the loader code:
557 #print (_Vectors - _EndLoaderCode)
558
559 #endif
560
561 ; End of the loader - Nothing should come after because it's out of the addressable memory range :)
562

  ViewVC Help
Powered by ViewVC 1.1.26