/[projet1]/public/oric/demos/PushingTheEnvelope/code/sector_2-microdisc.asm
Defence Force logotype

Annotation of /public/oric/demos/PushingTheEnvelope/code/sector_2-microdisc.asm

Parent Directory Parent Directory | Revision Log Revision Log


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



1 dbug 1099 ;
2     ; This part of the code is a bit tricky: Basically the Atmos with Microdisc and the Telestrat despite using a similar boot
3     ; loading system are actually loading the boot sector at different addresses.
4     ;
5     ; Since the 6502 is not particularly well equiped to handle code that can be loaded at any address we had to find a trick.
6     ; What we are doing is to make the code run at a particular address, and have a small module that makes sure that it is
7     ; moved at the correct place wherever it was loaded in first place. That makes the code a lot easier to write :)
8     ;
9     ; Warning: This whole code CANNOT be more than 256 bytes (ie: the size of the sector)
10     ;
11     ; The bootloader will be placed in the screen area because we know that this is not going to be used by the operating system.
12     ; By chosing an address in HIRES area, we also guarantee that it will not be visible on the screen (the Oric boots in TEXT).
13     ;
14     //#define FINAL_ADRESS $a000+50*40
15     #define FINAL_ADRESS $9800 ; First 256 bytes of the STD charset are invisible
16    
17    
18     #define OPCODE_RTS $60
19    
20     #define MICRODISC_LOADER
21     #include "disk_info.h"
22    
23     .zero
24    
25     *=$00
26    
27     retry_counter .dsb 1 ; Number of attempts at loading data (ie: not quite clear what happens when this fails...)
28    
29    
30     .text
31    
32     ;
33     ; These are the 23 header bytes that goes before the actual executable part of the bootsector
34     ;
35     .byt $00,$00,$FF,$00,$D0,$9F,$D0,$9F,$02,$B9,$01,$00,$FF,$00,$00,$B9,$E4,$B9,$00,$00,$E6,$12,$00
36    
37     .text
38    
39     ;
40     ; Here starts the actual executable part, maximum available size is 233 bytes (256-23)
41     ;
42    
43     ;
44     ; Try to find the load address
45     ;
46     sei ; Disable interruptions
47    
48     lda #OPCODE_RTS
49     sta $00 ; Write in $00 Page => take one less byte
50     jsr $0000 ; JSR on the RTS immediately return.
51    
52     ;
53     ; Compute the absolute address of where the code we want to copy begins,
54     ; and save it in zero page ($00 and $01)
55     ;
56     _start_relocator_
57     tsx ; Get stack offset
58     dex
59     clc
60     lda $0100,x ; Get LOW adress byte
61     adc #<(_end_relocator_-_start_relocator_+1)
62     sta $00
63     lda $0101,x ; Get HIGH adress byte
64     adc #>(_end_relocator_-_start_relocator_+1)
65     sta $01
66    
67     ; Now $00 and $01 contain the adress of LABEL
68     ; We can now copy the whole code to it's new
69     ; location
70     ldy #0
71     copy_loop
72     lda ($00),y
73     sta FINAL_ADRESS,y
74     iny
75     cpy _END_-_BEGIN_
76     bne copy_loop
77    
78     jmp FINAL_ADRESS
79     _end_relocator_
80    
81    
82     ;
83     ; Here is some code compiled at a fixed adress in memory.
84     ;
85    
86     *=FINAL_ADRESS
87    
88     _BEGIN_
89     ;
90     ; Switch to HIRES
91     ;
92     ldy #39 ; From $9900 to $c000 is 39 pages (9984 bytes)
93     lda #0
94     loop_hires_outer
95     tax
96     loop_hires_inner
97     __auto_hires
98     sta $9900,x
99     inx
100     bne loop_hires_inner
101     inc __auto_hires+2
102     dey
103     bne loop_hires_outer
104    
105     lda #30 ; Write hires switch
106     sta $bfdf
107    
108    
109     ;
110     ; Read sector data
111     ;
112     ldy #4
113     sty retry_counter
114     read_sectors_loop
115    
116     readretryloop
117     nop
118     nop
119     nop
120    
121     read_one_sector
122     ;
123     ; Check if we are on the correct track already and if not
124     ; then send a SEEK command to the FDC to move the head to
125     ; the correct track.
126     ;
127     ldx #loader_track_position
128 Jede 1403 .dsb ((FDC_track_register&3)-((*+3)&3))&3,$ea
129 dbug 1099 cpx FDC_track_register
130     beq track_ok
131    
132 Jede 1403 .dsb ((FDC_data&3)-((*+3)&3))&3,$ea
133 dbug 1099 ; Write the track number in the FDC data register
134     stx FDC_data
135    
136 Jede 1403 .dsb ((FDC_drq&3)-((*+3)&3))&3,$ea
137 dbug 1099 wait_drive2
138     lda FDC_drq ; We are waiting for the drive maybe not useful if drive is ready after the eprom boot
139     bmi wait_drive2
140    
141     ;
142     ; Send a SEEK command (change track)
143     ;
144     lda #CMD_Seek
145 Jede 1403 .dsb ((FDC_command_register&3)-((*+3)&3))&3,$ea
146 dbug 1099 sta FDC_command_register
147     ;
148     ; Command words should only be loaded in the Command Register when the Busy status bit is off (Status bit 0). The one exception is the Force Interrupt command.
149     ; Whenever a command is being executed, the Busy status bit is set.
150     ; When a command is completed, an interrupt is generated and the busy status bit is reset.
151     ; The Status Register indicates whethter the completed command encountered an error or was fault free. For ease of discussion, commands are divided into four types (I, II, III, IV).
152     ldy #4
153     r_wait_completion
154     dey
155     bne r_wait_completion
156 Jede 1403 .dsb ((FDC_status_register&3)-((*+3)&3))&3,$ea
157 dbug 1099 r2_wait_completion
158     lda FDC_status_register
159     lsr
160     bcs r2_wait_completion
161     asl
162    
163     track_ok
164    
165     ; Write the sector number in the FDC sector register
166     __auto__sector_index
167     lda #loader_sector_position
168 Jede 1403 .dsb ((FDC_sector_register&3)-((*+3)&3))&3,$ea
169 dbug 1099 sta FDC_sector_register ;
170    
171     ; Interdire les IRQ du fdc ICI !
172     ;lda #%10000101 ; on force les le Microdisk en side0, drive A ... Set le bit de données !!!
173     lda #%10000100 ; on force les le Microdisk en side0, drive A ... Set le bit de données !!!
174     sta FDC_flags
175    
176     ;
177     ; Send a READSECTOR command
178     ;
179     lda #CMD_ReadSector
180 Jede 1403 .dsb ((FDC_command_register&3)-((*+3)&3))&3,$ea
181 dbug 1099 sta FDC_command_register
182    
183     ldy #wait_status_floppy
184     waitcommand
185     nop ; Not useful but for old Floppy drive maybe
186     nop ; Not useful but for old Floppy drive maybe
187     dey
188     bne waitcommand
189    
190     ;
191     ; Read the sector data
192     ;
193     ldy #0
194 Jede 1403 .dsb ((FDC_drq&3)-((*+3)&3))&3,$ea
195 dbug 1099 fetch_bytes_from_FDC
196     lda FDC_drq
197     bmi fetch_bytes_from_FDC
198 Jede 1403 .dsb ((FDC_data&3)-((*+3)&3))&3,$ea
199 dbug 1099 lda FDC_data
200     __auto_write_address
201     sta location_loader,y
202    
203     iny
204     bne fetch_bytes_from_FDC
205     ; Done loading the sector
206    
207 Jede 1403 .dsb ((FDC_status_register&3)-((*+3)&3))&3,$ea
208 dbug 1099 lda FDC_status_register
209     and #$1C
210    
211     beq sector_OK
212     dec retry_counter
213     bne readretryloop
214    
215     sector_OK
216     inc __auto__sector_index+1
217     inc __auto_write_address+2
218     dec sector_counter
219     bne read_sectors_loop
220    
221     ;
222     ; Data successfully loader (we hope)
223     ;
224     sei
225     lda #%10000001 ; Disable the FDC (Eprom select + FDC Interrupt request)
226     sta FDC_flags
227    
228     ldx #FDC_OFFSET_MICRODISC
229     jmp location_loader
230    
231    
232     sector_counter .byt (($FFFF-location_loader)+1)/256
233    
234    
235     _END_
236    
237    
238    
239     ; Type I commands
240     ; The type I commands include the Restore, Seek, Step, Step-In and Step-
241     ; Out commands. Each of the Type I commands contains a rate field r1 r0
242     ; which determines the stepping motor rate.
243     ; r1 r0 Stepping rate
244     ; 0 0 6 ms
245     ; 0 1 12 ms
246     ; 1 0 20 ms
247     ; 1 1 30 ms
248     ; An optional verification of head position can be performed by settling
249     ; bit 2 (V=1) in the command word. The track number from the first
250     ; encountered ID Field is compared against the contents of the Track
251     ; Register. If the track numbers compare (and the ID Field CRC is correct)
252     ; the verify operation is complete and an INTRQ is generated with no
253     ; errors.
254     ;
255     ; Seek
256     ; This command assumes that the Track Register contains the track number
257     ; of the current position of the head and the Data Register contains the
258     ; desired track number. The FD179X will update the Track Register and
259     ; issue stepping pulses in the appropriate direction until the contents of
260     ; the Track Register are equal to the contents of the Data Register. An
261     ; interrupt is generated at the completion of the command. Note: when
262     ; using multiple drives, the track register must be updated for the drive
263     ; selected before seeks are issued.
264    
265     ;
266     ; Type II commands
267     ; Type II commands are the Read Sector and Write Sector commands. Prior
268     ; to loading the Type II command into the Command Register, the computer
269     ; must load the Sector Register with the desired sector number. Upon
270     ; receipt of the Type II command, the busy status bit is set. The FD179X
271     ; must find an ID field with a matching Track number and Sector number,
272     ; otherwise the Record not found status bit is set and the command is
273     ; terminated with an interrupt. Each of the Type II commands contains an
274     ; m flag which determines if multiple records (sectors) are to be read or
275     ; written. If m=0, a single sector is read or written and an interrupt is
276     ; generated at the completion of the command. If m=1, multiple records are
277     ; read or written with the sector register internally updated so that an
278     ; address verification can occur on the next record. The FD179X will
279     ; continue to read or write multiple records and update the sector
280     ; register in numerical ascending sequence until the sector register
281     ; exceeds the number of sectors on the track or until the Force Interrupt
282     ; command is loaded into the Command Register. The Type II commands for
283     ; 1791-94 also contain side select compare flags. When C=0 (bit 1), no
284     ; comparison is made. When C=1, the LSB of the side number is read off the
285     ; ID Field of the disk and compared with the contents of the S flag.
286     ;
287     ; Read Sector
288     ; Upon receipt of the command, the head is loaded, the busy status bit set
289     ; and when an ID field is encountered that has the correct track number,
290     ; correct sector number, correct side number, and correct CRC, the data
291     ; field is presented to the computer. An DRQ is generated each time a byte
292     ; is transferred to the DR. At the end of the Read operation, the type of
293     ; Data Address Mark encountered in the data field is recorded in the
294     ; Status Register (bit 5).
295     ;
296    
297    
298     /*
299     From: http://www.metabarn.com/v1050/docs/v1050_ProgTechDoc.txt
300    
301     During a command which performs a data transfer such as diskette
302     read or write, data must be read from or written to the diskettes
303     byte-by—byte via the Z-80A. This can be done either by polling
304     the WD1793 data request bit (DRQ, status bit 1) or by the DRQ
305     interrupt. Reading or writing the data register will reset both
306     the DRQ bit and interrupt. The total time between byte transfers
307     is 23 microseconds for 5" double density or 8" single density;
308     the polling loop or interrupt service routine must be shorter
309     than this to insure that no bytes are lost.
310    
311     The diskette motors are turned on by resetting bit 6 of port A of
312     the miscellaneous 8255, and turned off by setting the same bit.
313     Our BIOS code turns the motors on, then leaves them on for two
314     seconds to save time in the case of multiple disk accesses.
315     After turning on the motors, you must wait 800 ms. to be sure
316     that the drives are up to speed before attempting to transfer
317     data. The Ready input of the WD1793 is supplied from pin 34 of
318     the drive interface; it indicates that the drive is loaded and
319     has made at least one revolution at > 50% of normal speed. Note
320     that the drive looks at the index pulse for this; if a hard-
321     sectored disk is inserted the results are invalid.
322    
323     The reset line of the WD1793 is held in the reset mode by
324     hardware at power-on. A timing restriction is inherent in the
325     WD1793: after writing a command, the Z-80A must not read the
326     status register for 28 microseconds.
327    
328     */

  ViewVC Help
Powered by ViewVC 1.1.26