From 8717e916c0783613de67f84a8a2c74523b704a4e Mon Sep 17 00:00:00 2001 From: Robert Pengelly Date: Mon, 5 Aug 2024 16:36:54 +0100 Subject: [PATCH] Write to console --- build/chimaera.img | Bin 368640 -> 368640 bytes build/chimaera.vhd | Bin 34120704 -> 34120704 bytes src/Makefile.unix | 1 + src/apps/hello/Makefile.unix | 2 +- src/apps/hello/hello.asm | 111 +++++++++++----- src/kernel/int21.asm | 237 ++++++++++++++++++++++++++++++++++ src/lib/crt/include/stdio.inc | 7 + src/lib/crt/stdio/fputc.asm | 158 +++++++++++++++++++++++ src/lib/crt/stdio/fwrite.asm | 225 ++++++++++++++++++++++++++++++++ 9 files changed, 711 insertions(+), 30 deletions(-) create mode 100644 src/lib/crt/stdio/fputc.asm create mode 100644 src/lib/crt/stdio/fwrite.asm diff --git a/build/chimaera.img b/build/chimaera.img index 759b6197612384af68ee2b86871c1b7fefb655a1..c5dc8e7cfdbc5070a8ea341100aff353f6d767aa 100644 GIT binary patch delta 3118 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 D*1p{C delta 2999 zcmZ`*4OCM{7M{F>7eM|MBnc)j`~(Q^JxD1{8n?#cmRPN5yNE)M)s`LvZFjPCt@wihEbP31E$!KT=e&70 z-@W&{cV_OLNuxWe(H*rfQJ{%i`@#n)*8DK6|U+Vq98YKXa6;zZKlu-Xe9|n{K0IVomwJNtXpTb`Xg!=+N2oMXx z6P@ARPX_Og4p}unv)RZjJC_$l{VKEB%pYWit$wBFJIjf8_?We9J}ckn_WxObIo}nU z!e7l-0F0QogMWk~RfJm!{mWk`5|z&O^5^}7s^i<-u3Vt%N7{IpQY|6U<6%+t&?1_( zoED6ROYIliu4rG}JqFCG{s^ws_fHkuRf&LvRR}t+7NC(+jg1k+8V7xAl6yA;edcxm<-3BSrk@JSx@Ta=S-=VGlUj> z80(DOc!3voN6A_hx0GzhI2Ks165g#-M%2bQR-iR8p8Y}hb(Q}(BJJWs)uzn5dnk&F<@gmRgGo-AOGEbuj1NEaoV zpv2QuLV#Q;lhbd?(*k3chR0^r#^&TCEL)$jd}Bghm7=glQFKDF@)JezS;b@L6(xU6 zEX_?SYe=rNerq5b*OSwug2qykSJRi~_GtaJtryS}5`7pT3}4w?P3;$Bzn8?=uT_lwEaJHh)8huH@i+ou$d)Gh zhNyG;Q_u1lM{uY0%ho#He49RpKRPeM1#(X0@b{b+!H>7Z@>1dOmQ5ML$?m7Xy??!) zcD?m1nw;SE?4CIxH2S$t2zfo$=e-#AqH7cW?s~$(Yt`Jxzb~T!*t9iI@+XnybYQDy zvRdEG1696P2&yWys8Ixmx8}%BOc>&=_mFw9VTrZ^9S<{vqq@jyy)o!`7(m|!!yH34 zVUP6{%?;7~qDhT`ZyDsgGI-MPDskpNkZO=Fu-+r9R9`D>vhFFk+ZY+VS#CK^SWn)5 zTUP6uf*r=pfP>L;yfFxg;djPF-V_WmiNmMjwJ2;cUL{$r9B&f#U200gx+hJ^L83@Q z391Y+6rzBI@O6_iWGY^xno-#N+T5$rqZI5jHOAP+4MIGH$(y4Bt~utGw8r!11ZsrO z)H`|8P}Yzn${NFZa-RNOFEWgI{_2IBw$-E-dePM&Pp%g=2Ya%-$QA6#@ZuU0x_Ds1 zqx4ql$}3h^ky5RWv|d6t@4(4zEb;GqP`N$%p&~VIyJBuA;f7N6p-~~~3S|#!)ZU+x zIdCuSI@_U9v$iPQ=6kl6EYM}Nol?!PS<=c3IJkWScOVu#TTWEmhHpGuM;MZ!a0gpj zcB@*i=qU^aKw&KmRamPQqN6_;66R>}*4C)pUeB?+^8juQJn!6HyKX*4VC?0)(6Zw! zG4vg`SMZsgp@}ctFogeP23VJl4H|~svIMAcv?^D`K{aQBN_kKQmkpX~hv^w8O2kN6- zfIKEso%=`|-5Yk4NSjgh_lAw~(bYlUaq_nm^ie1p7*vg0rlXB{Vb+_f{^LR5-k7|< zJ{+AGgq6>wN45;2romZ0lb_36(kn-AkH8;ll(6TyFO$NIY;@ip6%Mn zLcd*UsevQLr#I9+y~#vvZg|?Te&gnC!GXX&z`NX`%jk{xfE>8mQJG;|rpr*dvzAq6 z?9YsXJ9cd&N{8X?UEPZkzHtEoz5*`*w&U$ZbF^okSFu_(7pKi_{Z=)uno+q`U#rfk z`ajBIyNXyBc&t}$AVveaqFFQ$gucH56U@buN&MGBG?D@U^)(*kBTE2?9mZ1JF(rJ_ zTuwYS1ivx=llK}NG{-r68&i118(+c6-4}_{uVC*BZxZicfg3Gyf`0|>wX7ftufQ)X zOdL!FQU|IQGYy<;1Bgc|RsE_5}e!}z8o0;a>#rl=&CZW1aQ zcg?W%q=W5TIr_4LvP|$BUhEw4cEj{EHzvE?*@cbmO(|krwrb%zoj128b5L9LuSvb6BF_blnIjnRA z1OLz*K@_RsbIl^^+*Koq&y0zhQ&!D1?m66YE+WrXJIyU5N*aNGZ%#Jet9waCMcDHT?!9VqM}Z9Zx^)DlSuhTwS1@^GAsO;N-(KF-MYNQv61X(G68M`J2Sgh(wdgLu$D-UV)0+xsZ&{tomhc+s@AYwV$WDxaTpUmY-*-h5#ELnQbcXI56FQ$D!g)vDIJz+4q4b9yO-sgY b<;*1_2ut7LmcGM0{1W)(AL~0TP~G}3Bzv@} diff --git a/build/chimaera.vhd b/build/chimaera.vhd index f3a04cbe879f8acffdc1701f63627400b7bd2736..dcb9b66214d61b4c4710436cc3349bbaea786129 100644 GIT binary patch delta 5986 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 delta 5857 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 + ;****************************************************************************** ; @function _free ;****************************************************************************** @@ -12,10 +17,10 @@ global _main _main: mov bx, offset msg_hello - call _writestr - call _crlf - + +; call _crlf +; ; mov ah, HEX (08) ; int HEX (21) ; @@ -30,28 +35,80 @@ _main: ; ; xor ax, ax ; int HEX (16) - - mov ah, HEX (39) - mov dx, offset _dir_non_exist - int HEX (21) - - call _writehex - call _crlf - - mov ah, HEX (39) - mov dx, offset _dir_exist - int HEX (21) - - call _writehex - call _crlf - - mov ah, HEX (39) - mov dx, offset _dir_file - int HEX (21) - - call _writehex - call _crlf - +; +; mov ah, HEX (39) +; mov dx, offset _dir_non_exist +; int HEX (21) +; +; call _writehex +; call _crlf +; +; mov ah, HEX (39) +; mov dx, offset _dir_exist +; int HEX (21) +; +; call _writehex +; call _crlf +; +; mov ah, HEX (39) +; mov dx, offset _dir_file +; int HEX (21) +; +; call _writehex +; call _crlf +; +; mov si, offset msg_hello +; xor ax, ax +; +; mov bx, stdout +; +;.loop: +; +; lodsb +; +; and al, al +; jz .exit +; +; push bx +; push ax +; +; call _fputc +; add sp, 4 +; +; jmp .loop +; +; mov bx, 1 +; mov cx, 15 +; mov dx, offset msg_hello +; +; mov ax, stdout +; push ax +; +; push cx +; push bx +; push dx +; +; call _fwrite +; add sp, 8 +; +; call _writehex +; call _crlf +; +; mov ax, stdout +; push ax +; +; push bx +; push cx +; push dx +; +; call _fwrite +; add sp, 8 +; +; call _writehex +; call _crlf + +.exit: + xor ax, ax ret @@ -59,7 +116,3 @@ _main: ;; Data area. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; msg_hello: db "Hello, world!", HEX (0D), HEX (0A), HEX (00) - -_dir_non_exist: db "abc\\123", HEX (00) -_dir_exist: db "temp", HEX (00) -_dir_file: db "hello.com", HEX (00) diff --git a/src/kernel/int21.asm b/src/kernel/int21.asm index cb56f04..d9bf5f0 100644 --- a/src/kernel/int21.asm +++ b/src/kernel/int21.asm @@ -860,6 +860,12 @@ _int21_dispatch.list: db HEX (3F) dw _int21_3F + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Write to File or Device Using Handle. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + db HEX (40) + dw _int21_40 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Delete/Unlink File. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2518,6 +2524,237 @@ _int21_3F.done: jmp iretc +;****************************************************************************** +; @function _int21_40 +; @brief Write to File or Device Using Handle +; +; @in BX -> File handle.. +; @in CX -> Number of bytes to write. +; @in DS:DX -> Pointer to write buffer. +; +; @out AX -> Number of written. Error code if CF is set. +;****************************************************************************** +_int21_40: + + push bp + push bx + push cx + push dx + push si + push di + push es + push ds + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; First, lets check if we're writing to the console. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp bx, 2 + ja _int21_40.check + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If stdin was passed then we can't write to it. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and bx, bx + jz _int21_40.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Otherwise, lets write the bytes. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov si, dx + +_int21_40.console_loop: + + and cx, cx + jz _int21_40.done + + lodsb + call _writechr + + dec cx + jmp _int21_40.console_loop + +_int21_40.check: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Check if we have any open files. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp word ptr cs:[_vec_files + 2], 0 + je _int21_40.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure we have a valid file handle. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp bx, 3 + jb _int21_40.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the correct file offset by subtracting 3. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + sub bx, 3 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate the offset into our vector. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push dx + push cx + + mov ax, bx + xor dx, dx + + mov cx, 2 + mul cx + + mov bx, ax + pop cx + pop dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Intialize the es register with address of our vector entries + ;; and zero out bx for the counter. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, cs:[_vec_files + 0] + mov es, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If the vector entry is zero then the file handle is invalid. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp word ptr es:[bx], 0 + je _int21_40.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Re-initialize the extra segment but this time with the address + ;; of the vector entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + +_int21_40.copy: + + push si + push ds + push ax + push cx + + mov ds, ax + xor si, si + + lodsw + mov cs:[_curr_cluster], ax + + lodsw + mov cs:[_curr_cluster + 2], ax + + mov di, offset _fat_bpb + mov ax, cs + mov es, ax + + mov cx, 25 + rep movsb + + lodsb + mov cs:[_drive_no], al + + lodsw + mov cs:[_root_cluster], ax + + lodsw + mov cs:[_root_cluster + 2], ax + + lodsw + mov cs:[_fat_start], ax + + lodsw + mov cs:[_fat_start + 2], ax + + lodsw + mov cs:[_root_start], ax + + lodsw + mov cs:[_root_start + 2], ax + + lodsw + mov cs:[_data_start], ax + + lodsw + mov cs:[_data_start + 2], ax + + lodsw + mov cs:[_fat_secmask], ax + + lodsw + mov cs:[_fat_secshift], ax + + lodsw + mov cs:[_clustsize], ax + + lodsw + mov cs:[_info_sector], ax + + mov bx, cs:[_root_cluster] + mov cx, cs:[_root_cluster + 2] + + or bx, cx + + and bx, bx + jnz _int21_40.fat32 + + call _getfattype + jmp _int21_40.write + +_int21_40.fat32: + + mov ax, offset _convert_cluster32 + mov cs:[_convert_cluster], ax + + mov ax, offset _find_free32 + mov cs:[_find_free], ax + + mov ax, offset _nextcluster_fat32 + mov cs:[_next_cluster], ax + + mov ax, offset _update_cluster32 + mov cs:[_update_cluster], ax + +_int21_40.write: + + pop cx + pop ax + pop ds + pop si + + mov es, ax + +_int21_40.error: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop bp + + mov ax, 6 + stc + + jmp iretc + +_int21_40.done: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop bp + + mov ax, cx + clc + + jmp iretc + ;****************************************************************************** ; @function _int21_42 ; @brief Move File Pointer Using Handle diff --git a/src/lib/crt/include/stdio.inc b/src/lib/crt/include/stdio.inc index 165b10a..701b5e3 100644 --- a/src/lib/crt/include/stdio.inc +++ b/src/lib/crt/include/stdio.inc @@ -10,4 +10,11 @@ %define __SEOF 0x0020 %define __SAPP 0x0100 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Console file pointers. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%define stdin 0x0001 +%define stdout 0x0002 +%define stderr 0x0003 + %endif ; _STDIO_INC diff --git a/src/lib/crt/stdio/fputc.asm b/src/lib/crt/stdio/fputc.asm new file mode 100644 index 0000000..401b2a8 --- /dev/null +++ b/src/lib/crt/stdio/fputc.asm @@ -0,0 +1,158 @@ +;****************************************************************************** +; @file fputc.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _fputc +;****************************************************************************** +global _fputc +_fputc: + + push bp + + mov bp, sp + sub sp, 2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push si + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the character off the stack. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + mov [_buffer], al + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the file stream off the stack. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bx, word ptr [bp + 6] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure we actually have a file stream. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and bx, bx + jz _fputc.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If we're 2 or 3 then we're writing to the console. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp bx, 2 + jb _fputc.error + + cmp bx, 3 + ja _fputc.check + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Decrement the value to get the correct file number. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + dec bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Write the character. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ah, HEX (40) + mov cx, 1 + mov dx, offset _buffer + int HEX (21) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If there was a carry then we failed. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jc _fputc.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Otherwise we succeeded. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jmp _fputc.done + +_fputc.check: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get our file handle from the pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push es + push di + + mov es, bx + xor di, di + + mov bx, es:[di + 0] + pop di + pop es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Write the character. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ah, HEX (40) + mov cx, 1 + mov dx, offset _buffer + int HEX (21) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If there was a carry then we failed. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jc _fputc.error + +_fputc.done: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Return the character. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 4] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop si + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Clean up the stack and clear the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add sp, 2 + clc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +_fputc.error: + + xor ax, -1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop si + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Clean up the stack and set the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add sp, 2 + stc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Data area. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +_buffer: db 2 dup (0) diff --git a/src/lib/crt/stdio/fwrite.asm b/src/lib/crt/stdio/fwrite.asm new file mode 100644 index 0000000..3d7f92d --- /dev/null +++ b/src/lib/crt/stdio/fwrite.asm @@ -0,0 +1,225 @@ +;****************************************************************************** +; @file fread.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Includes. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%include + +;****************************************************************************** +; @function _fwrite +;****************************************************************************** +global _fwrite +_fwrite: + + push bp + + mov bp, sp + sub sp, 2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push dx + push si + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Zero out the reserved stack value. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov word ptr [bp - 2], 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the file handle off the stack. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bx, word ptr [bp + 10] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure we actually have a file handle. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and bx, bx + jz _fwrite.done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If we're 2 or 3 then we're writing to the console. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp bx, 2 + jb _fwrite.error + + cmp bx, 3 + ja _fwrite.check + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Decrement the value to get the correct file number. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + dec bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate the amount of bytes to read. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 8] + xor dx, dx + + mov cx, word ptr [bp + 6] + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If the number of bytes are zero then we're done. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and cx, cx + jz _fwrite.done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Move the number of bytes into the cx register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the dx register with the address of the buffer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov dx, word ptr [bp + 4] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Write # no of bytes from the buffer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ah, HEX (40) + int HEX (21) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If there was a carry then we failed. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jc _fwrite.error + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Otherwise we succeeded. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jmp _fwrite.check2 + +_fwrite.check: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Calculate the amount of bytes to read. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp + 8] + xor dx, dx + + mov cx, word ptr [bp + 6] + mul cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If the number of bytes are zero then we're done. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and cx, cx + jz _fwrite.done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get our file handle from the pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push es + push di + + mov es, bx + xor di, di + + mov bx, es:[di + 0] + pop di + pop es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Move the number of bytes into the cx register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the dx register with the address of the buffer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov dx, word ptr [bp + 4] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Write # no of bytes from the buffer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ah, HEX (40) + int HEX (21) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If there was a carry then we failed. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jc _fwrite.error + +_fwrite.check2: + + cmp word ptr [bp + 8], 1 + jne _fwrite.check3 + + cmp ax, word ptr [bp + 6] + jne _fwrite.zero + + mov ax, 1 + jmp _fwrite.done + +_fwrite.check3: + + cmp word ptr [bp - 6], 1 + je _fwrite.done + + xor dx, dx + + mov cx, word ptr [bp + 6] + div cx + + jmp _fwrite.done + +_fwrite.zero: + + xor ax, ax + +_fwrite.done: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop si + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Clean up the stack and clear the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add sp, 2 + clc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret + +_fwrite.error: + + xor ax, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop si + pop dx + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Clean up the stack and set the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add sp, 2 + stc + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the base pointer and return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop bp + ret -- 2.34.1