Loading a File from disc

If you want to ask questions about how the machine works, peculiar details, the differences between models, here it is !
How to program the oric hardware (VIA, FDC, ...) is also welcome.
User avatar
Twilighte
Game master
Posts: 819
Joined: Sat Jan 07, 2006 12:07 am
Location: Luton, UK
Contact:

Loading a File from disc

Post by Twilighte »

The following code has been simplified in that it does not currently detect errors and therefore no retries are performed if a byte is read incorrectly.

Code: Select all

;FDC Addresses
#define	fdc_command  $310
#define 	fdc_status   $0310
#define	fdc_track    $311
#define	fdc_sector   $312
#define	fdc_data     $313
#define	fdc_intrq    $314
#define	fdc_control  $314
;0
#define	fdc_drqstate $318

;Address to start loading to
#define	address	   $00
#define	loader_temp  $00
#define	loader_temp1 $01
;length of load (high only)
#define	hibyte_count $02
;sector to start loading from
#define	file_sector  $03
;Track to start loading from
#define	file_track   $04

*=$8000

example_load
; We are assuming that the BASIC ROM has already been switched out
; and therefore any Standard Routines like HIRES must be written again.
                     jsr soft_hires
;Set the start address that we wish to load data into in 'address' (low)
;and 'address+1' (High)
                     lda #<$a000
                     sta address
                     lda #>$a000
                     sta address+1
;We will load 32 sectors which evaluates as 8192 bytes (about the Size of 
;hires)
                     lda #$1F
                     sta hibyte_count
;We will start at Sector 2 on the disc.
                     lda #02
                     sta file_sector
;And Track 3
                     lda #03
                     sta file_track
;Then we can call off to load the file
                     jsr load_file
                     rts

load_file	     
;Ensure that the internal VIA irq is turned off since this routine is fairly
;precise and would crash if paused to service interrupts
                     jsr core_noirq
;Store the previously set up sector (2) in the actual FDC sector register
                     ldx file_sector
                     stx fdc_sector
;locate Track&Sector by first of all rewinding the head to Track 0 then
;using the FDC's Seek command to locate the starting Track(3).
;Note: We need to rewind the Track to 0 because we will not know which 
;         track the disc head will be on when intitially called like this.
                     jsr core_headhome
                     lda #00
                     sta fdc_track
                     lda file_track
                     sta fdc_data
                     lda #%00011100
                     sta fdc_command
;Wait for the above command to complete.
loop1	     jsr intrq_wait
;Now Read the sector
loop3	     stx fdc_sector
                     lda #%10000000
                     sta fdc_command
                     ldy #00
;As each byte arrives, the DRQstate will change, this prevents us fetching
;the same byte many times.
loop2	     lda fdc_drqstate
                     bmi loop2
;Now we can fetch the byte and store to memory
                     lda fdc_data
                     sta (address),y
;This is the 256 byte loop increment.
                     iny
                     bne loop2
;Whilst the 6502 may have read all the bytes of a sector it needs, the
;FDC may have other ideas, so we must Wait on the read command
loop4	     jsr intrq_wait
;Then we can Adjust memory, Sector and finally the Track(if appropriate)
                     inc address+1
                     inx
                     cpx #18
                     bcc loop3
                     ; Move the disc head in one track
                     ldx #01
                     jsr core_head_in
;Finally count down the high byte count (32 sectors)
                     dec hibyte_count
                     bne loop3
                     cli
                     rts

core_noirq      sei
                     ;Drv0,side0,sdm, etc.
                     lda #%10000101
                     sta fdc_control
                     rts

core_headhome
;Set the command
                     lda #%00001011
                     sta fdc_command
;And wait on it completing
                     jmp intrq_wait

core_head_in
                     lda #%01011100
                     sta fdc_command
intrq_wait
                     lda fdc_intrq
                     bmi intrq_wait
;Clear IRQ status
                     lda fdc_status
;May trap Errors here in the future
                     rts


;Ignore the details of this code, since it does not have anything todo with
;Disc but is needed to load a test Image.
soft_hires
	LDY #$00		;COPY CHARSET
.(
hm_03
	lda $b500,y
	sta $9900,y
	lda $b600,y
	sta $9a00,y
	lda $b700,y
	sta $9b00,y
	lda $b900,y

	sta $9d00,y
	lda $ba00,y
	sta $9e00,y

	lda $bb00,y
	sta $9f00,y

	dey
	bne hm_03
.)
	lda #$a0             ;clear down all memory area with zero
	sta loader_temp1
	lda #$00
	sta loader_temp
	ldy #0
	ldx #$20
.(
hm_01
	sta (loader_temp),y
	iny
	bne hm_01
	inc loader_temp1
	dex
	bne hm_01
.)
	lda #30		;write hires switch
	sta $bf40

clear_hires
	lda #0
.(
	sta r_hires_soft+1
	lda #$a0
	sta r_hires_soft+2

	ldy #200
r2_hires_soft
	lda #$40
	ldx #0
r_hires_soft
	sta $a000,x
	inx
	cpx #40
	bne r_hires_soft

	lda r_hires_soft+1
	clc
	adc #40
	bcc s_hires_soft
	inc r_hires_soft+2
s_hires_soft
	sta r_hires_soft+1
	dey
	bne r2_hires_soft
.)



	lda #$a0		;clear hires with #$40
	sta loader_temp1
	ldx #$20
	ldx #64
.(
hm_04
	ldy #124
hm_05
	lda #$40
	sta (loader_temp),y
	dey
	bpl hm_05
	lda loader_temp
	adc #125
	sta loader_temp
	bcc hm_02
	inc loader_temp1
hm_02	dex
	bne hm_04
.)
	rts