Problem loading tapes

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
Chema
Game master
Posts: 3014
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Problem loading tapes

Post by Chema »

Hi Guys.

After not suceeding in loading Skool Daze without errors in my Oric, I decided to dig a bit into this CLOAD trouble and check what was happening.

I will try to summarize my experiences and see if anybody can help with some ideas or clear some bits of information I might not have understood correctly.

The thing is that every time I try to load the game, it simply does not auto run. If I use tap2wav (with the -11 option) I usually end up getting some loading errors (that are clearly loading errors), but when I use tap2cd, things seem to work ok, although the game does not auto run.

I tried adding a silence at the end of the file, but nothing. Different volume settings, windows settings (of course I disabled system sounds and tried different programs from the windows recorder, to Audacity), plugging just the ear and both ear and mic, two different cables.. The results were always exactly the same.

However, some other games (for instance Damsell in Distress or O-Thrust) load perfectly well 100% of the times, even with quite different volume settings and conditions (cables, plugs, players,...).

I, then, tried to add a small BASIC loader, to do the trick with DOKE #1b,#500 and then CLOAD the game and, to my surprise, this basic loader didn't auto run either. It does if converted with tap2wav, though.

Then I started PEEKing into #2B1. Having a look at the Oric Atmos ROM disassembly, this address stores the number of parity errors. To my surprise I always get 1 and only 1.

It seems my ROM is not one of the newest with the load bug "corrected". In the Oric ROM disassembly the section which leads with loading errors seems to be:

Code: Select all

E8D3 JSR $E651 Print filename if there is a
E8D6 LDA $02AE format error.
E8D9 BEQ $E8E9
E8DB LDA $02AD Jump to start of machine code
E8DE BEQ $E8E8 program if correct file type
E8E0 LDA $02B1 and there are no loading errors.
E8E3 NOP
E8E4 NOP
E8E5 JMP ($02A9)
E8E8 RTS
Look at the two NOPs. They simply replace what I have in my ROM: a BNE 3 (to the RTS); so the new ones simply ignore any loading errors and jump to the starting address. This piece of code is for when the program is in machine code, something similar is done for basic programs, anyway.

What I don't understand is why I don't get any Errors Found message. The routine at $E651, which is called after loading the program, does:

Code: Select all

E651 LDA $02B1 Print out string after " if
E654 BEQ $E65D there was an error in format.
E656 LDA #$27
E658 LDY #$E5
E65A JSR $CCB0
E65D RTS
So, if $2b1 is 1, it should print the error string. No idea what is going wrong here...

Also, checking the ROM disassembly, I did not find any point which could explain the loading bug. I think that some errors may occur with unstable sync leads in the program (for instance when some players tried to adjust volume automatically), but this shouldn't be the case here, and won't explain why some programs work and why some don't.

I guess I cannot promise that I have no real loading errors, but it seems quite improbable. The basic loader is correct and the game runs for hours with no bugs. And I always get just 1 parity error... very suspicious.

Difficult to draw some conclusions. Is it possible that tap2cd converted programs work better due to its higher frequency (22Khz, instead of 11)? Is there a possibility that the converted wav files have any kind of error which is the cause of all this? Maybe an extra buggy byte, a bad parity calculation somewhere, or a wrong header or sync signal, or something similar which appears only with some tap files? I think none of these will be noticed in Euphoric (loading from the WAV file) because it uses the 11b ROM, with the two NOPs, so it will autorun even in the pressence of errors.

I could hack something that could work, converting the loader as a standalone tap with tap2wav and the game with tap2cd and merging both wavs with Audacity, but I would like to understand why this is not working.

Can anybody enlighten me here?
User avatar
Symoon
Archivist
Posts: 2307
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Post by Symoon »

