Jump to content
Vorticon

CP/M related questions

Recommended Posts

Since I foresee having lots of questions related to CP/M on the Adam, I figured I might as well create a bucket topic for them. Who knows, it might even be useful for others! :)

So my first question is: how does one access the VDP (video display processor) from CP/M in assembly? On the TI 99/4A, which uses a similar VDP chip (9918A), the assembler has instructions specifically designed for this purpose to set up the VDP registers and read/write data from/to the VDP RAM space which is separate from the user RAM.

At this time I'm looking to switch from graphics mode to 40 col text mode under CP/M, although of course having complete access to the VDP would be awesome!

Share this post


Link to post
Share on other sites

So I made a little progress in figuring this out via the Hacker's guide and the Adam technical reference and it looks like ports 190 and 191 on the Z80 are mapped to the VDP and I should be able to access it using an OUT instruction in assembly. I need to experiment a bit though because the Hacker's guide does not give any examples on how to do it in practice.

Unfortunately, the OUT instruction is throwing a syntax error every time during assembly with the ASM assembler under CP/M even though I know my syntax is correct. 

OUT (C),B

This should work, transferring the 8-bit contents of register B to the port referenced by register C.

Does anyone here have any experience with the OUT instruction on the Adam?

Share this post


Link to post
Share on other sites

So I made a little progress in figuring this out via the Hacker's guide and the Adam technical reference and it looks like ports 190 and 191 on the Z80 are mapped to the VDP and I should be able to access it using an OUT instruction in assembly. I need to experiment a bit though because the Hacker's guide does not give any examples on how to do it in practice.

Unfortunately, the OUT instruction is throwing a syntax error every time during assembly with the ASM assembler under CP/M even though I know my syntax is correct. 

OUT (C),B

This should work, transferring the 8-bit contents of register B to the port referenced by register C.

Does anyone here have any experience with the OUT instruction on the Adam?

HI - I have TONS of experience with programming the Adam and the z80 - it is better to contact me on FB or via email - I do not come on here often

 

William "Milli" Hicks

Share this post


Link to post
Share on other sites

HI - I have TONS of experience with programming the Adam and the z80 - it is better to contact me on FB or via email - I do not come on here often

 

William "Milli" Hicks

 

Done :)

Share this post


Link to post
Share on other sites

For the benefits of others however, it turned out that the OUT instruction which is Z80 specific is not supported by the standard CP/M 2.2 assembler ASM as the latter only recognizes 8080 code, a subset of Z80. Did not know that... On real hardware, the workaround is to replace the OUT instruction with its proper opcode in the hex file, a pain at the very least. Under emulation, Mili Vee suggested using an online Z80 assembler here: http://clrhome.org/asm/.

I did a small test in DDT on my Adam machine to set up 40 col text mode using the following code (no comments in DDT and replace out(c),b with ED41). Run with a g100 assuming you started assembly at 100h (bottom of TPA). This code tidbit should complement the info in the Hacker's guide.

mvi c,bf ;VDP port address in c
mvi b,21 ;green on black
out (c),b ;write byte to port
mvi b,87 ;select VDP register 7
out (c),b
mvi b,f0 ;set up VDP register 1 for text mode
out (c),b
mvi b,81 ;select VDP register 1
out (c),b 
rst 7 ;return to CP/M

Share this post


Link to post
Share on other sites

I'll post this here but the discussion will be on FB
 

I have just finished reverse engineering how CP/M sets up the VDP. For those of you that want access graphics in CP/M here is the basic CPM VDP setup

 

Notes: CPM breaks the screen up into thirds: TOP, MID, BOT
CPM uses a sprite for the cursor

0000h - 07FFh Font patterns for the top 8 lines of screen

0800h - 0FFFh Font patterns for the middle 8 lines of screen

1000h - 17FFh Font patterns for the bottom 8 lines of screen

1800h - 18FFh Characters for the top 8 lines

1900h - 19FFh Characters for the middle 8 lines

1A00h - 1AFFh Characters for the bottom 8 lines

1B00h - 1FFFh Unused, CP/M may use for scratch RAM

2000h - 27FFh Colors for the top 8 lines of the screen

2800h - 3FFFh Colors for the middle 8 lines of the screen

3000h - 37FFh Colors for the bottom 8 lines of the screen

3800h - 387Fh Sprite Data, 128 bytes used for cursor

3880h - 38FFh Sprite attributes

3900h - 3FFFh Unused, CP/M may use for scratch RAM
 

Milli

Share this post


Link to post
Share on other sites

As I was inspecting the VDP map Milli put up, I realized it was nothing more than the standard bitmap mode!

I confirmed that by playing with the VDP registers a little. Why they did not instead go for the much easier to use text mode is unclear to me... At the very least they could have changed the character set to accommodate 40 columns in bitmap rather than the ridiculously complicated 32 col scheme. 

Jeff Brown even created an 80 col font for the bitmap mode which was used in his Term80 terminal program for the TI 99/4A to emulate 80 columns on the VDP. It was surprisingly readable! Theoretically one should be able to patch the CP/M BIOS on the Adam to load the 80col font on startup from disk and change the display scheme to suppress scrolling and we should end up with an 80 column system with no additional hardware. BIOS hacking is not trivial though... Something for me to look into at some point :)

Share this post


