knowledge-database (beta)

Current group: comp.lang.forth

retroforth 386 assembler

retroforth 386 assembler  
Albert van der Horst
 Re: retroforth 386 assembler  
Marc Olschok
 Re: retroforth 386 assembler  
Jerry Avins
 Re: retroforth 386 assembler  
crc
 Re: retroforth 386 assembler  
PhiHo Hoang
 Re: retroforth 386 assembler  
crc
 Re: retroforth 386 assembler  
Albert van der Horst
 Re: retroforth 386 assembler  
crc
 Re: retroforth 386 assembler  
crc
 Re: retroforth 386 assembler  
Marc Olschok
 Re: retroforth 386 assembler  
PhiHo Hoang
 Re: retroforth 386 assembler  
Coos Haak
 Re: retroforth 386 assembler  
PhiHo Hoang
From:Albert van der Horst
Subject:retroforth 386 assembler
Date:12 Jan 2005 04:35:53 +0100
It took the better part of an evening but here it is:
an assembler for retroforth at the 386 level without sib byte.
(You may add the Pentium instructions of a recent post, but I don't
think floating point and the scaled index byte are retro.)

I felt very, well, retro. Debugging a source with no possibility to load
files or blocks. ( Pasting in and redirection worked reasonable in linux KDE).
The very basic debugging aids like .s and dump are missing from
retroforth. It doesn't help that there is no prompt. So there is no
difference between correct execution and an infinite loop.

Don't think that I wrote r@ and dsp@ in assembler. I used the parse and
unparse programs to go back and forth between retro blocks with
machine code and assembler.

If you do something substantially more difficult than the ``nip''
example at the end, I would advise to use the fully documented, great
assembler at forthassembler.html
You have than syntax checking during development. The syntax of this
assembler may be cumbersome, but once errorfree it is unambiguous.
The testset contains all possible combinations. I leave it as an
exercise to pull the testset through retroforth.

--------------8<---------------8<------------------8<-----------8<----
| Words needed extra in behalf of miniassembler
| ----------------------- compatibility prelude --------------------

' | alias \

macro

\ ISO
: r@ $04ee83 3, $0689 2, $58 1, $50 1, ;

\ Return the data stack POINTER as before execution of this word.
: dsp@ $04ee83 3, $0689 2, $c68b 2, ;

forth

: depth $8049daf dsp@ - 2 >> ;

\ Note retroforth's +! is not ISO-compatible.
: !+ swap +! ;

\ Print top 3 stack items
: .s cr rot dup . rot dup . rot dup . cr ;

\ -------------------- assembler proper ----------------------

hex

\ -------------------- retroforth specific -------------
\ --assembler_generic split 1pi fir 1family, ) \ A4sep27 AvdH
: split dup 8 >> swap $ff and ; \ Split X : REMAINDER and ls BYTE
\ Post INSTRUCTION of LENGTH. Big endian specific!
: post swap , 1 cells - allot ;
\ Fixup with ms byte of FIX below ADDR, leave next FIX ADDR
: fix| 1 - >r split r@ !+ r> ;
: 1pi create , does> @ 1 post ; \ 1 byte post-it opcode
: 2pi create , does> @ 2 post ; \ 2 byte post-it opcode
: 3pi create , does> @ 3 post ; \ 3 byte post-it opcode
\ Fixup from behind starting with ls byte.
: fir create , does> @ here swap repeat swap fix| swap 1+ until drop ;
\ Create a family adding INC to OPCODE with COUNT members
: 1family, repeat >r dup 1pi over + r> until drop drop ;
: 2family, repeat >r dup 2pi over + r> until drop drop ;
: 3family, repeat >r dup 3pi over + r> until drop drop ;
: family|r repeat >r dup fir over + r> until drop drop ;
: (C,) 1, ;
: (W,) 2, ;
: (L,) , ;

\ -------------------- system independant -------------

\ --assembler_i86_fixups_1 [AX] AX| AX|) CF: ?32 | A4sep27 AvdH

