flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Fat12/RAM-DISK OS with DOSemu for Floppy or CD-R with FASM

Author
Thread Post new topic Reply to topic
mbr_tsr



Joined: 03 Apr 2011
Posts: 4903
mbr_tsr
;HOLY SMOKE, THIS OS NOW RUNS FASM.EXE
;Step1 = Copy FreeDOS Boot Sector to a 512 byte file on A: or B:
;Step2 = Copy KERNEL.SYS and COMMAND.COM to A: or B:
;Step3 = Copy FASM.EXE to drive A: or B:
;Step4 = Boot to Zorker and type 'boot' and name of boot sector file
;and BANG! You can FASM.EXE the ASM Files
;i bet you can run other boot sectors for any OS too
;Once you are done, You can go right back to Zorker; like MAGIC!

Code:
;======================================================================
;Zorker Fat12/RAM-DISK Kernel with DOSemu for Floppy or CD-R (By S.T.C.)
;Start this COM file at Org 100H from Boot Sector or DOS
;Enter the name of a .COM file to execute (assumes .COM when no extension)
;You can enter and execute hex from the main command prompt
;Running .COM files can use all Zorker Interrupts
;'disk' command toggles Disk Writes to RAM Drive at 9000:0000h
;'drive' command selects between drive A: and B:
;Note: Files for Read/Write must already exist on Disk
;Uses segments 0x3000 and 0x6000 for File I/O (RESERVED)
;At the bottom of this code is an Anything: label for whatever
;Finally, 'boot' command loads and runs a boot sector from 512 byte file
;======================================================================
DRIVE = 0    ;0=A 1=B
;======================================================================
Org  0x0100
;======================================================================
mov  ax, cs
mov  ds, ax
mov  es, ax
mov  si, OldVect
call SaveVect
;======================================================================
jmp  StartInit
;======================================================================
BytesPerSector        dw 0x0200
SectorsPerCluster     db 0x01
ReservedSectors       dw 0x0001
TotalFATs             db 0x01
MaxRootEntries        dw 0x00E0
SectorsPerFAT         dw 0x0012
SectorsPerTrack       dw 0x0012
NumHeads              dw 0x0002
DriveNumber           db DRIVE
absoluteSector        db 0x00
absoluteHead          db 0x00
absoluteTrack         db 0x00
datasector            dw 0x0000
cluster               dw 0x0000
;======================================================================

StartInit:
RestartOS:

mov  dx, Fat12
mov  al, byte [cs:SysInt]
call SetV
mov  dx, MsDos
mov  al, byte [cs:DosInt]
call SetV

;mov  dx, Timer
;mov  al, byte [cs:TimInt]
;call SetV
;create some timers 80h to 8Eh
;create OverKill timer 8Fh

;mov  al, 80h
;mov  dx, NulInt
;call SetV
;mov  al, 81h
;mov  dx, NulInt
;call SetV
;mov  al, 82h
;mov  dx, NulInt
;call SetV
;mov  al, 83h
;mov  dx, NulInt
;call SetV
;mov  al, 84h
;mov  dx, NulInt
;call SetV
;mov  al, 85h
;mov  dx, NulInt
;call SetV
;mov  al, 86h
;mov  dx, NulInt
;call SetV
;mov  al, 87h
;mov  dx, NulInt
;call SetV
;mov  al, 88h
;mov  dx, NulInt
;call SetV
;mov  al, 89h
;mov  dx, NulInt
;call SetV
;mov  al, 8ah
;mov  dx, NulInt
;call SetV
;mov  al, 8bh
;mov  dx, NulInt
;call SetV
;mov  al, 8ch
;mov  dx, NulInt
;call SetV
;mov  al, 8dh
;mov  dx, NulInt
;call SetV
;mov  al, 8eh
;mov  dx, NulInt
;call SetV
;mov  al, 8fh
;mov  dx, NulInt
;call SetV
;

;int 90h and 21h hook vector ints
mov  al, 91h
mov  dx, NulInt
call SetV
mov  al, 92h
mov  dx, NulInt
call SetV

;======================================================================
mov  si, NewVect
call SaveVect
;======================================================================

Start:
;======================================================================
mov  ax, cs
mov  ds, ax
mov  es, ax
;======================================================================
mov  word [cs:ImageAddr], ImageName
mov  si, Intro
call Show
call GetImageName
;======================================================================
cmp  byte [cs:Any], 1
je   Start
;======================================================================
mov  si, Loading
mov  bl, 10
call Show
;======================================================================
jmp  Shell
;======================================================================
Fat12:
int  91h
cmp  bp, 0
je   bp0l
cmp  bp, 1
je   bp1l
cmp  bp, 2
je   bp2l
cmp  bp, 3
je   bp3l
cmp  bp, 4
je   bp4l
cmp  bp, 5
je   bp5l
cmp  bp, 6
je   bp6l
cmp  bp, 7
je   bp7l
cmp  bp, 8
je   bp8l
cmp  bp, 9
je   bp9l
cmp  bp, 0x12
je   bp12l
cmp  bp, 0x13
je   bp13l
iret
;======================================================================
bp0l:  jmp bp0
bp1l:  jmp bp1
bp2l:  jmp bp2
bp3l:  jmp bp3
bp4l:  jmp bp4
bp5l:  jmp bp5
bp6l:  jmp bp6
bp7l:  jmp bp7
bp8l:  jmp bp8
bp9l:  jmp bp9
bp12l: jmp bp12
bp13l: jmp bp13
;======================================================================
bp0:
push ds
push cs
pop  ds
call LoadRoot
pop  ds
iret
;========================
bp1:
push ds
push cs
pop  ds
call FindFile
pop  ds
iret
;========================
bp2:
push ds
push cs
pop  ds
call LoadFat
pop  ds
iret
;========================
bp3:
push ds
push cs
pop  ds
call FileIO
pop  ds
iret
;========================
bp4:
jmp Launch
;========================
bp5:
call CheckIfFileExists
iret
;========================
bp6:
push cs
pop  es
mov  di, word [cs:ImageAddr]

