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

  ViewVC Help
Powered by ViewVC 1.1.26