diff --git a/.hgignore b/.hgignore index 231210b94..de1136d12 100644 --- a/.hgignore +++ b/.hgignore @@ -1,3 +1,5 @@ .obj .sass-cache _site +.vscode + diff --git a/build.lua b/build.lua index d7eb0829f..ccd113f1a 100644 --- a/build.lua +++ b/build.lua @@ -27,17 +27,8 @@ vars.plats_with_tests = { "pc86", } -local plat_packages = {} -local test_packages = {} -for _, p in ipairs(vars.plats) do - plat_packages[#plat_packages+1] = "plat/"..p.."+pkg" -end -for _, p in ipairs(vars.plats_with_tests) do - test_packages[#test_packages+1] = "plat/"..p.."/tests+tests" -end - installable { - name = "ack", + name = "ack-common", map = { "lang/basic/src+pkg", "lang/cem/cemcom.ansi+pkg", @@ -53,6 +44,31 @@ installable { "util/led+pkg", "util/misc+pkg", "util/opt+pkg", + }, +} + +local plat_packages = {} +local test_packages = {} +for _, p in ipairs(vars.plats) do + local pkg = "plat/"..p.."+pkg" + plat_packages[#plat_packages+1] = pkg + + installable { + name = "ack-"..p, + map = { + "+ack-common", + pkg, + }, + } +end +for _, p in ipairs(vars.plats_with_tests) do + test_packages[#test_packages+1] = "plat/"..p.."/tests+tests" +end + +installable { + name = "ack", + map = { + "+ack-common", "examples+pkg", plat_packages }, diff --git a/first/ackbuilder.lua b/first/ackbuilder.lua index 81e86b528..616c805d2 100644 --- a/first/ackbuilder.lua +++ b/first/ackbuilder.lua @@ -7,6 +7,7 @@ -- is = { set of rule types which made the target } -- } +local posix = require("posix") local emitter = {} local rules = {} local targets = {} @@ -544,7 +545,7 @@ local function definerule(rulename, types, cb) local args = {} for propname, typespec in pairs(types) do - if not e[propname] then + if e[propname] == nil then if not typespec.optional and (typespec.default == nil) then error(string.format("missing mandatory property '%s'", propname)) end diff --git a/mach/i80/ncg/table b/mach/i80/ncg/table index 74c85f89e..783500195 100644 --- a/mach/i80/ncg/table +++ b/mach/i80/ncg/table @@ -2475,5 +2475,6 @@ with hlreg gen shld {label,".reghp"} pat trp -kills ALL -gen Call {label,".trp"} + with areg + kills ALL + gen Call {label,".trp"} diff --git a/plat/cpm/boot.s b/plat/cpm/boot.s index 40ab0d775..4b33dbfab 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 - jnc __exit ! 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.) @@ -46,6 +47,9 @@ begtext: ! Set up the stack (now it's been cleared, since it's in the BSS). + lxi h, 0 + dad sp + shld saved_sp ! save old stack pointer lxi sp, stack + STACKSIZE ! Initialise the rsts (if desired). @@ -54,8 +58,15 @@ begtext: call .rst_init #endif + ! Now the 'heap'. + + 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. - + lxi h, 0x0080 mov a, m ! a = length of command line cpi 0x7F ! 127-byte command lines... @@ -120,15 +131,40 @@ end_of_argify: mvi h, 0 push h call __m_a_i_n - ! FALLTHROUGH +.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 -EXIT: -__exit: - rst 0 +.define _cpm_warmboot +_cpm_warmboot = 0 +! Special CP/M stuff. + +.define _cpm_fcb, _cpm_fcb2 +_cpm_fcb = 0x005c +_cpm_fcb2 = 0x006c + +.define _cpm_ramtop +.comm _cpm_ramtop, 2 + +.define _cpm_default_dma +_cpm_default_dma = 0x0080 + +.define _cpm_iobyte +_cpm_iobyte = 3 + +.define _cpm_cmdlinelen, _cpm_cmdline +_cpm_cmdlinelen = 0x0080 +_cpm_cmdline = 0x0081 + ! Define symbols at the beginning of our various segments, so that we can find ! them. (Except .text, which has already been done.) @@ -139,8 +175,7 @@ __exit: ! Some magic data. All EM systems need these. -.define .trppc, .ignmask, _errno -.comm .trppc, 2 +.define .ignmask, _errno .comm .ignmask, 2 .comm _errno, 2 @@ -153,11 +188,10 @@ envp: .space 2 ! envp array (always empty, must be after argv) ! These are used specifically by the i80 code generator. -.define .trapproc, .retadr, .retadr1 +.define .retadr, .retadr1 .define .bcreg, .areg .define .tmp1, .fra, block1, block2, block3 -.comm .trapproc, 2 .comm .retadr, 2 ! used to save return address .comm .retadr1, 2 ! reserve .comm .bcreg, 2 @@ -168,5 +202,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/descr b/plat/cpm/descr index 58fef69d5..2dea09e10 100644 --- a/plat/cpm/descr +++ b/plat/cpm/descr @@ -3,19 +3,19 @@ # $Revision$ var w=2 -var wa=1 +var wa=2 var p=2 -var pa=1 +var pa=2 var s=2 -var sa=1 +var sa=2 var l=4 -var la=1 +var la=2 var f=4 -var fa=1 +var fa=2 var d=8 -var da=1 +var da=2 var x=8 -var xa=1 +var xa=2 var ARCH=i80 var PLATFORM=cpm var PLATFORMDIR={EM}/share/ack/{PLATFORM} diff --git a/plat/cpm/include/cpm.h b/plat/cpm/include/cpm.h index bdda5ed23..3ea9f6e09 100644 --- a/plat/cpm/include/cpm.h +++ b/plat/cpm/include/cpm.h @@ -1,66 +1,117 @@ -/* - * unistd.h - standard system calls - */ -/* $Id$ */ - -#ifndef _CPM_H -#define _CPM_H +#ifndef CPM_H +#define CPM_H #include -/* These interface provides a very bare-bones interface to the CP/M BDOS. Set - * the following four variables as you wish, call cpm_bdos(), and the contents - * of the variables will have been updated accordingly. */ - -extern uint8_t cpm_a_register; -extern uint16_t cpm_bc_register; -extern uint16_t cpm_de_register; -extern uint16_t cpm_hl_register; +/* EM requires 2-byte alignment, even on the i80, so we can't declare these + * structures to contain uint16_ts. Use U16() to access them. */ -extern void cpm_bdos(void); - -/* Describes the available CP/M BDOS calls. They're a fairly conservative set - * taken from the CP/M 2.0 manual. */ - -enum +typedef struct { - CPM_BDOS_SYSTEM_RESET, - CPM_BDOS_CONSOLE_INPUT, - CPM_BDOS_CONSOLE_OUTPUT, - CPM_BDOS_READER_INPUT, - CPM_BDOS_PUNCH_OUTPUT, - CPM_BDOS_LIST_OUTPUT, - CPM_BDOS_CONSOLE_IO, - CPM_BDOS_GET_IO_BYTE, - CPM_BDOS_SET_IO_BYTE, - CPM_BDOS_PRINT_STRING, - CPM_BDOS_READ_CONSOLE_BUFFER, - CPM_BDOS_GET_CONSOLE_STATUS, - CPM_BDOS_GET_VERSION_NUMBER, - CPM_BDOS_RESET_DISK_SYSTEM, - CPM_BDOS_SELECT_DISK, - CPM_BDOS_OPEN_FILE, - CPM_BDOS_CLOSE_FILE, - CPM_BDOS_SEARCHFIRST, - CPM_BDOS_SEARCHNEXT, - CPM_BDOS_DELETE_FILE, - CPM_BDOS_READ_SEQ, - CPM_BDOS_WRITE_SEQ, - CPM_BDOS_MAKE_FILE, - CPM_BDOS_RENAME_FILE, - CPM_BDOS_GET_LOGIN_VECTOR, - CPM_BDOS_GET_CURRENT_DISK, - CPM_BDOS_SET_DMA_ADDRESS, - CPM_BDOS_GET_ALLOC_VECTOR, - CPM_BDOS_WRITE_PROTECT, - CPM_BDOS_GET_RO_VECTOR, - CPM_BDOS_SET_FILE_ATTR, - CPM_BDOS_GET_DISK_PARMS, - CPM_BDOS_SETGET_USER, - CPM_BDOS_READ_RANDOM, - CPM_BDOS_WRITE_RANDOM, - CPM_BDOS_GET_FILE_SIZE, - CPM_BDOS_SET_RANDOM -}; + uint8_t dr; + uint8_t f[11]; + uint8_t ex; + uint8_t s1; + uint8_t s2; + uint8_t rc; + uint8_t d[16]; + uint8_t cr; + uint8_t r[3]; +} +FCB; + +typedef struct +{ + uint8_t dr; + uint8_t src[11]; + uint8_t _padding[5]; + uint8_t dest[11]; +} +RCB; + +typedef struct +{ + uint8_t us; + uint8_t f[11]; + uint8_t ex; + uint8_t s[2]; + uint8_t rc; + uint8_t al[16]; +} +DIRE; + +typedef struct +{ + uint8_t spt[2]; /* number of 128-byte sectors per track */ + uint8_t bsh; /* block shift; 3=1kB, 4=2kB, 5=4kB etc */ + uint8_t blm; /* block mask; 0x07=1kB, 0x0f=2kB, 0x1f=4k etc */ + uint8_t exm; /* extent mask */ + uint8_t dsm[2]; /* maximum block number */ + uint8_t drm[2]; /* maximum directory entry number */ + uint8_t al[2]; /* directory allocation bitmap */ + uint8_t cks[2]; /* checksum vector size */ + uint8_t off[2]; /* number of reserved tracks */ +} +DPB; + +/* Access an unaligned field (see above). */ +#define U16(ptr) (*(uint16_t*)(ptr)) + +extern FCB cpm_fcb; /* primary FCB */ +extern FCB cpm_fcb2; /* secondary FCB (special purpose) */ +extern uint8_t cpm_iobyte; + +extern uint8_t cpm_default_dma[128]; /* also contains the parsed command line */ +extern uint8_t* cpm_ram; +extern uint8_t* cpm_ramtop; +extern uint8_t cpm_cmdlinelen; +extern char cpm_cmdline[0x7f]; + +/* Special: if the CCP hasn't been overwritten, returns to it; otherwise does + * a warmboot. */ +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); +/* 4 */ extern void cpm_auxout(uint8_t b); +/* 5 */ extern void cpm_lstout(uint8_t b); +/* 6 */ extern uint8_t cpm_conio(uint8_t b); +/* 7 */ extern uint8_t cpm_get_iobyte(void); +/* 8 */ extern void cpm_set_iobyte(uint8_t iob); +/* 9 */ extern void cpm_printstring(const char* s); /* $-terminated */ +/* 10 */ extern uint8_t cpm_readline(uint8_t* buffer); +/* 11 */ extern uint8_t cpm_const(void); +/* 12 */ extern uint16_t cpm_get_version(void); +/* 13 */ extern void cpm_reset_disk_system(void); +/* 14 */ extern void cpm_select_drive(uint8_t disk); +/* 15 */ extern uint8_t cpm_open_file(FCB* fcb); +/* 16 */ extern uint8_t cpm_close_file(FCB* fcb); +/* 17 */ extern uint8_t cpm_findfirst(FCB* fcb); +/* 18 */ extern uint8_t cpm_findnext(FCB* fcb); +/* 19 */ extern uint8_t cpm_delete_file(FCB* fcb); +/* 20 */ extern uint8_t cpm_read_sequential(FCB* fcb); +/* 21 */ extern uint8_t cpm_write_sequential(FCB* fcb); +/* 22 */ extern uint8_t cpm_make_file(FCB* fcb); +/* 23 */ extern uint8_t cpm_rename_file(RCB* rcb); +/* 24 */ extern uint16_t cpm_get_login_vector(void); +/* 25 */ extern uint8_t cpm_get_current_drive(void); +/* 26 */ extern void cpm_set_dma(void* ptr); +/* 27 */ extern uint8_t* cpm_get_allocation_vector(void); +/* 28 */ extern void cpm_write_protect_drive(void); +/* 29 */ extern uint16_t cpm_get_readonly_vector(void); +/* 30 */ extern uint8_t cpm_set_file_attributes(FCB* fcb); +/* 31 */ extern DPB* cpm_get_dpb(void); +/* 32 */ extern uint8_t cpm_get_set_user(uint8_t user); +/* 33 */ extern uint8_t cpm_read_random(FCB* fcb); +/* 34 */ extern uint8_t cpm_write_random(FCB* fcb); +/* 35 */ extern void cpm_seek_to_end(FCB* fcb); +/* 36 */ extern void cpm_seek_to_seq_pos(FCB* fcb); +/* 37 */ extern uint8_t cpm_reset_drives(uint16_t drive_bitmap); +/* 40 */ extern uint8_t cpm_write_random_filled(FCB* fcb); #endif diff --git a/plat/cpm/libsys/_bdos.s b/plat/cpm/libsys/_bdos.s index 4a05dfcdf..fd6b53de5 100644 --- a/plat/cpm/libsys/_bdos.s +++ b/plat/cpm/libsys/_bdos.s @@ -1,55 +1,20 @@ # -! $Source$ -! $State$ -! $Revision$ +#include "asm.h" -! Declare segments (the order is important). +! Calls a BDOS routine and returns the result. +! a = BDOS opcode -.sect .text -.sect .rom -.sect .data -.sect .bss +.define call_bdos +call_bdos: + pop h ! pop return address + pop d ! pop parameter (possibly junk) + push d + push h -.sect .text - -! Calls a BDOS routine. - -.define _cpm_bdos -_cpm_bdos: - push b + push b ! save FP as the BDOS will corrupt it + mov c, a ! move opcode to C + call 0x0005 + pop b ! restore FP - lda _cpm_a_register - - lhld _cpm_bc_register - mov b, h - mov c, l - - lhld _cpm_de_register - mov d, h - mov e, l - - lhld _cpm_hl_register - - call 5 - - shld _cpm_hl_register - - mov h, d - mov l, e - shld _cpm_de_register - - mov h, b - mov l, c - shld _cpm_bc_register - - sta _cpm_a_register - - pop b - ret - -.sect .bss -.define _cpm_a_register, _cpm_bc_register, _cpm_de_register, _cpm_hl_register -.comm _cpm_a_register, 1 -.comm _cpm_bc_register, 2 -.comm _cpm_de_register, 2 -.comm _cpm_hl_register, 2 + xchg ! DE = HL + ret \ No newline at end of file diff --git a/plat/cpm/libsys/_trap.s b/plat/cpm/libsys/_trap.s index a3836c998..cd561fa65 100644 --- a/plat/cpm/libsys/_trap.s +++ b/plat/cpm/libsys/_trap.s @@ -3,23 +3,18 @@ ! $State$ ! $Revision$ -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss +# +#include "asm.h" .define .trp -.define earray, erange, eset, eiovfl, efovfl, efunfl, eidivz, eidivz -.define efdivz, eiund, efund, econv, estack, eheap, eillins, eoddz -.define ecase, ememflt, ebadptr, ebadpc, ebadlae, ebadmon, ebadlin, ebadgto -.define eunimpl - -.sect .text +.define EARRAY, ERANGE, ESET, EIOVFL, EFOVFL, EFUNFL, EIDIVZ, EIDIVZ +.define EFDIVZ, EIUND, EFUND, ECONV, ESTACK, EHEAP, EILLINS, EODDZ +.define ECASE, EMEMFLT, EBADPTR, EBADPC, EBADLAE, EBADMON, EBADLIN, EBADGTO +.define EUNIMPL ! Trap routine -! Expects trap number on stack. +! Expects trap number in A, and must be called directly from the code +! where execution should resume (for those traps which support it). ! Just returns if trap has to be ignored. ! Otherwise it calls a user-defined trap handler if provided. ! When no user-defined trap handler is provided or when the user-defined @@ -51,130 +46,7 @@ EBADGTO = 27 EUNIMPL = 63 ! unimplemented em-instruction called -earray: lxi h,EARRAY - push h - call .trp - ret - -erange: lxi h,ERANGE - push h - call .trp - ret - -eset: lxi h,ESET - push h - call .trp - ret - -eiovfl: lxi h,EIOVFL - push h - call .trp - ret - -efovfl: lxi h,EFOVFL - push h - call .trp - ret - -efunfl: lxi h,EFUNFL - push h - call .trp - ret - -eidivz: lxi h,EIDIVZ - push h - call .trp - ret - -efdivz: lxi h,EFDIVZ - push h - call .trp - ret - -eiund: lxi h,EIUND - push h - call .trp - ret - -efund: lxi h,EFUND - push h - call .trp - ret - -econv: lxi h,ECONV - push h - call .trp - ret - -estack: lxi h,ESTACK - push h - call .trp - ret - -eheap: lxi h,EHEAP - push h - call .trp - ret - -eillins:lxi h,EILLINS - push h - call .trp - ret - -eoddz: lxi h,EODDZ - push h - call .trp - ret - -ecase: lxi h,ECASE - push h - call .trp - ret - -ememflt:lxi h,EMEMFLT - push h - call .trp - ret - -ebadptr:lxi h,EBADPTR - push h - call .trp - ret - -ebadpc: lxi h,EBADPC - push h - call .trp - ret - -ebadlae:lxi h,EBADLAE - push h - call .trp - ret - -ebadmon:lxi h,EBADMON - push h - call .trp - ret - -ebadlin:lxi h,EBADLIN - push h - call .trp - ret - -ebadgto:lxi h,EBADGTO - push h - call .trp - ret - -eunimpl:lxi h,EUNIMPL - push h - call .trp - ret - .trp: - pop h - xthl - push h ! trap number and return address exchanged mov a,l cpi 16 jnc 3f ! jump if trap cannot be ignored @@ -192,10 +64,12 @@ eunimpl:lxi h,EUNIMPL ret ! OGEN DICHT EN ... SPRING!!! 3: - lhld .trapproc ! user defined trap handler? +.define .trapproc +.trapproc = . + 1 + lxi h, 0 ! user defined trap handler held inline here mov a,l ora h - jz 1f ! jump if there was not + jz 1f ! jump if there was not xra a sta .trapproc ! .trapproc := 0 sta .trapproc+1 @@ -206,15 +80,11 @@ eunimpl:lxi h,EUNIMPL pop d ret 1: - lxi h, 6 - push h - lxi h, text - push h - lxi h, 1 - push h - call _write - jmp EXIT + lxi d, text + mvi c, 9 ! write $-terminated string + call 0x0005 + rst 0 ! abend .sect .rom -text: .ascii "TRAP!\n" +text: .ascii "TRAP!\r\n$" diff --git a/plat/cpm/libsys/asm.h b/plat/cpm/libsys/asm.h new file mode 100644 index 000000000..f86b91104 --- /dev/null +++ b/plat/cpm/libsys/asm.h @@ -0,0 +1,13 @@ +#ifndef ASM_H +#define ASM_H + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +#endif diff --git a/plat/cpm/libsys/brk.c b/plat/cpm/libsys/brk.c index 6c139dd2a..5debaa5ff 100644 --- a/plat/cpm/libsys/brk.c +++ b/plat/cpm/libsys/brk.c @@ -1,42 +1,34 @@ -/* $Source$ - * $State$ - * $Revision$ - */ - +#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]; -static char* current = _end; +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; - current = 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 current; + return cpm_ram; - old = current; + old = cpm_ram; new = old + increment; if ((increment > 0) && (new <= old)) diff --git a/plat/cpm/libsys/build.lua b/plat/cpm/libsys/build.lua index c2a75a4c3..9091a6917 100644 --- a/plat/cpm/libsys/build.lua +++ b/plat/cpm/libsys/build.lua @@ -1,12 +1,110 @@ +acklibrary { + name = "internal", + hdrs = { "./*.h" } +} + +local bdos_calls = { + [ 0] = "cpm_exit", + [ 1] = "cpm_conin", + [ 2] = "cpm_conout", + [ 3] = "cpm_auxin", + [ 4] = "cpm_auxout", + [ 5] = "cpm_lstout", + [ 6] = "cpm_conio", + [ 7] = "cpm_get_iobyte", + [ 8] = "cpm_set_iobyte", + [ 9] = "cpm_printstring", + [10] = "cpm_readline", + [11] = "cpm_const", + [12] = "cpm_get_version", + [13] = "cpm_reset_disk_system", + [14] = "cpm_select_drive", + [15] = "cpm_open_file", + [16] = "cpm_close_file", + [17] = "cpm_findfirst", + [18] = "cpm_findnext", + [19] = "cpm_delete_file", + [20] = "cpm_read_sequential", + [21] = "cpm_write_sequential", + [22] = "cpm_make_file", + [23] = "cpm_rename_file", + [24] = "cpm_get_login_vector", + [25] = "cpm_get_current_drive", + [26] = "cpm_set_dma", + [27] = "cpm_get_allocation_vector", + [28] = "cpm_write_protect_drive", + [29] = "cpm_get_readonly_vector", + [30] = "cpm_set_file_attributes", + [31] = "cpm_get_dpb", + [32] = "cpm_get_set_user", + [33] = "cpm_read_random", + [34] = "cpm_write_random", + [35] = "cpm_seek_to_end", + [36] = "cpm_seek_to_seq_pos", + [37] = "cpm_reset_drives", + [40] = "cpm_write_random_filled", +} + +local trap_calls = { + "EARRAY", + "ERANGE", + "ESET", + "EIOVFL", + "EFOVFL", + "EFUNFL", + "EIDIVZ", + "EFDIVZ", + "EIUND", + "EFUND", + "ECONV", + "ESTACK", + "EHEAP", + "EILLINS", + "EODDZ", + "ECASE", + "EMEMFLT", + "EBADPTR", + "EBADPC", + "EBADLAE", + "EBADMON", + "EBADLIN", + "EBADGTO", + "EUNIMPL", +} + +local generated = {} +for n, name in pairs(bdos_calls) do + generated[#generated+1] = normalrule { + name = name, + ins = { "./make_bdos_call.sh" }, + outleaves = { name..".s" }, + commands = { + "%{ins[1]} "..n.." "..name.." > %{outs}" + } + } +end +for _, name in pairs(trap_calls) do + generated[#generated+1] = normalrule { + name = name, + ins = { "./make_trap.sh" }, + outleaves = { name..".s" }, + commands = { + "%{ins[1]} "..name:lower().." "..name.." > %{outs}" + } + } +end + acklibrary { name = "lib", srcs = { "./*.c", "./*.s", + generated }, deps = { "lang/cem/libcc.ansi/headers+headers", - "plat/cpm/include+headers", + "plat/cpm/include+headers", + "+internal", }, vars = { plat = "cpm" 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 diff --git a/plat/cpm/libsys/make_bdos_call.sh b/plat/cpm/libsys/make_bdos_call.sh new file mode 100755 index 000000000..949523007 --- /dev/null +++ b/plat/cpm/libsys/make_bdos_call.sh @@ -0,0 +1,10 @@ +#!/bin/sh +cat <