CopyMem1:
mov  AL, byte [ds:SI]
mov  byte [es:DI], AL
cmp  AL, 0
je   DoneThis1
inc  SI
inc  DI
jmp  CopyMem1
DoneThis1:

push cs
pop  ds
mov  si, word [cs:ImageAddr]
call StrLen
call Parse
call ChkCmds
cmp  byte [cs:Any], 1
je   SkipStuff2
call CmdLine
mov  di, word [cs:ImageAddr]
call Convert
mov  si, Loading
mov  bl, 10
call Show
jmp  Shell
SkipStuff2:
iret
;======================================================================
bp7:
push ds
push cs
pop  ds
call LoadRoot
call PrintCrLf
call ShowNames
pop  ds
iret
;======================================================================
bp8:
pusha
push es
push di
push cs
pop  es
mov  di, word [cs:ImageAddr]

CopyMem2:
mov  AL, byte [ds:SI]
mov  byte [es:DI], AL
cmp  AL, 0
je   DoneThis2
inc  SI
inc  DI
jmp  CopyMem2
DoneThis2:

push cs
pop  ds
mov  di, word [cs:ImageAddr]
call Convert
mov  si, msg0
call Show
mov  bp, 0
call Sys
mov  si, msg1
call Show
mov  si, word [cs:ImageAddr]
call Show
mov  bp, 1
call Sys
mov  si, msg2
call Show
mov  bp, 2
call Sys
mov  si, msg5
call Show
pop  bx
pop  es
mov  [cs:Status], 'w'
mov  byte [cs:io], 0x03
call FileIOz
mov  byte [cs:io], 0x02
mov  [cs:Status], 'r'
popa
iret
;======================================================================
bp9:
pusha
push ds

push es
push di

push cs
pop  es
mov  di, word [cs:ImageAddr]

CopyMem3:
mov  AL, byte [ds:SI]
mov  byte [es:DI], AL
cmp  AL, 0
je   DoneThis3
inc  SI
inc  DI
jmp  CopyMem3
DoneThis3:

