One last experiment: Since I figured out, that my Alphatronic P2 has an additional 16 kB card (which might make it a P2U), I shall try to use this memory. This is achieved by bank switching.

Boards assembly

As you have seen, the Alphatronic is very modular. There are several different boards that are connected together with a backplane. The cpu (Intel 8085A) is on one card, and on another is RAM. The computermuseum of the University of Stuttgart also has a Alphatronic computer in its collection and they were so kind to put the system documentation of the Alphatronic P1 and P2 computers online on their FTP server: computermuseum.informatik.uni-stuttgart.de/alphatronic/.

There the assembly of the boards is documented:

boards assembly

So there are two slots for power supply boards, one for the board interfacing the keyboard (which interestingly has an own micro controller on board: 8041A), three slots for for memory boards (RAM), one slot for the video controller (CRT5037), then an empty slot, the floppy controller, the cpu board, another empty slot and then a free slot for I/O cards. To the right are the two mini floppy drives.

In reality this looks like this:

real assembly photo

My Alphatronic only has 2 memory boards (16kB and 48kB). It has no I/O cards, but there doesn’t seem to be real space there either. And one floppy drive is a GoTek emulator.

The Alphatronic was available in several models: P1 and P2 and P2 had two flavors: P2S which is P2 but with better floppy drives (double sided), P2U additionally has 64kB of RAM instead of only 48kB.

It seems that my Alphatronic doesn’t fit any of these, it is basically a P2 with extra 16kB or a P2U with single sided floppy drives.

Memory map

In the same system documentation, there is also the complete memory map specified and it is also explained, how to switch the memory banks. Memory bank switching is necessary, since the Alphatronic will boot up from ROM and ROM itself is 6kB+1kB static RAM, so it total the Alphatronic has 48kB + 16kB + 6kB + 1kB memory, which is more than 64kB which is directly addressable by the 16 bit address bus used by 8085A.

memory map

On the left, the memory map of model P2/P2S is displayed. There only the 48kB card is available. The ROM is mapped from 0x0000 to 0x17ff (6 kB), after that the 1 kB static RAM is mapped from 0x1800 to 0x1bff. The space between 0x1c00 to 0x2fff is reserved - probably there is no real memory mapped here. Maybe some other memory repeats here. The video RAM is mapped from 0x3000 to 0x3fff (4 kB). The 48 kB RAM is mapped from 0x4000 to 0xffff.

Now for the memory of model P2U, there are two possible states: the initial (boot) state is like this: The memory from 0x0000 up to 0x3fff is the same: it’s the ROM (from the 8085A booted) and the video RAM. But the remaining memory is partly on the 48 kB card, and partly on the 16 kB card. Exactly: 0x4000 to 0xbfff (32 kB) resides on the 48 kB card, 0xc000 to 0xffff resides on the extra 16 kB card.

This is the status, where I ran all the programs to measure the floppy drive speed. I located it in Measuring Floppy Drive rotation speed - Part 2 at 0xff00 which is then on the extra 16 kB card. I established already, that this memory is slower than the memory at 0x1800, which is the static RAM on the CPU card.

Now there is a mechanism (see below) with which one can switch the lower 16 kB memory space (0x0000 to 0x3fff) with the 16 kB of the memory from the 48 kB, that is currently not accessible. If that switch is done, then the ROM is not available anymore until the memory bank is switched back. After the switch, the memory content from 0x4000 to 0xffff stays the same (also physically), only the lower part is swapped.

I wonder, why they decided to split the 48 kB part in that way. There is also a Alphatronic model P1, which has less memory - only 32 kB. But maybe, the P1 and P2 have the same 48 kB card and only P2 has the additional 16 kB card. Due to bank switching, only 32 kB are available together with the default BIOS (MOS) that runs from ROM. That would mean, that the difference between P2 (with 48 kB) and P2U (with 64 kB) is really only software. This is indicated also in the manual “P2U has 64 K-RAM which however can only be leveraged when using the 64 K-CP/M operating system”.

Switching memory banks

For switching memory banks, one has to write a bit combination out to port 0x78. Switching is as easy as the following assembler sample:

; swap in 16kB - disable system ROM access
mvi a,0x60
out 0x78
; swap out 16kB - enable system ROM access - initial boot state
mvi a,0x20
out 0x78

One interesting note from the manual: “the machine program to switch must be in the address space above 0x4000 otherwise the program will crash.”

Yes, that’s true: the program counter will continue just after the “out” instruction, but when you have switched the memory, you don’t know, what the next instruction is. So it might do something useful, but more likely it won’t.

Another thing to consider is interrupts: The interrupt vectors for 8085A start at address 0x0000. After boot, the initial state is, that the system ROM is available at this address, so the reset interrupt is executed from ROM and the whole system is correctly initialized. But once you have switched and some other interrupt occurs, it would now not be executed from system ROM but from this extra 16 kB RAM. So I guess, the 64-K-CP/M system needs to install its own interrupt vector table.

For my simple experiments I hope, I can do without. And still switch back and forth between the memory spaces.

Another side effect: the video RAM is also not available. I assume, the 64-K-CP/M would need to switch shortly back to update the video RAM in 0x3000-0x3fff. Everytime when something should be printed on the screen.

The plan

