Videopac / Odyssey2 forum
August 25, 2019, 02:54:28 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: If you have some news and you want it to be shown here, pm Janzl!
 
   Home   arcade Help Login Register links videopac.nl  
Pages: 1 [2] 3 4   Go Down
  Print  
Author Topic: mbed emulating a ROM cartridge  (Read 14741 times)
gertk
Post Axe Pete!
*****
Posts: 859



gertk64
WWW
« Reply #15 on: January 06, 2012, 08:10:41 AM »

The emulation part is now working ok, including the Voice emulation.

Steps to take:

  • identify the cartridge roms and load them correctly from the mbed flash space into mbed ram, which chunk goes where, some cartridges use A10 some don't
  • create some kind of menu (Videopac software)
  • try to 'catch' the Videopac CPU after loading a cartridge into mbed ram and start the game, preferably without reset
  • create a cartridge PCB design for mbed or LPC1768
  • update the emulator so it does Chess and Basic module emulation (that is all just software now)
Logged

>>G7000 G7200(P+S) G7400 N60 JET27 VG5000 ZX80 ZX81 ORIC-1 COMX35 Aquarius<<
manopac
Game & App Development
Give this man a Jopac!
*
Posts: 1116



« Reply #16 on: January 06, 2012, 10:58:37 AM »

can't wait for it :-)
Logged

sex, lies, and videopac
gertk
Post Axe Pete!
*****
Posts: 859



gertk64
WWW
« Reply #17 on: January 29, 2012, 10:54:58 PM »

Well, ok this should officially be in 'programming'  I guess..

I now have a usable screen output on the Videopac which can be written into from the mbed. It is based on Rene's original code to rewrite the quads multiple times.

My Videopac code fills the quads from rom space (characters at 0x600 and attributes 0x700) and since the rom can be written into from the mbed side it is now sort of a text output screen which can be controlled by the mbed.

The screen is now 7 lines of 16 characters with color attributes for each character.
My idea is to use this as a menu screen for the Videopac rom images on the mbed's internal storage of which you can then make a selection and it will be loaded into the rom emulator.

I could not manage 128 characters like Rene did because of my routine taking more cycles but still, 7 lines is not bad either. Also it is at the moment PAL only, have not tried it on a Odyssey2 yet. (O2EM displays it the same whether I use the -euro switch or not)

A sneak peak to how the display looks like (after hours and hours of trying to get the timing right):
« Last Edit: May 22, 2012, 07:39:52 AM by gertk » Logged

>>G7000 G7200(P+S) G7400 N60 JET27 VG5000 ZX80 ZX81 ORIC-1 COMX35 Aquarius<<
gertk
Post Axe Pete!
*****
Posts: 859



gertk64
WWW
« Reply #18 on: January 30, 2012, 08:22:15 PM »

Just to show how tight the timing is: In the picture below the white bars represent the time spent in the routine rewriting the quads. If anyone can think of a faster way to write the data for four quads directly from rom...
« Last Edit: May 22, 2012, 07:40:30 AM by gertk » Logged

>>G7000 G7200(P+S) G7400 N60 JET27 VG5000 ZX80 ZX81 ORIC-1 COMX35 Aquarius<<
TedFoolery
Played Munchkin once...
**
Posts: 75


« Reply #19 on: January 31, 2012, 03:45:59 PM »

I wanted to try something last night, but didn't have time.

How many lines were you looking to achieve? If you want a 16x8 display like Rene, you could pack all the data in 0x600 alone. You only really need 2 bytes per character (char/color - bytes 2 & 3), since the X & Y (bytes 0 & 1) are predetermined.
So 8 lines * 16 columns * 2 bytes = 256

Pulling data from 1 page should be quicker than switching between multiple pages.

I think I can get this to work on an NTSC machine. Hopefully I can find some time tonight to tinker around.

...And the goal is to get all the characters inside the large grid, right?
Logged
gertk
Post Axe Pete!
*****
Posts: 859



gertk64
WWW
« Reply #20 on: January 31, 2012, 06:35:12 PM »

I wanted to try something last night, but didn't have time.
How many lines were you looking to achieve? If you want a 16x8 display like Rene, you could pack all the data in 0x600 alone. You only really need 2 bytes per character (char/color - bytes 2 & 3), since the X & Y (bytes 0 & 1) are predetermined.
So 8 lines * 16 columns * 2 bytes = 256

Hi Ted,

If I put all 256 bytes in page 0x600 where would I leave the code to access it with movp ? AFAIk the code has to be on the same page ?

Quote
Pulling data from 1 page should be quicker than switching between multiple pages.

