diff --git a/xboot.asm b/xboot.asm index 0856247..5af5d3e 100644 --- a/xboot.asm +++ b/xboot.asm @@ -1,4 +1,4 @@ -; ><-B00T IV b. Fox +; ><-B00T V b. Fox IDEAL P386 @@ -6,19 +6,42 @@ CODESEG zero db 100h dup(?) -blen = 60*1024 +blen = 59*1024 m_pro = 1 ; /p switch -m_wild = 2 ; obx has wild char -m_errs = 4 ; error/warning occured while current file -m_donta = 8 ; don't change output ext to atr - -ffnam = 80h+1eh +m_errs = 2 ; error/warning occured while current file +m_file = 4 ; single file (atr name for one file given) +m_lfn = 8 ; LFN search eol equ 13,10 eot equ 13,10,'$' -MACRO lda _rg ;shorter than 'mov (e)ax, _rg' +struc finddata16 + db 21 dup(?) +attr db ? +time dw ? +date dw ? +fsize dd ? +fname db 13 dup(?) + ends + +struc filetime32 + dd ?,? + ends + +struc finddata32 +attr dd ? +creat filetime32 ? +acces filetime32 ? +write filetime32 ? +fsizeh dd ? +fsizel dd ? + dd ?,? +fname db 260 dup(?) +aname db 14 dup(?) + ends + +MACRO lda _rg ; shorter than 'mov (e)ax, _rg' _rge SUBSTR <_rg>, 1, 1 IFIDNI _rge, xchg eax, _rg @@ -27,7 +50,7 @@ ELSE ENDIF ENDM -MACRO sta _rg ;shorter than 'mov _rg, (e)ax' +MACRO sta _rg ; shorter than 'mov _rg, (e)ax' _rge SUBSTR <_rg>, 1, 1 IFIDNI _rge, xchg _rg, eax @@ -36,7 +59,7 @@ ELSE ENDIF ENDM -MACRO dos _func +MACRO dos _func ; call DOS function IFNB <_func> IF _func and 0ff00h mov ax, _func @@ -69,7 +92,7 @@ ENDIF jmp xdisk ENDM -MACRO print _text +MACRO print _text ; print ascii$ text IFNB <_text> mov dx, offset _text ENDIF @@ -82,126 +105,191 @@ start: mov [spt], sp print hello - mov si, 81h ; pobierz argumenty - mov di, offset obxnam - mov ch, -1 +; Get arguments: obxnam, atrnam & /p switch +; Set onam & anam to end of filenames + mov si, 81h + mov bx, offset onam arg1: lodsb cmp al, ' ' - je arg1 ; spacje omijamy + je arg1 ; skip spaces + cmp al, '-' + je swit cmp al, '/' jne nswit - lodsb ; '/' - switch +; Switch +swit: lodsb and al, 0dfh cmp al, 'P' jne usg or [flags], m_pro ; '/P' jmp arg1 + nswit: cmp al, 0dh je argx - cmp di, offset atrnam - ja usg ; byly juz dwie nazwy - -spath: mov dl, -1 ; dolaczaj rozsz. - cmp di, offset atrnam - jnb snam1 - and [flags], not m_wild - mov [onam], di ; onam - adres nazwy PLIKU .obx -snam1: cmp di, offset atrnam - ja snam2 - cmp al, '*' ; w obx sprawdzaj wildy - je wildch - cmp al, '?' - jne snam2 -wildch: or [flags], m_wild -snam2: cmp al, '.' - jne npoint - xor dl, dl ; jest rozszerzenie - nie dolaczaj .obx -npoint: stosb ; przepisz nazwe - lodsb - cmp al, ' ' ; spacja lub eol konczy - je snamx +; Filename + cmp bx, offset enam + jae usg ; two names already parsed + mov di, [bx] + mov ah, '"' + cmp al, ah + je qname ; "file name with spaces" + mov ah, ' ' +gname: stosb ; copy name +qname: lodsb + cmp al, ah ; space/'"', eol and '/' terminate name + je xname cmp al, 0dh - je snamx + je bname cmp al, '/' - je snamx ; '/' tez konczy - cmp [byte di-1], '\' - je spath - jmp snam1 + jne gname +bname: dec si +xname: mov [bx], di ; save end of name ptr + inc bx + inc bx + mov [byte di], 0 + jmp arg1 +; Usage usg: print usgtxt dos 4c03h -snamx: mov eax, 'XBO.' - cmp di, offset atrnam - jb adobx - test [flags], m_wild - jz atrnwl - mov al, '\' - cmp al, [di-1] - je panam - stosb -panam: mov [anam], di - jmp nadext -atrnwl: test dl, dl - jz adatr ; jest podane rozszerzenie - - or [flags], m_donta ; nie zmieniaj go na atr -adatr: mov eax, 'RTA.' -adobx: test dl, dl - jz nadext - stosd -nadext: xor al, al - stosb - mov [nfin], di - dec si - cmp di, offset atrnam +; End of arguments +argx: cmp bx, offset anam + jb usg ; no obxnam given + +; Find where obx FILE name begins + mov di, [onam] + lea cx, [di+1+zero-obxnam] +fofna1: dec di + cmp [byte di], '\' + je fofnax + cmp [byte di], ':' + loopne fofna1 +fofnax: inc di + mov [ofna], di + +; Is atr given? + cmp bx, offset anam + ja atrgvn ; atr given + +; Only obx given +; Move path of obx to atrnam + mov si, offset obxnam mov di, offset atrnam - jb jarg1 - inc di -jarg1: jmp arg1 +mobat1: lodsb + stosb + cmp al, '\' + je mobat2 + cmp al, ':' + jne mobat3 +mobat2: mov [anam], di +mobat3: test al, al + jnz mobat1 + mov di, [anam] + mov [byte di], 0 + jmp srvobx -argx: cmp di, offset atrnam - jb usg ; nie ma nazwy - ja jesatr - mov cx, [nfin] - test [flags], m_wild - jz nowil1 ; jak jeden plik, to przepiszemy cala nazwe - mov cx, [onam] ; jak wiele, to tylko sciezke -nowil1: mov si, offset obxnam - sub cx, si - rep movsb - mov [nfin], di -jesatr: +; Atr given +; Delete trailing '\' if not "\" or "C:\" +atrgvn: mov di, [anam] + dec di + cmp [byte di], '\' + jne atrg1 + mov [anam], di + cmp di, offset atrnam + jbe atrg1 + cmp [byte di-1], ':' + je atrg1 + mov [byte di], 0 +atrg1: +; Check if it is file or dir + mov dx, offset atrnam + xor bx, bx ; try LFN function + stc + dos 7143h + jnc chkafd + cmp ax, 7100h ; LFN not supported + jne afile ; possibly file/dir doesn't exist -> file + dos 43h ; call MS-DOS function 4300h + jc afile ; failed -> file +chkafd: test cl, 10h + jnz adir +; It is file +; Add .atr extension, if none +afile: or [flags], m_file + mov di, [anam] + lea cx, [di+zero-atrnam] + mov eax, 'rta.' + call adext + jmp srvobx +; It is dir +; Add trailing '\' +adir: mov di, [anam] + mov [byte di], '\' + inc [anam] - test [flags], m_wild - jz nowild - xor cx, cx +; Serve obx +; Add .obx extension, if none +srvobx: mov di, [onam] + lea cx, [di+zero-obxnam] + mov eax, 'xbo.' + call adext + +; Find first file mov dx, offset obxnam - mov ah, 4eh ; jak wiele, to szukamy + mov cx, 7 ; try LFN + mov si, 1 + mov di, offset f32 + stc + dos 714eh + jnc flfn + cmp ax, 7100h ; LFN not supported + jne nofil + xor cx, cx ; call MS-DOS function 4Eh + dos 4eh + jnc main1 +nofil: print e_nofil ; "No file found" + dos 4c02h +flfn: or [flags], m_lfn ; LFN successfull + mov [fhand], ax + +; Main loop - convert found file main1: and [flags], not m_errs mov [ohand], 0 mov [ahand], 0 mov [len], lodlen+endlen - dos - jc fin - mov si, 80h+1eh - mov di, [anam] - mov bx, [onam] + +; Move name from finddata to obxnam + mov si, offset (finddata16 80h).fname + test [flags], m_lfn + jz nolfn1 + mov si, offset f32.fname +nolfn1: mov di, [ofna] mona1: lodsb stosb - mov [bx], al - inc bx test al, al jnz mona1 - mov [nfin], di -nowild: mov si, offset obxnam - call printz ; file.obx - mov dx, offset obxnam +; Print "file.obx" + mov si, offset obxnam + call printz + +; Open obx for reading mov bp, offset e_open - file 3d00h ; open for reading + mov dx, offset obxnam ; MS-DOS + mov ax, 3d00h + test [flags], m_lfn + jz nolfn2 + mov si, dx ; LFN + xor bx, bx + mov dx, 1 + mov ax, 716ch +nolfn2: file mov [ohand], ax + +; Check if Atari executable call xreadh jb enate cmp [head], -1 @@ -214,39 +302,57 @@ nowild: mov si, offset obxnam enate: mov dx, offset e_nota jmp error nenate: + +; Set default run address at first block mov ax, [head] mov [l1runl], al mov [l2runl], al mov [l1runh], ah mov [l2runh], ah - print arrow ; -> - test [flags], m_donta - jnz jatrex - mov di, [nfin] - mov si, di -cetatr: dec si - cmp [byte si], '\' - je cetafn - cmp [byte si], '.' - jne cetatr - mov di, si -cetafn: mov eax, 'RTA.' +; Print "->" + print arrow + +; Atr FILE name given? + test [flags], m_file + jnz sfile +; No: move name from obx, replacing extension with ".atr" + mov si, [ofna] + mov di, [anam] +mona2: lodsb + stosb + cmp al, '.' + jne mona2 + mov eax, 'rta' stosd - mov [byte di], 0 -jatrex: +sfile: + +; Print "file.atr" mov si, offset atrnam call printz ; file.atr - xor cx, cx - mov dx, offset atrnam - mov bp, offset e_creat - file 3ch ; create - mov [ahand], ax - print kropki ; ... +; Create atr file + mov bp, offset e_creat + mov dx, offset atrnam + xor cx, cx + mov ax, 3c00h + test [flags], m_lfn + jz nolfn3 + mov si, dx + mov bx, 1 + mov dx, 12h ; create or truncate + mov ax, 716ch +nolfn3: file + mov [ahand], ax + +; Print "..." + print kropki + +; Write atr header mov cx, beglen mov dx, offset begin call xwrite +; Write loader in boot sector mov cx, lodlen mov dx, offset stdlod test [flags], m_pro @@ -255,8 +361,9 @@ jatrex: stlo: call xwrite jmp firs -skff: - call xreadh +; Converting +; Read obx header +skff: call xreadh jb chtrun cmp [head], -1 je skff @@ -264,6 +371,7 @@ skff: call xread2 jb trunca +; Read block firs: mov cx, [head+2] sub cx, [head] inc cx @@ -273,9 +381,11 @@ firs: mov cx, [head+2] okhead: mov dx, offset blok call xread jb trunc +; Write call xwrihd jmp skff +; Check if block is truncated chtrun: test ax, ax jnz trunca jmp finfil @@ -290,7 +400,11 @@ trunc: test ax, ax call xwrihd trunca: mov dx, offset w_trunc +; Warning warfin: call warni + +; End of file +; Write endsequence finfil: mov dx, offset endseq1 test [flags], m_pro jz endst @@ -306,7 +420,10 @@ endst: mov cx, endlen and ecx, 7fh jz fuls call xwrith -fuls: xor cx, cx ; seek back to para's atr header field +fuls: + +; Write number of paragraphs (para=16 bytes) to atr + xor cx, cx ; seek back to para's atr header field mov dx, 2 mov bp, offset e_write file 4200h @@ -315,6 +432,7 @@ fuls: xor cx, cx ; seek back to para's atr header field mov dx, offset len call xwrite +; Close files shut: mov bx, [ahand] mov bp, offset e_write call xclose @@ -326,14 +444,42 @@ shut: mov bx, [ahand] jnz nook print oktxt nook: print eoltxt - test [flags], m_wild - jz fin - mov ah, 4fh + +; Find next file + test [flags], m_lfn + jnz lfnnx + + dos 4fh ; MS-DOS function + jc fin +nexfil: test [flags], m_file + jnz singl jmp main1 +lfnnx: mov bx, [fhand] ; LFN function + mov si, 1 + mov di, offset f32 + dos 714fh + jnc nexfil + + dos 71a1h ; LFN search close + fin: mov ax, [exitcod] dos +singl: print e_singl + dos 4c02h + +; Add extension if none (di=end of name, cx=len, eax=ext) +adext: mov bx, di +adext1: dec bx + cmp [byte bx], '.' + je adextr + cmp [byte bx], '\' + loopne adext1 + stosd +adextr: mov [byte di], 0 + ret + xdisk: push bp dos pop dx @@ -405,13 +551,10 @@ printz: lodsb jnz pnam1 ret -hello db 'X-BOOT 4.1.-9 by Fox/Taquart',eot -usgtxt db 'XBOOT [/p] obxfile [atrfile]',eol - db ' Convert single Atari 8-bit executable into .ATR disk image.',eol - db 'XBOOT [/p] obxfiles [atrpath]',eol - db ' Convert many files - wildcards allowed.',eol - db '/p switch',eol - db ' Write professional loader rather than standard.' +hello db 'X-BOOT 5.0 by Fox/Taquart',eot +usgtxt db 'Converts Atari 8-bit executables to .ATR disk images.',eol + db 'Syntax: XBOOT [/p] obxfiles [atrpath][atrfile]',eol + db '/p Write professional loader rather than standard.' eoltxt db eot arrow db ' -> $' kropki db ' ... $' @@ -419,6 +562,8 @@ oktxt db 'OK$' w_mem db eol,' WARNING: Memory conflict$' w_prof db eol,' WARNING: Professional loader needed$' w_trunc db eol,' WARNING: File is truncated$' +e_nofil db 'ERROR: File not found',eot +e_singl db 'ERROR: Single target for many files',eot e_nota db eol,' ERROR: Not Atari executable$' e_open db eol,' ERROR: Can''t open file$' e_read db eol,' ERROR: Disk read error$' @@ -440,7 +585,7 @@ l1runh db 7,141,225,2,169,7,141,5,3,169,255 db 11,3,32,83,228,48,217,14,210,7,173,127,7,166,67,208,223,129 db 68,230,68,208,2,230,69,165,70,197,68,165,71,229,69,176,210,169 db 3,141,15,210,108,226,2,44,111,97,100,105,110,103,14,14,14,0 - db 52,46,48 + db 53,46,48 lodlen = $-stdlod ; Ending Header for loader #1 @@ -456,7 +601,7 @@ l2runh db 4,141,225,2,173,56,96 db 67,238,220,4,16,32,238,10,3,208,3,238,11,3,169,255,141,1 db 211,78,14,212,88,32,83,228,48,208,120,238,14,212,206,1,211,14 db 220,4,173,127,4,166,67,208,207,129,68,230,68,208,2,230,69,165 - db 70,197,68,165,71,229,69,176,194,169,3,141,15,210,108,226,2,52 + db 70,197,68,165,71,229,69,176,194,169,3,141,15,210,108,226,2,53 db 46,48,112 ; Ending Header for loader #2 @@ -465,16 +610,20 @@ endseq2 db 250,4,250,4,224 exitcod dw 4c00h flags db 0 len dd lodlen+endlen -ohand dw 0 -ahand dw 0 +onam dw obxnam anam dw atrnam -onam dw ? -nfin dw ? +enam: +fhand dw ? +ohand dw ? +ahand dw ? +ofna dw ? spt dw ? obxnam db 100h dup(?) atrnam db 100h dup(?) +f32 finddata32 ? + head dw ?,? blok db blen dup(?)