push cs
pop  ds
mov  di, word [cs:ImageAddr]
call Convert
mov  si, msg0
call Show
mov  bp, 0
call Sys
mov  si, msg1
call Show
mov  si, word [cs:ImageAddr]
call Show
mov  bp, 1
call Sys
mov  si, msg2
call Show
mov  bp, 2
call Sys
mov  [cs:Status], 'r'
mov  si, msg3
call Show
pop  bx
pop  es
call FileIOz
call PrintCrLf
pop ds
popa
iret
;======================================================================
bp12:
push ax
push si
push di
WriteHex:
call ScnHex
stosb
lodsb
cmp  al, 0
je   Bud
jmp  WriteHex
Bud:
pop  di
pop  si
pop  ax
iret
;======================================================================
bp13:
push ax
push dx
mov  ax, es
mov  ds, ax
mov  dx, di
mov  al, byte [cs:UseInt]
mov  byte [cs:Patch+1], al
call SetV
Patch:
db   0xCD, 0x00
pop  dx
pop  ax
iret
;======================================================================
LoadRoot:
xor  cx, cx
xor  dx, dx
mov  ax, 0x0020
mul  WORD [cs:MaxRootEntries]
div  WORD [cs:BytesPerSector]
xchg ax, cx
mov  al, BYTE [cs:TotalFATs]
mul  WORD [cs:SectorsPerFAT]
add  ax, WORD [cs:ReservedSectors]
mov  WORD [cs:datasector], ax
add  WORD [cs:datasector], cx
push cs
pop  es
mov  bx, Buff1
mov  [cs:Status], 'r'
mov  byte [cs:io], 0x02
call SectorIO
ret
;======================================================================
FindFile:
push cs
pop  ds
mov  di, Buff1
Loop1:
push cx
mov  cx, 0x000B
mov  si, word [cs:ImageAddr]
push di
rep  cmpsb
pop  di
pop  cx
je   AllDone
add  di, 0x0020
loop Loop1
mov  si, err1
mov  bl, 12
call Show
pop  ax
jmp  Start
AllDone:
ret
;======================================================================
LoadFat:
mov  dx, WORD [cs:di + 0x001A]
mov  WORD [cs:cluster], dx
mov  ax, WORD [cs:ReservedSectors]
mov  bx, Buff1
mov  cx, WORD [cs:SectorsPerFAT]
mov  [cs:Status], 'r'
mov  byte [cs:io], 0x02
call SectorIO
ret
;======================================================================
FileIOz:
cmp  [cs:Status], 'w'
jne  NotWritingOScrap
push bx
jmp LoadImage
NotWritingOScrap:
mov  byte [cs:RestoreMe], 1
mov  word [cs:RestoreSeg], es
mov  word [cs:RestoreOff], bx
mov  ax, word [cs:addrS2]
mov  es, ax
mov  bx, word [cs:addrO2]
push bx
jmp LoadImage
FileIO:
mov  ax, word [cs:addrS1]
mov  es, ax
mov  bx, word [cs:addrO1]
push bx
LoadImage:
mov  ax, WORD [cs:cluster]
pop  bx
call ClusterLBA
xor  cx, cx
mov  cl, BYTE [cs:SectorsPerCluster]
call SectorIO
push bx
mov  ax, WORD [cs:cluster]
mov  cx, ax
mov  dx, ax
shr  dx, 0x0001
add  cx, dx
mov  bx, Buff1
add  bx, cx
mov  dx, WORD [bx]
test ax, 0x0001
jnz  OddBall
EvenBall:
and  dx, 0000111111111111b
jmp  Done1
OddBall:
shr  dx, 0x0004
Done1:
mov  WORD [cs:cluster], dx
cmp  dx, 0x0FF0
jb   LoadImage
Done:
pop  ax
cmp  byte [cs:RestoreMe], 1
jne  SkipShift
cmp  [cs:Status], 'w'
je   DoneWrite
push ds
push es
pusha
mov  ax, word [cs:addrS2]
mov  ds, ax
mov  si, word [cs:addrO2]
mov  es, word [cs:RestoreSeg]
mov  di, word [cs:RestoreOff]
mov  cx, word [cs:GotSize]
cmp  cx, [cs:FileSize]
jg   WantsLess
mov  cx, word [cs:FileSize]
mov  word [cs:GotSize], cx
WantsLess:
ShiftMemory:
lodsb
stosb
loop ShiftMemory
popa
pop es
pop ds
DoneWrite:
SkipShift:
mov  byte [cs:RestoreMe], 0
ret
;======================================================================
Launch:
mov  ax, WORD [cs:addrS1]
mov  ds, ax
mov  es, ax
push WORD [cs:addrS1]
push WORD [cs:addrO1]
retf
;======================================================================
Show:
push ax
push bx
push si
Show1:
lodsb
cmp  al, 0
je   Okay
cmp  al, '$'
je   Okay
mov  ah, 0x0E
mov  bh, 0x00
mov  bl, 0x07
int  0x10
jmp  Show1
Okay:
pop  si
pop  bx
pop  ax
ret
;======================================================================
;SectorIO
;reads cx sectors from disk starting at ax into
;memory location es:bx
SectorIO:
Main:
mov  di, 0x0005
Sloop:
push ax
push bx
push cx
call Lbachs
mov  ah, byte [cs:io]
mov  al, 0x01
mov  ch, BYTE [cs:absoluteTrack]
mov  cl, BYTE [cs:absoluteSector]
mov  dh, BYTE [cs:absoluteHead]
mov  dl, BYTE [cs:DriveNumber]
int  0x13
jnc  Success
xor  ax, ax
int  0x13
dec  di
pop  cx
pop  bx
pop  ax
jnz  Sloop
mov  [cs:Status], 'r'
mov  byte [cs:io], 0x02
mov  si, err4
mov  bl, 12
call Show
ret
Success:
push bx
mov  bl, 2
mov  si, Cont
call Show
pop  bx
pop  cx
pop  bx
pop  ax
add  bx, WORD [cs:BytesPerSector]
inc  ax
add  word [cs:GotSize], 512
loop Main
ret
;======================================================================
;ClusterLBA
;convert FAT cluster into LBA addressing scheme
;LBA = (cluster - 2) * sectors per cluster
ClusterLBA:
sub  ax, 0x0002
xor  cx, cx
mov  cl, BYTE [cs:SectorsPerCluster]
mul  cx
add  ax, WORD [cs:datasector]
ret
;======================================================================
;Lbachs
;convert ax LBA addressing scheme to CHS addressing scheme
;absolute sector = (logical sector / sectors per track) + 1
;absolute head   = (logical sector / sectors per track) MOD number of heads
;absolute track  = logical sector / (sectors per track * number of heads)
Lbachs:
xor  dx, dx
div  WORD [cs:SectorsPerTrack]
inc  dl
mov  BYTE [cs:absoluteSector], dl
xor  dx, dx
div  WORD [cs:NumHeads]
mov  BYTE [cs:absoluteHead], dl
mov  BYTE [cs:absoluteTrack], al
ret
;======================================================================
Input:
push ax
push bx
push cx
push dx
push bp
push si
mov  ah, 0x03
mov  bh, 0
int  0x10
mov  byte [cs:OldPos], dl
mov  BP, si
GetInput3:
mov  ah, 0
int  0x16
cmp  al, 8
jne  NotBackSpace
mov  ah, 0x03
mov  bh, 0
int  0x10
cmp  byte [cs:OldPos], dl
je   GetInput3
mov  ah, 0x03
mov  bh, 0
int  0x10
dec  dl
mov  ah, 0x02
mov  bh, 0
int  0x10
mov  bx, 000fh
mov  al, ' '
call putc
mov  ah, 0x03
mov  bh, 0
int  0x10
cmp  dl, 0
jle  NotDecDrip
dec  dl
NotDecDrip:
mov  ah, 0x02
mov  bh, 0
int  0x10
cmp  SI, BP
jle  char0
dec  SI
char0:
jmp  SkipBS
NotBackSpace:
mov  bx, 000fh
call putc
cmp  al, 13
jne  NotIOver3
mov  byte [ds:SI], 0
jmp  GotIt3
NotIOver3:
mov  byte [ds:SI], al
mov  byte [ds:SI+1], 0
inc  SI
SkipBS:
jmp  GetInput3
GotIt3:
pop  si
pop  bp
pop  dx
pop  cx
pop  bx
pop  ax
ret
;======================================================================
;convert standard file name to FAT12 image file name
Convert:
push di
push bp
mov  BX, 0
lopo:
cmp  BYTE [DI+BX], '.'
jne  notdot
mov  AH, [DI+BX+1]
mov  AL, [DI+BX+2]
mov  DH, [DI+BX+3]
cmp  AH, 0
jne  nz1
mov  AH, ' '
mov  AL, ' '
mov  DH, ' '
nz1:
cmp  AL, 0
jne  nz2
mov  AL, ' '
mov  DH, ' '
nz2:
cmp  DH, 0
jne  nz3
mov  DH, ' '
nz3:
n8:
mov  byte [DI+BX], ' '
inc  BX
cmp  BX, 8
jle  n8
cmp  AH,'a'
jb   KeepIt2
cmp  AH,'z'
ja   KeepIt2
sub  AH,32
KeepIt2:
cmp  AL,'a'
jb   KeepIt3
cmp  AL,'z'
ja   KeepIt3
sub  AL,32
KeepIt3:
cmp  DH,'a'
jb   KeepIt4
cmp  DH,'z'
ja   KeepIt4
sub  DH,32
KeepIt4:
mov  BYTE [DI+8], AH
mov  BYTE [DI+9], AL
mov  BYTE [DI+10], DH
mov  BYTE [DI+11], 0
jmp  overr
notdot:
cmp  BYTE [DI+BX], 0
jne  noppp
total0:
mov  BYTE [DI+BX], ' '
inc  BX
cmp  BX, 12
jl   total0
jmp  overr
noppp:
UpCase:
cmp  BYTE [DI+BX],'a'
jb   KeepIt
cmp  BYTE [DI+BX],'z'
ja   KeepIt
sub  BYTE [DI+BX],32
KeepIt:
inc  BX
cmp  BX, 11
jle  lopo
overr:
mov  byte [DI+11], 0
pop  bp
pop  di
ret
;==================================================================
putc:
mov  ah, 0x0e
mov  bx, 0x0007
int  0x10
ret
;==================================================================
Compare:
;Compare SI with DI al = 1 if match
push bx
mov  bx, 0
c_loop:
mov  al, byte [si+bx]
cmp  byte [di+bx], al
jne  c_nope
cmp  al, 00
je   c_yup
inc  bx
jmp  c_loop
c_yup:
pop  bx
mov  al, 01
ret
c_nope:
pop  bx
mov  al, 00
ret
;======================================================================
Parse:
push ax
push si
Parse1:
mov  al, byte [ds:SI]
cmp  al, ','
jne  NopThat
mov  al, 0
NopThat:
mov  byte [ds:SI], al
inc  SI
loop Parse1
pop  si
pop  ax
ret
;======================================================================
Point:
push AX
push CX
push DX
mov  DL, AL
mov  CX, 64000
cmp  DL, 0
je   AllOverP
CounterLoop:
cmp  byte [SI], 0
jne  NotUpCount
inc  SI
dec  DL
cmp  DL, 0
je   AllOverP
NotUpCount:
inc SI
loop CounterLoop
AllOverP:
pop  DX
pop  CX
pop  AX
ret
;======================================================================
ScnHex:
push cx
push dx
mov  cl,4
xor  dx,dx
scn:
lodsb
cmp  al,'0'
jb   endr
cmp  al,'9'
jna  decdgt
or   al,0x20
cmp  al,'a'
jb   endr
cmp  al,'z'
ja   endr
sub  al,'a'-'9'-1
decdgt:
sub  al,'0'
shl  dx,cl
or   dl,al
jmp  scn
endr:
xchg dx, ax
dec  si
pop  dx
pop  cx
ret
;======================================================================
SaveVect:
push ax
push cx
push si
push di
push es
push ds
mov  di, si
mov  si, 0
mov  ax, 0
mov  ds, ax
mov  cx, 4 * 256
CpyVect:
lodsb
stosb
loop CpyVect
pop  ds
pop  es
pop  di
pop  si
pop  cx
pop  ax
ret
;======================================================================
RestoreVect:
push ax
push cx
push si
push di
push es
push ds
mov  di, 0
mov  ax, 0
mov  es, ax
mov  cx, 4 * 256
RstVect:
lodsb
stosb
loop RstVect
pop  ds
pop  es
pop  di
pop  si
pop  cx
pop  ax
ret
;======================================================================
MsDos:
int  92h
cmp  ah, 0x09
je   msdos9
cmp  ah, 0x0a
je   msdosa
cmp  ah, 0x0c
je   msdosc
cmp  ah, 0x3d
je   msdos3d
cmp  ah, 0x3f
je   msdos3f
cmp  ah, 0x40
je   msdos40
cmp  ah, 0x4c
je   msdos4c
iret
;======================================================================
msdos9:  jmp msdos09
msdosa:  jmp msdos0a
msdosc:  jmp msdos0c
msdos3d: jmp msdos03d
msdos3f: jmp msdos03f
msdos40: jmp msdos040
msdos4c: jmp msdos04c
;======================================================================
msdos09:
push sp
push bp
push ds
push es
push fs
pusha
mov  SI, DX
call Show
popa
pop  fs
pop  es
pop  ds
pop  bp
pop  sp
iret
;======================================================================
msdos0a:
push  sp
push  bp
push  ds
push  es
push  fs
pusha
mov   SI, DX
add   SI, 1
mov   byte [SI], 64
add   SI, 1
call  Input
popa
pop  fs
pop  es
pop  ds
pop  bp
pop  sp
iret
;==================================================================
msdos0c:
push sp
push bp
push ds
push es
push fs
pusha
mov  SI, DX
mov  byte [SI], 0
mov  byte [SI+1], 0
mov  byte [SI+2], 0
mov  ah, al
int  0x21
popa
pop  fs
pop  es
pop  ds
pop  bp
pop  sp
iret
;======================================================================
msdos03d:
push  sp
push  bp
push  ds
push  es
push  fs
pusha
mov   bp, ds
push  cs
push  cs
pop   ds
pop   es
mov  word [cs:ImageAddr], ImageName2
call  CopyName
mov  word [cs:ImageAddr], ImageName
popa
pop  fs
pop  es
pop  ds
pop  bp
pop  sp
clc
iret
;======================================================================
;int 90h function 08h Write buffer es:di to filename in ds:si
;int 90h function 09h Read filename in ds:si into buffer es:di
msdos03f:
push  sp
push  bp
push  ds
push  es
push  fs
push  si
push  di
pusha