40 00 4 family|r ZO| BO| XO| R|
05 fir MEM| | instead of ZO| BP| )
01 00 8 family|r [AX] [CX] [DX] [BX] ~SIB| [BP] [SI] [DI]
01 00 8 family|r AL| CL| DL| BL| AH| CH| DH| BH|
01 00 8 family|r AX| CX| DX| BX| SP| BP| SI| DI|
08 00 8 family|r AL'| CL'| DL'| BL'| AH'| CH'| DH'| BH'|
08 00 8 family|r AX'| CX'| DX'| BX'| SP'| BP'| SI'| DI'|
08 00 6 family|r ES| CS| SS| DS| FS| GS|
0100 0000 2 family|r B| X| 0200 0000 2 family|r F| T|

\ Use any primed thingies with AS: prefix . )
6 fir MEM|'
1 0 8 family|r [BX+SI]' [BX+DI]' [BP+SI]' [BP+DI]' [SI]' [DI]' [BP]' [BX]'
\ --assembler_commaers ) \ A4sep27 AvdH

\ O=obligatory R=Relative I=Immediate )
' (W,) alias OW, ' (L,) alias IL,
' (L,) alias (RL,) ' (W,) alias IW,
' (W,) alias (RW,) ' (C,) alias IB,
' (C,) alias (RB,) ' (L,) alias L,
' (W,) alias SG, ' (W,) alias W,
' (C,) alias P, ' (C,) alias B,
' (C,) alias IS,



\ --assembler_i86_opcodes_1 ) \ A4sep27 AvdH
08 06 4 1family, PUSH|ES, PUSH|CS, PUSH|SS, PUSH|DS,
08 07 4 1family, POP|ES, -- POP|SS, POP|DS,
08 26 4 1family, ES:, CS:, SS:, DS:,
08 27 4 1family, DAA, DAS, AAA, AAS,
01 00 2 family|r B'| X'|
08 04 8 1family, ADDI|A, ORI|A, ADCI|A, SBBI|A, ANDI|A, SUBI|A, XORI|A, CMPI|A,
02 A0 2 1family, MOV|TA, MOV|FA,

70 1pi J, \ As in J, L| Y| S, )
01 00 2 family|r Y| N|
02 00 8 family|r O| C| Z| CZ| S| P| L| LE|

08 40 4 1family, INC|X, DEC|X, PUSH|X, POP|X,
90 1pi XCHG|AX,
\ --assembler_i86_opcodes_2 ) \ A4sep27 AvdH
08 00 8 2family, ADD, OR, ADC, SBB, AND, SUB, XOR, CMP,
02 84 2 2family, TEST, XCHG,
01 98 8 1family, CBW, CWD, IR2, WAIT, PUSHF, POPF, SAHF, LAHF,
02 A4 6 1family, MOVS, CMPS, -- STOS, LODS, SCAS,
08 B0 2 1family, MOVI|BR, MOVI|XR,
08 C3 2 1family, RET, RETFAR, 08 C2 2 1family, RET+, RETFAR+,
01 C4 2 2family, LES, LDS, 00C6 2pi MOVI, 0CD 1pi INT,
01 CC 4 1family, INT3, -- INTO, IRET,
01 D4 4 1family, AAM, AAD, -- XLAT,
01 E0 4 1family, LOOPNZ, LOOPZ, LOOP, JCXZ,
02 E4 2 1family, IN|P, OUT|P, 2 EC 2 1family, IN|D, OUT|D,
01 E8 2 1family, CALL, JMP,

0088 2pi MOV, 008C 2pi MOV|SG, 008D 2pi LEA,
EA 1pi JMPFAR, EB 1pi JMPS, 9A 1pi CALLFAR, A8 1pi TESTI|A,
\ --assembler_i86_opcodes_3 ) \ A2oct21 AvdH
01 F0 6 1family, LOCK, -- REPNZ, REPZ, HLT, CMC,
01 F8 6 1family, CLC, STC, CLI, STI, CLD, STD, | 38FE
800 80 8 2family, ADDI, ORI, ADCI, SBBI, ANDI, SUBI, XORI, CMPI,
0800 83 8 2family, ADDSI, -- ADCSI, SBBSI, -- SUBSI, -- CMPSI,
800 10F6 6 2family, NOT, NEG, MUL|AD, IMUL|AD, DIV|AD, IDIV|AD,
0800 00FE 2 2family, INC, DEC,
0800 10FF 4 2family, CALLO, CALLFARO, JMPO, JMPFARO,

