i still dont know what im doing
This commit is contained in:
parent
4847eb4d88
commit
bc238a3bf9
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,2 +1,8 @@
|
||||
*.com
|
||||
*.bs
|
||||
*.0
|
||||
*.lst
|
||||
*.img
|
||||
*.bin
|
||||
scripts/
|
||||
*.rom
|
||||
/scripts
|
||||
|
86
Makefile
86
Makefile
@ -1,17 +1,81 @@
|
||||
.PHONY: default
|
||||
FLOPPY = 360
|
||||
|
||||
cp437.bin: src/cp437.bmp scripts/bmp2font
|
||||
scripts/bmp2font $< $@
|
||||
PROGRAMS = $(patsubst %.asm,%.com,$(wildcard com/*.asm))
|
||||
DISTFILES = $(PROGRAMS)
|
||||
ROMS =
|
||||
|
||||
vga11.bin: src/vga11.asm cp437.bin
|
||||
nasm -o $@ $<
|
||||
QEMU_ARCH = $(shell uname -m)
|
||||
QEMU = qemu-system-$(QEMU_ARCH)
|
||||
QEMU_ARGS = $(addprefix --option-rom ,$(ROMS))
|
||||
|
||||
forth.bin: src/forth.asm
|
||||
nasm -o $@ $<
|
||||
NASM = nasm
|
||||
NASM_ARGS = -s -Ilib -Plib/nasmcomp.asm -w-macro-params
|
||||
|
||||
scripts/%: src/scripts/%.c
|
||||
mkdir -p scripts
|
||||
gcc -o $@ $<
|
||||
EMUL = utils/emul
|
||||
|
||||
ifdef KVM
|
||||
QEMU_ARGS += --enable-kvm
|
||||
endif
|
||||
|
||||
ifdef DEBUG
|
||||
ROMS += rom/debug.rom
|
||||
NASM_ARGS += -l $(basename $@).lst
|
||||
endif
|
||||
|
||||
ifndef DISPLAY
|
||||
QEMU_ARGS += --display curses
|
||||
endif
|
||||
|
||||
.PHONY: default bootstrap clean qemu-rom qemu-floppy qemu-pxe
|
||||
|
||||
default: fdimage.img
|
||||
|
||||
# Host utils
|
||||
utils/%: src/utils/%.c
|
||||
mkdir -p utils
|
||||
$(CC) -o $@ $<
|
||||
|
||||
cp437.bin: src/cp437.bmp utils/bmp2font
|
||||
utils/bmp2font $< $@
|
||||
|
||||
# BIOS option roms
|
||||
rom/%.rom: rom/%.asm utils/fix-rom
|
||||
$(NASM) $(NASM_ARGS) -o $@ $< && utils/fix-rom $@
|
||||
|
||||
# COM programs
|
||||
%.com: %.asm
|
||||
$(NASM) $(NASM_ARGS) -DCOM -DBASE=0x0100 -o $@ $<
|
||||
|
||||
# Bootloaders, first sector on partition
|
||||
%.bs: %.asm
|
||||
$(NASM) $(NASM_ARGS) -DBOOT -DBASE=0x7C00 -o $@ $<
|
||||
: check boot signature
|
||||
test "$$(echo $$(xxd -p -l 2 -s 510 pxe.bs))" == 55aa
|
||||
|
||||
# Network bootstrap protocol as used for PXE
|
||||
%.0: %.asm
|
||||
$(NASM) $(NASM_ARGS) -DNBP -DBASE=0x7C00 -o $@ $<
|
||||
|
||||
fdimage.img: boot/fat.bs $(BDOSIMG) $(BIOSIMG) $(DISTFILES)
|
||||
mformat -R 9 -C -i $@ -f $(FLOPPY) -B boot/fat.bs ::
|
||||
dd if=$(BDOSIMG) bs=512 seek=1 count=4 conv=notrunc of=$@
|
||||
dd if=$(BIOSIMG) bs=512 seek=5 count=4 conv=notrunc of=$@
|
||||
mcopy -i $@ $(DISTFILES) ::
|
||||
|
||||
hdimage.img: boot/mbr.bs fdimage.img
|
||||
cat boot/mbr.bs fdimage.img >$@
|
||||
|
||||
clean:
|
||||
rm -f *.bin scripts/*
|
||||
rm -f *.com *.bs *.0 *.lst *.img *.bin *.rom
|
||||
|
||||
qemu-floppy: fdimage.img $(ROMS)
|
||||
$(QEMU) $(QEMU_ARGS) -boot a -fda fdimage.img
|
||||
|
||||
qemu-hdd: hdimage.img $(ROMS)
|
||||
$(QEMU) $(QEMU_ARGS) -boot c -hda hdimage.img
|
||||
|
||||
qemu-pxe: pxe.bs $(ROMS)
|
||||
$(QEMU) $(QEMU_ARGS) -boot n \
|
||||
-option-rom /usr/share/qemu/pxe-rtl8139.rom \
|
||||
-device e1000,netdev=mynet0,mac=52:54:00:12:34:56 \
|
||||
-netdev user,id=mynet0,net=192.168.76.0/24,dhcpstart=192.168.76.9,tftp=$(CURDIR),bootfile=pxe.bs
|
||||
|
234
bdos/8086.asm
234
bdos/8086.asm
@ -1,234 +0,0 @@
|
||||
ORG BDOS
|
||||
|
||||
%include "hdr/bios.asm"
|
||||
%include "hdr/fcb.asm"
|
||||
%include "hdr/bpb.asm"
|
||||
|
||||
DISKBUF: EQU (BDOS-0x200) ; deblocking
|
||||
DISKBPB: EQU (DISKBUF-21) ; BPB of the current driv
|
||||
DISKDRV: EQU (DISKBPB-1) ; BYTE denoting drive of current fcb (1=A, ...)
|
||||
|
||||
PROGBX: EQU (DISKDRV-2)
|
||||
|
||||
STACK: EQU (PROGBX & 0xFFFE) ; even address, grows down
|
||||
|
||||
DEFDRV: EQU 4 ; default drive when opening a FCB (1=A, ...)
|
||||
|
||||
SYSCALL:
|
||||
MOV [PROGBX], BX
|
||||
XOR BH, BH
|
||||
MOV BL, CL
|
||||
ADD BX, BX
|
||||
ADD BX, FUNCS
|
||||
MOV BX, [BX]
|
||||
PUSH BX
|
||||
MOV BX, [PROGBX]
|
||||
SYSRET:
|
||||
RET
|
||||
|
||||
FUNCS:
|
||||
DW SETUP,GETC,PUTC,SYSRET
|
||||
DW SYSRET,SYSRET,SYSRET,SYSRET
|
||||
DW SYSRET,PUTS,GETS,STATUS
|
||||
DW SYSRET,DISKRST,SETDEFDSK,FCBOPEN
|
||||
DW SYSRET,SYSRET,SYSRET,SYSRET
|
||||
DW SYSRET,SYSRET,SYSRET,SYSRET
|
||||
|
||||
SETUP:
|
||||
MOV SP, STACK
|
||||
MOV BYTE [DEFDRV], 0x01
|
||||
MOV CX, DISKBUF
|
||||
CALL SETDMA
|
||||
|
||||
SUB SP, 0x20
|
||||
MOV BX, SP
|
||||
CALL FCBOPEN
|
||||
|
||||
CLI
|
||||
HALT:
|
||||
HLT
|
||||
JMP HALT
|
||||
|
||||
GETC:
|
||||
CALL CONIN
|
||||
TEST AL, AL
|
||||
JZ GETC
|
||||
PUSH DX
|
||||
MOV DL, AL
|
||||
CALL CONOUT
|
||||
POP DX
|
||||
ret
|
||||
|
||||
PUTC:
|
||||
JMP CONOUT
|
||||
|
||||
PUTS:
|
||||
PUSH SI
|
||||
MOV SI, DX
|
||||
PUTS_L:
|
||||
MOV DL, BYTE [SI]
|
||||
CMP DL, '$'
|
||||
JZ PUTS_E
|
||||
CALL CONOUT
|
||||
INC SI
|
||||
JMP PUTS_L
|
||||
PUTS_E:
|
||||
POP SI
|
||||
RET
|
||||
|
||||
; BX base ptr to buffer
|
||||
; CH maximum BL
|
||||
; CL minimum BL
|
||||
GETS:
|
||||
PUSH AX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH BX
|
||||
; BX is base pointer
|
||||
MOV BX, DX
|
||||
; CL is maximum, CH is current position
|
||||
MOV CX, [BX]
|
||||
XOR CH, CH
|
||||
; BX starts at actual character area
|
||||
ADD BX, 2
|
||||
GETS_L:
|
||||
; Read and maybe handle control chars
|
||||
CALL GETC
|
||||
CMP AL, 0x0D
|
||||
JE GETS_E
|
||||
CMP AL, 8
|
||||
JE GETS_BS
|
||||
; Store character
|
||||
PUSH BX
|
||||
ADD BL, CH
|
||||
ADC BH, 0
|
||||
MOV [BX], AL
|
||||
POP BX
|
||||
; Loop if we arent full yet
|
||||
INC CH
|
||||
CMP CH, CL
|
||||
JC GETS_L
|
||||
GETS_E:
|
||||
; Append LF to CR
|
||||
MOV DL, 0x0A
|
||||
CALL PUTC
|
||||
; Write back length data
|
||||
SUB BX, 2
|
||||
MOV [BX], CX
|
||||
; Restore registers
|
||||
POP BX
|
||||
POP DX
|
||||
POP CX
|
||||
POP AX
|
||||
ret
|
||||
GETS_BS:
|
||||
TEST CH, CH
|
||||
JZ GETS_L
|
||||
MOV DL, 0x20
|
||||
CALL PUTC
|
||||
MOV DL, 8
|
||||
CALL PUTC
|
||||
DEC CL
|
||||
JMP GETS_L
|
||||
|
||||
STATUS:
|
||||
JMP CONST
|
||||
|
||||
DISKRST:
|
||||
MOV BYTE [DISKDRV], 0xFF
|
||||
RET
|
||||
|
||||
SETDEFDSK:
|
||||
MOV BYTE [DEFDRV], DL
|
||||
RET
|
||||
|
||||
FCBOPEN:
|
||||
MOV CL, BYTE [BX]
|
||||
TEST CL, CL
|
||||
JNZ NODEFDRV
|
||||
MOV CL, BYTE [DEFDRV]
|
||||
MOV BYTE [BX], CL
|
||||
NODEFDRV:
|
||||
CALL LOADBPB
|
||||
|
||||
MOV CX, [DISKBPB+BPB_RDE]
|
||||
|
||||
CALL FATSIZE
|
||||
ADD DX, WORD [DISKBPB+BPB_RSC]
|
||||
CALL SETLSEC
|
||||
CALL READ
|
||||
|
||||
MOV AX, [DISKBUF]
|
||||
|
||||
INT3
|
||||
; TODO: search for file in rootdir
|
||||
; TODO: init cluster number
|
||||
RET
|
||||
|
||||
; Set logical sector number
|
||||
; IN DX sector number
|
||||
SETLSEC:
|
||||
PUSH AX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
XOR AX, AX
|
||||
XCHG AX, DX
|
||||
DIV WORD [DISKBPB+BPB_SPT]
|
||||
MOV CX, AX
|
||||
CALL SETTRK
|
||||
MOV CX, DX
|
||||
INC CX
|
||||
CALL SETSEC
|
||||
POP DX
|
||||
POP CX
|
||||
POP AX
|
||||
RET
|
||||
|
||||
; OUT DX number of sectors by all FATs
|
||||
FATSIZE:
|
||||
PUSH AX
|
||||
MOV DL, BYTE [DISKBPB+BPB_FN]
|
||||
MOV AL, BYTE [DISKBPB+BPB_SF]
|
||||
MUL DL
|
||||
XCHG AX, DX
|
||||
POP AX
|
||||
RET:
|
||||
RET
|
||||
|
||||
; IN CL drive num, 1=A, 2=B, 3=C
|
||||
LOADBPB:
|
||||
CMP BYTE [DISKDRV], CL
|
||||
JE RET
|
||||
|
||||
PUSH CX
|
||||
DEC CL
|
||||
CALL SELDSK
|
||||
; first track
|
||||
MOV CX, 0
|
||||
CALL SETTRK
|
||||
; first sector
|
||||
MOV CX, 1
|
||||
CALL SETSEC
|
||||
; into default diskbuf
|
||||
MOV CX, DISKBUF
|
||||
CALL SETDMA
|
||||
POP CX
|
||||
|
||||
CALL READ
|
||||
JC DISKRST
|
||||
|
||||
; copy BPB
|
||||
PUSH CX
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
MOV CX, 21
|
||||
MOV SI, DISKBUF+0x0B
|
||||
MOV DI, DISKBPB
|
||||
REP MOVSB
|
||||
POP DI
|
||||
POP SI
|
||||
POP CX
|
||||
|
||||
; store drive number
|
||||
MOV BYTE [DISKDRV], CL
|
||||
RET
|
218
bios/8086.asm
218
bios/8086.asm
@ -1,218 +0,0 @@
|
||||
ORG BIOS
|
||||
CPU 8086
|
||||
|
||||
DISKCX: EQU 0x8
|
||||
DISKDX: EQU 0xA
|
||||
DISKBX: EQU 0xC
|
||||
|
||||
JMP NEAR BOOT
|
||||
JMP NEAR WBOOT
|
||||
JMP NEAR CONST
|
||||
JMP NEAR CONIN
|
||||
JMP NEAR CONOUT
|
||||
JMP NEAR LIST
|
||||
JMP NEAR PUNCH
|
||||
JMP NEAR READER
|
||||
JMP NEAR HOME
|
||||
JMP NEAR SELDSK
|
||||
JMP NEAR SETTRK
|
||||
JMP NEAR SETSEC
|
||||
JMP NEAR SETDMA
|
||||
JMP NEAR READ
|
||||
JMP NEAR WRITE
|
||||
JMP NEAR LISTST
|
||||
|
||||
BOOT:
|
||||
MOV AL, 0x86
|
||||
CALL MSG
|
||||
DB "BIOS", 0
|
||||
|
||||
WBOOT:
|
||||
XOR CX, CX
|
||||
JMP BDOS
|
||||
RET
|
||||
|
||||
; CHAR I/O
|
||||
CONST:
|
||||
MOV AH, 1
|
||||
INT 0x16
|
||||
JZ .END
|
||||
MOV AL, 0xFF
|
||||
RET
|
||||
.END:
|
||||
XOR AL, AL
|
||||
RET
|
||||
|
||||
CONIN:
|
||||
XOR AX, AX
|
||||
INT 0x16
|
||||
TEST AL, AL
|
||||
JZ CONIN
|
||||
RET
|
||||
|
||||
MSG:
|
||||
POP SI
|
||||
.LOOP:
|
||||
MOV DL, BYTE [SI]
|
||||
INC SI
|
||||
TEST DL, DL
|
||||
JZ .END
|
||||
CALL CONOUT
|
||||
JMP .LOOP
|
||||
.END:
|
||||
MOV DL, 0x20
|
||||
CALL CONOUT
|
||||
CALL PRINTAL
|
||||
MOV DL, 0x0A
|
||||
CALL CONOUT
|
||||
MOV DL, 0x0D
|
||||
CALL CONOUT
|
||||
PUSH SI
|
||||
RET
|
||||
|
||||
PRINTAL:
|
||||
PUSH AX
|
||||
PUSH DX
|
||||
AAM 16
|
||||
MOV DL, AH
|
||||
CALL PRINTNIB
|
||||
MOV DL, AL
|
||||
CALL PRINTNIB
|
||||
POP DX
|
||||
POP AX
|
||||
RET
|
||||
|
||||
PRINTNIB:
|
||||
ADD DL, 0x30
|
||||
CMP DL, 0x3a
|
||||
JL CONOUT
|
||||
ADD DL, 0x07
|
||||
|
||||
CONOUT:
|
||||
PUSH AX
|
||||
PUSH BX
|
||||
MOV AH, 0x0E
|
||||
MOV AL, DL
|
||||
XOR BX, BX
|
||||
INT 0x10
|
||||
POP BX
|
||||
POP AX
|
||||
RET
|
||||
|
||||
LIST:
|
||||
PUSH DX
|
||||
XOR AH, AH
|
||||
MOV AL, DL
|
||||
INT 0x17
|
||||
POP DX
|
||||
RET
|
||||
|
||||
LISTST:
|
||||
STC
|
||||
RET
|
||||
|
||||
PUNCH:
|
||||
STC
|
||||
RET
|
||||
|
||||
READER:
|
||||
STC
|
||||
RET
|
||||
|
||||
; DISK I/O
|
||||
HOME:
|
||||
MOV WORD [DISKCX], 0x0001
|
||||
MOV BYTE [DISKDX+1], 0x00
|
||||
RET
|
||||
|
||||
SELDSK:
|
||||
MOV BYTE [DISKDX], CL
|
||||
XOR BX, BX
|
||||
RET
|
||||
|
||||
SETTRK:
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
|
||||
MOV DX, CX
|
||||
; CH for headnum, CL for SAL
|
||||
MOV CX, 0x0006
|
||||
|
||||
; Take off LSB as head number
|
||||
XOR CH, CH
|
||||
RCR DX, 1
|
||||
RCL CH, 1
|
||||
MOV BYTE [DISKDX+1], CH
|
||||
|
||||
; DX is sector number now
|
||||
; Shift into format for int13
|
||||
; DX ------9876543210
|
||||
SAL DX, CL
|
||||
; DX 9876543210------
|
||||
ROL DX, 1
|
||||
ROL DX, 1
|
||||
; DX 76543210------98
|
||||
SAL DL, CL
|
||||
; DX 7654321098------
|
||||
AND WORD [DISKCX], 0x003F
|
||||
OR WORD [DISKCX], DX
|
||||
|
||||
POP DX
|
||||
POP CX
|
||||
RET
|
||||
|
||||
SETSEC:
|
||||
AND WORD [DISKCX], 0xFFC0
|
||||
OR BYTE [DISKCX], CL
|
||||
RET
|
||||
|
||||
SETDMA:
|
||||
MOV WORD [DISKBX], CX
|
||||
RET
|
||||
|
||||
READ:
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH BX
|
||||
|
||||
MOV AX, 0x0201
|
||||
MOV CX, [DISKCX]
|
||||
MOV DX, [DISKDX]
|
||||
MOV BX, [DISKBX]
|
||||
INT 0x13
|
||||
XCHG AH, AL
|
||||
|
||||
POP BX
|
||||
POP DX
|
||||
POP CX
|
||||
|
||||
JC DISKERR
|
||||
RET
|
||||
|
||||
WRITE:
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH BX
|
||||
|
||||
MOV AX, 0x0301
|
||||
MOV CX, [DISKCX]
|
||||
MOV DX, [DISKDX]
|
||||
MOV BX, [DISKBX]
|
||||
INT 0x13
|
||||
XCHG AH, AL
|
||||
|
||||
POP BX
|
||||
POP DX
|
||||
POP CX
|
||||
|
||||
JC DISKERR
|
||||
RET
|
||||
|
||||
DISKERR:
|
||||
PUSHF
|
||||
PUSH SI
|
||||
CALL MSG
|
||||
DB "DISKERR", 0
|
||||
POP SI
|
||||
POPF
|
||||
RET
|
@ -1,21 +0,0 @@
|
||||
org 0x100
|
||||
|
||||
jmp start
|
||||
|
||||
%include "fcbparse.asm"
|
||||
|
||||
fcb_asm:
|
||||
times 36 db 0
|
||||
|
||||
fcb_bin:
|
||||
times 36 db 0
|
||||
|
||||
fcb_lst:
|
||||
times 36 db 0
|
||||
|
||||
start:
|
||||
mov si, 0x81
|
||||
mov bx, fcb_asm
|
||||
mov ax, 0x1234
|
||||
call fcb_parse
|
||||
ret
|
@ -1,17 +0,0 @@
|
||||
org 0x0100
|
||||
|
||||
main:
|
||||
mov si, hello
|
||||
.loop:
|
||||
lodsb
|
||||
test al, al
|
||||
jz .ret
|
||||
mov dl, al
|
||||
mov cl, 0x02
|
||||
call 5
|
||||
jmp .loop
|
||||
.ret:
|
||||
ret
|
||||
|
||||
hello:
|
||||
db "Hello!", 0x0A, 0x0D, 0
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
17
hdr/bios.asm
17
hdr/bios.asm
@ -1,17 +0,0 @@
|
||||
; Labels for BIOS entry points
|
||||
BOOT: EQU (BIOS+0)
|
||||
WBOOT: EQU (BIOS+3)
|
||||
CONST: EQU (BIOS+6)
|
||||
CONIN: EQU (BIOS+9)
|
||||
CONOUT: EQU (BIOS+12)
|
||||
LIST: EQU (BIOS+15)
|
||||
PUNCH: EQU (BIOS+18)
|
||||
READER: EQU (BIOS+21)
|
||||
HOME: EQU (BIOS+24)
|
||||
SELDSK: EQU (BIOS+27)
|
||||
SETTRK: EQU (BIOS+30)
|
||||
SETSEC: EQU (BIOS+33)
|
||||
SETDMA: EQU (BIOS+36)
|
||||
READ: EQU (BIOS+39)
|
||||
WRITE: EQU (BIOS+42)
|
||||
LISTST: EQU (BIOS+45)
|
12
hdr/bpb.asm
12
hdr/bpb.asm
@ -1,12 +0,0 @@
|
||||
; BPB from first sector on FAT fs, starting 0x0B
|
||||
BPB_SS: EQU 0 ; WORD sector size
|
||||
BPB_SC: EQU 2 ; BYTE sectors per cluster
|
||||
BPB_RSC: EQU 3 ; WORD reserved sector count
|
||||
BPB_FN: EQU 5 ; BYTE number of FATs
|
||||
BPB_RDE: EQU 6 ; WORD number of root directory entries
|
||||
BPB_TS: EQU 8 ; WORD total number of sectors
|
||||
BPB_MI: EQU 10 ; BYTE medium identifier
|
||||
BPB_SF: EQU 11 ; WORD sectors per FAT
|
||||
BPB_SPT: EQU 13 ; WORD sectors per track
|
||||
BPB_NOS: EQU 15 ; WORD number of sides/heads
|
||||
BPB_PO: EQU 17 ; DWORD partition offset
|
10
hdr/fcb.asm
10
hdr/fcb.asm
@ -1,10 +0,0 @@
|
||||
; File control block
|
||||
FCB_DRV: EQU 0 ; BYTE 0=A: 1=B: 2=C: ...
|
||||
FCB_NAM: EQU 1 ; 8 BYTES, space padded
|
||||
FCB_EXT: EQU 9 ; 3 BYTES, space padded
|
||||
FCB_TYP: EQU 12 ; BYTE FCB type
|
||||
; TYP=1: regular file
|
||||
FCB_BLK: EQU 13 ; current 128b block in sector
|
||||
FCB_CLU: EQU 14 ; current sector
|
||||
FCB_LFT: EQU 16 ; bytes left to read in current file
|
||||
FCB_END: EQU 20 ; FCB length
|
@ -1,54 +1,22 @@
|
||||
; print a word
|
||||
; in: ax
|
||||
print16:
|
||||
xchg ah,al
|
||||
call print8
|
||||
xchg ah,al
|
||||
|
||||
; print a byte
|
||||
; in: al
|
||||
print8:
|
||||
push ax ; avoid destroying ah
|
||||
push bx
|
||||
xor bx, bx
|
||||
aam 16 ; high nibble moved into ah, low nibble into al
|
||||
add ax, 0x3030
|
||||
push ax
|
||||
xchg al, ah
|
||||
call .nib
|
||||
pop ax
|
||||
call .nib
|
||||
pop bx
|
||||
pop ax
|
||||
ret
|
||||
.nib:
|
||||
cmp al, 0x3a
|
||||
jl .out
|
||||
add al, 0x07
|
||||
.out:
|
||||
mov dl, al
|
||||
call CONOUT
|
||||
ret
|
||||
|
||||
dump:
|
||||
push ax
|
||||
push cx
|
||||
push dx
|
||||
push bx
|
||||
mov dl, 0x0A
|
||||
call CONOUT
|
||||
mov dl, 0x0D
|
||||
call CONOUT
|
||||
mov al, 0x0A
|
||||
call putc
|
||||
mov al, 0x0D
|
||||
call putc
|
||||
mov cx, 4
|
||||
.loop_line:
|
||||
push cx
|
||||
push bx
|
||||
mov ax, bx
|
||||
call print16
|
||||
mov dl, ':'
|
||||
call CONOUT
|
||||
mov dl, ' '
|
||||
call CONOUT
|
||||
mov al, ':'
|
||||
call putc
|
||||
mov al, ' '
|
||||
call putc
|
||||
mov cx, 0x8
|
||||
.loop_bin:
|
||||
mov ax, [bx]
|
113
pxe.asm
Normal file
113
pxe.asm
Normal file
@ -0,0 +1,113 @@
|
||||
org BASE
|
||||
|
||||
main:
|
||||
mov ax, [es:bx+0x0A]
|
||||
mov [cs:pxejmp], ax
|
||||
mov ax, [es:bx+0x0A+2]
|
||||
mov [cs:pxejmp+2], ax
|
||||
|
||||
mov ax, cs
|
||||
mov ds, ax
|
||||
mov si, pxejmp
|
||||
call dump
|
||||
|
||||
mov ax, cs
|
||||
mov ds, ax
|
||||
mov di, pxestat
|
||||
mov bx, 0x0071
|
||||
|
||||
call UsePXEAPI
|
||||
|
||||
mov ax, cs
|
||||
mov ds, ax
|
||||
mov si, pxestat
|
||||
call dump
|
||||
call dump
|
||||
|
||||
hlt: hlt
|
||||
jmp hlt
|
||||
|
||||
UsePXEAPI:
|
||||
push ds
|
||||
push di
|
||||
push bx
|
||||
int 3
|
||||
call far [pxejmp]
|
||||
int 3
|
||||
add sp, 6
|
||||
ret
|
||||
|
||||
pxejmp: dd 0
|
||||
|
||||
pxestat:
|
||||
.Status dw 0
|
||||
.PacketType dw 2
|
||||
.BufferSize dw 0
|
||||
.BufferOff dw 0
|
||||
.BufferSeg dw 0
|
||||
.BufferLimit dw 0
|
||||
|
||||
;tftp_open:
|
||||
; .Status dw 0
|
||||
; .SIP dd 0
|
||||
; .GIP dd 0
|
||||
; .Filename db "pxe.bs"
|
||||
; times (128-6) db 0
|
||||
; .Port dw 0
|
||||
; .PacketSize dw 0
|
||||
|
||||
space:
|
||||
mov al, 0x20
|
||||
jmp putc
|
||||
putbc:
|
||||
cmp al, 0x80
|
||||
jnc dot
|
||||
cmp al, 0x20
|
||||
jnc putc
|
||||
dot:
|
||||
mov al, '.'
|
||||
putc:
|
||||
push ax
|
||||
push bx
|
||||
mov ah, 0x0e
|
||||
xor bx, bx
|
||||
int 0x10
|
||||
pop bx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
dump: push cx
|
||||
mov ax, ds
|
||||
call print16
|
||||
mov al, ':'
|
||||
call putc
|
||||
mov ax, si
|
||||
call print16
|
||||
call space
|
||||
call space
|
||||
|
||||
mov cx, 0x08
|
||||
push si
|
||||
.hloop: lodsb
|
||||
call print8
|
||||
lodsb
|
||||
call print8
|
||||
call space
|
||||
loop .hloop
|
||||
pop si
|
||||
call space
|
||||
|
||||
mov cx, 0x10
|
||||
.aloop: lodsb
|
||||
call putbc
|
||||
loop .aloop
|
||||
|
||||
mov al, 0x0A
|
||||
call putc
|
||||
mov al, 0x0D
|
||||
call putc
|
||||
pop cx
|
||||
ret
|
||||
|
||||
%include "print.asm"
|
||||
%include "printf.asm"
|
@ -1,518 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
uint8_t mem[64*1024];
|
||||
|
||||
typedef struct flagbits {
|
||||
unsigned int c : 1;
|
||||
unsigned int u1 : 1;
|
||||
unsigned int p : 1;
|
||||
unsigned int u3 : 1;
|
||||
|
||||
unsigned int a : 1;
|
||||
unsigned int u5 : 1;
|
||||
unsigned int z : 1;
|
||||
unsigned int s : 1;
|
||||
} flagbits;
|
||||
|
||||
typedef struct reg {
|
||||
uint8_t flags;
|
||||
uint8_t a;
|
||||
uint8_t c;
|
||||
uint8_t b;
|
||||
uint8_t e;
|
||||
uint8_t d;
|
||||
uint8_t l;
|
||||
uint8_t h;
|
||||
} reg;
|
||||
|
||||
typedef struct regp {
|
||||
uint16_t psw;
|
||||
uint16_t bc;
|
||||
uint16_t de;
|
||||
uint16_t hl;
|
||||
} regp;
|
||||
|
||||
union regset {
|
||||
struct reg reg;
|
||||
struct regp regp;
|
||||
} regset;
|
||||
|
||||
#define A regset.reg.a
|
||||
#define B regset.reg.b
|
||||
#define C regset.reg.c
|
||||
#define D regset.reg.d
|
||||
#define E regset.reg.e
|
||||
#define H regset.reg.h
|
||||
#define L regset.reg.l
|
||||
#define M mem[HL]
|
||||
|
||||
#define BC regset.regp.bc
|
||||
#define DE regset.regp.de
|
||||
#define HL regset.regp.hl
|
||||
|
||||
#define flags (*(struct flagbits*)®set.reg.flags)
|
||||
|
||||
uint16_t IP = 0x100;
|
||||
uint16_t SP = 0;
|
||||
unsigned int tmp;
|
||||
|
||||
// Dump registers
|
||||
void dump() {
|
||||
printf("\n");
|
||||
printf("A=%02X BC=%04X DE=%04X HL=%04X M=%02X SP=%04X ", A, BC, DE, HL, M, SP);
|
||||
printf("%c", flags.s ? 'S' : '-');
|
||||
printf("%c", flags.z ? 'Z' : '-');
|
||||
printf("%c", flags.a ? 'A' : '-');
|
||||
printf("%c", flags.p ? 'P' : '-');
|
||||
printf("%c", flags.c ? 'C' : '-');
|
||||
|
||||
printf("\n");
|
||||
printf("IP=%04X : %02X %02X\n", IP, mem[IP], mem[IP+1]);
|
||||
}
|
||||
|
||||
uint8_t imm8() {
|
||||
uint8_t r = *(uint8_t*)&mem[IP];
|
||||
IP++;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint16_t imm16() {
|
||||
uint16_t r = *(uint16_t*)&mem[IP];
|
||||
IP+=2;
|
||||
return r;
|
||||
}
|
||||
|
||||
void push(uint16_t v) {
|
||||
SP -= 2;
|
||||
*(uint16_t*)&mem[SP] = v;
|
||||
}
|
||||
|
||||
uint16_t pop() {
|
||||
uint16_t v = *(uint16_t*)&mem[SP];
|
||||
SP += 2;
|
||||
return v;
|
||||
}
|
||||
|
||||
void in(uint8_t port) {
|
||||
|
||||
}
|
||||
|
||||
void out(uint8_t port) {
|
||||
|
||||
}
|
||||
|
||||
int has_even_parity(uint8_t x){
|
||||
unsigned int count = 0, i, b = 1;
|
||||
|
||||
for(i = 0; i < 8; i++){
|
||||
if( x & (b << i) ){count++;}
|
||||
}
|
||||
|
||||
if( (count % 2) ){return 0;}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cpm_syscall(int number) {
|
||||
switch(number) {
|
||||
case 0:
|
||||
exit(0);
|
||||
break;
|
||||
case 2:
|
||||
printf("%c", E);
|
||||
break;
|
||||
case 0x0C:
|
||||
H=0x02;
|
||||
L=0x00;
|
||||
break;;
|
||||
default:
|
||||
fprintf(stderr, "Fatal: Unhandled CP/M syscall C=%02Xh\n", number);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void call(uint16_t v) {
|
||||
switch(v) {
|
||||
case 0:
|
||||
exit(0);
|
||||
break;;
|
||||
case 5:
|
||||
cpm_syscall(C);
|
||||
break;;
|
||||
default:
|
||||
push(IP);
|
||||
IP=v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void interrupt(int number) {
|
||||
call(number << 3);
|
||||
}
|
||||
|
||||
#define add16c(a, b) \
|
||||
tmp = a + b; \
|
||||
flags.c = (tmp >> 16) & 1
|
||||
|
||||
#define unarync(a, op) \
|
||||
tmp=a; \
|
||||
tmp op; \
|
||||
flags.p = has_even_parity(tmp & 8); \
|
||||
flags.z = !(tmp); \
|
||||
flags.s = (tmp >> 7) & 1; \
|
||||
a=tmp
|
||||
|
||||
#define aritht(a, op, b) \
|
||||
tmp=a; \
|
||||
tmp=a op b; \
|
||||
flags.c = (tmp >> 8) & 1; \
|
||||
flags.p = has_even_parity(tmp & 8); \
|
||||
flags.z = !(tmp); \
|
||||
flags.s = (tmp >> 7) & 1;
|
||||
|
||||
#define arith(a, op, b) \
|
||||
aritht(a, op, b); \
|
||||
a=tmp
|
||||
|
||||
// Execute a single instruction
|
||||
void step() {
|
||||
uint8_t opcode = mem[IP];
|
||||
IP++;
|
||||
switch(opcode) {
|
||||
case 0x00: break;;
|
||||
case 0x01: BC=imm16(); break;;
|
||||
case 0x02: mem[BC]=A; break;;
|
||||
case 0x03: BC++;
|
||||
case 0x04: unarync(B, ++); break;;
|
||||
case 0x05: unarync(B, --); break;;
|
||||
case 0x06: B=imm8(); break;;
|
||||
case 0x07: tmp=A; A = A << 1 | flags.c; flags.c = tmp >> 7; break;;
|
||||
|
||||
case 0x09: HL=add16c(HL,BC); break;;
|
||||
case 0x0a: A=mem[BC]; break;;
|
||||
case 0x0b: BC--;
|
||||
case 0x0c: unarync(B, ++); break;;
|
||||
case 0x0d: unarync(B, --); break;;
|
||||
case 0x0e: C=imm8(); break;;
|
||||
|
||||
case 0x11: DE=imm16(); break;;
|
||||
case 0x12: mem[DE]=A; break;;
|
||||
case 0x13: DE++;
|
||||
case 0x14: unarync(D, ++); break;;
|
||||
case 0x15: unarync(D, --); break;;
|
||||
case 0x16: D=imm8(); break;;
|
||||
|
||||
case 0x19: HL=add16c(HL,DE); break;;
|
||||
case 0x1a: A=mem[DE]; break;;
|
||||
case 0x1b: DE--;
|
||||
case 0x1c: unarync(E, ++); break;;
|
||||
case 0x1d: unarync(E, --); break;;
|
||||
case 0x1e: E=imm8(); break;;
|
||||
|
||||
case 0x21: HL=imm16(); break;;
|
||||
case 0x22: *(uint16_t*)&mem[imm16()]=HL; break;;
|
||||
case 0x23: HL++;
|
||||
case 0x24: unarync(H, ++); break;;
|
||||
case 0x25: unarync(H, --); break;;
|
||||
case 0x26: H=imm8(); break;;
|
||||
|
||||
case 0x29: HL=add16c(HL,HL); break;;
|
||||
case 0x2a: HL=*(uint16_t*)&mem[imm16()]; break;;
|
||||
case 0x2b: HL--;
|
||||
case 0x2c: unarync(L, ++); break;;
|
||||
case 0x2d: unarync(L, --); break;;
|
||||
case 0x2e: L=imm8(); break;;
|
||||
case 0x2f: A=~A; break;;
|
||||
|
||||
case 0x31: SP=imm16(); break;;
|
||||
case 0x32: mem[imm16()]=A; break;;
|
||||
case 0x33: SP++;
|
||||
case 0x34: unarync(M, ++); break;;
|
||||
case 0x35: unarync(M, --); break;;
|
||||
case 0x36: M=imm8(); break;;
|
||||
case 0x37: flags.c = 1; break;;
|
||||
|
||||
case 0x39: HL=add16c(HL,SP); break;;
|
||||
case 0x3a: A=mem[imm16()]; break;;
|
||||
case 0x3b: SP--;
|
||||
case 0x3c: unarync(A, ++); break;;
|
||||
case 0x3d: unarync(A, --); break;;
|
||||
case 0x3e: A=imm8(); break;;
|
||||
case 0x3f: flags.c = !flags.c; break;;
|
||||
|
||||
case 0x40: B=B; break;;
|
||||
case 0x41: B=C; break;;
|
||||
case 0x42: B=D; break;;
|
||||
case 0x43: B=E; break;;
|
||||
case 0x44: B=H; break;;
|
||||
case 0x45: B=L; break;;
|
||||
case 0x46: B=M; break;;
|
||||
case 0x47: B=A; break;;
|
||||
|
||||
case 0x48: C=B; break;;
|
||||
case 0x49: C=C; break;;
|
||||
case 0x4a: C=D; break;;
|
||||
case 0x4b: C=E; break;;
|
||||
case 0x4c: C=H; break;;
|
||||
case 0x4d: C=L; break;;
|
||||
case 0x4e: C=M; break;;
|
||||
case 0x4f: C=A; break;;
|
||||
|
||||
case 0x50: D=B; break;;
|
||||
case 0x51: D=C; break;;
|
||||
case 0x52: D=D; break;;
|
||||
case 0x53: D=E; break;;
|
||||
case 0x54: D=H; break;;
|
||||
case 0x55: D=L; break;;
|
||||
case 0x56: D=M; break;;
|
||||
case 0x57: D=A; break;;
|
||||
|
||||
case 0x58: E=B; break;;
|
||||
case 0x59: E=C; break;;
|
||||
case 0x5a: E=D; break;;
|
||||
case 0x5b: E=E; break;;
|
||||
case 0x5c: E=H; break;;
|
||||
case 0x5d: E=L; break;;
|
||||
case 0x5e: E=M; break;;
|
||||
case 0x5f: E=A; break;;
|
||||
|
||||
case 0x60: H=B; break;;
|
||||
case 0x61: H=C; break;;
|
||||
case 0x62: H=D; break;;
|
||||
case 0x63: H=E; break;;
|
||||
case 0x64: H=H; break;;
|
||||
case 0x65: H=L; break;;
|
||||
case 0x66: H=M; break;;
|
||||
case 0x67: H=A; break;;
|
||||
|
||||
case 0x68: L=B; break;;
|
||||
case 0x69: L=C; break;;
|
||||
case 0x6a: L=D; break;;
|
||||
case 0x6b: L=E; break;;
|
||||
case 0x6c: L=H; break;;
|
||||
case 0x6d: L=L; break;;
|
||||
case 0x6e: L=M; break;;
|
||||
case 0x6f: L=A; break;;
|
||||
|
||||
case 0x70: M=B; break;;
|
||||
case 0x71: M=C; break;;
|
||||
case 0x72: M=D; break;;
|
||||
case 0x73: M=E; break;;
|
||||
case 0x74: M=H; break;;
|
||||
case 0x75: M=L; break;;
|
||||
case 0x76: exit(0); break;;
|
||||
case 0x77: M=A; break;;
|
||||
|
||||
case 0x78: A=B; break;;
|
||||
case 0x79: A=C; break;;
|
||||
case 0x7a: A=D; break;;
|
||||
case 0x7b: A=E; break;;
|
||||
case 0x7c: A=H; break;;
|
||||
case 0x7d: A=L; break;;
|
||||
case 0x7e: A=M; break;;
|
||||
case 0x7f: A=A; break;;
|
||||
|
||||
case 0x80: arith(A, +, B); break;;
|
||||
case 0x81: arith(A, +, C); break;;
|
||||
case 0x82: arith(A, +, D); break;;
|
||||
case 0x83: arith(A, +, E); break;;
|
||||
case 0x84: arith(A, +, H); break;;
|
||||
case 0x85: arith(A, +, L); break;;
|
||||
case 0x86: arith(A, +, M); break;;
|
||||
case 0x87: arith(A, +, A); break;;
|
||||
|
||||
case 0x88: arith(A, +flags.c+, B); break;;
|
||||
case 0x89: arith(A, +flags.c+, C); break;;
|
||||
case 0x8A: arith(A, +flags.c+, D); break;;
|
||||
case 0x8B: arith(A, +flags.c+, E); break;;
|
||||
case 0x8C: arith(A, +flags.c+, H); break;;
|
||||
case 0x8D: arith(A, +flags.c+, L); break;;
|
||||
case 0x8E: arith(A, +flags.c+, M); break;;
|
||||
case 0x8F: arith(A, +flags.c+, A); break;;
|
||||
|
||||
case 0x90: arith(A, -, B); break;;
|
||||
case 0x91: arith(A, -, C); break;;
|
||||
case 0x92: arith(A, -, D); break;;
|
||||
case 0x93: arith(A, -, E); break;;
|
||||
case 0x94: arith(A, -, H); break;;
|
||||
case 0x95: arith(A, -, L); break;;
|
||||
case 0x96: arith(A, -, M); break;;
|
||||
case 0x97: arith(A, -, A); break;;
|
||||
|
||||
case 0x98: arith(A, -flags.c-, B); break;;
|
||||
case 0x99: arith(A, -flags.c-, C); break;;
|
||||
case 0x9A: arith(A, -flags.c-, D); break;;
|
||||
case 0x9B: arith(A, -flags.c-, E); break;;
|
||||
case 0x9C: arith(A, -flags.c-, H); break;;
|
||||
case 0x9D: arith(A, -flags.c-, L); break;;
|
||||
case 0x9E: arith(A, -flags.c-, M); break;;
|
||||
case 0x9F: arith(A, -flags.c-, A); break;;
|
||||
|
||||
case 0xA0: arith(A, &, B); break;;
|
||||
case 0xA1: arith(A, &, C); break;;
|
||||
case 0xA2: arith(A, &, D); break;;
|
||||
case 0xA3: arith(A, &, E); break;;
|
||||
case 0xA4: arith(A, &, H); break;;
|
||||
case 0xA5: arith(A, &, L); break;;
|
||||
case 0xA6: arith(A, &, M); break;;
|
||||
case 0xA7: arith(A, &, A); break;;
|
||||
|
||||
case 0xA8: arith(A, ^, B); break;;
|
||||
case 0xA9: arith(A, ^, C); break;;
|
||||
case 0xAA: arith(A, ^, D); break;;
|
||||
case 0xAB: arith(A, ^, E); break;;
|
||||
case 0xAC: arith(A, ^, H); break;;
|
||||
case 0xAD: arith(A, ^, L); break;;
|
||||
case 0xAE: arith(A, ^, M); break;;
|
||||
case 0xAF: arith(A, ^, A); break;;
|
||||
|
||||
case 0xB0: arith(A, |, B); break;;
|
||||
case 0xB1: arith(A, |, C); break;;
|
||||
case 0xB2: arith(A, |, D); break;;
|
||||
case 0xB3: arith(A, |, E); break;;
|
||||
case 0xB4: arith(A, |, H); break;;
|
||||
case 0xB5: arith(A, |, L); break;;
|
||||
case 0xB6: arith(A, |, M); break;;
|
||||
case 0xB7: arith(A, |, A); break;;
|
||||
|
||||
case 0xB8: aritht(A, -, B); break;;
|
||||
case 0xB9: aritht(A, -, C); break;;
|
||||
case 0xBA: aritht(A, -, D); break;;
|
||||
case 0xBB: aritht(A, -, E); break;;
|
||||
case 0xBC: aritht(A, -, H); break;;
|
||||
case 0xBD: aritht(A, -, L); break;;
|
||||
case 0xBE: aritht(A, -, M); break;;
|
||||
case 0xBF: aritht(A, -, A); break;;
|
||||
|
||||
case 0xC0: if (!flags.z) IP=pop(); break;;
|
||||
case 0xC1: BC=pop(); break;;
|
||||
case 0xC2: tmp=imm16(); if (!flags.z) IP=tmp; break;;
|
||||
case 0xC3: IP=imm16(); break;;
|
||||
case 0xC4: tmp=imm16(); if (!flags.z) call(tmp); break;;
|
||||
case 0xC5: push(BC); break;;
|
||||
case 0xC6: arith(A, +, imm8()); break;;
|
||||
case 0xC7: interrupt(0); break;;
|
||||
|
||||
case 0xC8: if (flags.z) IP=pop(); break;;
|
||||
case 0xC9: IP=pop(); break;;
|
||||
case 0xCA: tmp=imm16(); if (flags.z) IP=tmp; break;;
|
||||
case 0xCC: tmp=imm16(); if (flags.z) call(tmp); break;;
|
||||
case 0xCD: call(imm16()); break;;
|
||||
case 0xCE: arith(A, +flags.c+, imm8()); break;;
|
||||
case 0xCF: interrupt(1); break;;
|
||||
|
||||
case 0xD0: if (!flags.c) IP=pop(); break;;
|
||||
case 0xD1: DE=pop(); break;;
|
||||
case 0xD2: tmp=imm16(); if (!flags.c) IP=tmp; break;;
|
||||
case 0xD3: out(imm8()); break;;
|
||||
case 0xD4: tmp=imm16(); if (!flags.c) call(tmp); break;;
|
||||
case 0xD5: push(DE); break;;
|
||||
case 0xD6: arith(A, -, imm8()); break;;
|
||||
case 0xD7: interrupt(2); break;;
|
||||
|
||||
case 0xD8: if (flags.c) IP=pop(); break;;
|
||||
case 0xDA: tmp=imm16(); if (flags.c) IP=tmp; break;;
|
||||
case 0xDB: in(imm8()); break;;
|
||||
case 0xDC: tmp=imm16(); if (flags.c) call(tmp); break;;
|
||||
case 0xDE: arith(A, -flags.c-, imm8()); break;;
|
||||
case 0xDF: interrupt(3); break;;
|
||||
|
||||
case 0xE0: if (!flags.p) IP=pop(); break;;
|
||||
case 0xE1: HL=pop(); break;;
|
||||
case 0xE2: tmp=imm16(); if (!flags.p) IP=tmp; break;;
|
||||
case 0xE3: tmp=HL; HL=pop(); push(tmp); break;;
|
||||
case 0xE4: tmp=imm16(); if (!flags.p) call(tmp); break;;
|
||||
case 0xE5: push(HL); break;;
|
||||
case 0xE6: arith(A, &, imm8()); break;;
|
||||
case 0xE7: interrupt(4); break;;
|
||||
|
||||
case 0xE8: if (flags.p) IP=pop(); break;;
|
||||
case 0xE9: IP=HL; break;;
|
||||
case 0xEA: tmp=imm16(); if (flags.p) IP=tmp; break;;
|
||||
case 0xEB: tmp=HL; HL=DE; DE=tmp;; break;;
|
||||
case 0xEC: tmp=imm16(); if (flags.p) call(tmp); break;;
|
||||
case 0xEE: arith(A, ^, imm8()); break;;
|
||||
case 0xEF: interrupt(5); break;;
|
||||
|
||||
case 0xF0: if (!flags.s) IP=pop(); break;;
|
||||
case 0xF1: regset.regp.psw=pop(); break;;
|
||||
case 0xF2: tmp=imm16(); if (!flags.s) IP=tmp; break;;
|
||||
case 0xF4: tmp=imm16(); if (!flags.s) call(tmp); break;;
|
||||
case 0xF5: push(regset.regp.psw); break;;
|
||||
case 0xF6: arith(A, |, imm8()); break;;
|
||||
case 0xF7: interrupt(6); break;;
|
||||
|
||||
case 0xF8: if (flags.s) IP=pop(); break;;
|
||||
case 0xF9: SP=HL; break;;
|
||||
case 0xFA: tmp=imm16(); if (flags.s) IP=tmp; break;;
|
||||
case 0xFC: tmp=imm16(); if (flags.s) call(tmp); break;;
|
||||
case 0xFE: aritht(A, -, imm8()); break;;
|
||||
case 0xFF: interrupt(7); break;;
|
||||
|
||||
default:
|
||||
IP--;
|
||||
dump();
|
||||
fprintf(stderr, "Invalid opcode at IP=%04X\n", IP);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void copy_cmdline(char* str) {
|
||||
int i, c;
|
||||
uint8_t *len = &mem[0x80];
|
||||
char* ptr = (char*)&mem[0x81];
|
||||
c = strlen(str);
|
||||
// Clip at max length
|
||||
if (c>0x7E) {
|
||||
fprintf(stderr, "Command line too long, max is 126 bytes\n");
|
||||
exit(1);
|
||||
}
|
||||
memcpy(ptr, str, c);
|
||||
ptr[c]=0x0D;
|
||||
*len=c;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
memset(&mem, sizeof(mem), 0);
|
||||
// Prepare default exit into int 20h
|
||||
mem[0]=0x76;
|
||||
push(0);
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
while(argc && argv[0][0]=='-') {
|
||||
switch(argv[0][1]) {
|
||||
default:
|
||||
fprintf(stderr, "Unknown option %s\n", argv[0]);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (argc) {
|
||||
FILE* fd = fopen(argv[0], "r");
|
||||
fread(mem + IP, 1, sizeof(mem) - IP, fd);
|
||||
argc--;
|
||||
argv++;
|
||||
} else {
|
||||
fprintf(stderr, "No COM file specified\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (argc) {
|
||||
copy_cmdline(argv[0]);
|
||||
} else {
|
||||
copy_cmdline("");
|
||||
}
|
||||
|
||||
while(1) {
|
||||
dump();
|
||||
step();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user