mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-26 13:28:06 +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
|
550 TI-84+ Recipe 580 RC2014 Recipe
|
||||||
620 Sega Master System Recipe
|
620 Sega Master System Recipe
|
||||||
650 AVR assembler 730 8086 assembler
|
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,, ;
|
: MOVxm, 0x8b A, SWAP <<3 0x6 OR A, A,, ;
|
||||||
: MOVmr, 0x88 A, <<3 0x6 OR A, A,, ;
|
: MOVmr, 0x88 A, <<3 0x6 OR A, A,, ;
|
||||||
: MOVmx, 0x89 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, ;
|
: SUBxi, 0x83 A, SWAP 0xe8 OR A, A, ;
|
||||||
: ADDxi, 0x83 A, SWAP 0xc0 OR A, A, ;
|
: ADDxi, 0x83 A, SWAP 0xc0 OR A, A, ;
|
||||||
: JMPr, 0xff A, 7 AND 0xe0 OR 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 )
|
lblchkPS BSET ( CX -> expected size )
|
||||||
JMPs, L1 FWRs ( start )
|
AX PS_ADDR MOVxI, AX SP SUBxx, 2 SUBAXI, ( CALL adjust )
|
||||||
ORG @ 0x25 + HERE ! ( bypass BPB )
|
AX CX CMPxx,
|
||||||
L1 FSET ( start )
|
IFNC, ( we're good ) RETn, THEN,
|
||||||
CLI, CLD, AX 0x800 MOVxI, DS AX MOVsx, ES AX MOVsx,
|
( underflow ) DI 0x06 MOVxm, JMPs, lblexec @ RPCs,
|
||||||
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,
|
|
||||||
|
24
blk/812
24
blk/812
@ -1,15 +1,9 @@
|
|||||||
VARIABLE lblexec VARIABLE lblnext
|
PC 3 - ORG @ 1+ ! ( main )
|
||||||
H@ ORG !
|
DX POPx, ( boot drive no ) 0x03 DL MOVmr,
|
||||||
JMPn, 0 A,, ( 00, main ) 0 A, ( 03, boot driveno )
|
SP PS_ADDR MOVxI, BP RS_ADDR MOVxI,
|
||||||
0 A,, ( 04, BOOT )
|
DI 0x08 MOVxm, ( LATEST )
|
||||||
0 A,, ( 06, uflw ) 0 A,, ( 08, LATEST )
|
( HERE begins at CURRENT )
|
||||||
0 A, 0 A, 0 A,, ( unused )
|
RAMSTART 0x4 ( HERE ) + DI MOVmx,
|
||||||
0 A, 0 A,, ( unused ) JMPn, 0 A,, ( 11, pushRS )
|
RAMSTART 0x2 ( CURRENT ) + DI MOVmx,
|
||||||
JMPn, 0 A,, ( 14, popRS ) 0 A, 0 A,, ( unused )
|
DI 0x04 ( BOOT ) MOVxm,
|
||||||
JMPn, 0 A,, ( 1a, next ) 0 A, 0 A,, ( unused )
|
JMPn, lblexec @ RPCn, ( execute )
|
||||||
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 )
|
|
||||||
|
32
blk/813
32
blk/813
@ -1,16 +1,16 @@
|
|||||||
( BOOT DICT: There are only 3 words in the boot dict, but
|
( native words )
|
||||||
these words' offset need to be stable, so they're part of
|
CODE EXECUTE 1 chkPS,
|
||||||
the "stable ABI" )
|
DI POPx, JMPn, lblexec @ RPCn,
|
||||||
'E' A, 'X' A, 'I' A, 'T' A, 0 A,, ( prev ) 4 A, ( len )
|
CODE >R 1 chkPS,
|
||||||
H@ XCURRENT ! ( set current tip of dict, 0x42 )
|
BP INCx, BP INCx, [BP] 0 POP[w]+,
|
||||||
0 A, ( native )
|
;CODE NOP, NOP, NOP,
|
||||||
DX [BP] 0 MOVx[]+, BP DECx, BP DECx, ( popRS )
|
CODE R>
|
||||||
;CODE NOP,
|
[BP] 0 PUSH[w]+, BP DECx, BP DECx,
|
||||||
CODE (br) ( 0x53 ) L2 BSET ( used in br? )
|
;CODE
|
||||||
DI DX MOVxx, DI [DI] MOVx[], DX DI ADDxx,
|
CODE 2R> 2 chkPS,
|
||||||
;CODE NOP, NOP,
|
[BP] -2 PUSH[w]+, [BP] 0 PUSH[w]+, BP 4 SUBxi,
|
||||||
CODE (?br) ( 0x67 )
|
;CODE
|
||||||
AX POPx, AX AX ORxx, JZ, L2 @ RPCs, ( False, branch )
|
CODE ROT ( a b c -- b c a ) 3 chkPS,
|
||||||
( True, skip next 2 bytes and don't branch )
|
CX POPx, BX POPx, AX POPx,
|
||||||
L1 BSET ( loop will jump here ) DX INCx, DX INCx,
|
BX PUSHx, CX PUSHx, AX PUSHx,
|
||||||
;CODE NOP, NOP, NOP, NOP, NOP,
|
;CODE
|
||||||
|
27
blk/814
27
blk/814
@ -1,15 +1,12 @@
|
|||||||
CODE (loop) ( 0x80 )
|
CODE DUP 1 chkPS, AX POPx, AX PUSHx, AX PUSHx, ;CODE
|
||||||
[BP] 0 INC[w]+, ( I++ )
|
CODE ?DUP 1 chkPS, AX POPx, AX AX ORxx, AX PUSHx,
|
||||||
( Jump if I <> I' )
|
IFNZ, AX PUSHx, THEN, ;CODE
|
||||||
AX [BP] 0 MOVx[]+, AX [BP] -2 CMPx[]+,
|
CODE DROP 1 chkPS, AX POPx, ;CODE
|
||||||
JNZ, L2 @ RPCs, ( branch )
|
CODE SWAP AX POPx, BX POPx, AX PUSHx, BX PUSHx, ;CODE
|
||||||
( don't branch )
|
CODE OVER ( a b -- a b a ) 2 chkPS,
|
||||||
BP 4 SUBxi, JMPs, L1 @ RPCs,
|
DI SP MOVxx, AX [DI] 2 MOVx[]+, AX PUSHx, ;CODE
|
||||||
ORG @ 0xa3 + HERE !
|
CODE PICK
|
||||||
CODE 2>R ( 0xa9 )
|
DI POPx, DI SHLx1, ( x2 )
|
||||||
[BP] 4 POP[w]+, [BP] 2 POP[w]+, BP 4 ADDxi,
|
CX DI MOVxx, CX 2 ADDxi, CALLn, lblchkPS @ RPCn,
|
||||||
;CODE NOP, NOP, NOP, NOP, NOP,
|
DI SP ADDxx, DI [DI] MOVx[], DI PUSHx,
|
||||||
CODE (n) ( 0xbf, number literal )
|
;CODE
|
||||||
DI DX MOVxx, DI [DI] MOVx[], DI PUSHx,
|
|
||||||
DX INCx, DX INCx,
|
|
||||||
;CODE NOP, NOP,
|
|
||||||
|
20
blk/815
20
blk/815
@ -1,6 +1,16 @@
|
|||||||
CODE (s) ( 0xd4, string literal, see B287 )
|
CODE (roll) ( "2 3 4 5 4 --> 2 4 5 5". See B311 )
|
||||||
DI DX MOVxx, ( IP )
|
CX POPx, CX 2 ADDxi, CALLn, lblchkPS @ RPCn, CX 2 SUBxi,
|
||||||
AH AH XORrr, AL [DI] MOVr[], ( slen )
|
SI SP MOVxx, SI CX ADDxx,
|
||||||
DX PUSHx, DX INCx, DX AX ADDxx,
|
DI SI MOVxx, DI 2 ADDxi, STD, REPZ, MOVSB,
|
||||||
;CODE
|
;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 )
|
CODE XOR 2 chkPS,
|
||||||
( RSP check )
|
AX POPx, BX POPx, AX BX XORxx, AX PUSHx, ;CODE
|
||||||
AX RS_ADDR MOVxI, BP AX CMPxx,
|
CODE NOT 1 chkPS,
|
||||||
IFC, ( BP < RS_ADDR )
|
AX POPx, AX AX ORxx,
|
||||||
DI 0x06 MOVxm, JMPs, L1 FWRs ( execute )
|
IFNZ, AX -1 MOVxI, THEN, AX INCx, AX PUSHx,
|
||||||
THEN,
|
;CODE
|
||||||
DI DX MOVxx, ( <-- IP ) DX INCx, DX INCx,
|
CODE + 2 chkPS,
|
||||||
DI [DI] MOVx[], ( wordref )
|
AX POPx, BX POPx, AX BX ADDxx, AX PUSHx, ;CODE
|
||||||
( continue to execute ) L1 FSET
|
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 )
|
CODE /MOD 2 chkPS,
|
||||||
AL [DI] MOVr[], DI INCx, ( PFA )
|
BX POPx, AX POPx, DX PUSHx, ( protect )
|
||||||
AL AL ORrr, IFZ, DI JMPr, THEN, ( native )
|
DX DX XORxx, BX DIVx,
|
||||||
AL DECr, IFNZ, ( cell or does )
|
BX DX MOVxx, DX POPx, ( unprotect )
|
||||||
DI PUSHx, ( push PFA )
|
BX PUSHx, ( modulo ) AX PUSHx, ( division )
|
||||||
AL DECr, IFZ, ( cell ) JMPs, lblnext @ RPCs, THEN,
|
;CODE
|
||||||
( does, see B302 )
|
CODE ! 2 chkPS, DI POPx, AX POPx, [DI] AX MOV[]x, ;CODE
|
||||||
DI INCx, DI INCx, DI [DI] MOVx[],
|
CODE @ 1 chkPS, DI POPx, AX [DI] MOVx[], AX PUSHx, ;CODE
|
||||||
THEN, ( continue to compiled )
|
CODE C! 2 chkPS, DI POPx, AX POPx, [DI] AX MOV[]r, ;CODE
|
||||||
( compiled )
|
CODE C@ 1 chkPS,
|
||||||
BP INCx, BP INCx, [BP] 0 DX MOV[]+x, ( pushRS )
|
DI POPx, AH AH XORrr, AL [DI] MOVr[], AX PUSHx, ;CODE
|
||||||
DX DI MOVxx, DX INCx, DX INCx, ( --> IP )
|
CODE I [BP] 0 PUSH[w]+, ;CODE
|
||||||
DI [DI] MOVx[],
|
CODE I' [BP] -2 PUSH[w]+, ;CODE
|
||||||
JMPs, lblexec @ RPCs,
|
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 )
|
CODE BYE BEGIN, JMPs, AGAIN, ;CODE
|
||||||
AX PS_ADDR MOVxI, AX SP SUBxx, 2 SUBAXI, ( CALL adjust )
|
CODE S= 2 chkPS,
|
||||||
AX CX CMPxx,
|
SI POPx, DI POPx, CH CH XORrr, CL [SI] MOVr[],
|
||||||
IFNC, ( we're good ) RETn, THEN,
|
CL [DI] CMPr[],
|
||||||
( underflow ) DI 0x06 MOVxm, JMPs, lblexec @ RPCs,
|
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
|
750 LOAD
|
||||||
811 LOAD
|
832 LOAD
|
||||||
ORG @ 256 /MOD 2 PC! 2 PC!
|
ORG @ 256 /MOD 2 PC! 2 PC!
|
||||||
H@ 256 /MOD 2 PC! 2 PC!
|
H@ 256 /MOD 2 PC! 2 PC!
|
||||||
|
@ -1,69 +1,3 @@
|
|||||||
0xff00 CONSTANT RS_ADDR
|
842 LOAD ( PC/AT xcomp )
|
||||||
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,
|
|
||||||
ORG @ 256 /MOD 2 PC! 2 PC!
|
ORG @ 256 /MOD 2 PC! 2 PC!
|
||||||
H@ 256 /MOD 2 PC! 2 PC!
|
H@ 256 /MOD 2 PC! 2 PC!
|
||||||
|
Loading…
Reference in New Issue
Block a user