add flat assembler toolchain

This commit is contained in:
2024-11-24 23:13:28 -05:00
parent 99e8e4072b
commit dbfd94ea40
302 changed files with 145599 additions and 0 deletions

View File

@ -0,0 +1,229 @@
format MZ
heap 0
stack 8000h
entry loader:init
include 'loader.inc'
segment main use32
start:
call get_params
jnc make_listing
mov esi,_usage
call display_string
mov ax,4C02h
int 21h
make_listing:
call listing
mov ax,4C00h
int 21h
error:
mov esi,_error_prefix
call display_string
pop esi
call display_string
mov esi,_error_suffix
call display_string
mov ax,4C00h
int 21h
get_params:
push ds
mov ds,[psp_selector]
mov esi,81h
mov edi,params
find_param:
lodsb
cmp al,20h
je find_param
cmp al,'-'
je option_param
cmp al,0Dh
je all_params
or al,al
jz all_params
cmp [es:input_file],0
jne get_output_file
mov [es:input_file],edi
jmp process_param
get_output_file:
cmp [es:output_file],0
jne bad_params
mov [es:output_file],edi
process_param:
cmp al,22h
je string_param
copy_param:
stosb
lodsb
cmp al,20h
je param_end
cmp al,0Dh
je param_end
or al,al
jz param_end
jmp copy_param
string_param:
lodsb
cmp al,22h
je string_param_end
cmp al,0Dh
je param_end
or al,al
jz param_end
stosb
jmp string_param
option_param:
lodsb
cmp al,'a'
je addresses_option
cmp al,'A'
je addresses_option
cmp al,'b'
je bytes_per_line_option
cmp al,'B'
je bytes_per_line_option
invalid_option:
pop ds
stc
ret
get_option_value:
xor eax,eax
mov edx,eax
get_option_digit:
lodsb
cmp al,20h
je option_value_ok
cmp al,0Dh
je option_value_ok
or al,al
jz option_value_ok
sub al,30h
jc bad_params_value
cmp al,9
ja bad_params_value
imul edx,10
jo bad_params_value
add edx,eax
jc bad_params_value
jmp get_option_digit
option_value_ok:
dec esi
clc
ret
bad_params_value:
stc
ret
bytes_per_line_option:
lodsb
cmp al,20h
je bytes_per_line_option
cmp al,0Dh
je invalid_option
or al,al
jz invalid_option
dec esi
call get_option_value
jc bad_params
or edx,edx
jz invalid_option
cmp edx,1000
ja invalid_option
mov [es:code_bytes_per_line],edx
jmp find_param
addresses_option:
lodsb
cmp al,20h
je set_addresses_option
cmp al,0Dh
je set_addresses_option
or al,al
jnz bad_params
set_addresses_option:
dec esi
mov [es:show_addresses],1
jmp find_param
param_end:
dec esi
string_param_end:
xor al,al
stosb
jmp find_param
all_params:
xor al,al
stosb
pop ds
cmp [input_file],0
je bad_params
cmp [output_file],0
je bad_params
clc
ret
bad_params:
stc
ret
include 'system.inc'
include '..\listing.inc'
_usage db 'listing generator for flat assembler',0Dh,0Ah
db 'usage: listing <input> <output>',0Dh,0Ah
db 'optional settings:',0Dh,0Ah
db ' -a show target addresses for assembled code',0Dh,0Ah
db ' -b <number> set the amount of bytes listed per line',0Dh,0Ah
db 0
_error_prefix db 'error: ',0
_error_suffix db '.',0Dh,0Ah,0
input_file dd 0
output_file dd 0
code_bytes_per_line dd 16
show_addresses db 0
line_break db 0Dh,0Ah
input dd ?
assembled_code dd ?
assembled_code_length dd ?
code_end dd ?
code_offset dd ?
code_length dd ?
output_handle dd ?
output_buffer dd ?
current_source_file dd ?
current_source_line dd ?
source dd ?
source_length dd ?
maximum_address_length dd ?
address_start dd ?
last_listed_address dd ?
psp_selector dw ?
environment_selector dw ?
memory_handles_count dd ?
memory_handles rd 400h
params rb 1000h
characters rb 100h
segment buffer_segment
buffer = (buffer_segment-main) shl 4
db 1000h dup ?
segment stack_segment
stack_bottom = (stack_segment-main) shl 4
db 4000h dup ?
stack_top = stack_bottom + $