push ds
push dx

mov  [cs:FileSize], cx
mov  ax, cs
mov  ds, ax

mov  si, msguse
call Show
mov  si, ImageName2
call Show

mov  si, msgr
call Show
call GetFileName
mov  ax, cs
mov  ds, ax

push cs
pop  ds
pop  di
pop  es
mov  bp, 9
mov  word [cs:GotSize], 0
call Sys
mov  word [cs:ImageAddr], ImageName

popa
pop  di
pop  si
pop  fs
pop  es
pop  ds
pop  bp
pop  sp
mov  ax, word [cs:GotSize]
clc
iret
;======================================================================
msdos040:
push  sp
push  bp
push  ds
push  es
push  fs
push  si
push  di
pusha

push ds
push dx

mov  [cs:FileSize], cx
mov  ax, cs
mov  ds, ax

cmp  byte [cs:RamDrive], 1
jne  NotRamDisk
mov  si, msgRamDrive
call Show
pop  dx
mov  cx, 0xFFFF
mov  si, dx
mov  ax, 0x9000
mov  es, ax
mov  di, 0
pop  ds
CopyTheStuff:
lodsb
stosb
loop CopyTheStuff
jmp  DoneWriteToRamDrive
NotRamDisk:

mov  si, msguse
call Show
mov  si, ImageName2
call Show

