mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-26 09:18:05 +11:00
Compare commits
3 Commits
496826cdc4
...
94ed01086a
Author | SHA1 | Date | |
---|---|---|---|
|
94ed01086a | ||
|
1bea45acb8 | ||
|
06d997f26a |
2
blk/001
2
blk/001
@ -10,7 +10,7 @@ MASTER INDEX
|
||||
550 TI-84+ Recipe 580 RC2014 Recipe
|
||||
620 Sega Master System Recipe
|
||||
650 AVR assembler 730 8086 assembler
|
||||
810 PC/AT Recipe
|
||||
800 8086 boot code 830 PC/AT recipe
|
||||
|
||||
|
||||
|
||||
|
1
blk/760
1
blk/760
@ -5,6 +5,7 @@
|
||||
: MOVxm, 0x8b A, SWAP <<3 0x6 OR A, A,, ;
|
||||
: MOVmr, 0x88 A, <<3 0x6 OR A, A,, ;
|
||||
: MOVmx, 0x89 A, <<3 0x6 OR A, A,, ;
|
||||
: PUSHs, <<3 0x06 OR A, ; : POPs, <<3 0x07 OR A, ;
|
||||
: SUBxi, 0x83 A, SWAP 0xe8 OR A, A, ;
|
||||
: ADDxi, 0x83 A, SWAP 0xc0 OR A, A, ;
|
||||
: JMPr, 0xff A, 7 AND 0xe0 OR A, ;
|
||||
|
16
blk/800
Normal file
16
blk/800
Normal file
@ -0,0 +1,16 @@
|
||||
8086 boot code
|
||||
|
||||
Code in the following blocks assemble into a binary that is
|
||||
suitable to plug into Core words (B350) to achieve a fully
|
||||
functional Collapse OS. It is structured in a way that is
|
||||
very similar to Z80 boot code (B280) and requires the same
|
||||
constants to be pre-declared.
|
||||
|
||||
RESERVED REGISTERS: SP is reserved for PSP, BP is for RSP and
|
||||
DX is for IP. Whenever you use these registers for another
|
||||
purpose, be sure to protect their initial value. Like with
|
||||
Z80, you can use SP freely in native code, but you have to make
|
||||
sure it goes back to its previous level before next is called.
|
||||
|
||||
|
||||
(cont.)
|
13
blk/801
Normal file
13
blk/801
Normal file
@ -0,0 +1,13 @@
|
||||
STABLE ABI: As a compatible binary, this binary follows the
|
||||
same stable ABI as its z80 counterpart.
|
||||
|
||||
PS CHECKS: Unlike z80 boot code, we don't check PS at each next
|
||||
call (we do check RS though). It is the responsibility of every
|
||||
native PSP-modifying word to call chkPS, . Also, chkPS, is a
|
||||
bit different than in z80: it is parametrizable. The idea is
|
||||
that we always call chkPS, before popping, telling the expected
|
||||
size of stack. This allows for some interesting optimization.
|
||||
For example, in SWAP, no need to pop, chkPS, then push, we can
|
||||
chkPS and then proceed to optimized swapping in PS.
|
||||
|
||||
To assemble, load blocks 805 through 820.
|
15
blk/805
Normal file
15
blk/805
Normal file
@ -0,0 +1,15 @@
|
||||
VARIABLE lblexec VARIABLE lblnext
|
||||
H@ ORG !
|
||||
JMPn, 0 A,, ( 00, main ) 0 A, ( 03, boot driveno )
|
||||
0 A,, ( 04, BOOT )
|
||||
0 A,, ( 06, uflw ) 0 A,, ( 08, LATEST )
|
||||
0 A, 0 A, 0 A,, ( unused )
|
||||
0 A, 0 A,, ( unused ) JMPn, 0 A,, ( 11, pushRS )
|
||||
JMPn, 0 A,, ( 14, popRS ) 0 A, 0 A,, ( unused )
|
||||
JMPn, 0 A,, ( 1a, next ) 0 A, 0 A,, ( unused )
|
||||
0 A, 0 A, 0 A, 0 A, ( unused )
|
||||
0 A, 0 A, 0 A, 0 A, ( unused )
|
||||
0 A, 0 A,, ( unused )
|
||||
0 A, 0 A,, 0 A, 0 A, ( unused )
|
||||
0 A, 0 A,, ( unused )
|
||||
JMPn, 0 A,, ( 33, execute ) 0 A, 0 A, 0 A, 0 A,, ( unused )
|
16
blk/806
Normal file
16
blk/806
Normal file
@ -0,0 +1,16 @@
|
||||
( BOOT DICT: There are only 3 words in the boot dict, but
|
||||
these words' offset need to be stable, so they're part of
|
||||
the "stable ABI" )
|
||||
'E' A, 'X' A, 'I' A, 'T' A, 0 A,, ( prev ) 4 A, ( len )
|
||||
H@ XCURRENT ! ( set current tip of dict, 0x42 )
|
||||
0 A, ( native )
|
||||
DX [BP] 0 MOVx[]+, BP DECx, BP DECx, ( popRS )
|
||||
;CODE NOP,
|
||||
CODE (br) ( 0x53 ) L2 BSET ( used in br? )
|
||||
DI DX MOVxx, DI [DI] MOVx[], DX DI ADDxx,
|
||||
;CODE NOP, NOP,
|
||||
CODE (?br) ( 0x67 )
|
||||
AX POPx, AX AX ORxx, JZ, L2 @ RPCs, ( False, branch )
|
||||
( True, skip next 2 bytes and don't branch )
|
||||
L1 BSET ( loop will jump here ) DX INCx, DX INCx,
|
||||
;CODE NOP, NOP, NOP, NOP, NOP,
|
15
blk/807
Normal file
15
blk/807
Normal file
@ -0,0 +1,15 @@
|
||||
CODE (loop) ( 0x80 )
|
||||
[BP] 0 INC[w]+, ( I++ )
|
||||
( Jump if I <> I' )
|
||||
AX [BP] 0 MOVx[]+, AX [BP] -2 CMPx[]+,
|
||||
JNZ, L2 @ RPCs, ( branch )
|
||||
( don't branch )
|
||||
BP 4 SUBxi, JMPs, L1 @ RPCs,
|
||||
ORG @ 0xa3 + HERE !
|
||||
CODE 2>R ( 0xa9 )
|
||||
[BP] 4 POP[w]+, [BP] 2 POP[w]+, BP 4 ADDxi,
|
||||
;CODE NOP, NOP, NOP, NOP, NOP,
|
||||
CODE (n) ( 0xbf, number literal )
|
||||
DI DX MOVxx, DI [DI] MOVx[], DI PUSHx,
|
||||
DX INCx, DX INCx,
|
||||
;CODE NOP, NOP,
|
6
blk/808
Normal file
6
blk/808
Normal file
@ -0,0 +1,6 @@
|
||||
CODE (s) ( 0xd4, string literal, see B287 )
|
||||
DI DX MOVxx, ( IP )
|
||||
AH AH XORrr, AL [DI] MOVr[], ( slen )
|
||||
DX PUSHx, DX INCx, DX AX ADDxx,
|
||||
;CODE
|
||||
( END OF STABLE ABI )
|
9
blk/809
Normal file
9
blk/809
Normal file
@ -0,0 +1,9 @@
|
||||
lblnext BSET PC 0x1d - ORG @ 0x1b + ! ( next )
|
||||
( RSP check )
|
||||
AX RS_ADDR MOVxI, BP AX CMPxx,
|
||||
IFC, ( BP < RS_ADDR )
|
||||
DI 0x06 MOVxm, JMPs, L1 FWRs ( execute )
|
||||
THEN,
|
||||
DI DX MOVxx, ( <-- IP ) DX INCx, DX INCx,
|
||||
DI [DI] MOVx[], ( wordref )
|
||||
( continue to execute ) L1 FSET
|
29
blk/810
29
blk/810
@ -1,16 +1,15 @@
|
||||
PC/AT Recipe
|
||||
lblexec BSET PC 0x36 - ORG @ 0x34 + ! ( DI -> wordref )
|
||||
AL [DI] MOVr[], DI INCx, ( PFA )
|
||||
AL AL ORrr, IFZ, DI JMPr, THEN, ( native )
|
||||
AL DECr, IFNZ, ( cell or does )
|
||||
DI PUSHx, ( push PFA )
|
||||
AL DECr, IFZ, ( cell ) JMPs, lblnext @ RPCs, THEN,
|
||||
( does, see B302 )
|
||||
DI INCx, DI INCx, DI [DI] MOVx[],
|
||||
THEN, ( continue to compiled )
|
||||
( compiled )
|
||||
BP INCx, BP INCx, [BP] 0 DX MOV[]+x, ( pushRS )
|
||||
DX DI MOVxx, DX INCx, DX INCx, ( --> IP )
|
||||
DI [DI] MOVx[],
|
||||
JMPs, lblexec @ RPCs,
|
||||
|
||||
Work in progress.
|
||||
|
||||
Register usage: SP is PSP, BP is RSP, DX is IP
|
||||
|
||||
Unlike z80 boot code, we don't check PS at each next call (we
|
||||
do check RS though). It is the responsibility of every native
|
||||
PSP-modifying word to call chkPS, . Also, chkPS, is a bit
|
||||
different than in z80: it is parametrizable. The idea is that
|
||||
we always call chkPS, before popping, telling the expected size
|
||||
of stack. This allows for some interesting optimization. For
|
||||
example, in SWAP, no need to pop, chkPS, then push, we can
|
||||
chkPS and then proceed to optimized swapping in PS.
|
||||
|
||||
811 MBR bootloader 812-829 Boot code
|
||||
|
17
blk/811
17
blk/811
@ -1,12 +1,5 @@
|
||||
H@ ORG ! 0x7c00 BIN( ! ( BIOS loads boot bin at 0x7c00 )
|
||||
JMPs, L1 FWRs ( start )
|
||||
ORG @ 0x25 + HERE ! ( bypass BPB )
|
||||
L1 FSET ( start )
|
||||
CLI, CLD, AX 0x800 MOVxI, DS AX MOVsx, ES AX MOVsx,
|
||||
SS AX MOVsx, DX PUSHx, ( will be popped by OS ) STI,
|
||||
AH 2 MOVri, DH 0 MOVri, CH 0 MOVri, CL 2 MOVri, AL 15 MOVri,
|
||||
BX 0 MOVxI, 0x13 INT, ( read sectors 2-15 of boot floppy )
|
||||
( TODO: reading 12 sectors like this probably doesn't work
|
||||
on real vintage PC/AT with floppy. Make this more robust. )
|
||||
0x800 0 JMPf,
|
||||
ORG @ 0x1fe + HERE ! 0x55 A, 0xaa A,
|
||||
lblchkPS BSET ( CX -> expected size )
|
||||
AX PS_ADDR MOVxI, AX SP SUBxx, 2 SUBAXI, ( CALL adjust )
|
||||
AX CX CMPxx,
|
||||
IFNC, ( we're good ) RETn, THEN,
|
||||
( underflow ) DI 0x06 MOVxm, JMPs, lblexec @ RPCs,
|
||||
|
24
blk/812
24
blk/812
@ -1,15 +1,9 @@
|
||||
VARIABLE lblexec VARIABLE lblnext
|
||||
H@ ORG !
|
||||
JMPn, 0 A,, ( 00, main ) 0 A, ( 03, boot driveno )
|
||||
0 A,, ( 04, BOOT )
|
||||
0 A,, ( 06, uflw ) 0 A,, ( 08, LATEST )
|
||||
0 A, 0 A, 0 A,, ( unused )
|
||||
0 A, 0 A,, ( unused ) JMPn, 0 A,, ( 11, pushRS )
|
||||
JMPn, 0 A,, ( 14, popRS ) 0 A, 0 A,, ( unused )
|
||||
JMPn, 0 A,, ( 1a, next ) 0 A, 0 A,, ( unused )
|
||||
0 A, 0 A, 0 A, 0 A, ( unused )
|
||||
0 A, 0 A, 0 A, 0 A, ( unused )
|
||||
0 A, 0 A,, ( unused )
|
||||
0 A, 0 A,, 0 A, 0 A, ( unused )
|
||||
0 A, 0 A,, ( unused )
|
||||
JMPn, 0 A,, ( 33, execute ) 0 A, 0 A, 0 A, 0 A,, ( unused )
|
||||
PC 3 - ORG @ 1+ ! ( main )
|
||||
DX POPx, ( boot drive no ) 0x03 DL MOVmr,
|
||||
SP PS_ADDR MOVxI, BP RS_ADDR MOVxI,
|
||||
DI 0x08 MOVxm, ( LATEST )
|
||||
( HERE begins at CURRENT )
|
||||
RAMSTART 0x4 ( HERE ) + DI MOVmx,
|
||||
RAMSTART 0x2 ( CURRENT ) + DI MOVmx,
|
||||
DI 0x04 ( BOOT ) MOVxm,
|
||||
JMPn, lblexec @ RPCn, ( execute )
|
||||
|
32
blk/813
32
blk/813
@ -1,16 +1,16 @@
|
||||
( BOOT DICT: There are only 3 words in the boot dict, but
|
||||
these words' offset need to be stable, so they're part of
|
||||
the "stable ABI" )
|
||||
'E' A, 'X' A, 'I' A, 'T' A, 0 A,, ( prev ) 4 A, ( len )
|
||||
H@ XCURRENT ! ( set current tip of dict, 0x42 )
|
||||
0 A, ( native )
|
||||
DX [BP] 0 MOVx[]+, BP DECx, BP DECx, ( popRS )
|
||||
;CODE NOP,
|
||||
CODE (br) ( 0x53 ) L2 BSET ( used in br? )
|
||||
DI DX MOVxx, DI [DI] MOVx[], DX DI ADDxx,
|
||||
;CODE NOP, NOP,
|
||||
CODE (?br) ( 0x67 )
|
||||
AX POPx, AX AX ORxx, JZ, L2 @ RPCs, ( False, branch )
|
||||
( True, skip next 2 bytes and don't branch )
|
||||
L1 BSET ( loop will jump here ) DX INCx, DX INCx,
|
||||
;CODE NOP, NOP, NOP, NOP, NOP,
|
||||
( native words )
|
||||
CODE EXECUTE 1 chkPS,
|
||||
DI POPx, JMPn, lblexec @ RPCn,
|
||||
CODE >R 1 chkPS,
|
||||
BP INCx, BP INCx, [BP] 0 POP[w]+,
|
||||
;CODE NOP, NOP, NOP,
|
||||
CODE R>
|
||||
[BP] 0 PUSH[w]+, BP DECx, BP DECx,
|
||||
;CODE
|
||||
CODE 2R> 2 chkPS,
|
||||
[BP] -2 PUSH[w]+, [BP] 0 PUSH[w]+, BP 4 SUBxi,
|
||||
;CODE
|
||||
CODE ROT ( a b c -- b c a ) 3 chkPS,
|
||||
CX POPx, BX POPx, AX POPx,
|
||||
BX PUSHx, CX PUSHx, AX PUSHx,
|
||||
;CODE
|
||||
|
27
blk/814
27
blk/814
@ -1,15 +1,12 @@
|
||||
CODE (loop) ( 0x80 )
|
||||
[BP] 0 INC[w]+, ( I++ )
|
||||
( Jump if I <> I' )
|
||||
AX [BP] 0 MOVx[]+, AX [BP] -2 CMPx[]+,
|
||||
JNZ, L2 @ RPCs, ( branch )
|
||||
( don't branch )
|
||||
BP 4 SUBxi, JMPs, L1 @ RPCs,
|
||||
ORG @ 0xa3 + HERE !
|
||||
CODE 2>R ( 0xa9 )
|
||||
[BP] 4 POP[w]+, [BP] 2 POP[w]+, BP 4 ADDxi,
|
||||
;CODE NOP, NOP, NOP, NOP, NOP,
|
||||
CODE (n) ( 0xbf, number literal )
|
||||
DI DX MOVxx, DI [DI] MOVx[], DI PUSHx,
|
||||
DX INCx, DX INCx,
|
||||
;CODE NOP, NOP,
|
||||
CODE DUP 1 chkPS, AX POPx, AX PUSHx, AX PUSHx, ;CODE
|
||||
CODE ?DUP 1 chkPS, AX POPx, AX AX ORxx, AX PUSHx,
|
||||
IFNZ, AX PUSHx, THEN, ;CODE
|
||||
CODE DROP 1 chkPS, AX POPx, ;CODE
|
||||
CODE SWAP AX POPx, BX POPx, AX PUSHx, BX PUSHx, ;CODE
|
||||
CODE OVER ( a b -- a b a ) 2 chkPS,
|
||||
DI SP MOVxx, AX [DI] 2 MOVx[]+, AX PUSHx, ;CODE
|
||||
CODE PICK
|
||||
DI POPx, DI SHLx1, ( x2 )
|
||||
CX DI MOVxx, CX 2 ADDxi, CALLn, lblchkPS @ RPCn,
|
||||
DI SP ADDxx, DI [DI] MOVx[], DI PUSHx,
|
||||
;CODE
|
||||
|
20
blk/815
20
blk/815
@ -1,6 +1,16 @@
|
||||
CODE (s) ( 0xd4, string literal, see B287 )
|
||||
DI DX MOVxx, ( IP )
|
||||
AH AH XORrr, AL [DI] MOVr[], ( slen )
|
||||
DX PUSHx, DX INCx, DX AX ADDxx,
|
||||
CODE (roll) ( "2 3 4 5 4 --> 2 4 5 5". See B311 )
|
||||
CX POPx, CX 2 ADDxi, CALLn, lblchkPS @ RPCn, CX 2 SUBxi,
|
||||
SI SP MOVxx, SI CX ADDxx,
|
||||
DI SI MOVxx, DI 2 ADDxi, STD, REPZ, MOVSB,
|
||||
;CODE
|
||||
( END OF STABLE ABI )
|
||||
CODE 2DROP 2 chkPS, SP 4 ADDxi, ;CODE
|
||||
CODE 2DUP 2 chkPS,
|
||||
AX POPx, BX POPx,
|
||||
BX PUSHx, AX PUSHx, BX PUSHx, AX PUSHx,
|
||||
;CODE
|
||||
CODE S0 AX PS_ADDR MOVxI, AX PUSHx, ;CODE
|
||||
CODE 'S SP PUSHx, ;CODE
|
||||
CODE AND 2 chkPS,
|
||||
AX POPx, BX POPx, AX BX ANDxx, AX PUSHx, ;CODE
|
||||
CODE OR 2 chkPS,
|
||||
AX POPx, BX POPx, AX BX ORxx, AX PUSHx, ;CODE
|
||||
|
24
blk/816
24
blk/816
@ -1,9 +1,15 @@
|
||||
lblnext BSET PC 0x1d - ORG @ 0x1b + ! ( next )
|
||||
( RSP check )
|
||||
AX RS_ADDR MOVxI, BP AX CMPxx,
|
||||
IFC, ( BP < RS_ADDR )
|
||||
DI 0x06 MOVxm, JMPs, L1 FWRs ( execute )
|
||||
THEN,
|
||||
DI DX MOVxx, ( <-- IP ) DX INCx, DX INCx,
|
||||
DI [DI] MOVx[], ( wordref )
|
||||
( continue to execute ) L1 FSET
|
||||
CODE XOR 2 chkPS,
|
||||
AX POPx, BX POPx, AX BX XORxx, AX PUSHx, ;CODE
|
||||
CODE NOT 1 chkPS,
|
||||
AX POPx, AX AX ORxx,
|
||||
IFNZ, AX -1 MOVxI, THEN, AX INCx, AX PUSHx,
|
||||
;CODE
|
||||
CODE + 2 chkPS,
|
||||
AX POPx, BX POPx, AX BX ADDxx, AX PUSHx, ;CODE
|
||||
CODE - 2 chkPS,
|
||||
BX POPx, AX POPx, AX BX SUBxx, AX PUSHx, ;CODE
|
||||
CODE * 2 chkPS,
|
||||
AX POPx, BX POPx,
|
||||
DX PUSHx, ( protect from MUL ) BX MULx, DX POPx,
|
||||
AX PUSHx,
|
||||
;CODE
|
||||
|
31
blk/817
31
blk/817
@ -1,15 +1,16 @@
|
||||
lblexec BSET PC 0x36 - ORG @ 0x34 + ! ( DI -> wordref )
|
||||
AL [DI] MOVr[], DI INCx, ( PFA )
|
||||
AL AL ORrr, IFZ, DI JMPr, THEN, ( native )
|
||||
AL DECr, IFNZ, ( cell or does )
|
||||
DI PUSHx, ( push PFA )
|
||||
AL DECr, IFZ, ( cell ) JMPs, lblnext @ RPCs, THEN,
|
||||
( does, see B302 )
|
||||
DI INCx, DI INCx, DI [DI] MOVx[],
|
||||
THEN, ( continue to compiled )
|
||||
( compiled )
|
||||
BP INCx, BP INCx, [BP] 0 DX MOV[]+x, ( pushRS )
|
||||
DX DI MOVxx, DX INCx, DX INCx, ( --> IP )
|
||||
DI [DI] MOVx[],
|
||||
JMPs, lblexec @ RPCs,
|
||||
|
||||
CODE /MOD 2 chkPS,
|
||||
BX POPx, AX POPx, DX PUSHx, ( protect )
|
||||
DX DX XORxx, BX DIVx,
|
||||
BX DX MOVxx, DX POPx, ( unprotect )
|
||||
BX PUSHx, ( modulo ) AX PUSHx, ( division )
|
||||
;CODE
|
||||
CODE ! 2 chkPS, DI POPx, AX POPx, [DI] AX MOV[]x, ;CODE
|
||||
CODE @ 1 chkPS, DI POPx, AX [DI] MOVx[], AX PUSHx, ;CODE
|
||||
CODE C! 2 chkPS, DI POPx, AX POPx, [DI] AX MOV[]r, ;CODE
|
||||
CODE C@ 1 chkPS,
|
||||
DI POPx, AH AH XORrr, AL [DI] MOVr[], AX PUSHx, ;CODE
|
||||
CODE I [BP] 0 PUSH[w]+, ;CODE
|
||||
CODE I' [BP] -2 PUSH[w]+, ;CODE
|
||||
CODE J [BP] -4 PUSH[w]+, ;CODE
|
||||
CODE (resSP) SP PS_ADDR MOVxI, ;CODE
|
||||
CODE (resRS) BP RS_ADDR MOVxI, ;CODE
|
||||
|
21
blk/818
21
blk/818
@ -1,5 +1,16 @@
|
||||
lblchkPS BSET ( CX -> expected size )
|
||||
AX PS_ADDR MOVxI, AX SP SUBxx, 2 SUBAXI, ( CALL adjust )
|
||||
AX CX CMPxx,
|
||||
IFNC, ( we're good ) RETn, THEN,
|
||||
( underflow ) DI 0x06 MOVxm, JMPs, lblexec @ RPCs,
|
||||
CODE BYE BEGIN, JMPs, AGAIN, ;CODE
|
||||
CODE S= 2 chkPS,
|
||||
SI POPx, DI POPx, CH CH XORrr, CL [SI] MOVr[],
|
||||
CL [DI] CMPr[],
|
||||
IFZ, ( same size? )
|
||||
SI INCx, DI INCx, CLD, REPZ, CMPSB,
|
||||
THEN,
|
||||
PUSHZ,
|
||||
;CODE
|
||||
CODE CMP 2 chkPS,
|
||||
BX POPx, AX POPx, CX CX XORxx, AX BX CMPxx,
|
||||
IFNZ, ( < or > )
|
||||
CX INCx, IFC, ( < ) CX DECx, CX DECx, THEN,
|
||||
THEN,
|
||||
CX PUSHx,
|
||||
;CODE
|
||||
|
9
blk/821
9
blk/821
@ -1,9 +0,0 @@
|
||||
PC 3 - ORG @ 1+ ! ( main )
|
||||
DX POPx, ( boot drive no ) 0x03 DL MOVmr,
|
||||
SP PS_ADDR MOVxI, BP RS_ADDR MOVxI,
|
||||
DI 0x08 MOVxm, ( LATEST )
|
||||
( HERE begins at CURRENT )
|
||||
RAMSTART 0x4 ( HERE ) + DI MOVmx,
|
||||
RAMSTART 0x2 ( CURRENT ) + DI MOVmx,
|
||||
DI 0x04 ( BOOT ) MOVxm,
|
||||
JMPn, lblexec @ RPCn, ( execute )
|
16
blk/822
16
blk/822
@ -1,16 +0,0 @@
|
||||
( native words )
|
||||
CODE EXECUTE 1 chkPS,
|
||||
DI POPx, JMPn, lblexec @ RPCn,
|
||||
CODE >R 1 chkPS,
|
||||
BP INCx, BP INCx, [BP] 0 POP[w]+,
|
||||
;CODE NOP, NOP, NOP,
|
||||
CODE R>
|
||||
[BP] 0 PUSH[w]+, BP DECx, BP DECx,
|
||||
;CODE
|
||||
CODE 2R> 2 chkPS,
|
||||
[BP] -2 PUSH[w]+, [BP] 0 PUSH[w]+, BP 4 SUBxi,
|
||||
;CODE
|
||||
CODE ROT ( a b c -- b c a ) 3 chkPS,
|
||||
CX POPx, BX POPx, AX POPx,
|
||||
BX PUSHx, CX PUSHx, AX PUSHx,
|
||||
;CODE
|
12
blk/823
12
blk/823
@ -1,12 +0,0 @@
|
||||
CODE DUP 1 chkPS, AX POPx, AX PUSHx, AX PUSHx, ;CODE
|
||||
CODE ?DUP 1 chkPS, AX POPx, AX AX ORxx, AX PUSHx,
|
||||
IFNZ, AX PUSHx, THEN, ;CODE
|
||||
CODE DROP 1 chkPS, AX POPx, ;CODE
|
||||
CODE SWAP AX POPx, BX POPx, AX PUSHx, BX PUSHx, ;CODE
|
||||
CODE OVER ( a b -- a b a ) 2 chkPS,
|
||||
DI SP MOVxx, AX [DI] 2 MOVx[]+, AX PUSHx, ;CODE
|
||||
CODE PICK
|
||||
DI POPx, DI SHLx1, ( x2 )
|
||||
CX DI MOVxx, CX 2 ADDxi, CALLn, lblchkPS @ RPCn,
|
||||
DI SP ADDxx, DI [DI] MOVx[], DI PUSHx,
|
||||
;CODE
|
16
blk/824
16
blk/824
@ -1,16 +0,0 @@
|
||||
CODE (roll) ( "2 3 4 5 4 --> 2 4 5 5". See B311 )
|
||||
CX POPx, CX 2 ADDxi, CALLn, lblchkPS @ RPCn, CX 2 SUBxi,
|
||||
SI SP MOVxx, SI CX ADDxx,
|
||||
DI SI MOVxx, DI 2 ADDxi, STD, REPZ, MOVSB,
|
||||
;CODE
|
||||
CODE 2DROP 2 chkPS, SP 4 ADDxi, ;CODE
|
||||
CODE 2DUP 2 chkPS,
|
||||
AX POPx, BX POPx,
|
||||
BX PUSHx, AX PUSHx, BX PUSHx, AX PUSHx,
|
||||
;CODE
|
||||
CODE S0 AX PS_ADDR MOVxI, AX PUSHx, ;CODE
|
||||
CODE 'S SP PUSHx, ;CODE
|
||||
CODE AND 2 chkPS,
|
||||
AX POPx, BX POPx, AX BX ANDxx, AX PUSHx, ;CODE
|
||||
CODE OR 2 chkPS,
|
||||
AX POPx, BX POPx, AX BX ORxx, AX PUSHx, ;CODE
|
15
blk/825
15
blk/825
@ -1,15 +0,0 @@
|
||||
CODE XOR 2 chkPS,
|
||||
AX POPx, BX POPx, AX BX XORxx, AX PUSHx, ;CODE
|
||||
CODE NOT 1 chkPS,
|
||||
AX POPx, AX AX ORxx,
|
||||
IFNZ, AX -1 MOVxI, THEN, AX INCx, AX PUSHx,
|
||||
;CODE
|
||||
CODE + 2 chkPS,
|
||||
AX POPx, BX POPx, AX BX ADDxx, AX PUSHx, ;CODE
|
||||
CODE - 2 chkPS,
|
||||
BX POPx, AX POPx, AX BX SUBxx, AX PUSHx, ;CODE
|
||||
CODE * 2 chkPS,
|
||||
AX POPx, BX POPx,
|
||||
DX PUSHx, ( protect from MUL ) BX MULx, DX POPx,
|
||||
AX PUSHx,
|
||||
;CODE
|
16
blk/826
16
blk/826
@ -1,16 +0,0 @@
|
||||
CODE /MOD 2 chkPS,
|
||||
BX POPx, AX POPx, DX PUSHx, ( protect )
|
||||
DX DX XORxx, BX DIVx,
|
||||
BX DX MOVxx, DX POPx, ( unprotect )
|
||||
BX PUSHx, ( modulo ) AX PUSHx, ( division )
|
||||
;CODE
|
||||
CODE ! 2 chkPS, DI POPx, AX POPx, [DI] AX MOV[]x, ;CODE
|
||||
CODE @ 1 chkPS, DI POPx, AX [DI] MOVx[], AX PUSHx, ;CODE
|
||||
CODE C! 2 chkPS, DI POPx, AX POPx, [DI] AX MOV[]r, ;CODE
|
||||
CODE C@ 1 chkPS,
|
||||
DI POPx, AH AH XORrr, AL [DI] MOVr[], AX PUSHx, ;CODE
|
||||
CODE I [BP] 0 PUSH[w]+, ;CODE
|
||||
CODE I' [BP] -2 PUSH[w]+, ;CODE
|
||||
CODE J [BP] -4 PUSH[w]+, ;CODE
|
||||
CODE (resSP) SP PS_ADDR MOVxI, ;CODE
|
||||
CODE (resRS) BP RS_ADDR MOVxI, ;CODE
|
16
blk/827
16
blk/827
@ -1,16 +0,0 @@
|
||||
CODE BYE BEGIN, JMPs, AGAIN, ;CODE
|
||||
CODE S= 2 chkPS,
|
||||
SI POPx, DI POPx, CH CH XORrr, CL [SI] MOVr[],
|
||||
CL [DI] CMPr[],
|
||||
IFZ, ( same size? )
|
||||
SI INCx, DI INCx, CLD, REPZ, CMPSB,
|
||||
THEN,
|
||||
PUSHZ,
|
||||
;CODE
|
||||
CODE CMP 2 chkPS,
|
||||
BX POPx, AX POPx, CX CX XORxx, AX BX CMPxx,
|
||||
IFNZ, ( < or > )
|
||||
CX INCx, IFC, ( < ) CX DECx, CX DECx, THEN,
|
||||
THEN,
|
||||
CX PUSHx,
|
||||
;CODE
|
5
blk/830
Normal file
5
blk/830
Normal file
@ -0,0 +1,5 @@
|
||||
PC/AT recipe
|
||||
|
||||
832 MBR bootloader 834 KEY/EMIT drivers
|
||||
836-838 BLK drivers 840 AT-XY drivers
|
||||
842 xcomp unit
|
12
blk/832
Normal file
12
blk/832
Normal file
@ -0,0 +1,12 @@
|
||||
H@ ORG ! 0x7c00 BIN( ! ( BIOS loads boot bin at 0x7c00 )
|
||||
JMPs, L1 FWRs ( start )
|
||||
ORG @ 0x25 + HERE ! ( bypass BPB )
|
||||
L1 FSET ( start )
|
||||
CLI, CLD, AX 0x800 MOVxI, DS AX MOVsx, ES AX MOVsx,
|
||||
SS AX MOVsx, DX PUSHx, ( will be popped by OS ) STI,
|
||||
AH 2 MOVri, DH 0 MOVri, CH 0 MOVri, CL 2 MOVri, AL 15 MOVri,
|
||||
BX 0 MOVxI, 0x13 INT, ( read sectors 2-15 of boot floppy )
|
||||
( TODO: reading 12 sectors like this probably doesn't work
|
||||
on real vintage PC/AT with floppy. Make this more robust. )
|
||||
0x800 0 JMPf,
|
||||
ORG @ 0x1fe + HERE ! 0x55 A, 0xaa A,
|
6
blk/834
Normal file
6
blk/834
Normal file
@ -0,0 +1,6 @@
|
||||
CODE (emit) 1 chkPS,
|
||||
AX POPx, AH 0x0e MOVri, ( print char ) 0x10 INT,
|
||||
;CODE
|
||||
CODE (key)
|
||||
AH AH XORrr, 0x16 INT, AH AH XORrr, AX PUSHx,
|
||||
;CODE
|
14
blk/836
Normal file
14
blk/836
Normal file
@ -0,0 +1,14 @@
|
||||
CODE 13H08H ( driveno -- cx dx )
|
||||
DI POPx, DX PUSHx, ( protect ) DX DI MOVxx, AX 0x800 MOVxI,
|
||||
ES PUSHs, DI DI XORxx, ES DI MOVsx,
|
||||
0x13 INT, DI DX MOVxx, ES POPs, DX POPx, ( unprotect )
|
||||
CX PUSHx, DI PUSHx,
|
||||
;CODE
|
||||
CODE 13H ( ax bx cx dx -- ax bx cx dx )
|
||||
SI POPx, ( DX ) CX POPx, BX POPx, AX POPx,
|
||||
DX PUSHx, ( protect ) DX SI MOVxx, DI DI XORxx,
|
||||
0x13 INT, SI DX MOVxx, DX POPx, ( unprotect )
|
||||
AX PUSHx, BX PUSHx, CX PUSHx, SI PUSHx,
|
||||
;CODE
|
||||
: FDSPT 0x70 RAM+ ;
|
||||
: FDHEADS 0x71 RAM+ ;
|
10
blk/837
Normal file
10
blk/837
Normal file
@ -0,0 +1,10 @@
|
||||
: _ ( AX BX sec )
|
||||
( AH=read sectors, AL=1 sector, BX=dest,
|
||||
CH=trackno CL=secno DH=head DL=drive )
|
||||
FDSPT C@ /MOD ( AX BX sec trk )
|
||||
FDHEADS C@ /MOD ( AX BX sec head trk )
|
||||
8 LSHIFT ROT OR 1+ ( AX BX head CX )
|
||||
SWAP 8 LSHIFT 0x03 C@ ( boot drive ) OR ( AX BX CX DX )
|
||||
13H 2DROP 2DROP
|
||||
;
|
||||
|
14
blk/838
Normal file
14
blk/838
Normal file
@ -0,0 +1,14 @@
|
||||
: FD@
|
||||
2 * 16 + ( blkfs starts at sector 16 )
|
||||
0x0201 BLK( 2 PICK _
|
||||
0x0201 BLK( 0x200 + ROT 1+ _ ;
|
||||
: FD!
|
||||
2 * 16 + ( blkfs starts at sector 16 )
|
||||
0x0301 BLK( 2 PICK _
|
||||
0x0301 BLK( 0x200 + ROT 1+ _ ;
|
||||
: FD$
|
||||
( get number of sectors per track with command 08H. )
|
||||
0x03 ( boot drive ) C@ 13H08H
|
||||
8 RSHIFT 1+ FDHEADS C!
|
||||
0x3f AND FDSPT C!
|
||||
;
|
8
blk/840
Normal file
8
blk/840
Normal file
@ -0,0 +1,8 @@
|
||||
: COLS 80 ; : LINES 25 ;
|
||||
CODE AT-XY ( x y )
|
||||
( DH=row DL=col BH=page )
|
||||
AX POPx, BX POPx, DX PUSHx, ( protect )
|
||||
DH AL MOVrr, DL BL MOVrr, BX BX XORxx, AH 2 MOVri,
|
||||
0x10 INT, DX POPx, ( unprotect )
|
||||
;CODE
|
||||
|
13
blk/842
Normal file
13
blk/842
Normal file
@ -0,0 +1,13 @@
|
||||
0xff00 CONSTANT RS_ADDR
|
||||
0xfffa CONSTANT PS_ADDR
|
||||
RS_ADDR 0x80 - CONSTANT RAMSTART
|
||||
750 LOAD ( 8086 asm )
|
||||
262 LOAD ( xcomp ) 270 LOAD ( xcomp overrides )
|
||||
805 820 LOADR
|
||||
353 LOAD ( xcomp core low )
|
||||
834 LOAD ( KEY/EMIT drivers )
|
||||
836 838 LOADR ( BLK drivers )
|
||||
840 LOAD ( AT-XY drivers )
|
||||
380 LOAD ( xcomp core high )
|
||||
(entry) _ ( Update LATEST ) PC ORG @ 8 + !
|
||||
," BLK$ FD$ ' FD@ BLK@* ! ' FD! BLK!* ! " EOT,
|
@ -1,3 +1,48 @@
|
||||
# PC/AT recipe
|
||||
# PC/AT
|
||||
|
||||
Work in progress.
|
||||
PC-compatible machines need no introduction. They are one of the most popular
|
||||
machines of all time. Collapse OS has a 8086 assembler and has boot code
|
||||
allowing it to run on a PC/AT-compatible machine, using BIOS interrupts in
|
||||
real mode. Collapse OS always runs in real mode.
|
||||
|
||||
In this recipe, we will compile Collapse OS and write it to a USB drive that
|
||||
is bootable on a modern PC-compatible machine.
|
||||
|
||||
## Gathering parts
|
||||
|
||||
* A modern PC-compatible machine that can boot from a USB drive.
|
||||
* A USB drive
|
||||
* qemu for emulation
|
||||
|
||||
## Build the binary
|
||||
|
||||
Running `make` in this folder with yield:
|
||||
|
||||
* mbr.bin: a 512 byte binary that goes at the beginning of the disk
|
||||
* os.bin: 8086 Collapse OS binary
|
||||
* disk.bin: a concatenation of the above, with `blkfs` appended to it starting at
|
||||
`0x2000`.
|
||||
|
||||
`disk.bin` is what goes on the drive.
|
||||
|
||||
This binary has `BLK` and `AT-XY` support, which means you have disk I/Os and
|
||||
can run `VE`.
|
||||
|
||||
## Emulation
|
||||
|
||||
You can run the built binary in qemu using `make emul`.
|
||||
|
||||
## Running on a modern PC
|
||||
|
||||
First, copy `disk.bin` onto your USB drive. For example, on an OpenBSD machine,
|
||||
it could look like:
|
||||
|
||||
doas dd if=disk.bin of=/dev/sd1c
|
||||
|
||||
Your USB drive is now BIOS-bootable. Boot your computer and enter your BIOS
|
||||
setup to make sure that "legacy boot" (non-EFI boot, that is, BIOS boot) is
|
||||
enabled. Configure your boot device priority to ensure that the USB drive has
|
||||
a chance to boot.
|
||||
|
||||
Reboot, you have Collapse OS. Boot is of course instantaneous (we're not used
|
||||
to this with modern software...).
|
||||
|
@ -1,4 +1,4 @@
|
||||
750 LOAD
|
||||
811 LOAD
|
||||
832 LOAD
|
||||
ORG @ 256 /MOD 2 PC! 2 PC!
|
||||
H@ 256 /MOD 2 PC! 2 PC!
|
||||
|
@ -1,69 +1,3 @@
|
||||
0xff00 CONSTANT RS_ADDR
|
||||
0xfffa CONSTANT PS_ADDR
|
||||
RS_ADDR 0x80 - CONSTANT RAMSTART
|
||||
750 LOAD ( 8086 asm )
|
||||
262 LOAD ( xcomp )
|
||||
270 LOAD ( xcomp overrides )
|
||||
812 829 LOADR
|
||||
353 LOAD ( xcomp core low )
|
||||
CODE (emit) 1 chkPS,
|
||||
AX POPx, AH 0x0e MOVri, ( print char ) 0x10 INT,
|
||||
;CODE
|
||||
CODE (key)
|
||||
AH AH XORrr, 0x16 INT, AH AH XORrr, AX PUSHx,
|
||||
;CODE
|
||||
CODE 13H08H ( driveno -- cx dx )
|
||||
DI POPx, DX PUSHx, ( protect ) DX DI MOVxx, AX 0x800 MOVxI,
|
||||
DI DI XORxx, ES DI MOVsx,
|
||||
0x13 INT, DI DX MOVxx, DX POPx, ( unprotect )
|
||||
CX PUSHx, DI PUSHx,
|
||||
DI 0x800 MOVxI, ES DI MOVsx,
|
||||
;CODE
|
||||
CODE 13H ( ax bx cx dx -- ax bx cx dx )
|
||||
SI POPx, ( DX ) CX POPx, BX POPx, AX POPx,
|
||||
DX PUSHx, ( protect ) DX SI MOVxx, DI DI XORxx,
|
||||
0x13 INT, SI DX MOVxx, DX POPx, ( unprotect )
|
||||
AX PUSHx, BX PUSHx, CX PUSHx, SI PUSHx,
|
||||
;CODE
|
||||
: FDSPT 0x70 RAM+ ;
|
||||
: FDHEADS 0x71 RAM+ ;
|
||||
: _ ( AX BX sec )
|
||||
( AH=read sectors, AL=1 sector, BX=dest,
|
||||
CH=trackno CL=secno DH=head DL=drive )
|
||||
FDSPT C@ /MOD ( AX BX sec trk )
|
||||
FDHEADS C@ /MOD ( AX BX sec head trk )
|
||||
8 LSHIFT ROT OR 1+ ( AX BX head CX )
|
||||
SWAP 8 LSHIFT 0x03 C@ ( boot drive ) OR ( AX BX CX DX )
|
||||
13H 2DROP 2DROP
|
||||
;
|
||||
: FD@
|
||||
2 * 16 + ( blkfs starts at sector 16 )
|
||||
0x0201 BLK( 2 PICK _
|
||||
0x0201 BLK( 0x200 + ROT 1+ _ ;
|
||||
: FD!
|
||||
2 * 16 + ( blkfs starts at sector 16 )
|
||||
0x0301 BLK( 2 PICK _
|
||||
0x0301 BLK( 0x200 + ROT 1+ _ ;
|
||||
: FD$
|
||||
( get number of sectors per track with command 08H. )
|
||||
0x03 ( boot drive ) C@ 13H08H
|
||||
8 RSHIFT 1+ FDHEADS C!
|
||||
0x3f AND FDSPT C!
|
||||
;
|
||||
: COLS 80 ; : LINES 25 ;
|
||||
CODE AT-XY ( x y )
|
||||
( DH=row DL=col BH=page )
|
||||
AX POPx, BX POPx, DX PUSHx, ( protect )
|
||||
DH AL MOVrr, DL BL MOVrr, BX BX XORxx, AH 2 MOVri,
|
||||
0x10 INT, DX POPx, ( unprotect )
|
||||
;CODE
|
||||
380 LOAD ( xcomp core high )
|
||||
(entry) _
|
||||
( Update LATEST )
|
||||
PC ORG @ 8 + !
|
||||
," BLK$ FD$ "
|
||||
," ' FD@ BLK@* ! "
|
||||
," ' FD! BLK!* ! "
|
||||
EOT,
|
||||
842 LOAD ( PC/AT xcomp )
|
||||
ORG @ 256 /MOD 2 PC! 2 PC!
|
||||
H@ 256 /MOD 2 PC! 2 PC!
|
||||
|
Loading…
Reference in New Issue
Block a user