My code jumps from a piece of code on page 0x600 (with 127 bytes characterdata at the beginning of the page) to a piece of code in page 0x700 (with the 127 bytes atttribute data at the beginning). But with 7 lines it might be possible to condense it into a single page. ('attribute data' is the ninth bit and the color) Still the loading of the A register (for movp A,@A) from my pointer register is an extra byte/set of cycles.

Code:
mov R0,#VDC_QUADn  ; select appropriate quad register n
mov A,R5                   ; get pointer (offset from page start) in A
movp A,@A                ; read a byte from 'rom'
movx @R0,A              ; move into VDC register
inc R5                        ; increment pointer
.... ad nauseum for two registers per quad and all quads..
In my first code attempt I jumped from page to page each time for each character per quad in a subroutine but then I thought of 'unrolling the loop' by putting all character writes in one page and all attribute writes in the other (one after eachother) so I only needed to jump once to the other page.

Quote
I think I can get this to work on an NTSC machine. Hopefully I can find some time tonight to tinker around.
...And the goal is to get all the characters inside the large grid, right?

Yes that would be nice but I have disabled the inner lines so it is still inside the large square  Smiley
I am planning to use the characters also, I think it is possible to squeeze in a row of 8 characters before (or after) the quads. And then I have the sprites for a multicolor cursor or such.  Cheesy

I will place my quad fill code here below if Rene does not mind (I used his code as a guideline)  Smiley
« Last Edit: January 31, 2012, 06:56:26 PM by gertk » Logged

>>G7000 G7200(P+S) G7400 N60 JET27 VG5000 ZX80 ZX81 ORIC-1 COMX35 Aquarius<<
TedFoolery
Played Munchkin once...
**
Posts: 75


« Reply #21 on: January 31, 2012, 08:46:14 PM »

There's a command movp3 A,@A  which works like movp, but pulls data specifically from page 3, no matter what page you are currently in (I guess that would mean you'd need to put the data in 0x0700, not 0x0600). You then wouldn't need to put any retrieval code in page 3.
Logged
gertk
Post Axe Pete!
*****
Posts: 859



gertk64
WWW
« Reply #22 on: February 01, 2012, 07:36:12 AM »

There's a command movp3 A,@A  which works like movp, but pulls data specifically from page 3, no matter what page you are currently in (I guess that would mean you'd need to put the data in 0x0700, not 0x0600). You then wouldn't need to put any retrieval code in page 3.

I stumbled on that command too  Smiley When I read it in the 8048 manual I first interpreted it as reading from a page where A10 and A11 where high (meaning 0xC00-0xCFF which would be nice!) but alas it means A8 and A9 are high so it really reads from 'page 3' meaning 0x300-0x3ff .. so that is internal rom of the CPU so it is of no use for my routine.

Here is a small excerpt of my code:

Code:

.org 0x600 ; page boundary
romdata:
;
; include externally generated character codes
;
.include "characters.asm"

; copy character byte
; quad 0 is interleaved with quad 1 and quad 2 is interleaved with quad 3
;
docopy:
mov r0,#0x42 ; pointer to quad '0 0'
mov a,r5 ; get pointer
movp a,@a ; get character byte
movx @r0,a ; store
inc r5

mov r0,#0x52 ; pointer to quad '1 0'
mov a,r5 ; get pointer
movp a,@a ; get character byte
movx @r0,a ; store
inc r5



mov r0,#0x46 ; pointer to quad '0 1'
mov a,r5 ; get pointer
movp a,@a ; get character byte
movx @r0,a ; store
inc r5

mov r0,#0x56 ; pointer to quad '1 1'
mov a,r5 ; get pointer
movp a,@a ; get character byte
movx @r0,a ; store
inc r5
....
        jmp docopy2

; attribute data is preset to be white
;        16 characters on a single row (4 quads)
.org 0x700 ; next page boundary
;
; include externally generated attribute codes
;
.include "attributes.asm"
;
; copy attribute (color and bit 9)

docopy2:
mov r0,#0x43 ; pointer to quad '0 0'
mov a,r5 ; get pointer
add a,#-15 ; adjust pointer back
mov r5,a ; and store
movp a,@a ; get attribute byte
movx @r0,a ; store
inc r5

mov r0,#0x53 ; pointer to quad '1 0'
mov a,r5 ; get pointer
movp a,@a ; get attribute byte
movx @r0,a ; store
inc r5

mov r0,#0x47 ; pointer to quad '0 1'
mov a,r5 ; get pointer
movp a,@a ; get attribute byte
movx @r0,a ; store
inc r5

mov r0,#0x57 ; pointer to quad '1 1'
mov a,r5 ; get pointer
movp a,@a ; get attribute byte
movx @r0,a ; store
inc r5
.....
        jmp copydone     ; jump back to main program

