Jump to content
Eagle

My experiments with Atari 7800

Recommended Posts

Well, it still might be a problem. The number of scanlines is hardcoded into Maria, so an NTSC deck won't display all of the lines in a PAL game. When running PAL on NTSC, best case you'll get a cropped screen and a game that runs a bit too fast, worst case the game will crash due to an expected-but-missing interrupt in the cropped portion of the screen.

Share this post


Link to post
Share on other sites

Yes I know. But I have few ideas. 

Today OutRun - Last Wave (No Waves)

 

http://www.vgmpf.com/Wiki/index.php?title=OutRun_(ARC)

 

Also I've made some PAL test with Miker songs and he reported that 2 instruments was too loud.

So there is some bug/feature in Deflamask with TL in OP4 ;)

After changing TL to 25 for this instruments everything start playing as normal.

 

outrun.a78

  • Like 2

Share this post


Link to post
Share on other sites
9 minutes ago, Eagle said:

Squadron again (NTSC)

Let me know if it works on ntsc A7800

That sounds great here on my NTSC machine. 👍

  • Thanks 1

Share this post


Link to post
Share on other sites

Thanks @DrVenkman

So I can publish beta version Deflamask VGM player.

Yo can use in PAL mode as well so you need change 

sub_frame = pal_wait

and header (byte 57 -> 1)

 

Save song in Deflamask as VGM

Unfortunately song can't be longer than 44kb (for now)

Player in MADS format.

Enjoy

 

 

		icl 'maria.h'

		opt f+h-

		org $40
dest 	.ds 2 		;2 bytes
sour	.ds 2
counter .ds 2

          ORG     $4000-128
HEADER       .byte    1  			; 0   Header version     - 1 byte
        .by    "ATARI7800       "	; 1..16  "ATARI7800   "  - 16 bytes
        .by    "VGMPlayer YM2151"	; 17..48 Cart title      - 32 bytes
        .by    "   2021 Eagle   "	; 2 line
        DTA r	($C000)				; 49..52 data length      - 4 bytes (Big-endian format)
        .byte    $08,$08  			; 53..54 cart type      - 2 bytes
    ;    bit 0 - pokey at $4000
    ;    bit 1 - supergame bank switched
    ;    bit 2 - supergame ram at $4000
    ;    bit 3 - rom at $4000
    ;    bit 4 - bank 6 at $4000
    ;    bit 5 - supergame banked ram
    ;    bit 6 - pokey at $450
    ;    bit 7 - mirror ram at $4000
    ;    bit 8-15 - Special
    ;   0 = Normal cart
        .byte     2  ; 55   controller 1 type  - 1 byte
        .byte     0  ; 56   controller 2 type  - 1 byte
    ;    0 = None
    ;    1 = Joystick
    ;    2 = Light Gun
        .byte    0  ; 57 0 = NTSC 1 = PAL
        .byte    0  ; 58   Save data peripheral - 1 byte (version 2)
    ;    0 = None / unknown (default)
    ;    1 = High Score Cart (HSC)
    ;    2 = SaveKey
        .byte 0,0,0,0	;ORG     HEADER+63
        .byte    0  ; 63   Expansion module
    ;    0 = No expansion module (default on all currently released games)
    ;    1 = Expansion module required
	.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
     ;   ORG     HEADER+100      ; 100..127 "ACTUAL CART DATA STARTS HERE" - 28 bytes
        .by    "ACTUAL CART DATA STARTS HERE"

	.macro clear_ram
	ldy #$00
	MWA #:1 dest
	lda #$00
@	sta (dest),y
	INW dest
	lda dest+1
	cmp #>[:2+1]
	bne @-
	.endm


            org $4000
fnt 	ins 'cmc.fnt'
vgm_header
vgm_data = vgm_header+$80
;
		ins 'squadron.vgm'

