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

Contents of /public/oric/demos/OricTech/code/sector_2-microdisc.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1346 - (show annotations)
Sat Jan 9 16:14:40 2016 UTC (3 years, 8 months ago) by dbug
File size: 10312 byte(s)
Updated Oric Tech to use the new FloppyBuilder API, and fixed some bugs.
1 ;
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 cpx FDC_track_register
129 beq track_ok
130
131 ; Write the track number in the FDC data register
132 stx FDC_data
133
134 wait_drive2
135 lda FDC_drq ; We are waiting for the drive maybe not useful if drive is ready after the eprom boot
136 bmi wait_drive2
137
138 ;
139 ; Send a SEEK command (change track)
140 ;
141 lda #CMD_Seek
142 sta FDC_command_register
143 ;
144 ; 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.
145 ; Whenever a command is being executed, the Busy status bit is set.
146 ; When a command is completed, an interrupt is generated and the busy status bit is reset.
147 ; 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).
148 ldy #4
149 r_wait_completion
150 dey
151 bne r_wait_completion
152 r2_wait_completion
153 lda FDC_status_register
154 lsr
155 bcs r2_wait_completion
156 asl
157
158 track_ok
159
160 ; Write the sector number in the FDC sector register
161 __auto__sector_index
162 lda #loader_sector_position
163 sta FDC_sector_register ;
164
165 ; Interdire les IRQ du fdc ICI !
166 ;lda #%10000101 ; on force les le Microdisk en side0, drive A ... Set le bit de données !!!
167 lda #%10000100 ; on force les le Microdisk en side0, drive A ... Set le bit de données !!!
168 sta FDC_flags
169
170 ;
171 ; Send a READSECTOR command
172 ;
173 lda #CMD_ReadSector
174 sta FDC_command_register
175
176 ldy #wait_status_floppy
177 waitcommand
178 nop ; Not useful but for old Floppy drive maybe
179 nop ; Not useful but for old Floppy drive maybe
180 dey
181 bne waitcommand
182
183 ;
184 ; Read the sector data
185 ;
186 ldy #0
187 fetch_bytes_from_FDC
188 lda FDC_drq
189 bmi fetch_bytes_from_FDC
190 lda FDC_data
191 __auto_write_address
192 sta location_loader,y
193
194 iny
195 bne fetch_bytes_from_FDC
196 ; Done loading the sector
197
198 lda FDC_status_register
199 and #$1C
200
201 beq sector_OK
202 dec retry_counter
203 bne readretryloop
204
205 sector_OK
206 inc __auto__sector_index+1
207 inc __auto_write_address+2
208 dec sector_counter
209 bne read_sectors_loop
210
211 ;
212 ; Data successfully loader (we hope)
213 ;
214 sei
215 lda #%10000001 ; Disable the FDC (Eprom select + FDC Interrupt request)
216 sta FDC_flags
217
218 ldx #FDC_OFFSET_MICRODISC
219 jmp location_loader
220
221
222 sector_counter .byt (($FFFF-location_loader)+1)/256
223
224
225 _END_
226
227
228
229 ; Type I commands
230 ; The type I commands include the Restore, Seek, Step, Step-In and Step-
231 ; Out commands. Each of the Type I commands contains a rate field r1 r0
232 ; which determines the stepping motor rate.
233 ; r1 r0 Stepping rate
234 ; 0 0 6 ms
235 ; 0 1 12 ms
236 ; 1 0 20 ms
237 ; 1 1 30 ms
238 ; An optional verification of head position can be performed by settling
239 ; bit 2 (V=1) in the command word. The track number from the first
240 ; encountered ID Field is compared against the contents of the Track
241 ; Register. If the track numbers compare (and the ID Field CRC is correct)
242 ; the verify operation is complete and an INTRQ is generated with no
243 ; errors.
244 ;
245 ; Seek
246 ; This command assumes that the Track Register contains the track number
247 ; of the current position of the head and the Data Register contains the
248 ; desired track number. The FD179X will update the Track Register and
249 ; issue stepping pulses in the appropriate direction until the contents of
250 ; the Track Register are equal to the contents of the Data Register. An
251 ; interrupt is generated at the completion of the command. Note: when
252 ; using multiple drives, the track register must be updated for the drive
253 ; selected before seeks are issued.
254
255 ;
256 ; Type II commands
257 ; Type II commands are the Read Sector and Write Sector commands. Prior
258 ; to loading the Type II command into the Command Register, the computer
259 ; must load the Sector Register with the desired sector number. Upon
260 ; receipt of the Type II command, the busy status bit is set. The FD179X
261 ; must find an ID field with a matching Track number and Sector number,
262 ; otherwise the Record not found status bit is set and the command is
263 ; terminated with an interrupt. Each of the Type II commands contains an
264 ; m flag which determines if multiple records (sectors) are to be read or
265 ; written. If m=0, a single sector is read or written and an interrupt is
266 ; generated at the completion of the command. If m=1, multiple records are
267 ; read or written with the sector register internally updated so that an
268 ; address verification can occur on the next record. The FD179X will
269 ; continue to read or write multiple records and update the sector
270 ; register in numerical ascending sequence until the sector register
271 ; exceeds the number of sectors on the track or until the Force Interrupt
272 ; command is loaded into the Command Register. The Type II commands for
273 ; 1791-94 also contain side select compare flags. When C=0 (bit 1), no
274 ; comparison is made. When C=1, the LSB of the side number is read off the
275 ; ID Field of the disk and compared with the contents of the S flag.
276 ;
277 ; Read Sector
278 ; Upon receipt of the command, the head is loaded, the busy status bit set
279 ; and when an ID field is encountered that has the correct track number,
280 ; correct sector number, correct side number, and correct CRC, the data
281 ; field is presented to the computer. An DRQ is generated each time a byte
282 ; is transferred to the DR. At the end of the Read operation, the type of
283 ; Data Address Mark encountered in the data field is recorded in the
284 ; Status Register (bit 5).
285 ;
286
287
288 /*
289 From: http://www.metabarn.com/v1050/docs/v1050_ProgTechDoc.txt
290
291 During a command which performs a data transfer such as diskette
292 read or write, data must be read from or written to the diskettes
293 byte-by—byte via the Z-80A. This can be done either by polling
294 the WD1793 data request bit (DRQ, status bit 1) or by the DRQ
295 interrupt. Reading or writing the data register will reset both
296 the DRQ bit and interrupt. The total time between byte transfers
297 is 23 microseconds for 5" double density or 8" single density;
298 the polling loop or interrupt service routine must be shorter
299 than this to insure that no bytes are lost.
300
301 The diskette motors are turned on by resetting bit 6 of port A of
302 the miscellaneous 8255, and turned off by setting the same bit.
303 Our BIOS code turns the motors on, then leaves them on for two
304 seconds to save time in the case of multiple disk accesses.
305 After turning on the motors, you must wait 800 ms. to be sure
306 that the drives are up to speed before attempting to transfer
307 data. The Ready input of the WD1793 is supplied from pin 34 of
308 the drive interface; it indicates that the drive is loaded and
309 has made at least one revolution at > 50% of normal speed. Note
310 that the drive looks at the index pulse for this; if a hard-
311 sectored disk is inserted the results are invalid.
312
313 The reset line of the WD1793 is held in the reset mode by
314 hardware at power-on. A timing restriction is inherent in the
315 WD1793: after writing a command, the Z-80A must not read the
316 status register for 28 microseconds.
317
318 */

  ViewVC Help
Powered by ViewVC 1.1.26