0200 0000 2 family|r 1| V|
0800 00D0 8 2family, ROL, ROR, RCL, RCR, SHL, SHR, -- SAR,
0800 C0 8 2family, ROLI, RORI, RCLI, RCRI, SHLI, SHRI, -- SARI,

00F6 2pi TESTI, 008F 2pi POP, 30FF 2pi PUSH,
00AF0F 3pi IMUL,


decimal


\ ---------------------- a small test ------------------------------
\ retroforth specific

: nip [ LEA, SI'| BO| [SI] 4 B, ] ;

.." test of nip"
1 2 3 4 .s nip .s

--------------8<---------------8<------------------8<-----------8<----

Groetjes Albert
--
Albert van der Horst,Oranjestr 8,3511 RA UTRECHT,THE NETHERLANDS
To suffer is the prerogative of the strong. The weak -- perish.
albert@spenarnc.xs4all.nl http://home.hccnet.nl/a.w.m.van.der.horst
From:Marc Olschok
Subject:Re: retroforth 386 assembler
Date:Thu, 13 Jan 2005 16:34:24 +0000 (UTC)
Albert van der Horst wrote:
>[...]
> I felt very, well, retro. Debugging a source with no possibility to load
> files or blocks. ( Pasting in and redirection worked reasonable
> in linux KDE).
> The very basic debugging aids like .s and dump are missing from
> retroforth.[...]

You can grab a (very simple) dump and some other utilities from
.
There was a small block-editor included in version 7.4. Together with
the file-words you can edit and save your source.

Marc
From:Jerry Avins
Subject:Re: retroforth 386 assembler
Date:Thu, 13 Jan 2005 13:57:48 -0500
Marc Olschok wrote:

> Albert van der Horst wrote:
>
>>[...]
>>I felt very, well, retro. Debugging a source with no possibility to load
>>files or blocks. ( Pasting in and redirection worked reasonable
>>in linux KDE).
>>The very basic debugging aids like .s and dump are missing from
>>retroforth.[...]
>
>
> You can grab a (very simple) dump and some other utilities from
> .
> There was a small block-editor included in version 7.4. Together with
> the file-words you can edit and save your source.
>
> Marc

Augmented .S and DUMP to suit my taste; MAXXforth:

2VARIABLE X.R 7 0 X.R 2! \ Argument and print routine

\ : .S_WIDTH ( n -- ) X.R CELL+ ! ;

: (.S) DEPTH 0= IF CR ." Empty "
ELSE DEPTH DUP ." Depth (decimal): " .D CR 0B MIN DUP
0 DO DUP PICK X.R 2@ EXECUTE 1- LOOP DROP
THEN CR ;

: .S [ ' .R CFA ] LITERAL X.R ! (.S) ;
: U.S [ ' U.R CFA ] LITERAL X.R ! (.S) ;

: >CHAR ( n -- c ) DUP 9 > 7 AND + 30 + ;

\ DUMP

: key-check ( start-of-line -- start-of-line | nothing )
?TERMINAL IF KEY 1B = IF SPACE ." OK " DROP QUIT ELSE BEGIN
?TERMINAL UNTIL KEY 1B = IF SPACE ." OK " DROP QUIT THEN THEN THEN ;

: dump-header ( -- )
CR 7 SPACES 10 0 DO I >CHAR EMIT 2 SPACES LOOP
10 0 DO I >CHAR EMIT LOOP ;

: dump-line ( start-of-line -- start-of-next-line )
CR DUP BASE @ >R HEX 4 U.R SPACE
10 0 DO SPACE DUP I + C@ 10 /MOD >CHAR EMIT >CHAR EMIT LOOP 2 SPACES
10 0 DO DUP I + C@ DUP 1F 80 WITHIN IF EMIT ELSE DROP ." ." THEN LOOP
10 + R> BASE ! key-check ;

: DUMP ( start count -- )
SWAP 10 /MOD 10 * SWAP ROT + 10 /MOD SWAP 0= 1+ + DUP >R
dump-header 0 DO dump-line LOOP DROP
R> 9 > IF dump-header THEN SPACE ;

Jerry
--
Engineering is the art of making what you want from things you can get.
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
From:crc
Subject:Re: retroforth 386 assembler
Date:15 Jan 2005 17:42:30 -0800
I don't define QUIT in RetroForth. Use of a nested definiton is the
best way to test it though.

Something like:

: foo bye ;
: bar foo ;
: baz bar ;
baz

should be enough to mess up the returns stack a bit. If it can exit
successfully, then your "bye" works ok.

--
Charles
From:PhiHo Hoang
Subject:Re: retroforth 386 assembler
Date:Sat, 15 Jan 2005 21:48:45 -0500

charles.childers

>I don't define QUIT in RetroForth.

Just replace :

interpret:

with :

code 'QUIT', interpret

> Use of a nested definiton is the
> best way to test it though.
>
> Something like:
>
> : foo bye ;
> : bar foo ;
> : baz bar ;
> baz
>
> should be enough to mess up the returns stack a bit. If it can exit
> successfully, then your "bye" works ok.
>

Hooray ! Yes, it works :-)

Thanks,

Cheers,

PhiHo
From:crc
Subject:Re: retroforth 386 assembler
Date:12 Jan 2005 15:30:58 -0800
I'm very impressed with this. I've made a few changes to make it work
on RetroForth 7.6. While I still find the syntax a bit convulated; it
works wonderfully from what I can see so far.
From:Albert van der Horst
Subject:Re: retroforth 386 assembler
Date:13 Jan 2005 12:38:37 GMT
In article <1105572658.876232.282450@c13g2000cwb.googlegroups.com>,
crc wrote:
>I'm very impressed with this. I've made a few changes to make it work
>on RetroForth 7.6. While I still find the syntax a bit convulated; it
>works wonderfully from what I can see so far.

There is a price to pay for simplicity.

You can use ciasdis for syntax checking though:
Example ---------------------------
ciasdis
0 ORG \ Don't forget this, or you will regret it.
OK
CODE JAN
ADD,
OK
X| F| AX'| R| BX|
OK
ADD,
OK
ADD,
ADD,? ciforth ERROR # 26 : AS: PREVIOUS INSTRUCTION INCOMPLETE
-------------------------
To recover after an error just start a new word:
CODE JAN ADD,
OK
>

Did you find parse and unparse usefull that I sent the other
day?

Groetjes Albert

--

--
Albert van der Horst,Oranjestr 8,3511 RA UTRECHT,THE NETHERLANDS
One man-hour to invent,
One man-week to implement,
One lawyer-year to patent.
From:crc
Subject:Re: retroforth 386 assembler
Date:13 Jan 2005 15:08:36 -0800
Yes, those parse/unparse programs are quite helpful. I'm starting to
make sense of the assembly syntax now; with luck I'll be able to write
words using it soon.
From:crc
Subject:Re: retroforth 386 assembler
Date:13 Jan 2005 14:56:11 -0800
Since I don't mind lowercase chars in a dump, I use:

: h. hex . decimal ;
: dump over h. repeat >r dup c@ h. 1+ r> until cr ;

I've been using varients of this "dump" word for a couple of years now.


I really like the code in the S0x files. Would it be ok for me to add
them to the code library? And if so, what license/copyright information
should be included with them?

You'll be seeing the block editor again soon; a slightly updated
version will be included in 7.7. (The block editor plays a major role
in the work I'm doing on 8.0). I have some words that will allow
loading and saving of a blockfile under Linux and am working on
implementations of these words for the Windows, FreeBSD, and
BeOS/Generic/Generic+libdl.so ports.
From:Marc Olschok
Subject:Re: retroforth 386 assembler
Date:Fri, 14 Jan 2005 15:39:31 +0000 (UTC)
crc wrote:
>[...]
> I really like the code in the S0x files. Would it be ok for me to add
> them to the code library? And if so, what license/copyright information
> should be included with them?

You are welcome to include them, I am glad that they might be
useful to somebody else.

I would feel rather stupid, if I put more restrictions on these
files than on the underlying Forth.
Since Retroforth is given available 'completely free' the same
can be applied to the above files.

>
> You'll be seeing the block editor again soon; a slightly updated
> version will be included in 7.7. (The block editor plays a major role
> in the work I'm doing on 8.0). I have some words that will allow
> loading and saving of a blockfile under Linux and am working on
> implementations of these words for the Windows, FreeBSD, and
> BeOS/Generic/Generic+libdl.so ports.
>

Good news.
Best regards, Marc
From:PhiHo Hoang
Subject:Re: retroforth 386 assembler
Date:Sat, 15 Jan 2005 12:11:32 -0500
charles.childers wrote:

[SNIP]

>
> You'll be seeing the block editor again soon; a slightly updated
> version will be included in 7.7. (The block editor plays a major role
> in the work I'm doing on 8.0). I have some words that will allow
> loading and saving of a blockfile under Linux and am working on
> implementations of these words for the Windows, FreeBSD, and
> BeOS/Generic/Generic+libdl.so ports.
>

This is cool.

I also like to suggest adding to rf.asm:

eval_cb:

upsh [esp + 4] ; Start of bootstrap
upsh [esp + 8] ; Length of bootstrap
call eval ; Interpret bootstrap

ret

with eval_cb exported, IA32FVM wrapper now can run either
Win32For or RetoForth kernel via [Setup] , [RetroForth] and
[R4Blocks] sections in IA32FVM.ini

[Setup]
Forth= RetroForth
; Forth = Win32Forth

[RetroForth]
HPK = RF.dll
Extend = R4Blocks
R4 = 1
DLL = 1
Interp = 1

[R4Blocks]
B000 = Block 000
B001 = Block 001
B002 = Block 002
B003 = Block 003
B004 = Block 004

as a result, RF.dll is now 4KB

To further reduce the size of RF.dll, bye is now
a "high level" word in in block B000 ;-)

: bye [ $5b 1, ] ;

Some pusha popa were also commented out.

If you can find time to review these changes ,
they will be emailed to you .

Cheers,

PhiHo
From:Coos Haak
Subject:Re: retroforth 386 assembler
Date:Sat, 15 Jan 2005 20:48:39 +0100
Op Sat, 15 Jan 2005 12:11:32 -0500 schreef PhiHo Hoang:


> To further reduce the size of RF.dll, bye is now
> a "high level" word in in block B000 ;-)
>
>: bye [ $5b 1, ] ;
>
Are you sure there is nothing on the returnstack that
you can just pop a register and do a return?
What if you put BYE deep in a series of nested words?

Why not (under Windows/Dos) like this:
: bye [ $4cb4 2, $21cd 2, ] ;

And the lowest byte on the data stack is returned
to the OS too ;-)
--
Coos
From:PhiHo Hoang
Subject:Re: retroforth 386 assembler
Date:Sat, 15 Jan 2005 19:58:20 -0500
Coos Haak wrote:

>> To further reduce the size of RF.dll, bye is now
>> a "high level" word in in block B000 ;-)
>>
>>: bye [ $5b 1, ] ;
>>
> Are you sure there is nothing on the returnstack that
> you can just pop a register and do a return?

Honestly, no, I am not. :-)

