6502 routines/lib repository

Here you can ask questions or provide insights about how to use efficiently 6502 assembly code on the Oric.
User avatar
kamelito
Flying Officer
Posts: 182
Joined: Sun Jan 08, 2006 6:34 pm
Location: Nantes, France

6502 routines/lib repository

Post by kamelito »

Hi all,

It would be nice IMHO to have a repository in this forum where coder will put their routines/lib source code so others could use them to create games, demo, compo stuffs etc ...

The aim should be to do not reinvent the wheel and to be more productive.
Routines/lib optimized, updated, upgraded could then be re-released.

At the end everybody will have the routines they need like read a file from disk, play sample, draw sprite, move sprite, clear screen, write text etc.

What do you think, I think its a nice idea but I might be wrong...

Regards
Kamel
/kml
skype pseudo : kamelitoloveless
User avatar
kamelito
Flying Officer
Posts: 182
Joined: Sun Jan 08, 2006 6:34 pm
Location: Nantes, France

Re: 6502 routines/lib repository

Post by kamelito »

Re

code could be low level algorithm implementation or more api like.
Intersting stuff available at :

http://6502.org/source/
http://www.ffd2.com/fridge/

Regards
Kamel
/kml
skype pseudo : kamelitoloveless
User avatar
Twilighte
Game master
Posts: 819
Joined: Sat Jan 07, 2006 12:07 am
Location: Luton, UK
Contact:

Post by Twilighte »

This routine may not be useful to everyone, but i used it in the later versions of Sonix to set the maximum volume for a song.

Code: Select all

	lda Maximum_volume
	eor #15
	sta real_volume
	ldx #02
loop1	lda SourceVolume,x
	sec
	sbc real_volume
	bcs skip1
	lda #00
skip1	sta RegisterVolume,x
	dex
	bpl loop1
	rts
The maximum volume is 0 to 15.
Best to work with example...
Three source volumes are 2,6 and 14 and the maximum volume is 12.
We exclusive OR the maximum volume with 15 to get 3.
We then subtract 3 from 14 to get 11 for channel C, and then on the second loop do the same for Channel B and get 3.
Finally we subtract 3 from 2 and since a borrow will occur, we reset the volume to Zero.
So from 2,6 and 14 with a maximum volume of 12, we get 11, 3 and 0 which is proportionally less volume.

In music this works better than just having a limited volume of 12. ;)
User avatar
Twilighte
Game master
Posts: 819
Joined: Sat Jan 07, 2006 12:07 am
Location: Luton, UK
Contact:

Post by Twilighte »

Here is another routine to calculate the pitch for a note in the range 0 to 127 as used in Sonix.
In music, each note is twice the frequency of the same note in the next lower octave.
On this basis, we can perform a Note to 12 (or 16 bit) pitch conversion using this simple routine...

Code: Select all

Note to Pitch
        lda Note	;0-127
        ;Perform Modulo12 on Note
        ldx #255
        sec
loop1   inx
        sbc #12
        bcs loop1
        adc #12
        ;A holds Real Note, X now holds Octave
        stx Octave
        tax
        ;Fetch Base Pitch for lowest Semitone
        lda Base_Pitch_lo,x
        sta Pitch_lo
        lda Base_Pitch_hi,x
        cpx #00
        beq Skip1	;No shifts required
        ;Shift up to required Octave
loop2   lsr
        ror Pitch_Lo
        dex
        bne loop2
skip1   sta Pitch_Hi
        rts
The values for the two base pitch tables (12 Bytes each) are as follows...

Code: Select all

base_pitch_lo
 .byt $ee,$16,$4c,$8e,$d8,$2e,$8e,$f6,$66,$e0,$60,$e8
base_pitch_hi
 .byt $0e,$0e,$0d,$0c,$0b,$0b,$0a,$09,$09,$08,$08,$07
User avatar
Chema
Game master
Posts: 3014
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Disk access sector based.

Post by Chema »

This set of routines were developed by Fabrice for using in Pinforic Infocom Interpreter. They access a disk sector by sector with a quite easy-to-use C interface. Technical questions, ask Fabrice!

Code: Select all

__sectors_per_track db 9
__double_sided db $ff
__stepping_rate db 0	; 6 ms
sectors_per_cyl db 0