On startup, the MOS (system ROM) is available at 0x0000-0x1fff. I don’t know, whether the BASIC interpreter, which is loaded at 0x4000 will use the MOS routines e.g. to print to the screen. So I should be careful when switching the bank and switch it back afterwards. Then hopefully the interpreter won’t crash. But maybe the interpreter just writes directly into the video RAM at 0x3000. But that isn’t available either.

In the previous post Alphatronic P2 speed follow-up 2 I already relocated the floppy index read routine to 0x1800, so I can reuse this. However, I need to switch the memory, before I poke the routine in, so that it ends up in the correct memory location. After the routine returns, the BASIC program should switch back the bank.

In the end, I expect that the program will run as slow as at 0xff00 and not as fast as in the static RAM. If that is the outcome, I can see, that the memory switch worked. I assume, that the memory on the 48 kB card and the 16 kB card is dynamic RAM which requires a refresh cycle regularly. And this might slow it down. The machine programs on the 8085A tend to be always memory intensive, since every instruction needs to be loaded from memory. There is no cache or pipelining involved.

Bank switching routines

The bank switching routines need to be in the upper memory area. I’ll just use 0xff00, which is well known. I need two routines, one to switch to and another one to switch back. For now, these routines will only be called from BASIC, but they could also be called from machine code itself (via the CALL instruction). In any case, the RET instruction needs to be last. It returns to the address that was stored by CALL in the stack register.

; address       machine code    mnemonic        comments
; swap in 16 kB - ROM is not available afterwards
; ff00          3e 60           mvi a, 0x60
; ff02          d3 78           out 0x78
; ff04          c9              ret

; swap out 16 kB - ROM is available again
; ff05          3e 20           mvi a, 0x20
; ff07          d3 78           out 0x78
; ff09          c9              ret

BASIC program

As always, the BASIC program will poke the machine program into memory and call it. This time, we have three machine programs, we can call.

Important detail: We first need to switch the memory bank, before we poke the machine program “read_index_duration” so that it ends up in the correct memory location.

100 '************** DRIVEROT5
110 CLEAR , &HFF00
120 DEFINT D
130 GOSUB 500 ' install switches
140 CALL SWITCH
150 GOSUB 700 ' install read_index_duration
160 CALL BACK
170 PRINT"In the last used drive a floppy has to be inserted!"
180 INPUT"How many measurements should be taken?"; COUNT
190 DIM DAT%(COUNT)
200 FOR D=0 TO COUNT-1
210     PRINT"  Start measurement ";D
220     CALL SWITCH
230     CALL RID(LOOPS%)
240     CALL BACK
250     DAT%(D)=LOOPS%
260     PRINT"    result:";D;"->";DAT%(D)
270 NEXT
280 PRINT"Data ready"
290 MIN=DAT(0) :MAX=MIN :SUM=0
300 FOR D=0 TO COUNT-1
310     IF DAT(D)<MIN THEN MIN=DAT(D)
320     IF DAT(D)>MAX THEN MAX=DAT(D)
330     SUM=SUM+DAT(D)
340 NEXT
350 MEAN=SUM/COUNT
360 LPS=103448! 'loops per second: 3 MHz/29 cycles - dur. of one loop
370 RPM=INT(60*LPS/MEAN+.5)
380 DIF=MAX-MIN
390 PRINT"  Minimum:";MIN/LPS;"s"
400 PRINT"  Maximum:";MAX/LPS;"s"
410 PRINT"     Mean:";MEAN/LPS;"s"
420 PRINT"Rotations:";RPM;"rpm"
430 PRINT" Accuracy:";DIF*1000/LPS;"ms"
440 END
500 ' Machine programs SWITCH and BACK
510 SWITCH=&HFF00 : BACK=&HFF05
520 I=&HFF00
530    READ D$
540    D=VAL("&H"+D$)
550    IF D>255 THEN RETURN
560    POKE I,D
570    I=I+1
580 GOTO 530
590 DATA 3E,60,D3,78,C9,3E,20,D3,78,C9,E0F
700 ' Machine program RID (=read_index_duration)
710 RID=&H1800
720 I=&H1800
730    READ D$
740    D=VAL("&H"+D$)
750    IF D>255 THEN RETURN
760    POKE I,D
770    I=I+1
780 GOTO 730
790 DATA 3E,D4,D3,50,06,40,11,00,00,DB,50,DB,54
800 DATA A0,CA,0B,18,DB,50,13,DB,54,A0,CA,13,18
810 DATA 73,23,72,C9,E0F

Results and summary

Overall the experiment was not successful. At least, the memory switch seems to do something, but as soon as the switch occurred, the program hangs. I verified it with some additional PRINT statements. It just hangs at line 140. Sometimes the MOS restarts with an error code (I guess a warm boot). But it doesn’t run the BASIC program further.

The hang situation also happens when I directly write to the I/O port from basic, which is possible with the OUT statement, e.g. OUT &H78, &H60. So actually, I would not have needed to write the little machine program.

Also adding a DI (disable interrupts) into the switch routine and a EI (enable interrupts) when switching back didn’t help. I’ve inserted it into the machine code, the opcode for DI is 0xF3 and for EI it is 0xFB. It still hung.

The conclusion is, that the basic interpreter seems to call routines from MOS, the firmware. And as soon this is done - while we have switched the memory banks - we get stuck. Because the firmware is not there. Instead, the 16kB memory is there. And this memory is potentially uninitialized, which means it’s hard to say, what will happen. It probably contains random data. And this random data is executed…