Reduce sectorlisp from 948 to 856 bytes

This commit is contained in:
Justine Tunney 2020-10-27 13:42:10 -07:00
parent a561e031ae
commit 665668a7a0
8 changed files with 171 additions and 203 deletions

View file

@ -51,10 +51,10 @@ clean:; $(RM) $(CLEANFILES)
lisp.bin.dbg: start.o lisp.real.o lisp.lds lisp.bin.dbg: start.o lisp.real.o lisp.lds
sectorlisp.bin.dbg: start.o sectorlisp.o lisp.lds sectorlisp.bin.dbg: start.o sectorlisp.o lisp.lds
start.o: start.S start.o: start.S Makefile
lisp.o: lisp.c lisp.h lisp.o: lisp.c lisp.h Makefile
lisp.real.o: lisp.c lisp.h lisp.real.o: lisp.c lisp.h Makefile
sectorlisp.o: sectorlisp.S sectorlisp.o: sectorlisp.S Makefile
%.real.o: %.c %.real.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(REALFLAGS) -c -o $@ $< $(CC) $(CPPFLAGS) $(CFLAGS) $(REALFLAGS) -c -o $@ $<

View file

@ -29,7 +29,7 @@ of running natively without dependencies on modern PCs, sectorlisp might
be the tiniest self-hosting LISP interpreter to date. be the tiniest self-hosting LISP interpreter to date.
We're still far off however from reaching our goal, which is to have We're still far off however from reaching our goal, which is to have
sectorilsp be small enough to fit in the master boot record of a floppy sectorlisp be small enough to fit in the master boot record of a floppy
disk, like [sectorforth](https://github.com/cesarblum/sectorforth). If disk, like [sectorforth](https://github.com/cesarblum/sectorforth). If
you can help this project reach its goal, please send us a pull request! you can help this project reach its goal, please send us a pull request!

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

View file

@ -4,12 +4,12 @@ SECTIONS {
.text 0x7c00 - 0x600 : { .text 0x7c00 - 0x600 : {
*(.start) *(.start)
*(.text.startup)
rodata = .; rodata = .;
*(.rodata .rodata.*) *(.rodata .rodata.*)
. = 0x1fe; . = 0x1fe;
SHORT(0xaa55); SHORT(0xaa55);
*(.text .text.*) *(.text .text.*)
/*BYTE(0x90);*/
_etext = .; _etext = .;
. = ALIGN(512); . = ALIGN(512);
} }
@ -21,6 +21,7 @@ SECTIONS {
} }
/DISCARD/ : { /DISCARD/ : {
*(.yoink)
*(.*) *(.*)
} }
} }

View file

@ -40,6 +40,7 @@ NIL
;; CONS CELL ;; CONS CELL
;; BUILDING BLOCK OF DATA STRUCTURES ;; BUILDING BLOCK OF DATA STRUCTURES
(CONS NIL NIL) (CONS NIL NIL)
(CONS (QUOTE X) (QUOTE Y))
;; REFLECTION ;; REFLECTION
;; EVERYTHING IS AN ATOM OR NOT AN ATOM ;; EVERYTHING IS AN ATOM OR NOT AN ATOM

View file

