LORES: different between ROM 1.0 and ROM1.1?
LORES: different between ROM 1.0 and ROM1.1?
Maybe this has been spotted and discussed before, but anyway... Did anyone notice that LORES 1 modes, which display the 2nd character set, have a different shape between Oric-1 and Oric Atmos?
Noticed that when testing an unknown little game which runs in LORES.
Atmos: Oric-1:
Noticed that when testing an unknown little game which runs in LORES.
Atmos: Oric-1:
- mikeb
- Flight Lieutenant
- Posts: 282
- Joined: Wed Sep 05, 2018 8:03 pm
- Location: West Midlands, UK
- Contact:
Re: LORES: different between ROM 1.0 and ROM1.1?
Yes, this is a long standing feature
The character cells are supposed to be an equal 2 x 3 grid for teletext/viewdata blocks
For Oric this means 3 pixels left, 3 pixels right, as there are only 6 bits in a character that become visible pixels (the other 2 bits are for attributes etc.)
xx 000 000
xx 000 111
xx 111 000
xx 111 111
But I think the routines that generate the codes for Oric-1 forgot this, and used the full 8 bits.
0000 0000
0000 1111
1111 0000
1111 1111
Meaning the shapes onscreen are wrong :-
00 0000
00 1111
11 0000
11 1111
So the left hand lo-res cell is too small, the right hand is too big. Off by one pixel.
The character cells are supposed to be an equal 2 x 3 grid for teletext/viewdata blocks
For Oric this means 3 pixels left, 3 pixels right, as there are only 6 bits in a character that become visible pixels (the other 2 bits are for attributes etc.)
xx 000 000
xx 000 111
xx 111 000
xx 111 111
But I think the routines that generate the codes for Oric-1 forgot this, and used the full 8 bits.
0000 0000
0000 1111
1111 0000
1111 1111
Meaning the shapes onscreen are wrong :-
00 0000
00 1111
11 0000
11 1111
So the left hand lo-res cell is too small, the right hand is too big. Off by one pixel.
Re: LORES: different between ROM 1.0 and ROM1.1?
Ha ha thanks!
What's curious thought, is that the character generation routine seems to be the same for both ROMs ($F7E0 / $F816)? But I've checked quickly, maybe I'm not looking at the right place.
What's curious thought, is that the character generation routine seems to be the same for both ROMs ($F7E0 / $F816)? But I've checked quickly, maybe I'm not looking at the right place.
- mikeb
- Flight Lieutenant
- Posts: 282
- Joined: Wed Sep 05, 2018 8:03 pm
- Location: West Midlands, UK
- Contact:
Re: LORES: different between ROM 1.0 and ROM1.1?
No idea how it was fixed, $F263 is the highest address that "Rambling In The ROM" got to in OUM, so that would be where I would look for details.
There must be a subtle difference between the routines (a stray ROL or something) hidden in there that fixes it.
Edit to add: I just compared Leycester Whewell's commented ATMOS ROM disassembly (from the Advanced User Guide) with Bob Maunders un-commented Oric-1 disassembly.
You're right, the routines are the same and are both correct, the problem is GIGO -- Garbage In, Garbage Out.
ATMOS
Code: $F816 to $F860
$F861 Four Data Bytes used by the routine :-
$00 (00 000 000)
$38 (00 111 000)
$07 (00 000 111)
$3F (00 111 111)
These are correct and make allowances for the two first bits being non-visible pixels, so the cells are 3+3 pixels/bits wide.
ORIC:
Code: $F7E0 to $F82A
$F82A Data :-
$00 (00 00 0000)
$F0 (11 11 0000)
$0F (00 00 1111)
$FF (11 11 1111)
These are wrong, and assume that all bits are treated as visible, simply cleaving the byte into 2 nybbles. I've spaced them to show the 2 bits left, 4 bits right offset.
The fix for Oric, (as a post-ROM generation, user correction), is to just ROR every location down one bit, and clear the top two bits just for neatness (AND with $03F)
There must be a subtle difference between the routines (a stray ROL or something) hidden in there that fixes it.
Edit to add: I just compared Leycester Whewell's commented ATMOS ROM disassembly (from the Advanced User Guide) with Bob Maunders un-commented Oric-1 disassembly.
You're right, the routines are the same and are both correct, the problem is GIGO -- Garbage In, Garbage Out.
ATMOS
Code: $F816 to $F860
$F861 Four Data Bytes used by the routine :-
$00 (00 000 000)
$38 (00 111 000)
$07 (00 000 111)
$3F (00 111 111)
These are correct and make allowances for the two first bits being non-visible pixels, so the cells are 3+3 pixels/bits wide.
ORIC:
Code: $F7E0 to $F82A
$F82A Data :-
$00 (00 00 0000)
$F0 (11 11 0000)
$0F (00 00 1111)
$FF (11 11 1111)
These are wrong, and assume that all bits are treated as visible, simply cleaving the byte into 2 nybbles. I've spaced them to show the 2 bits left, 4 bits right offset.
The fix for Oric, (as a post-ROM generation, user correction), is to just ROR every location down one bit, and clear the top two bits just for neatness (AND with $03F)
Re: LORES: different between ROM 1.0 and ROM1.1?
Better late than never, here's LoresFix 1.0, quickly done, that fixes Oric-1's LORES 1 mode.
Code: Select all
AD 08 B9 LDA $B908 Let's control if we already seem to have the right values
C9 38 CMP #$38 by testing one
F0 20 BEQ exit If so, exit!
A2 00 LDX #$00 else get ready to change a whole page
loopB9:
BD 00 B9 LDA $B900,X Load a byte from page $B9
F0 06 BEQ nextB9 If $00, nothing to do, skip to next
6A ROR else shift once to the right
29 3F AND #$3F then set the two left bytes to 0 ($3F=00111111)
9D 00 B9 STA B900,X and replace the value in RAM
nextB9:
CA DEX Next byte
D0 F2 BNE loopB9 As long as X is not zeroed again, loop
A2 00 LDX #$00 else get ready to change a whole page --- Ooooh this is useless, thanks ISS for spotting this!
loopBA:
BD 00 BA LDA $BA00,X Load a byte from page $BA
F0 06 BEQ nextBA If $00, nothing to do, skip to next
6A ROR else shift once to the right
29 3F AND #$3F then set the two left bytes to 0 ($3F=00111111)
9D 00 BA STA BA00,X and replace the value in RAM
nextBA:
CA DEX Next byte
D0 F2 BNE loopBA As long as X is not zeroed again, loop
exit:
60 RTS
Here's the TAP file, set in page 1, with auto-run
File removed, see below for better version
Last edited by Symoon on Tue Sep 03, 2024 4:55 pm, edited 2 times in total.
Re: LORES: different between ROM 1.0 and ROM1.1?
Cool!
Here:
you don't need the line:
because reg. X is already #$00 and so 2 bytes shorter .
Here:
Code: Select all
...
nextB9:
CA DEX Next byte
D0 F2 BNE loopB9 As long as X is not zeroed again, loop
A2 00 LDX #$00 else get ready to change a whole page
loopBA:
...
Code: Select all
A2 00 LDX #$00 else get ready to change a whole page
Re: LORES: different between ROM 1.0 and ROM1.1?
Ooooh thanks.iss wrote: ↑Tue Sep 03, 2024 9:21 am you don't need the line:because reg. X is already #$00 and so 2 bytes shorter .Code: Select all
A2 00 LDX #$00 else get ready to change a whole page
Will fix this
Re: LORES: different between ROM 1.0 and ROM1.1?
New version, optimised by ISS, 5% less bytes
Code: Select all
AD 08 B9 LDA $B908 Let's control if we already seem to have the right values
C9 38 CMP #$38 by testing one
F0 1E BEQ exit If so, exit!
A2 00 LDX #$00 else get ready to change a whole page
loopB9:
BD 00 B9 LDA $B900,X Load a byte from page $B9
F0 06 BEQ nextB9 If $00, nothing to do, skip to next
6A ROR else shift once to the right
29 3F AND #$3F then set the two left bytes to 0 ($3F=00111111)
9D 00 B9 STA B900,X and replace the value in RAM
nextB9:
CA DEX Next byte
D0 F2 BNE loopB9 As long as X is not zeroed again, loop
loopBA:
BD 00 BA LDA $BA00,X X already at 0 here. Load a byte from page $BA
F0 06 BEQ nextBA If $00, nothing to do, skip to next
6A ROR else shift once to the right
29 3F AND #$3F then set the two left bytes to 0 ($3F=00111111)
9D 00 BA STA BA00,X and replace the value in RAM
nextBA:
CA DEX Next byte
D0 F2 BNE loopBA As long as X is not zeroed again, loop
exit:
60 RTS
- Sodiumlightbaby
- Flight Lieutenant
- Posts: 308
- Joined: Thu Feb 22, 2024 11:38 am
Re: LORES: different between ROM 1.0 and ROM1.1?
I'm not a seasoned 6502 assembly expert, but as far as I know ULA ignores the top two bits of then character data byte. Could not the inner loop be boiled down from
to
(And then same for BA) Or am I missing something?
Edit: The initial test could perhaps also be slimmed down a little. Assuming $B908 has MSB set originally.
Upside we don't clobber the A register anymore
Edit2:
... and do both B9 and BA pages in the same loop
Code: Select all
loopB9:
BD 00 B9 LDA $B900,X Load a byte from page $B9
F0 06 BEQ nextB9 If $00, nothing to do, skip to next
6A ROR else shift once to the right
29 3F AND #$3F then set the two left bytes to 0 ($3F=00111111)
9D 00 B9 STA B900,X and replace the value in RAM
Code: Select all
5E 00 B9 LSR $B900,X
Edit: The initial test could perhaps also be slimmed down a little. Assuming $B908 has MSB set originally.
Code: Select all
BIT $B908
BPL exit
Edit2:
... and do both B9 and BA pages in the same loop
Re: LORES: different between ROM 1.0 and ROM1.1?
It works indeed if the program is ran once!Sodiumlightbaby wrote: ↑Thu Sep 05, 2024 8:29 am(And then same for BA) Or am I missing something?Code: Select all
5E 00 B9 LSR $B900,X
I began making a TAP file of it but had (already) forgotten that we have ton consider that the program can:
- be ran on Atmos (then has to find exactly #$38 on $B908 to avoid shifting correct values)
- be ran more than once on Oric-1 (if set at the beginning of a program for instance), so looking for #$38 in $B908 also avoids shifting several times all the bits. Problem: "LSRing" won't set it to #$38 as bit 6 will be set, and bit 7 will be 0 or 1 according to C previously.
But great ideas, maybe we can change the test location to find a specific value that would give good results with LSR and BIT, haven't looked for it yet!
EDIT: testing F0 in $B908 (ROM 1.0 value) then exiting with a BNE should at least work so we can use LSR . I'm so unfamiliar with BIT that I have to think twice here!
Last edited by Symoon on Thu Sep 05, 2024 11:39 am, edited 1 time in total.
- Sodiumlightbaby
- Flight Lieutenant
- Posts: 308
- Joined: Thu Feb 22, 2024 11:38 am
Re: LORES: different between ROM 1.0 and ROM1.1?
What is the value of $B908 on Basic 1.0?
Re: LORES: different between ROM 1.0 and ROM1.1?
Just editied my message while you were asking lol.
- Sodiumlightbaby
- Flight Lieutenant
- Posts: 308
- Joined: Thu Feb 22, 2024 11:38 am
Re: LORES: different between ROM 1.0 and ROM1.1?
Great! Using BIT would be a simplified test just checking if bit 7 is '1' or not. One of the things BIT does is move bit7 to the N flag so we can use BMI or BPL to branch if bit7 is '1' or '0'. Should work but CMP with $F0 is perhaps more readable
Re: LORES: different between ROM 1.0 and ROM1.1?
I was completely wrong with LSR and bit 7, as it shifts a zero in.
So I now have the new listing, thanks to all your remarks and a bit of thinking here, we are now at 16 bytes
Code: Select all
AE 18 B9 LDX $B918 Test if we have a ROM 1.0: value FF in $B918 (3F on ROM 1.1, 7F once shifted on ROM 1.0)
E8 INX increment by 1 to get 00 if we had FF, thus get ready to change a whole page
D0 09 BNE exit if result was different from 00, it's not a ROM 1.0 or it was already fixed, so exit!
loop:
5E 00 B9 LSR $B900,X shift bytes from page $B9
5E 00 BA LSR $BA00,X shift bytes from page $BA
CA DEX Next byte
D0 F7 BNE loop As long as X is not zeroed again, loop
exit:
60 RTS
- run the code on Oric-1
- try to enter a basic line like: 50 JIJ
- you should get an ?OUT OF MEMORY ERROR
Strange things already happened with the previous versions. Are we messing up something in the Oric-1 system by changing values between B900 and BAFF?
EDIT: tried to save/restore X, etc. before/after, but no change.
EDIT 2: actually, it's the loading routines in ROM 1.0 that mess with the "end of basic" pointer, even when loading a memory block 9C-9D in zero page have a wrong value after the loading.
Seems also the $100 address is not a good idea when playing with Basic or the interpreter afterwards.