Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions rt/bk10dx/file.coh
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ sub FCBOpenIn(fcb: [FCB], filename: [uint8]): (errno: uint8) is
var dxcb := &fcb.dxcb;
errno := 0;
_fcb_init(fcb);
fcb.readonly := FCB_FLAG_READONLY;

@asm "mov", filename, ", r1";
@asm "mov", dxcb, ", r4";
Expand All @@ -134,6 +135,7 @@ end sub;

sub FCBOpenUp(fcb: [FCB], filename: [uint8]): (errno: uint8) is
errno := FCBOpenIn(fcb, filename);
fcb.readonly := 0;
end sub;

sub FCBOpenOut(fcb: [FCB], filename: [uint8]): (errno: uint8) is
Expand Down
13 changes: 10 additions & 3 deletions rt/fileio.coh
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
const FCB_FLAG_ERROR := 1<<0;
const FCB_FLAG_READ := 1<<1;
const FCB_FLAG_WRITE := 1<<2;
const FCB_FLAG_READONLY := 1<<3;

record FCB: RawFCB is
pos: uint32;
buflen: FCBIndexType;
index: FCBIndexType;
buffer: uint8[FCB_BUFFER_SIZE];
flags: uint8;
readonly: uint8;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this belong in flags? I see it's being set to FCB_FLAG_READONLY, which looks like a flags value.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flags are changed by read/write/flush functions, and I didn't want to change common code too much.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping?

end record;

@decl sub FCBRawRead(fcb: [FCB], pos: uint32, len: FCBIndexType): (amount: FCBIndexType);
Expand All @@ -18,6 +20,7 @@ sub _fcb_init(fcb: [FCB]) is
fcb.buflen := 0;
fcb.index := 0;
fcb.flags := 0;
fcb.readonly := 0;
end sub;

sub _fcb_advance(fcb: [FCB]) is
Expand All @@ -28,7 +31,7 @@ sub _fcb_fillbuffer(fcb: [FCB]): (b: uint8) is
var bufpos := fcb.pos + (fcb.index as uint32);
fcb.buflen := FCBRawRead(fcb, bufpos, FCB_BUFFER_SIZE);
b := 0;
if (fcb.flags & FCB_FLAG_ERROR) != 0 then
if (fcb.flags & FCB_FLAG_ERROR) != 0 then
return;
end if;
fcb.flags := FCB_FLAG_READ;
Expand All @@ -42,7 +45,11 @@ end sub;

sub FCBFlush(fcb: [FCB]) is
if (fcb.flags & FCB_FLAG_WRITE) != 0 then
FCBRawWrite(fcb, fcb.pos, fcb.index);
if (fcb.readonly != 0) then
fcb.flags := fcb.flags | FCB_FLAG_ERROR;
else
FCBRawWrite(fcb, fcb.pos, fcb.index);
end if;
if (fcb.flags & FCB_FLAG_ERROR) != 0 then
return;
end if;
Expand All @@ -55,7 +62,7 @@ end sub;

sub _fcb_flushbuffer(fcb: [FCB], b: uint8) is
FCBFlush(fcb);
if (fcb.flags & FCB_FLAG_ERROR) != 0 then
if (fcb.flags & FCB_FLAG_ERROR) != 0 then
return;
end if;
fcb.flags := FCB_FLAG_WRITE;
Expand Down
44 changes: 44 additions & 0 deletions rt/rt11/argv.coh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# XXX not ported yet

var argv: uint8[81];
var argv_pointer: [uint8] := &argv[0];

sub ArgvInit() is
var carry: uint8 := 0;
var prompt: [uint8] := "DCL>";
var tmp: uint8[81];
var ptr: [uint8];

@asm ".gtlin", argv_pointer, ",", prompt;
@asm "adcb", carry;

print("error: "); print_i32(carry as uint32); print_nl();
print("csi args: "); print(argv_pointer); print_nl();
ptr := argv_pointer + StrLen(argv_pointer);

# undo CSI conversion: "a b c" -> "b c=a"
loop
ptr := @prev ptr;
var c := [ptr];
if (c == '=') then break; end if;
if ptr == argv_pointer then return; end if;
end loop;

print("tmp: "); print(ptr); print_nl();
print("tmp: "); print_char([ptr + 1]); print_nl();

# found '=' char
[ptr] := 0;
CopyString(ptr + 1, &tmp[0]);
tmp[StrLen(ptr + 1) as uint8] := ' ';
CopyString(argv_pointer, &tmp[StrLen(ptr + 1) as uint8 + 1]);
CopyString(&tmp[0], argv_pointer);
print("unix args: "); print(argv_pointer); print_nl();
end sub;

