Ruud
Veteran Member
This is mainly meant for people who are familiar with the V20 8080 mode (or want to learn it). I hope they can correct my findings and/or add their own experiences.
I am trying to find out how to go from 8088 mode to 8080 mode and back when using a NEC V20. And this is the result so far.
BRKEM:
This is from the "User manual":
The BRKEM instruction starts the 8080 emulation mode.
It saves the contents of the PSW, PS, and PC, and resets
the MD flag to O. The segment base and offset values are
then loaded into the PS and PC registers respectively
from the interrupt vector table. The interrupt vector
number is specified by the immediate operand of the
BRKEM instruction.
This and various source code I found lead to these guide lines:
- Choose a free interrupt, like 80H (*)
- Choose a free segment of 64 KB of RAM. This depends purely on what you have running on your system but I personally think of the 64 KB at the end of the program.
- Load the CP/M part from disk into this segment. I think this should be something that fills the segment from 0000h up to 0FFFFH.
- Fill the interrupt segment part of the interrupt with the number of your segment.
- Fill the interrupt offset part with the address where the V20 should start to execute the 8080 code. I wonder if it can be a piece of RAM that can be overwritten by, for example, a CP/M program. In this way we free up some RAM.
- Fill DS with the value of the chosen segment as well.
- Make sure that the interrupt is enabled: STI.
- NASM/MASM/TASM don't know this typical V20 command so a macro has to be created for this instruction.
- Execute: BRKEM 80h
(*) The manual advises to reserve four interrupt vectors:
Vectors 32 to 255 are for general use. These vectors are
used for the four interrupt sources: 2-byte break, BRKEM,
CALLN instructions (during emulation), and INT input.
I have to find out yet what are meant with "2-byte break" and "INT input".
CALLN:
This command is used in 8080 mode.
- We need to reserve a free interrupt like 81H
- Fill the interrupt segment part of the interrupt with the number of your segment.
- Fill the interrupt offset part with the address where the V20 should start to execute the 8080 code for CALLN.
- I created my Z80 assembler so I can add the instructions CALLN and RETI. But I guess someone else has to create macros for these ones.
- Execute: CALLN 81h
CALLN is used to tell the V20 to execute 8088 code. That can range from putting a character on the screen to reading a file from disk into memory. These are pre-programmed tasks and the various codes in the registers tell the V20 what task to execute.
Various source code I saw so far mentioned that the 8088 code should be inside the CP/M segment as well. But I wonder: must it? What about doing a far jump to the segment next to this one and execute the code there? Would surely save memory and that would allow us to do nice tricks without having to worry about narrowing the available memory for CP/M itself.
I found two source codes using CALLN. What wondered me was that they used in fact two interrupts: one to handle BIOS things the other to handle BDOS things. Why should these been kept appart?
RETEM:
This command is used in 8080 mode and is meant to exit the 8080 (more or less) permanently. "More or less" because one of the source codes used RETEM to perform a warm boot. AFAIK a warm boot means reloading the CCP. After the CCP has been loaded, BRKEM has to be executed again. So beside the CCP, another piece of code has to be loaded, the piece that should be executed after BRKEM. Or should a pointer somewhere inside the CCP be enough? I have to find that out as well.
Please shoot
I am trying to find out how to go from 8088 mode to 8080 mode and back when using a NEC V20. And this is the result so far.
BRKEM:
This is from the "User manual":
The BRKEM instruction starts the 8080 emulation mode.
It saves the contents of the PSW, PS, and PC, and resets
the MD flag to O. The segment base and offset values are
then loaded into the PS and PC registers respectively
from the interrupt vector table. The interrupt vector
number is specified by the immediate operand of the
BRKEM instruction.
This and various source code I found lead to these guide lines:
- Choose a free interrupt, like 80H (*)
- Choose a free segment of 64 KB of RAM. This depends purely on what you have running on your system but I personally think of the 64 KB at the end of the program.
- Load the CP/M part from disk into this segment. I think this should be something that fills the segment from 0000h up to 0FFFFH.
- Fill the interrupt segment part of the interrupt with the number of your segment.
- Fill the interrupt offset part with the address where the V20 should start to execute the 8080 code. I wonder if it can be a piece of RAM that can be overwritten by, for example, a CP/M program. In this way we free up some RAM.
- Fill DS with the value of the chosen segment as well.
- Make sure that the interrupt is enabled: STI.
- NASM/MASM/TASM don't know this typical V20 command so a macro has to be created for this instruction.
- Execute: BRKEM 80h
(*) The manual advises to reserve four interrupt vectors:
Vectors 32 to 255 are for general use. These vectors are
used for the four interrupt sources: 2-byte break, BRKEM,
CALLN instructions (during emulation), and INT input.
I have to find out yet what are meant with "2-byte break" and "INT input".
CALLN:
This command is used in 8080 mode.
- We need to reserve a free interrupt like 81H
- Fill the interrupt segment part of the interrupt with the number of your segment.
- Fill the interrupt offset part with the address where the V20 should start to execute the 8080 code for CALLN.
- I created my Z80 assembler so I can add the instructions CALLN and RETI. But I guess someone else has to create macros for these ones.
- Execute: CALLN 81h
CALLN is used to tell the V20 to execute 8088 code. That can range from putting a character on the screen to reading a file from disk into memory. These are pre-programmed tasks and the various codes in the registers tell the V20 what task to execute.
Various source code I saw so far mentioned that the 8088 code should be inside the CP/M segment as well. But I wonder: must it? What about doing a far jump to the segment next to this one and execute the code there? Would surely save memory and that would allow us to do nice tricks without having to worry about narrowing the available memory for CP/M itself.
I found two source codes using CALLN. What wondered me was that they used in fact two interrupts: one to handle BIOS things the other to handle BDOS things. Why should these been kept appart?
RETEM:
This command is used in 8080 mode and is meant to exit the 8080 (more or less) permanently. "More or less" because one of the source codes used RETEM to perform a warm boot. AFAIK a warm boot means reloading the CCP. After the CCP has been loaded, BRKEM has to be executed again. So beside the CCP, another piece of code has to be loaded, the piece that should be executed after BRKEM. Or should a pointer somewhere inside the CCP be enough? I have to find that out as well.
Please shoot