Jump to content
IGNORED

Project Veronica


Recommended Posts

Here is a simple application that shows how to program for Veronica. It should be self explanatory. You need a fairly new version of Mads in order to assemble the below program.

 

//*********************************************************************************************************************
// Constants
//*********************************************************************************************************************
// Atari hardware register
SEMAPHORE_WAIT = $00 // b7 = 0
SEMAPHORE_SIGNALLED = $80 // b7 = 1
RAMBANK_REGION_1_ENABLED = $20 // b5 = 1
RAMBANK_REGION_0_DISABLED = $00 // b4 = 0
RAMBANK_REGION_0_ENABLED = $10 // b4 = 1
SUBBANK_1 = $08 // b3 = 1
RAMBANK_CONFIG_A = $00 // b1 = 0
VERONICA_CPU_HALTED = $00 // b0 = 0
VERONICA_CPU_STARTED = $01 // b0 = 1
// Veronica hardware register
RAMBANK_LOCATION_4000 = $40 // b6 = 1
SEMAPHORE_BIT_MASK = $80 // b7
RAMBANK_LOCATION_MASK = $40 // b6
RAMBANK_CONFIG_SWITCH = $02 // b1
VERONICA_BOOTSTRAP_PREPARATION = SEMAPHORE_SIGNALLED |\
RAMBANK_REGION_1_ENABLED |\
RAMBANK_REGION_0_DISABLED |\
SUBBANK_1 |\
RAMBANK_CONFIG_A |\
VERONICA_CPU_HALTED
VERONICA_STARTUP =\
SEMAPHORE_WAIT |\
RAMBANK_REGION_1_ENABLED |\
RAMBANK_REGION_0_ENABLED |\
SUBBANK_1 |\
VERONICA_CPU_STARTED
INITIAL_VERONICA_STACK_POINTER = $ff
VERONICA_BOOTSTRAP_OFFSET = $3e00
COLOR_LOCATION_OFFSET = $0100
INITIAL_COLOR = 0
PORTB = %11111110
//*********************************************************************************************************************
// Pointers
//*********************************************************************************************************************
// Atari memory map.
AtariRambankAddress = $8000
AtariHardwareRegister = $d5c0
AtariColorDataAddress = AtariRambankAddress + COLOR_LOCATION_OFFSET
// Veronica memory map.
VeronicaHardwareRegister = $0200
VeronicaColorData = $0300
VeronicaProgramDestinationAddress = $0400
VeronicaStartupRambankAddress = $c000
VeronicaDestinationRambankAddress = $4000
VeronicaStartupAddress = VeronicaStartupRambankAddress + VERONICA_BOOTSTRAP_OFFSET
VeronicaCpuResetVector = $bffc
VeronicaColorDataAddress = VeronicaDestinationRambankAddress + COLOR_LOCATION_OFFSET
// Hardware
Runad = $02e0
Startup = $2000
Colbak = $d01a
Irqen = $d20e
Portb = $d301
Dmactl = $d400
Wsync = $d40a
Nmien = $d40e
//*********************************************************************************************************************
// Code
//*********************************************************************************************************************
org Startup
jmp program
//*********************************************************************************************************************
.proc program
jsr prepareSystem
jsr bootVeronica
loop
jsr waitForVeronica
jsr processVeronicaData
jsr swapRambanksAndUnlockVeronica
jmp loop
//---------------------------------------------------------------------------------------------------------------------
.proc prepareSystem
jsr disableInterrupts
jsr turnScreenOff
jsr turnSystemAndBasicOff
rts
//---------------------------------------------------------------------------------------------------------------------
.proc disableInterrupts
sei
lda #0
sta Irqen
sta Nmien
rts
.endp
//---------------------------------------------------------------------------------------------------------------------
.proc turnScreenOff
lda #0
sta Dmactl
rts
.endp
//---------------------------------------------------------------------------------------------------------------------
.proc turnSystemAndBasicOff
lda #PORTB
sta Portb
rts
.endp
.endp // prepareSystem
//---------------------------------------------------------------------------------------------------------------------
.proc bootVeronica
jsr prepareVeronica
jsr copyVeronicaBootstrap
jsr setVeronicaCpuResetVector
jsr startVeronica
rts
//---------------------------------------------------------------------------------------------------------------------
.proc prepareVeronica
lda #VERONICA_BOOTSTRAP_PREPARATION
sta AtariHardwareRegister
nop // The RESB signal must be held low for at least two clock cycles after VDD reaches operating voltage.
rts
.endp
//---------------------------------------------------------------------------------------------------------------------
.proc copyVeronicaBootstrap
VERONICA_BOOTSTRAP_SIZE = veronicaBootstrapEnd - veronicaBootstrapBegin
ldy #0
loop:
lda veronicaBootstrapBegin,y
sta AtariRambankAddress+VERONICA_BOOTSTRAP_OFFSET,y
iny
cpy #VERONICA_BOOTSTRAP_SIZE
bne loop
rts
.endp
//---------------------------------------------------------------------------------------------------------------------
.proc setVeronicaCpuResetVector
lda #<VeronicaStartupAddress
sta VeronicaCpuResetVector
lda #>VeronicaStartupAddress
sta VeronicaCpuResetVector+1
rts
.endp
//---------------------------------------------------------------------------------------------------------------------
.proc startVeronica
lda #VERONICA_STARTUP
eor #RAMBANK_CONFIG_SWITCH
sta AtariHardwareRegister
rts
.endp
.endp // bootVeronica
//---------------------------------------------------------------------------------------------------------------------
.proc waitForVeronica
loop:
lda AtariHardwareRegister
bpl loop
rts
.endp
//---------------------------------------------------------------------------------------------------------------------
.proc processVeronicaData
lda AtariColorDataAddress
sta Wsync
sta Colbak
rts
.endp
//---------------------------------------------------------------------------------------------------------------------
.proc swapRambanksAndUnlockVeronica
lda AtariHardwareRegister
and #~SEMAPHORE_BIT_MASK
eor #RAMBANK_CONFIG_SWITCH
sta AtariHardwareRegister
rts
.endp
.endp // program
//*********************************************************************************************************************
veronicaBootstrapBegin = *
.local veronicaBootstrap, VeronicaStartupAddress
ldx #INITIAL_VERONICA_STACK_POINTER
txs
jsr copyProgram
jmp VeronicaProgramDestinationAddress
//---------------------------------------------------------------------------------------------------------------------
.proc copyProgram
VERONICA_PROGRAM_SIZE = veronicaProgramEnd - veronicaProgramBegin
ldy #0
loop:
lda veronicaProgramBegin,y
sta VeronicaProgramDestinationAddress,y
iny
cpy #VERONICA_PROGRAM_SIZE
bne loop
rts
.endp
//---------------------------------------------------------------------------------------------------------------------
veronicaProgramBegin = *
.local veronicaProgram, VeronicaProgramDestinationAddress
jsr changeRambankLocation
jsr initColorData
loop:
jsr waitForAtari
jsr executeCommand
jsr unlockVeronica
jmp loop
//---------------------------------------------------------------------------------------------------------------------
.proc changeRambankLocation
lda VeronicaHardwareRegister
ora #RAMBANK_LOCATION_4000
sta VeronicaHardwareRegister
rts
.endp
//---------------------------------------------------------------------------------------------------------------------
.proc initColorData
lda #INITIAL_COLOR
sta VeronicaColorData
rts
.endp
//---------------------------------------------------------------------------------------------------------------------
.proc waitForAtari
loop:
lda VeronicaHardwareRegister
bpl loop
rts
.endp
//---------------------------------------------------------------------------------------------------------------------
.proc executeCommand
inc VeronicaColorData
lda VeronicaColorData
sta VeronicaColorDataAddress
rts
.endp
//---------------------------------------------------------------------------------------------------------------------
.proc unlockVeronica
lda VeronicaHardwareRegister
and #~SEMAPHORE_BIT_MASK
sta VeronicaHardwareRegister
rts
.endp
.endl // veronicaProgram
veronicaProgramEnd = *
.endl // veronicaBootstrap
veronicaBootstrapEnd = *
//*********************************************************************************************************************
org Runad
dta a(Startup)
Edited by Marek Konopka
  • Like 1