View File

@ -0,0 +1,102 @@
segment loader use16
init:
mov ax,1687h
int 2Fh
or ax,ax ; DPMI installed?
jnz short no_dpmi
test bl,1 ; 32-bit programs supported?
jz short no_dpmi
mov word [cs:mode_switch],di
mov word [cs:mode_switch+2],es
mov bx,si ; allocate memory for DPMI data
mov ah,48h
int 21h
jnc init_protected_mode
init_failed:
call init_error
db 'error: DPMI initialization failed.',0Dh,0Ah,0
no_dpmi:
call init_error
db 'error: 32-bit DPMI services are not available.',0Dh,0Ah,0
init_error:
pop si
push cs
pop ds
display_error:
lodsb
test al,al
jz short error_finish
mov dl,al
mov ah,2
int 21h
jmp short display_error
error_finish:
mov ax,4CFFh
int 21h
init_protected_mode:
mov es,ax
mov ds,[ds:2Ch]
mov ax,1
call far [cs:mode_switch] ; switch to protected mode
jc init_failed
mov cx,1
xor ax,ax
int 31h ; allocate descriptor for code
jc init_failed
mov si,ax
xor ax,ax
int 31h ; allocate descriptor for data
jc init_failed
mov di,ax
mov dx,cs
lar cx,dx
shr cx,8
or cx,0C000h
mov bx,si
mov ax,9
int 31h ; set code descriptor access rights
jc init_failed
mov dx,ds
lar cx,dx
shr cx,8
or cx,0C000h
mov bx,di
int 31h ; set data descriptor access rights
jc init_failed
mov ecx,main
shl ecx,4
mov dx,cx
shr ecx,16
mov ax,7
int 31h ; set data descriptor base address
jc init_failed
mov bx,si
int 31h ; set code descriptor base address
jc init_failed
mov cx,0FFFFh
mov dx,0FFFFh
mov ax,8 ; set segment limit to 4 GB
int 31h
jc init_failed
mov bx,di
int 31h
jc init_failed
mov ax,ds
mov ds,di
mov [psp_selector],es
mov [environment_selector],ax
cli
mov ss,di
mov esp,stack_top
sti
mov es,di
xor eax,eax
mov [memory_handles_count],eax
push si
push start
retf
mode_switch dd ?

View File

@ -0,0 +1,136 @@
format MZ
heap 0
stack 8000h
entry loader:init
include 'loader.inc'
segment main use32
start:
call get_params
jnc make_dump
mov esi,_usage
call display_string
mov ax,4C02h
int 21h
make_dump:
call preprocessed_source
mov ax,4C00h
int 21h
error:
mov esi,_error_prefix
call display_string
pop esi
call display_string
mov esi,_error_suffix
call display_string
mov ax,4C00h
int 21h
get_params:
push ds
mov ds,[psp_selector]
mov esi,81h
mov edi,params
find_param:
lodsb
cmp al,20h
je find_param
cmp al,0Dh
je all_params
or al,al
jz all_params
cmp [es:input_file],0
jne get_output_file
mov [es:input_file],edi
jmp process_param
get_output_file:
cmp [es:output_file],0
jne bad_params
mov [es:output_file],edi
process_param:
cmp al,22h
je string_param
copy_param:
stosb
lodsb
cmp al,20h
je param_end
cmp al,0Dh
je param_end
or al,al
jz param_end
jmp copy_param
string_param:
lodsb
cmp al,22h
je string_param_end
cmp al,0Dh
je param_end
or al,al
jz param_end
stosb
jmp string_param
bad_params_value:
stc
ret
param_end:
dec esi
string_param_end:
xor al,al
stosb
jmp find_param
all_params:
xor al,al
stosb
pop ds
cmp [input_file],0
je bad_params
cmp [output_file],0
je bad_params
clc
ret
bad_params:
stc
ret
include 'system.inc'
include '..\prepsrc.inc'
_usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah
db 'usage: prepsrc <input> <output>',0Dh,0Ah
db 0
_error_prefix db 'error: ',0
_error_suffix db '.',0Dh,0Ah,0
input_file dd 0
output_file dd 0
psp_selector dw ?
environment_selector dw ?
memory_handles_count dd ?
memory_handles rd 400h
params rb 1000h
segment buffer_segment
buffer = (buffer_segment-main) shl 4
db 1000h dup ?
segment stack_segment
stack_bottom = (stack_segment-main) shl 4
db 4000h dup ?
stack_top = stack_bottom + $