mov  si, msgw
call Show
call GetFileName

push cs
pop  ds
pop  di
pop  es
mov  bp, 8
call Sys
mov  word [cs:ImageAddr], ImageName

DoneWriteToRamDrive:
popa
pop  di
pop  si
pop  fs
pop  es
pop  ds
pop  bp
pop  sp
mov  ax, [cs:FileSize]
clc
iret
;======================================================================
msdos04c:
push cs
push cs
pop  ds
pop  es
jmp  Start
;======================================================================
SetV:
pusha
cli
xor  bx, bx
mov  es, bx
mov  bl, 4
mul  bl
mov  bx, ax
mov  word [es:bx], dx
add  bx, 2
mov  word [es:bx], ds
push cs
pop  es
sti
popa
ret
;======================================================================
GetV:
cli
xor  bx, bx
mov  es, bx
mov  bl, 4
mul  bl
mov  bx, ax
mov  dx, word [es:bx]
add  bx, 2
mov  ds, word [es:bx]
push cs
pop  es
sti
ret
;======================================================================
Shell:
mov  si, msg0
call Show
mov  bp, 0
call Sys
mov  si, msg1
call Show
mov  si, word [cs:ImageAddr]
call Show
mov  bp, 1
call Sys
mov  si, msg2
call Show
mov  bp, 2
call Sys
mov  si, msg3
call Show
mov  [cs:Status], 'r'
mov  bp, 3
call Sys
call PrintCrLf
mov  si, msg4
call Show
jmp  Launch
;======================================================================
ChkCmds:
push cs
pop  ds
mov  si, word [cs:ImageAddr]
mov  byte [cs:Any], 1
mov  di, iq
call Compare
cmp  al, 1
jne  NotQuit
push cs
push cs
pop  ds
pop  es
mov  si, OldVect
call RestoreVect
push cs
pop  ds
mov  si, msgoff
call Show
mov  ah, 0x4c
int  0x21
NotQuit:
;======================================================================
mov  di, ilist
call Compare
cmp  al, 1
jne  Notilist
mov  bp, 7
call Sys
jmp  RetFromList
Notilist:
;======================================================================
mov  di, ihex
call Compare
cmp  al, 1
jne  NotHex
mov  si, word [cs:ImageAddr]
mov  al, 1
call Point
push cs
push cs
pop  es
pop  ds
mov  di, HexDat
GetHexDat:
cmp  byte [ds:si], 0
je   Bud000
cmp  byte [ds:si], ' '
je   RedoSp
call ScnHex
stosb
RedoSp:
inc  si
jmp  GetHexDat
Bud000:
mov  al, 0xc3
stosb
call HexDat
jmp RetFromList
NotHex:
;======================================================================
mov  di, ihelp
call Compare
cmp  al, 1
jne  Notihelp
mov  si, help
call Show
jmp RetFromList
Notihelp:
;======================================================================
mov  di, idisk
call Compare
cmp  al, 1
jne  Notidisk
cmp  byte [cs:RamDrive], 1
je   SetRDto0
cmp  byte [cs:RamDrive], 0
je   SetRDto1
mov  byte [cs:RamDrive], 1
mov  si, msgRDon
call Show
jmp RetFromList
SetRDto0:
mov  byte [cs:RamDrive], 0
mov  si, msgRDoff
call Show
jmp RetFromList
SetRDto1:
mov  byte [cs:RamDrive], 1
mov  si, msgRDon
call Show
jmp RetFromList
Notidisk:
;======================================================================
mov  di, idrive
call Compare
cmp  al, 1
jne  Notidrive
cmp  byte [cs:DriveNumber], 1
je   SetDto0
cmp  byte [cs:DriveNumber], 0
je   SetDto1
mov  byte [cs:DriveNumber], 1
mov  si, driveb
call Show
jmp RetFromList
SetDto0:
mov  byte [cs:DriveNumber], 0
mov  si, drivea
call Show
jmp RetFromList
SetDto1:
mov  byte [cs:DriveNumber], 1
mov  si, driveb
call Show
jmp RetFromList
Notidrive:
;======================================================================
mov  di, iboot
call Compare
cmp  al, 1
jne  Notiboot
mov si, bootsec
call Show
mov dx, bs
mov ah, 3dh
mov al, 2
int 21h
mov ax, 0x0000
mov ds, ax
mov ah, 0x3f
mov cx, 512
mov dx, 0x7c00
int 21h
mov dl, byte [cs:DriveNumber]
mov ax, 0
mov ds, ax
mov es, ax
jmp 0000:7c00h
jmp RetFromList
Notiboot:
;======================================================================
mov  byte [cs:Any], 0
RetFromList:
call PrintCrLf
ret
;======================================================================
;parse command line paramiters
CmdLine:
push es
push bp
mov  ax, word [cs:addrS1]
mov  es, ax
mov  ax, 80h
mov  bp, ax
mov  BX, 0
mov  di, word [cs:ImageAddr]
clearparam:
mov  byte [es: bp], 0
inc  BP
inc  BX
cmp  BX, 80
jl   clearparam
mov  BX, 0
mov  byte [es:81h], 0
parse:
cmp  byte [di+BX], 0
je   done1
cmp  byte [di+BX], ' '
jne  skp
push BX
mov  byte [es:80h], 80
parse2:
mov  ax, word [cs:addrS1]
mov  es, ax
mov  ax, 81h
mov  bp, ax
parse3:
mov  AL, byte [di+BX]
mov  byte [es: bp], AL
cmp  AL, 0
je   doneW
inc  BP
inc  BX
jmp  parse3
skp:
inc  BX
jmp  parse
doneW:
SkipSpace:
pop  BX
mov  byte [di+BX], 0
done1:
pop  bp
pop  es
ret
;======================================================================
CheckIfFileExists:
push bx
push cx
push dx
push si
push di
push ds
push es
mov  bx, si
mov  DI, word [cs:ImageAddr]
LoopDSA:
mov  al, byte [ds:bx]
mov  byte [cs:di], al
cmp  al, 0
je   DoneDSA
inc  bx
inc  di
jmp  LoopDSA
DoneDSA:
mov  ax, cs
mov  ds, ax
mov  es, ax
mov  DI, word [cs:ImageAddr]
call Convert
call LoadRoot
mov  SI, word [cs:ImageAddr]
call Exist
pop  es
pop  ds
pop  di
pop  si
pop  dx
pop  cx
pop  bx
ret
;======================================================================
Exist:
push bx
push cx
push dx
push bp
push ds
push es
mov  ax, cs
mov  ds, ax
mov  cx, WORD [MaxRootEntries]
mov  di, Buff1
LoopsX:
push cx
mov  cx, 0x000B
mov  si, word [cs:ImageAddr]
push di
rep  cmpsb
pop  di
pop  cx
je   FileFound
add  di, 0x0020
loop LoopsX
mov  ax, 0x0000
jmp  Skipper
FileFound:
mov  ax, 0x0001
Skipper:
pop  es
pop  ds
pop  bp
pop  dx
pop  cx
pop  bx
ret
;======================================================================
ShowNames:
push ax
push bx
push cx
push dx
push bp
push ds
push es
push cs
pop  ds
mov  cx, WORD [MaxRootEntries]
mov  si, Buff1
mov  dx, 0
Loops1S:
push cx
call StrLen
cmp  cx, 11
jl   TooSmall
mov  al, '['
mov  bx, 0x000b
call putc
mov  byte [si+11], 0
call Show
mov  al, ']'
mov  bx, 0x000b
call putc
mov  al, ' '
mov  bx, 0x0001
call putc
inc  dx
cmp  dx, 5
jne  NotDX5
mov  dx, 0
call PrintCrLf
NotDX5:
TooSmall:
pop  cx
add  si, 0x0020
cmp  byte [cs:si], 0
je   DoneListing
loop Loops1S
DoneListing:
pop  es
pop  ds
pop  bp
pop  dx
pop  cx
pop  bx
pop  ax
ret
;======================================================================
StrLen:
push SI
mov  cx, 0
GetLen:
cmp  byte [ds:si], 0
je   OverLen
cmp  cx, 0xffff
je   OverLen
inc  CX
inc  SI
jmp  GetLen
OverLen:
pop  SI
ret
;=====================================================================
PrintCrLf:
push si
mov  si, CrLf
call Show
pop  si
ret
;=====================================================================
GetFileName:
pusha
ReGetFname:
mov  ax, cs
mov  ds, ax
mov  es, ax
mov  si, word [cs:ImageAddr]
mov  word [cs:ImageAddr], si
call Input
cmp  byte [cs:si], 0
jne  NotImg2
mov  si, ImageName2
mov  bp, ImageName2
mov  word [cs:ImageAddr], si
NotImg2:
call PrintCrLf
call StrLen
call Parse
call ChkCmds
cmp  byte [cs:Any], 1
je   SkipStuff3
call CmdLine
mov  bp, word [cs:ImageAddr]
mov  di, bp
call Convert
mov  si, bp
call CheckIfFileExists
cmp  al, 1
je   FileDoesExist
mov  si, FileNotFound
call Show
mov  ah, 0
int  0x16
cmp  al, 'a'
je   Abortedr
SkipStuff3:
call PrintCrLf
mov  si, GetFname
call Show
jmp  ReGetFname
Abortedr:
popa
pop eax
pop eax
jmp Start
FileDoesExist:
popa
mov si, word [cs:ImageAddr]
ret
;=====================================================================
GetImageName:
mov  si, word [cs:ImageAddr]
call Input
call PrintCrLf
mov  si, word [cs:ImageAddr]
call StrLen
call Parse
call ChkCmds
cmp  byte [cs:Any], 1
je   SkipStuff1
call CmdLine
mov  di, word [cs:ImageAddr]
call Convert
mov  si, word [cs:ImageAddr]
call CheckIfFileExists
cmp  al, 1
je   NotCOMextAdd
mov  byte [cs:si+8], 'C'
mov  byte [cs:si+9], 'O'
mov  byte [cs:si+10], 'M'
call CheckIfFileExists
cmp  al, 1
je   FileOkay
mov  si, err3
mov  bl, 12
call Show
NotCOMextAdd:
FileOkay:
SkipStuff1:
WasCmd2:
ret
;======================================================================
CopyName:
push  sp
push  bp
push  ds
push  es
push  fs
push  si
push  di
pusha
mov  si, dx
mov  di, word [cs:ImageAddr]
push cs
pop  es
push bp
pop  ds
mov  cx, 90
CopyName1:
lodsb
stosb
loop CopyName1
popa
pop  di
pop  si
pop  fs
pop  es
pop  ds
pop  bp
pop  sp
ret
;=====================================================================
Sys:
push ax
mov  al, byte [cs:SysInt]
mov  byte [cs:TheInt+1], al
TheInt db 0xcd, 0x00
pop  ax
ret
;======================================================================
Timer:
int 80h
int 81h
int 82h
int 83h
int 84h
int 85h
int 86h
int 87h
int 88h
int 89h
int 8ah
int 8bh
int 8ch
int 8dh
int 8eh
push cx
mov  cx, 0x0010
OverKill:
push cx
int 8fh
pop  cx
loop OverKill
pop  cx
iret
;======================================================================
NulInt:
iret
;======================================================================
io           db 0x02
CrLf         db 13, 10, 0x00
Cont         db "รพ", 0x00
Loading      db 13,10,"Loading...", 0x00
Intro        db 13,10,"Zorker OS"
             db 13,10,"Cmd?",0
