Jump to content

Xuel's Photo


Member Since 21 Aug 2008
OFFLINE Last Active Today, 3:34 AM

#3893814 Joe Blade NTSC version?

Posted by Xuel on Sun Nov 19, 2017 4:21 PM

The speed of the enemies is faster in the first part of this version than in the original game (and Xuel's NTSC version). I'm not sure how the rest of the game compares, as I didn't play through much of this version yet.


Yeah I noticed that too. The reason is that Rambo Blade replaces the LDA VCOUNT / BNE with LDA VCOUNT / BEQ which effectively gets rid of the frame syncing altogether. This means if you run on a 65816 at a higher frequency (e.g. 21MHz), then the enemies are super fast.


Other than that difference, it's interesting that Rambo Blade uses a similar NTSC-fixing strategy to the one I employed with Joe Blade II, i.e. just swap the immediate and deferred vertical blank routines instead of moving both into deferred as I did with Joe Blade.

#3892486 Joe Blade NTSC version?

Posted by Xuel on Fri Nov 17, 2017 3:17 PM

Does the countdown timer need slowing down?


Good idea. I see another case at B828 probably for the subgames. Not sure why the creators used $34. I agree $32 makes more sense. Maybe they adjusted it to make it slightly easier?


Here it is with $3C:


Attached File  joe-blade-ii-ntsc-fix.zip   132.74KB   22 downloads

#3892450 Joe Blade NTSC version?

Posted by Xuel on Fri Nov 17, 2017 2:02 PM

Joe Blade II:


Attached File  joe-blade-ii-ntsc-fix.xex   26.66KB   21 downloads



  • Swapped use of Timer 1 and Timer 2 since Timer 1 code was making immediate VBLANK too long but is fine as deferred VBLANK. Not sure if I introduced any order dependency issues with this swap but a quick play through looked OK.



Attached File  joe-blade-ii-ntsc-fix.zip   1.09MB   11 downloads

#3892314 Joe Blade NTSC version?

Posted by Xuel on Fri Nov 17, 2017 9:58 AM

Possible fix:


Attached File  joe-blade-ntsc-fix.xex   30.5KB   23 downloads



  • Replace an instance of LDA VCOUNT / BNE with LDA $14 / CMP $14 / BEQ. That way it isn't thwarted when the VBI runs long.



Attached File  joe-blade-ntsc-fix.zip   775.95KB   9 downloads


I'll take a look at Joe Blade II.

#3892212 Joe Blade NTSC version?

Posted by Xuel on Fri Nov 17, 2017 4:25 AM

I made an attempt at NTSC-fixing and converting the original CAS to an XEX:


Attached File  joe-blade-ntsc-fix.xex   30.48KB   27 downloads



  • Move long immediate VBLANK routine into deferred routine
  • Insure proper initialization of DLIs when switching from bomb screen to main screen
  • Disable BASIC



Attached File  joe-blade-ntsc-fix.zip   750.81KB   13 downloads

#3890702 "The Graphic Demo" in NTSC?

Posted by Xuel on Tue Nov 14, 2017 11:15 PM

I took a shot at NTSC-fixing the original demo:


Attached File  graphic-demo-ntsc-fix.atr   90.02KB   20 downloads


  • Shorten the kernel on the top of the screen so it doesn't eat up so much CPU time
  • Move the computation of rainbow colors into the kernel itself instead of as a separate loop
  • Clean up the bottom border so that the color change is stable (only visible on extended PAL height)

Messy patch code:


Attached File  graphic-demo-ntsc-fix.asm   4.91KB   16 downloads

#3886857 how many CPU cycles in a scanline?

Posted by Xuel on Thu Nov 9, 2017 11:28 AM

There's no difference in the number of cycles per line between PAL and NTSC. When DMA is disabled, DRAM refresh always consumes 9 cycles. The only time refresh takes fewer cycles is on "badlines" where some of the refresh cycles are blocked by character set index lookups depending on the width of the screen and the HSCROL status. See the timing diagrams in the Altirra Hardware Reference Manual for precise timings.

#3886846 how many CPU cycles in a scanline?

Posted by Xuel on Thu Nov 9, 2017 11:06 AM

I second what flashjazzcat said. You can see all refresh and DMA cycles in Altirra by pressing Shift-F8. If you do that when DMA is completely disabled you see the following pattern:




Notice that the positions of the DRAM refresh cycles correspond to the area where your bars are distorted.


Maybe you could even out the bars by intermixing ST* ABS, ST* ABS,Y and STA (ZP),Y instructions to adjust the width by one or two cycles at opportune moments since those take 4, 5 and 6 cycles respectively. You could also get 7 cycles if you force a page boundary to be crossed.

#3876636 Bon Jovi's "Living on a prayer"

Posted by Xuel on Wed Oct 25, 2017 10:46 PM

Ok thx, one more question.Why you use in audc values from 0x78 to 0x87, why not 4*lsr?


Oh, I just realized I think I misunderstood your question. I think you are proposing packing two 4-bit samples into one byte and using masking and shifting to separate them on-the-fly. That is definitely possible. The only reason I didn't do that for this demo is laziness. :)

#3876629 Bon Jovi's "Living on a prayer"

Posted by Xuel on Wed Oct 25, 2017 10:36 PM

Ok thx, one more question.Why you use in audc values from 0x78 to 0x87, why not 4*lsr?


The raw unsigned 8-bit values range from 0 to $FF with $80 representing the speaker at rest. raw2audc expects the volume to already have been lowered such that the effective range is only from $78 to $87. It then converts values in this range to AUDC values in the range $10 to $1F.


I could have left the volume at 100% in the raw samples. Then I could have reduced the volume in raw2audc. But I figured I'd let sox reduce the volume because I wasn't sure how about the math for minimizing quantization noise. I could also then let it dither the samples if desired. Basically by reducing the volume, I'm effectively forcing sox to produce ready-made 4-bit samples instead of 8-bit samples that I would then have to convert to 4-bit samples.

#3876366 Bon Jovi's "Living on a prayer"

Posted by Xuel on Wed Oct 25, 2017 4:12 PM

Hi Lyren,
Could you p.l.e.a.s.e. explain in detail how to convert mp3 files to this audio format for Atari?
- Y -

I used sox and a custom Perl script. You can see the sox command-line on my github page in my Makefile and the Perl code is in raw2audf and raw2audc. I'm working on updating the repo to work with the latest version of sox. Basically you just need to replace -u with -e unsigned-integer.

How in sox make ~ 7-bit sample?

That is just to say that the values you use for AUDF should not exceed the number of clock cycles on a scan line, i.e. 114, or probably a bit less to account for STIMER counter reset cycles. I say ~7 bits because 114 is almost 127 which is the highest value that fits into 7 bits. You're definitely getting less than 7 bits of fidelity. The moral of the story is that you just need to play with the attenuation in sox until it doesn't clip too badly. Storage still requires 8-bits per sample because the samples are stored as bytes in the Atari's memory.

#3873992 Help! add music format sap (mads)

Posted by Xuel on Sun Oct 22, 2017 7:49 PM

Relocated to $F000:
Attached File  speednik-reloc.zip   95.92KB   20 downloads
This was a bit of a challenge! There are a lot of hard-coded addresses in the song data and the player has some address constants.
In order to tackle it I made some modifications to my disassembler to automatically convert address constants into label expressions like "<addr" and ">addr" as appropriate. You just tell it where the high and low address bytes are and it does the rest.
For example, if you have a 16-bit address in two consecutive data bytes of the binary then it will automatically determine the address, assign it a label and use the label instead of the hard-coded constants:
    dta $8B            ; 46FD: 8B
    dta $46            ; 46FE: 46
dis specification:

    address 46FD

    dta <s2l468B               ; 46FD: 8B
    dta >s2l468B               ; 46FE: 46

It also handles addresses that are split into high-byte and low-byte tables. For example:

    dta $18            ; 401A: 18
    dta $48            ; 401B: 48
    dta $78            ; 401C: 78

    dta $41            ; 403B: 41
    dta $41            ; 403C: 41
    dta $41            ; 403D: 41

dis specification: (high-byte table address, low-byte table address, table size)

    address 403B_401A+20

    dta <s2l4118               ; 401A: 18
    dta <s2l4148               ; 401B: 48
    dta <s2l4178               ; 401C: 78

    dta >s2l4118               ; 403B: 41
    dta >s2l4148               ; 403C: 41
    dta >s2l4178               ; 403D: 41

It also handles any arbitrary separation between high and low bytes so it can handle code like this:

    ldx #$00           ; 3952: A2 00
    ldy #$40           ; 3954: A0 40

dis specification:

    address 3955_3953


    ldx <song          ; 3952: A2 00
    ldy >song          ; 3954: A0 40

It of course reuses any labels you've explicitly defined, so in the above example it used the user-defined label "song" instead of auto-generating a label.

I imagine there are other disassemblers that can do this but it was fun to implement myself.

#3844092 Atari 8 bit file formats

Posted by Xuel on Sat Sep 9, 2017 8:22 AM

I found atariki to have many useful file and file system format descriptions. For example, the CMS docs helped me understand how to relocate Stereo Chaos Music Composer songs to different memory addresses.

#3836740 Veronika megademo last part

Posted by Xuel on Mon Aug 28, 2017 9:56 PM

I used phaeron's pointers to come up with this hack:
Attached File  veronika-xe-fix.atr   130.02KB   19 downloads

Note that the dancer shows up immediately upon the start of that section of the demo instead of a black screen for several seconds. This means that the synchronization with the music is not quite the same as in the original.

My steps were:
  • Notice that the index value of $36 for a certain table led to the bogus $D000 address in another table
  • Extract the XOR cipher key from memory at $680-$6FF and apply to the ATR ciphertext sectors to recover the plaintext
  • Locate the offending $36 values in the following section of the ATR plaintext:
    00011a00: 3333 3333 33ff b200 0636 3636 3636 3636  33333....6666666
    00011a10: 3636 3636 ffb2 0003 1f20 2122 2336 2536  6666..... !"#6%6
    00011a20: 2736 2936 ff00 0000 0c0c 0d0d 0e0e 0f0f  '6)6............
    00011a30: 1010 1111 1212 1313 1414 1515 1616 1717  ................
    00011a40: 1818 1936 1a36 1b36 1c36 ffb2 0005 0102  ...
  • Apply the cipher to values of $FF instead of $36 and use hex editor to apply the new values at the appropriate locations
XOR key and other work files I used available here:

Attached File  veronika-hack.zip   220.12KB   22 downloads

#3833944 Telengard-BASIC debugging challenge

Posted by Xuel on Thu Aug 24, 2017 2:31 PM

Basic error 8 happens when an INPUT statement is trying to read a number but finds a string instead. So, I suspect that the save character file on your disk is not getting read in correctly, possibly due to disk corruption or hardware malfunction. This would also explain the bogus character in your name "BAKER" at the letter K since the program reads the name from disk and prints it out right before the line where it's failing for you.