Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
bios.c
Go to the documentation of this file.
1 /* Re-CP/M: CP/M-like own implementation + Z80 emulator
2  Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
3  Copyright (C)2016-2019 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18 
19 
20 #include "xemu/emutools.h"
21 #include "bios.h"
22 #include "hardware.h"
23 #include "console.h"
24 #include "bdos.h"
25 
26 
27 static int bios_start;
28 
29 // Addr must be 256 byte aligned! This is not a need by the func too much, but in general CP/M apps
30 // may depend on that (?).
31 void bios_install ( int addr )
32 {
33  bios_start = addr;
34  for (int tab_addr = addr, tab_end = addr + 99, fnc_addr = tab_end; tab_addr < tab_end;) {
35  // We could put the "dispatch" points here directly. But some tricky software may expect to have real addresses here, as a true JMP table ...
36  emu_mem_write(tab_addr++, 0xC3); // opcode of "JP"
37  emu_mem_write(tab_addr++, fnc_addr & 0xFF); // jump addr, low byte
38  emu_mem_write(tab_addr++, fnc_addr >> 8); // jump addr, high byte
39  // the dispatches
40  emu_mem_write(fnc_addr++, 0xD3); // opcode of "OUT (n),A", we use this as only a dispatch point
41  emu_mem_write(fnc_addr++, 0xD3); // argument of the OUT, let's use the same as opcode if someone managed to jump on the wrong place ;-P
42  emu_mem_write(fnc_addr++, 0xC9); // opcode of "RET"
43  }
44  // write BIOS call to the "zero page"
45  // it must point to WBOOT, and kinda important, some software use this, to find out the BIOS JUMP table address
46  emu_mem_write(0, 0xC3); // opcode of "JP"
47  emu_mem_write(1, (bios_start + 3) & 0xFF); // low byte for BIOS WBOOT
48  emu_mem_write(2, (bios_start + 3) >> 8); // high byte for BIOS WBOOT
49  DEBUGPRINT("BIOS: installed from $%04X, entry point is $%04X" NL, bios_start, bios_start + 3);
50 }
51 
52 // dispatch addr (OUT emulation with the PC ...)
53 int bios_handle ( int addr )
54 {
55  addr = (addr - bios_start - 99) / 3;
56  if (addr < 0 || addr > 32)
57  return 0; // not BIOS call dispatch area, tell the caller about this
58  DEBUG("BIOS: calling function #%d" NL, addr);
59  switch (addr) {
60  case 0: // BOOT
61  conputs("<<BOOT BIOS vector>>");
62  stop_emulation = 1;
63  break;
64  case 1: // WBOOT
65  conputs("<<WBOOT BIOS vector>>");
66  stop_emulation = 1;
67  break;
68  case 2: // CONST
70  break;
71  case 3: // CONIN
72  Z80_A = console_input();
73  if (Z80_A == 0)
74  Z80_PC -= 2; // re-execute, if no char is read (CONIN should *wait* for character)
75  break;
76  case 4: // CONOUT
78  break;
79  case 5: // LIST, it should wait while printer is ready. But we don't have printer, so who cares to wait ...
80  break;
81  case 6: // PUNCH/AUXOUT, it should wait while paper tape punch / aux device is ready. But we don't have those, so who cares ...
82  break;
83  case 7: // READER, paper tape reader :-O
84  Z80_A = 26; // ^Z should be returned if device is not implemented, which is our case exactly.
85  break;
86  case 8: // HOME
87  break; // move current drive to track 0, we don't have any low-level disk access, just ignore it
88  case 9: // SELDSK, output HL=Disk parameter header
89  Z80_HL = 0; // FIXME?
90  break;
91  case 10: // SETTRK, set tack of current drive
92  break; // ignore
93  case 11: // SETSEC, set sector of current drive
94  break; // ignore
95  case 12: // SETDMA
96  cpm_dma = Z80_BC; // FIXME: is BDOS and BIOS call of setting DMA is the same?!
97  DEBUGPRINT("BIOS: setting DMA to $%04X" NL, cpm_dma);
98  break;
99  case 13: // READ
100  Z80_A = 1; // report unrecoverable error, as we don't emulate low level disk access
101  break;
102  case 14: // WRITE
103  Z80_A = 1; // report unrecoverable error, as we don't emulate low level disk access
104  break;
105  case 15: // LISTST - status of printer
106  Z80_A = 0; // report not ready, we don't emulate printer
107  break;
108  case 16: // SECTRAN, translate sector for skewing
109  Z80_HL = Z80_BC; // we on't emulate low level disk access, but do what others do here as well, without software-skewing used
110  break;
111  // The rest is for CP/M 3 BIOS ... Not so much supported ...
112  default:
113  DEBUGPRINT("BIOS: unknown BIOS call #%d, triggering JMP 0" NL, addr);
114  Z80_PC = 0;
115  break;
116  }
117  return 1; // it WAS BIOS call dispatch area!
118 }
console_input
int console_input(void)
Definition: console.c:157
console_status
int console_status(void)
Definition: console.c:148
Z80_A
#define Z80_A
Definition: z80ex.h:75
emutools.h
bdos.h
bios_handle
int bios_handle(int addr)
Definition: bios.c:53
Z80_HL
#define Z80_HL
Definition: z80ex.h:89
cpm_dma
int cpm_dma
Definition: bdos.c:27
emu_mem_write
void emu_mem_write(int addr, int data)
Definition: hardware.c:129
addr
int addr
Definition: dma65.c:81
stop_emulation
int stop_emulation
Definition: hardware.c:30
bios.h
DEBUGPRINT
#define DEBUGPRINT(...)
Definition: emutools_basicdefs.h:171
NL
#define NL
Definition: fat32.c:37
Z80_C
#define Z80_C
Definition: z80ex.h:80
Z80_BC
#define Z80_BC
Definition: z80ex.h:81
hardware.h
Z80_PC
#define Z80_PC
Definition: z80ex.h:121
bios_install
void bios_install(int addr)
Definition: bios.c:31
DEBUG
#define DEBUG(...)
Definition: emutools_basicdefs.h:167
conputs
void conputs(const char *s)
Definition: console.c:140
console.h
console_output
void console_output(Uint8 data)
Definition: console.c:106