help         db 13,10,"list = list all files on FAT12 disk"
             db 13,10,"hex,# # # ... = execute hex"
             db 13,10,"disk = Toggle Write between RAM Drive and FAT12"
             db 13,10,"drive = Toggle between Disk I/O Drive A: and B:"
             db 13,10,"boot = Run a 512 byte file containing a boot sector"             
             db 13,10,"q = exit (use only if started from MS-DOS)",0
err1         db 13,10,"error #1 --> File not found", 0x00
err2         db 13,10,"error #2 --> Sector i/o", 0x00
err3         db 13,10,"error #3 --> Invalid command", 0x00
err4         db 13,10,"Disk I/O Buffer has reached 0xFFFF", 0x00
msg0         db 13,10,"msg #0 --> Reading root",0
msg1         db 13,10,"msg #1 --> Finding file: ",0
msg2         db 13,10,"msg #2 --> Reading fat",0
msg3         db 13,10,"msg #3 --> Reading file",0
msg4         db 13,10,"msg #4 --> Launching...",13,10,0
msg5         db 13,10,"msg #5 --> Writing file",0
msguse       db 13,10,"Press ENTER to use: ",0
msgr         db 13,10,"Enter filename to read from or command?",0
msgw         db 13,10,"WARNING: THIS WILL WRITE TO DISK"
             db 13,10,"Enter the filename to write to or command?",0