;
START
		sei					;Disable interrupts
		cld					;Clear decimal mode
		MVA #$07 INPTCTRL
		MVA	#$7F CTRL
		MVA	#$00 OFFSET
		MVA #$00 INPTCTRL
		ldx	#$FF			;Reset stack pointer
		txs
;Clear zeropage,stack,RAM
		clear_ram $42,$FF	;skip $40&$41 (dest)
		clear_ram $140,$1FF
		clear_ram $1800,$1FFF
		clear_ram $2200,$27FF
	
; copy Display List List To RAM
      	ldy #0
copy  	MVA .adr(DLLs),y DLLs,y+
	    cpy #.len DLLs
	    bne copy
;
		MVA #<DLLs DPPL\ MVA #>DLLs DPPH	;set display list list address
		jsr	WaitVBLANK						;wait until no DMA would happen

		MVA	#>fnt	CHBASE
		MVA	#$40	CTRL

		MWA #vgm_data sour
		MWA #$00 counter

;set colors
		MVA	#$00 BACKGRND\ MVA #$02 P0C1\ MVA #$04 P0C2\ MVA #$0c P0C3
;LOOP
endloop		jmp endloop
;
;************************************************************************
;
;Yamaha 2151 player 
;
;************************************************************************
;
YM2151BASE 		= $460
YM_Data 		= $54
wait_n_sample 	= $61	;44100 samples per second
wait_ntsc_frame	= $62
wait_pal_frame	= $63
endsong 		= $66
w7x				= $70
pcm				= $c0
ntsc_wait		= $2df
pal_wait		= $372

;TV system for player
;**************************
sub_frame = ntsc_wait
;sub_frame = pal_wait
;**************************

Play_Yamaha 		
		bit counter+1
		beq check_counter
subframe
		jmp	substract
check_counter
		bit counter
		bne subframe
		jmp read_data

		.align 256

;skip 1 vblank
;commands $62 and $63
wait_frame
	MWA #$00 counter		;just in case
	INW sour
	rts

; skip PCM entry 4 bytes
; format $C0,$xx,$xx,$xx
skip_pcm
	adw sour #4 sour

;reading VGM data
Read_Data
		ldy #$00
Read_data_noY
		lda (sour),y
		cmp #YM_Data
		beq YM_store
Skip_YM_data
		cmp #wait_n_sample
		beq	check_wait_n_sample
		cmp #pcm
		beq skip_pcm
		cmp #wait_pal_frame
		beq wait_frame
		cmp #wait_ntsc_frame
		beq wait_frame
		cmp #endsong 
		beq set_restart_song
		tax
		and #$F0
		cmp #w7x
		beq skip_n_sample
		jmp error_read	;color bars if unknown command
		

skip_n_sample
		INW sour
		txa
		and #$0F
		tax
		beq Read_Data_noY
@		dex
		nop
		bne @-
		jmp Read_Data_noY		

; $66 = end off VGM data (restart song)
; TO DO - 
;
set_restart_song
		MWA #vgm_data sour
		MWA #$00 counter
		rts

;write data to Yamaha 2151
YM_store
		INW sour
		lda (sour),y
		sta YM2151BASE
		INW sour
		lda (sour),y
		sta YM2151BASE+1
		INW sour	
;saving 3 cycles per data read 
		lda (sour),y
		cmp #YM_Data
		beq YM_store

		jmp skip_YM_data
		
;delay $xxxx/$0372 frames (PAL)
;delay $xxxx/$02DF frames (NTSC)
;	
check_wait_n_sample		
		INW sour
		lda (sour),y
		sta counter
		INW sour
		lda (sour),y
		sta counter+1
		INW sour
substract
		SBW counter #sub_frame
		rts

; loop - color bars when error
error_read
		inx
		sta WSYNC
		stx BACKGRND
		jmp error_read

;******************************************************
;End of Player
;******************************************************


;DLI Interrupt
NMI
		PHR
		MVA #$96 BACKGRND
		JSR	Play_Yamaha
		MVA #$00 BACKGRND
		PLR
		RTI

IRQ		RTI