@ -35,22 +35,18 @@
#define ATOM_CONS 88 #define ATOM_CONS 88
#define ATOM_LAMBDA 98 #define ATOM_LAMBDA 98
#define SYNTAX 0x4000 #define STR 0x4186
#define LOOK 0x4100
#define GLOBALS 0x4102
#define INDEX 0x4104
#define TOKEN 0x4106
#define STR 0x41c8
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
.section .start,"ax",@progbits .section .start,"ax",@progbits
.globl main .globl main
.code16 .code16
main: mov $SYNTAX,%bx main: mov $q.syntax,%bx
movb $32,32(%bx) mov $32,%al
movb $32,13(%bx) mov %al,32(%bx)
movb $32,10(%bx) mov %al,13(%bx)
mov %al,10(%bx)
movw $10536,40(%bx) movw $10536,40(%bx)
movb $46,46(%bx) movb $46,46(%bx)
mov $STR,%di mov $STR,%di
@ -58,58 +54,41 @@ main: mov $SYNTAX,%bx
mov $57,%cx mov $57,%cx
rep movsb rep movsb
0: call GetChar 0: call GetChar
mov %ax,LOOK mov %ax,q.look
call GetToken call GetToken
call GetObject call GetObject
xchg %ax,%di xchg %ax,%di
mov GLOBALS,%si mov q.globals,%si
call Eval call Eval
xchg %ax,%di xchg %ax,%di
call PrintObject call PrintObject
mov $kCrlf,%di mov $kCrlf,%si
call PrintString call PrintString
jmp 0b jmp 0b
PutChar:push %bx
push %bp # original ibm pc scroll up bug
mov $0x0007,%bx # normal mda/cga style page zero
xchg %di,%ax # character to display
mov $0x0E,%ah # teletype output
int $0x10 # vidya service
pop %bp # result dilal
pop %bx
ret
GetChar:xor %ax,%ax # get keystroke GetChar:xor %ax,%ax # get keystroke
int $0x16 # keyboard service int $0x16 # keyboard service
xor %ah,%ah # ah is bios scancode xor %ah,%ah # ah is bios scancode
push %ax # al is ascii character push %ax # al is ascii character
xchg %ax,%di # result is ax call PutChar # ax will have result
call PutChar cmp $'\r,%al # don't clobber stuff
cmp $'\r,%al
jne 1f jne 1f
mov $'\n,%di mov $'\n,%al
call PutChar call PutChar
1: pop %ax 1: pop %ax
ret ret
PrintString: Cadr: and $-2,%di # (object >> 1) * sizeof(word)
mov %di,%dx mov 2(%di),%di # contents of decrement register
0: mov %dx,%di and $-2,%di # contents of address register
mov (%di),%al mov (%di),%ax
test %al,%al ret
je 1f
xchg %ax,%di
call PutChar
inc %dx
jmp 0b
1: ret
GetToken: GetToken:
xor %bx,%bx xor %bx,%bx
mov $SYNTAX,%si mov $q.syntax,%si
mov LOOK,%ax mov q.look,%ax
mov $TOKEN,%cx mov $q.token,%di
0: mov %al,%bl 0: mov %al,%bl
mov (%bx,%si),%dl mov (%bx,%si),%dl
mov %dl,%bl mov %dl,%bl
@ -119,24 +98,19 @@ GetToken:
jmp 0b jmp 0b
1: test %dl,%dl 1: test %dl,%dl
je 3f je 3f
xchg %cx,%di
stosb stosb
xchg %di,%cx
call GetChar call GetChar
jmp 4f jmp 4f
2: test %bl,%bl 2: test %bl,%bl
jne 4f jne 4f
xchg %cx,%di
stosb stosb
xchg %di,%cx
call GetChar call GetChar
mov %ax,%bx mov %ax,%bx
mov (%bx,%si),%bl mov (%bx,%si),%bl
3: test %al,%al 3: test %al,%al
jne 2b jne 2b
4: mov %cx,%di 4: movb $0,(%di)
movb $0,(%di) mov %al,q.look
mov %al,LOOK
ret ret
Assoc: xchg %si,%bx Assoc: xchg %si,%bx
@ -158,24 +132,56 @@ Assoc: xchg %si,%bx
ret ret
GetObject: GetObject:
cmpb $40,TOKEN cmpb $40,q.token
je 1f je GetList
mov $TOKEN,%di mov $q.token,%di
jmp Intern
1: #jmp GetList
/ 𝑠𝑙𝑖𝑑𝑒 / 𝑠𝑙𝑖𝑑𝑒
Intern: mov %di,%bx
mov $STR,%si
0: lodsb
test %al,%al
je 4f
xor %dx,%dx
1: mov %dx,%di
mov (%bx,%di),%cl
cmp %cl,%al
jne 3f
inc %dx
test %al,%al
jne 2f
sub %di,%si
lea -STR-1(%si),%ax
jmp 6f
2: lodsb
jmp 1b
3: test %al,%al
jz 0b
lodsb
jmp 3b
4: lea -1(%si),%di
push %di
mov %bx,%si
0: lodsb
stosb
test %al,%al
jnz 0b
pop %ax
sub $STR,%ax
6: shl %ax
ret
GetList:call GetToken GetList:call GetToken
mov TOKEN,%al mov q.token,%al
cmp $'),%al cmp $'),%al
je 2f je 2f
cmp $'.,%al cmp $'.,%al
je 1f je 1f
call GetObject call GetObject
push %ax push %ax # save
call GetList call GetList
xchg %ax,%si xchg %ax,%si
pop %di pop %di # restore
jmp Cons jmp Cons
1: call GetToken 1: call GetToken
jmp GetObject jmp GetObject
@ -187,7 +193,7 @@ EvalCons:
mov 2(%bx),%bx mov 2(%bx),%bx
mov %bx,%di mov %bx,%di
call Cadr call Cadr
mov %ax,%di xchg %ax,%di
mov %bp,%si mov %bp,%si
call Eval call Eval
mov %bp,%si mov %bp,%si
@ -200,7 +206,7 @@ EvalCons:
/ jmp Cons / jmp Cons
/ 𝑠𝑙𝑖𝑑𝑒 / 𝑠𝑙𝑖𝑑𝑒
Cons: mov $INDEX,%bx Cons: mov $q.index,%bx
mov (%bx),%ax mov (%bx),%ax
addw $2,(%bx) addw $2,(%bx)
shl %ax shl %ax
@ -213,92 +219,83 @@ Cons: mov $INDEX,%bx
Bind: test %di,%di Bind: test %di,%di
je 1f je 1f
push %bp push %bp
mov %sp,%bp and $-2,%si
push %dx
push %dx
xchg %si,%bx
and $-2,%bx
and $-2,%di and $-2,%di
mov %di,-4(%bp) mov %di,%bp
mov 2(%bx),%si push %dx # save no. 1
push %si # save no. 2
mov 2(%si),%si
mov 2(%di),%di mov 2(%di),%di
push %bx # save no. 1
call Bind call Bind
pop %bx # rest no. 1 pop %si # rest no. 2
push %ax # save no. 2 mov (%si),%di
mov (%bx),%bx pop %si # rest no. 1
mov %bx,%di push %ax # save no. 3
mov -2(%bp),%si
call Eval call Eval
mov -4(%bp),%di mov %ds:(%bp),%di
mov (%di),%di
xchg %ax,%si xchg %ax,%si
call Cons call Cons
pop %si # rest no. 2 pop %si # rest no. 3
xchg %ax,%di xchg %ax,%di
leave pop %bp
jmp Cons jmp Cons
1: xchg %dx,%ax 1: xchg %dx,%ax
ret ret
EvalCdr: PrintString: # nul-terminated in si
mov %dx,%di 0: lodsb # don't clobber bp, bx
mov %bp,%si test %al,%al
call Arg1 je 1f
and $-2,%ax call PutChar
mov %ax,%di jmp 0b
mov 2(%di),%ax 1: ret
pop %bp
ret
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
.text .text
Cadr: and $-2,%di # (object >> 1) * sizeof(word) PrintObject:
mov 2(%di),%di # contents of decrement register test $1,%di
and $-2,%di # contents of address register jnz 1f
mov (%di),%ax shr %di
lea STR(%di),%si
jmp PrintString
1: push %bx
mov %di,%bx
mov $40,%al
call PutChar
2: and $-2,%bx
mov (%bx),%di
call PrintObject
mov 2(%bx),%bx
test %bx,%bx
jz 4f
test $1,%bl
jz 3f
mov $0x20,%al
call PutChar
jmp 2b
3: mov $kDot,%si
call PrintString
mov %bx,%di
call PrintObject
4: pop %bx
mov $41,%al
/ jmp PutChar
/ 𝑠𝑙𝑖𝑑𝑒
PutChar:push %bx # don't clobber bp,bx,di,si,cx
push %bp # original ibm pc scroll up bug
mov $7,%bx # normal mda/cga style page zero
mov $0x0e,%ah # teletype output al cp437
int $0x10 # vidya service
pop %bp # preserves al
pop %bx
ret ret
Arg1: call Cadr Arg1: call Cadr
xchg %ax,%di xchg %ax,%di
jmp Eval / jmp Eval
/ 𝑠𝑙𝑖𝑑𝑒
PrintObject:
push %bp
mov %di,%bp
test $1,%di
setz %al
shr %di
test %al,%al
je 1f
add $STR,%di
pop %bp
jmp PrintString
1: mov $40,%di
call PutChar
2: mov %bp,%bx
and $-2,%bx
mov (%bx),%di
call PrintObject
mov %bp,%bx
and $-2,%bx
mov 2(%bx),%bx
mov %bx,%bp
test %bx,%bx
je 4f
test $1,%bl
je 3f
mov $0x20,%di
call PutChar
jmp 2b
3: mov $kDot,%di
call PrintString
mov %bp,%di
call PrintObject
4: mov $41,%di
pop %bp
jmp PutChar
Eval: push %bp Eval: push %bp
mov %di,%dx mov %di,%dx
@ -314,27 +311,24 @@ Eval: push %bp
mov (%bx),%ax mov (%bx),%ax
test $1,%al test $1,%al
je 1f je 1f
mov (%bx),%ax mov (%bx),%di
and $-2,%ax and $-2,%di
mov %ax,%di cmp $ATOM_LAMBDA,(%di)
mov (%di),%ax
cmp $ATOM_LAMBDA,%ax
jne EvalUndefined jne EvalUndefined
mov 2(%bx),%si mov 2(%bx),%si
mov (%bx),%di mov (%bx),%di
push %bx push %bx
call Cadr call Cadr
mov %si,%si xchg %ax,%di
mov %ax,%di
mov %bp,%dx mov %bp,%dx
call Bind call Bind
mov %ax,%bp xchg %ax,%bp
pop %bx pop %bx
mov (%bx),%bx mov (%bx),%bx
mov %bx,%di mov %bx,%di
and $-2,%di and $-2,%di
mov 2(%di),%di mov 2(%di),%di
jmp 8f jmp EvalCadrLoop
1: mov (%bx),%ax 1: mov (%bx),%ax
cmp $ATOM_COND,%ax cmp $ATOM_COND,%ax
je EvalCond je EvalCond
@ -355,7 +349,7 @@ Eval: push %bp
mov 2(%bx),%bx mov 2(%bx),%bx
mov %bx,%di mov %bx,%di
call Cadr call Cadr
mov %ax,%di xchg %ax,%di
mov %bp,%si mov %bp,%si
call Eval call Eval
mov %bp,%si mov %bp,%si
@ -365,14 +359,37 @@ Eval: push %bp
pop %dx # restore pop %dx # restore
cmp %dx,%ax cmp %dx,%ax
jmp 3f jmp 3f
EvalCdr:
mov %dx,%di
mov %bp,%si
call Arg1
and $-2,%ax
xchg %ax,%di
mov 2(%di),%ax
pop %bp
ret
EvalCond:
mov 2(%bx),%bx
and $-2,%bx
mov (%bx),%di
and $-2,%di
mov (%di),%di
mov %bp,%si
push %bx # save
call Eval
pop %bx # restore
test %ax,%ax
je EvalCond
mov (%bx),%di
jmp EvalCadrLoop
2: cmp $ATOM_CDR,%ax 2: cmp $ATOM_CDR,%ax
je EvalCdr je EvalCdr
cmp $ATOM_CONS,%ax cmp $ATOM_CONS,%ax
je EvalCons je EvalCons
cmp $ATOM_CAR,%ax cmp $ATOM_CAR,%ax
jne EvalCall jne EvalCall
mov %bp,%si
mov %dx,%di mov %dx,%di
mov %bp,%si
call Arg1 call Arg1
and $-2,%ax and $-2,%ax
xchg %ax,%di xchg %ax,%di
@ -387,78 +404,24 @@ EvalAtom:
je 9f je 9f
xor %ax,%ax xor %ax,%ax
jmp 9f jmp 9f
EvalCond:
mov 2(%bx),%bx
mov %bx,%bx
and $-2,%bx
mov (%bx),%di
push %bx # save
and $-2,%di
mov (%di),%di
mov %bp,%si
call Eval
test %ax,%ax
pop %bx # restore
je EvalCond
mov (%bx),%bx
mov %bx,%di
jmp 8f
EvalCall: EvalCall:
mov 2(%bx),%cx mov 2(%bx),%cx
mov (%bx),%bx mov (%bx),%di
mov %bx,%di
mov %bp,%si mov %bp,%si
call Assoc call Assoc
mov %cx,%si xchg %cx,%si
mov %ax,%di xchg %ax,%di
call Cons call Cons
jmp 1f jmp 1f
8: call Cadr EvalCadrLoop:
1: mov %ax,%dx call Cadr
1: xchg %ax,%dx
jmp 0b jmp 0b
EvalUndefined: EvalUndefined:
mov $UNDEFINED,%ax mov $UNDEFINED,%ax
9: pop %bp 9: pop %bp
ret ret
Intern: push %bp
xchg %di,%bx
mov $STR,%si
0: lodsb
test %al,%al
je 4f
xor %dx,%dx
1: mov %dx,%bp
mov %dx,%di
mov (%bx,%di),%cl
cmp %cl,%al
jne 3f
inc %dx
test %al,%al
jne 2f
mov %bp,%cx
sub %cx,%si
lea -STR-1(%si),%ax
jmp 6f
2: lodsb
jmp 1b
3: test %al,%al
je 0b
lodsb
jmp 3b
4: lea -1(%si),%dx
mov %dx,%di
xchg %bx,%si
0: lodsb
stosb
test %al,%al
jnz 0b
xchg %dx,%ax
sub $STR,%ax
6: shl %ax
pop %bp
ret
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
.section .rodata,"a",@progbits .section .rodata,"a",@progbits

View file

@ -42,4 +42,7 @@ _begin: push %cs # memory model cs=ds=es = 0x600
xor %dh,%dh # drive dl head zero xor %dh,%dh # drive dl head zero
mov $0x0200+v_sectors,%ax # read sectors mov $0x0200+v_sectors,%ax # read sectors
int $0x13 # disk service int $0x13 # disk service
jmp main / 𝑠𝑙𝑖𝑑𝑒
.section .yoink
nop main