msgRamDrive  db 13,10,"Writing Data to Segment 0x9000 offset 0x0000 RamDrive",0
msgRDon      db 13,10,"Disk Writes Set to RAM DRIVE at 9000:0000h",0
msgRDoff     db 13,10,"Disk Writes Set to FAT12 Disk Files",0
FileNotFound db 13,10,"File not found (a)bort or (r)etry?",0
GetFname     db 13,10,"Enter Filename or command?",0
msgoff       db 13,10,"Zork is Turned OFF",0
drivea       db 13,10,"Disk I/O Drive Set to A:",0
driveb       db 13,10,"Disk I/O Drive Set to B:",0
bootsec      db 13,10,"Enter the name of a file containing a Boot sector",0
iq           db "q",0
ilist        db "list",0
ihex         db "hex",0
ihelp        db "help",0
idisk        db "disk",0
idrive       db "drive",0
iboot        db "boot",0
bs           db "boot.sec",0
addrS1       dw 0x3000
addrO1       dw 0x0100
addrS2       dw 0x6000
addrO2       dw 0x0000
RestoreSeg   dw 0x0000
RestoreOff   dw 0x0000
FileSize     dw 0x0000
ImageAddr    dw 0x0000
GotSize      dw 0x0000
RestoreMe    db 0x00
Status       db 'r'
;TimInt       db 0x1C
SysInt       db 0x90
DosInt       db 0x21
UseInt       db 0x22
OldPos       db 0x00
Any          db 0x00
Speed        dw 0x0000
RamDrive     db 0x01
HexDat       rb 128
ImageName    rb 90
ImageName2   rb 90
OldVect      rb 4 * 256
NewVect      rb 4 * 256
Buff1        rb 512 * 0x12
Anything:
rb 0xffff - $

