From a804375560c6f10cad779fc914bd10e2b1758764 Mon Sep 17 00:00:00 2001 From: David Given Date: Tue, 11 Jun 2019 20:32:00 +0200 Subject: [PATCH] Miscellaneous byte shaving; you can now choose whether or not you want the CCP overwritten or not, and cpm_exit() does the right thing. --- plat/cpm/boot.s | 44 ++++++++++++++++------------- plat/cpm/include/cpm.h | 11 +++++--- plat/cpm/libsys/brk.c | 17 +++++------ plat/cpm/libsys/cpm_overwrite_ccp.s | 12 ++++++++ 4 files changed, 51 insertions(+), 33 deletions(-) create mode 100644 plat/cpm/libsys/cpm_overwrite_ccp.s diff --git a/plat/cpm/boot.s b/plat/cpm/boot.s index 64f85fd2a..1330e8309 100644 --- a/plat/cpm/boot.s +++ b/plat/cpm/boot.s @@ -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$' diff --git a/plat/cpm/include/cpm.h b/plat/cpm/include/cpm.h index 9a354eb03..81dfa5dab 100644 --- a/plat/cpm/include/cpm.h +++ b/plat/cpm/include/cpm.h @@ -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); diff --git a/plat/cpm/libsys/brk.c b/plat/cpm/libsys/brk.c index e9f13c1e6..5debaa5ff 100644 --- a/plat/cpm/libsys/brk.c +++ b/plat/cpm/libsys/brk.c @@ -1,32 +1,29 @@ #include +#include #include #include #include #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; diff --git a/plat/cpm/libsys/cpm_overwrite_ccp.s b/plat/cpm/libsys/cpm_overwrite_ccp.s new file mode 100644 index 000000000..78083b770 --- /dev/null +++ b/plat/cpm/libsys/cpm_overwrite_ccp.s @@ -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