Link to comment
Share on other sites

Minor, but DETECTOR seems to have some issues with the way it measures clock speed. I'm running Veronica emulation at a clock speed locked at 8x against the main Atari clock, but DETECTOR is reporting a speed slightly off for PAL and way off for NTSC:

 

post-16457-0-85080900-1426460998_thumb.jpgpost-16457-0-94509300-1426460994_thumb.jpg

 

 

 

I looked at the project again and found that the polarity of SEMAPHORE bit in last revision is still inverted.

 

 

 

Ha, I knew I was right! :)

 

One thing about the semaphore system, though: it looks like it is a bit tough to do reliable, safe two-way communication. The semaphore bit is the only bit in common, and since neither side has true interlocked operations on the registers which means it may be difficult or impossible to do race-free bidirectional IPC. Only the Atari side can swap the windows, so Veronica must signal through the semaphore or memory window to do so. However, doing so through the semaphore is problematic since the Atari side could be in the middle of read/modify/write on the register, and doing so through the window is also problematic because either side of the window may be active at the moment that Veronica writes into the window. I wonder if it wouldn't be better to have a way for the Atari side to pull IRQ and use the semaphore mainly for the return channel.

 

The reason I bring this up is because I'm wondering about the feasibility of setting up an Atari-like environment within Veronica to have a relatively similar API for running software, such as an accelerated BASIC interpreter. Two issues I've already identified are a lack of interrupts on the Veronica side and the difficulty of getting events back from Veronica to the Atari side.

 