View File

@ -0,0 +1,140 @@
format MZ
heap 0
stack 8000h
entry loader:init
include 'loader.inc'
segment main use32
start:
call get_params
jnc make_dump
mov esi,_usage
call display_string
mov ax,4C02h
int 21h
make_dump:
call symbols
mov ax,4C00h
int 21h
error:
mov esi,_error_prefix
call display_string
pop esi
call display_string
mov esi,_error_suffix
call display_string
mov ax,4C00h
int 21h
get_params:
push ds
mov ds,[psp_selector]
mov esi,81h
mov edi,params
find_param:
lodsb
cmp al,20h
je find_param
cmp al,0Dh
je all_params
or al,al
jz all_params
cmp [es:input_file],0
jne get_output_file
mov [es:input_file],edi
jmp process_param
get_output_file:
cmp [es:output_file],0
jne bad_params
mov [es:output_file],edi
process_param:
cmp al,22h
je string_param
copy_param:
stosb
lodsb
cmp al,20h
je param_end
cmp al,0Dh
je param_end
or al,al
jz param_end
jmp copy_param
string_param:
lodsb
cmp al,22h
je string_param_end
cmp al,0Dh
je param_end
or al,al
jz param_end
stosb
jmp string_param
bad_params_value:
stc
ret
param_end:
dec esi
string_param_end:
xor al,al
stosb
jmp find_param
all_params:
xor al,al
stosb
pop ds
cmp [input_file],0
je bad_params
cmp [output_file],0
je bad_params
clc
ret
bad_params:
stc
ret
include 'system.inc'
include '..\symbols.inc'
_usage db 'symbols dumper for flat assembler',0Dh,0Ah
db 'usage: symbols <input> <output>',0Dh,0Ah
db 0
_error_prefix db 'error: ',0
_error_suffix db '.',0Dh,0Ah,0
input_file dd 0
output_file dd 0
input dd ?
output_buffer dd ?
output_handle dd ?
psp_selector dw ?
environment_selector dw ?
memory_handles_count dd ?
memory_handles rd 400h
params rb 1000h
segment buffer_segment
buffer = (buffer_segment-main) shl 4
db 1000h dup ?
segment stack_segment
stack_bottom = (stack_segment-main) shl 4
db 4000h dup ?
stack_top = stack_bottom + $

View File