WaitVBLANK:	
WaitVBoff:
		bit		MSTAT
		bmi		WaitVBoff
WaitVBon:
		bit		MSTAT
		bpl		WaitVBon
		rts


; RAM
		ORG	$1800,*
.local DLLs
	:3	.byte	$0F,>emptyline,<emptyline
		.byte	$07,>line,<line
		.byte	$0F,>emptyline,<emptyline
		.byte	$8f,>emptyline,<emptyline		;$8x DLI interrupt
	:24	.byte	$0F,>emptyline,<emptyline



	.byte 0
line		.byte <text,$60,>text,0,20
emptyline	.byte $00,$00

text	.sb 'YM2151 VGM Player by Eagle               '
		.endl




;************** Cart reset vector **************************

	 ORG	$fff8
	.byte	$FF		;Region verification
	.byte	$47		;ROM start $8000
	.word	NMI
	.word	START
	.word	IRQ

 

PlayerVGM_NTSC.asm CMC.FNT maria.h squadron.vgm

  • Like 3

Share this post


Link to post
Share on other sites

Some MADS macros explained 

 

INW dest

inw dest  ->       inc dest
          ->       bne skip
          ->       inc dest+1
          ->  skip      

MVA src dest

 

    lda src    ->  mva src dst
    sta dst    ->

MWA #adr dst

    lda <adr    ->  mwa #adr dst
    sta dst     ->
    lda >adr    ->
    sta dst+1   ->

SBW src #$4080

 

  SBW SRC #$4080 -> SEC  
                 -> LDA SRC
                 -> SBC <$4080
                 -> STA SRC
                 -> LDA SRC+1
                 -> SBC >$4080
                 -> STA SRC+1 

ADW src #$40 src

 

  ADW SRC #$40 SRC -> CLC
                   -> LDA SRC
                   -> ADC #$40
                   -> STA SRC
                   -> LDA SRC+1
                   -> ADC #$00
                   -> STA SRC+1

PHR and PLR

 

  PHR  -> PHA         PLR  -> PLA
       -> TXA              -> TAY
       -> PHA              -> PLA
       -> TYA              -> TAX
       -> PHA              -> PLA

 

  • Like 1

Share this post


Link to post
Share on other sites

The YM capability in a7800 and js7800 are currently designed to emulate the XM, so you need to hit the XM $470 register with $84 to enable the YM. I confirmed that doing that manually in the a7800 debugger enabled your demo to play. Pretty sure js7800 will work once you do the same.

 

Also, the [email protected] bit in the a78 header is a modifier for supergame format. It's not needed for 48k.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
3 hours ago, Eagle said:

I don't have a frame of reference for the others, but this one is fabulous, thanks for converting it.

 

Stickerbush Symphony is also very mellow, I like that one.

 

I'd love to be able to include a YM tune in my future projects, but I wouldn't have the first clue about getting this working in 7800 Basic.

 

Thanks for sharing!

  • Like 1

Share this post


Link to post
Share on other sites

@Muddyfunster when I finish should be easy to adapt for Basic

 

VGM Player with Huffmunch decompressor (not finished yet) - no RAM used 

Stickerbush Symphony from 46KB down to 9700B

SexySix from 22KB to 3.62KB (Deflemask file was 2.87KB) and I'm sure that I can reduce to 3KB easily

I can change VGM format for my player from 0x54,xx,xx,0x54,xx,xx........ to for example 0x54,yy,xx,xx,xx,xx,xx,xx,xx..... (yy-how many times read pairs of xx)

 

ps. crashing at the end (no loop yet)

 

https://raz0red.github.io/js7800/?cart=https://atariage.com/forums/applications/core/interface/file/attachment.php?id=895665

 

Stickerbush_Huffmunch.a78

  • Like 1

Share this post


Link to post
Share on other sites

The Neverending story full version compressed (120KB -> 21KB) - Sometimes "dropping a frame" due decompression and heavy instruments changes but using only 9 bytes of ram. 

