Category : Files from Magazines
Archive   : PJ81.ZIP
Filename : DB.ASM
dosseg
.model small
NULL segment para public 'BEGDATA'
NULL ends
NULL_POINTER equ 0
NULL_CHAR equ 0
CR_CHAR equ 13
SPACE_CHAR equ 32
wptr equ word ptr
.stack
.data
dgroup_start label word
psp dw 0
argc dw 0
argv dd 0
error_text dw 0 ; asciiz error msg offset in DGROUP
db_txt db ' db ',0
err_default db 'Error',0
err_no_memory db 'Insufficient memory',0
err_too_big db 'malloc exceeds maximum',0
err_file_not_found db 'File not found',0
err_file_io db 'File I/O error',0
err_file_too_big db 'File too big',0
help_text db 'db dumps file as assembly language db statements',13,10,0
.code
extrn exit_program:near,exit_with_error:near,ms_dos:near,outchr:near
extrn outchr_asciiz_dgroup:near,outchr_hex_byte:near,outchr_newline:near
extrn strcpy:near,strskp:near,strskp_white:near
;; fatal error handler
;
fatal_error_handler proc
mov ax,NULL_POINTER ; display error message
xchg ax,error_text[bp]
cmp ax,NULL_POINTER
jne feh1 ; if error text found
lea ax,err_default[bp] ; else use default error text
feh1: call outchr_asciiz_dgroup
jmp exit_with_error
fatal_error_handler endp
;; free raw
;
; entry ES:DI storage bucket ptr
; exit Cf if bad ptr
; uses AX
;
free_raw proc
mov ah,49h
jmp ms_dos
free_raw endp
;; malloc raw
;
; entry CX request bytes size (0
; Cf if not enough memory or request too large
; uses AX
;
malloc_raw proc
push bx ; convert byte count to
mov bx,cx ; paragraph count
add bx,15
jc mar2 ; if too much requested
shr bx,1
shr bx,1
shr bx,1
shr bx,1
mov ah,48h ; request memory from dos
call ms_dos
jc mar3 ; if not enough memory
mov es,ax
mov di,0
mar1: pop bx
ret
mar2: mov error_text[bp],offset err_too_big
jmp mar1
mar3: mov error_text[bp],offset err_no_memory
jmp mar1
malloc_raw endp
;; main
;
main proc
mov ax,@data ; set dgroup stack
mov ss,ax
mov sp,offset stack
call start_up
cmp argc[bp],1
jbe mai1 ; if no parameters - display help
lds si,argv[bp] ; get 1st command line parameter
mov si,[si+2]
call read_entire_file
jc mai2 ; if error reading file
call outchr_db_bytes ; convert file to db statements
jmp exit_program
mai1: lea ax,help_text[bp] ; display help text
call outchr_asciiz_dgroup
jmp exit_program
mai2: jmp fatal_error_handler
main endp
;; open input file
;
; entry DS:SI asciiz file path
; exit AX,BX file handle
; Cf if error
;
open_input_file proc
mov ax,3D00h
xchg dx,si
call ms_dos
xchg dx,si
mov bx,ax
ret
open_input_file endp
;; outchr memory byte
;
; entry DS:SI byte pointer
; exit SI updated
; uses AX
;
outchr_memory_byte proc
mov al,'0'
call outchr
lodsb
call outchr_hex_byte
mov al,'h'
jmp outchr
outchr_memory_byte endp
;; outchr db bytes
;
; entry DS:SI memory pointer
; CX byte count
; uses AX,CX,DX,SI
;
outchr_db_bytes proc
jcxz odb4 ; if no bytes
odb1: lea ax,db_txt[bp] ; * db *
call outchr_asciiz_dgroup
mov dx,8 ; set count for bytes on this line
cmp cx,dx ; minimum of 8 or bytes left
ja odb2
mov dx,cx
odb2: call outchr_memory_byte ; display memory bytes
dec dx
jz odb3 ; if 16th byte on current line
mov al,','
call outchr
loop odb2 ; if more bytes
inc cx ; (adjust CX for loop below)
odb3: call outchr_newline
loop odb1 ; if more bytes
odb4: ret
outchr_db_bytes endp
;; read command line
;
; exit DS:SI program command line
;
read_command_line proc
mov ds,psp[bp]
mov si,81h
ret
read_command_line endp
;; read entire file
;
; entry DS:SI asciiz file name
; exit DS:SI ptr to storage containing file (NULL delimited)
; CX file byte count
; Cf if file not found or too big
; uses AX
;
read_entire_file proc
push bx
push dx
push di
push es
call open_input_file
jc ref3 ; if file not found
mov ax,4202h ; get file size
mov cx,0
mov dx,0
call ms_dos
jc ref4 ; if unexpected file i/o error
add ax,1 ; bump file size for delimiting zero
adc dx,0
jnz ref5 ; if file too big (>64k)
mov cx,ax ; allocate storage for file contents
call malloc_raw
jc ref1 ; if insufficient memory
mov ax,4200h ; rewind file
mov cx,0
mov dx,0
call ms_dos
jc ref4 ; if unexpected file i/o error
mov ah,3Fh ; read entire file
mov cx,-1
mov dx,di
push es
pop ds
call ms_dos
jc ref4 ; if unexpected file i/o error
mov cx,ax ; return file byte count
mov si,di ; and storage pointer
add di,ax ; delimit file with NULL
mov al,NULL_CHAR
stosb
ref1: mov ah,3Eh ; close file
pushf ; (preserve carry flag)
call ms_dos
popf
ref2: pop es
pop di
pop dx
pop bx
ret
ref3: mov error_text[bp],offset err_file_not_found
jmp ref2
ref4: mov error_text[bp],offset err_file_io
jmp ref1
ref5: mov error_text[bp],offset err_file_too_big
stc
jmp ref1
read_entire_file endp
;; read environment
;
; exit DS:SI environment
;
read_environment proc
mov si,0
mov ds,psp[bp]
mov ds,[si+2Ch]
ret
read_environment endp
;; set argc argv
;
; exit Cf if no memory
; uses AX,CX,DI,SI,ES,DS
;
set_argc_argv proc
mov cx,256 ; allocate storage for parameters
call malloc_raw
jc saa9 ; if no memory
mov argc[bp],1
mov wptr argv[bp],di
mov wptr argv[bp+2],es
mov ah,30h ; check DOS version
call ms_dos
cmp al,3
jb saa10 ; if prior to DOS 3.x
call read_environment ; skip environment (program name
saa1: call strskp ; is found after environment in
lodsb ; DOS 3.x)
cmp al,NULL_CHAR
jne saa1
lodsw ; (skip 1)
call strcpy ; use program name as argv[0]
inc di
saa2: call read_command_line
saa3: call strskp_white ; extract next command line parameter
cmp al,CR_CHAR
je saa7 ; if not end of command line
inc argc[bp] ; advance parameter count
jmp saa5 ; copy parameter
saa4: stosb
saa5: lodsb
cmp al,SPACE_CHAR
jbe saa6 ; if delimiter
cmp al,','
je saa6 ; if separator
cmp al,'~'
jbe saa4 ; if valid character (not delimiter)
saa6: cmp al,CR_CHAR ; delimit parameter
mov al,NULL_CHAR
stosb
jne saa3 ; if not end of command line
saa7: inc di ; word align array of offsets
and di,-2
lds si,argv[bp] ; get ptr to first parameter
mov wptr argv[bp],di ; set pointer list offset
mov cx,argc[bp] ; get list count (cannot==0)
saa8: mov ax,si ; build array of offsets to each
stosw ; parameter
call strskp
loop saa8
clc
saa9: ret
saa10: mov ax,'C' ; microsoft c uses argv[0]=="C"
stosw ; for dos 2
jmp saa2
set_argc_argv endp
;; start up
;
; entry ES program segment prefix
; SS dgroup
; exit BP dgroup base offset (always 0)
; may use AX,BX,CX,DX,DI,SI,DS,ES
;
start_up proc
cld
mov bp,offset dgroup_start
mov psp[bp],es
mov ax,offset stack+15 ; compute number of paragraphs
mov cl,4 ; in program
shr ax,cl
mov bx,ss
add bx,ax
sub bx,psp[bp]
mov ah,4Ah ; shrink program memory block for
call ms_dos ; dynamic storage system
call set_argc_argv
ret
start_up endp
end main
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/