# Returns null is there's no next argument.
sub ArgvNext(): (arg: [uint8]) is
arg := argv_pointer;
end sub;

# vim: ts=4 sw=4 et
5 changes: 5 additions & 0 deletions rt/rt11/build.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
cowwrap {
ins = { "rt/rt11/cowgol.cos" },
outs = { "$OBJ/rt/rt11/cowgol.coo" }
}

3 changes: 3 additions & 0 deletions rt/rt11/build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from src.build import cowwrap

cowwrap(name="cowgolcoo", src="./cowgol.cos")
63 changes: 63 additions & 0 deletions rt/rt11/cowgol.coh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
var LOMEM: [uint8];
var HIMEM: [uint8];
var HW: int16;
var API: int16;

@asm "; set LOMEM and HIMEM";
@asm "mov limit+2,", LOMEM;
@asm ".gval #limit, #^O266"; # $USRLC
@asm ".setto r0";
@asm "mov r0,", HIMEM;
@asm "clr", HW;
@asm "clr", API;
@asm ";";

sub Exit() is
@asm "bisb\t#1, @#^O53";
@asm "br\texit";
end sub;

sub ExitWithError() is
@asm "bisb\t#4, @#^O53";
@asm "br\texit";
end sub;

sub AlignUp(in: intptr): (out: intptr) is
out := (in + 1) & ~1;
end sub;

sub print_char(c: uint8) is
if c == '\n' then
@asm ".ttyou #^O15";
end if;
@asm ".ttyou", c;
end sub;

sub MemSet(buf: [uint8], byte: uint8, len: uint16) is
var bufend := buf + len;
loop
if buf == bufend then
return;
end if;
[buf] := byte;
buf := buf + 1;
end loop;
end sub;

sub print_oct_i16(value: uint16) is
var i: uint8 := 5;
print_char(((value >> 15) + '0') as uint8);
loop
var digit := (((value >> 12) & 7) + '0') as uint8;
print_char(digit);
value := value << 3;
i := i - 1;
if i == 0 then
break;
end if;
end loop;
end sub;

include "common.coh";

# vim: ts=4 sw=4 et
86 changes: 86 additions & 0 deletions rt/rt11/cowgol.cos
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Unsigned 32-bit division.
# Computes r2r3/r0r1, putting the quotient in r2r3 and the remainder in r4r5.
&X _divremu4
; _divremu4
``:
; The PDP11 has a 32/16->16%16 signed division instruction. Synthesising
; 32/32->32%32 unsigned division from this is surprisingly hard, so for
; now we don't bother and just use long division.

clr r4 ; reset remainder
clr r5
mov r0, -(sp) ; move hi(RHS) onto the stack, as we need r0...
mov #32, r0 ; ...for the loop counter
br ``_entry

``_loop:
dec r0
beq ``_exit
``_entry:
ashc #1, r2 ; left shift LHS
rol r5 ; ...moving the shifted out top bit into the remainder
rol r4

cmp r4, (sp) ; if remainder < RHS, loop without subtracting
bcs ``_loop
bne ``_skip
cmp r5, r1
bcs ``_loop

``_skip:
inc r3 ; set the bottom bit of the quotient (guaranteed to be 0)
sub r1, r5
sbc r4 ; remainder = remainder - RHS
sub (sp), r4
br ``_loop
``_exit:
mov (sp)+, r0 ; retract stack
rts pc

# Signed 32-bit division.
# Computes r2r3/r0r1, putting the quotient in r2r3 and the remainder in r4r5.
# This is a wrapper around _divremu4 above.
&X _divrems4
; _divrems4
``:
xor r2, r0 ; discover sign of result
mov r0, -(sp) ; save for later
xor r2, r0 ; recover result
mov r2, -(sp) ; save result for sign of remainder

tst r0 ; set flags from hi(rhs)
bpl ``_1
com r0 ; negate r0r1
com r1
add #1, r1 ; add (setting carry)
adc r0
``_1:
tst r2 ; set flags from hi(lhs)
bpl ``_2
com r2 ; negate r2r3
com r3
add #1, r3
adc r2
``_2:

call `_divremu4 ; perform unsigned division

tst (sp) ; check sign of remainder
bpl ``_3
com r4
com r5
add #1, r5
adc r4
``_3:
tst 2(sp) ; check sign of quotient
bpl ``_4
com r2
com r3
add #1, r3
adc r2
``_4:
add #4, sp ; retract over stack
rts pc

# vim: ts=4 sw=4 et

Loading