Because of the repetetive character I did not show all lines but you get the idea.
I could shave of a few cycles by interleaving the character and attribute data.This means one  mov R0,#nn can be replaced by inc R0 which should be a bit faster.
Logged

>>G7000 G7200(P+S) G7400 N60 JET27 VG5000 ZX80 ZX81 ORIC-1 COMX35 Aquarius<<
Rene_G7400
Pedit5
I take the Videopac and leave the Canoli!
*
Posts: 2519



WWW
« Reply #23 on: February 01, 2012, 09:45:34 AM »

I will place my quad fill code here below if Rene does not mind (I used his code as a guideline)  Smiley

I don't mind.
Logged
TedFoolery
Played Munchkin once...
**
Posts: 75


« Reply #24 on: February 01, 2012, 04:43:00 PM »

gertk,
Sorry, you're right about the movp3. (forgive me. It's been a while)

And I passed out last night, so I didn't get to try anything. But this is what I was going to try: It's more complex, but you could do a two step process:
1. Somewhere in the middle of a line, you can get the interrupt to move data from ROM into EXRAM. The data can be stored in multiple pages, but interleave it when writing to EXRAM. Since you are not updating the screen, you don't have to turn off the gfx.
2. Now, when the line of text is complete, turn off the gfx and retrieve data from EXRAM and write VDC. This should be a bit faster than reading from ROM. (there is a special setting that enables Ext reads from RAM and Ext writes to VDC)

This is cumbersome, but I think you can shave off a few cycles from the VDC writes.

The VDC writing would be something like this. This is untested.
Code:
mov r0,#0x42 ; pointer to quad '0 0'
mov r1,#0xff ; pointer to exram

orl p1,#0x7c                      ; enable exram reads, vdc writes
anl p1,#0xe7

movx a,@r1 ; get character byte
movx @r0,a ; store
inc r0
dec r1

movx a,@r1 ; get color byte
movx @r0,a ; store
inc r0
inc r0
inc r0
dec r1

movx a,@r1 ; get character byte
movx @r0,a ; store
inc r0
dec r1

..... Insert other read/writes

movx a,@r1 ; get character byte
movx @r0,a ; store
inc r0
dec r1

movx a,@r1 ; get color byte
movx @r0,a ; store
jmp
Logged
gertk
Post Axe Pete!
*****
Posts: 859



gertk64
WWW
« Reply #25 on: February 03, 2012, 10:20:19 PM »

This weekend I will give it a try and mix both methods.

Another weird thing I thought of: the bit which sets 'copy' mode, can it be 'abused' to read from EXRAM and write to the VDC at the same time (both devices selected) I did not check the schematics for this yet.

I used a read with automatic write once for a microcontroller experiment which drove a controllerless 320x240 monochrome LCD display. I connected the 4 bits of the LCD screens high speed bus to a multiplexer which was connected to the RAM chip's 8 bit data bus. By 'dummy' reading an address from ram, the data was clocked into the LCD simultaneously, on each read the multiplexer was flipped to put the other nibble onto the LCD's bus (I did need to read the same byte twice). This way the microcontroller could still determine what had to be sent to the display but there was no need for reading and writing and multiplexing by software. It went from 15 frames per second to over 150 and I had to slow it down back to 70 which was the manufacturers recommended frame rate  Smiley
Logged

>>G7000 G7200(P+S) G7400 N60 JET27 VG5000 ZX80 ZX81 ORIC-1 COMX35 Aquarius<<
manopac
Game & App Development
Give this man a Jopac!
*
Posts: 1116



« Reply #26 on: February 03, 2012, 11:04:22 PM »

Another weird thing I thought of: the bit which sets 'copy' mode, can it be 'abused' to read from EXRAM and write to the VDC at the same time (both devices selected) I did not check the schematics for this yet.

not sure I interpret your question correctly, but yes - thats exactly what the copy mode is for - to copy data fast from EXRAM to VDC ... so its not really abuse ;-)
Logged

sex, lies, and videopac
gertk
Post Axe Pete!
*****
Posts: 859



gertk64
WWW
« Reply #27 on: February 05, 2012, 11:21:46 AM »

not sure I interpret your question correctly, but yes - thats exactly what the copy mode is for - to copy data fast from EXRAM to VDC ... so its not really abuse ;-)

I meant accessing them in 'one stroke' so the read operation from the EXRAM triggers the write operation into the VDC.
If I'd place the data to be written in the same offsets in EXRAM as they are in the VDC you could address them simultaneously.
But since the /WR line is connected directly to the CPU I guess that is not possible (on some microcontrollers you can drive the WR and RD lines just like any other port pin)

