I'm creating CPM BIOS in C

Discussion about other targets
Post Reply
DJ Sures
Member
Posts: 67
Joined: Sun Dec 11, 2022 12:41 pm

I'm creating CPM BIOS in C

Post by DJ Sures »

Hey gang - I'm trying something different, which I'm excited about the adventure. I'm creating a CPM BIOS in z88dk C for NABU :D And, it's booting!

The only question I have - that I can't seem to figure out - is how to Get and Set a register value. The only reason I need this is because the BDOS functions pass their parameters in regs C, HL, DE, or BC, and expects A response.

So far I have the BIOS skeleton template done, and it's booting fine. The CCP is calling BDOS functions, which are in turn calling my BIOS functions - such as setdma, seldsk, home, constant, conin, conout, etc... I just can't figure out how to get the register values into C variables.

Any tips?
DJ Sures
Member
Posts: 67
Joined: Sun Dec 11, 2022 12:41 pm

Re: I'm creating CPM BIOS in C

Post by DJ Sures »

Here is the top portion of the bios. And you can see I'm trying the _variable for inline assembly without success. If I can capture the register values at the top of the function and then set a few registers at the bottom before ret. The registers can be mangled in between

Code: Select all

#include "../CPM Loader/Addresses.h"

static void orgit() __naked {
  __asm
  org     BIOS;
  JP	_doBoot;        // 0 Initialize.
  JP	_doWboot;       // 1 Warm boot.
  JP	_doConst;       // 2 Console status.
  JP	_doConin;       // 3 Console input.
  JP	_doConout;      // 4 Console OUTput.
  JP	_doList;        // 5 List OUTput.
  JP	_doPunch;       // 6 punch OUTput.
  JP	_doReader;      // 7 Reader input.
  JP	_doHome;        // 8 Home disk.
  JP	_doSeldsk;      // 9 Select disk.
  JP	_doSettrk;      // 10 Select track.
  JP	_doSetsec;      // 11 Select sector.
  JP	_doSetdma;      // 12 Set DMA ADDress.
  JP	_doRead;        // 13 Read 128 bytes.
  JP	_doWrite;       // 14 Write 128 bytes.
  JP	_doListst;      // 15 List status.
  JP	_doSectran;     // 16 Sector translate.
  jp _doRestartError;
  __endasm;
}

//#define FONT_AMIGA
//#define FONT_SET1
//#define FONT_STANDARD
#define LM80C

#include "RetroNET-FileStore.h"
#include "NABU-LIB.h"

#define BUFFERSIZE 64
uint8_t _buffer[BUFFERSIZE];

/// <summary>
/// If one of the JPs are not returned, then we get here and this should never happen
/// </summary>
void doRestartError() {

  vdp_print("We should never ever be here");

  while (true);
}

/// <summary>
/// 0 Boot Initialize
/// 
/// gets control from the coldstart loader (i.e. CPM Boot Loader)
/// </summary>
void doBoot() __naked {

  volatile static uint8_t val;

  __asm
  ld a, (_val);
//  ld(_val), a;
  __endasm;

  vdp_initTextMode(VDP_WHITE, VDP_DARK_BLUE, true);

  hcca_enableReceiveBufferInterrupt();

  vdp_print("NABU Cloud CP/M BIOS");
  vdp_newLine();

  // set IOBYTE
  // If IOBYTE function is used, we must set it here

  __asm

  // make stack 
  ld sp, 0x100;

  // wipe page zero (0 - 0xff)
  ld hl, 0;
  ld de, 1;
  ld bc, 0xff;
  ld(hl), 0;
  ldir;

  // jump instruction to warm start entry point
  // Allows a simple programmed restart (jp 0x00)
  // address 0, 1, 2 : add a command (JP BIOS + 3 = WBoot)
  ld a, 0xc3; // jp
  ld hl, BIOS + 3;
  ld(0x0000), a;
  ld(0x0001), hl;

  // address 3 : IOBYTE (optional)
  // optionally included in section 6
  ld a, 0x0;
  ld(0x0003), a;

  // address 4 : current drive number (0=a, ..., 15=p)
  ld a, 0x0;
  ld(0x0004), a;

  // init BDOS entrypoint
  // address 5, 6, 7 : add a command (JP BDOS) this is the entry point into BDOS from transient programs for bdos calls
  ld a, 0xc3; // jp
  ld hl, BDOS;
  ld(0x0005), a;
  ld(0x0006), hl;

  // current selected disk
  ld a, 0x04;
  ld c, a;

  jp CCP;
  __endasm;
}
DJ Sures
Member
Posts: 67
Joined: Sun Dec 11, 2022 12:41 pm