@ -0,0 +1,239 @@
display_string:
lods byte [esi]
or al,al
jz string_end
mov dl,al
mov ah,2
int 21h
jmp display_string
string_end:
ret
alloc:
push ebx esi edi
mov cx,ax
shr eax,16
mov bx,ax
mov ax,501h
int 31h
jc dpmi_allocation_failed
mov ax,bx
shl eax,16
mov ax,cx
mov edx,main
shl edx,4
sub eax,edx
mov bx,si
shl ebx,16
mov bx,di
mov ecx,[memory_handles_count]
inc [memory_handles_count]
shl ecx,3
add ecx,memory_handles
mov [ecx],eax
mov [ecx+4],ebx
pop edi esi ebx
clc
ret
dpmi_allocation_failed:
pop edi esi ebx
stc
ret
free:
push ebx esi edi
mov esi,memory_handles
mov ecx,[memory_handles_count]
find_memory_handle:
cmp eax,[esi]
je memory_handle_found
add esi,8
loop find_memory_handle
pop edi esi
ret
memory_handle_found:
mov ebx,[esi+4]
dec [memory_handles_count]
dec ecx
jz free_memory
remove_memory_handle:
mov edx,[esi+8]
mov edi,[esi+8+4]
mov [esi],edx
mov [esi+4],edi
add esi,8
loop remove_memory_handle
free_memory:
mov esi,ebx
shr esi,16
mov di,bx
mov ax,502h
int 31h
pop edi esi ebx
ret
open:
push esi edi ebp
call adapt_path
mov ax,716Ch
mov bx,100000b
mov dx,1
xor cx,cx
xor si,si
call dos_int
jnc open_done
cmp ax,7100h
je old_open
stc
jmp open_done
old_open:
mov ax,3D00h
xor dx,dx
call dos_int
open_done:
mov bx,ax
pop ebp edi esi
ret
adapt_path:
mov esi,edx
mov edi,buffer
copy_path:
lodsb
cmp al,'/'
jne path_char_ok
mov al,'\'
path_char_ok:
stosb
or al,al
jnz copy_path
ret
dos_int:
push 0 0 0
pushw buffer_segment buffer_segment
stc
pushfw
push eax
push ecx
push edx
push ebx
push 0
push ebp
push esi
push edi
mov ax,300h
mov bx,21h
xor cx,cx
mov edi,esp
push es ss
pop es
int 31h
pop es
mov edi,[esp]
mov esi,[esp+4]
mov ebp,[esp+8]
mov ebx,[esp+10h]
mov edx,[esp+14h]
mov ecx,[esp+18h]
mov ah,[esp+20h]
add esp,32h
sahf
mov eax,[esp-32h+1Ch]
ret
create:
push esi edi ebp
call adapt_path
mov ax,716Ch
mov bx,100001b
mov dx,10010b
xor cx,cx
xor si,si
xor di,di
call dos_int
jnc create_done
cmp ax,7100h
je old_create
stc
jmp create_done
old_create:
mov ah,3Ch
xor cx,cx
xor dx,dx
call dos_int
create_done:
mov bx,ax
pop ebp edi esi
ret
write:
push edx esi edi ebp
mov ebp,ecx
mov esi,edx
write_loop:
mov ecx,1000h
sub ebp,1000h
jnc do_write
add ebp,1000h
mov ecx,ebp
xor ebp,ebp
do_write:
push ecx
mov edi,buffer
shr ecx,2
rep movsd
mov ecx,[esp]
and ecx,11b
rep movsb
pop ecx
mov ah,40h
xor dx,dx
call dos_int
or ebp,ebp
jnz write_loop
pop ebp edi esi edx
ret
read:
push edx esi edi ebp
mov ebp,ecx
mov edi,edx
read_loop:
mov ecx,1000h
sub ebp,1000h
jnc do_read
add ebp,1000h
mov ecx,ebp
xor ebp,ebp
do_read:
push ecx
mov ah,3Fh
xor dx,dx
call dos_int
cmp ax,cx
jne eof
mov esi,buffer
mov ecx,[esp]
shr ecx,2
rep movsd
pop ecx
and ecx,11b
rep movsb
or ebp,ebp
jnz read_loop
read_done:
pop ebp edi esi edx
ret
eof:
pop ecx
stc
jmp read_done
close:
mov ah,3Eh
int 21h
ret
lseek:
mov ah,42h
mov ecx,edx
shr ecx,16
int 21h
pushf
shl edx,16
popf
mov dx,ax
mov eax,edx
ret