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:
parent
3feb79ad0c
commit
a804375560
|
@ -22,12 +22,13 @@ begtext:
|
||||||
! BDOS and crash CP/M. We cheat by comparing only high bytes
|
! BDOS and crash CP/M. We cheat by comparing only high bytes
|
||||||
! of each address.
|
! of each address.
|
||||||
|
|
||||||
lxi b, __end
|
|
||||||
lda 0x0007
|
lda 0x0007
|
||||||
mov c, a ! c = high byte of BDOS address
|
mov c, a ! c = high byte of BDOS address
|
||||||
mov a, b ! a = high byte of _end
|
lda _cpm_ram+1 ! a = high byte of top of BSS, a.k.a. _end
|
||||||
cmp c
|
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.)
|
! We have to clear the bss. (argify requires it.)
|
||||||
|
|
||||||
|
@ -59,8 +60,10 @@ begtext:
|
||||||
|
|
||||||
! Now the 'heap'.
|
! Now the 'heap'.
|
||||||
|
|
||||||
lxi h, __end
|
lhld 0x0006 ! BDOS entry point
|
||||||
shld _cpm_ram
|
lxi d, -0x806 ! offset to start of CCP
|
||||||
|
dad d
|
||||||
|
shld _cpm_ramtop
|
||||||
|
|
||||||
! C-ify the command line at 0x0080.
|
! C-ify the command line at 0x0080.
|
||||||
|
|
||||||
|
@ -127,31 +130,29 @@ end_of_argify:
|
||||||
lhld argc ! slightly evil
|
lhld argc ! slightly evil
|
||||||
mvi h, 0
|
mvi h, 0
|
||||||
push h
|
push h
|
||||||
push h ! return address is 0
|
call __m_a_i_n
|
||||||
jmp __m_a_i_n
|
.define _cpm_exit, EXIT, __exit
|
||||||
|
_cpm_exit:
|
||||||
.define _cpm_fastexit
|
EXIT:
|
||||||
_cpm_fastexit:
|
__exit:
|
||||||
saved_sp = _cpm_fastexit + 1
|
stc ! set carry bit
|
||||||
|
jnc _cpm_warmboot ! warm boot if not set
|
||||||
|
saved_sp = . + 1
|
||||||
lxi sp, 0 ! patched on startup
|
lxi sp, 0 ! patched on startup
|
||||||
ret
|
ret
|
||||||
|
|
||||||
! Emergency exit routine.
|
! Emergency exit routine.
|
||||||
|
|
||||||
.define EXIT, __exit, _cpm_exit
|
.define _cpm_warmboot
|
||||||
EXIT = 0
|
_cpm_warmboot = 0
|
||||||
__exit = 0
|
|
||||||
_cpm_exit = 0
|
|
||||||
|
|
||||||
! Special CP/M stuff.
|
! Special CP/M stuff.
|
||||||
|
|
||||||
.define _cpm_fcb
|
.define _cpm_fcb
|
||||||
_cpm_fcb = 0x005c
|
_cpm_fcb = 0x005c
|
||||||
|
|
||||||
.define _cpm_ram
|
|
||||||
.comm _cpm_ram, 2
|
|
||||||
.define _cpm_ramtop
|
.define _cpm_ramtop
|
||||||
_cpm_ramtop = 0x0001
|
.comm _cpm_ramtop, 2
|
||||||
|
|
||||||
.define _cpm_default_dma
|
.define _cpm_default_dma
|
||||||
_cpm_default_dma = 0x0080
|
_cpm_default_dma = 0x0080
|
||||||
|
@ -197,5 +198,10 @@ block1: .space 4 ! used by 32 bits divide and
|
||||||
block2: .space 4 ! multiply routines
|
block2: .space 4 ! multiply routines
|
||||||
block3: .space 4 ! must be contiguous (.comm doesn't guarantee this)
|
block3: .space 4 ! must be contiguous (.comm doesn't guarantee this)
|
||||||
|
|
||||||
|
.sect .data
|
||||||
|
.define _cpm_ram
|
||||||
|
_cpm_ram: .data2 __end
|
||||||
|
|
||||||
.sect .rom
|
.sect .rom
|
||||||
progname: .asciz 'ACKCPM'
|
progname: .asciz 'ACKCPM'
|
||||||
|
noroom: .ascii 'No room$'
|
||||||
|
|
|
@ -67,11 +67,14 @@ extern uint8_t* cpm_ramtop;
|
||||||
extern uint8_t cpm_cmdlinelen;
|
extern uint8_t cpm_cmdlinelen;
|
||||||
extern char cpm_cmdline[0x7f];
|
extern char cpm_cmdline[0x7f];
|
||||||
|
|
||||||
/* Special: longjmps out of the program. Don't use if you've overwritten the
|
/* Special: if the CCP hasn't been overwritten, returns to it; otherwise does
|
||||||
* CCP. */
|
* a warmboot. */
|
||||||
extern void cpm_fastexit(void);
|
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);
|
/* 1 */ extern uint8_t cpm_conin(void);
|
||||||
/* 2 */ extern void cpm_conout(uint8_t b);
|
/* 2 */ extern void cpm_conout(uint8_t b);
|
||||||
/* 3 */ extern uint8_t cpm_auxin(void);
|
/* 3 */ extern uint8_t cpm_auxin(void);
|
||||||
|
|
|
@ -1,32 +1,29 @@
|
||||||
#include <cpm.h>
|
#include <cpm.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define OUT_OF_MEMORY (void*)(-1) /* sbrk returns this on failure */
|
#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)
|
int brk(void* newend)
|
||||||
{
|
{
|
||||||
/* We determine the amount of free memory by looking at the address of the
|
uint8_t* p = newend;
|
||||||
* BDOS vector at 0x0006. */
|
|
||||||
char* memtop = (char*) ((*(unsigned char*)0x0007)<<8);
|
|
||||||
char* p = newend;
|
|
||||||
|
|
||||||
if ((p >= memtop) ||
|
if ((p >= cpm_ramtop) ||
|
||||||
(p < _end))
|
(p < _end))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
cpm_ram = p;
|
cpm_ram = (uint8_t*)p;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* sbrk(int increment)
|
void* sbrk(int increment)
|
||||||
{
|
{
|
||||||
char* old;
|
uint8_t* old;
|
||||||
char* new;
|
uint8_t* new;
|
||||||
|
|
||||||
if (increment == 0)
|
if (increment == 0)
|
||||||
return cpm_ram;
|
return cpm_ram;
|
||||||
|
|
12
plat/cpm/libsys/cpm_overwrite_ccp.s
Normal file
12
plat/cpm/libsys/cpm_overwrite_ccp.s
Normal 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
|
Loading…
Reference in a new issue