Oberon/ETH Oberon/Cast

PROCEDURE Cast(VAR in:ARRAY OF REAL; VAR out: ARRAY OF INTEGER);
CODE {SYSTEM.i386, SYSTEM.FPU}
    MOV   EDI, 8[EBP]         ; dest   = ADR(out)
    MOV   ECX, 12[EBP]        ; count  = LEN(out)
    MOV   ESI, 16[EBP]        ; source = ADR(in)
    CMP   ECX, 20[EBP]
    JGE   Ok
    PUSH  99                  ; LEN(in) > LEN(out)  then TRAP(99)
    INT   3
Ok:
    SUB   ESP, 8              ; change FPU rounding to "chop"
    FSTCW 0[ESP]
    WAIT
    MOV   EBX, 0[ESP]
    OR    EBX, 0400H          ; clear bit 10,11 (chop/truncate toward zero)
    MOV   4[ESP], EBX
    FLDCW 4[ESP]
    
    JMP   Check
Loop:
    DEC   ECX
    FLD   DWORD [ESI][ECX*4]  ; in: REAL
    FISTP WORD [EDI][ECX*2]   ; out: INTEGER
    WAIT
Check:
    CMP   ECX, 0
    JG    Loop

    FLDCW 0[ESP]               ; restore original FPU configuration
    ADD   ESP, 8
END Cast;



If in: ARRAY OF LONGREAL then use
    FLD   QWORD [ESI][ECX*8]  ; in: LONGREAL

If out: ARRAY OF LONGINT then use
    FISTP DWORD [ESI][ECX*4]  ; out: LONGINT