Re: I'm creating CPM BIOS in C

Post by DJ Sures »

Oooooooh - I guess the scope matters.

Code: Select all

// 4 Console OUTput
volatile static uint8_t _A;
void doConout() __naked {

  __asm;
  ld a, c;
  ld(__A), a;
  __endasm;

  vdp_write(_A, true);

  __asm
  ret;
  __endasm;
}
DJ Sures
Member
Posts: 67
Joined: Sun Dec 11, 2022 12:41 pm

Re: I'm creating CPM BIOS in C

Post by DJ Sures »

Well this is a lot of fun - and there is quite a bit of assembler, but majority of the cpm bios I've built is actually in C. It's kind of neat proof of concept - guess it's more than that because I'm making it live soon on the nabu channel in the internet adapter. It's a cloud based cp/m that does not require local storage. the bios loads the file system over the hcca. I'm thinking of fudging a few things to make a PWD and CD program, which will send directory and folder change info to and from the bios. So you can make A: into A:\FOLDER ... even though cpm will still show A: as in A:, but really it's A:\FOLDER

Come to think of it... i could modify the CCP to display that folder data as well. hmmmmmm okay
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: I'm creating CPM BIOS in C

Post by stefano »

It's a funny idea, I did something similar in the past replacing the BASIC COMPILER's runtime library with a z88dk-generated one which included trace output information. The result was quite a mock-up (and wouldn't work with the recent versions of z80asm), but was very funny.

Regarding the opportunity of using C on the CP/M system, I ran into those beautiful snippets..

https://github.com/z88dk/z88dk-ext/tree ... ted/CPM/DR
DJ Sures
Member
Posts: 67
Joined: Sun Dec 11, 2022 12:41 pm

Re: I'm creating CPM BIOS in C

Post by DJ Sures »

That's cool CPM C stuff! Right on.

Try as I might, I cannot get my code to compile for a specific address. I'm currently using an .ORG in assembly at the top of my program in a naked function. But the linker is throwing variables at the same memory addresses and all over the place. Here's what I'm using on the commandline...

zcc +z80 -mz80 -Wl-bCSEG=0xDCD0 -zorg 0xdcd0 --code-loc0xdcd0 --stack-loc0 -startup 0 -compiler=sdcc --list --no-crt -O3 --opt-code-speed --no-peep -lm main.c -o "BIOS.BIN"

I have tried every commandline parameter I could find but nothing seems to work.
DJ Sures
Member
Posts: 67
Joined: Sun Dec 11, 2022 12:41 pm

Re: I'm creating CPM BIOS in C

Post by DJ Sures »

It was a long night! But fighting with a limited stack, I was able to get it going. The only libraries I need is stdbool and stdint. I overcame the non-initialized variable issue by initializing every variable lol. I have a lot of optimizing to do because there's functions being called that don't need to be functions, or at least inline.

https://www.youtube.com/watch?v=EO3RATtwr5E
pjshumphreys
Member
Posts: 66
Joined: Sat Feb 06, 2021 2:32 pm

Re: I'm creating CPM BIOS in C

Post by pjshumphreys »

very nice!
DJ Sures
Member
Posts: 67
Joined: Sun Dec 11, 2022 12:41 pm

Re: I'm creating CPM BIOS in C

Post by DJ Sures »

Thanks! I released the BIOS today and it seems to working well. I do wish sdcc displayed more warnings, specifically between types with loss of resolution. I was struggling for a while trying to figure out why I wasn't getting a correct sector reference with this...

Code: Select all

  uint8_t _TRACK = 10;
  uint8_t _SECTOR = 3;
  uint32_t offset = (_TRACK * 128 * 4) + (_SECTOR * 128);
lol - spot it? Took me a day to notice it.

Anyway, here's the release video! https://www.youtube.com/watch?v=sc0_dr1mwvs
Post Reply