Thinking of it: using the same offsets in EXRAM as in the VDC decreases the number of instructions, you'd need only one pointer.. Hmmm...   Smiley

Logged

>>G7000 G7200(P+S) G7400 N60 JET27 VG5000 ZX80 ZX81 ORIC-1 COMX35 Aquarius<<
gertk
Post Axe Pete!
*****
Posts: 859



gertk64
WWW
« Reply #28 on: February 05, 2012, 02:37:02 PM »

Done it.. all 8 lines present using EXRAM in copy mode and filling the EXRAM from 'ROM'.
In the picture below you can see the timing (the white bars are the time spent in copying the quad data from EXRAM)
By using a single pointer it just fits in between the quads vertically..\
The mbed already fills the 'rom' space with a list of filenames found on its internal storage.

Next step is to make the mbed respond to joystick and/or keyboard commands from the Videopac.
I think I will use the already present emulated 'voice command register' as transfer medium to get key or joystick codes to the mbed side and handshake through the T0 line.

« Last Edit: May 22, 2012, 07:41:53 AM by gertk » Logged

>>G7000 G7200(P+S) G7400 N60 JET27 VG5000 ZX80 ZX81 ORIC-1 COMX35 Aquarius<<
gertk
Post Axe Pete!
*****
Posts: 859



gertk64
WWW
« Reply #29 on: February 05, 2012, 02:48:14 PM »

A small piece of the code used:

Code:
..................
;
; wait for start of line 'r6'
;
mov r0,#vdc_scanline ; pointer to VDC scanline register
mov r1,#vdc_scanrow ; pointer to VDC scanrow register
;
; wait for scanline to arrive at next Y (r6) position
;
chky:
movx a,@r1 ; read scanrow
movx a,@r0 ; read scanline
add a,r6           ; add R6 (compare to -R6)
jnc chky           ; if not reached, just wait


; --------------------------------------------------------------------------------
; disable VDC output and set the new Y positions for all 4 quads
; this routine needs to be as short as possible
;
mov r1,#vdc_control ; preset r1 to vdc control
mov a,#0x0a ; set grid on and strobe XY but disable display
movx @r1,a ; store in vdc control

mov r0,#vdc_color ; timing debug code
mov a,#0x3a
movx @r0,a

mov a,r4 ; get Y pos for this line of quads
mov r0,#vdc_quad0_ypos ; store in quad 0 y position
movx @r0,a
mov r0,#vdc_quad1_ypos ; store in quad 1 y position
movx @r0,a
mov r0,#vdc_quad2_ypos ; store in quad 2 y position
movx @r0,a
mov r0,#vdc_quad3_ypos ; store in quad 3 y position
movx @r0,a

jmp exram2vdc ; do copy from exram to vdc
copydone:
mov r0,#vdc_color ; timing debug code
mov a,#0x02
movx @r0,a

mov a,#0x2a ; set FOREGROUND, GRID and STROBE XY bits
movx @r1,a ; store in vdc control enable display
; --------------------------------------------------------------------------------

mov a,r4 ; get Y pos for this line of quads
add a,#LINEDISTANCE ; add LINEDISTANCE
mov r4,a ; store back in R4

mov a,r6 ; advance R6 with LINEDISTANCE lines
add a,#-LINEDISTANCE ; store back in R6
mov r6,a

djnz r3,doupdate ; until all screen lines done

jmp mainloop ; endless loop...

;
; copy EXRAM data to VDC in copy mode
; the data is already set at VDC offsets
exram2vdc:
;
; enable 'copy' mode
;
orl p1,#0x7c            ; enable exram reads, vdc writes
anl p1,#0xe7

mov r0,#0x42 ; pointer to quad '0 0' character data
movx a,@r0 ; read from EXRAM
movx @r0,a ; write to VDC
inc r0 ; increment pointer to attribute data
movx a,@r0 ; read from EXRAM
movx @r0,a ; write to VDC

mov r0,#0x52 ; pointer to quad '1 0'
movx a,@r0 ; read from EXRAM
movx @r0,a ; write to VDC
inc r0 ; increment pointer to attribute data
movx a,@r0 ; read from EXRAM
movx @r0,a ; write to VDC
.....
;
; disable 'copy' mode and enable VDC access
;
orl p1,#0xbc            ; enable VDC access
anl p1,#0xb7

jmp copydone ; jump is faster than return
Logged

>>G7000 G7200(P+S) G7400 N60 JET27 VG5000 ZX80 ZX81 ORIC-1 COMX35 Aquarius<<
Pages: 1 [2] 3 4   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!