Link to comment
Share on other sites

Minor, but DETECTOR seems to have some issues with the way it measures clock speed.

 

One thing about the semaphore system, though: it looks like it is a bit tough to do reliable, safe two-way communication.

 

The reason I bring this up is because I'm wondering about the feasibility of setting up an Atari-like environment within Veronica to have a relatively similar API for running software, such as an accelerated BASIC interpreter. Two issues I've already identified are a lack of interrupts on the Veronica side and the difficulty of getting events back from Veronica to the Atari side.

DETECTOR is clearly faulty. Will work on fixing it.

 

There might be a race condition on electrical level (need Simius to confirm), however if both sides respect the protocol similar to what was presented in the above program, there will be none. Once one of the sides stores "0" to semaphore it is not allowed to write into it again until polling it gives "1". This scheme protects semaphore from being modified by two writers in uncoordinated fashion.

 

Stripping Veronica from interrupt system was a conscious design decision. It simplifies things a lot, and since its primary goal is to be a coprocessor there is no real need for them.

 

Could you please elaborate more on how interrupts would suppose to help in implementing BASIC on Veronica?

Link to comment
Share on other sites

Once one of the sides stores "0" to semaphore it is not allowed to write into it again until polling it gives "1". This scheme protects semaphore from being modified by two writers in uncoordinated fashion.

 

I don't see how... it's a classic race condition leading to deadlock:

  • Processor A writes 0
  • Processor B writes 0
  • Processor A begins waiting for 1
  • Processor B begins waiting for 1

If atomic primitives were being used then this could be straightforwardly avoided, but the 6502 doesn't have TRB/TSB, and those wouldn't work anyway unless the hardware respects the memory lock signal.

 

Furthermore, there is also a race condition on the Veronica side trying to write to the memory window, since the Atari side and only the Atari side can swap it at any time:

  • Atari enters routine to send message to Veronica
  • Atari writes to its memory window bank
  • Veronica enters routine to send message to Atari
  • Atari swaps memory banks
  • Veronica writes to wrong memory window bank
  • Atari asserts semaphore

Without a way to guard against the Atari side swapping the window, the Veronica CPU can't safely ensure that its writes go to the correct bank. It might be doable, but I think it would require the Veronica CPU to write into an area that was free in both sides of the window, check for a conflict at the end of the write, and retry the write after the Atari swaps the banks back.

 