Silent  compressed from 60KB -> 9KB - also heavy CPU usage

I will change VGM to my format. Less data and CPU usage. I'll spread decompression equally to frames between playing music (probably will have to use some small buffer) 

Seems like emulator ignoring waiting for YM when real HW not.

 

Silent

 

Neverending Story NTSC

 

edit:

 

RayFuture 112KB ->12KB

 

RayFuture 2203

 

RayFuture2203.a78

Neverending120to21KB.a78 Silent60to9KB.a78

  • Like 1

Share this post


Link to post
Share on other sites

All of them were sounding great on my 7800 last night when I was testing them out. I will be sure to check out these newer releases later!

 

  • Like 1

Share this post


Link to post
Share on other sites

@SlidellMan thanks I didn't know this.

I will try add missing sample soon.

 

Few more tests today.

Al Capone 50KB ->7KB (no sample version) cover by LukeMcQueen

The Cheetahmen 83KB ->11KB by SuperJet Spade

Opmeridian 87KB ->15KB by SuperJet Spade

 

AlCapone - link JS7800

 

The Cheetahamen - link JS7800

 

Opmeridian - link JS7800

AlCapone_Michael_Jackson_cover_NTSC.a78 TheCheetahmen_NTSC.a78 opmeridian_NTSC.a78

Share this post


Link to post
Share on other sites

I have changed the VGM format to my own and also decompress the data stream to a 256 byte buffer in the background.

But I ran in to problem with YM timing (?). Looks like after waiting for Write Busy Flag I can't write data straight away. 

If I not put Nop's after reading Write Busy Flag, music not playing good on Dragonfly (sounds ok on emulator)

@RevEng sorry for calling you again but you may know answer. I have no idea what's going on :( Looks like I need put minimum 3 NOP after BIT

I know that YM need 68 internal clocks before writing again (about 35 cycles 6502) but should be no problem after checking flag 

I attached examples (PAL unfortunately)

copy_ym_data
		iny			;2
		lda (sour),y		;5
@		bit YM2151BASE		;4
		bmi @-			;3
		:3 nop			;3*2=6
		sta YM2151BASE		;4
		iny			;2
		lda (sour),y		;5
@		bit YM2151BASE+1	;4
		bmi @-			;3
		:3 nop			;3*2=6
		sta YM2151BASE+1	;4
		dec licznik		;5
		bne copy_ym_data	;3

 

PlayerEYP_noNOP.a78 PlayerEYP_2x1NOP.a78 PlayerEYP_2x2NOP.a78 PlayerEYP_2x3NOP.a78

Share this post


Link to post
Share on other sites

It's nothing I've run into before... if this is the only code accessing the YM at the same time (i.e. there isn't access happening on both interrupts and the main code loop) then it would seem to be a timing quirk.

 

Try throwing a single NOP before each BIT test loop. Maybe it takes a few more cycles to chew on the last input before the YM realizes it needs to raise it's busy flag. Something to try anyway.

 

(Adding @tep392 in case he's seen it before)

  • Thanks 1

Share this post


Link to post
Share on other sites

It's only writing YM on Interrupt, main loop writing in to the buffer.

17 minutes ago, RevEng said:

Try throwing a single NOP before each BIT test loop. Maybe it takes a few more cycles to chew on the last input before the YM realizes it needs to raise it's busy flag. Something to try anyway.

I had to put 5 NOP's before BIT to make this sounds ok.

Share this post


Link to post
Share on other sites

Ok, so it doesn't sound like my guess is right.

 

Is it purely a sound quality thing, or are notes actually dropped from the transfer? If you send a note-off very shortly after a note-on on the same channel, you get distortion. I think that's just a quirk of the YM.

Share this post


Link to post
Share on other sites

Looks like transfer problem. In first frame it's transferring 240 bytes (instruments)

After restart song without NOP's (VGM reload instruments) sounds OK/Better (? hard to say I'm not musician)

But why?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...