;======================================================================
;Commands
;q     - Quit Zork OS and Return to MS-DOS
;list  - List all files on current disk
;hex   - Enter and execute hexidecimal code
;disk  - Toggle between RAM Drive or FAT12
;drive - Toggle between Disk I/O Drive A: and B:
;example: hex,b4 0 b0 13 cd 10
;======================================================================
;Int 90h input/output function summary
;call with function number in bp

;int 90h function 00h 
;Load root directory entry from fat12 floppy

;int 90h function 01h
;Find filename located in loaded root

;int 90h function 02h 
;Load fat from fat12 floppy

;int 90h function 03h 
;Read file clusters from loaded fat

;int 90h function 04h 
;Launch read program file

;int 90h function 05h 
;Check if file in ds:si exists
;returns ax as 0 if file dont exist
;returns ax as 1 if file exists

;int 90h function 06h 
;Run program using filename in ds:si

;int 90h function 07h 
;List all files on disk

;int 90h function 08h 
;Write buffer es:di to filename in ds:si

;int 90h function 09h 
;Read filename in ds:si into buffer es:di

;int 90h function 12h 
;Write hex to any memory address

;int 90h function 13h 
;Jump to any memory address and return to caller
;int 80h to 8Eh are normal int 1Ch timers
;int 8fh is a super fast OverKill timer
;int 91h is used to hook int 90h
;int 92h is used to hook int 21h

;======================================================================
;int 90h function 12h
;Write hex to any memory address
;call with:
;es:di = address
;ds:si = hex string
;returns:
;hex written to memory address specified
;an example hex string is "b4 0 b0 16 cf"
;The hex code 'cf' is an iret
;======================================================================
;int 90h function 13h
;Jump to any memory address and return to caller
;call with:
;es:di = address
;returns:
;executes the code and returns to caller
;notes:
;code must be terminated with iret
;======================================================================

;AVAILABLE MS DOS INTERRUPTS
;int 0x21 Function 0x09
;int 0x21 Function 0x0a
;int 0x21 Function 0x0c
;int 0x21 Function 0x3d
;int 0x21 Function 0x3f
;int 0x21 Function 0x40
;int 0x21 Function 0x4c
;Keep it simple!


    


Last edited by mbr_tsr on 22 Jun 2011, 00:22; edited 1 time in total
Post 20 Jun 2011, 20:17
View user's profile Send private message Reply with quote
mbr_tsr



Joined: 03 Apr 2011
Posts: 4903
mbr_tsr
i wish i could port FASM to Zorker, yet there is a 0xFFFF memory allocation error, and disk I/O errors i would like to solve, Then there would be a "FASM for Zorker" i keep trying, perhaps someday there will be.
Post 20 Jun 2011, 22:06
View user's profile Send private message Reply with quote
mbr_tsr



Joined: 03 Apr 2011
Posts: 4903
mbr_tsr
i just found a segment 0x9000 bug cause FreeDOS uses this segment when running Zorker from DOS, so if you run into this bug, change every "9000" in this code to any unused available 64K segment. Note the RAM Drive only kicks in during int 21h function 40h. Note this OS runs .ASI programs, it is the ASIC 5 BASIC compiler that can make Zork .com files, you can get ASIC 5 on the net.
Post 23 Jun 2011, 01:43
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.