>
> What if you put BYE deep in a series of nested words?
>

Actually, the original code word for bye is :

code 'bye', windows_bye
mov dword [rf_eax], eax
mov dword [rf_esi], esi
pop ebx
ret

where

rf_eax rd 1
rf_esi rd 1

and

retroforth_interpreter:
call retroforth_attach
mov eax, dword [rf_eax]
mov esi, dword [rf_esi]
call interpret
ret

retroforth_init:
call init_retroforth
mov dword [rf_eax], eax
mov dword [rf_esi], esi
ret

After a bit of refactoring bye just became:

code 'bye', windows_bye
pop ebx
ret

hence

: bye [ $5b 1, ] ;

Well, I am not quite sure how good is this bye.

After RetroForth was started up the snippet :

words QUIT

was repeated 10 times then a sequence of 11 bye
ended that RetroForth session.

>
> Why not (under Windows/Dos) like this:
> : bye [ $4cb4 2, $21cd 2, ] ;
>
Trying the same test, after the first

words QUIT

then a bye , RetroForth crashed.

> And the lowest byte on the data stack is returned
> to the OS too ;-)

Maybe RetroForth didn't like that lowest byte ;-)

I am willing to do some further testing if there is some
further tests besides that

words QUIT bye

Cheers,

PhiHo
   

Copyright © 2006 knowledge-database   -   All rights reserved