Compare commits

..

3 commits

278 changed files with 36433 additions and 4786 deletions

View file

@ -5,7 +5,7 @@
# What platform to build for by default? # What platform to build for by default?
DEFAULT_PLATFORM ?= pc86 DEFAULT_PLATFORM ?= pc65oo2
# Where should the ACK put its temporary files? # Where should the ACK put its temporary files?
@ -40,7 +40,7 @@ LUA ?= lua
# Which build system to use; use 'ninja' or 'make' (in lower case). Leave # Which build system to use; use 'ninja' or 'make' (in lower case). Leave
# blank to autodetect. # blank to autodetect.
BUILDSYSTEM ?= BUILDSYSTEM ?= make
# Build flags for ninja. # Build flags for ninja.

View file

@ -6,26 +6,10 @@ vars.ackcflags = {
} }
vars.ackldflags = {} vars.ackldflags = {}
vars.plats = { vars.plats = {
"mintia", "pc65oo2",
"cpm",
"linux386",
"linux68k",
"linuxppc",
"linuxmips",
"msdos86",
"msdos386",
"osx386",
"osxppc",
"pc86",
"rpi",
"pdpv7",
"em22",
} }
vars.plats_with_tests = { vars.plats_with_tests = {
"cpm", "pc65oo2",
"linux68k",
"linuxppc",
"pc86",
} }
local is_windows = os.getenv("OS") == "Windows_NT" local is_windows = os.getenv("OS") == "Windows_NT"
@ -40,7 +24,7 @@ installable {
map = { map = {
"lang/basic/src+pkg", "lang/basic/src+pkg",
"lang/cem/cemcom.ansi+pkg", "lang/cem/cemcom.ansi+pkg",
"lang/m2/comp+pkg", --"lang/m2/comp+pkg",
"lang/pc/comp+pkg", "lang/pc/comp+pkg",
"lang/b/compiler+pkg", "lang/b/compiler+pkg",
"util/ack+pkg", "util/ack+pkg",

62
lib/m65oo2/descr Normal file
View file

@ -0,0 +1,62 @@
# $Revision$
var w=4
var p=4
var s=2
var l=4
var f=4
var d=8
var NAME=m65oo2
var M=m65oo2
var LIB=lib/{M}/tail_
var RT=lib/{M}/head_
var CPP_F=-D__unix -D__USG
var ALIGN=-a0:2 -a1:2 -a2:2 -a3:2
var C_LIB={EM}/{LIB}cc.1s {EM}/{LIB}cc.2g
var OLD_C_LIB={C_LIB}
var MACHOPT_F=-m8
name be
from .m.g
to .s
program {EM}/lib.bin/{M}/ncg
args <
stdout
need .e
end
name as
from .s.so
to .o
program {EM}/lib.bin/{M}/as
args - -o > <
prep cond
end
name led
from .o.a
to .out
program {EM}/lib.bin/em_led
mapflag -l* LNAME={EM}/{LIB}*
mapflag -i SEPID=-b1:0
mapflag -ansi C_LIB={EM}/{LIB}ac
args {ALIGN} {SEPID?} (.e:{HEAD}={EM}/{RT}em) \
({RTS}:.ocm.bas={EM}/{RT}cc) \
({RTS}{ANSI?}:.c={EM}/{RT}cc) \
({RTS}{ANSI?}:.cansi={EM}/{RT}ac) \
({RTS}:.mod={EM}/{RT}m2) \
({RTS}:.p={EM}/{RT}pc) \
-o > < \
(.p:{TAIL}={EM}/{LIB}pc) \
(.bas:{TAIL}={EM}/{LIB}bc) \
(.mod:{TAIL}={EM}/{LIB}m2) \
(.ocm:{TAIL}={EM}/{LIB}ocm) \
(.ocm.bas:{TAIL}={OLD_C_LIB}) \
(.c:{TAIL}={C_LIB}) \
{FLOATS?} \
(.e:{TAIL}={EM}/{LIB}em {EM}/{LIB}mon {EM}/lib/{M}/end_em)
linker
end
name cv
from .out
to .cv
program {EM}/lib.bin/{M}/cv
args < >
outfile a.out
end

21
mach/m65oo2/Action Normal file
View file

@ -0,0 +1,21 @@
name "Intel 8086 assembler"
dir as
end
name "Intel 8086 backend"
dir ncg
end
name "Intel 8086 EM library"
dir libem
end
name "Intel 8086 etext,edata,end library"
dir libend
end
name "Intel 8086 floating point library"
dir libfp
end
name "Intel 8086 PC/IX systemcall library"
dir libsys
end
name "Intel 8086 conversion program from ack.out --> PC/IX a.out"
dir cv
end

12
mach/m65oo2/as/build.lua Normal file
View file

@ -0,0 +1,12 @@
bundle {
name = "headers",
srcs = {
"./mach0.c",
"./mach1.c",
"./mach2.c",
"./mach3.c",
"./mach4.c",
"./mach5.c",
}
}

9
mach/m65oo2/as/mach0.c Normal file
View file

@ -0,0 +1,9 @@
#define THREE_PASS /* branch and offset optimization */
#define LISTING /* enable listing facilities */
#define RELOCATION /* generate relocation info */
#define DEBUG 0
#undef ALIGNWORD
#define ALIGNWORD 4
#undef ALIGNSECT
#define ALIGNSECT 4

19
mach/m65oo2/as/mach1.c Normal file
View file

@ -0,0 +1,19 @@
#define TARGET_SIZE_B 0x0
#define TARGET_SIZE_W 0x1
#define TARGET_SIZE_L 0x2
#define TARGET_SIZE_zext 1 << 2
#define ADDR_SIZE_B (0x0 << 3)
#define ADDR_SIZE_W (0x1 << 3)
#define ADDR_SIZE_L (0x2 << 3)
#define TARGET_SIZE(x) (x & 0x3)
#define TARGET_ZEXT(x) (x & 0x4)
#define ADDR_SIZE(x) (x >> 3)
#define FIT8(x) (((x) & ~((int)0xFF)) == 0)
#define FIT16(x) (((x) & ~((int)0xFFFF)) == 0)
void encode_imm(int opc, int sz, expr_t exp);
void encode_addr(expr_t exp, int sz);
void branch(register int opc,expr_t exp);

18
mach/m65oo2/as/mach2.c Normal file
View file

@ -0,0 +1,18 @@
%token <y_word> SIZE
%token <y_word> REG_acc
%token <y_word> REG_x
%token <y_word> REG_y
%token <y_word> OP_impl
%token <y_word> OP_branch
%token <y_word> OP_arithm
%token <y_word> OP_jump
%token <y_word> OP_jsr
%token <y_word> OP_rol
%token <y_word> OP_bit
%token <y_word> OP_cpx
%token <y_word> OP_inc
%token <y_word> OP_stx
%token <y_word> OP_ldx

76
mach/m65oo2/as/mach3.c Normal file
View file

@ -0,0 +1,76 @@
{0, SIZE, 0x00, ".b"},
{0, SIZE, 0x01, ".w"},
{0, SIZE, 0x02, ".l"},
{0, SIZE, 0x04, ".sb"},
{0, SIZE, 0x05, ".sw"},
{0, REG_acc, 0x00, "a"},
{0, REG_x, 0x00, "x"},
{0, REG_y, 0x00, "y"},
{0, OP_impl, 0x00, "brk"},
{0, OP_impl, 0x08, "php"},
{0, OP_impl, 0x18, "clc"},
{0, OP_impl, 0x28, "plp"},
{0, OP_impl, 0x38, "sec"},
{0, OP_impl, 0x40, "rti"},
{0, OP_impl, 0x48, "pha"},
{0, OP_impl, 0x58, "cli"},
{0, OP_impl, 0x60, "rts"},
{0, OP_impl, 0x68, "pla"},
{0, OP_impl, 0x78, "sei"},
{0, OP_impl, 0x88, "dey"},
{0, OP_impl, 0x8A, "txa"},
{0, OP_impl, 0x98, "tya"},
{0, OP_impl, 0x9A, "txs"},
{0, OP_impl, 0xA8, "tay"},
{0, OP_impl, 0xAA, "tax"},
{0, OP_impl, 0xB8, "clv"},
{0, OP_impl, 0xBA, "tsx"},
{0, OP_impl, 0xC8, "iny"},
{0, OP_impl, 0xCA, "dex"},
{0, OP_impl, 0xD8, "cld"},
{0, OP_impl, 0xE8, "inx"},
{0, OP_impl, 0xEA, "nop"},
{0, OP_impl, 0xF8, "sed"},
{0, OP_branch, 0x10, "bpl"},
{0, OP_branch, 0x30, "bmi"},
{0, OP_branch, 0x50, "bvc"},
{0, OP_branch, 0x70, "bvs"},
{0, OP_branch, 0x90, "bcc"},
{0, OP_branch, 0xB0, "bcs"},
{0, OP_branch, 0xD0, "bne"},
{0, OP_branch, 0xF0, "beq"},
/* XXX: change OP_arithm with smthg more accurate */
{0, OP_arithm, 0x00, "ora"},
{0, OP_arithm, 0x20, "and"},
{0, OP_arithm, 0x40, "eor"},
{0, OP_arithm, 0x60, "adc"},
{0, OP_arithm, 0x80, "sta"},
{0, OP_arithm, 0xA0, "lda"},
{0, OP_arithm, 0xC0, "cmp"},
{0, OP_arithm, 0xE0, "sbc"},
{0, OP_jump, 0x4C, "jmp"},
{0, OP_jsr, 0x20, "jsr"},
{0, OP_rol, 0x00, "asl"},
{0, OP_rol, 0x20, "rol"},
{0, OP_rol, 0x40, "lsr"},
{0, OP_rol, 0x60, "ror"},
{0, OP_bit, 0x2C, "bit"},
{0, OP_cpx, 0xC0, "cpy"},
{0, OP_cpx, 0xE0, "cpx"},
{0, OP_inc, 0xCE, "dec"},
{0, OP_inc, 0xEE, "inc"},
{0, OP_stx, 0x8C, "sty"},
{0, OP_stx, 0x8E, "stx"},
{0, OP_ldx, 0xA0, "ldy"},
{0, OP_ldx, 0xA2, "ldx"},

50
mach/m65oo2/as/mach4.c Normal file
View file

@ -0,0 +1,50 @@
operation
: OP_impl
{ emit1($1);}
| OP_branch expr
{ branch($1, $2);}
| OP_arithm SIZE '#' expr
{ encode_imm($1+0x9, $2, $4);}
| OP_arithm SIZE expr
{ emit1($1+0x0D); encode_addr($3, $2);}
| OP_arithm SIZE expr ',' REG_x
{ emit1($1+0x1D); encode_addr($3, $2);}
| OP_arithm SIZE expr ',' REG_y
{ emit1($1+0x19); encode_addr($3, $2);}
| OP_arithm SIZE '(' expr ',' REG_x ')'
{ emit1($1+0x01); encode_addr($4, $2);}
| OP_arithm SIZE '(' expr ')' ',' REG_y
{ emit1($1+0x11); encode_addr($4, $2);}
| OP_jump expr
{ emit1($1); encode_addr($2, 0);}
| OP_jump '(' expr ')'
{ emit1($1+0x20); encode_addr($3, 0);}
| OP_jsr expr
{ emit1($1); encode_addr($2, 0);}
| OP_rol REG_acc
{ emit1($1+0x0A);}
| OP_rol SIZE expr
{ emit1($1+0x0E);encode_addr($3, $2);}
| OP_rol SIZE expr ',' REG_x
{ emit1($1+0x1E);encode_addr($3, $2);}
| OP_bit SIZE expr
{ emit1($1);encode_addr($3, $2);}
| OP_cpx SIZE '#' expr
{ encode_imm($1, $2, $4);}
| OP_cpx SIZE expr
{ emit1($1+0x0C);encode_addr($3, $2);}
| OP_inc SIZE expr
{ emit1($1+0x0E);encode_addr($3, $2);}
| OP_inc SIZE expr ',' REG_x
{ emit1($1+0x1E);encode_addr($3, $2);}
| OP_stx SIZE expr
{ emit1($1);encode_addr($3, $2);}
| OP_ldx SIZE '#' expr
{ encode_imm($1, $2, $4);}
| OP_ldx SIZE expr
{ emit1($1+0x0C);encode_addr($3, $2);}
| OP_ldx SIZE expr ',' REG_x
{ emit1($1+0x1C);encode_addr($3, $2);}
;

69
mach/m65oo2/as/mach5.c Normal file
View file

@ -0,0 +1,69 @@
void
encode_imm(int opc, int sz, expr_t exp)
{
emit1(opc);
emit1(sz);
switch(TARGET_SIZE(sz))
{
case 0:
if (!FIT8(exp.val)) serror("bad operand size");
emit1(exp.val);
break;
case 1:
if (!FIT16(exp.val)) serror("bad operand size");
emit2(exp.val);
break;
case 2:
emit4(exp.val);
break;
default:
break;
}
}
void
encode_addr(expr_t exp, int sz)
{
uint32_t dist;
dist = exp.val;
if (FIT8(dist))
{
emit1(ADDR_SIZE_B | sz);
emit1(dist & 0xFF);
}
else if (FIT16(dist))
{
emit1(ADDR_SIZE_W | sz);
emit2(dist & 0xFFFF);
}
else
{
emit1(ADDR_SIZE_L | sz);
emit4(dist);
}
}
void branch(register int opc, expr_t exp)
{
uint32_t dist;
dist = exp.val - (DOTVAL + 2);
if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
dist -= DOTGAIN;
if (small(FIT16(dist) && (exp.typ & ~S_DOT) == DOTTYP, 3)) {
emit1(opc); emit2(dist & 0xFFFF);
} else {
emit1(opc^0x20); emit1(0x03); /* Skip over ... */
emit1(0x4C); /* ... far jump. */
#ifdef RELOCATION
newrelo(exp.typ, RELO2);
#endif
emit2(exp.val);
}
}

1266
mach/m65oo2/ce/EM_table Normal file

File diff suppressed because it is too large Load diff

312
mach/m65oo2/ce/as.c Normal file
View file

@ -0,0 +1,312 @@
#include "arg_type.h"
#include "as.h"
static struct t_operand dummy = { IS_REG, AX, 0, 0, 0};
struct t_operand saved_op, *AX_oper = &dummy;
save_op( op)
struct t_operand *op;
{
saved_op.type = op->type;
saved_op.reg = op->reg;
saved_op.expr = op->expr;
saved_op.lab = op->lab;
saved_op.off = op->off;
}
#define last( s) ( s + strlen( s) - 1)
#define LEFT '('
#define RIGHT ')'
#define DOLLAR '$'
block_assemble( instr, nr, first, Last)
char **instr;
int nr, first, Last;
{
int i;
if ( first) {
if( strncmp( instr[0], "pop", 3) == 0) {
*instr[0] = 'P';
*( instr[0]+1) = 'O';
*( instr[0]+2) = 'P';
}
else
@clean_push_buf();
}
if ( Last && strncmp( instr[nr-1], "push", 4) == 0) {
*instr[nr-1] = 'P';
*( instr[nr-1]+1) = 'U';
*( instr[nr-1]+2) = 'S';
*( instr[nr-1]+3) = 'H';
}
for( i=0; i<nr; i++)
assemble( instr[i]);
}
process_label( l)
char *l;
{
}
process_mnemonic( m)
char *m;
{
}
process_operand( str, op)
char *str;
struct t_operand *op;
/* expr -> IS_DATA en IS_LABEL
* reg -> IS_REG en IS_ACCU
* (expr) -> IS_ADDR
* expr(reg) -> IS_MEM
*/
{
char *ptr, *strchr();
op->type = UNKNOWN;
if ( *last( str) == RIGHT) {
ptr = strchr( str, LEFT);
*last( str) = '\0';
*ptr = '\0';
if ( is_reg( ptr+1, op)) {
op->type = IS_MEM;
op->expr = ( *str == '\0' ? "0" : str);
}
else {
set_label( ptr+1, op);
op->type = IS_ADDR;
}
}
else
if ( is_reg( str, op))
op->type = IS_REG;
else {
if ( contains_label( str))
set_label( str, op);
else {
op->type = IS_DATA;
op->expr = str;
}
}
}
int is_reg( str, op)
char *str;
struct t_operand *op;
{
if ( strlen( str) != 2)
return( 0);
switch ( *(str+1)) {
case 'x' :
case 'l' : switch( *str) {
case 'a' : op->reg = 0;
return( TRUE);
case 'c' : op->reg = 1;
return( TRUE);
case 'd' : op->reg = 2;
return( TRUE);
case 'b' : op->reg = 3;
return( TRUE);
default : return( FALSE);
}
case 'h' : switch( *str) {
case 'a' : op->reg = 4;
return( TRUE);
case 'c' : op->reg = 5;
return( TRUE);
case 'd' : op->reg = 6;
return( TRUE);
case 'b' : op->reg = 7;
return( TRUE);
default : return( FALSE);
}
case 'p' : switch ( *str) {
case 's' : op->reg = 4;
return( TRUE);
case 'b' : op->reg = 5;
return( TRUE);
default : return( FALSE);
}
case 'i' : switch ( *str) {
case 's' : op->reg = 6;
return( TRUE);
case 'd' : op->reg = 7;
return( TRUE);
default : return( FALSE);
}
default : return( FALSE);
}
}
#include <ctype.h>
#define isletter( c) ( isalpha( c) || c == '_')
int contains_label( str)
char *str;
{
while( !isletter( *str) && *str != '\0')
if ( *str == '$')
if ( arg_type( str) == STRING)
return( TRUE);
else
str += 2;
else
str++;
return( isletter( *str));
}
set_label( str, op)
char *str;
struct t_operand *op;
{
char *ptr, *strchr(), *sprint();
static char buf[256];
ptr = strchr( str, '+');
if ( ptr == 0)
op->off = "0";
else {
*ptr = '\0';
op->off = ptr + 1;
}
if ( isdigit( *str) && ( *(str+1) == 'b' || *(str+1) == 'f') &&
*(str+2) == '\0') {
*(str+1) = '\0'; /* b of f verwijderen! */
op->lab = str;
op->type = IS_ILB;
}
else {
op->type = IS_LABEL;
if ( strchr( str, DOLLAR) != 0)
op->lab = str;
else
/* nood oplossing */
op->lab = sprint( buf, "\"%s\"", str);
}
}
/******************************************************************************/
mod_RM( reg, op)
int reg;
struct t_operand *op;
{
if ( REG( op))
R233( 0x3, reg, op->reg);
else if ( ADDR( op)) {
R233( 0x0, reg, 0x6);
@reloc2( %$(op->lab), %$(op->off), ABSOLUTE);
}
else if ( strcmp( op->expr, "0") == 0)
switch( op->reg) {
case SI : R233( 0x0, reg, 0x4);
break;
case DI : R233( 0x0, reg, 0x5);
break;
case BP : R233( 0x1, reg, 0x6); /* Uitzondering! */
@text1( 0);
break;
case BX : R233( 0x0, reg, 0x7);
break;
default : fprint( STDERR, "Wrong index register %d\n",
op->reg);
}
else {
@if ( fit_byte( %$(op->expr)))
switch( op->reg) {
case SI : R233( 0x1, reg, 0x4);
break;
case DI : R233( 0x1, reg, 0x5);
break;
case BP : R233( 0x1, reg, 0x6);
break;
case BX : R233( 0x1, reg, 0x7);
break;
default : fprint( STDERR, "Wrong index register %d\n",
op->reg);
}
@text1( %$(op->expr));
@else
switch( op->reg) {
case SI : R233( 0x2, reg, 0x4);
break;
case DI : R233( 0x2, reg, 0x5);
break;
case BP : R233( 0x2, reg, 0x6);
break;
case BX : R233( 0x2, reg, 0x7);
break;
default : fprint( STDERR, "Wrong index register %d\n",
op->reg);
}
@text2( %$(op->expr));
@fi
}
}
mov_REG_EADDR( dst, src)
struct t_operand *dst, *src;
{
if ( REG(src) && dst->reg == src->reg)
; /* Nothing!! result of push/pop optimization */
else {
@text1( 0x8b);
mod_RM( dst->reg, src);
}
}
R233( a, b, c)
int a,b,c;
{
@text1( %d( (a << 6) | ( b << 3) | c));
}
R53( a, b)
int a,b;
{
@text1( %d( (a << 3) | b));
}

40
mach/m65oo2/ce/as.h Normal file
View file

@ -0,0 +1,40 @@
#define UNKNOWN 0
#define IS_REG 0x1
#define IS_ACCU 0x2
#define IS_DATA 0x4
#define IS_LABEL 0x8
#define IS_MEM 0x10
#define IS_ADDR 0x20
#define IS_ILB 0x40
#define AX 0
#define BX 3
#define CL 1
#define SP 4
#define BP 5
#define SI 6
#define DI 7
#define REG( op) ( op->type & IS_REG)
#define ACCU( op) ( op->type & IS_REG && op->reg == AX)
#define REG_CL( op) ( op->type & IS_REG && op->reg == CL)
#define DATA( op) ( op->type & IS_DATA)
#define lABEL( op) ( op->type & IS_LABEL)
#define ILB( op) ( op->type & IS_ILB)
#define MEM( op) ( op->type & IS_MEM)
#define ADDR( op) ( op->type & IS_ADDR)
#define EADDR( op) ( op->type & ( IS_ADDR | IS_MEM | IS_REG))
#define CONST1( op) ( op->type & IS_DATA && strcmp( "1", op->expr) == 0)
#define MOVS( op) ( op->type & IS_LABEL&&strcmp("\"movs\"", op->lab) == 0)
#define IMMEDIATE( op) ( op->type & ( IS_DATA | IS_LABEL))
#define TRUE 1
#define FALSE 0
struct t_operand {
unsigned type;
int reg;
char *expr, *lab, *off;
};
extern struct t_operand saved_op, *AX_oper;

232
mach/m65oo2/ce/as_table Normal file
View file

@ -0,0 +1,232 @@
adc dst:REG, src:EADDR ==> @text1( 0x13);
mod_RM( dst->reg, src).
add dst:REG, src:EADDR ==> @text1( 0x3);
mod_RM( dst->reg, src).
... dst:ACCU, src:DATA ==> @text1( 0x5);
@text2( %$(src->expr)).
... dst:EADDR, src:DATA ==> @text1( 0x81);
mod_RM( 0, dst);
@text2( %$(src->expr)).
... dst:ACCU, src:lABEL ==> @text1( 0x5);
@reloc2( %$(src->lab), %$(src->off), !PC_REL).
... dst:EADDR, src:lABEL ==> @text1( 0x81);
mod_RM( 0, dst);
@reloc2( %$(src->lab), %$(src->off), !PC_REL).
and dst:REG, src:EADDR ==> @text1( 0x23);
mod_RM( dst->reg, src).
... dst:ACCU, src:DATA ==> @text1( 0x25);
@text2( %$(src->expr)).
call dst:lABEL ==> @text1( 0xe8);
@reloc2( %$(dst->lab), %$(dst->off), PC_REL).
... dst:EADDR ==> @text1( 0xff);
mod_RM( 2, dst).
cmp dst:REG, src:EADDR ==> @text1( 0x3b);
mod_RM( dst->reg, src).
... dst:ACCU, src:DATA ==> @text1( 0x3d);
@text2( %$(src->expr)).
... dst:EADDR, src:DATA ==> @text1( 0x81);
mod_RM(7,dst);
@text2( %$(src->expr)).
cwd ==> @text1( 0x99).
dec dst:REG ==> R53( 9, dst->reg).
... dst:EADDR ==> @text1( 0xff);
mod_RM( 1, dst).
div divisor:EADDR ==> @text1( 0xf7);
mod_RM( 6, divisor).
idiv divisor:EADDR ==> @text1( 0xf7);
mod_RM( 7, divisor).
inc dst:REG ==> R53( 8, dst->reg).
... dst:EADDR ==> @text1( 0xff);
mod_RM( 0, dst).
jb dst:ILB ==> @text1( 0x72);
@text1( %dist( dst->lab)).
je dst:ILB ==> @text1( 0x74);
@text1( %dist( dst->lab)).
... dst:lABEL ==> save_op( dst);
assemble( "jne 9f");
jmp_instr( &saved_op);
assemble( "9:").
jg dst:ILB ==> @text1( 0x7f);
@text1( %dist( dst->lab)).
... dst:lABEL ==> save_op( dst);
assemble( "jle 9f");
jmp_instr( &saved_op);
assemble( "9:").
jge dst:ILB ==> @text1( 0x7d);
@text1( %dist( dst->lab)).
... dst:lABEL ==> save_op( dst);
assemble( "jl 9f");
jmp_instr( &saved_op);
assemble( "9:").
jl dst:ILB ==> @text1( 0x7c);
@text1( %dist( dst->lab)).
... dst:lABEL ==> save_op( dst);
assemble( "jge 9f");
jmp_instr( &saved_op);
assemble( "9:").
jle dst:ILB ==> @text1( 0x7e);
@text1( %dist( dst->lab)).
... dst:lABEL ==> save_op( dst);
assemble( "jg 9f");
jmp_instr( &saved_op);
assemble( "9:").
jmp dst:ILB ==> @text1( 0xeb);
@text1( %dist( dst->lab)).
... dst:lABEL ==> @text1( 0xe9);
@reloc2( %$(dst->lab), %$(dst->off), PC_REL).
jne dst:ILB ==> @text1( 0x75);
@text1( %dist( dst->lab)).
... dst:lABEL ==> save_op( dst);
assemble( "je 9f");
jmp_instr( &saved_op);
assemble( "9:").
lea dst:REG, src:EADDR ==> @text1( 0x8d);
mod_RM( dst->reg, src).
loop dst:ILB ==> @text1( 0xe2);
@text1( %dist( dst->lab)).
mov dst:REG, src:EADDR ==> mov_REG_EADDR( dst, src).
... dst:REG, src:DATA ==> R53( 0x17, dst->reg);
@text2( %$(src->expr)).
... dst:REG, src:lABEL ==> R53( 0x17, dst->reg);
@reloc2( %$(src->lab), %$(src->off), !PC_REL).
... dst:EADDR, src:REG ==> @text1( 0x89);
mod_RM( src->reg, dst).
... dst:EADDR, src:DATA ==> @text1( 0xc7);
mod_RM( 0, dst);
@text2( %$(src->expr)).
... dst:EADDR, src:lABEL ==> @text1( 0xc7);
mod_RM( 0, dst);
@reloc2( %$(src->lab), %$(src->off), !PC_REL).
movb dst:REG, src:EADDR ==> @text1( 0x8a);
mod_RM( dst->reg, src).
... dst:EADDR, src:REG ==> @text1( 0x88);
mod_RM( src->reg, dst).
mul mplier:EADDR ==> @text1( 0xf7);
mod_RM( 4, mplier).
neg dst:EADDR ==> @text1( 0xf7);
mod_RM( 3, dst).
not dst:EADDR ==> @text1( 0xf7);
mod_RM( 2, dst).
or dst:REG, src:EADDR ==> @text1( 0x0b);
mod_RM( dst->reg, src).
pop dst:REG ==> R53( 0xb, dst->reg).
... dst:EADDR ==> @text1( 0x8f);
mod_RM( 0, dst).
POP dst ==> @if ( push_waiting)
mov_instr( dst, AX_oper);
@assign( push_waiting, FALSE).
@else
pop_instr( dst).
@fi.
push src:REG ==> R53( 0xa, src->reg).
... src:EADDR ==> @text1( 0xff);
mod_RM( 6, src).
PUSH src ==> mov_instr( AX_oper, src);
@assign( push_waiting, TRUE).
rcr dst:EADDR, src:CONST1 ==> @text1( 0xd1);
mod_RM( 3, dst).
rep ins:MOVS ==> @text1( 0xf3);
@text1( 0xa5). /* Wie zet direction flag? */
ret ==> @text1( 0xc3). /* Altijd NEAR! */
rol dst:EADDR, src:REG_CL ==> @text1( 0xd3);
mod_RM( 0, dst).
ror dst:EADDR, src:REG_CL ==> @text1( 0xd3);
mod_RM( 1, dst).
sal dst:EADDR, src:REG_CL ==> @text1( 0xd3);
mod_RM( 4, dst).
sar dst:EADDR, src:REG_CL ==> @text1( 0xd3);
mod_RM( 7, dst).
... dst:EADDR, src:CONST1 ==> @text1( 0xd1);
mod_RM( 7, dst).
sbb dst:REG, src:EADDR ==> @text1( 0x1b);
mod_RM( dst->reg, src).
... dst:ACCU, src:DATA ==> @text1( 0x1d);
@text2( %$(src->expr)).
shl dst, src ==> sal_instr( dst, src).
shr dst:EADDR, src:REG_CL ==> @text1( 0xd3);
mod_RM( 5, dst).
... dst:EADDR, src:CONST1 ==> @text1( 0xd1);
mod_RM( 5, dst).
sub dst:REG, src:EADDR ==> @text1( 0x2b);
mod_RM( dst->reg, src).
... dst:EADDR, src:DATA ==> @text1( 0x81);
mod_RM( 5, dst);
@text2( %$(src->expr)).
test dst:REG, src:EADDR ==> @text1( 0x85);
mod_RM( dst->reg, src).
xchg dst:EADDR, src:REG ==> @text1( 0x87);
mod_RM( src->reg, dst).
xor dst:REG, src:EADDR ==> @text1( 0x33);
mod_RM( dst->reg, src).

27
mach/m65oo2/ce/mach.c Normal file
View file

@ -0,0 +1,27 @@
#define CODE_EXPANDER
#include <system.h>
#include "back.h"
#include "mach.h"
#ifdef DEBUG
arg_error( s, arg)
char *s;
int arg;
{
fprint( STDERR, "arg_error %s %d\n", s, arg);
}
#endif
int push_waiting = FALSE;
int fit_byte( val)
int val;
{
return( val >= -128 && val <= 127);
}
#define IEEEFLOAT
#define FL_MSL_AT_LOW_ADDRESS 0
#define FL_MSW_AT_LOW_ADDRESS 0
#define FL_MSB_AT_LOW_ADDRESS 0
#include <con_float>

30
mach/m65oo2/ce/mach.h Normal file
View file

@ -0,0 +1,30 @@
#define BSS_INIT 0
#define ONE_BYTE int
#define TWO_BYTES int
#define FOUR_BYTES long
#define EM_WSIZE 2
#define EM_PSIZE 2
#define EM_BSIZE 4
#define NAME_FMT "_%s"
#define DNAM_FMT "_%s"
#define DLB_FMT "I_%ld"
#define ILB_FMT "I%03d%ld"
#define HOL_FMT "hol%d"
#define GENLAB 'I'
#define TRUE 1
#define FALSE 0
#define clean_push_buf() if(push_waiting){text1(0x50);push_waiting=FALSE;}
#define assign( l, r) l = r
extern int push_waiting;
#ifndef DEBUG
#define arg_error(s,i)
#endif

32
mach/m65oo2/ce/proto.make Normal file
View file

@ -0,0 +1,32 @@
# $Id$
#PARAMS do not remove this line!
MACH = m65oo2
OBJ = obj
SRC_DIR = $(SRC_HOME)/mach/$(MACH)/ce
CEG = $(TARGET_HOME)/lib.bin/ceg/util
all:
make -f $(CEG)/make_asobj "OBJ="$(OBJ) "MACH="$(MACH)
install:
make -f $(CEG)/make_asobj "OBJ="$(OBJ) "MACH="$(MACH) install
cmp:
-make -f $(CEG)/make_asobj "OBJ="$(OBJ) "MACH="$(MACH) cmp
pr:
@pr $(SRC_DIR)/proto.make $(SRC_DIR)/EM_table $(SRC_DIR)/mach.h $(SRC_DIR)/mach.c $(SRC_DIR)/as_table $(SRC_DIR)/as.h $(SRC_DIR)/as.c
opr:
make pr | opr
# total cleanup
clean:
make -f $(CEG)/make_asobj "OBJ="$(OBJ) clean
# only remove ce, ceg, and back directories
dclean:
make -f $(CEG)/make_asobj "OBJ="$(OBJ) dclean

322
mach/m65oo2/cv/cv.c Normal file
View file

@ -0,0 +1,322 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
*/
/*
* This program converts ack.out format to PC/IX a.out format.
* It uses ~em/modules/lib/libobject.a.
*/
#include <stdio.h>
/* unsigned char: not portable */
struct exec {
char a_magic[2];
char a_flags;
char a_cpu;
char a_hdrlen;
char a_unused;
unsigned short a_version;
long a_text;
long a_data;
long a_bss;
long a_entry;
long a_misc;
long a_syms;
};
struct nlist
{ char n_name[8];
long n_value;
char n_sclass;
char n_numaux;
unsigned short n_type;
};
#include <out.h>
#ifndef NORCSID
static char rcs_id[] = "$Id$" ;
#endif
#define ENTRY 0x0 /* entry point */
/*
* Header and section table of new format object file.
*/
struct outhead outhead;
struct outsect outsect[S_MAX];
struct exec exec;
char *output_file;
int outputfile_created;
FILE *output;
char *program ;
char *chars;
char *malloc();
char flag ;
/* Output file definitions and such */
#define TEXTSG 0
#define ROMSG 1
#define DATASG 2
#define BSSSG 3
#define LSECT BSSSG+1
#define NSECT LSECT+1
long align(a,b)
long a,b;
{
a += b - 1;
return a - a % b;
}
int
follows(pa, pb)
register struct outsect *pa, *pb;
{
/* return 1 if pa follows pb */
return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign);
}
main(argc, argv)
int argc;
char *argv[];
{
register struct exec *e = &exec;
output = stdout;
program= argv[0] ;
if ( argc>1 && argv[1][0]=='-' ) {
flag=argv[1][1] ;
argc-- ; argv++ ;
}
switch (argc) {
case 1: rd_fdopen(0);
break;
case 3: if ((output = fopen(argv[2], "wb")) == 0) {
fatal("Can't write %s.\n", argv[2]);
}
output_file = argv[2];
outputfile_created = 1;
/* FALLTHROUGH */
case 2:
if (! rd_open(argv[1]))
fatal("Can't read %s.\n", argv[1]);
break;
default:fatal("Usage: %s <as object> <dl object>.\n", argv[0]);
}
rd_ohead(&outhead);
if (BADMAGIC(outhead))
fatal("Not an ack object file.\n");
if (outhead.oh_flags & HF_LINK)
fatal("Contains unresolved references.\n");
if (outhead.oh_nrelo > 0)
fprintf(stderr, "Warning: relocation information present.\n");
if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT )
fatal("Input file must have %d sections, not %ld\n",
NSECT,outhead.oh_nsect) ;
rd_sect(outsect, outhead.oh_nsect);
/* A few checks */
if ( outsect[TEXTSG].os_base != ENTRY)
fatal("text must start at %d not at 0x%lx\n", ENTRY,
outsect[TEXTSG].os_base) ;
if ( outsect[BSSSG].os_flen != 0 )
fatal("bss space contains initialized data\n") ;
if (! follows(&outsect[BSSSG], &outsect[DATASG]))
fatal("bss segment must follow data segment\n") ;
if (! follows(&outsect[DATASG], &outsect[ROMSG]))
fatal("data segment must follow rom\n") ;
outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
e->a_magic[0] = 01;
e->a_magic[1] = 03;
e->a_cpu = 04;
e->a_hdrlen = 32;
e->a_data = outsect[BSSSG].os_base - outsect[ROMSG].os_base;
e->a_bss = outsect[BSSSG].os_size;
e->a_entry = outsect[TEXTSG].os_base;
e->a_syms = (long) outhead.oh_nname * sizeof (struct nlist);
e->a_misc = 0x10000;
if ( outsect[ROMSG].os_base == 0x0 ) {
/* Separate I/D */
e->a_flags = 0x20;
outsect[TEXTSG].os_size = e->a_text =
align(outsect[TEXTSG].os_size,16L);
} else {
e->a_flags = 0x10;
outsect[TEXTSG].os_size = e->a_text =
outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
if (! follows(&outsect[ROMSG], &outsect[TEXTSG]))
fatal("rom segment must follow text\n") ;
}
if ( outhead.oh_nsect==NSECT ) {
if (! follows(&outsect[LSECT], &outsect[BSSSG]))
fatal("end segment must follow bss\n") ;
if ( outsect[LSECT].os_size != 0 )
fatal("end segment must be empty\n") ;
}
if (((unsigned) outhead.oh_nchar != outhead.oh_nchar) ||
(outhead.oh_nchar != 0 &&
(chars = malloc((unsigned)outhead.oh_nchar)) == 0)) {
fprintf(stderr, "%s: (warning) No name list generated\n", program);
e->a_syms = 0;
}
/* Action at last */
fwrite((char *) e, 1, 6, output);
wr_int2((int) e->a_version);
wr_long(e->a_text);
wr_long(e->a_data);
wr_long(e->a_bss);
wr_long(e->a_entry);
wr_long(e->a_misc);
wr_long(e->a_syms);
emits(&outsect[TEXTSG]) ;
emits(&outsect[ROMSG]) ;
emits(&outsect[DATASG]) ;
if (e->a_syms) emit_symtab();
fclose(output);
if ( outputfile_created ) chmod(argv[2],0755);
exit(0);
}
wr_int2(n)
int n;
{
char buf[2];
buf[0] = n;
buf[1] = (n >> 8);
fwrite(buf, 1, 2, output);
}
wr_long(l)
long l;
{
char buf[4];
buf[0] = l;
buf[1] = (l >> 8);
buf[2] = (l >> 16);
buf[3] = (l >> 24);
fwrite(buf, 1, 4, output);
}
/*
* Transfer the emitted byted from one file to another.
*/
emits(section) struct outsect *section ; {
register long n ;
register int blk;
char buffer[BUFSIZ];
n= section->os_flen ;
rd_outsect(section - outsect);
while (n > 0) {
blk = n > BUFSIZ ? BUFSIZ : n;
rd_emit(buffer, (long) blk);
fwrite(buffer, 1, blk, output);
n -= blk;
}
if ((n = section->os_size - section->os_flen) > 0) {
for (blk = BUFSIZ - 1; blk >= 0; blk--) {
buffer[blk] = 0;
}
while (n > 0) {
blk = n > BUFSIZ ? BUFSIZ : n;
fwrite(buffer, 1, blk, output);
n -= blk;
}
}
}
emit_symtab()
{
struct outname ACK_name; /* symbol table entry in ACK format */
struct nlist IX_name; /* symbol table entry in PC/IX format */
register unsigned short i;
long l;
long off = OFF_CHAR(outhead);
int j;
char *p;
rd_string(chars,outhead.oh_nchar);
for (i = 0; i < outhead.oh_nname; i++) {
rd_name(&ACK_name, 1);
switch(ACK_name.on_type & S_TYP) {
case S_UND:
IX_name.n_sclass = 0;
break;
case S_ABS:
IX_name.n_sclass = 01;
break;
case S_MIN + TEXTSG:
IX_name.n_sclass = 02;
break;
case S_MIN + ROMSG:
case S_MIN + DATASG:
IX_name.n_sclass = 03;
break;
case S_MIN + BSSSG:
case S_MIN + LSECT:
IX_name.n_sclass = 04;
break;
default:
fprintf(stderr,"warning: unknown s_type: %d\n",
ACK_name.on_type & S_TYP);
}
if (ACK_name.on_type & S_EXT) IX_name.n_sclass |= 020;
IX_name.n_value = ACK_name.on_valu;
if (ACK_name.on_foff == 0) {
p = "\0\0";
}
else {
l = ACK_name.on_foff - off;
if (l < 0 || l >= outhead.oh_nchar) {
fatal("bad on_off: %ld\n",l);
}
p = &chars[l];
}
for (j = 0; j < 8; j++) {
IX_name.n_name[j] = *p++;
if (*p == '\0') break;
}
for (j++; j < 8; j++) {
IX_name.n_name[j] = 0;
}
fwrite((char *) &IX_name, 1, 8, output);
wr_long(IX_name.n_value);
fwrite(&(IX_name.n_sclass), 1, 2, output);
wr_int2((int) IX_name.n_type);
}
}
/* VARARGS1 */
fatal(s, a1, a2)
char *s;
{
fprintf(stderr,"%s: ",program) ;
fprintf(stderr, s, a1, a2);
if (outputfile_created) {
fclose(output);
unlink(output_file);
}
exit(1);
}
rd_fatal()
{
fatal("read error\n");
}

34
mach/m65oo2/cv/proto.make Normal file
View file

@ -0,0 +1,34 @@
# $Id$
#PARAMS do not remove this line!
OBJLIB=$(TARGET_HOME)/modules/lib/libobject.$(LIBSUF)
SRC_DIR = $(SRC_HOME)/mach/m65oo2/cv
all: cv
cv: cv.$(SUF)
$(CC) $(LDOPTIONS) -o cv cv.$(SUF) $(OBJLIB)
cv.$(SUF): $(SRC_DIR)/cv.c
$(CC) $(COPTIONS) -I$(TARGET_HOME)/h -c $(SRC_DIR)/cv.c
install: all
-mkdir $(TARGET_HOME)/lib.bin/m65oo2
cp cv $(TARGET_HOME)/lib.bin/m65oo2/cv
cmp: all
-cmp cv $(TARGET_HOME)/lib.bin/m65oo2/cv
clean:
rm -f *.$(SUF) Out cv
lint:
$(LINT) $(LINTOPTIONS) -I$(TARGET_HOME)/h $(SRC_DIR)/cv.c $(UTIL_HOME)/modules/lib/$(LINTPREF)object.$(LINTSUF)
pr:
@pr $(SRC_DIR)/proto.make $(SRC_DIR)/cv.c
opr:
make pr | opr

60
mach/m65oo2/libem/LIST Normal file
View file

@ -0,0 +1,60 @@
libem_s.a
adi.s
and.s
cii.s
cms.s
cmi4.s
cmu4.s
com.s
csa2.s
csb2.s
csa4.s
csb4.s
cuu.s
dup.s
dvi.s
dvi4.s
dvu.s
dvu4.s
exg.s
fp8087.s
gto.s
iaar.s
ilar.s
inn.s
ior.s
isar.s
lar2.s
loi.s
mli.s
mli4.s
mon.s
ngi.s
nop.s
rck.s
rmi.s
rmi4.s
rmu.s
rmu4.s
rol.s
ror.s
sar2.s
sbi.s
set.s
sli.s
sri.s
sti.s
strhp.s
xor.s
error.s
unknown.s
fat.s
trp.s
print.s
ret6.s
ret8.s
lfr6.s
lfr8.s
retarea.s
blm.s
return.s

28
mach/m65oo2/libem/adi.s Normal file
View file

@ -0,0 +1,28 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .adi
! #bytes in cx , top of stack in ax
.sect .text
.adi:
pop bx ! return address
cmp cx,2
jne 1f
pop cx
add ax,cx
jmp bx
1:
cmp cx,4
jne 9f
pop dx
pop cx
add ax,cx
pop cx
adc dx,cx
push dx
jmp bx
9:
.extern EODDZ
.extern .trp
mov ax,EODDZ
push bx
jmp .trp

20
mach/m65oo2/libem/and.s Normal file
View file

@ -0,0 +1,20 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .and
! #bytes in cx
! save di; it might be a register variable
.sect .text
.and:
pop bx ! return address
mov dx,di
mov di,sp
add di,cx
sar cx,1
1:
pop ax
and ax,(di)
stos
loop 1b
mov di,dx
jmp bx

15
mach/m65oo2/libem/blm.s Normal file
View file

@ -0,0 +1,15 @@
.sect .text
.define .blm
! cx: count in words
.blm:
mov bx,sp
mov ax,si
mov dx,di
mov di,2(bx)
mov si,4(bx)
rep movs
mov si,ax
mov di,dx
ret 4

View file

@ -0,0 +1,68 @@
for _, plat in ipairs(vars.plats) do
acklibrary {
name = "lib_"..plat,
srcs = {
"./adi.s",
"./and.s",
"./blm.s",
"./cii.s",
"./cmi4.s",
"./cms.s",
"./cmu4.s",
"./com.s",
"./csa2.s",
"./csa4.s",
"./csb2.s",
"./csb4.s",
"./cuu.s",
"./dup.s",
"./dvi4.s",
"./dvi.s",
"./dvu4.s",
"./dvu.s",
"./error.s",
"./exg.s",
"./fat.s",
"./fp8087.s",
"./gto.s",
"./iaar.s",
"./ilar.s",
"./inn.s",
"./ior.s",
"./isar.s",
"./lar2.s",
"./lfr6.s",
"./lfr8.s",
"./loi.s",
"./mli4.s",
"./mli.s",
"./mon.s",
"./ngi.s",
"./nop.s",
"./print.s",
"./rck.s",
"./ret6.s",
"./ret8.s",
"./retarea.s",
"./return.s",
"./rmi4.s",
"./rmi.s",
"./rmu4.s",
"./rmu.s",
"./rol.s",
"./ror.s",
"./sar2.s",
"./sbi.s",
"./set.s",
"./sli.s",
"./sri.s",
"./sti.s",
"./strhp.s",
"./trp.s",
"./unknown.s",
"./xor.s",
},
vars = { plat = plat },
}
end

38
mach/m65oo2/libem/cii.s Normal file
View file

@ -0,0 +1,38 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .cii
.sect .text
.cii:
pop bx ! return address
! pop cx, dest. size
! pop dx, src. size
! ax is first word of source
cmp dx,1
jne 2f
cbw
mov dx,2
2:
cmp dx,cx
je 8f
cmp dx,2
je 1f
cmp dx,4
jne 9f
cmp cx,2
jne 9f
pop dx
8:
jmp bx
1:
cmp cx,4
jne 9f
cwd
push dx
jmp bx
9:
push ax ! push low source
.extern EILLINS
.extern .fat
mov ax,EILLINS
push ax
jmp .fat

28
mach/m65oo2/libem/cmi4.s Normal file
View file

@ -0,0 +1,28 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .cmi4
.sect .text
.cmi4:
pop bx ! return address
pop cx
pop dx
pop ax
push si
mov si,sp
xchg bx,2(si)
pop si
cmp bx,dx
jg 1f
jl 2f
cmp ax,cx
ja 1f
je 3f
2:
mov ax,-1
ret
3:
xor ax,ax
ret
1:
mov ax,1
ret

23
mach/m65oo2/libem/cms.s Normal file
View file

@ -0,0 +1,23 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .cms
! #bytes in cx
.sect .text
.cms:
pop bx ! return address
mov dx,sp
push si
push di
mov si,dx
add dx,cx
mov di,dx
add dx,cx
sar cx,1
repe cmps
je 1f
inc cx
1:
pop di
pop si
mov sp,dx
jmp bx

28
mach/m65oo2/libem/cmu4.s Normal file
View file

@ -0,0 +1,28 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .cmu4
.sect .text
.cmu4:
pop bx ! return address
pop cx
pop dx
pop ax
push si
mov si,sp
xchg bx,2(si)
pop si
cmp bx,dx
ja 1f
jb 2f
cmp ax,cx
ja 1f
je 3f
2:
mov ax,-1
ret
3:
xor ax,ax
ret
1:
mov ax,1
ret

15
mach/m65oo2/libem/com.s Normal file
View file

@ -0,0 +1,15 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .com
! #bytes in cx
.sect .text
.com:
mov bx,sp
add bx,2
sar cx,1
1:
not (bx)
inc bx
inc bx
loop 1b
ret

27
mach/m65oo2/libem/csa2.s Normal file
View file

@ -0,0 +1,27 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .csa2
.sect .text
.csa2:
! bx, descriptor address
! ax, index
mov dx,(bx) ! default
sub ax,2(bx)
cmp ax,4(bx)
ja 1f
sal ax,1
add bx,ax
mov bx,6(bx)
test bx,bx
jnz 2f
1:
mov bx,dx
test bx,bx
jnz 2f
.extern ECASE
.extern .fat
mov ax,ECASE
push ax
jmp .fat
2:
jmp bx

30
mach/m65oo2/libem/csa4.s Normal file
View file

@ -0,0 +1,30 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .csa4
.sect .text
.csa4:
! bx, descriptor address
! ax, dx: index
mov cx,(bx) ! default
sub ax,2(bx)
! ignore high order word; if non-zero, the
! case descriptor would not fit anyway
cmp ax,6(bx)
ja 1f
2:
sal ax,1
add bx,ax
mov bx,10(bx)
test bx,bx
jnz 2f
1:
mov bx,cx
test bx,bx
jnz 2f
.extern ECASE
.extern .fat
mov ax,ECASE
push ax
jmp .fat
2:
jmp bx

29
mach/m65oo2/libem/csb2.s Normal file
View file

@ -0,0 +1,29 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .csb2
.sect .text
.csb2:
!bx, descriptor address
!ax, index
mov dx,(bx)
mov cx,2(bx)
1:
add bx,4
dec cx
jl 4f
cmp ax,(bx)
jne 1b
mov bx,2(bx)
2:
test bx,bx
jnz 3f
.extern ECASE
.extern .fat
mov ax,ECASE
push ax
jmp .fat
3:
jmp bx
4:
mov bx,dx
jmp 2b

33
mach/m65oo2/libem/csb4.s Normal file
View file

@ -0,0 +1,33 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .csb4
.sect .text
.csb4:
!bx: descriptor address
!ax, dx: index
push (bx) ! default
mov cx,2(bx) ! count (ignore high order word, the descriptor
! would not fit anyway)
1:
add bx,6
dec cx
jl 4f
cmp ax,(bx)
jne 1b
cmp dx,2(bx)
jne 1b
pop cx
mov bx,4(bx)
2:
test bx,bx
jnz 3f
.extern ECASE
.extern .fat
mov ax,ECASE
push ax
jmp .fat
3:
jmp bx
4:
pop bx
jmp 2b

37
mach/m65oo2/libem/cuu.s Normal file
View file

@ -0,0 +1,37 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .ciu
.define .cui
.define .cuu
.sect .text
.ciu:
.cui:
.cuu:
pop bx ! return address
! pop cx, dest. size
! pop dx, source size
! ax is low word of source
cmp dx,cx
je 8f
cmp dx,2
je 1f
cmp dx,4
jne 9f
cmp cx,2
jne 9f
pop dx
8:
jmp bx
1:
cmp cx,4
jne 9f
xor dx,dx
push dx
jmp bx
9:
push ax ! to help debugging ?
.extern EILLINS
.extern .fat
mov ax,EILLINS
push ax
jmp .fat

17
mach/m65oo2/libem/dup.s Normal file
View file

@ -0,0 +1,17 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .dup
! #bytes in cx
.sect .text
.dup:
pop bx ! return address
mov ax,si
mov dx,di
mov si,sp
sub sp,cx
mov di,sp
sar cx,1
rep movs
mov si,ax
mov di,dx
jmp bx

39
mach/m65oo2/libem/dvi.s Normal file
View file

@ -0,0 +1,39 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .dvi
! #bytes in ax
.sect .text
.dvi:
pop bx ! return address
cmp ax,2
jne 1f
pop ax
cwd
pop cx
idiv cx
push ax
jmp bx
1:
cmp ax,4
jne 9f
pop ax
pop dx
pop si
pop di
push bx
push di
push si
push dx
push ax
.extern .dvi4
call .dvi4
pop bx
push dx
push ax
jmp bx
9:
.extern EODDZ
.extern .trp
mov ax,EODDZ
push bx
jmp .trp

91
mach/m65oo2/libem/dvi4.s Normal file
View file

@ -0,0 +1,91 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .dvi4
yl=6
yh=8
xl=10
xh=12
.sect .text
.dvi4:
push si
push di
mov si,sp ! copy of sp
mov bx,yl(si)
mov ax,yh(si)
cwd
mov di,dx
cmp dx,ax
jne 7f
and dx,dx
jge 1f
neg bx
je 7f
1:
xor dx,dx
mov cx,xl(si)
mov ax,xh(si)
and ax,ax
jge 2f
neg ax
neg cx
sbb ax,dx
not di
2:
div bx
xchg ax,cx
div bx ! cx = high abs(result), ax=low abs(result)
9:
and di,di
jge 1f
neg cx
neg ax
sbb cx,0
1:
! cx is high order result
! ax is low order result
mov dx,cx
pop di
pop si
ret 8 ! result in ax/dx
7:
push dx ! sign of y
mov di,ax
xor bx,bx
and di,di
jge 1f
neg di
neg yl(si)
sbb di,bx
1:
mov ax,xl(si)
mov dx,xh(si)
and dx,dx
jge 1f
neg dx
neg ax
sbb dx,bx
not -2(si)
1:
mov cx,16
1:
shl ax,1
rcl dx,1
rcl bx,1
cmp di,bx
ja 3f
jb 2f
cmp yl(si),dx
jbe 2f
3:
loop 1b
jmp 1f
2:
sub dx,yl(si)
sbb bx,di
inc ax
loop 1b
1:
pop di ! di=sign of result,ax= result
jmp 9b

39
mach/m65oo2/libem/dvu.s Normal file
View file

@ -0,0 +1,39 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .dvu
! #bytes in ax
.sect .text
.dvu:
pop bx ! return address
cmp ax,2
jne 1f
pop ax
xor dx,dx
pop cx
div cx
push ax
jmp bx
1:
cmp ax,4
jne 9f
pop ax
pop dx
pop si
pop di
push bx
push di
push si
push dx
push ax
.extern .dvu4
call .dvu4
pop bx
push dx
push ax
jmp bx
9:
.extern EODDZ
.extern .trp
mov ax,EODDZ
push bx
jmp .trp

55
mach/m65oo2/libem/dvu4.s Normal file
View file

@ -0,0 +1,55 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .dvu4
yl=6
yh=8
xl=10
xh=12
.sect .text
.dvu4:
push si
push di
mov si,sp ! copy of sp
mov bx,yl(si)
mov ax,yh(si)
or ax,ax
jne 7f
xor dx,dx
mov cx,xl(si)
mov ax,xh(si)
div bx
xchg ax,cx
div bx
9:
! cx is high order result
! ax is low order result
mov dx,cx
pop di
pop si
ret 8 ! result in ax/dx
7:
mov di,ax
xor bx,bx
mov ax,xl(si)
mov dx,xh(si)
mov cx,16
1:
shl ax,1
rcl dx,1
rcl bx,1
cmp di,bx
ja 3f
jb 2f
cmp yl(si),dx
jbe 2f
3:
loop 1b
jmp 9b
2:
sub dx,yl(si)
sbb bx,di
inc ax
loop 1b
jmp 9b

42
mach/m65oo2/libem/error.s Normal file
View file

@ -0,0 +1,42 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .error
.define .Xtrp
! ax is trap number
! all registers must be saved
! because return is possible
! May only be called with error no's <16
.sect .text
.error:
push bp
push si
push di
push dx
push cx
push bx
push ax
mov cx,ax
mov bx,1
sal bx,cl
.extern .ignmask
.extern .trp
test bx,(.ignmask)
jne 2f
call .trp
2:
pop ax
pop bx
pop cx
pop dx
pop di
pop si
pop bp
ret
.Xtrp:
cmp ax,16
jge 1f
call .error
ret
1:
jmp .trp

22
mach/m65oo2/libem/exg.s Normal file
View file

@ -0,0 +1,22 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .exg
! #bytes in cx
.sect .text
.exg:
push di
mov di,sp
add di,4
mov bx,di
add bx,cx
sar cx,1
1:
mov ax,(bx)
xchg ax,(di)
mov (bx),ax
add di,2
add bx,2
loop 1b
2:
pop di
ret

10
mach/m65oo2/libem/fat.s Normal file
View file

@ -0,0 +1,10 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .fat
.fat:
.extern .trp
.extern .stop
call .trp
call .stop
! no return

615
mach/m65oo2/libem/fp8087.s Normal file
View file

@ -0,0 +1,615 @@
.define .adf4, .adf8, .sbf4, .sbf8, .mlf4, .mlf8, .dvf4, .dvf8
.define .ngf4, .ngf8, .fif4, .fif8, .fef4, .fef8
.define .cif4, .cif8, .cuf4, .cuf8, .cfi, .cfu, .cff4, .cff8
.define .cmf4, .cmf8
.sect .text; .sect .rom; .sect .data; .sect .bss
! $Id$
! Implement interface to floating point package for Intel 8087
.sect .rom
one:
.data2 1
two:
.data2 2
bigmin:
.data2 0, -32768
.sect .text
.adf4:
mov bx,sp
wait
flds 2(bx)
wait
fadds 6(bx)
wait
fstps 6(bx)
wait
ret
.adf8:
mov bx,sp
wait
fldd 2(bx)
wait
faddd 10(bx)
wait
fstpd 10(bx)
wait
ret
.sbf4:
mov bx,sp
wait
flds 6(bx)
wait
fsubs 2(bx)
wait
fstps 6(bx)
wait
ret
.sbf8:
mov bx,sp
wait
fldd 10(bx)
wait
fsubd 2(bx)
wait
fstpd 10(bx)
wait
ret
.mlf4:
mov bx,sp
wait
flds 2(bx)
wait
fmuls 6(bx)
wait
fstps 6(bx)
wait
ret
.mlf8:
mov bx,sp
wait
fldd 2(bx)
wait
fmuld 10(bx)
wait
fstpd 10(bx)
wait
ret
.dvf4:
mov bx,sp
wait
flds 6(bx)
wait
fdivs 2(bx)
wait
fstps 6(bx)
wait
ret
.dvf8:
mov bx,sp
wait
fldd 10(bx)
wait
fdivd 2(bx)
wait
fstpd 10(bx)
wait
ret
.ngf4:
mov bx,sp
wait
flds 2(bx)
wait
fchs
wait
fstps 2(bx)
wait
ret
.ngf8:
mov bx,sp
wait
fldd 2(bx)
wait
fchs
wait
fstpd 2(bx)
wait
ret
.fif4:
mov bx,sp
push bx ! make room for FP status word
wait
flds 4(bx)
wait
fmuls 8(bx) ! multiply
wait
fld st ! copy result
wait
ftst ! test sign; handle negative separately
wait
fstsw -2(bx)
wait
mov ax,-2(bx)
sahf ! result of test in condition codes
jb 1f
frndint ! this one rounds (?)
wait
fcom st(1) ! compare with original; if <=, then OK
wait
fstsw -2(bx)
wait
mov ax,-2(bx)
sahf
jbe 2f
fisubs (one) ! else subtract 1
wait
jmp 2f
1: ! here, negative case
frndint ! this one rounds (?)
wait
fcom st(1) ! compare with original; if >=, then OK
wait
fstsw -2(bx)
wait
mov ax,-2(bx)
sahf
jae 2f
fiadds (one) ! else add 1
wait
2:
fsub st(1),st ! subtract integer part
wait
mov bx,2(bx)
fstps (bx)
wait
fstps 4(bx)
wait
pop bx
ret
.fif8:
mov bx,sp
push bx ! make room for FP status word
wait
fldd 4(bx)
wait
fmuld 12(bx) ! multiply
wait
fld st ! and copy result
wait
ftst ! test sign; handle negative separately
wait
fstsw -2(bx)
wait
mov ax,-2(bx)
sahf ! result of test in condition codes
jb 1f
frndint ! this one rounds (?)
wait
fcom st(1) ! compare with original; if <=, then OK
wait
fstsw -2(bx)
wait
mov ax,-2(bx)
sahf
jbe 2f
fisubs (one) ! else subtract 1
wait
jmp 2f
1: ! here, negative case
frndint ! this one rounds (?)
wait
fcom st(1) ! compare with original; if >=, then OK
wait
fstsw -2(bx)
wait
mov ax,-2(bx)
sahf
jae 2f
fiadds (one) ! else add 1
wait
2:
fsub st(1),st ! subtract integer part
mov bx,2(bx)
fstpd (bx)
wait
fstpd 8(bx)
wait
pop bx
ret
.fef4:
! this could be simpler, if only the
! fxtract instruction was emulated properly
mov bx,sp
mov ax,6(bx)
and ax,077600
je 1f ! zero exponent
mov cx,7
shr ax,cl
sub ax,126
mov cx,ax ! exponent in cx
mov ax,6(bx)
and ax,0100177
or ax,0037400 ! load -1 exponent
mov dx,4(bx)
mov bx,2(bx)
mov 4(bx),ax
mov 2(bx),dx
mov (bx),cx
ret
1: ! we get here on zero exp
mov ax,6(bx)
and ax,0177
or ax,4(bx)
jne 1f ! zero result
xor ax,ax
mov bx,2(bx)
mov (bx),ax
mov 2(bx),ax
mov 4(bx),ax
ret
1: ! otherwise unnormalized number
mov cx,6(bx)
and cx,0100177
mov dx,cx
and cx,0x8000
mov ax,-125
2:
test dx,0x80
jne 1f
dec ax
shl 4(bx),1
rcl dx,1
or dx,cx
jmp 2b
1:
mov cx,4(bx)
mov bx,2(bx)
mov (bx),ax
mov 2(bx),cx
and dx,0100177
or dx,0037400 ! load -1 exponent
mov 4(bx),dx
ret
.fef8:
! this could be simpler, if only the
! fxtract instruction was emulated properly
mov bx,sp
mov ax,10(bx)
and ax,077760
je 1f ! zero exponent
mov cx,4
shr ax,cl
sub ax,1022
mov cx,ax ! exponent in cx
mov ax,10(bx)
and ax,0100017
or ax,0037740 ! load -1 exponent
push 8(bx)
push 6(bx)
push 4(bx)
mov bx,2(bx)
pop 2(bx)
pop 4(bx)
pop 6(bx)
mov 8(bx),ax
mov (bx),cx
ret
1: ! we get here on zero exp
mov ax,10(bx)
and ax,017
or ax,8(bx)
or ax,6(bx)
or ax,4(bx)
jne 1f ! zero result
xor ax,ax
mov bx,2(bx)
mov (bx),ax
mov 2(bx),ax
mov 4(bx),ax
mov 6(bx),ax
mov 8(bx),ax
ret
1: ! otherwise unnormalized number
mov cx,10(bx)
and cx,0100017
mov dx,cx
and cx,0x8000
mov ax,-1021
2:
test dx,0x10
jne 1f
dec ax
shl 4(bx),1
rcl 6(bx),1
rcl 8(bx),1
rcl dx,1
or dx,cx
jmp 2b
1:
and dx,0100017
or dx,0037740 ! load -1 exponent
mov cx,8(bx)
push 6(bx)
push 4(bx)
mov bx,2(bx)
mov (bx),ax
mov 8(bx),dx
mov 6(bx),cx
pop 2(bx)
pop 4(bx)
ret
.cif4:
mov bx,sp
cmp 2(bx),2
jne 1f
wait
filds 4(bx)
wait
fstps 2(bx)
wait
ret
1:
wait
fildl 4(bx)
wait
fstps 4(bx)
wait
ret
.cif8:
mov bx,sp
cmp 2(bx),2
jne 1f
wait
filds 4(bx)
wait
fstpd 2(bx)
wait
ret
1:
wait
fildl 4(bx)
wait
fstpd 2(bx)
wait
ret
.cuf4:
mov bx,sp
cmp 2(bx),2
jne 1f
mov ax,4(bx)
mov 2(bx),ax
mov 4(bx),0
wait
fildl 2(bx)
wait
fstps 2(bx)
wait
ret
1:
wait
fildl 4(bx)
wait
cmp 6(bx),0
jge 1f
2:
wait
fisubl (bigmin)
wait
fisubl (bigmin)
1:
wait
fstps 4(bx)
wait
ret
.cuf8:
mov bx,sp
cmp 2(bx),2
jne 1f
mov 6(bx),0
1:
wait
fildl 4(bx)
wait
cmp 6(bx),0
jge 1f
2:
wait
fisubl (bigmin)
wait
fisubl (bigmin)
1:
wait
fstpd 2(bx)
wait
ret
.cfi:
mov bx,sp
push bx
wait
fstcw -2(bx)
wait
mov dx,-2(bx)
or -2(bx),0xc00 ! truncating mode
wait
fldcw -2(bx)
pop ax
cmp 4(bx),4
jne 2f
! loc 4 loc ? cfi
wait
flds 6(bx)
wait
fistpl 6(bx)
wait
cmp 2(bx),2
jne 1f
mov ax,6(bx)
1:
mov 4(bx),dx
wait
fldcw 4(bx)
wait
ret
2:
! loc 8 loc ? cfi
wait
fldd 6(bx)
wait
fistpl 10(bx)
wait
cmp 2(bx),2
jne 1b
mov ax,10(bx)
jmp 1b
.cfu:
mov bx,sp
push bx
wait
fstcw -2(bx)
wait
mov dx,-2(bx)
and -2(bx),0xf3ff
or -2(bx),0x400 ! to -infinity
wait
fldcw -2(bx)
wait
pop ax
cmp 4(bx),4
jne 2f
! loc 4 loc ? cfu
flds 6(bx)
wait
fabs ! ???
wait
fiaddl (bigmin)
fistpl 6(bx)
wait
mov ax,8(bx)
sub ax,(bigmin+2)
mov 8(bx),ax
cmp 2(bx),2
jne 1f
mov ax,6(bx)
1:
mov 4(bx),dx
wait
fldcw 4(bx)
wait
ret
2:
wait
! loc 8 loc ? cfu
fldd 6(bx)
wait
fabs ! ???
wait
fiaddl (bigmin)
fistpl 10(bx)
wait
mov ax,12(bx)
sub ax,(bigmin+2)
mov 12(bx),ax
cmp 2(bx),2
jne 1b
mov ax,10(bx)
jmp 1b
.cff4:
mov bx,sp
wait
fldd 2(bx)
wait
fstcw 2(bx)
wait
mov dx,2(bx)
and 2(bx),0xf3ff ! set to rounding mode
wait
fldcw 2(bx)
wait
fstps 6(bx)
mov 2(bx),dx
wait
fldcw 2(bx)
wait
ret
.cff8:
mov bx,sp
wait
flds 2(bx)
wait
fstpd 2(bx)
wait
ret
.cmf4:
mov bx,sp
push bx ! room for 8087 status word
xor cx,cx
wait
flds 6(bx)
wait
flds 2(bx)
wait
fcompp ! compare and pop operands
wait
fstsw -2(bx)
wait
mov ax,-2(bx)
sahf
je 1f
jb 2f
dec cx
jmp 1f
2:
inc cx
1:
mov ax,cx
pop bx
ret
.cmf8:
mov bx,sp
push bx ! room for 8087 status word
xor cx,cx
wait
fldd 10(bx)
wait
fldd 2(bx)
wait
fcompp ! compare and pop operands
wait
fstsw -2(bx)
wait
mov ax,-2(bx)
sahf
je 1f
jb 2f
dec cx
jmp 1f
2:
inc cx
1:
mov ax,cx
pop bx
ret

8
mach/m65oo2/libem/gto.s Normal file
View file

@ -0,0 +1,8 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .gto
.gto:
mov bp,4(bx)
mov sp,2(bx)
jmp (bx)

18
mach/m65oo2/libem/iaar.s Normal file
View file

@ -0,0 +1,18 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .iaar
.iaar:
pop cx
pop dx
cmp dx,2
.extern .unknown
jne .unknown
pop bx ! descriptor address
pop ax ! index
sub ax,(bx)
mul 4(bx)
pop bx ! base address
add bx,ax
push cx
ret

15
mach/m65oo2/libem/ilar.s Normal file
View file

@ -0,0 +1,15 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .ilar
.ilar:
pop cx
pop dx
.extern .unknown
cmp dx,2
jne .unknown
pop bx ! descriptor address
pop ax ! index
push cx
.extern .lar2
jmp .lar2

32
mach/m65oo2/libem/inn.s Normal file
View file

@ -0,0 +1,32 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .inn
! #bytes in cx
! bit # in ax
.inn:
xor dx,dx
mov bx,8
div bx
mov bx,sp
add bx,2
add bx,ax
cmp ax,cx
jae 1f
movb al,(bx)
mov bx,dx
testb al,bits(bx)
jz 1f
mov ax,1
jmp 2f
1:
xor ax,ax
2:
pop bx
add sp,cx
! ax is result
jmp bx
.sect .data
bits:
.data1 1,2,4,8,16,32,64,128

18
mach/m65oo2/libem/ior.s Normal file
View file

@ -0,0 +1,18 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .ior
! #bytes in cx
.ior:
pop bx ! return address
mov dx,di
mov di,sp
add di,cx
sar cx,1
1:
pop ax
or ax,(di)
stos
loop 1b
mov di,dx
jmp bx

15
mach/m65oo2/libem/isar.s Normal file
View file

@ -0,0 +1,15 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .isar
.isar:
pop cx
pop ax
cmp ax,2
.extern .unknown
jne .unknown
pop bx ! descriptor address
pop ax ! index
push cx
.extern .sar2
jmp .sar2

35
mach/m65oo2/libem/lar2.s Normal file
View file

@ -0,0 +1,35 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .lar2
.lar2:
! bx, descriptor address
! ax, index
pop cx
pop dx ! base address
push cx
push si
mov si,dx
sub ax,(bx)
mov cx,4(bx)
imul cx
add si,ax
sar cx,1
jnb 1f
xorb ah,ah
lodsb
pop si
pop bx
push ax
jmp bx
1:
pop dx ! saved si
mov ax,4(bx)
pop bx ! return address
sub sp,ax
mov ax,di ! save di
mov di,sp
rep movs
mov di,ax
mov si,dx
jmp bx

10
mach/m65oo2/libem/lfr6.s Normal file
View file

@ -0,0 +1,10 @@
.sect .text
.define .lfr6
.extern .retarea
.lfr6:
pop bx
push (.retarea+4)
push (.retarea+2)
push (.retarea)
jmp bx

11
mach/m65oo2/libem/lfr8.s Normal file
View file

@ -0,0 +1,11 @@
.sect .text
.define .lfr8
.extern .retarea
.lfr8:
pop bx
push (.retarea+6)
push (.retarea+4)
push (.retarea+2)
push (.retarea)
jmp bx

38
mach/m65oo2/libem/loi.s Normal file
View file

@ -0,0 +1,38 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .loi
.define .los
! #bytes in cx
! address in bx
! save si/di. they might be register variables
.los:
mov dx,si
mov si,bx
pop bx
mov ax,cx
sar cx,1
jnb 1f
xorb ah,ah
lodsb
mov si,dx
push ax
jmp bx
1:
sub sp,ax
jmp 1f
.loi:
! only called with size > 4
mov dx,si
mov si,bx
pop bx
sub sp,cx
sar cx,1
1:
mov ax,di
mov di,sp
rep movs
mov si,dx
mov di,ax
jmp bx

42
mach/m65oo2/libem/mli.s Normal file
View file

@ -0,0 +1,42 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .mli
! #bytes in ax
.mli:
pop bx ! return address
cmp ax,2
jne 1f
pop ax
pop cx
mul cx
push ax
jmp bx
1:
cmp ax,4
jne 9f
push bx
mov cx,bx
mov bx,sp
mov ax,2(bx)
mov (bx),ax
mov ax,4(bx)
mov 2(bx),ax
mov ax,6(bx)
mov 4(bx),ax
mov ax,8(bx)
mov 6(bx),ax
mov 8(bx),cx
pop ax
pop dx
call .mli4
pop bx
push dx
push ax
jmp bx
9:
.extern EODDZ
.extern .trp
mov ax,EODDZ
push bx
jmp .trp

26
mach/m65oo2/libem/mli4.s Normal file
View file

@ -0,0 +1,26 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .mli4
yl=2
yh=4
! x * y
! xl in ax
! xh in dx
.mli4:
mov bx,sp
push dx
mov cx,ax
mul yh(bx) ! xl*yh
pop dx
push ax
mov ax,dx
mul yl(bx) ! xh * yl
pop dx
add dx,ax ! xh*yl+xl*yh
mov ax,cx
mov cx,dx
mul yl(bx) ! xl*yl
add dx,cx
ret 4

7
mach/m65oo2/libem/mon.s Normal file
View file

@ -0,0 +1,7 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .mon
.mon:
.extern .stop
call .stop

30
mach/m65oo2/libem/ngi.s Normal file
View file

@ -0,0 +1,30 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .ngi
! #bytes in ax
.ngi:
pop bx ! return address
cmp ax,2
jne 1f
pop cx
neg cx
push cx
jmp bx
1:
cmp ax,4
jne 9f
pop dx
pop ax
neg ax
neg dx
sbb ax,0
push dx
push ax
jmp bx
9:
.extern EODDZ
.extern .trp
mov ax,EODDZ
push bx
jmp .trp

24
mach/m65oo2/libem/nop.s Normal file
View file

@ -0,0 +1,24 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .nop
.extern printd, printc, hol0
SIO_S = 0xDA
SIO_D = 0xD8
RXRDY = 0x02
.nop:
mov ax,(hol0)
call printd
! movb al,' '
! call printc
! mov ax,sp
! call printd
!1:
! inb SIO_S
! andb al,RXRDY
! jz 1b
! inb SIO_D
! call printc
movb al,'\n'
jmp printc

47
mach/m65oo2/libem/print.s Normal file
View file

@ -0,0 +1,47 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define printc,printd,prints
! argument in ax
! uses bx
prints:
xchg ax,bx
1:
movb al,(bx)
inc bx
testb al,al
jz 2f
call printc
jmp 1b
2:
ret
! argument in ax
! uses cx and dx
printd:
xor dx,dx
mov cx,10
div cx
test ax,ax
jz 1f
push dx
call printd
pop dx
1:
xchg ax,dx
addb al,'0'
! argument in ax
printc:
push ax
mov bx,sp
mov ax,1
push ax
push bx
push ax
call __write
pop bx
pop bx
pop bx
pop bx
ret

20
mach/m65oo2/libem/rck.s Normal file
View file

@ -0,0 +1,20 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .rck
! descriptor address in bx
! value in ax, must be left there
.rck:
cmp ax,(bx)
jl 2f
cmp ax,2(bx)
jg 2f
ret
2:
push ax
.extern ERANGE
.extern .error
mov ax,ERANGE
call .error
pop ax
ret

10
mach/m65oo2/libem/ret6.s Normal file
View file

@ -0,0 +1,10 @@
.sect .text
.define .ret6
.extern .retarea
.ret6:
pop bx
pop (.retarea)
pop (.retarea+2)
pop (.retarea+4)
jmp bx

11
mach/m65oo2/libem/ret8.s Normal file
View file

@ -0,0 +1,11 @@
.sect .text
.define .ret8
.extern .retarea
.ret8:
pop bx
pop (.retarea)
pop (.retarea+2)
pop (.retarea+4)
pop (.retarea+6)
jmp bx

View file

@ -0,0 +1,5 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.define .retarea
.retarea:
.space 8

View file

@ -0,0 +1,17 @@
.define .sdret, .dsret, .sret, .dret, .cret
.sect .text
.dsret:
pop di
.sret:
pop si
.cret:
mov sp,bp
pop bp
ret
.sdret:
pop si
.dret:
pop di
jmp .cret

39
mach/m65oo2/libem/rmi.s Normal file
View file

@ -0,0 +1,39 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .rmi
! #bytes in ax
.rmi:
pop bx ! return address
cmp ax,2
jne 1f
pop ax
cwd
pop cx
idiv cx
push dx
jmp bx
1:
cmp ax,4
jne 9f
pop ax
pop dx
pop si
pop di
push bx
push di
push si
push dx
push ax
.extern .rmi4
call .rmi4
pop bx
push dx
push ax
jmp bx
9:
.extern EODDZ
.extern .trp
mov ax,EODDZ
push bx
jmp .trp

90
mach/m65oo2/libem/rmi4.s Normal file
View file

@ -0,0 +1,90 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .rmi4
yl=6
yh=8
xl=10
xh=12
.rmi4:
push si
push di
mov si,sp ! copy of sp
mov bx,yl(si)
mov ax,yh(si)
cwd
cmp dx,ax
jne 7f
and dx,dx
jge 1f
neg bx
je 7f
1:
xor dx,dx
mov cx,xl(si)
mov ax,xh(si)
and ax,ax
jge 2f
neg ax
neg cx
sbb ax,dx
2:
div bx
xchg ax,cx
div bx ! dx= result(low), 0=result(high)
xor bx,bx
9:
cmp xh(si),0
jge 1f
neg bx
neg dx
sbb bx,0
1:
! bx is high order result
! dx is low order result
mov ax,dx
mov dx,bx ! result in ax/dx
pop di
pop si
ret 8
7:
mov di,ax
xor bx,bx
and di,di
jge 1f
neg di
neg yl(si)
sbb di,bx
1:
mov ax,xl(si)
mov dx,xh(si)
and dx,dx
jge 1f
neg dx
neg ax
sbb dx,bx
1:
mov cx,16
1:
shl ax,1
rcl dx,1
rcl bx,1
cmp di,bx
ja 3f
jb 2f
cmp yl(si),dx
jbe 2f
3:
loop 1b
! dx=result(low), bx=result(high)
jmp 9b
2:
sub dx,yl(si)
sbb bx,di
inc ax
loop 1b
1:
! dx=result(low), bx=result(high)
jmp 9b

39
mach/m65oo2/libem/rmu.s Normal file
View file

@ -0,0 +1,39 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .rmu
! #bytes in ax
.rmu:
pop bx ! return address
cmp ax,2
jne 1f
pop ax
xor dx,dx
pop cx
idiv cx
push dx
jmp bx
1:
cmp ax,4
jne 9f
pop ax
pop dx
pop si
pop di
push bx
push di
push si
push dx
push ax
.extern .rmu4
call .rmu4
pop bx
push dx
push ax
jmp bx
9:
.extern EODDZ
.extern .trp
mov ax,EODDZ
push bx
jmp .trp

62
mach/m65oo2/libem/rmu4.s Normal file
View file

@ -0,0 +1,62 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .rmu4
yl=6
yh=8
xl=10
xh=12
.rmu4:
push si
push di
mov si,sp ! copy of sp
mov bx,yl(si)
mov ax,yh(si)
or ax,ax
jne 7f
1:
xor dx,dx
mov cx,xl(si)
mov ax,xh(si)
2:
div bx
xchg ax,cx
div bx
xor bx,bx
9:
! bx is high order result
! dx is low order result
mov ax,dx
mov dx,bx
pop di
pop si
ret 8 ! result in ax/dx
7:
mov di,ax
xor bx,bx
mov ax,xl(si)
mov dx,xh(si)
mov cx,16
1:
shl ax,1
rcl dx,1
rcl bx,1
cmp di,bx
ja 3f
jb 2f
cmp yl(si),dx
jbe 2f
3:
loop 1b
! dx=result(low), bx=result(high)
jmp 9b
2:
sub dx,yl(si)
sbb bx,di
inc ax
loop 1b
1:
! dx=result(low), bx=result(high)
jmp 9b

36
mach/m65oo2/libem/rol.s Normal file
View file

@ -0,0 +1,36 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .rol
! #bytes in ax
.rol:
pop dx ! return address
cmp ax,2
jne 1f
pop ax
pop cx
rol ax,cl
push ax
jmp dx
1:
cmp ax,4
jne 9f
pop cx
jcxz 2f
pop ax
pop bx
3:
sal ax,1
rcl bx,1
adc ax,0
loop 3b
push bx
push ax
2:
jmp dx
9:
.extern EODDZ
.extern .trp
mov ax,EODDZ
push dx
jmp .trp

37
mach/m65oo2/libem/ror.s Normal file
View file

@ -0,0 +1,37 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .ror
! #bytes in ax
.ror:
pop dx ! return address
cmp ax,2
jne 1f
pop ax
pop cx
ror ax,cl
push ax
jmp dx
1:
cmp ax,4
jne 9f
pop cx
jcxz 2f
neg cx
add cx,32
pop ax
pop bx
3:
sar bx,1
rcr ax,1
loop 3b
push bx
push ax
2:
jmp dx
9:
.extern EODDZ
.extern .trp
mov ax,EODDZ
push dx
jmp .trp

33
mach/m65oo2/libem/sar2.s Normal file
View file

@ -0,0 +1,33 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .sar2
.sar2:
! bx, descriptor address
! ax, index
pop cx
pop dx ! base address
push cx
xchg di,dx ! di = base address, dx is saved di
sub ax,(bx)
mov cx,4(bx)
push dx
imul cx
pop dx
add di,ax
sar cx,1
jnb 1f
pop bx
pop ax
stosb
mov di,dx
jmp bx
1:
pop bx
mov ax,si
mov si,sp
rep movs
mov sp,si
mov si,ax
mov di,dx
jmp bx

30
mach/m65oo2/libem/sbi.s Normal file
View file

@ -0,0 +1,30 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .sbi
! #bytes in cx , top of stack in ax
.sbi:
pop bx ! return subress
cmp cx,2
jne 1f
pop cx
sub ax,cx
neg ax
jmp bx
1:
cmp cx,4
jne 9f
pop dx
pop cx
sub cx,ax
mov ax,cx
pop cx
sbb cx,dx
push cx
jmp bx
9:
.extern EODDZ
.extern .trp
mov ax,EODDZ
push bx
jmp .trp

42
mach/m65oo2/libem/set.s Normal file
View file

@ -0,0 +1,42 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .set
! #bytes in cx
! bit # in ax
.set:
pop bx ! return address
xor dx,dx
!ifdef create set
sub sp,cx
push bx
push di
mov bx,sp
xor di,di
sar cx,1
1:
mov 4(bx)(di),dx
add di,2
loop 1b
!endif
mov bx,8
div bx
cmp ax,di
jae 2f
mov di,dx
movb dl,bits(di)
mov di,sp
add di,ax
orb 4(di),dl
pop di
ret
2:
.extern ESET
.extern .trp
pop di
mov ax,ESET
jmp .trp
.sect .data
bits:
.data1 1,2,4,8,16,32,64,128

35
mach/m65oo2/libem/sli.s Normal file
View file

@ -0,0 +1,35 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .sli
! #bytes in ax
.sli:
pop dx ! return address
cmp ax,2
jne 1f
pop ax
pop cx
sal ax,cl
push ax
jmp dx
1:
cmp ax,4
jne 9f
pop cx
jcxz 2f
pop ax
pop bx
3:
sal ax,1
rcl bx,1
loop 3b
push bx
push ax
2:
jmp dx
9:
.extern EODDZ
.extern .trp
mov ax,EODDZ
push dx
jmp .trp

35
mach/m65oo2/libem/sri.s Normal file
View file

@ -0,0 +1,35 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .sri
! #bytes in ax
.sri:
pop dx ! return address
cmp ax,2
jne 1f
pop ax
pop cx
sar ax,cl
push ax
jmp dx
1:
cmp ax,4
jne 9f
pop cx
jcxz 2f
pop ax
pop bx
3:
sar bx,1
rcr ax,1
loop 3b
push bx
push ax
2:
jmp dx
9:
.extern EODDZ
.extern .trp
mov ax,EODDZ
push dx
jmp .trp

32
mach/m65oo2/libem/sti.s Normal file
View file

@ -0,0 +1,32 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .sti
.define .sts
! #bytes in cx
! address in bx
! save di/si. they might be register variables
.sts:
mov dx,di ! save di
mov di,bx
pop bx
sar cx,1
jnb 1f
pop ax
stosb
mov di,dx
jmp bx
.sti:
! only called with count > 4
mov dx,di
mov di,bx
pop bx
sar cx,1
1:
mov ax,si
mov si,sp
rep movs
mov sp,si
mov di,dx
mov si,ax
jmp bx

41
mach/m65oo2/libem/strhp.s Normal file
View file

@ -0,0 +1,41 @@
! $Source$
! $State$
! $Revision$
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .strhp
.extern .reghp, .limhp, EHEAP, .trp
! Updates the heap pointer:
!
! int .strhp(void* newpointer)
!
! .reghp is the current heap pointer;
! .limhp is the current top of memory.
!
! If the desired new heap pointer is above the top of memory, then BRK is
! called to extend the memory.
.strhp:
pop bx
pop ax
mov (.reghp),ax
cmp ax,(.limhp)
jb 1f
add ax,02000
and ax,~0777
push bx
push ax
call BRK
pop cx
pop bx
cmp ax,-1
je 2f
1:
mov (.limhp),cx
jmp bx
2:
mov ax,EHEAP
push bx
jmp .trp

21
mach/m65oo2/libem/trp.s Normal file
View file

@ -0,0 +1,21 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .trp
.define .stop
.extern .trppc
! ax is trap number
.trp:
xor bx,bx
xchg bx,(.trppc)
test bx,bx
jz 2f
push ax
call bx
pop ax
ret
2:
call .stop
.stop:
jmp EXIT

View file

@ -0,0 +1,9 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .unknown
.extern EILLINS, .fat
.unknown:
mov ax,EILLINS
push ax
jmp .fat

18
mach/m65oo2/libem/xor.s Normal file
View file

@ -0,0 +1,18 @@
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .xor
! #bytes in cx
.xor:
pop bx ! return address
mov dx,di
mov di,sp
add di,cx
sar cx,1
1:
pop ax
xor ax,(di)
stos
loop 1b
mov di,dx
jmp bx

5
mach/m65oo2/libend/LIST Normal file
View file

@ -0,0 +1,5 @@
end_s.a
edata.s
em_end.s
end.s
etext.s

View file

@ -4,6 +4,4 @@
.sect .bss .sect .bss
.define _edata .define _edata
.sect .data .sect .data
.align 4
.sect .data
_edata: _edata:

View file

@ -10,15 +10,11 @@
.define endtext, endrom, enddata, endbss, __end .define endtext, endrom, enddata, endbss, __end
.sect .text .sect .text
.align 4
endtext: endtext:
.sect .rom .sect .rom
.align 4
endrom: endrom:
.sect .data .sect .data
.align 4
enddata: enddata:
.sect .end .sect .end
.align 4
__end: __end:
endbss: endbss:

View file

@ -4,6 +4,4 @@
.sect .bss .sect .bss
.define _etext .define _etext
.sect .text .sect .text
.align 4
.sect .text
_etext: _etext:

76
mach/m65oo2/libsys/LIST Normal file
View file

@ -0,0 +1,76 @@
libmon_s.a
_alarm.s
_sbrk.s
_brk.s
_close.s
_creat.s
_dup.s
_execl.s
_execve.s
_fork.s
_fstat.s
_ftime.s
_getpid.s
_gtty.s
_ioctl.s
_kill.s
_link.s
_lseek.s
_open.s
_pause.s
_pipe.s
_read.s
_unlink.s
_wait.s
_write.s
exit.s
_exit.s
abort.s
access.s
chdir.s
chmod.s
chown.s
cleanup.s
close.s
creat.s
dup.s
execl.s
execle.s
execv.s
execve.s
time.s
exece.s
fork.s
fstat.s
getgid.s
getpid.s
getuid.s
gtty.s
stty.s
ioctl.s
kill.s
link.s
lseek.s
mknod.s
mount.s
nice.s
open.s
pipe.s
profil.s
read.s
sbrk.s
brk.s
setgid.s
setuid.s
signal.s
stat.s
sync.s
umount.s
unlink.s
wait.s
write.s
cerror.s
error.s
pause.s
alarm.s
ftime.s

View file

@ -0,0 +1,8 @@
.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
.define __alarm
.extern __alarm, cerror
__alarm: int 0x9b
jb 9f
ret
9:
jmp cerror

32
mach/m65oo2/libsys/_brk.s Normal file
View file

@ -0,0 +1,32 @@
.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
.define __brk
.define xbrk
__brk:
mov bx,sp
mov ax,2(bx)
mov cx,sp
sub cx,128
jbe 1f
mov bx,(.limhp)
mov (.limhp),ax
sub ax,bx
jbe 2f
call xbrk
2:
xor ax,ax
ret
1:
mov ax,0xc
jmp cerror
xbrk:
push di
mov di,bx
mov cx,ax
xor ax,ax
shr cx,1
repz stos
jae 3f
stosb
3:
pop di
ret

View file

@ -0,0 +1,8 @@
.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
.define __close
.extern __close, cerror
__close: int 0x86
jb 9f
xor ax,ax
ret
9: jmp cerror

View file

@ -0,0 +1,7 @@
.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
.define __creat
.extern __creat, cerror
__creat: int 0x88
jb 9f
ret
9: jmp cerror

View file

@ -0,0 +1,8 @@
.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
.define __dup
.extern __dup, cerror
__dup: int 0xc9
jb 9f
ret
9: jmp cerror

View file

@ -0,0 +1,20 @@
.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
.define __execl
.extern __execl, _environ, __execve
__execl:
push si
push di
push bp
mov bp,sp
push (_environ)
lea ax,10(bp)
push ax
push 8(bp)
call __execve
add sp,6
mov sp,bp
pop bp
pop di
pop si
ret

View file

@ -0,0 +1,8 @@
.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
.define __execve
.extern __execve, cerror
__execve:
int 0x8b
jb 9f
ret
9: jmp cerror

View file

@ -0,0 +1,10 @@
.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
.define __exit
.sect .text
__exit:
mov bx,sp
xor ax,ax
push ax ! unused memory
push 2(bx)
push ax ! dummy return address
int 0x81

View file

@ -0,0 +1,11 @@
.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
.define __fork
.extern __fork, cerror
__fork: int 0x82
jmp 1f
jae 2f
jmp cerror
1:
xor ax,ax
2:
ret

View file

@ -0,0 +1,8 @@
.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
.define __fstat
.extern __fstat, cerror
__fstat: int 0x9c
jb 9f
xor ax,ax
ret
9: jmp cerror

View file

@ -0,0 +1,8 @@
.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
.define __ftime
.extern __ftime, cerror
__ftime: int 0xa3
jb 9f
ret
9:
jmp cerror

View file

@ -0,0 +1,8 @@
.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
.define __getpid
.extern __getpid, cerror
__getpid: int 0x94
jb 9f
ret
9:
jmp cerror

Some files were not shown because too many files have changed in this diff Show more