Category : Files from Magazines
Archive   : PJ81.ZIP
Filename : DB.ASM

 
Output of file : DB.ASM contained in archive : PJ81.ZIP
title dump file as db statements
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 ; exit ES:DI storage bucket pointer
; 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


  3 Responses to “Category : Files from Magazines
Archive   : PJ81.ZIP
Filename : DB.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. 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/