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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1403 - (show annotations)
Mon Apr 17 20:43:40 2017 UTC (2 years, 5 months ago) by Jede
File size: 11043 byte(s)
Telestrat correction



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 bne 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 #else
262 cli
263 jsr WaitCommand
264 sei
265 #endif
266
267 lda current_sector
268 .dsb ((FDC_sector_register&3)-((*+3)&3))&3,$ea
269 sta FDC_sector_register,y
270 inc current_sector
271
272 ; Check if the drive is on the correct track
273 lda current_track
274 .dsb ((FDC_track_register&3)-((*+3)&3))&3,$ea
275 cmp FDC_track_register,y
276 beq stay_on_the_track
277
278 .dsb ((FDC_data&3)-((*+3)&3))&3,$ea
279 ; Set the new track
280 sta FDC_data,y
281
282 lda #CMD_Seek
283 .dsb ((FDC_command_register&3)-((*+3)&3))&3,$ea
284 sta FDC_command_register,y
285 jsr WaitCompletion
286
287 stay_on_the_track
288 lda #%10000100 ; on force les le Microdisk en side0, drive A ... Set le bit de données !!!
289 ora current_side
290 sta FDC_flags,y
291
292 lda #CMD_ReadSector
293 .dsb ((FDC_command_register&3)-((*+3)&3))&3,$ea
294 sta FDC_command_register,y
295
296 ;cli
297 jsr WaitCommand
298 ;sei
299
300 ;
301 ; Read the sector data
302 ;
303 ldx #0
304 .dsb (($318&3)-((*+3)&3))&3,$ea
305 microdisc_read_data
306 lda $0318
307 bmi microdisc_read_data
308 ;.dsb ((FDC_data&3)-((*+3)&3))&3,$ea
309 lda FDC_data,y
310 sta $200,x ; Store the byte in page 2
311 inx
312
313 bne microdisc_read_data
314
315 .dsb ((FDC_status_register&3)-((*+3)&3))&3,$ea
316 lda FDC_status_register,y
317 and #$1C
318
319 jsr WaitCompletion
320 cli
321 rts
322
323 WaitCommand
324 ldx #wait_status_floppy
325 waitcommand
326 nop
327 nop
328 dex
329 bne waitcommand
330 rts
331
332 WaitCompletion
333 txa
334 pha
335
336 php
337 sei
338 nop
339 nop
340 nop
341
342 ldx #4
343 r_wait_completion
344 dex
345 bne r_wait_completion
346 plp
347
348
349 .dsb ((FDC_status_register&3)-((*+3)&3))&3,$ea
350 r2_wait_completion
351 lda FDC_status_register,y
352 lsr
353 bcs r2_wait_completion
354
355 ;asl
356 pla
357 tax
358 rts
359
360 #ifdef LOADER_SHOW_DEBUGINFO
361 HexData .byt "0123456789ABCDEF"
362
363 DisplayPosition
364 .(
365 lda current_side
366 lsr
367 lsr
368 lsr
369 lsr
370 tax
371 lda HexData,x
372 sta $bb80+40*27+0
373
374 lda #3
375 sta $bb80+40*27+1
376
377 lda current_track
378 lsr
379 lsr
380 lsr
381 lsr
382 tax
383 lda HexData,x
384 sta $bb80+40*27+2
385
386 lda current_track
387 and #15
388 tax
389 lda HexData,x
390 sta $bb80+40*27+3
391
392 lda #2
393 sta $bb80+40*27+4
394
395 lda current_sector
396 lsr
397 lsr
398 lsr
399 lsr
400 tax
401 lda HexData,x
402 sta $bb80+40*27+5
403
404 lda current_sector
405 and #15
406 tax
407 lda HexData,x
408 sta $bb80+40*27+6
409
410 ;jsr WaitLoop
411 rts
412 .)
413 #endif
414
415
416 GetNextByte
417 php
418 lda __fetchByte+1
419 bne __fetchByte
420 nop
421 nop
422 nop
423 nop
424 sei
425 jsr ReadNextSector
426 nop
427 nop
428 nop
429 nop
430 cli
431 ldx #0
432 ldy #0
433 __fetchByte
434 lda $200
435 inc __fetchByte+1
436 plp
437 rts
438
439
440
441 ; void file_unpack(void *ptr_dst,void *ptr_src)
442
443 ; Need to be called with valid values in:
444 ; ptr_destination
445 ; ptr_source
446 ; ptr_destination_end (Destination + size)
447 UnpackData
448 ;jmp UnpackData
449 .(
450 cli
451
452 ; Initialise variables
453 ; We try to keep "y" null during all the code,
454 ; so the block copy routine has to be sure that
455 ; y is null on exit
456 ldy #0
457 sty __fetchByte+1
458 lda #1
459 sta mask_value
460
461 unpack_loop
462 ; Handle bit mask
463 lsr mask_value
464 bne end_reload_mask
465
466 jsr GetNextByte ; Read from source stream
467
468 ror
469 sta mask_value
470 end_reload_mask
471 bcc back_copy
472
473 write_byte
474 ; Copy one byte from the source stream
475 jsr GetNextByte ; Read from source stream
476 sta (ptr_destination),y
477
478 lda #1
479 sta nb_dst
480
481
482
483 _UnpackEndLoop
484 ;// We increase the current destination pointer,
485 ;// by a given value, white checking if we reach
486 ;// the end of the buffer.
487 clc
488 lda ptr_destination
489 adc nb_dst
490 sta ptr_destination
491
492 .(
493 bcc skip
494 inc ptr_destination+1
495 skip
496 .)
497 cmp ptr_destination_end
498 lda ptr_destination+1
499 sbc ptr_destination_end+1
500 bcc unpack_loop
501 rts
502
503
504 back_copy
505 ;BreakPoint jmp BreakPoint
506 ; Copy a number of bytes from the already unpacked stream
507 ; Here we know that y is null. So no need for clearing it.
508 ; Just be sure it's still null at the end.
509 ; 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.
510 ; The counter is in the 4 high order bits.
511 ;clc <== No need, since we access this routie from a BCC
512 jsr GetNextByte ; Read from source stream
513 adc #1
514 sta offset
515 jsr GetNextByte ; Read from source stream
516 tax
517 and #$0f
518 adc #0
519 sta offset+1
520
521 txa
522 lsr
523 lsr
524 lsr
525 lsr
526 clc
527 adc #3
528 sta nb_dst
529
530 sec
531 lda ptr_destination
532 sbc offset
533 sta ptr_source_back
534 lda ptr_destination+1
535 sbc offset+1
536 sta ptr_source_back+1
537
538 ; Beware, in that loop, the direction is important
539 ; since RLE like depacking is done by recopying the
540 ; very same byte just copied... Do not make it a
541 ; reverse loop to achieve some speed gain...
542 .(
543 copy_loop
544 lda (ptr_source_back),y ; Read from already unpacked stream
545 sta (ptr_destination),y ; Write to destination buffer
546 iny
547 cpy nb_dst
548 bne copy_loop
549 .)
550 ldy #0
551 beq _UnpackEndLoop
552 rts
553 .)
554
555 _EndLoaderCode
556
557 ;
558 ; This is free memory that can be used, when it reaches zero then the loader start address should be changed
559 ;
560
561 .dsb $FFF4 - _EndLoaderCode
562
563 _Vectors
564
565 #if ( _Vectors <> $FFF4 )
566 #error - Vector address is incorrect, loader will crash
567 #else
568
569 ;
570 ; Here are the functions that the user can call from his own application
571 ;
572 _ApiSetLoadAddress .byt $4c,<SetLoadAddress,>SetLoadAddress ; $FFF4
573 _ApiSetLoadData .byt $4c,<LoadData,>LoadData ; $FFF7
574
575 ;
576 ; These three HAVE to be at these precise adresses, they map to hardware registers
577 ;
578 _VectorNMI .word IrqDoNothing ; FFFA-FFFB - NMI Vector (Usually points to $0247)
579 _VectorReset .word IrqDoNothing ; FFFC-FFFD - RESET Vector (Usually points to $F88F)
580 _VectorIRQ .word IrqHandler ; FFFE-FFFF - IRQ Vector (Normally points to $0244)
581
582 #echo Remaining space in the loader code:
583 #print (_Vectors - _EndLoaderCode)
584
585 #endif
586
587 ; End of the loader - Nothing should come after because it's out of the addressable memory range :)
588

  ViewVC Help
Powered by ViewVC 1.1.26