Miscellaneous byte shaving; you can now choose whether or not you want the CCP

overwritten or not, and cpm_exit() does the right thing.
This commit is contained in:
David Given 2019-06-11 20:32:00 +02:00
parent 3feb79ad0c
commit a804375560
4 changed files with 51 additions and 33 deletions

View file

@ -22,12 +22,13 @@ begtext:
! BDOS and crash CP/M. We cheat by comparing only high bytes
! of each address.
lxi b, __end
lda 0x0007
mov c, a ! c = high byte of BDOS address
mov a, b ! a = high byte of _end
mov c, a ! c = high byte of BDOS address
lda _cpm_ram+1 ! a = high byte of top of BSS, a.k.a. _end
cmp c
rnc ! emergency exit if a >= c
lxi d, noroom
mvi c, 9
jnc 0x0005 ! print error and exit if a >= c
! We have to clear the bss. (argify requires it.)
@ -59,8 +60,10 @@ begtext:
! Now the 'heap'.
lxi h, __end
shld _cpm_ram
lhld 0x0006 ! BDOS entry point
lxi d, -0x806 ! offset to start of CCP
dad d
shld _cpm_ramtop
! C-ify the command line at 0x0080.
@ -127,31 +130,29 @@ end_of_argify:
lhld argc ! slightly evil
mvi h, 0
push h
push h ! return address is 0
jmp __m_a_i_n
.define _cpm_fastexit
_cpm_fastexit:
saved_sp = _cpm_fastexit + 1
call __m_a_i_n
.define _cpm_exit, EXIT, __exit
_cpm_exit:
EXIT:
__exit:
stc ! set carry bit
jnc _cpm_warmboot ! warm boot if not set
saved_sp = . + 1
lxi sp, 0 ! patched on startup
ret
! Emergency exit routine.
.define EXIT, __exit, _cpm_exit
EXIT = 0
__exit = 0
_cpm_exit = 0
.define _cpm_warmboot
_cpm_warmboot = 0
! Special CP/M stuff.
.define _cpm_fcb
_cpm_fcb = 0x005c
.define _cpm_ram
.comm _cpm_ram, 2
.define _cpm_ramtop
_cpm_ramtop = 0x0001
.comm _cpm_ramtop, 2
.define _cpm_default_dma
_cpm_default_dma = 0x0080
@ -197,5 +198,10 @@ block1: .space 4 ! used by 32 bits divide and
block2: .space 4 ! multiply routines
block3: .space 4 ! must be contiguous (.comm doesn't guarantee this)
.sect .data
.define _cpm_ram
_cpm_ram: .data2 __end
.sect .rom
progname: .asciz 'ACKCPM'
noroom: .ascii 'No room$'

View file

@ -67,11 +67,14 @@ extern uint8_t* cpm_ramtop;
extern uint8_t cpm_cmdlinelen;
extern char cpm_cmdline[0x7f];
/* Special: longjmps out of the program. Don't use if you've overwritten the
* CCP. */
extern void cpm_fastexit(void);
/* Special: if the CCP hasn't been overwritten, returns to it; otherwise does
* a warmboot. */
extern void cpm_exit(void);
/* 0 */ extern void cpm_exit(void);
/* Extends cpm_ramtop over the CCP, for a little extra space. */
extern void cpm_overwrite_ccp(void);
/* 0 */ extern void cpm_warmboot(void);
/* 1 */ extern uint8_t cpm_conin(void);
/* 2 */ extern void cpm_conout(uint8_t b);
/* 3 */ extern uint8_t cpm_auxin(void);

View file

@ -1,32 +1,29 @@
#include <cpm.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#define OUT_OF_MEMORY (void*)(-1) /* sbrk returns this on failure */
#define STACK_BUFFER 128 /* number of bytes to leave for stack */
extern char _end[1];
extern uint8_t _end[1];
int brk(void* newend)
{
/* We determine the amount of free memory by looking at the address of the
* BDOS vector at 0x0006. */
char* memtop = (char*) ((*(unsigned char*)0x0007)<<8);
char* p = newend;
uint8_t* p = newend;
if ((p >= memtop) ||
if ((p >= cpm_ramtop) ||
(p < _end))
return -1;
cpm_ram = p;
cpm_ram = (uint8_t*)p;
return 0;
}
void* sbrk(int increment)
{
char* old;
char* new;
uint8_t* old;
uint8_t* new;
if (increment == 0)
return cpm_ram;

View file

@ -0,0 +1,12 @@
#
#include "asm.h"
.define _cpm_overwrite_ccp
_cpm_overwrite_ccp:
mvi a, 0xaf ! 0xaf = xor a = clear carry bit
sta _cpm_exit
lhld _cpm_ramtop
lxi d, 0x800
dad d
shld _cpm_ramtop
ret