Could you please elaborate more on how interrupts would suppose to help in implementing BASIC on Veronica?

 

It makes I/O handling closer to what it's like on the Atari, and avoids the need to invoke a service loop in any place that reads I/O locations normally updated by the OS off interrupt. The most direct cases are the break key and the RTCLOK counter.

 

  • Like 1
Link to comment
Share on other sites

 

I don't see how... it's a classic race condition leading to deadlock:

  • Processor A writes 0
  • Processor B writes 0
  • Processor A begins waiting for 1
  • Processor B begins waiting for 1

Furthermore, there is also a race condition on the Veronica side trying to write to the memory window, since the Atari side and only the Atari side can swap it at any time:

 

I think the semaphore operation might have not been explained correctly.

 

Semaphore access is guarded by following rules.

 

1) Semaphore is initialized with "0" on startup/reset.

2) Atari accesses semaphore with default polarity, meaning:

Reads X when semaphore stores X.

Stores X when writing X.

3) Veronica accesses the semaphore with inverted polarity:

Retrieves not X when reading

Stores not X when writing X.

 

Such scheme prevents race conditions.

 

If both sides respect the above protocol there will be no case with two parties writing to semaphore at the same time.

The same applies to window location. It is guarded by the semaphore.

  • Like 1
Link to comment
Share on other sites

Ah, so it's push only. That would work, but means that the Veronica side has no direct way to signal attention -- the Atari side has to poll it by message.

 

BTW, I noticed that the BIOS and rotator are both running the 65816 in emulation mode and not really using anything beyond 65C02 instructions. For instance, the BIOS uses an LDA/STA (dp),Y loop instead of MVN. I assume they were just written this way for expediency and there's no problem running the 65816 in native mode?

Link to comment
Share on other sites

Ah, so it's push only. That would work, but means that the Veronica side has no direct way to signal attention -- the Atari side has to poll it by message.

 

BTW, I noticed that the BIOS and rotator are both running the 65816 in emulation mode and not really using anything beyond 65C02 instructions. For instance, the BIOS uses an LDA/STA (dp),Y loop instead of MVN. I assume they were just written this way for expediency and there's no problem running the 65816 in native mode?

Communication with Veronica is achieved through master/slave model. Atari CPU is always a master device and Veronica CPU a slave one.

 

There are no technical means of signalling interrupts through "LEFT" cartidge port. We decided to go that way in order to provide full compatibility with all Atari 8-bit machines.

 

Indeed, the software created so far does not utilize extended capabilities of 65816. There are no counter-indications for using 16-bit registers or native CPU mode in your own programs.

 

EDIT:

Correction to the above rules: the semaphore bit flag is not re-initialized after soft reset (clearing B0 in $d5c0).

Edited by Marek Konopka
Link to comment
Share on other sites

Differences are:

1. Lack of the crystal oscillator. System clock is now produced by the PLL multiplier (x8) from the 1,77MHz Atari clock.

2. Different memory handling. There is no separate chips of banked memory, which is now mapped in the Veronica system memory chip. Much more complicated CPLD logic because of the need to ensure simultaneous access of the both CPUs to the same memory.

3. Smaller CPLD because of smaller amount of I/O ports needed.

There is no need to upgrade.

Link to comment
Share on other sites

Now, how about making it easier to use... ;-)

 

Seriously, is what you have supplied thus far all the documentation that you intend to provide? Or is it still in development?

 

Can you envision this cartridge being used for anything but straight assembly language programming?

 

-Larry

  • Like 1
Link to comment
Share on other sites

Now, how about making it easier to use... ;-)

 

Seriously, is what you have supplied thus far all the documentation that you intend to provide? Or is it still in development?

 

Can you envision this cartridge being used for anything but straight assembly language programming?

 

-Larry

Just curious - what were you hoping this cart would do? It is a 65816 coprocessor, which means it sits there and runs custom code in parallel with the Atari. Nothing more.

  • Like 2