_init_disk
	php
	sei
	lda #LOW(irq_handler)
	sta $fffe
	lda #HIGH(irq_handler)
	sta $ffff
	jsr restore_track0
	plp
	rts

_sect_write
	lda #$a0	; write command
	bne sect_rw
_sect_read
	lda #$80	; read command
sect_rw
	sta readwrite

	ldy #2
	lda (sp),y
	sta __buffer
	iny
	lda (sp),y
	sta __buffer+1

	jsr __linear_to_physical_sector
	jsr __sector_readwrite
	ldx #0
	rts

__linear_to_physical_sector
	ldy #0
	lda (sp),y
	tax
	iny
	lda (sp),y
	tay
	txa

	ldx __sectors_per_track
	stx sectors_per_cyl
	ldx #$ff
	bit __double_sided
	bpl compute_cylinder
	asl sectors_per_cyl
compute_cylinder
	inx
	sec
	sbc sectors_per_cyl
	bcs compute_cylinder
	dey
	bpl compute_cylinder
	adc sectors_per_cyl

	stx __cylinder
	ldy #0
	cmp __sectors_per_track
	bcc store_side
	ldy #$10
	sbc __sectors_per_track
store_side
	sty __side
	tay
	iny
	sty __sector

	rts


__sector db 0
__cylinder db 0
__side db 0
__status db 0
__buffer dw 0

restart_counter db 0
readwrite db 0
old_ier db 0

save_ier
	ldy $030e
	sty old_ier
	ldy #$7f
	sty $030e
	rts

restore_ier
	ldy old_ier
	sty $030e
	rts

wait_completion
	lda $0314
	bmi wait_completion
	lda $0310
	rts

restore_track0
	lda #$0C
	sta $0310
	jsr wait_completion
	and #$10	; seek error ?
	bne restore_track0
	rts

seek_track
	lda #$1C
	ora __stepping_rate
	sta $0310
	jsr wait_completion
	and #$18	; seek error or CRC error ?
	beq seek_ok
	jsr restore_track0
	beq seek_track
seek_ok
	rts
	
__select_sector
	lda $04fb	; current drive/side selection
	and #$ef
	ora __side
	sta $04fb	; side updated
	ora #$01	; enables FDC interrupts
	sta $0314

	lda __cylinder
	sta $0313
	cmp $0311
	beq *+5
	jsr seek_track
	lda __sector
	sta $0312
	rts

readwrite_data
	cli
	lda #0
	sta $f3
	lda __buffer+1
	sta $f4
	ldy __buffer
	lda readwrite
	cmp #$a0
	beq write_data
read_data
	lda $0318
	bmi read_data
	lda $0313
	sta ($f3),y
	iny
	bne read_data
	inc $f4
	jmp read_data
write_data
	lda $0318
	bmi write_data
	lda ($f3),y
	sta $0313
	iny
	bne write_data
	inc $f4
	jmp write_data
	
irq_handler
	bit $0314
	bpl fdc_irq
	jmp $04f5
fdc_irq
	pla		; get rid of IRQ context
	pla
	pla
	lda $04fb
	sta $0314	; disables disk irq
	lda $0310	; gets status and resets irq
	and #$7c
	sta __status
	rts
	
__sector_readwrite
	php
	sei
	jsr save_ier
	ldy #8
	sty restart_counter
again
	jsr __select_sector
	lda readwrite
	sta $0310
	jsr readwrite_data
	lda __status
	beq success
	dec restart_counter
	bne again
success
	jsr restore_ier
	plp
	rts
User avatar
Dbug
Site Admin
Posts: 4444
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug »

I guess that this kind of read/write functions could be integrated in the OSDK, sounds good :)
User avatar
Chema
Game master
Posts: 3014
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Post by Chema »

Dbug wrote:I guess that this kind of read/write functions could be integrated in the OSDK, sounds good :)
Now that you mention it DBug... I have the whole sources of Pinforic (really Fabrice's version). We used the old oric C compiler for Linux and had to make many changes (even in the library) to make it work correctly... I remember adding the switching of the ROM in and out in some functions that called ROM routines.

I am telling this because maybe, in the future, you want to test if these sources could be compiled with the OSDK.. :)
Post Reply