@@ -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 | |||||
@@ -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.) |
@@ -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. |
@@ -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 ) |
@@ -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, |
@@ -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, |
@@ -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 ) |
@@ -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 |
@@ -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 |
@@ -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, |
@@ -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 ) |
@@ -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 |
@@ -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 |
@@ -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 | ;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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 ) |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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, |
@@ -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 |
@@ -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+ ; |
@@ -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 | |||||
; | |||||
@@ -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! | |||||
; |
@@ -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 | |||||
@@ -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,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,68 +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, | |||||
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+ ; | |||||
: _ ( 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! | ORG @ 256 /MOD 2 PC! 2 PC! | ||||
H@ 256 /MOD 2 PC! 2 PC! | H@ 256 /MOD 2 PC! 2 PC! |