Link to comment
Share on other sites

Just curious - what were you hoping this cart would do? It is a 65816 coprocessor, which means it sits there and runs custom code in parallel with the Atari. Nothing more.

 

Yes, I understand it is a 65816 co-processor. Hence the "wink."

 

Was hopeful that it would be useful from the 1.79 master side in Basic or other high-level languages via USR calls when speed is needed. Sorting, moving players and missiles, possibly crunching numbers would be things I could think of. And it probably can be. To make it more useful to a wider audience, then there would have to be "cookbook" recipes/examples available. Are you familiar with the "Basic Turbocharger" from Alpha Systems? Some example uses akin to that would be very useful, and would (I think) interest a larger group in purchasing Veronica.

 

And the other possibility that I see is that there will be some applications written that Veronica users can run effectively if they own the cartridge.

Link to comment
Share on other sites

 

Was hopeful that it would be useful from the 1.79 master side in Basic or other high-level languages via USR calls when speed is needed.

 

 

Ok, I understand. You'd ideally like to see high-level language bindings to access the cart.

 

Thinking about that some more, would you like to be able to upload code written in the same high-level language to the cart at run-time (where it is then interpreted on the cart itself), or would you be content to compile the code written in the high-level language down to machine language, store it, and then upload that from Atari BASIC at run-time?

Link to comment
Share on other sites

I think that uploaded from Basic to Veronica in machine code at run-time would be better, but I really never had thought about having some type of interpreter/compiler on the Veronica side. I'm pretty much in the dark as to how to effectively use it. I'm decent in Basic, fair in Action!, and can write short ML routines (under duress).

 

-Larry

Link to comment
Share on other sites

  • 2 weeks later...

Can this be put into an 800 incognito? if so, what about putting it in the right slot?

Well shit. To answer your question, no. The current case (while a beautiful professional design) is too wide to fit into the metal casing of an 800. I won't get to demo this now until after I move, as all my other gear is packed away. Damn.

Link to comment
Share on other sites

IMO -- For someone wanting to code ML demos, it would likely be a nice tool. But even this is definitely a "chicken and egg" situation -- the user would have to have one also to see the benefit. For the typical Atari user, he/she would be better off waiting for the Rapidus or XL14 accelerators. Much more "user friendly." And even for these true accelerators, the greater benefit will be the linear ram. If someone is thinking of buying one, I will sell my "very lightly used" ;) Veronica V1 for $50 + $6 Priority mail to the U.S. Send PM if interested.

 

Nice device, but not for the average user.

 

-Larry

  • Like 1
Link to comment
Share on other sites

It has the advantage of plug & play though, so is much more inviting to the average user. No opening up the machine, no soldering, no having to use custom OSes.

 

Though that said, a faster main CPU has the advantage that some games can immediately benefit and some could do so with mimimal modification.

  • Like 2
Link to comment
Share on other sites

It has the advantage of plug & play though, so is much more inviting to the average user. No opening up the machine, no soldering, no having to use custom OSes.

 

Though that said, a faster main CPU has the advantage that some games can immediately benefit and some could do so with mimimal modification.

Sort of. Both accelerators are "drop in". You will need to remove some memory chips, etc. For the XL14. Not as familiar with Rapidus, but neither should be anything like an Ultimate or VBXE to install. No custom OS that I'm aware of, and in the case of the XL14, choice of acceleration: 1.79, 7.16, or 14.32 MHz.

 

-Larry

Link to comment
Share on other sites

A couple of questions...

 

1. Can Veronica be used as a slave processor with a system that is already CPU upgraded to a 65816?

2. Would you consider making an Atari 800-specific version of Veronica that could use the Right Cartridge slot? I would think that a 'Right Cart" configuration would sell very well, and become a classic piece of gear.

  • Like 2
Link to comment
Share on other sites

That's a great idea in my opinion. Picture an Atari 800 with Veronica in the right cart slot and the dragon cart in the left. (Assuming that actually works). Now stick in an Incognito. (Assuming that also works with everything else.)

  • Like 1
Link to comment
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...