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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26