/[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 1038 - (show annotations)
Tue Dec 17 21:24:32 2013 UTC (5 years, 11 months ago) by dbug
File size: 11676 byte(s)
FloppyBuilder 0.10
- The compression code now generates correct data (it was using the Atari ST mode encoding, making the unpacking code not happy)
- Added to the report file the occupation ratio of the floppy (by maintaining an internal list of used sectors also used to check if there's no overlap)
The loader code is now able to decompress data on the fly just using the page 2 as a temporary sector loader.
1
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 Initialize
33 jmp StartUp
34
35 #define LOADER
36
37 ; This file is generated by the floppy builder
38 #include "floppy_description.h"
39
40 ; Some local variables we need
41
42 StartUp
43 ;jmp StartUp
44 jsr SoftHiresWithCopyCharset
45
46 ;ldx #LOADER_COMPRESSED_TEST
47 ;jsr LoadData
48
49 ; Load the slideshow
50 ldx #LOADER_SLIDESHOW
51 jsr LoadData
52
53 ;STOP(1)
54 jsr ExecuteData
55
56 ;
57 ; End of demo - Just stay there doing nothing
58 ;
59 sei
60 loop_forever_demo_finished
61 jmp loop_forever_demo_finished
62
63
64
65 IrqHandler
66 sta irq_save_a
67 pla
68 pha
69 and #%00010000 ; Check the saved B flag to detect a BRK
70 bne from_brk
71
72 from_irq
73 #ifdef LOADER_SHOW_DEBUGINFO
74 lda $bfdf
75 eor #1
76 ora #16
77 sta $bfdf
78 #endif
79 lda irq_save_a
80 bit $304
81 IrqDoNothing
82 rti
83
84 from_brk
85 lda #16+1
86 sta $bb80+40*27
87 nop
88 nop
89 nop
90 lda #16+2
91 sta $bb80+40*27
92 jmp from_brk
93
94
95
96
97 ; X=File index
98 ; A=Low
99 ; Y=High
100 SetLoadAddress
101 sta FileLoadAdressLow,x
102 tya
103 sta FileLoadAdressHigh,x
104 rts
105
106
107 ; X=File index
108 LoadData
109 ;STOP(2)
110
111 ; We have to start somewhere no matter what, compressed or not
112 jsr StartReadOperation
113
114 ; Now at this stage we have to check if the data is compressed or not
115 lda FileStoredSizeLow,x
116 cmp FileSizeLow,x
117 bne LoadCompressedData
118
119 lda FileStoredSizeHigh,x
120 cmp FileSizeHigh,x
121 bne LoadCompressedData
122
123 LoadUncompressedData
124
125 ;
126 ; Loop to read all the sectors
127 ;
128 read_sectors_loop
129 jsr ReadNextSector
130
131 ; Try to let time to an IRQ to play, and during that time copy the sector to the final location
132 cli
133
134 ldy #0
135 loop_copy
136 lda $200,y ; Load the byte from page 2
137 __auto_write_address
138 sta $c000,y ; Store it to the final location
139 iny
140 bne loop_copy
141
142 nop
143 nop
144 sei
145
146 ; Next sector
147 inc __auto_write_address+2
148 dec sectors_to_go
149 bne read_sectors_loop
150
151 ; Data successfully loaded (we hope), so we restore the interrupts
152 cli
153 rts
154
155
156 LoadCompressedData
157 clc
158 lda FileLoadAdressLow,x
159 sta ptr_destination+0
160 adc FileSizeLow,x
161 sta ptr_destination_end+0
162
163 lda FileLoadAdressHigh,x
164 sta ptr_destination+1
165 adc FileSizeHigh,x
166 sta ptr_destination_end+1
167
168 ;STOP(2)
169
170 jsr UnpackData
171 cli
172 rts
173
174
175 StartReadOperation
176 sei
177
178 ; Make sure the microdisc IRQ is disabled
179 jsr WaitCompletion
180
181 lda #%10000100 ; Disable the FDC (Eprom select + FDC Interrupt request)
182 sta MICRODISC
183
184 ;jsr WaitCompletion
185
186 ;
187 ; Setup, we use the table to find out where the file is located on the floppy,
188 ; where to write it in memory, and how large it is.
189 ;
190 lda FileLoadAdressHigh,x
191 sta __auto_execute_address+2
192 sta __auto_write_address+2
193
194 lda FileLoadAdressLow,x
195 sta __auto_execute_address+1
196 sta __auto_write_address+1
197
198 ; Starting track
199 ldy #%00000000 ; Side 0
200 lda FileStartTrack,x ; If the track id is larger than 128, it means it is on the other side of the floppy
201 bpl first_side
202 ; The file starts on the second side
203 ldy #%00010000 ; Side 1
204 and #%01111111 ; Mask out the extra bit
205 first_side
206 sty current_side
207 sta current_track
208
209 ; First sector
210 lda FileStartSector,x
211 sta current_sector
212
213 ; FileSizeLow/FileSizeHigh
214 ; Number of sectors to load
215 .(
216 lda FileStoredSizeHigh,x
217 sta sectors_to_go
218 lda FileStoredSizeLow,x
219 beq skip
220 inc sectors_to_go
221 skip
222 .)
223 rts
224
225
226 ReadNextSector
227 cli
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 #%00010000
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
265 inc current_sector
266
267 ; Check if the drive is on the correct track
268 lda current_track
269 cmp FDC_track_register
270 beq stay_on_the_track
271
272 ; Set the new track
273 sta FDC_data
274
275 lda #CMD_Seek
276 sta FDC_command_register
277 jsr WaitCompletion
278
279 lda #%10000100 ; on force les le Microdisk en side0, drive A ... Set le bit de données !!!
280 ora current_side
281 sta MICRODISC
282
283 stay_on_the_track
284 lda #CMD_ReadSector
285 sta FDC_command_register
286
287
288 ldy #wait_status_floppy
289 waitcommand
290 nop
291 nop
292 dey
293 bne waitcommand
294
295 ;
296 ; Read the sector data
297 ;
298 ldy #0
299 microdisc_read_data
300 lda $0318
301 bmi microdisc_read_data
302
303 lda $313
304 sta $200,y ; Store the byte in page 2
305 iny
306
307 bne microdisc_read_data
308
309 lda FDC_status_register
310 and #$1C
311
312 jsr WaitCompletion
313 cli
314 rts
315
316
317 ExecuteData
318 __auto_execute_address
319 jmp $a000
320
321
322 WaitCompletion
323 ldy #4
324 r_wait_completion
325 dey
326 bne r_wait_completion
327 r2_wait_completion
328 lda FDC_status_register
329 lsr
330 bcs r2_wait_completion
331 asl
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 ; 97 bytes, would not fit in the boot sector unfortunately...
391 SoftHiresWithCopyCharset
392 ldy #$00 ;copy charset
393 .(
394 copy_charset_loop
395 lda $b500,y
396 sta $9900,y
397 lda $b600,y
398 sta $9a00,y
399 lda $b700,y
400 sta $9b00,y
401 lda $b900,y
402 sta $9d00,y
403 lda $ba00,y
404 sta $9e00,y
405 lda $bb00,y
406 sta $9f00,y
407 dey
408 bne copy_charset_loop
409 .)
410 SoftHires
411 lda #$a0 ;clear down all memory area with zero
412 sta $01
413 lda #$00
414 sta $00 ; a = 0 from here
415 ldx #$20
416 hm_01
417 sta ($00),y
418 iny
419 bne hm_01
420 inc $01
421 dex
422 bne hm_01
423 lda #30 ;write hires switch
424 sta $bf40
425 lda #$a0 ;clear hires with #$40
426 sta $01
427 ldx #$20
428 ldx #64
429 hm_04
430 ldy #124
431 hm_05
432 lda #$40
433 sta ($00),y
434 dey
435 bpl hm_05
436 lda $00
437 adc #125
438 sta $00
439 bcc hm_02
440 inc $01
441 hm_02
442 dex
443 bne hm_04
444 rts
445
446
447
448
449
450
451 UnpackError
452 rts
453
454
455
456 GetNextByte
457 php
458 lda __fetchByte+1
459 bne __fetchByte
460 nop
461 nop
462 nop
463 nop
464 sei
465 jsr ReadNextSector
466 nop
467 nop
468 nop
469 nop
470 cli
471 ldx #0
472 ldy #0
473 __fetchByte
474 lda $200
475 inc __fetchByte+1
476 plp
477 rts
478
479 /*
480 GetNextByte
481 lda (ptr_source),y
482 ; Move stream pointer (one byte)
483 .(
484 inc ptr_source
485 bne skip
486 inc ptr_source+1
487 skip
488 .)
489 rts
490 */
491
492
493
494 ; void file_unpack(void *ptr_dst,void *ptr_src)
495
496 ; Need to be called with valid values in:
497 ; ptr_destination
498 ; ptr_source
499 ; ptr_destination_end (Destination + size)
500 UnpackData
501 ;jmp UnpackData
502 .(
503 cli
504
505 ; Initialise variables
506 ; We try to keep "y" null during all the code,
507 ; so the block copy routine has to be sure that
508 ; y is null on exit
509 ldy #0
510 sty __fetchByte+1
511 lda #1
512 sta mask_value
513
514 unpack_loop
515 ; Handle bit mask
516 lsr mask_value
517 bne end_reload_mask
518
519 jsr GetNextByte ; Read from source stream
520
521 ror
522 sta mask_value
523 end_reload_mask
524 bcc back_copy
525
526 write_byte
527 ; Copy one byte from the source stream
528 jsr GetNextByte ; Read from source stream
529 sta (ptr_destination),y
530
531 lda #1
532 sta nb_dst
533
534
535
536 _UnpackEndLoop
537 ;// We increase the current destination pointer,
538 ;// by a given value, white checking if we reach
539 ;// the end of the buffer.
540 clc
541 lda ptr_destination
542 adc nb_dst
543 sta ptr_destination
544
545 .(
546 bcc skip
547 inc ptr_destination+1
548 skip
549 .)
550 cmp ptr_destination_end
551 lda ptr_destination+1
552 sbc ptr_destination_end+1
553 bcc unpack_loop
554 rts
555
556
557 back_copy
558 ;BreakPoint jmp BreakPoint
559 ; Copy a number of bytes from the already unpacked stream
560 ; Here we know that y is null. So no need for clearing it.
561 ; Just be sure it's still null at the end.
562 ; At this point, the source pointer points to a two byte
563 ; value that actually contains a 4 bits counter, and a
564 ; 12 bit offset to point back into the depacked stream.
565 ; The counter is in the 4 high order bits.
566 ;clc <== No need, since we access this routie from a BCC
567 jsr GetNextByte ; Read from source stream
568 adc #1
569 sta offset
570 jsr GetNextByte ; Read from source stream
571 tax
572 and #$0f
573 adc #0
574 sta offset+1
575
576 txa
577 lsr
578 lsr
579 lsr
580 lsr
581 clc
582 adc #3
583 sta nb_dst
584
585 sec
586 lda ptr_destination
587 sbc offset
588 sta ptr_source_back
589 lda ptr_destination+1
590 sbc offset+1
591 sta ptr_source_back+1
592
593 ; Beware, in that loop, the direction is important
594 ; since RLE like depacking is done by recopying the
595 ; very same byte just copied... Do not make it a
596 ; reverse loop to achieve some speed gain...
597 .(
598 copy_loop
599 lda (ptr_source_back),y ; Read from already unpacked stream
600 sta (ptr_destination),y ; Write to destination buffer
601 iny
602 cpy nb_dst
603 bne copy_loop
604 .)
605 ldy #0
606 beq _UnpackEndLoop
607 rts
608 .)
609
610
611 ; Taille actuelle du code 279 octets
612 ; 0x08d7 - 0x07e8 => 239 octets
613 ; 0x08c8 - 0x07e5 => 227 octets
614 ; 0x08d5 - 0x0800 => 213 octets
615 ; 0x08c9 - 0x0800 => 201 octets
616 ; 0x08c5 - 0x0800 => 197 octets
617 ; 0x08c3 - 0x0800 => 195 octets
618 ; 0x08c0 - 0x0800 => 192 octets
619 ; => 146 octets
620
621
622 _EndLoaderCode
623
624 ;
625 ; This is free memory that can be used, when it reaches zero then the loader start address should be changed
626 ;
627
628 .dsb $FFF4 - _EndLoaderCode
629
630 _Vectors
631
632 #if ( _Vectors <> $FFF4 )
633 #error - Vector address is incorrect, loader will crash
634 #else
635
636 ;
637 ; Here are the functions that the user can call from his own application
638 ;
639 _ApiSetLoadAddress .byt $4c,<SetLoadAddress,>SetLoadAddress ; $FFF4
640 _ApiSetLoadData .byt $4c,<LoadData,>LoadData ; $FFF7
641
642 ;
643 ; These three HAVE to be at these precise adresses, they map to hardware registers
644 ;
645 _VectorNMI .word IrqDoNothing ; FFFA-FFFB - NMI Vector (Usually points to $0247)
646 _VectorReset .word IrqDoNothing ; FFFC-FFFD - RESET Vector (Usually points to $F88F)
647 _VectorIRQ .word IrqHandler ; FFFE-FFFF - IRQ Vector (Normally points to $0244)
648
649 #echo Remaining space in the loader code:
650 #print (_Vectors - _EndLoaderCode)
651
652 #endif
653
654 ; End of the loader - Nothing should come after because it's out of the addressable memory range :)
655
656 #print (UnpackError -SoftHiresWithCopyCharset)

  ViewVC Help
Powered by ViewVC 1.1.26