Short reply, it's late.
You indeed have the early bugged ROM 1.1.
Tap2cd probably works because it has its own loading routines, and IIRC the "standard loaded" part is loaded in the stack so could get automatically executed regardless of AUTO mode or not (just a guess I'm not a stack specialist). That could explain why you have no problem.

Your parity errors probably come from the sync part. According to l'Oric à Nu, the ROM has been corrected between E4B6-E4D1 to prevent parity errors during the sync.

I had never noticed the newer ROM actually totally ignores the parity errors from the loaded program!

About the rest I have no idea, at least today at 1.30AM ! ;)
highwayman
Flying Officer
Posts: 148
Joined: Fri Oct 12, 2007 8:08 pm

Post by highwayman »

i didnt know there was several atmos roms with the same (v1.1) version number!

so, what does 1.0 (oric-1) do?
check for errors, or ignore them?
User avatar
Chema
Game master
Posts: 3014
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Post by Chema »

I don't know what the Oric-1 does... Certainly it checks for errors differently (I had an Oric-1 and error message was different "File error / load aborted" and aborted the loading).

I just peeked into my atmos rom to check for differencies in the routine Symoon mentions. Here they are:
The buggy rom routine at E4AC does:

Code: Select all

get_file
    JSR $E735 Get in sync with tape.

seek_start
    JSR $E6C9 Read byte from tape.
    CMP #$24
    BNE seek_start Get bytes until "$" is read.

    LDX #$09
loop1
    JSR $E6C9 Read byte.
    STA $02A7,X Save in header block.
    DEX
    BNE loop1

loop2
    JSR $E6C9 Get byte.
    BEQ end_name End of file name.
    STA $0293,X Save chars of file name.
    INX
    CPX #$10 Continue for up to 16 bytes.
    BNE loop2

    ; This seems to skip the rest of the name, if too long
loop3
    JSR $E6C9 Get byte.
    BNE loop3

end_name
    STA $0293,X Store end of file indicator.
    JSR $E594 Print "Found" <filename>.
    JSR $E790 Compare names of files.
    TXA
    BNE get_file Correct filename is not found.
    RTS Exit.
The problem, I think, is that the routine at $e6c9 (read byte from cassette) sets the error flag at $2b1. This is routine is also used in the routine $e735 which gets in sync with tape, thus any error in the sync header will be noticed. This was a problem whith some cassette players which had the auto-volume feature, IIRC.

I mentioned in my previous post that $2b1 had the number of parity errors. That is misleading. If a parity error is detected the carry is set and ROL'ed into $2b1. So one error will appear as a value of 1, two errors 3, three errors 7, etc.

The new rom rewrote this routine to save three bytes and put a zero in $2b1 (register X is zero when reaching e4b6, so stx $2b1 does this). Here is the code:

Code: Select all

E4AC JSR $E735 Get in sync with tape.
E4AF JSR $E6C9 Read byte from tape.
E4B2 CMP #$24
E4B4 BNE $E4AF Get bytes until "$" is read.

E4B6 STX $02B1 *** Here it is ***

E4B9 LDX #$09
E4BB JSR $E6C9 Read byte.
E4BE STA $02A7,X Save in header block.
E4C1 DEX
E4C2 BNE $E4BB
E4C4 JSR $E6C9 Get byte.
E4C7 BEQ $E4D3 End of file name.
E4C9 CPX #$10 Continue for up to 16 bytes.
E4CB BCS $E4C4
E4CD STA $0293,X Save chars of file name.
E4D0 INX
E4D1 BNE $E4C4
E4D3 STA $0293,X Store end of file indicator.
E4D6 JSR $E594 Print "Found" <filename>.
E4D9 JSR $E790 Compare names of files.
E4DC TXA
E4DD BNE $E4AC Correct filename is not found.
E4DF RTS Exit.
Still they removed the code that disabled auto-run if errors were detected. It seems that they were not too confident on the tape system...

Anyway, my question is still there. Why two wavs, generated from two taps with tap2cd and fed into the Oric under the same conditions will behave differently? One always generating a parity error and the other never generating it?

If it were the player program which made something strange at the begining of the wav, it should affect both. If it were a wrong header produced by the tap2cd it will also affect both, so this is still a mistery for me.

But I am learning a lot with all this :)
User avatar
Symoon
Archivist
Posts: 2307
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Post by Symoon »