Link to post
Share on other sites
Yes, please do! Thanks to you guys we hopefully soon will be able to program graphics, sound and joystick controls in CP/M (and even better, Turbo Pascal), in 80 columns. I think that will usher in a new wave of CV games, and Adam software too.

Share this post


Link to post
Share on other sites

Ahh, a most interesting topic. I do hope there's lots of posts on this subject.

 

For myself I'm a total CP/M n00b so there's every chance I shall be asking some very basic questions in the near future. Apologies in advance for polluting a potentially most interesting thread with daft questions.

 

 

(FWIW: Plan "A" for my attempt at an 80 column card, assuming I get it to work at all, is primarily support for a colour VT100 terminal under CP/M (TDOS?). In the future I'd really, really like to get the computer-side A2Pi software ported to the ADAM... and later there's all sorts of Pi-related projects that could be leveraged for use with an ADAM. Sadly I can't code for toffee and I suspect 6502 code intended to run under the Apple II might be a bit unfunny to port to the Z80 on the ADAM. (I believe there is source code available)

Sadly my card will never be a straight replacement for the 9918A, but I'd be very willing to do a Pi-ADAM (Colecovision) interface with a view to making a F18a-esque board - if anyone with the coding talent was interested in the software side.)

Share this post


Link to post
Share on other sites

I was wondering if any one here has any suggestions for my dilemma. I asked on the Facebook page but unfortunately so far no luck.

Is there a way to trap the Missing Media and Unknown Drive errors so that they don't cause a warm boot in CP/M? While this is fine at the command line, if this happens inside a program then it causes a crash and loss of data. None of the BDOS functions work here because they also cause a warm boot when trying to access a non-existent drive or an empty one.

For example, if I try to access drive B (no disk inserted) using BDOS function Eh, I immediately get an error and drop back to the CCP. 

 

[attachment=641671:CPM.jpg]

 

Any thoughts? I have been at this for the past 3 days, scouring the internet for information, but to no avail... I might just have to live with it short of hacking the BIOS which I am not really inclined to consider at this time...

Share this post


Link to post
Share on other sites

 

For the benefits of others however, it turned out that the OUT instruction which is Z80 specific is not supported by the standard CP/M 2.2 assembler ASM as the latter only recognizes 8080 code, a subset of Z80. Did not know that... On real hardware, the workaround is to replace the OUT instruction with its proper opcode in the hex file, a pain at the very least. Under emulation, Mili Vee suggested using an online Z80 assembler here: http://clrhome.org/asm/.

I did a small test in DDT on my Adam machine to set up 40 col text mode using the following code (no comments in DDT and replace out(c),b with ED41). Run with a g100 assuming you started assembly at 100h (bottom of TPA). This code tidbit should complement the info in the Hacker's guide.

Just wondering... does the CP/M assembler do macros?  Does it have assembler directives for placing literal bytes at . ? (like the .byte directive in AT&T ASM)  If the answer to both of those is yes, then you can create an "out" macro to output the correct assembly.

 

And yeah, the z80 was created by former Intel engineers who decided they could do better.  So z80 was founded on the 8080 instruction set and expanded.  It's mostly compatible, but there are enough differences to make straight 8080 code incompatible.

Share this post


Link to post
Share on other sites

I was wondering if any one here has any suggestions for my dilemma. I asked on the Facebook page but unfortunately so far no luck.

Is there a way to trap the Missing Media and Unknown Drive errors so that they don't cause a warm boot in CP/M? While this is fine at the command line, if this happens inside a program then it causes a crash and loss of data. None of the BDOS functions work here because they also cause a warm boot when trying to access a non-existent drive or an empty one.

For example, if I try to access drive B (no disk inserted) using BDOS function Eh, I immediately get an error and drop back to the CCP. 

 

attachicon.gifCPM.jpg

 

Any thoughts? I have been at this for the past 3 days, scouring the internet for information, but to no avail... I might just have to live with it short of hacking the BIOS which I am not really inclined to consider at this time...

Huh.  I guess CP/M inspired M$DOS's behavior in that too.

 

Not knowing CP/M all that well, I do remember that M$DOS's program segment prefix is based heavily on the CP/M zero-page concept.  The PSP has a set of vectors:  Call to DOS, Terminate program, Break, and Critical error (aka INT 24).  In about that same place, CP/M has the RST vectors.  I bet one of those vectors is analogous to the Critical error, which is where we get the "Abort, Retry, Ignore?" prompts.

 

If Adam has the zero page in ROM, you can bet that its RST vectors point to a location in RAM that can be modified.  For pure ColecoVision, these vectors are in cartridge ROM space around 0x8000, so that the cartridge can supply its own RST handlers.

 

Edit:  I found a CP/M programming manual.  It is definitely not specific to ADAM, but ADAM probably didn't do a huge amount of tweaking either.  There is probably a lot of overlap between what this manual says and what ADAM does.

 

https://web.archive.org/web/20170820223839/http://www.cpm.z80.de/manuals/cpm3-pgr.pdf

 

There is a function call, SET BDOS ERROR MODE (function 45) that determines how physical errors are handled.  Call with register E set to 0xff to simply get an error return code.  Call with 0xfe to get a return code, but still have the OS print out an error message.  Any other value goes to warm restart.

Edited by ChildOfCv

Share this post


Link to post
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.

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...