Chema wrote:Anyway, my question is still there. Why two wavs, generated from two taps with tap2cd and fed into the Oric under the same conditions will behave differently? One always generating a parity error and the other never generating it?
Let's focus on this.
IIRC, a program converted with tap2cd holds 2 parts:
1- the loader, which is recorded in standard fast speed, that holds the code of the special tap2cd loading routines
2- the main program in "very fast" format, loaded by the special routines that have just been loaded before.

If both of your WAVs are loading the main program, that means that the tap2cd loader, which is recorded with standard routines, loads fine and is executed fine.
I don't remeber much about tap2cd, but logic tells me that the source of your problem is then a conjonction between your ROM and tap2cd special routines. I tried long ago to build a version of tap2cd for ROM 1.0, and gave up because it made ROM calls that were too different in ROM 1.0 and I never had the nerve to try and find a solution.
So maybe one of these ROM calls from tap2cd, with your "unusual" ROM, leads to a random error.
User avatar
Chema
Game master
Posts: 3014
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Post by Chema »

Symoon wrote: Let's focus on this.
IIRC, a program converted with tap2cd holds 2 parts:
1- the loader, which is recorded in standard fast speed, that holds the code of the special tap2cd loading routines
2- the main program in "very fast" format, loaded by the special routines that have just been loaded before.

If both of your WAVs are loading the main program, that means that the tap2cd loader, which is recorded with standard routines, loads fine and is executed fine.
This is right, and also agrees with the fact that the basic loader I made loads fine if I use tap2wav.
I don't remeber much about tap2cd, but logic tells me that the source of your problem is then a conjonction between your ROM and tap2cd special routines. I tried long ago to build a version of tap2cd for ROM 1.0, and gave up because it made ROM calls that were too different in ROM 1.0 and I never had the nerve to try and find a solution.
So maybe one of these ROM calls from tap2cd, with your "unusual" ROM, leads to a random error.
Mmmm... That coud be a reason indeed. I emailed Fabrice Frances about this. Maybe he can help here. I also would like to disassemble the loading routine in tap2cd and see what it is doing. Maybe he is making a call inside a routine which has been modified.

Pitty you tried to make it compatible with Rom1.0 and did not finishthe job. I just had the same idea, probably in addition with some custom code to make some kind of loading effect (though pretty simple) if there is time.

I also had the idea of making a kind of dummy loader (ultra fast speed) so it prints each parity error with the supposed loading addr. Just to check.
User avatar
Symoon
Archivist
Posts: 2307
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Post by Symoon »

Chema wrote:Mmmm... That coud be a reason indeed. I emailed Fabrice Frances about this. Maybe he can help here. I also would like to disassemble the loading routine in tap2cd and see what it is doing. Maybe he is making a call inside a routine which has been modified.
Yes he seems to call (at least) the sync routine in #E4AC.
But be careful with what I'm saying, I noticed in my old notes that I had just begun disassembling an "old" version of tap2cd, and that the machine code for the decoding routine was modified. There are 2 versions (one from 5-oct-99, and one from 8-oct-99). Can't recall why but we should use the latest, I guess.

The tap2cd program also generates gaps (probably to let the Oric do the decoding work), so maybe this can be another candidate for parity errors source in the "buggy" 1.1 ROM?

(disclaimer; all I'm saying is taken from fragments of what I had begun 10 years ago, and is totally unfinished work, based on an outdate version of tap2cd, so don't think I know tap2cd that much ;))
Chema wrote:Pitty you tried to make it compatible with Rom1.0 and did not finishthe job. I just had the same idea, probably in addition with some custom code to make some kind of loading effect (though pretty simple) if there is time.
Actually the big problem was that the loading routines in ROM 1.0 are many sequential instructions, while in ROM 1.1 it was fragmented in multiple sub-routines. So tap2cd could call these subroutines and carry on after the RTS, but on ROM 1.0 there are no such RTS soo one could'nt call the ROM.
I'm not saying it's impossible to make but as I'm no machine code expert I remember I thought it would be tough and probably forgot it while switching to ohter things I had in mind for Oric ;-)
Post Reply