├── README ├── apps ├── 3DWIRE68 ├── ARC19 ├── BTRFLY ├── DOS15 ├── DROPDN ├── FACT7 ├── FADER15 ├── FERN10 ├── FIRE62 ├── FLIN60 ├── FLSHCRD ├── FPATAN ├── GRAFX ├── HELLO9 ├── HERSHEY ├── HUB11 ├── LBTS281 ├── MANDL18 ├── MINE63 ├── PLASMA38 ├── PONG40k ├── RANREC22 ├── README ├── STAR50 ├── TCAD │ ├── README │ ├── aro.s │ ├── bez.s │ ├── demo.pdf │ ├── demo.tcd │ ├── io.s │ ├── main.s │ ├── makefile │ ├── seg.s │ └── txt.s ├── TICTAC │ ├── TICTAC39 │ ├── o.bts │ ├── rory.bts │ ├── smily.bts │ └── x.bts ├── TREE15 ├── WIN06 ├── XOR9 ├── dir ├── grafx.png └── palette.png ├── boot ├── boot1.s ├── boot2.s ├── gdtidttss.s ├── irq0.s ├── irq1.s ├── irq11.s ├── mouse.s ├── picpitinit.s ├── ps2init.s └── ps2mouseinit.s ├── build.s ├── doc ├── 2do ├── LICENSE ├── README ├── asmDOS ├── asmLinux ├── asmWin ├── auto-local ├── bochsrc ├── chs ├── dd ├── disasm ├── faith ├── fpu ├── hardware ├── makebootcd ├── memorymap ├── mrm ├── optimization ├── privilege ├── resources ├── tedit-help ├── tomsasmtips ├── tomsimagetips ├── tomslinuxmacros ├── tomslinuxtips ├── ttasm-help └── usbkeybd ├── makefile ├── tatOS.config ├── tatOS.img ├── tlib ├── README-tlib ├── alloc.s ├── arc.s ├── bcd2bin.s ├── bezier.s ├── bits.s ├── bmp.s ├── calc.s ├── circle.s ├── clipboard.s ├── clipping.s ├── controls.s ├── cpuid.s ├── datetime.s ├── dd.s ├── dropdown.s ├── dump.s ├── fat16.s ├── filemanager.s ├── flood.s ├── font01.inc ├── font02.inc ├── fontHershey.inc ├── geometry.s ├── getc.s ├── getline.s ├── gets.s ├── is.s ├── line.s ├── list.s ├── make.s ├── math.s ├── memset.s ├── origin.s ├── paging.s ├── palette.s ├── pci.s ├── pointer.s ├── polar.s ├── polygon.s ├── put.s ├── puthershey.s ├── rand.s ├── rectangle.s ├── roundmode.s ├── scriptT.bits ├── shell.s ├── sort.s ├── string.s ├── subdivide.s ├── tableext.s ├── tablepub.s ├── tablesym.s ├── tatOS.inc ├── tatOSinit.s ├── tedit.s ├── time.s ├── tlib.s ├── tlibentry.s ├── tlink.s ├── ttasm.s ├── video.s ├── viewtxt.s └── xxd.s └── usb ├── README ├── README-TD ├── README-Toggle ├── baseaddress.s ├── checkcsw.s ├── clearep.s ├── configdesc.s ├── devicedesc.s ├── error.s ├── hubdesc.s ├── hubport.s ├── info.s ├── initdevices.s ├── initehci.s ├── initflash.s ├── inithub.s ├── initkeyboard.s ├── initmouse.s ├── inituhci.s ├── inquiry.s ├── interkeybd.s ├── intermouse.s ├── modesense.s ├── port.s ├── prepareTD-ehci.s ├── prepareTD-uhci.s ├── protocol.s ├── queuehead.s ├── read10.s ├── readcapacity.s ├── reportdesc.s ├── requestsense.s ├── run.s ├── saveEP.s ├── setaddress.s ├── setconfig.s ├── setidle.s ├── showehcireg.s ├── showehciroothubports.s ├── showuhcireg.s ├── status.s ├── testunit.s ├── usb.s ├── usbcentral.s ├── usbdump.s ├── usberror └── write10.s /README: -------------------------------------------------------------------------------- 1 | README - tatOS - July 2016 2 | 3 | Welcome to tatOS - "programming for the common man in assembler" 4 | 5 | What's new: bezier, bez2pdf, apps/TCAD update 6 | 7 | tatOS is an x86 32 bit hobby operating system that gets worked on in my spare time. 8 | It has provided many hours of programming enjoyment (perhaps too many !) 9 | 10 | The corner stone of tatOS is the "tedit" text editor and the "ttasm" assembler. 11 | The assembler will create 32 bit executables from single source files, and supports 12 | public and extern symbols and works with "tlink" and "make" to create executables 13 | from multiple source file projects. 14 | 15 | There is a suite of functions for graphics, string handling, file system (/tlib) 16 | There is a suite of functions to control usb devices. (/usb) 17 | 18 | This version of tatOS includes 4 differant usb controller drivers: 19 | * usb 1.0 uhci 20 | * usb 2.0 ehci with uhci companion controllers 21 | * usb 2.0 ehci with integrated root hub 22 | * usb 2.0 ehci with no usb 1.0 support 23 | You must set USBCONTROLLERTYPE in tatOS.config and reassemble for your hdwre. 24 | 25 | This version of tatOS supports these usb devices: 26 | * usb mouse 27 | * usb keyboard 28 | * usb flash drive 29 | 30 | I now use ehci w/root hub exclusively. The Lenovo desktop does not have ps2 ports. 31 | The ps2 keyboard driver and ps2 mouse driver are included for reference only. 32 | 33 | Not supported: 34 | * ohci and usb 3.0 xhci usb controllers 35 | * wireless usb 36 | * multi-tasking, multi-threading, multiple processors 37 | * APIC, ACPI, EFI, MMX, or SSE. 38 | See /doc/hardware for a more complete list of supported hardware 39 | 40 | tatOS includes a protected mode interface using sysenter/sysexit (see tlib/tlibentry.s) 41 | tatOS includes an elementary identify mapped paging scheme (see tlib/paging.s) 42 | 43 | tatOS is designed for desktop/laptop computers with a single 32bit Intel or 44 | Amd processor. It will also run on 64 bit multi-processor machines using the 45 | bootstrap processor only in 32 bit protected mode. 46 | 47 | Most apps and utilities I develop for tatOS use the keyboard only because of time 48 | constraints, but a few also require the usb mouse. 49 | 50 | Video is SVGA graphics mode 0x103 which is 800x600x8bpp, 256 color palletized mode. 51 | This is the only mode supported. A tatOS app can draw over the entire 800x600 pixel 52 | screen with graphic primitives like line, circle, arc, text, rectangle, 53 | or draw to a private pixel buffer. See functions in /tlib. 54 | See tlib/video.s for swaping pixel buffers to the screen. 55 | 56 | tatOS supports the following file formats: txt & bmp for input and pdf for output. 57 | 58 | tatOS can not read or write to your hard drive so dont worry. 59 | 60 | tatOS requires a BIOS to boot that supports booting from floppy or flash drive using 61 | floppy emulation. Use a floppy disc on an old computer or unformatted flash drive with 62 | a modern computer. Copy the file "tatOS.img" to the first sector of the device. 63 | Use "dd" on Linux or "rawrite" on Windows. 64 | Linux Floppy Disc: dd if=tatOS.img of=/dev/fd0 65 | Linux Flash Drive: dd if=tatOS.img of=/dev/sda 66 | I have also had some success booting modern computers with an external floppy drive 67 | with usb attach. The filesystem on your flash drive will not be preserved but there 68 | are utilities on Linux or Windows or tatOS to restore this. 69 | 70 | If you are able to successfully boot then you will be running a program called the 71 | tatOS "shell" which gives a scrolling list of utilities you can run. At this point 72 | you can remove your boot flash drive and install a tatOS FAT16 formatted flash drive 73 | and go thru the sequence of usb controller init and usb flash drive init (see USB 74 | Central from the shell). The shell includes a utility to format a flash drive with 75 | a single partition FAT16 filesystem that is also useable by Linux and Windows. See 76 | notes in /tatOS/tlib/fat.s about the tatOS FAT16 filesystem restrictions. 77 | 78 | Some graphic controls are available. 79 | See controls.s, list.s, dropdown.s, gets.s in /tlib 80 | 81 | There are 3 fonts available which support the ascii character set. 82 | * font01 is the standard bitmap font. 83 | * font02 is a smaller bitmap font I use for menus 84 | * fontHershey is a scaleable vector font. 85 | See put.s for functions to display ascii characters and strings. 86 | 87 | A special memory block called the "dump" (tlib/dump.s) is used by the kernel and your 88 | apps to write ascii strings (logging) about what is going on. 89 | 90 | To shut down tatOS just hold down your power button. 91 | 92 | If you have added code to /tlib or /usb and nasm reports a TIMES error, 93 | increase the SIZEOFTLIB in tlib/tatOS.inc and reassemble. 94 | 95 | You can break out of most infinite loops or interrupt service routines with 96 | ctrl+alt+del which sends you back to the shell. 97 | 98 | See /doc for more details and help. 99 | See /tlib and /usb source code for all OS function capability. 100 | See /apps for sample applications that can be assembled by ttasm and run 101 | under tatOS directly from the tedit text editor. 102 | 103 | tatOS is written in x86 assembly with NASM and developed on a Debian Linux machine. 104 | Thanks for trying tatOS. 105 | 106 | Tom Timmermann 107 | Janesville, Wisconsin USA 108 | 109 | 110 | -------------------------------------------------------------------------------- /apps/DOS15: -------------------------------------------------------------------------------- 1 | 2 | 3 | ;DOSTEST 4 | ;your basic starter code for a tatOS app 5 | ;no fancy code for mouse/paint or keyboard 6 | ;just calc some things and paint or dump 7 | ;used mostly to debug some small portion of code 8 | 9 | org STARTOFEXE 10 | 11 | 12 | 13 | ;************* 14 | ; DATA 15 | ;************* 16 | 17 | str1: 18 | db 'Hello World',0 19 | str2: 20 | db 'value of ebx',0 21 | 22 | 23 | ;************* 24 | ; CODE 25 | ;************* 26 | 27 | 28 | ..start 29 | 30 | backbufclear 31 | 32 | fillrect 0,100,50,50,RED 33 | 34 | puts FONT01,100,100,str1,0xeffe 35 | 36 | mov ebx,0xaabbccdd 37 | putebx ebx,100,150,0xefff,0 38 | 39 | setpixel 10,10,RED 40 | 41 | dumpstr str1 42 | 43 | mov ebx,3 44 | dumpebx ebx,str2,0 ;eax=9, ebx=value, ecx=addressofstring, edx=regsize 45 | 46 | swapbuf 47 | getc 48 | 49 | exit 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /apps/FACT7: -------------------------------------------------------------------------------- 1 | 2 | ;****************************************************** 3 | ;Factorial 4 | 5 | ;our first effort into the interesting field of 6 | ;recursive programming. 7 | 8 | ;The first time I ran this program it triple faulted 9 | ;and rebooted the computer. Then I had 2 processor faults 10 | ;to deal with. (bad coding, recursive function not exiting) 11 | 12 | ;A couple things to remember about writting a 13 | ;recursive function: 14 | ; * args are passed on stack 15 | ; * must use retn ?? end of recursive proc 16 | ; * must have a test to stop calling itself 17 | 18 | ;this program is not interactive 19 | ;you have to change the "push 10" below and re-assemble 20 | ;this solution is displayed to the screen in reg eax 21 | ;plus check the dump for more info 22 | 23 | ;2009 tat for tatOS 24 | ;latest rev Sept 2013 for protected mode interface 25 | ;****************************************************** 26 | 27 | org STARTOFEXE 28 | 29 | 30 | 31 | ;********* 32 | ; DATA 33 | ;********* 34 | 35 | 36 | stor: 37 | dd 1 38 | 39 | str1: 40 | db 'factorial value in ebx',0 41 | 42 | ;********* 43 | ; CODE 44 | ;********* 45 | 46 | 47 | ..start 48 | 49 | 50 | mov dword [stor],1 51 | 52 | ;push a number to compute the factorial 53 | ;here we compute 10*9*8*7*6*5*4*3*2*1=0x375f00 54 | ;max allowable to push is 12 55 | push 10 56 | call Factorial 57 | 58 | ;display the solution 59 | ;the biggest number to fit in a 32bit reg is 60 | ;0xffffffff=4.29E9 61 | ;which means this program cant compute factorial 62 | ;for any number bigger than 12 63 | ;for bigger nums we need to save edx:eax after mul 64 | ;and compute a solution that fits in 2 dwords not 1 65 | mov ebx,[stor] 66 | putebx ebx,0,0,0xeffe,0 67 | swapbuf 68 | getc 69 | exit 70 | 71 | 72 | 73 | 74 | 75 | ;************************************** 76 | ;Factorial 77 | ;this function computes the factorial 78 | ;of any integer smaller than 13 79 | 80 | ;the factorial of numbers larger than 13 81 | ;doesnt fit in one dword 82 | 83 | ;e.g. factorial of 5 = 5*4*3*2*1 84 | 85 | ;input 86 | ;push value to be computed on stack 87 | ;solution is stored in global [stor] 88 | 89 | ;this is a recursive function 90 | ;because it calls itself 91 | ;************************************** 92 | 93 | Factorial: 94 | 95 | push ebp 96 | mov ebp,esp 97 | 98 | ;get function arg 99 | mov ebx,[ebp+8] 100 | 101 | ;dump the value in ebx 102 | dumpebx ebx,str1 103 | 104 | ;multiply it by stor and resave 105 | mov eax,[stor] 106 | xor edx,edx 107 | mul ebx 108 | mov [stor],eax 109 | 110 | ;decrement the arg 111 | dec ebx 112 | 113 | ;done when ebx=1 114 | cmp ebx,1 115 | jz .done 116 | 117 | ;go again 118 | push ebx 119 | call Factorial ;call self 120 | 121 | .done: 122 | pop ebp 123 | retn 4 124 | 125 | 126 | 127 | ;***********************TheEnd ********************* 128 | 129 | 130 | -------------------------------------------------------------------------------- /apps/FADER15: -------------------------------------------------------------------------------- 1 | 2 | ;************************************************ 3 | ;textfader 4 | 5 | ;this demonstrates animation of one entry 6 | ;in the DAC palette 7 | 8 | ;program speed is controlled by the sleep function 9 | ;and will quit automatically (no need for keypress) 10 | 11 | ;Oct 2012 12 | ;rev Oct 2013 for tatOS protected mode interface 13 | ;************************************************ 14 | 15 | org STARTOFEXE 16 | 17 | 18 | 19 | ;********* 20 | ; DATA 21 | ;********* 22 | 23 | blue: 24 | db 0 25 | 26 | col: 27 | dd 0 28 | row: 29 | dd 0 30 | 31 | str1: 32 | db 'Hello World',0 33 | 34 | ;********* 35 | ; CODE 36 | ;********* 37 | 38 | start 39 | 40 | 41 | ;black screen 42 | fillrect 0,0,800,600,BLA 43 | 44 | ;draw a bunch of "hellow worlds" to fill the screen 45 | ;draw a column from bottom up and right to left 46 | mov dword [col],640 47 | mov dword [row],580 48 | 49 | ;we will animate the text color in the DAC palette 50 | ;index=0 is initially the same as the background color 51 | ;so the text wont show at first 52 | .1: 53 | puts FONT01,[col],[row],str1,0x00ef 54 | sub dword [row],15 55 | jns .1 56 | 57 | ;move left 58 | mov dword [row],580 59 | sub dword [col],150 60 | jns .1 61 | 62 | swapbuf 63 | 64 | 65 | 66 | 67 | ;make the text color go from black->blue 68 | .FadeIN_loop: 69 | 70 | mov eax,61 ;setdaccolor 71 | mov dl,0 ;red 72 | mov dh,0 ;green 73 | mov bl,[blue] ;blue 74 | mov ecx,0 ;set color index=0 in DAC 75 | sysenter 76 | 77 | mov eax,37 ;sleep 78 | mov ebx,100 ;milliseconds 79 | sysenter 80 | 81 | ;increment blue 82 | inc byte [blue] ;brighten the text color 83 | 84 | ;DAC colors are 6bit 85 | cmp byte [blue],0x3f 86 | jb .FadeIN_loop 87 | 88 | 89 | 90 | 91 | ;make the text go from blue->black 92 | .FadeOUT_loop: 93 | 94 | mov eax,61 ;setdaccolor 95 | mov dl,0 96 | mov dh,0 97 | mov bl,[blue] 98 | mov ecx,0 99 | sysenter 100 | 101 | mov eax,37 ;sleep 102 | mov ebx,100 103 | sysenter 104 | 105 | dec byte [blue] ;darken the text color 106 | 107 | cmp byte [blue],0 108 | ja .FadeOUT_loop 109 | 110 | 111 | 112 | exit ;to tedit 113 | 114 | 115 | ;***********************TheEnd ***************************** 116 | 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /apps/FPATAN: -------------------------------------------------------------------------------- 1 | 2 | ;main09 Sept 8, 2015 3 | 4 | ;FPATAN test 5 | ;to see what this fpu function gives 6 | ;all results are written to the dump 7 | 8 | 9 | org STARTOFEXE 10 | 11 | 12 | 13 | ;************* 14 | ; DATA 15 | ;************* 16 | 17 | 18 | num01745: 19 | dq .017455 20 | 21 | strNL: 22 | db 0xa,0 23 | 24 | str0: 25 | db 'All results written to the DUMP',0 26 | 27 | str1: 28 | db '1 deg......',0 29 | str2: 30 | db '90 deg......',0 31 | str3: 32 | db '180 deg......',0 33 | str4: 34 | db '181 deg......',0 35 | str5: 36 | db '270 deg......',0 37 | str6: 38 | db '359 deg......',0 39 | str7: 40 | db '360 deg......',0 41 | 42 | 43 | 44 | ;************* 45 | ; CODE 46 | ;************* 47 | 48 | 49 | ..start 50 | 51 | backbufclear 52 | 53 | 54 | ;the rounding mode = "nearest" 55 | ;****************************** 56 | 57 | 58 | ;1 deg 59 | dumpstr str1 60 | fld qword [num01745] ;st0=.017455 61 | fld1 ;st0=1, st1=.01745 62 | fpatan ;atan2(.01745/1) 63 | mov eax,116 ;dumpst09 64 | sysenter 65 | mov eax,99 ;rad2deg 66 | sysenter 67 | mov eax,116 ;dumpst09 68 | sysenter 69 | ffree st0 70 | dumpstr strNL 71 | ;result=.999996281 72 | 73 | 74 | ;90 deg 75 | dumpstr str2 76 | fld1 ;st0=1 77 | fldz ;st0=0, st1=1 78 | fpatan ;atan2(1/0) 79 | mov eax,116 ;dumpst09 80 | sysenter 81 | mov eax,99 ;rad2deg 82 | sysenter 83 | mov eax,116 ;dumpst09 84 | sysenter 85 | ffree st0 86 | dumpstr strNL 87 | ;result=89.999999995 88 | 89 | 90 | ;180 deg 91 | dumpstr str3 92 | fldz ;st0=0 93 | fld1 ;st0=1, st1=0 94 | fchs ;st0=-1, st1=0 95 | fpatan ;atan2(0/-1) 96 | mov eax,116 ;dumpst09 97 | sysenter 98 | mov eax,99 ;rad2deg 99 | sysenter 100 | mov eax,116 ;dumpst09 101 | sysenter 102 | mov eax,114 ;dumpFPUstatus/control 103 | sysenter 104 | ffree st0 105 | dumpstr strNL 106 | ;result=179.999999990 107 | 108 | 109 | ;181 deg 110 | dumpstr str4 111 | fld qword [num01745] ;st0=.017455 112 | fchs ;st0=-.017455 113 | fld1 ;st0=1, ... 114 | fchs ;st0=-1, ... 115 | fpatan ;atan2(-.017455/-1) 116 | mov eax,116 ;dumpst09 117 | sysenter 118 | mov eax,99 ;rad2deg 119 | sysenter 120 | mov eax,116 ;dumpst09 121 | sysenter 122 | mov eax,114 ;dumpFPUstatus/control 123 | sysenter 124 | ffree st0 125 | dumpstr strNL 126 | ;result=-179.000003709 127 | 128 | 129 | ;270 deg 130 | dumpstr str5 131 | fld1 ;st0=1 132 | fchs ;st0=-1 133 | fldz ;st0=0, st1=-1 134 | fpatan ;atan2(-1/0) 135 | mov eax,116 ;dumpst09 136 | sysenter 137 | mov eax,99 ;rad2deg 138 | sysenter 139 | mov eax,116 ;dumpst09 140 | sysenter 141 | mov eax,114 ;dumpFPUstatus/control 142 | sysenter 143 | ffree st0 144 | dumpstr strNL 145 | ;result = -89.999999995 146 | 147 | 148 | ;359 deg 149 | dumpstr str6 150 | fld qword [num01745] ;st0=.017455 151 | fchs ;st0=-.017455 152 | fld1 ;st0=1 153 | fpatan ;atan2(-.017455/1) 154 | mov eax,116 ;dumpst09 155 | sysenter 156 | mov eax,99 ;rad2deg 157 | sysenter 158 | mov eax,116 ;dumpst09 159 | sysenter 160 | mov eax,114 ;dumpFPUstatus/control 161 | sysenter 162 | ffree st0 163 | dumpstr strNL 164 | ;result = -.999996281 165 | 166 | 167 | ;360 deg 168 | dumpstr str7 169 | fldz ;st0=0 170 | fld1 ;st0=1, st1=0 171 | fpatan ;atan2(0,1) 172 | mov eax,116 ;dumpst09 173 | sysenter 174 | mov eax,99 ;rad2deg 175 | sysenter 176 | mov eax,116 ;dumpst09 177 | sysenter 178 | mov eax,114 ;dumpFPUstatus/control 179 | sysenter 180 | ffree st0 181 | dumpstr strNL 182 | ;result = 0 183 | 184 | 185 | ;so if you want to return a resulting angle that is always 186 | ;positive from 0->360 degrees then we do this: 187 | ;if dy is negative, add 360 deg else leave it alone 188 | 189 | 190 | 191 | 192 | 193 | ;now set the rounding mode to "UP" 194 | ;and see what we get 195 | ;ttasm does not yet support the "fldcw" insruction 196 | ;********************************** 197 | 198 | 199 | 200 | 201 | 202 | ;all results written to the dump 203 | puts FONT01,100,100,str0,0xeffe 204 | 205 | swapbuf 206 | getc 207 | 208 | exit 209 | 210 | -------------------------------------------------------------------------------- /apps/HELLO9: -------------------------------------------------------------------------------- 1 | 2 | ;******************************************************** 3 | ;HELLOWORLD 4 | ;demo of puts and fillrect functions 5 | ;modified to demo swaprectprep and swaprect 6 | ;you draw to upper left corner of backbuf 7 | ;and then display a "window" any where on the screen (LFB) 8 | ;assembles with ttasm for tatOS 9 | ;rev Sept 2013 for protected mode interface 10 | ;********************************************************* 11 | 12 | org STARTOFEXE 13 | 14 | 15 | 16 | ;************** 17 | ; DATA 18 | ;************** 19 | 20 | 21 | str1: 22 | db 'Hello World',0 23 | str2: 24 | db 'Press any key to quit',0 25 | 26 | color: 27 | dd 0 28 | 29 | ;************** 30 | ; CODE 31 | ;************** 32 | 33 | 34 | 35 | ..start 36 | 37 | ;the first two args control where the window appears on the screen 38 | mov eax,51 ;swaprectprep 39 | mov ebx,100 ;xwindow 40 | mov ecx,200 ;ywindow 41 | mov edx,300 ;width 42 | mov esi,100 ;height 43 | sysenter 44 | 45 | ;use ebx for the color 46 | mov ebx,BLU 47 | 48 | Draw: 49 | fillrect 0,0,300,100,[color] 50 | puts FONT01,20,20,str1,0xfdf0 51 | puts FONT01,20,40,str2,0xfdf0 52 | 53 | mov eax,52 ;swaprect 54 | sysenter 55 | 56 | 57 | ;we pause for a very short time 58 | ;then increment the rectangle color and draw again 59 | ;this should drive the user crazy I think 60 | mov eax,37 ;sleep 61 | mov ebx,5 ;milliseconds 62 | sysenter 63 | 64 | ;inc palette color 65 | add dword [color],1 66 | 67 | ;press any key to quit 68 | mov eax,12 ;checkc 69 | sysenter 70 | jz Draw 71 | 72 | 73 | exit 74 | 75 | 76 | 77 | ;***********************TheEnd *********************************************** 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /apps/MANDL18: -------------------------------------------------------------------------------- 1 | ;MANDELBROT 2 | ;This code is taken from A-linux 3 | ;a-linux.img is the bootable floppy image 4 | ;see linuxassembly.org for more info 5 | ;Tom Timmermann modified for 800x600x8bpp pmode 32bit 6 | ;assembles with ttasm as flat binary 7 | ;Dec 2008 8 | ;rev Oct 2013 for tatOS protected mode interface 9 | 10 | 11 | ;***************************************************************** 12 | ; 13 | ; MANDELBROT GENERATOR 14 | ; 15 | ; $Id: mandelbrot.asm,v 1.1 2006/02/09 07:36:07 konst Exp $ 16 | ; 17 | ; Original code by Tenie Remmel & John Eckerdal 18 | ; ported to Linux/framebuffer by Stephan Walter 19 | ; 20 | ; (c) 2002 by Stephan Walter - licensed under the GNU GPL 21 | ; 22 | ; v1.0 2002-06-02 --- First release (175 bytes) 23 | ; 24 | ; 25 | ; Well, it's nothing new, just another Mandelbrot proggie. It uses 26 | ; 640x480x8 fb mode (like all the other asmutils gfx programs). 27 | ; Use Ctrl-C to exit. 28 | ; 29 | ; Color palette is not set. If you run fire256 or X11 before running 30 | ; this program, you'll get different colors. 31 | ; 32 | ; The size of the DOS/INT10h program was 61 bytes, my version has 175 :-( 33 | ; 34 | ; 35 | ; Original file comment: 36 | ;================================================================ 37 | ;This is a small implementation of a mandelbrot generator. 38 | ;I've found this gem a some time ago in a swedish fido-net meeting 39 | ;as a UUencoded file. All comments have been inserted by me 40 | ;(John Eckerdal). I have tried to give some information about what 41 | ;the program acutally calculates. This information might however be 42 | ;incorrect. The source and a compiled version is available for 43 | ;download (1092 bytes). 44 | 45 | ; mandelbrot plotter, 61 bytes - Tenie Remmel 46 | ;=============================================================== 47 | 48 | org STARTOFEXE 49 | 50 | 51 | 52 | ;***************** 53 | ; DATA 54 | ;***************** 55 | 56 | ;we set pixels in a private userland buffer 57 | ;in the same page and directly after users code 58 | equ USERBUF,0x02005000 59 | 60 | bitsperscanline: 61 | dd 0 62 | 63 | 64 | ;***************** 65 | ; CODE 66 | ;***************** 67 | 68 | ..start 69 | 70 | 71 | ;get bitsperscanline 72 | mov eax,22 73 | sysenter 74 | mov [bitsperscanline],eax 75 | 76 | 77 | cld 78 | 79 | ;set edi to point to first pixel of users private buffer 80 | mov edi,USERBUF 81 | mov ecx,600 ;height and outer loop counter 82 | 83 | 84 | 85 | outer_loop: 86 | mov esi,[bitsperscanline] 87 | 88 | 89 | inner_loop: 90 | mov ebp, 127 91 | ; number of iterations. Can be >127 but then 92 | ; it uses 2 more bytes. >255 makes no sense 93 | ; because this is used for the pixel color. 94 | 95 | xor ebx,ebx 96 | ; re := 0 97 | xor edx,edx 98 | ; im := 0 99 | 100 | complex_loop: 101 | 102 | push edx 103 | mov eax, ebx 104 | sub eax,edx 105 | ; eax := re - im 106 | add edx,ebx 107 | ; edx := re + im 108 | imul edx 109 | ; u := (re-im) * (im+re) = re^2 - im^2 110 | sar eax,8 111 | ; u := u / 2^8 112 | pop edx 113 | 114 | xchg ebx, eax 115 | sub ebx,esi 116 | ; new_re := u - width 117 | 118 | imul edx 119 | 120 | ;shld edx, eax, 25 121 | ;ttasm does not support shld so we hardcode 122 | db 0x0f,0xa4,0xc2,0x19 123 | ; edx := 2(re * im) / 2^8 124 | 125 | sub edx,ecx 126 | ; new_im := 2(rm * im) / 2^8 - height 127 | 128 | ;test dh,dh 129 | ;yet another instruction unsupported by ttasm 130 | db 0x84,0xf6 131 | ; if j>=256 plot pixel 132 | 133 | jg plot_color 134 | 135 | dec ebp 136 | ; next iteration 137 | jnz complex_loop 138 | 139 | plot_color: 140 | 141 | xchg ebp,eax 142 | 143 | stosb ;plot pixel, al->edi, edi++ 144 | 145 | 146 | dec esi 147 | jnz inner_loop 148 | 149 | loop outer_loop 150 | 151 | 152 | 153 | mov eax,23 ;swapuserbuf 154 | mov esi,USERBUF 155 | sysenter 156 | 157 | getc 158 | exit 159 | 160 | 161 | 162 | ;*********************TheEnd********************************** 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /apps/RANREC22: -------------------------------------------------------------------------------- 1 | 2 | ;********************************************** 3 | ;RANDRECT 4 | ;simto Charles Petzold in Programming Windows 5 | ;assemble with ttasm for tatOS 6 | ;Oct 2012 7 | ;revised Aug 2013 to use dword values 8 | ;and new tatOS system calls 9 | 10 | ;the rectangle location isnt as random as I would like 11 | ;most rectangles are generated in the 4th quadrant 12 | ;the 1st and 3rd quadrant get the next most 13 | ;lastly the 2nd quadrant gets the least 14 | ;********************************************** 15 | 16 | org STARTOFEXE 17 | 18 | 19 | ;********** 20 | ; DATA 21 | ;********** 22 | 23 | x: 24 | dd 0 25 | y: 26 | dd 0 27 | w: 28 | dd 0 29 | h: 30 | dd 0 31 | c: 32 | dd 0 33 | 34 | clipw: 35 | dd 790 36 | cliph: 37 | dd 590 38 | 39 | str1: 40 | db 'Random Rectangles',10 41 | db 'This routine is inspired by a similar program',10 42 | db 'written by Charles Petzold in "Programming Windows"',10 43 | db 'press any key to continue',10 44 | db 'Press another key to quit',0 45 | 46 | 47 | ;********** 48 | ; CODE 49 | ;********** 50 | 51 | ..start 52 | 53 | 54 | ;3 overlapping startup rectangles 55 | fillrect 200,50,100,100,GRE 56 | fillrect 250,100,100,100,BLU 57 | fillrect 300,150,100,100,YEL 58 | 59 | ;background rectangle for startup message 60 | fillrect 150,350,600,100,BLA 61 | 62 | ;startup message inside black rectangle 63 | putsml FONT01,150,350,str1,0xf4ef 64 | 65 | swapbuf ;make everything show up 66 | getc ;get going after user hits a key 67 | 68 | 69 | ;assign a value of 333 as SEED for rand 70 | rand 333 71 | 72 | 73 | .mainloop: 74 | 75 | 76 | ;set X 77 | rand 0 78 | ;returns random number in eax 79 | mov edx,0 ;0 out before div 80 | div dword [clipw] 81 | ;div returns quotient in eax and remainder in edx 82 | mov [x],edx 83 | 84 | 85 | 86 | 87 | 88 | ;set Y 89 | rand 0 90 | mov edx,0 91 | div dword [cliph] 92 | mov [y],edx 93 | 94 | 95 | ;set WIDTH 96 | rand 0 97 | mov edx,0 98 | div dword [clipw] 99 | ;fillrect does not like w or h = 0 100 | add edx,10 101 | mov [w],edx 102 | 103 | 104 | ;set HEIGHT 105 | rand 0 106 | mov edx,0 107 | div dword [cliph] 108 | add edx,10 109 | mov [h],edx 110 | 111 | 112 | ;set color 113 | inc dword [c] 114 | cmp dword [c],255 115 | jb .doneColor 116 | mov dword [c],0 117 | .doneColor: 118 | 119 | 120 | 121 | 122 | cliprect [x],[y],[w],[h] 123 | ;return clipped values in eax,ebx,esi,edi for x,y,w,h 124 | 125 | 126 | 127 | 128 | ;draw the clipped rect 129 | mov ecx,eax ;x=ecx 130 | xchg ebx,ecx ;x=ebx, y=ecx 131 | fillrect ebx,ecx,esi,edi,[c] 132 | 133 | 134 | swapbuf 135 | checkc ;any keypress will kill the app 136 | jz .mainloop 137 | 138 | 139 | exit ;back to tedit 140 | 141 | 142 | 143 | ;***********************TheEnd *************************** 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /apps/README: -------------------------------------------------------------------------------- 1 | tatOS/apps/README 2 | 3 | Most tatOS apps last re-assembled with ttasm on May 2015 4 | 5 | This directory contains assembly language code and tips from my own flash drive. 6 | You can copy these files to a tatOS formatted flash drive and then boot tatOS 7 | and read this source code into tedit text editor and within tedit you can 8 | assemble these apps using ttasm and then run these programs directly from 9 | the editor. 10 | 11 | Some of these apps like 3dwire, minesweeper & tcad I developed from scratch on 12 | tatOS. Others are authored as noted (mandelbrot, butterfly) and tweeked by 13 | me so they run under tlib and tatOS with 800x600, 256 color graphics. 14 | 15 | Thanks for trying tatOS. 16 | TomT 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /apps/TCAD/demo.tcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tatimmer/tatOS/7c153b2987a1e7439e853d1b41fa4d1cc3dce6d5/apps/TCAD/demo.tcd -------------------------------------------------------------------------------- /apps/TCAD/makefile: -------------------------------------------------------------------------------- 1 | ;makefile23 2 | ;project: tatOS/apps/TCAD 3 | ;7/18/16 4 | main25 5 | seg16 6 | io01 7 | txt04 8 | aro11 9 | bezXX 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /apps/TICTAC/o.bts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tatimmer/tatOS/7c153b2987a1e7439e853d1b41fa4d1cc3dce6d5/apps/TICTAC/o.bts -------------------------------------------------------------------------------- /apps/TICTAC/rory.bts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tatimmer/tatOS/7c153b2987a1e7439e853d1b41fa4d1cc3dce6d5/apps/TICTAC/rory.bts -------------------------------------------------------------------------------- /apps/TICTAC/smily.bts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tatimmer/tatOS/7c153b2987a1e7439e853d1b41fa4d1cc3dce6d5/apps/TICTAC/smily.bts -------------------------------------------------------------------------------- /apps/TICTAC/x.bts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tatimmer/tatOS/7c153b2987a1e7439e853d1b41fa4d1cc3dce6d5/apps/TICTAC/x.bts -------------------------------------------------------------------------------- /apps/TREE15: -------------------------------------------------------------------------------- 1 | 2 | ;*************************************************** 3 | ;Tree 4 | ;draws a tree like object using a stack based approach 5 | ;each child branch is connected to the parent branch 6 | ;this algorithm is similar to floodfill 7 | ;we pop off the stack 1 branch and draw it 8 | ;we compute 3 new child branches 9 | ;we push on the stack each child branch 10 | ;that meets a minimum size 11 | 12 | ;May 2013 assembles with ttasm for tatOS 13 | ;rev Sept 2013 for protected mode interface 14 | ;*************************************************** 15 | 16 | org STARTOFEXE 17 | 18 | 19 | ;************* 20 | ; DATA 21 | ;************* 22 | 23 | 24 | ;total qty branches on stack 25 | numbranches: 26 | dd 0 27 | x1: 28 | dd 0 29 | y1: 30 | dd 0 31 | x2: 32 | dd 0 33 | y2: 34 | dd 0 35 | angle: 36 | dd 0 37 | length: 38 | dd 0 39 | color: 40 | dd 20 41 | 42 | totalbranchesdrawn: 43 | dd 0 44 | 45 | str1: 46 | db 'Total Branch Count',0 47 | 48 | title: 49 | db 'TREE',0 50 | 51 | ;************* 52 | ; CODE 53 | ;************* 54 | 55 | 56 | ..start 57 | 58 | ;black background 59 | fillrect 0,0,800,600,BLA 60 | 61 | 62 | ;Yaxis at bottom scanline and +y pointing up 63 | ;so the tree developes from the bottom up as it should 64 | ;for an upside down tree just comment out this line 65 | setyorient -1 66 | 67 | 68 | ;for starters 69 | ;push the parameters of the first branch on the stack 70 | ;parameters are: x1,y1,Length,angle 71 | push 400 72 | push 50 73 | push 150 74 | push 90 75 | 76 | mov dword [numbranches],1 77 | mov dword [totalbranchesdrawn],1 78 | 79 | 80 | GetBranch: 81 | 82 | 83 | ;test for done-ness or else we mess up the stack 84 | cmp dword [numbranches],0 85 | jz Done 86 | 87 | 88 | ;pop off 1 branch 89 | pop [angle] 90 | pop [length] 91 | pop [y1] 92 | pop [x1] 93 | dec dword [numbranches] 94 | 95 | 96 | ;compute branch dx,dy 97 | mov eax,59 ;polar2rect 98 | mov ebx,[length] 99 | mov ecx,[angle] 100 | sysenter 101 | ;returns ebx=rcos()=dx, eax=rsin()=dy 102 | 103 | ;compute x2 104 | add ebx,[x1] 105 | mov [x2],ebx 106 | ;compute y2 107 | add eax,[y1] 108 | mov [y2],eax 109 | 110 | 111 | ;draw the branch 112 | line 0xffffffff,[x1],[y1],[x2],[y2],[color] 113 | 114 | 115 | ;increment the branch color 116 | inc dword [color] 117 | 118 | 119 | ;compute length of child branch 120 | ;each child branch is shorter than parent 121 | ;we stop pushing branches on the stack 122 | ;when they get too short 123 | mov eax,[length] 124 | mov ebx,2 125 | mul ebx 126 | mov ebx,3 127 | xor edx,edx 128 | div ebx 129 | ;edi=length * 2 / 3 130 | cmp eax,5 131 | jb GetBranch 132 | mov edi,eax 133 | 134 | 135 | 136 | ;push parameters for 1st child branch on the stack 137 | ;************************************************* 138 | push [x2] 139 | push [y2] 140 | push edi 141 | ;set angle of child branch relative to parent 142 | ;angle should be 0-90 143 | ;change the angle and experiment with the affect 144 | ;it makes a big differance on the final image 145 | mov eax,[angle] 146 | add eax,60 147 | push eax 148 | ;increment the stack branch count 149 | inc dword [numbranches] 150 | inc dword [totalbranchesdrawn] 151 | 152 | 153 | ;push parameters for 2nd child branch on the stack 154 | ;************************************************* 155 | push [x2] 156 | push [y2] 157 | push edi 158 | ;make the angle of child2 differant than child1 159 | ;for a tree that is "blowing" in the wind 160 | mov eax,[angle] 161 | sub eax,30 162 | push eax 163 | ;increment the stack branch count 164 | inc dword [numbranches] 165 | inc dword [totalbranchesdrawn] 166 | 167 | 168 | ;we opt for a more "full" tree with lots of branches 169 | ;so we add a 3rd child branch 170 | ;for a more simple looking tree skip this child 171 | ;push parameters for 3rd child branch on the stack 172 | ;************************************************* 173 | push [x2] 174 | push [y2] 175 | push edi 176 | ;make the angle of child3 differant than child2 177 | mov eax,[angle] 178 | sub eax,10 179 | push eax 180 | ;increment the stack branch count 181 | inc dword [numbranches] 182 | inc dword [totalbranchesdrawn] 183 | 184 | 185 | jmp GetBranch 186 | 187 | 188 | Done: 189 | ;title for this program 190 | setyorient 1 191 | putshershey 50,100,title,YEL,1,3 192 | setyorient -1 193 | 194 | 195 | ;report the total branches drawn 196 | mov ebx,[totalbranchesdrawn] 197 | putebx ebx,50,50,0xf1ef,0 198 | puts FONT01,150,50,str1,0xf1ef 199 | swapbuf 200 | getc 201 | exit 202 | 203 | 204 | 205 | 206 | ;*****************THE END ******************************** 207 | 208 | 209 | 210 | 211 | 212 | 213 | -------------------------------------------------------------------------------- /apps/WIN06: -------------------------------------------------------------------------------- 1 | 2 | ;win06 Nov 03, 2015 3 | 4 | 5 | ;a basic program with ps2 keyboard and usb mouse functionality 6 | ;move the mouse, click mouse buttons 7 | ;press any key on your ps2 keyboard 8 | 9 | ;this program displays: 10 | ; * Left/Middle/Right mouse click message 11 | ; * x,y mouse coordinate 12 | ; * ascii value of each keypress on the keyboard 13 | 14 | ;note on the wheel message "toward" means toward the screen 15 | ;and away means away from the screen 16 | 17 | ;to quit the program press ESCAPE 18 | 19 | 20 | org STARTOFEXE 21 | 22 | 23 | 24 | ;************** 25 | ; DATA 26 | ;************** 27 | 28 | 29 | 30 | str1: 31 | db 'Good-day Mate !',0 32 | str2: 33 | db 'Left Button Down',0 34 | str3: 35 | db 'Middle Button Down',0 36 | str4: 37 | db 'Right Button Down',0 38 | str5: 39 | db 'Wheel Away',0 40 | str6: 41 | db 'Wheel Toward',0 42 | str10: 43 | db 'STARTWIN',0 44 | str11: 45 | db 'Last Key Pressed = 0x',0 46 | 47 | PaintMessage: 48 | dd str1 49 | 50 | KeyboardBuffer: 51 | db 0 52 | 53 | 54 | 55 | 56 | 57 | ;************** 58 | ; CODE 59 | ;************** 60 | 61 | ..start 62 | 63 | 64 | ;init values 65 | 66 | dumpstr str10 67 | 68 | mov dword [PaintMessage],str1 69 | mov byte [KeyboardBuffer],0 70 | 71 | 72 | 73 | AppMainLoop: 74 | 75 | 76 | ;********** 77 | ; PAINT 78 | ;********** 79 | 80 | backbufclear 81 | 82 | 83 | ;display a message response to mouse clicks 84 | puts FONT01,100,100,[PaintMessage],0xefff 85 | 86 | 87 | ;get mouse position 88 | mov eax,64 ;GetMouseXY 89 | sysenter ;returns eax=mouseX, ebx=mouseY 90 | 91 | ;display the mouse position x,y 92 | push ebx 93 | mov ebx,eax 94 | putebx ebx,100,150,0xefff,0 95 | pop ebx 96 | putebx ebx,200,150,0xefff,0 97 | 98 | 99 | 100 | ;display the keypress prompt string 101 | puts FONT01,100,200,str11,0xefff 102 | ;display the ascii key pressed 103 | mov bl,[KeyboardBuffer] 104 | mov eax,14 ;putebx 105 | mov ecx,310 ;x 106 | mov edx,200 ;y 107 | mov esi,0xefff ;colors 108 | mov edi,2 ;size=bl 109 | sysenter 110 | 111 | 112 | 113 | mov eax,62 ;arrowpointer 114 | sysenter 115 | 116 | swapbuf 117 | ;endpaint 118 | 119 | 120 | 121 | 122 | 123 | ;**************** 124 | ; PS2 Keyboard 125 | ;**************** 126 | 127 | mov eax,12 ;checkc 128 | sysenter 129 | ;return value in al 130 | jz endKeypress 131 | 132 | cmp al,ESCAPE 133 | jz doQuit 134 | 135 | ;save checkc return value for display 136 | ;this is in most cases the ascii char 137 | ;tatOS has some special defines for special keys 138 | mov byte [KeyboardBuffer],al 139 | jmp endKeypress 140 | 141 | 142 | endKeypress: 143 | 144 | 145 | 146 | 147 | ;**************** 148 | ; USB Mouse 149 | ;**************** 150 | 151 | ;this function checks the mouse report buffer for activity 152 | ;sets MOUSEX and MOUSEY 153 | ;returns mouse button/wheel activity in al 154 | ;"queues" up a new usb mouse request 155 | ;so you must include this call with every app that uses usb mouse 156 | 157 | mov eax,63 ;usbcheckmouse 158 | sysenter 159 | 160 | cmp al,0 161 | jz NoMouseActivity 162 | cmp al,1 163 | jz HandleLeftMouse 164 | cmp al,2 165 | jz HandleRightMouse 166 | cmp al,4 167 | jz HandleMiddleMouse 168 | cmp al,5 169 | jz HandleWheelToward 170 | cmp al,6 171 | jz HandleWheelAway 172 | NoMouseActivity: 173 | 174 | jmp AppMainLoop 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | ;******************** 184 | ; Mouse Handlers 185 | ;******************** 186 | 187 | HandleLeftMouse: 188 | mov dword [PaintMessage],str2 189 | jmp AppMainLoop 190 | 191 | HandleMiddleMouse: 192 | mov dword [PaintMessage],str3 193 | jmp AppMainLoop 194 | 195 | HandleRightMouse: 196 | mov dword [PaintMessage],str4 197 | jmp AppMainLoop 198 | 199 | HandleWheelAway: 200 | mov dword [PaintMessage],str5 201 | jmp AppMainLoop 202 | 203 | HandleWheelToward: 204 | mov dword [PaintMessage],str6 205 | jmp AppMainLoop 206 | 207 | 208 | 209 | ;************************** 210 | ; Keyboard Handlers 211 | ;************************** 212 | 213 | 214 | 215 | 216 | doQuit: 217 | exit ;return to tedit 218 | 219 | 220 | 221 | ;****************TheEnd*************************************** 222 | 223 | 224 | 225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /apps/XOR9: -------------------------------------------------------------------------------- 1 | 2 | 3 | ;XOR 4 | 5 | ;This code is the classic XOR background affect 6 | ;the idea is taken from a program called "Galileo" 7 | ;which comes from the collection of 256b.com 8 | ;rewritten by Tom Timmermann for tatOS 800x600x256color 9 | 10 | ;the xor background is very simple 11 | ;the color of each pixel is just (X xor Y) 12 | ;where X and Y are the pixel coordinates 13 | ;works only with a mono-tone gradient palette 14 | ;the affect is a repeating checker board of shaded squares 15 | 16 | ;May 2012 17 | ;rev Oct 2013 for tatOS protected mode interface 18 | 19 | ;Below are the intro comments from the original author of Galileo 20 | ;his program draws the xor background then draws a very cool 21 | ;shaded sphere, all with the paletized mode 13h 22 | ;this xor program omits the sphere 23 | 24 | 25 | ;**************************************************************** 26 | ; G A L I L E O 27 | ;**************************************************************** 28 | ; (C) 2001, loveC e-mail: lovec@cauldron.sk 29 | ; Big thanx for baze and Spektra Soft & Hardware 30 | ; Samozrejme moja vdaka patri aj Galileovi, ktory uz davno vedel ze: 31 | ; "A predsa sa toci!" 32 | 33 | 34 | org STARTOFEXE 35 | 36 | 37 | 38 | ;****************** 39 | ; DATA 40 | ;****************** 41 | 42 | 43 | ;we draw to a private pixel buffer 44 | equ XORBUF,0x02005000 45 | 46 | equ RED_LEAD 4 47 | 48 | bytesperscanline: 49 | dd 0 50 | 51 | ;reserve space for our blue palette 52 | BluePalette: 53 | db0 800 54 | 55 | 56 | 57 | ;****************** 58 | ; CODe 59 | ;****************** 60 | 61 | 62 | ..start 63 | 64 | ;save video LFB width 65 | mov eax,22 ;getbpsl 66 | sysenter 67 | mov [bytesperscanline],eax 68 | 69 | 70 | ;we are not sure how to initialize the loop counter 71 | ;Galileo ran in dos which must have done the init 72 | ;a value of 63 works giving a palette of about 170 bytes then zeros 73 | ;a value of 255 works almost filling the palette 74 | ;at some value > 256 we get a GPF 75 | ;a value of 255 gives a palette with the first 16 entries light blue 76 | ;entry 17 is white and the rest gets progressively darker 77 | ;in shades of blue until we have black 78 | ;a value of 235 gets rid of the first 16 light blue entries 79 | ;changing this value gives more or less color in the palette 80 | ;which affects the look of the background texture 81 | mov ecx,235 82 | 83 | 84 | ;build a custom palette with shades of blue 85 | mov edi,BluePalette 86 | cld 87 | 88 | 89 | 90 | BuildPalette: 91 | 92 | mov eax,ecx 93 | 94 | 95 | ;set red 96 | shr eax,2 97 | add eax,RED_LEAD 98 | ;the DOS code used OUT to ports to directly change the DAC 99 | stosb 100 | 101 | 102 | ;set green 103 | sub eax,RED_LEAD 104 | stosb 105 | 106 | 107 | ;set blue 108 | cmp cl,63 109 | ;cmc, compliment the carry flag 110 | db 0xf5 111 | ;salc, set al from carry, early undocument instruction 112 | db 0xd6 113 | ;or al,cl 114 | db 0x8,0xc8 115 | stosb 116 | 117 | 118 | loop BuildPalette 119 | 120 | 121 | 122 | 123 | 124 | ;now change our DAC palette 125 | mov eax,17 ;setpalette 126 | mov ebx,BluePalette 127 | mov edx,0xf5fe ;kernel text red on white 128 | sysenter 129 | 130 | ;Done building the palette 131 | 132 | 133 | 134 | 135 | 136 | 137 | ;background Texture 138 | ;this is the classic XOR grid texture 139 | ;we just do (X xor Y) where X & Y are the coordinates of each pixel 140 | ;******************************************************************* 141 | 142 | cld 143 | 144 | ;get address of buffer into edi 145 | mov edi,XORBUF 146 | 147 | ;init eax=row, ebx=col 148 | mov eax,0 149 | mov ebx,0 150 | 151 | 152 | 153 | doXOR: 154 | 155 | ;save row 156 | push eax 157 | 158 | ;sadly ttasm doesnt support this combo yet 159 | ;better get crackin Tom 160 | ;xor eax,ebx 161 | db 0x31, 0xd8 162 | 163 | ;set pixel al->edi, edi++ 164 | stosb 165 | 166 | ;restore row 167 | pop eax 168 | 169 | ;move toward end of row 170 | inc ebx 171 | 172 | ;make sure we dont exceed width of scanline 173 | cmp ebx,[bytesperscanline] 174 | 175 | jb doXOR 176 | ;done with one row 177 | 178 | 179 | ;reset col to 0 180 | mov ebx,0 181 | 182 | ;move down to the next row 183 | inc eax 184 | 185 | ;make sure we havent exceeded 599 rows 186 | cmp eax,599 187 | 188 | jb doXOR 189 | 190 | ;done with XOR grid texture 191 | 192 | 193 | 194 | 195 | done: 196 | 197 | ;make it show up 198 | mov eax,23 ;swapuserbuf 199 | mov esi,XORBUF 200 | sysenter 201 | 202 | ;pause for user to gaze at the beauty :) 203 | getc 204 | 205 | 206 | ;restore our standard palette 207 | ;if you dont, tatOS will become unuseable 208 | ;because the 0xff entry for background color in the palette is black 209 | ;and so is the text 210 | mov eax,17 ;setpalette 211 | mov ebx,0 212 | sysenter 213 | 214 | 215 | exit ;return to tedit 216 | 217 | 218 | ;****************END XOR ******************************** 219 | 220 | 221 | 222 | -------------------------------------------------------------------------------- /apps/dir: -------------------------------------------------------------------------------- 1 | May 2012 2 | This file is depreciated because tatos now has support for the FAT16 filesystem 3 | on your flash drive. But I still have this old flash drive with this stuff on it 4 | and who knows some day I might need it. Its like all that old stuff in your 5 | basement that you think you need and never touch. 6 | 7 | ***************************************************************** 8 | tatOS FILE DIRECTORY 9 | Tom Timmermann 10 | 11 | Describes whats stored on my SimpleTech Bonzai blue pen drive. 12 | (1) block = 512 bytes 13 | 14 | Jan 2010 15 | 16 | saved to my pendrive LBA=480,000 17 | **************************************************************** 18 | 19 | 20 | 21 | ************************************************************ 22 | name: LBAstart/qtyblocks DateStarted 23 | ************************************************************ 24 | 25 | FreeSpace 0-4999 26 | 27 | ScreenDump 5000/940 28 | 29 | AsmTest 10,000/1 Dec 08 30 | 31 | ******************************************************* 32 | ShowBMP.s 10,100/3 Dec 08 33 | mom.bmp 10,110/1800 34 | ******************************************************* 35 | 36 | HellowWorld.s 12,000/1 Dec 08 37 | 38 | RandRect.s 12,010/3 Dec 08 39 | 40 | TextFader.s 12,020/2 Dec 08 41 | 42 | Starfield.s 12,040/9 Dec 08 43 | 44 | Mandel.s 12,060/6 Dec 08 45 | 46 | ******************************************************* 47 | TicTacToe 48 | X.bits 12,100/6 49 | O.bits 12,110/6 50 | rory.bits 12,120/55 51 | smily.bits 12,200/20 52 | main.s 12,250/35 Dec 09 53 | ******************************************************* 54 | 55 | Littlebits.s 12,400/16 Dec 09 56 | 57 | ******************************************************* 58 | Minesweeper: 59 | Each bitmap is 16x16 60 | one.bits 13,000/1 61 | two.bits 13,005/1 62 | three.bits 13,010/1 63 | four.bits 13,015/1 64 | five.bits 13,020/1 65 | flag.bits 13,025/1 66 | bomb.bits 13,030/1 67 | redbomb.bits 13,035/1 68 | raised.bits 13,040/1 69 | blank.bits 13,045/1 70 | main.s 13,100/30 Jan 09 71 | *********************************************************** 72 | 73 | Graphic Primative Demo 74 | Demonstrates lines,circles,arcs... 75 | 76 | graphic.s 14,000/10 Mar 09 77 | 78 | *********************************************************** 79 | 80 | Fire.s 15,000/14 Apr 09 81 | 82 | *********************************************************** 83 | 84 | Plasma.s 15,100/9 Apr 09 85 | 86 | *********************************************************** 87 | 88 | Butterfly.s 15,500/12 Apr 09 89 | 90 | *********************************************************** 91 | 92 | Fern.s 16,100/12 Apr 09 93 | 94 | *********************************************************** 95 | 96 | ViewFlashDesc.s 17,000/10 Dec 09 97 | 98 | *********************************************************** 99 | 100 | Factorial.s 17,100/4 May 09 101 | 102 | *********************************************************** 103 | 104 | Tree.s 17,300/7 May 09 105 | 106 | *********************************************************** 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | Code Snippets 400000/26 116 | Winstarter Code 400100/3 117 | Ascii Table 420000/2 118 | Memory Map 420010/16 119 | tomsasmtips 420100/61 120 | 121 | 122 | ThisDirectory 480000/7 123 | 124 | 125 | ********************TheEnd*********************************** 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /apps/grafx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tatimmer/tatOS/7c153b2987a1e7439e853d1b41fa4d1cc3dce6d5/apps/grafx.png -------------------------------------------------------------------------------- /apps/palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tatimmer/tatOS/7c153b2987a1e7439e853d1b41fa4d1cc3dce6d5/apps/palette.png -------------------------------------------------------------------------------- /boot/irq0.s: -------------------------------------------------------------------------------- 1 | ;tatOS/boot/irq0.s 2 | 3 | 4 | ;PIT: Programmable Interrupt Timer 5 | ;referred to as the 8253 controller 6 | ;or system timer 7 | 8 | ;this is the interrupt service routine for the pit 9 | ;this code gets called about 1000 times per second 10 | 11 | ;see picpitinit.s which initializes the pit 12 | ;and sets the firing rate 13 | 14 | usb_keyboard_counter dd 0 15 | 16 | 17 | 18 | irq0: 19 | 20 | cli ;disable interrupts 21 | pushad 22 | 23 | ;I tried some code in here to push ds,es,fs,gs 24 | ;then assign 0x10 kernel data selector values 25 | ;then just after end of interrupt we pop ds,es,fs,gs 26 | ;but doing this is not reqd 27 | ;see discussion in tlibentry.s 28 | 29 | ;count up to 0xffffffff then 30 | ;roll over to 0 and continue 31 | ;this global is used by all functions in /tlib/time.s 32 | add dword [PITCOUNTER],1 33 | 34 | 35 | 36 | ;usb keyboard 37 | ;*************** 38 | ;call the usb keyboard interrupt procedure at regular intervals 39 | ;if not done at regular intervals the transfer descriptor will suffer 40 | ;a time out error and the keyboard will become unusable 41 | 42 | mov eax,[usb_keyboard_counter] 43 | add eax,1 44 | 45 | ;the usb keyboard polling frequency is set in tatOSinit 46 | ;and modified by /usb/interkeybd.s 47 | ;a value of 30 is good for general typing 48 | ;a value of 100 is good for showing the keyboard report 49 | cmp eax,[USBKEYBDPOLLFREQ] 50 | ja .1 51 | 52 | ;counter is <= USBKEYBDPOLLFREQ 53 | mov [usb_keyboard_counter],eax 54 | jmp .done 55 | 56 | .1: ;counter is > USBKEYBDPOLLFREQ 57 | mov dword [usb_keyboard_counter],0 58 | 59 | ;call usbkeyboardinterrupt() which is defined in /usb/interkeybd.s 60 | ;we are using the /tlib/tlib.s indirect call table 61 | call [0x10088] 62 | 63 | 64 | .done: 65 | ;end of interrupt 66 | mov al,0x20 67 | out 0x20,al 68 | popad 69 | sti ;enable interrupts 70 | iret 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /boot/irq11.s: -------------------------------------------------------------------------------- 1 | ;tatOS/boot/irq11.s 2 | 3 | 4 | ;this is the irq11 interrupt handler 5 | ;this file is included in boot2.s 6 | 7 | ;Feb 2016 8 | ;I decided to dabble into getting interrupts working for uhci keyboard interrupt 9 | ;tranfers but after a few failed attemps Im going to set this aside for now 10 | 11 | irq11str1 db 'this is irq11',0 12 | 13 | irq11: 14 | 15 | cli 16 | pushad 17 | push ds 18 | push es 19 | push fs 20 | push gs 21 | 22 | ;set kernel data selectors 23 | mov ax,0x10 24 | mov ds,ax 25 | mov es,ax 26 | mov fs,ax 27 | mov gs,ax 28 | 29 | 30 | STDCALL irq11str1,[DUMPSTR] 31 | 32 | 33 | 34 | ;EndOfInterrupt:any pic2 interrupt must also acknowledge pic1 35 | mov al,0x20 36 | out 0x20,al ;eoi for pic1 37 | out 0xa0,al ;eoi for pic2 38 | 39 | pop gs 40 | pop fs 41 | pop es 42 | pop ds 43 | popad 44 | sti 45 | iret 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /boot/mouse.s: -------------------------------------------------------------------------------- 1 | ;tatOS/boot/mouse.s 2 | 3 | ;this file is depreciated in favor of the usb mouse driver 4 | 5 | ;Oct 2009 6 | ;in the process of creating a usb mouse driver 7 | ;and trying to use shared code with the ps2 & usb mouse 8 | ;Ive come up with the following scheme 9 | ;both drivers will write the 4 mouse bytes starting at 0x550 10 | ;representing the mouse response (button,dX,dY,dZ) 11 | ;thats all the drivers will do 12 | 13 | ;this is the irq12 ps2 mouse driver 14 | ;this file is included in boot2.s 15 | ;this code may/maynot work for a mouse with a usb mouse 16 | ;and a usb2ps2 adapter, I have had mixed success. 17 | ;I suggest you buy a pure ps/2 mouse (6pin round connector) 18 | 19 | ;this isr is based on the fact that the bytes come 20 | ;from the mouse 1 per interrupt 21 | ;you may see some code elsewhere (on the net) 22 | ;that attempts to read all 4 bytes 23 | ;from the keyboard controller on 1 interrupt 24 | ;this actually works on some hdwre 25 | ;and it unfortunately works on Bochs 26 | ;but on other hdwre it will not work (mouse bounces around) 27 | ;the driver from Sanik (osdev) 28 | ;and a doc from cas.mcmaster.ca/~se3f03 29 | ;suggests you read 1 byte per interrupt 30 | ;local 31 | _mousepacketID db 0 ;0,1,2,3 = 4 byte packet 32 | ;*********************************************************** 33 | 34 | 35 | irq12: 36 | 37 | cli ;disable hdwre interrupts (can still get exception) 38 | pushad 39 | 40 | 41 | ;read mouse packet byte 42 | ;one byte per interrupt 43 | call wait_read 44 | in al,0x60 45 | 46 | 47 | ;store first byte of packet 48 | ;bit0=left button 49 | ;bit1=right button 50 | ;bit2=middle button 51 | ;bit3=always set 52 | ;bit4=X sign 53 | ;bit5=Y sign 54 | ;bit6=X overflow 55 | ;bit7=Y overflow 56 | cmp byte [_mousepacketID],0 57 | jnz .1 58 | inc byte [_mousepacketID] 59 | mov [0x550],al 60 | jmp .eoi 61 | 62 | .1: 63 | ;store second byte of packet (delta X) 64 | cmp byte [_mousepacketID],1 65 | jnz .2 66 | inc byte [_mousepacketID] 67 | mov [0x551],al 68 | jmp .eoi 69 | 70 | .2: 71 | ;store third byte of packet (delta Y) 72 | cmp byte [_mousepacketID],2 73 | jnz .3 74 | inc byte [_mousepacketID] 75 | mov [0x552],al 76 | jmp .eoi 77 | 78 | .3: 79 | ;store fourth byte of packet (delta Z) 80 | mov byte [_mousepacketID],0 81 | mov [0x553],al 82 | 83 | 84 | 85 | .eoi: 86 | 87 | ;eoi-end of interrupt signal for pic2 88 | mov al,0x20 89 | out 0xa0,al ;eoi for pic2 90 | out 0x20,al ;eoi for pic1 91 | 92 | 93 | popad 94 | sti ;enable interrupts 95 | iret 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /boot/picpitinit.s: -------------------------------------------------------------------------------- 1 | ;tatOS/boot/picpitinit.s 2 | 3 | ;this file is included in boot2.s 4 | 5 | ;init the PIC and PIT 6 | 7 | 8 | 9 | ;********************************** 10 | ; PIC 11 | ;programmable interrupt controller 12 | ;here we enable/disable 13 | ;which hdwre interrupts we want 14 | ;also we remap the hdwre interrupts 15 | ;so they dont interfere 16 | ;which some software interrupts 17 | ;pic1=irq0-irq7, master, port 0x20 18 | ;pic2=irq8-irq15, slave, port 0xa0 19 | ;to idt 32-47 20 | ;********************************** 21 | 22 | jmp picstart 23 | 24 | 25 | picpause: 26 | mov ecx,0xff 27 | .1: 28 | loop .1 29 | ret 30 | 31 | 32 | picstart: 33 | ;ICW1 (initilization command word 1) 34 | mov al,0x11 35 | out 0x20,al ;pic1 36 | call picpause 37 | out 0xa0,al ;pic2 38 | call picpause 39 | 40 | ;ICW2 41 | mov al,0x20 ;0x20=32=starting hdwre interrupt for pic1 42 | out 0x21,al 43 | call picpause 44 | mov al,0x28 ;0x28=40=starting hdwre interrupt for pic2 45 | out 0xa1,al 46 | call picpause 47 | 48 | ;ICW3 49 | mov al,4 50 | out 0x21,al 51 | call picpause 52 | mov al,2 53 | out 0xa1,al 54 | call picpause 55 | 56 | ;ICW4 57 | mov al,1 58 | out 0x21,al 59 | call picpause 60 | out 0xa1,al 61 | call picpause 62 | 63 | 64 | ;****************************** 65 | ;pic1 66 | ;****************************** 67 | 68 | ;OCW1 (operation control word 1) 69 | ;a bit of 0 means to enable 70 | ;a bit of 1 means to disable/maskoff 71 | 72 | ;irq0=bit0 = pit system timer 73 | ;irq1=bit1 = ps2 keyboard 74 | ;irq2=bit2 = redirect to pic2 75 | ;irq3=bit3 = serial port 76 | ;irq4=bit4 = serial port 77 | ;irq5=bit5 = sound card 78 | ;irq6=bit6 = floppydisc controller 79 | ;irq7=bit7 = parallel port 80 | 81 | ;note: usb controller initialization needs the pit for sleep() 82 | 83 | ;as of May 2016 we are only using the usb keyboard 84 | ;still we need to enable ps2 keyboard (irq1) 85 | ;because bios uses this to enable our usb keyboard on start up 86 | ;until we take control 87 | 88 | mov al,11111000b ;enable pit, ps2 keyboard, pic2 89 | ;mov al,11111010b ;enable pit, pic2 90 | ;mov al,11111100b ;enable pit and ps2 keyboard 91 | ;mov al,11111011b ;enable pic2 92 | ;mov al,11111101b ;enable ps2 keyboard 93 | ;mov al,11111111b ;enable nothing 94 | 95 | out 0x21,al 96 | call picpause 97 | 98 | 99 | ;****************************** 100 | ;pic2 101 | ;****************************** 102 | 103 | ;irq8 =bit0 = real time clock 104 | ;irq9 =bit1 = irq2 redirected 105 | ;irq10=bit2 = reserved 106 | ;irq11=bit3 = usb controller 107 | ;irq12=bit4 = ps/2 mouse 108 | ;irq13=bit5 = math co-processor 109 | ;irq14=bit6 = hard disc drive 110 | ;irq15=bit7 = reserved 111 | 112 | ;mov al,0 ;enable everything 113 | mov al,11101111b ;enable ps2mouse 114 | ;mov al,11100111b ;enable usb + ps2mouse 115 | ;mov al,11111111b ;enable nothing 116 | 117 | out 0xa1,al 118 | call picpause 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | ;***************************************************************** 127 | ;Initialize the Programmable Interrupt Timer 128 | ;set how many interrupts/sec we get from the PIT 129 | ;we use channel 0 here 130 | ;hits/second = 1193182 hz / divisor 131 | ;2^16=65536 is the max divisor you can use (bios uses this) 132 | ;using 65536 gives the lowest 18.2065 hits/second 133 | ;supposedly data bytes of 0 are same as 65536 134 | 135 | ;WARNING !!!!! 136 | ;/tlib/sleep uses the PITCOUNTER value 137 | ;to pause procedural code execution 138 | ;our sleep function expects the PITCOUNTER 139 | ;to increment once every millisecond (fast firing rate) 140 | ;if you reprogram the pit to change the firing rate 141 | ;then you will affect how long sleep is sleeping 142 | ;the usb controller & port reset are also dependent on sleep 143 | ;***************************************************************** 144 | 145 | ;square wave, lsb then msb, channel=0=irq0 146 | mov al,110110b 147 | out 0x43,al ;command 148 | 149 | 150 | ;slow firing rate 151 | ;******************* 152 | ;set the the slowest firing rate possible 153 | ;0=65536 divisor which gives 18 hits/seconds 154 | ;mov al,0 155 | ;out 0x40,al ;data: low byte hits/sec 156 | ;out 0x40,al ;data: hi byte hits/sec 157 | 158 | 159 | ;medium firing rate 160 | ;********************* 161 | ;1193182/11930 ~= 100 hits/second 162 | ;11930 = 0x2e90 163 | ;mov al,0x9a ;low data byte 164 | ;out 0x40,al 165 | ;mov al,0x2e ;hi data byte 166 | ;out 0x40,al 167 | 168 | 169 | ;fast firing rate 170 | ;****************** 171 | ;1193182/1193 ~= 1000 hits/second 172 | ;1193 = 0x04a9 173 | mov al,0xa9 ;low data byte 174 | out 0x40,al 175 | mov al,0x04 ;hi data byte 176 | out 0x40,al 177 | 178 | 179 | 180 | 181 | ;***************************** 182 | ;initialize some values 183 | ;***************************** 184 | 185 | ;interrupt bitmask 186 | mov dword [0x50c],0 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /build.s: -------------------------------------------------------------------------------- 1 | ;tatOS/build.s 2 | ;June 2013 3 | 4 | ;tatOS is assembled with NASM on Debian Linux 5 | ;cat /proc/version reports Linux version 2.6.26-2-686 (Debian 2.6.26-17) 6 | ;nasm -v report NASM version 2.03.01 compiled on Jun 18 2008 7 | 8 | ;all this file does is combine boot1+boot2+tlib = tatOS.img 9 | 10 | ;boot1 is exactly 1 sector = 512 bytes long 11 | ;org = 0x7c00 as usual 12 | incbin "boot/boot1" 13 | 14 | ;boot1 loads boot2 to org = 0x600 15 | ;boot2 loads tlib 16 | incbin "boot/boot2" 17 | 18 | ;the org of tlib is 0x10000 19 | ;all of tlib is included in tlib.s 20 | incbin "tlib/tlib" 21 | 22 | 23 | ;for making boot floppy or boot pen drive 24 | ;comment out this times directive 25 | ;for making bootCD we need to pad out img file to a full floppy 26 | ;times 1474560 - ($-$$) db 0 27 | 28 | 29 | -------------------------------------------------------------------------------- /doc/2do: -------------------------------------------------------------------------------- 1 | tatOS 2do - Dec 2015 2 | 3 | A list of things I want to add to tatOS. Not in any order, as the spirit moves me. 4 | 5 | 6 | USB DRIVER:: 7 | - rewrite usb driver code to handle failed TD's on flash drive init 8 | * without having to reinit controller 9 | * quicker 10 | * without having to reboot sometimes 11 | - why does the mouse occasionally freeze ? (usbcheckmouse fail to queue up ???) 12 | - driver for usb keyboard 13 | - driver for usb 3.0 xHCI (someday when we get hdwre) 14 | 15 | 16 | FAT filesystem & Filemanager: 17 | - support for partitions 18 | - the '.' and '..' entries should have ENTER key capability 19 | - support for subdirectories within subdirectories 20 | 21 | 22 | APPS: 23 | - tcadd: split into multiple source files, 24 | add circle, arc, text, dimension, dxf/step 25 | - asteroids, puzzle, solitaire, tatsnow, pong 26 | - draw gear tooth involute profile, 2d glxgears in rotation 27 | - 3d flat shading demo 28 | - Littlebits: 29 | *ability to edit large BTS images whos grid will not fit on the screen 30 | *set current color from the image grid 31 | *move a collection of pixels in the grid 32 | - a paint program :line/circle/arc... 33 | 34 | 35 | TLIB: 36 | - function filltriangle or fillpolygon 37 | - function thickline 38 | - function to mesh a polygon area with triangles 39 | - function to draw a graph of data points with legend, labels... 40 | - function to scale up bitmaps 41 | - function to draw a table with text or bitmap in the cells 42 | - function arc3p (finish what you started) 43 | - expand calc for fpu capability 44 | - medium cut algorithm for determining optimum color palette from 24bit DIB image 45 | - display "power of two" as a font character using byte sequence 0xc2 0xb2 like vim 46 | - add a scaleable and filled font like TimesNewRoman 47 | - simple html viewer 48 | - get rid of all indirect tlib.s function calls except what /boot needs 49 | - rewrite xxd to display up to 250 blocks 50 | - rewrite xxd to display the exact file size (no trailing zeros on last line) 51 | - support for UTF-8 52 | - support for higher graphics resolution: 16 bpp or 24bpp or 32bpp 53 | - add find/search to viewtxt to quickly jump to addresses in the assembled code 54 | - all the graphic controls need to save YORIENT, set YORIENT=1 then restore on exit 55 | - palette manager ability to display rgb component of any color box 56 | - palette manager ability to set stock background color 38,34,27 57 | - function dumpst0 which includes a string tag like dumpeax 58 | 59 | 60 | TEDIT: 61 | - multiple document interface 62 | - replace text 63 | - correct a problem in CaretNextLink for lines > 80char 64 | - ability to read off pen drive as ascii hex bytes, edit and save back 65 | - ability to move the carot vertically at current position not at the end of line 66 | - hyperlink/bookmark to quickly jump to spots in the source code 67 | 68 | 69 | TTASM: 70 | - fix dq error 71 | - assemble multiple source files into object files then into 1 big exe 72 | - assemble itself, then assemble tatOS (self hosting) 73 | - expand memory addressing [reg1 + reg2] 74 | - eliminate the need to set all memory addresses to 0 on the 1st pass 75 | - equ should print error message if dword numerical value is missing 76 | - need "and dword [memory],1 77 | - need BT or TEST for bit testing 78 | 79 | 80 | BOOT: 81 | - implement UEFI boot (dont have any hardware for this yet) 82 | - make the code to load tatOS more flexible as tlib grows 83 | 84 | 85 | -------------------------------------------------------------------------------- /doc/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | tatOS is copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016 3 | Tom Timmermann Janesville WI USA 4 | 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, 8 | are permitted provided that the following conditions are met: 9 | 10 | a.. Redistributions of SOURCE must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | 13 | b.. Redistributions in BINARY form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation and/or 15 | other materials provided with the distribution. 16 | 17 | c.. My name may not be used to endorse or promote products derived from this 18 | software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 25 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 26 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 28 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /doc/asmDOS: -------------------------------------------------------------------------------- 1 | ;asmDOS 2 | ;basic starter code for a DOS com file 3 | ;a simple flat binary that can be run in DOSBOX 4 | ;useful for looking at old asm DOS code 5 | 6 | ;make sure org=100h 7 | ;e.g. nasm -f bin main.s -o main.com 8 | 9 | ;run this program in DOSBOX within Virtual PC 10 | ;mount c c:\ 11 | ;c: 12 | 13 | 14 | ;this program just paints the upper 20% of the screen with pink pixels 15 | 16 | 17 | bits 16 18 | org 0x100 19 | 20 | ;set video modeX: 320x200, 256 color 21 | ;the video linear frame buffer starts at A000:0000 22 | mov ax,0x13 23 | int 10h 24 | 25 | mov ax,0xa000 ;video segment for mode 13h 26 | mov es,ax 27 | mov di,0 ;start of video offset 28 | mov al,12 ;color 29 | cld 30 | mov cx,15000 31 | rep stosb ;set pixels 32 | 33 | 34 | ;wait for keypress to review graphics 35 | mov ah,0 36 | int 16h 37 | 38 | ;return to text mode, 80x25, 16 color 39 | mov ax,3 40 | int 10h 41 | 42 | ret 43 | 44 | 45 | -------------------------------------------------------------------------------- /doc/asmLinux: -------------------------------------------------------------------------------- 1 | asmLinus 2 | Tips and starter code for Linux assembly 3 | 4 | tatos is developed on Linux using nasm. 5 | 6 | Assembly Language Debugger 7 | Copyright (C) 2000-2004 Patrick Alken 8 | http://ald.sourceforge.net 9 | 10 | I use ALD on linux for testing assembly code. Highly recommended. 11 | Allows you to step thru the code 1 line at a time and watch the registers. 12 | 13 | 14 | to invoke 15 | within ald to see list of interactive commands 16 | single step next instruction, skip over "call sub" 17 | single step, jump into "call sub" 18 | show 10 bytes starting address 'buf' 19 | show 10 bytes starting address in esi 20 | show 10 bytes starting this hex address 21 | set breakpoint at this instruction address 22 | disassemble get address etc for breakpoint 23 | run to breakpoint 24 | display registers & flags, n&s also give you this 25 | to see the fpu registers 26 | see also ~/.aldrc resource file 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | And here is the starter code I use with ald on Linux: 35 | Put this code in a file main.s 36 | 37 | 38 | 39 | bits 32 40 | 41 | global _start 42 | 43 | section .text 44 | _start: 45 | nop ;starting point for ald debugger 46 | 47 | ;insert your asm code here 48 | 49 | quit: 50 | PUTC 0xa ;newline 51 | mov eax,1 ;SYS_EXIT 52 | mov ebx,0 ;return 0 53 | int 80h ;call Linux 54 | 55 | 56 | section .bss 57 | random resb 10 58 | mac_char resb 1 59 | 60 | 61 | section .data 62 | buf times 10 db 0 63 | stor dd 0 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | And here are a couple of handy macros for 72 | i/o on a Linux terminal: 73 | 74 | ;************************************************** 75 | ;putc 76 | ;put char 77 | ;arg1=ascii character 78 | ;to print a newline use: PUTC 0xa 79 | ;************************************************** 80 | %macro PUTC 1 81 | pushad 82 | mov byte [mac_char], %1 83 | mov eax,SYS_WRITE 84 | mov ebx,STDOUT 85 | mov ecx,mac_char 86 | mov edx,1 87 | int 80h 88 | popad 89 | %endmacro 90 | 91 | 92 | ;************************************************** 93 | ;puts 94 | ;put string 95 | ;arg1=address of string 96 | ;arg2=num of char in string 97 | ;return value for put & get is in eax 98 | ;num bytes sucessfully read/write 99 | ;if string contains 0xa this is end of string 100 | ;then eax is less than arg2 101 | ;************************************************** 102 | %macro PUTS 2 103 | pushad 104 | mov eax,SYS_WRITE 105 | mov ebx,STDOUT 106 | mov ecx,%1 ;pointer to memory 107 | mov edx,%2 ;num bytes 108 | int 80h 109 | popad 110 | %endmacro 111 | 112 | 113 | ;******************************************* 114 | ;putebx 115 | ;display contents of ebx as hex 116 | ;the heart of this code comes from 117 | ;John Eckerdahls web site 118 | ;******************************************* 119 | %macro PUTEBX 0 120 | push eax 121 | push ecx 122 | mov ecx,8 123 | rol ebx,4 124 | 125 | %%.1: 126 | mov eax,ebx 127 | 128 | ;mask off all but low nibble 129 | and eax,0x0000000f 130 | 131 | ;convert al to ascii 132 | ;code from John Eckerdahl 133 | cmp al,10 134 | sbb al,69h 135 | das 136 | 137 | PUTC al 138 | 139 | rol ebx,4 140 | loop %%.1 141 | 142 | pop ecx 143 | pop eax 144 | %endmacro 145 | 146 | 147 | 148 | Some defines for Linux i/o 149 | %define STDIN 0 150 | %define STDOUT 1 151 | %define SYS_READ 3 152 | %define SYS_WRITE 4 153 | %define SYS_EXIT 1 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | And here is the makefile for your Linux asm starter code: 164 | 165 | # makefile for a simple nasm project 166 | # requires NASM and gnu ld to build the elf executable 167 | go: main.o 168 | ld -g -o go main.o 169 | 170 | main.o : main.s tatos.inc 171 | nasm -f elf main.s 172 | 173 | 174 | 175 | 176 | 177 | For more help see Dr. Paul Carters website. 178 | Download and study his "PC Assembly Language" and the code. 179 | See especially his file "asm_io.asm" 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /doc/asmWin: -------------------------------------------------------------------------------- 1 | asmWin 2 | 3 | In case you find yourself on a windows machine 4 | and have the itch to develope some asm code. 5 | Put code in a file main.s 6 | Need nasm and gcc/mingw installed 7 | 8 | Makefile would look something like this: 9 | 10 | #To produce main.obj 11 | nasm -f win32 main.s 12 | 13 | #To create windows executable and link with Clib 14 | gcc -o main.exe main.obj 15 | 16 | 17 | ;********************************************************** 18 | 19 | bits 32 20 | 21 | global _WinMain@16 22 | extern _scanf, _printf, _getchar, _putchar, _fputs, _puts 23 | 24 | section .text 25 | _WinMain@16: 26 | 27 | 28 | ;print contents of eax 29 | mov eax,123456 30 | push eax 31 | push format 32 | call _printf ;call C function 33 | pop ecx ;in C the caller does cleanup 34 | pop ecx 35 | 36 | ;print some dots 37 | push '.' 38 | call _putchar 39 | pop ecx 40 | push '.' 41 | call _putchar 42 | pop ecx 43 | 44 | ;print newline 45 | push 0xa 46 | call _putchar 47 | pop ecx 48 | 49 | ;print string 50 | ;make sure DF is clear or else results are unpredictable 51 | cld 52 | push string1 53 | call _puts 54 | pop ecx 55 | 56 | 57 | ;print double precision floating point qword 58 | push dword [dbl+4] 59 | push dword [dbl] 60 | push formatF 61 | call _printf 62 | pop ecx 63 | pop ecx 64 | pop ecx 65 | 66 | 67 | ;print contents of eax plus a string 68 | ;e.g. "1234...Hello World !" 69 | ;note the address of format string is pushed last 70 | ;the address of args within format are pushed right->left 71 | mov eax,1234 72 | push string1 73 | push eax 74 | push format3 75 | call _printf 76 | pop ecx 77 | pop ecx 78 | pop ecx 79 | 80 | 81 | ret 82 | 83 | 84 | 85 | section .data 86 | string1 db "Hello World !",0 87 | format db "%d",0 88 | formatF db "%.10g",0 89 | format3 db "%d...%s",0 90 | dbl dq 345.6789 91 | 92 | 93 | 94 | 95 | 96 | Check out Ollydebug. 97 | 98 | 99 | -------------------------------------------------------------------------------- /doc/auto-local: -------------------------------------------------------------------------------- 1 | auto-local variables 2 | ********************** 3 | 4 | Assembly programmers can use the stack to create space 5 | for what C calls auto or local variables. These variables live 6 | for the duration of the procedure and when the procedure returns 7 | these variables are no longer available. 8 | 9 | 10 | ;example to call a procedure requiring 3 args on the stack 11 | push dword A 12 | push dword B 13 | push dword C 14 | call myproc 15 | 16 | 17 | 18 | 19 | ;this subroutine requires 3 args on the stack 20 | 21 | ;input: 22 | ;push dword A [ebp+16] 23 | ;push dword B [ebp+12] 24 | ;push dword C [ebp+8] 25 | 26 | myproc: 27 | 28 | push ebp 29 | mov ebp,esp 30 | 31 | ;create space on stack for 4 local dwords = 16 bytes 32 | ;these locals can be accessed at [ebp-4], [ebp-8], [ebp-12], [ebp-16] 33 | ;see note [1] below 34 | sub esp,16 35 | 36 | ;other code 37 | 38 | .done: 39 | mov esp,ebp ;deallocate locals 40 | pop ebp 41 | retn 12 42 | 43 | 44 | 45 | 46 | note [1]: 47 | now the stack looks like this after [sub esp,16]: 48 | esp points here---> 49 | ebp-16 ;local dword storage 50 | ebp-12 ;local dword storage 51 | ebp-8 ;local dword storage 52 | ebp-4 ;local dword storage 53 | ebp ;value of ebp when "push"ed 54 | ebp+4 ;return address placed on stack by "call" 55 | ebp+8 ;dword C 56 | ebp+12 ;dword B 57 | ebp+16 ;dword A 58 | 59 | 60 | -------------------------------------------------------------------------------- /doc/bochsrc: -------------------------------------------------------------------------------- 1 | # configuration file generated by Bochs 2 | config_interface: textconfig 3 | display_library: sdl 4 | megs: 60 5 | romimage: file="/usr/share/bochs/BIOS-bochs-latest" 6 | vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest" 7 | boot: floppy 8 | floppy_bootsig_check: disabled=0 9 | floppya: 1_44=/home/tom/projects/tatOS/tatOS.img, status=inserted 10 | # no floppya 11 | # no floppyb 12 | ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 13 | ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 14 | ata2: enabled=0 15 | ata3: enabled=0 16 | parport1: enabled=1, file="" 17 | parport2: enabled=0 18 | com1: enabled=1, mode=null, dev="" 19 | com2: enabled=0 20 | com3: enabled=0 21 | com4: enabled=0 22 | usb1: enabled=0 23 | i440fxsupport: enabled=1 24 | vga_update_interval: 40000 25 | vga: extension=vbe 26 | cpu: count=1, ips=2000000, reset_on_triple_fault=1 27 | text_snapshot_check: enabled=0 28 | private_colormap: enabled=0 29 | clock: sync=none, time0=local 30 | # no cmosimage 31 | ne2k: enabled=0 32 | pnic: enabled=0 33 | sb16: enabled=0 34 | # no loader 35 | log: bochs.out 36 | logprefix: %t%e%d 37 | debugger_log: - 38 | panic: action=ask 39 | error: action=report 40 | info: action=report 41 | #debug: action=report 42 | debug: action=ignore 43 | pass: action=fatal 44 | keyboard_type: mf 45 | keyboard_serial_delay: 250 46 | keyboard_paste_delay: 1000 47 | keyboard_mapping: enabled=0, map= 48 | user_shortcut: keys=none 49 | mouse: enabled=0, type=ps2 50 | -------------------------------------------------------------------------------- /doc/chs: -------------------------------------------------------------------------------- 1 | IBM P/C CHS CYlinder Head Sector Addressing notes 2 | 3 | This info is useful for designing bootloaders which need the IBM p/c compatible 4 | bios to load sectors from disc. This bios uses cylinder-head-sector addressing. 5 | 6 | 7 | Sector Head Cylinder 8 | ********** ************* ********** 9 | 10 | encoding qty bits 6 8 10 11 | 12 | address start 1 0 0 13 | 14 | address end 0x3f=63 0xfe=254 [1] 0x3ff=1023 15 | 16 | max qty 63 255 1024 17 | 18 | 19 | [1] BIOS compatible with early MSDOS will only allow head address 20 | up to 0xfe 21 | 22 | 512 byte/sector * 63 sector/track * 255 heads * 1024 cylinders 23 | = 8 gig limit 24 | 25 | EIDE, ATA-2, ECHS schemes have extended the limit 26 | see extended int 13h functions 27 | 28 | DOS & old Windows partitions must start/end on a cylinder boundry 29 | 30 | 31 | -------------------------------------------------------------------------------- /doc/dd: -------------------------------------------------------------------------------- 1 | ********** 2 | DD 3 | ********** 4 | 5 | DD is a very powerful program on linux and you should get comfortable with it because it is your link to the outside world with tatos. 6 | 7 | 8 | 9 | DD and tatos.img 10 | ******************* 11 | 12 | To copy your tatos.img file to a floppy disc starting at the first sector of the disc. 13 | 14 | Floppy drive built into desktop computer: 15 | 16 | dd if=tatos.img of=/dev/fd0 17 | 18 | External floppy drive that plugs into a usb port: 19 | 20 | dd if=tatos.img of=/dev/sda 21 | 22 | Note that Linux labels your usb ports like sda, sdb, sdc, sdd, sde, sdf ... 23 | If I plug my flash drive into the front of my e-machines its /dev/sdf 24 | 25 | 26 | 27 | 28 | DD and Pen Drive 29 | ****************** 30 | 31 | Note as of Sept 2011 tatOS now supports the FAT16 formatted flash drive, but tatOS also provides a "dd" utility similar to Linux if you want to do direct read/write copy. 32 | 33 | tatos reads and writes to your pen drive with direct access by LBA logical block number and qty of blocks. Your pen drive can be divided up logically into a series of 512 byte blocks and tatos can read/write to any one of these blocks. See the functions READ10 and WRITE10 in tlib. tatos does not know anything about a file system. It assumes data is stored on your pen drive as a series of sequential bytes. tatos WRITE10 function places the bytes all together in 1 chunk. It does not spread them out in differanct places. A "file" is just a collection of bytes with an "LBAstart" and a "qtyblocks" designation. You are responsible to make sure there is enough available space to put the data so WRITE10 does not overwrite other data. SPREAD OUT YOUR DATA !!!! 34 | 35 | Therefore you should purchase a seperate pen drive for use with tatos because any filesystem will be destroyed (most pen drives come pre-formatted with FAT file system). No matter because pen drives are cheep, and we can communicate with Linux using the program "dd". 36 | 37 | 38 | To copy from Linux -> pen drive: 39 | 40 | dd if=filename of=/dev/sda seek=123 41 | 42 | The seek value is the LBAstart on your pen drive. 43 | 44 | 45 | To copy from pen drive -> Linux: 46 | 47 | dd if=/dev/sda of=filename skip=456 count=78 48 | 49 | The skip value is the LBAstart and count is the number of 512 byte blocks. 50 | 51 | 52 | After a transfer from your tatos pen drive to linux or vicaversa, you will have to open the file and delete some spurious bytes found at the end. This is because tatos and Linux use differant methods to detect "end of file". tatos uses a zero byte to terminate ascii text. 53 | 54 | See "man dd" on Linux for more info. 55 | 56 | 57 | -------------------------------------------------------------------------------- /doc/disasm: -------------------------------------------------------------------------------- 1 | disasm 2 | 3 | ndisasm is a utility that comes with nasm. It only works on flat binary files. 4 | 5 | Disassembling the binary files is useful when you have an error 6 | and want to know where the program stopped. The bochslog will give you among other 7 | things the value of EIP when the program quit. 8 | 9 | 10 | to disassemble boot1.s: 11 | ndisasm -b 16 -o 0x7c00 boot1 > out 12 | 13 | 14 | to disassemble boot2.s: 15 | this only applies to the 16 bit code at the beginning 16 | ndisasm -b 16 -o 0x600 boot2 > out 17 | 18 | 19 | to disassemble application.s: 20 | ndisasm -b 32 -o 0x1200 application > out 21 | 22 | 23 | to disassemble a DOS .com file: 24 | ndisasm -b 16 -o 0x100 mycomfile.com > out 25 | 26 | 27 | See "man ndisasm" for more info. 28 | 29 | 30 | -------------------------------------------------------------------------------- /doc/faith: -------------------------------------------------------------------------------- 1 | I am not ashamed of the gospel of Christ 2 | for it is the power of God 3 | to the salvation of every one who believes it. 4 | 5 | Paul 6 | 7 | ***************************************************** 8 | 9 | Jesus thy blood and righteousness 10 | my beauty are, my glorious dress 11 | midst flaming worlds in these arrayed 12 | with joy shall I lift up my head. 13 | 14 | Bold shall I stand in that great day 15 | for who aught to my charge shall lay 16 | fully thru these absolved I am 17 | from sin and fear, from guilt and shame. 18 | 19 | Ludwig von Zinzendorf 1739 20 | 21 | ***************************************************** 22 | -------------------------------------------------------------------------------- /doc/fpu: -------------------------------------------------------------------------------- 1 | FPU 2 | 3 | I have found fpu (floating point programming) to be most challenging. 4 | I wish they had designed these registers to operate like the general purpose 5 | registers, but alas such is not the case. 6 | 7 | tatOS functions that use the fpu will in general read input values as 64 bit qwords 8 | (double precision floating point) from memory and write qword results back to memory, 9 | leaving all the fpu registers free, although some functions will return a value in st0. 10 | 11 | It is most important with fpu programming to maintain a "balanced" fpu stack so every "load" is somewhere followed by a "fpupop" or "ffree" otherwise bad things will happen. 12 | 13 | To get an ascii string representation of whats in the first fpu register, look at st02str.s, dumpst0 and putst0. 14 | 15 | There are (8) 80 bit floating point registers numbered 0-7 (st0->st7) 16 | 17 | You will find many references on the web and older books on assembly programming that 18 | rely entirely on fixed point math which scales an integer up usually by a power of 2 19 | then later uses a right shift to scale the result back down, all in the name of speed. 20 | I find the fpu to be plenty fast for my needs. 21 | 22 | See the ttasm souce code and tlib for what tatOS supports in fpu operations. 23 | math.s, some apps like butterfly, fern & tcad, plus tlib functions like: 24 | offset, rotate, chamfer, fillet... all use the fpu. 25 | 26 | 27 | -------------------------------------------------------------------------------- /doc/makebootcd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # a Linux script for making a single track bootCD 3 | # using a CD-R or CD-RW disc 4 | # be sure you have a full 1474560 byte img file first ! 5 | 6 | # March 2016 - this script has not been used for a very long time 7 | # I boot tatOS from flash drive now and occasionally fall back to floppy 8 | # this script is moved to /docs 9 | 10 | 11 | #make new file.iso from the img file 12 | #-b option is for El Torito bootcd 13 | mkisofs -b ddusb.img -R -o file.iso /home/tom/projects/ddusb/ddusb.img 14 | 15 | 16 | #if CD-RW, first you must erase the disc 17 | #my drive does not accept blank=track 18 | #my drive will accept blank=all but its a 15 minute operation 19 | #blank=fast takes about 30 seconds 20 | sudo cdrecord -v blank=fast speed=8 dev=/dev/hdd 21 | 22 | 23 | #burn cd 24 | sudo cdrecord -v -tao speed=8 dev=/dev/hdd -data file.iso 25 | 26 | 27 | #remove the file.iso 28 | rm file.iso 29 | 30 | 31 | -------------------------------------------------------------------------------- /doc/mrm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # As an OS developer on Linux, I find it necessary to turn off hot plugging 4 | # and automounting of devices. Instead I use this script to mount when needed 5 | 6 | # script: mrm 7 | # Mount removable media 8 | # author: Tom Timmermann 9 | # rev Jan 2010 10 | # requires the Debian package "pmount" 11 | # without pmount you have to be root to mount pen drive or cdrom filesystem 12 | # in order to run "mrm" from any directory 13 | # execute the following from the commandline: 14 | # export FPATH=~/scripts 15 | # comment out entries in /etc/fstab to avoid conflict 16 | 17 | 18 | echo 19 | echo What do you want to do ? 20 | echo 1 = mount flash drive like floppy....sda 21 | echo 2 = un-mount flash drive like floppy 22 | echo 3 = mount floppy 23 | echo 4 = un-mount floppy 24 | echo 5 = mount data cd 25 | echo 6 = un-mount data cd 26 | echo 7 = mount flash drive like hard drive....sda1 27 | echo 8 = un-mount flash drive like hard drive 28 | read option 29 | 30 | echo Dont forget to UNmount when you are done !!! 31 | 32 | 33 | # mount pen drive 34 | # if pendrive is partitioned like a hard drive then: 35 | # * use /dev/sda1 36 | # * a partition table appears at offset 0x1be in the first sector 37 | # * the partition table defines offset to MBR 38 | # if pendrive is partitioned like a floppy then: 39 | # * use /dev/sda 40 | # * bootsector will not contain a partition table 41 | # * MBR starts immediately in first sector 42 | # dd and xxd may be used to copy sectors off the pendrive and examine 43 | # or just use trial and error along with dmesg 44 | 45 | if [ $option = "1" ] 46 | then 47 | echo mounting /dev/sda to /media/pendrive 48 | pmount --read-write --exec --sync --type vfat /dev/sda pendrive 49 | #nautilus /media/pendrive 50 | fi 51 | 52 | 53 | # un-mount pendrive 54 | if [ $option = "2" ] 55 | then 56 | pumount /dev/sda 57 | echo showing mounted file systems: 58 | mount 59 | fi 60 | 61 | 62 | 63 | 64 | 65 | # mount floppy 66 | # the floppy is formatted with the vfat filesystem and no partition information 67 | if [ $option = "3" ] 68 | then 69 | echo mounting /dev/fd0 to /media/floppy 70 | pmount --read-write --exec --sync --type vfat /dev/fd0 floppy 71 | #nautilus /media/floppy 72 | fi 73 | 74 | 75 | # un-mount floppy 76 | if [ $option = "4" ] 77 | then 78 | pumount /dev/fd0 79 | echo showing mounted file systems: 80 | mount 81 | fi 82 | 83 | 84 | # mount data cd 85 | if [ $option = "5" ] 86 | then 87 | echo mounting /dev/hdc to /media/cdrom 88 | pmount --read-only --exec --type iso9660 /dev/hdc cdrom 89 | #nautilus /media/cdrom 90 | fi 91 | 92 | 93 | # un-mount data cd 94 | if [ $option = "6" ] 95 | then 96 | pumount /dev/hdc 97 | echo showing mounted file systems: 98 | mount 99 | fi 100 | 101 | 102 | # mount pen drive with partition table formatted like a hard drive 103 | if [ $option = "7" ] 104 | then 105 | echo mounting /dev/sda to /media/pendrive 106 | pmount --read-write --exec --sync --type vfat /dev/sda1 pendrive 107 | #nautilus /media/pendrive 108 | fi 109 | 110 | 111 | # un-mount pendrive 112 | if [ $option = "8" ] 113 | then 114 | pumount /dev/sda1 115 | echo showing mounted file systems: 116 | mount 117 | fi 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /doc/optimization: -------------------------------------------------------------------------------- 1 | Optimization 2 | May 2009 3 | 4 | Every assembly language programmer should learn as much as possible 5 | about this topic. 6 | 7 | Download and study the Intel Pentium "Optimization" manuals. 8 | There are pdf's freely available on the web. 9 | These manuals also give the instruction timings. 10 | 11 | See also Agner Fogs "Optimizing Subroutines in Assembly Language". 12 | 13 | Topics for further study: 14 | 15 | branch prediction and elimination 16 | partial register or read/write stalls 17 | data alignment, location 18 | avoiding and unrolling loops 19 | instruction pairing 20 | counting clocks, latency & throughput, measuring performance 21 | problematic instructions 22 | out of order execution 23 | dependency chains 24 | code size vs speed 25 | 26 | -------------------------------------------------------------------------------- /doc/privilege: -------------------------------------------------------------------------------- 1 | The CPL or current priviledge level is determined by bits 0,1 of the 2 | segment selector currently in CS 3 | To tell the processor we are running at a differant privilege level 4 | we just load a new segment selector from the gdt 5 | and or bits1:0 to either 0 for kernel or 3 for user 6 | mov ebx,cs will put the current code segment into ebx 7 | for tatOS 0x08 is kernel code selector with DPL=0 8 | 0x1b will be user code with DPL=3 9 | 10 | The IOPL or i/o privilege level is usually always 0 in tatOS. 11 | this can be verified by examining bits 12,13 of eflags 12 | IOPL of 3 does not give access to the in/out port instructions. 13 | -------------------------------------------------------------------------------- /doc/resources: -------------------------------------------------------------------------------- 1 | tatOS-Resources 2 | 3 | 4 | 5 | The following books, articles and source code have been helpful to me in learning 6 | assembly language programming and developing the tatOS operating system. 7 | 8 | Nasm Manual (I suggest to print out the entire pdf-excellent reference) 9 | "PC Assembly Language", Dr. Paul Carter (print out this pdf) 10 | "Assembly Language Step by Step", Jeff Duntemann 11 | "Grapics Programming Black Book", Michael Abrash 12 | 13 | Keith Kanios, DynatOS source, dynatos.sourceforge.net 14 | Linux-.01 source code from kernel.org 15 | Visopsys source by Andy Mclaughlin 16 | MenuetOS 32bit source 17 | Christoffer Bubach, 2003, BOSOS version 02 and 04 18 | Rdos operating system 19 | 20 | osdev.org/osfaq2/ numerous helpful articles/discussions 21 | "PIC", osdev.org/wiki 22 | "PIT", osdev.org/osfaq2 23 | 24 | Brans Kernel Development tuts from osdever.net 25 | Gregor Brunmar tutorials from osdever.net 26 | Christopher Giese pmode tuts 27 | 28 | prodebug/sourceforge.net/pmtut.html 29 | 30 | Intel manuals 1,2,3 on programming the Pentium 31 | Vol 1 - Basic Architecture 32 | Vol 2 - Instructions 33 | Vol 3 - System Programming 34 | 35 | "Writting your own Toy OS", Linux Gazette 36 | 37 | Ralph Browns Interrupt List 38 | bios interrupts from htl-steyr.ac.at/~morg/pcinfo/hardware/ 39 | 40 | Daniel Rowell Faulkner tut on reading floppies 41 | 42 | Wikipedia, Cylinder-Head-Sector 43 | 44 | "Intercepting And Processing Hardware Interrupts", delorie.com 45 | 46 | "Interfacing the PC: Using Interrupts", beyondlogic.org 47 | 48 | keyboard driver, geocities.com/dev_das_2k 49 | 50 | freespace.virgin.net/hugo.elias/graphics 51 | 52 | FPU floating point programming: "Simply FPU" by Raymond Filiatreault 53 | 54 | Ron Thomas, "Graphics Programming Using Assembly", copywrite 1998 55 | free download from his website 56 | 57 | 58 | 59 | 60 | ps/2 keyboard/mouse driver development: 61 | ******************************************** 62 | "The PS/2 Mouse Interface" by Adam Capweske 63 | "The AT keyboard controller" www.win.tue.nl/~aeb/linux/kbd 64 | driver code by Sanik from osdev.org 65 | driver code from menuetos 66 | "MouseInput" from OsFaqWiki 67 | mouse.cc from mattise os 68 | ps2mouse.c from mobius os 69 | driver code by Arkon 2003, ragestorm.net 70 | 71 | 72 | 73 | 74 | For USB UHCI/EHCI Universal Host Controller Driver Development: 75 | ***************************************************************** 76 | [1] "Universal Serial Bus Mass Storage Class Bulk Only Transport", 77 | rev 1.0 Sept 1999 Usb Implementors Forum 78 | 79 | [2] "Universal Serial Bus Specification", rev 1.1 1998 and rev 2.0, ch9 is most important 80 | 81 | [3] "USB Device Class Definition for Human Interface Device (HID) ver 1.11 82 | 83 | [4] "USB HID Usage Tables" ver 1.11 84 | 85 | [5] Intel "82371AB PCI-ISA Xcelerator (PIIX4)" Controller Manual and 86 | "Universal Host Controller Interface (UHCI) Design Guide" rev 1.1, 87 | these are your hardware manuals 88 | 89 | [6] "Working Draft American National Standard SCSI Block Commands (SBC-2)" 90 | Nov 2004 and the "SCSI Primary Commands (SPC-2)" 91 | 92 | [7] "PCI Bios Spec" rev2.1 93 | 94 | [8] "Intel 82801EB (ICH5) Enhanced Host Controller Interface (EHCI), 95 | Programmers Reference Manual", April 2003 96 | 97 | [9] "Enhanced Host Controller Specification for the Universal Seriel Bus", 98 | rev 1.0, March 2002, Intel 99 | 100 | [10] Datasheet, VT6212, Pci Usb 2.0 Controller, Dec 2005, Via Technologies 101 | I bought this pci addon card for $25 to give my old computer the EHCI controller 102 | 103 | [11] "Simplified EHCI Data Structures for the High-End ColdFire Family USB Modules" 104 | Freescale Semiconductor. Shows how to fill in a QH and TD. Very good reference 105 | 106 | 107 | 108 | "Usb Simply Buffered Device Enumeration" and 109 | "Usb Simply Buffered Mass Storage Class - Bulk Only Transport" 110 | 2007 Shakthi Kannan, actual bytes from usb transactions 111 | 112 | "USB Made Simple", web site with 7 part series. 113 | 114 | "SnoopyPro" software for windows to view some usb transaction data. 115 | 116 | LinuxBios usb_scsi_low.h 117 | 118 | Beyond Logic "Usb in a Nutshell" excellent website 119 | 120 | waste.org "PCI bus info and code from a programmers perspective" 121 | 122 | 123 | 124 | 125 | 126 | FAT16 Filesystem for Flash Drive 127 | ********************************** 128 | [1] "File Allocation Table" from Wikipedia 129 | 130 | [2] Use "dd" on Linux to copy the first sector off a new flash to memory 131 | and study the bytes, Use the Linux or Windows format utility to reformat your flash 132 | and study the bytes. 133 | 134 | [3] "Operating Systems, Filesystems, FATFS", by FlushedSector fs@proglang.cjb.net from Pierres Library 135 | 136 | [4] "FAT16 Structure Information", by Jack Dobiash 137 | 138 | [5] "Pierres field guide to partition table recovery", www.datarescue.com/laboratory/partition.htm 139 | 140 | [6] "Partition Table", osdev.org/wiki/Partition_Table 141 | 142 | [7] "FAT16 File System", from Maverick OS, www.maverick-os.dk/FileSystemFormats/FAT16_FileSystem... 143 | 144 | [8] "FAT under Linux", fat-1.html and fat-2.html, source unknown 145 | 146 | [9] "FAT: General Overview of On-Disk Format", Microsoft Hardware White Paper, fatgen103.pdf 147 | 148 | [10] "Volume & File Structure of Disk Cartridges for Information Interchange", Standard ECMA-107 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | Jan 2011 157 | Tom Timmermann 158 | tatOS 159 | -------------------------------------------------------------------------------- /doc/tedit-help: -------------------------------------------------------------------------------- 1 | README-tedit 2 | Dec 2015 3 | 4 | tedit is the text editor included with tatOS. 5 | It is assembled into tlib as executable code. 6 | 7 | tedit uses a double link list starting at 0x100000 8 | 1meg is reserved allowing for 750,000 max chars per file 9 | 10 | CUT/COPY/PASTE is same as windows CTRL+X, CTRL+C, CTRL+V 11 | selection is made with SHIFT down and moving arrow keys 12 | Ctrl+y yanks/copies a single word at the caret to CLIPBOARD 13 | 14 | scrolling is done with the arrow keys, PAGEUP, PAGEDN, HOME, END 15 | thru the manipulation of the "toplink" 16 | toplink is the address of the first char drawn at upper left 17 | 18 | Ctrl+f to enter a string to find/search 19 | Ctrl+n to find the next instance 20 | Ctrl+8 jumps to the next instance of word at caret, then Ctrl+n 21 | 22 | Goto is handled with Ctrl+g to jump to a line number 23 | 24 | there are several options to delete characters: 25 | Delete 1 character at the caret 26 | Ctrl+Delete delete 1 word 27 | Alt+Delete delete a large block of chars from starting charnum (prompt) to caret 28 | Shift+Arrows then Delete the selection 29 | 30 | by default tedit file->open appends data to the existing link list at the caret 31 | unless you press F7 to clear first. 32 | if your usb File->save fails you can reinit the controller and flash 33 | and return to your tedit memory block and repeat the save 34 | 35 | each tedit link is 12 bytes: 36 | byte char (this is the ascii keypress) 37 | byte select (1=selected, 0=not selected) 38 | word unused (added to keep dword alignment 39 | dword prev (address of prev char link) 40 | dword next (address of next char link) 41 | 42 | if ebp holds address of a link then: 43 | byte [ebp] = the ascii char 44 | byte [ebp+1] = selected or not 45 | dword [ebp+4] = address of previous link 46 | dword [ebp+8] = address of next link 47 | 48 | messagepointer 49 | to display a 0 terminated string along the bottom of the screen 50 | do mov dword [messagepointer],AddressofMyString 51 | on the next paint cycle your message will show up 52 | 53 | 54 | Navigation 55 | *********** 56 | The caret is a non blinking rectangle. Text is inserted left of 57 | the caret. Insert mode is permanent and always active. There is 58 | no overstrike mode. 59 | 60 | The caret can be moved around the screen with 61 | the usual keys and combinations. See the comments in the source. 62 | [up/dn/left/right, home/end, Ctrl+home, Ctrl+end, Ctrl+right, 63 | Ctrl+left, Ctrl+up, Ctrl+dn] 64 | 65 | 66 | Line Numbers 67 | ************* 68 | tatOS.config has a variable TEDITSHOWLINENUMBERS 69 | if this value is 1 then line numbers will be displayed in the left column 70 | with line numbers you are limited to 75 chars per line 71 | without line numbers you can have 80 chars per line 72 | tedit uses the font01 73 | 74 | 75 | 76 | Function Keys 77 | ************** 78 | The tedit menu is shown at the bottom of the screen 79 | 80 | F1 = Open file off tatOS formatted fat16 flash drive 81 | 82 | F2 = Save file to tatOS formatted fat16 flash drive 83 | 84 | F3 = Metrics: caretbyte/qtybytes, line/qtylines, caretascii. 85 | 86 | F4 = Run calculator 87 | 88 | F6 = Show Dump 89 | 90 | F7 = Clear screen 91 | 92 | F10 = Run code currently assembled to STARTOFEXE 93 | 94 | F11 = Assemble with ttasm 95 | Ctrl+F11 = Run tlink 96 | 97 | F12 = quit 98 | 99 | 100 | 101 | 102 | 103 | Undo 104 | ***** 105 | None. 106 | 107 | 108 | 109 | Mouse Support 110 | ************** 111 | None. 112 | 113 | 114 | 115 | Thats all folks ! 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /doc/tomslinuxmacros: -------------------------------------------------------------------------------- 1 | ;*************************************** 2 | ; tmacros.inc 3 | ; toms 32bit i386 assembly macros 4 | ; with some subroutines added in 5 | ; www.ticon.net/~tatimmer 6 | ; May 27, 2007 7 | ; for Nasm on Linux using int80 i/o 8 | ;*************************************** 9 | 10 | 11 | %define STDIN 0 12 | %define STDOUT 1 13 | %define SYS_READ 3 14 | %define SYS_WRITE 4 15 | %define SYS_EXIT 1 16 | 17 | 18 | 19 | ;****************** 20 | ;exit 21 | ;***************** 22 | %macro exit 0 23 | mov eax,SYS_EXIT 24 | mov ebx,0 ;return 0 25 | int 80h ;call linux 26 | %endmacro 27 | 28 | 29 | 30 | 31 | 32 | ;************************************************** 33 | ;putc 34 | ;put char 35 | ;arg1=ascii character 36 | 37 | ;to print a newline use: 38 | ; PUTC 0xa 39 | ;************************************************** 40 | 41 | %macro PUTC 1 42 | pushad 43 | mov byte [mac_char], %1 44 | mov eax,SYS_WRITE 45 | mov ebx,STDOUT 46 | mov ecx,mac_char 47 | mov edx,1 48 | int 80h 49 | popad 50 | %endmacro 51 | 52 | 53 | 54 | ;************************************************** 55 | ;puts 56 | ;put string 57 | ;arg1=address of string 58 | ;arg2=num of char in string 59 | ;return value for put & get is in eax 60 | ;num bytes sucessfully read/write 61 | ;if string contains 0xa this is end of string 62 | ;then eax is less than arg2 63 | ;************************************************** 64 | 65 | %macro PUTS 2 66 | pushad 67 | mov eax,SYS_WRITE 68 | mov ebx,STDOUT 69 | mov ecx,%1 ;pointer to memory 70 | mov edx,%2 ;num bytes 71 | int 80h 72 | popad 73 | %endmacro 74 | 75 | 76 | 77 | 78 | ;************************************************************* 79 | ;strlen 80 | ;esi=address of 0 terminated source string 81 | ;returns length of string in edx (not including 0 terminator) 82 | ;************************************************************* 83 | 84 | strlen: 85 | mov edx,0 86 | .count: 87 | cmp byte [esi],0 88 | jz .done 89 | inc edx 90 | inc esi 91 | jmp .count 92 | .done: 93 | ret 94 | 95 | 96 | ;******************************************* 97 | ;putebx 98 | ;display contents of ebx as hex 99 | ;the heart of this code comes from 100 | ;John Eckerdahls web site 101 | ;******************************************* 102 | 103 | %macro PUTEBX 0 104 | push eax 105 | push ecx 106 | mov ecx,8 107 | rol ebx,4 108 | 109 | %%.1: 110 | mov eax,ebx 111 | 112 | ;mask off all but low nibble 113 | and eax,0x0000000f 114 | 115 | ;convert al to ascii 116 | ;code from John Eckerdahl 117 | cmp al,10 118 | sbb al,69h 119 | das 120 | 121 | PUTC al 122 | 123 | rol ebx,4 124 | loop %%.1 125 | 126 | pop ecx 127 | pop eax 128 | %endmacro 129 | 130 | 131 | 132 | ;************************************************** 133 | ;gets 134 | ;gets keystrokes and store in buffer 135 | ;arg1=address of memory buffer 136 | ;arg2=size of memory buffer 137 | ;return= number of keystrokes in eax not including enter key 138 | ;by default linux left justifies 139 | ;and appends 0x0A which we overwrite with 0 140 | ;************************************************** 141 | 142 | %macro gets 2 143 | memset %1,0,8,b ;zero out the buffer 144 | 145 | ;now read 146 | mov eax,SYS_READ 147 | mov ebx,STDIN 148 | mov ecx,%1 ;pointer to memory to stor 149 | mov edx,%2 ;num bytes 150 | int 80h 151 | 152 | ;replace 0x0a with 0 153 | mov [%1+eax-1],byte 0 154 | dec eax 155 | %endmacro 156 | 157 | 158 | 159 | 160 | 161 | ;************************************** 162 | ; data used by macros in this file 163 | ; use mac_ prefix to avoid conflicts 164 | ;************************************** 165 | section .bss 166 | mac_char resb 1 167 | 168 | 169 | 170 | section .data 171 | mac_h db 'h' ;hex suffix 172 | mac_b db 'b' ;binary suffix 173 | 174 | -------------------------------------------------------------------------------- /doc/usbkeybd: -------------------------------------------------------------------------------- 1 | tatOS/doc/usbkeybd 2 | 3 | Feb 6, 2016 4 | 5 | The usb keyboard gives a multi byte report. 6 | The values given are all differant then ps2 keyboard scancodes 7 | 8 | Here is a table giving the keyboard report for various key combinations 9 | 10 | The keyboard used is identified as: 11 | "Gear Head" 12 | 107 Key Gear Head Keyboard 13 | Model No. KB2500U 14 | made in china 15 | 16 | I got this data by going thru the usb mouse init sequence with the usb keyboard 17 | Yes the tatOS usb mouse init sequence works just fine on the usb keyboard 18 | since they are both low speed usb 1.0 devices 19 | 20 | The keyboard report is max 8 bytes: "aa bb cc dd ee ff gg hh" 21 | 22 | with all keys up all the bytes are 00 00 00 00 00 00 00 00 23 | 24 | when a single key is pressed, most keys give a value in the 'cc' byte 25 | all the other bytes remain 00 26 | the CTRL, ALT, SHIFT keys give a value in the 'aa' byte, see below 27 | 28 | when you hold down 2 keys like 'a' then 'b' the 29 | first key pressed is the 'cc' byte, the 2nd key pressed is the 'dd' byte 30 | if you press 3 keys at once the third key pressed is the 'ee' byte 31 | the tatOS usb keyboard driver does not support holding down 3 keys other than 32 | CTRL+ALT+DEL and you can only hold down 2 keys like CTRL+ or SHIFT+ 33 | 34 | I have not found the 'bb' byte to give anything other than 00 35 | 36 | there are some multiple key combinations like 'rty' held down together that 37 | must cause an overflow and the keyboard report just shows 00 00 01 01 01 01 01 38 | 39 | the table below gives the report for a single key pressed 40 | along with which byte of the report is giving the value 41 | 42 | 43 | 44 | single key held down 45 | key report 46 | ******* ******* 47 | a cc=04 48 | b cc=05 49 | c cc=06 50 | d cc=07 51 | e cc=08 52 | f cc=09 53 | g cc=0a 54 | h cc=0b 55 | i cc=0c 56 | j cc=0d 57 | k cc=0e 58 | l cc=0f 59 | m cc=10 60 | n cc=11 61 | o cc=12 62 | p cc=13 63 | q cc=14 64 | r cc=15 65 | s cc=16 66 | t cc=17 67 | u cc=18 68 | v cc=19 69 | w cc=1a 70 | x cc=1b 71 | y cc=1c 72 | z cc=1d 73 | 1 cc=1e 74 | 2 cc=1f 75 | 3 cc=20 76 | 4 cc=21 77 | 5 cc=22 78 | 6 cc=23 79 | 7 cc=24 80 | 8 cc=25 81 | 9 cc=26 82 | 0 cc=27 83 | ENTER cc=28 84 | ESCAPE cc=29 85 | bkspace cc=2a 86 | TAB cc=2b 87 | SPACE cc=2c 88 | - dash cc=2d 89 | = equal cc=2e 90 | [ lbrace cc=2f 91 | ] rbrace cc=30 92 | \ bslash cc=31 93 | 94 | ; semico cc=33 95 | ' squote cc=34 96 | ` btick cc=35 97 | , comma cc=36 98 | . period cc=37 99 | / fslash cc=38 100 | 101 | F1 cc=3a 102 | F2 cc=3b 103 | F3 cc=3c 104 | F4 cc=3d 105 | F5 cc=3e 106 | F6 cc=3f 107 | F7 cc=40 108 | F8 cc=41 109 | F9 cc=42 110 | F10 cc=43 111 | F11 cc=44 112 | F12 cc=45 113 | prntscrn cc=46 114 | scrollock cc=47 115 | break cc=48 116 | insert cc=49 117 | home cc=4a 118 | pageup cc=4b 119 | delete cc=4c 120 | end cc=4d 121 | pagedn cc=4e 122 | rightarrow cc=4f 123 | leftarrow cc=50 124 | dnarrow cc=51 125 | uparrow cc=52 126 | numlock cc=53 127 | 128 | 129 | MENU aa=65 130 | LSHIFT aa=02 131 | RSHIFT aa=20 132 | LCTRL aa=01 133 | RCTRL aa=10 134 | LALT aa=04 135 | RALT aa=40 136 | LCTRL+LALT aa=05 137 | LWINDOW aa=08 138 | RWINDOW aa=80 139 | 140 | 141 | 142 | special key combinations: 143 | 144 | LCTRL+LALT+DEL = 05 00 4c 145 | 146 | the upper case 'A' = LSHIFT + a = 02 00 04 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | #tatOS Makefile 2 | #Sept 2009 3 | #this will assemble everything from scratch 4 | #just type "make" from the Linux commandline 5 | #if you only have nasm and not the gcc tools 6 | #just issue these commands manually to build the image file 7 | #or use a script 8 | #tatOS is built on a Linux PIII desktop with Debian Lenny installed 9 | #if you get an error:" TIMES value -8 is negative" or something like that 10 | #then edit tatOS.inc SIZEOFTLIB define to some bigger number 11 | 12 | build: 13 | 14 | #assemble boot1 15 | nasm -f bin boot/boot1.s 16 | 17 | #assemble boot2 18 | nasm -f bin boot/boot2.s 19 | 20 | #assemble tlib 21 | nasm -f bin tlib/tlib.s 22 | 23 | #tatOS.img=boot1+boot2+tlib 24 | nasm -f bin build.s -o tatOS.img 25 | 26 | #use
to make bootable floppy or flash 27 | 28 | 29 | clean: 30 | rm boot/boot1 boot/boot2 tlib/tlib 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /tatOS.config: -------------------------------------------------------------------------------- 1 | ;tatOS.config 2 | ;April 2016 3 | 4 | ;this file sets hardware & software dependent options for tatOS 5 | ;set these values and re-assemble 6 | ;see "makefile" for how to build tatos 7 | 8 | 9 | ;note: if you introduce a new USBCONTROLLERTYPE then you must edit a great 10 | ;many files in /usb including initdevices, initflash, initmouse, initkeyboard 11 | ;devicedesc, configdesc, read10, write10 etc etc etc 12 | 13 | 14 | ;define the usb controller type 15 | ;********************************** 16 | ;this controls what usb controller you will use 17 | ;and controls what options are presented to you in usbcentral 18 | ;all the driver code in /usb depends on the value of USBCONTROLLERTYPE 19 | ;on linux run lspci -v 20 | ;on windows see the device manager 21 | ;on tatOS from usbcentral run the usb controller pci bus scan to get 22 | ;your vendorID, deviceID, bus:dev:fun 23 | ;pcidatabase.com will translate the vendorID & deviceID for you 24 | ;download and study your chipset & usb controller data sheets 25 | 26 | ;UHCI with 2-ports on back ...............USBCONTROLLERTYPE == 0 27 | ;EHCI with UHCI companion controllers ....USBCONTROLLERTYPE == 1 28 | ;EHCI with integrated root hub ...........USBCONTROLLERTYPE == 2 29 | ;EHCI only no usb 1.0 support ............USBCONTROLLERTYPE == 3 30 | %define USBCONTROLLERTYPE 2 31 | 32 | 33 | 34 | 35 | ;define the bus:dev:fun for controller type == 0 UHCI 36 | ;********************************************************** 37 | ;my old test machine was built with just UHCI and 2 root ports 38 | ;flash drive, keyboard and mouse work with UHCI directly 39 | ;VendorID=8086h DeviceID=7112h 40 | %define UHCI_BUS 0 41 | %define UHCI_DEV 7 42 | %define UHCI_FUN 2 43 | 44 | 45 | 46 | 47 | ;define the bus:dev:fun for controller type == 1 EHCI w/UHCI companions 48 | ;************************************************************************* 49 | ;VIA vt6212 pci addon card VendorID=1106h, DeviceID=3104h 50 | ;EHCI usb controller w/ (2) UHCI companion controllers 51 | %define EHCI_WITH_COMPANION_BUS 0 52 | %define EHCI_WITH_COMPANION_DEV 0x10 53 | %define EHCI_WITH_COMPANION_FUN 2 54 | %define EHCI_COMPANION_UHCI_BUS_1 0 55 | %define EHCI_COMPANION_UHCI_DEV_1 0x10 56 | %define EHCI_COMPANION_UHCI_FUN_1 0 57 | %define EHCI_COMPANION_UHCI_BUS_2 0 58 | %define EHCI_COMPANION_UHCI_DEV_2 0x10 59 | %define EHCI_COMPANION_UHCI_FUN_2 1 60 | 61 | 62 | 63 | 64 | ;define the bus:dev:fun for controller type == 2 EHCI w/integrated root hub 65 | ;***************************************************************************** 66 | ;ACER laptop has 2 Intel (8086) EHCI controllers, each with integrated root hub 67 | ;root hub (rate matching hub) acts as transaction translator for low speed devices 68 | ;deviceID=1e2d has bus:dev:fun 00:1a:00 webcam, no external ports 69 | ;deviceID=1e26 has bus:dev:fun 00:1d:00 3 external usb ports 70 | 71 | ;Lenovo desktop M81 with Intel 6/c200 series chipset 72 | ;this has 2 ehci controllers, each with integrated root hub 73 | ;deviceID=1c2d has bus:dev:fun 00:1a:00 6 ports on back 74 | ;deviceID=1c26 has bus:dev:fun 00:1d:00 2 ports on front 75 | 76 | %define EHCI_WITH_ROOTHUB_BUS 0 77 | %define EHCI_WITH_ROOTHUB_DEV 0x1a 78 | %define EHCI_WITH_ROOTHUB_FUN 0 79 | 80 | 81 | 82 | 83 | ;define the bus:dev:fun for controller type == 3 EHCI only no usb 1.0 support 84 | ;******************************************************************************** 85 | ;this is ehci only no usb 1.0 support 86 | ;developed for my sons mac with vmware which emulates ehci (& ohci) 87 | %define EHCIONLY_BUS 0 88 | %define EHCIONLY_DEV 0xb 89 | %define EHCIONLY_FUN 0 90 | 91 | 92 | 93 | 94 | ;USB Mouse Report Button Index 95 | ;******************************** 96 | ;for manhattan mouse with 6 byte report having leading 01 byte use 01 97 | ;for Logitech or Microsoft Mouse with the normal 4 byte report use 00 98 | ;run usb mouse report demo from usbcentral 99 | %define MOUSERPRTBTNINDX 1 100 | 101 | 102 | 103 | 104 | ;VERBOSEDUMP 105 | ;*************** 106 | ;some driver code and tlib functions can provide extra output of whats going on 107 | ;ttasm symbol table lookup return values are available with this option 108 | ;ttasm dump messages on pass=1 are normally erased but can be shown with this option 109 | ;note: ttasm will fill up the dump during assembly of very large files 110 | ;to the point that output to the dump will be truncated if you select this option 111 | ;usb driver bitfields are available 112 | ;all verbose output is written as ascii strings to the dump 113 | ;1=provide verbose dump 114 | ;0=do not provide verbose dump 115 | %define VERBOSEDUMP 0 116 | 117 | 118 | 119 | ;TEDIT Options 120 | ;***************** 121 | ;to show line numbers in the left hand column use 1 else use 0 122 | %define TEDITSHOWLINENUMBERS 1 123 | 124 | 125 | -------------------------------------------------------------------------------- /tatOS.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tatimmer/tatOS/7c153b2987a1e7439e853d1b41fa4d1cc3dce6d5/tatOS.img -------------------------------------------------------------------------------- /tlib/README-tlib: -------------------------------------------------------------------------------- 1 | README-tlib 2 | 3 | tlib is a handful of functions accessible by the tatOS kernel and user apps in support of direct hardware access bootable image programming using assembly. There are graphical functions that draw to the screen like puts, line, circle, and fillrect; utility functions that just compute things like abs and strlen, and actual controls that respond to user input like viewtxt, comprompt, gets, menu, & pickoption. 4 | 5 | All files in tlib and all function entry points are listed in tlib.s 6 | If you add a new file to the /tlib directory then you must %include that file in tlib.s 7 | #defines for memory addresses and magic numbers are located in tatos.inc 8 | tatos.inc is used by /usb and /boot 9 | 10 | Args in Regs: 11 | Most tlib functions take arguments in registers, but a few take args on the stack using our own version of "stdcall". Someday we may introduce some rentrant/recursive functions which use the stack for args but not yet. Usually registers are preserved with push/pop except if a value is returned in a register, usually in eax. 12 | 13 | Graphics Mode: 14 | On boot the bios will initialize your graphics adapter/monitor to 800x600x8bpp color mode. This a 256 color palletized mode. All graphic functions are designed around this mode and no other mode is supported. See the end of boot2.s where we generate and set a palette and the background color. 15 | 16 | Colors: 17 | Since with 8bpp graphics all colors are just an index into the DAC palette so we use byte values from 0-0x3f(0-63) since DAC colors are 6 bit values. For the "standard" palette we have some defined names for colors in tatos.inc. I generally save edx for passing colors, dl then dh and if you need a third color shift it to the hiword of edx. 18 | 19 | Double Buffer: 20 | tlib is setup for double buffer and all tlib graphic functions draw to the back buffer. See tatos.inc where this is defined in memory. To get anything to show up on the screen you must call [SWAPBUF] at the end of your paint routine. This copies the back buffer to the vesa linear frame buffer. Apps are responsible for drawing their own mouse cursor. This is done right before SWAPBUF. You may "call [CROSSCURSOR] or make up your own cursor function using [PUTTRANSBITS]. 21 | 22 | Applications: 23 | Some tlib functions like viewtxt and gets may be considered applications because they have their own main loop and their own paint routine. A well behaved application with its own paint routine will observe the following: 24 | 25 | * there must be a main loop with non-blocking calls to 26 | checkc() or checkmouse() or checktime(). Apon detecting 27 | the ESCAPE key the routine returns to the calling function. 28 | At the end of the main loop call the local paint routine. 29 | 30 | * a well behaved paint routine will observe the following: 31 | 32 | - begin paint with call [BACKBUFCLEAR] 33 | if using the entire screen. 34 | 35 | -if you wish to preserve the background and draw overtop 36 | before entering paint call [BACKBUFSAVE] 37 | begin paint with call [BACKBUFPUT] 38 | 39 | -end the paint routine with call [SWAPBUF] 40 | this copies the backbuffer to the linear frame buffer 41 | nothing shows up until you call [SWAPBUF] 42 | 43 | 44 | See files in tatOS/apps for examples of how to use tlib functions. 45 | Happy coding ! 46 | 47 | 48 | Tom Timmermann 49 | May 2013 50 | 51 | 52 | -------------------------------------------------------------------------------- /tlib/arc.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/arc.s 2 | 3 | ;************************************************************ 4 | ;arc 5 | ;draws a circular arc 6 | 7 | ;input: 8 | ;ebp=Address of 32 byte ARC structure 9 | 10 | ;return: none 11 | 12 | 13 | ;32 byte ARC structure (8 dwords) 14 | ;******************************************* 15 | ;dword Xcenter [ebp] 16 | ;dword Ycenter [ebp+4] 17 | ;dword radius,pixels [ebp+8] 18 | ;dword angle_start,deg (0-359) [ebp+12] 19 | ;dword angle_end ,deg (0-359) [ebp+16] 20 | ;dword angle_inc [ebp+20] 21 | ;dword color index (0-0xff) [ebp+24] 22 | ;dword linetype [ebp+28] 23 | 24 | ;all the inputs are unsigned dwords 25 | ;the arc is drawn by computing x,y points along the arc 26 | ;at equal intervals of angle_inc and connecting the points 27 | ;with straight line segments. 28 | ;use angle_inc=5 deg for a smooth looking arc 29 | ;if you are doing fast scrolling use angle_inc=30 30 | 31 | ;warning! angle_end must be greater than angle_start 32 | ;and both must be in the range +0->+359. See function 33 | ;normalizedeg in polar.s 34 | 35 | ;if YORIENT=1 and angle_start=0 and angle_end=180 36 | ;this draws a smile (holds water) 37 | ;if YORIENT=-1 and angle_start=0 and angle_end=180 38 | ;this draws a hill or frown (doesnt hold water) 39 | ;************************************************************* 40 | 41 | arc: 42 | pushad 43 | 44 | ;get the radius 45 | mov ecx,[ebp+8] 46 | 47 | ;set the starting angle 48 | mov edx,[ebp+12] 49 | 50 | ;get x,y start of first line segment 51 | push ecx 52 | push edx 53 | call polar2rect 54 | ;returns ebx=x, eax=y 55 | ;we reserve esi and edi to store x,y for start point 56 | mov esi,ebx ;esi=x_start 57 | mov edi,eax ;edi=y_start 58 | add esi,[ebp] ;+xc 59 | add edi,[ebp+4] ;+yc 60 | 61 | ;increment angle for end point of first segment 62 | add edx,[ebp+20] 63 | 64 | .arc_drawing_loop: 65 | 66 | ;get x,y for the segment end point 67 | push ecx 68 | push edx 69 | call polar2rect 70 | add ebx,[ebp] ;+xc 71 | add eax,[ebp+4] ;+yc 72 | 73 | ;draw the line segment 74 | push dword [ebp+28] ;linetype 75 | push dword esi ;x1 76 | push dword edi ;y1 77 | push ebx ;x2 78 | push eax ;y2 79 | push dword [ebp+24] ;color 80 | call line 81 | 82 | ;save the end point as the start point 83 | mov esi,ebx 84 | mov edi,eax 85 | 86 | ;increment angle 87 | add edx,[ebp+20] 88 | 89 | ;are we past angle end ? 90 | cmp edx,[ebp+16] 91 | jb .arc_drawing_loop 92 | 93 | 94 | ;the last segment drawn is short 95 | push ecx 96 | mov edx,[ebp+16] ;ending angle 97 | push edx 98 | call polar2rect 99 | add ebx,[ebp] ;+xc 100 | add eax,[ebp+4] ;+yc 101 | 102 | 103 | ;draw the line segment 104 | push dword [ebp+28] ;linetype 105 | push dword esi 106 | push dword edi 107 | push ebx 108 | push eax 109 | push dword [ebp+24] 110 | call line 111 | 112 | .done: 113 | popad 114 | ret 115 | 116 | 117 | -------------------------------------------------------------------------------- /tlib/bcd2bin.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/bcd2bin.s 2 | 3 | ;convert a bcd byte to binary 4 | 5 | ;bcd is used in date.s 6 | ;the bios returns the month/day/year in bcd 7 | ;this routine originally written to convert mon/day/year bytes to binary bytes 8 | ;for usage in fat.s 9 | 10 | ;to convert a bcd to binary: 11 | ;the 0xf is just to mask off and isolate the nibble 12 | ;each nibble is multiplied by 0,10,100,1000 ... 13 | ;then just add them all up 14 | ;(LoNibble & 0xf) + (NextNibble>>4 & 0xf)*10 + (NextNibble>>8 & 0xf)*100 ... 15 | 16 | ;since bcd values can only be 0,1,2...8,9 17 | ;the largest bcd byte is 0x99 which can be converted to binary 0x63 18 | 19 | 20 | ;**************************************** 21 | ;bcd2bin 22 | ;convert a bcd byte to binary byte 23 | ;input: al=bcd value to convert 24 | ;return al=binary equivalent 25 | ;**************************************** 26 | 27 | bcd2bin: 28 | push ebx 29 | push ecx 30 | 31 | mov bl,al ;copy 32 | mov cl,al ;copy again 33 | and cl,0xf ;save the low nibble 34 | 35 | ;work with the hi nibble 36 | shr bl,4 ;shift hi nibble to low position 37 | and bl,0xf ;mask off all but the nibble 38 | mov al,10 39 | mul bl ;ax=10*hinibble 40 | 41 | add ax,cx ;ax=10*hinibble + lonibble 42 | and eax,0xff ;mask off all but al 43 | 44 | pop ecx 45 | pop ebx 46 | ret 47 | 48 | 49 | -------------------------------------------------------------------------------- /tlib/circle.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/circle.s 2 | 3 | 4 | ;************************************************ 5 | ;circle 6 | ;draws a bresenham circle 7 | ;the border is drawn solid 1 pixel wide 8 | ;the center may be filled or unfilled 9 | ;computes x,y of border pixel in the 2nd Octant (theta=45->90) 10 | ;remainder of circle border is by mirror image 11 | 12 | ;input 13 | ;push 1=filled, 0=unfilled [ebp+24] 14 | ;push xcenter [ebp+20] 15 | ;push ycenter [ebp+16] 16 | ;push radius [ebp+12] 17 | ;push ColorIndex 0-0xff [ebp+8] 18 | 19 | 20 | ;local variables 21 | circle_xmax dd 0 22 | circle_dx dd 0 ;x coordinate in 2nd Octant 23 | circle_dy dd 0 24 | circle_d dd 0 25 | Octant1 dd 0 ;stores address of pixel on border for scanline filling 26 | Octant2 dd 0 27 | Octant3 dd 0 28 | Octant4 dd 0 29 | Octant5 dd 0 30 | Octant6 dd 0 31 | Octant7 dd 0 32 | Octant8 dd 0 33 | ;************************************************ 34 | 35 | circle: 36 | 37 | push ebp 38 | mov ebp,esp 39 | pushad 40 | 41 | 42 | ;get address of center of circle 43 | push dword [ebp+20] ;x 44 | push dword [ebp+16] ;y 45 | call getpixadd 46 | mov esi,edi ;save 47 | 48 | 49 | ;compute xmax=radius/sqrt(2)=radius*1000/1414 (integer) 50 | ;this is qty pixels to move horizontal 51 | ;from theta=90 to theta=45 52 | mov ebx,[ebp+12] 53 | mov eax,1000 54 | mul ebx ;eax=radius*1000 55 | xor edx,edx 56 | mov ebx,1414 57 | div ebx ;eax=radius*1000/1414 58 | mov dword [circle_xmax],eax ;save 59 | 60 | 61 | 62 | ;init dx 63 | mov dword [circle_dx],0 64 | 65 | ;init dy to radius 66 | mov eax,[ebp+12] 67 | mov [circle_dy],eax 68 | 69 | ;init the "d" error term to -radius 70 | neg eax 71 | mov [circle_d],eax 72 | 73 | ;color in cl 74 | mov ecx,[ebp+8] 75 | 76 | 77 | 78 | .topofCircleLoop: 79 | 80 | ;compute error term d=2*dx-1 81 | mov eax,[circle_dx] 82 | shl eax,1 ;2*dx 83 | sub eax,1 ;2*dx-1 84 | add [circle_d],eax ;d+=2*dx-1 85 | 86 | 87 | ;check if error term is >=0 88 | cmp dword [circle_d],0 89 | jl .dontupdate 90 | ;adjust dy if necessary (move closer to center of circle) 91 | dec dword [circle_dy] ;y-- 92 | mov eax,[circle_dy] 93 | shl eax,1 ;2*dy 94 | sub [circle_d],eax ;d-=2*dy 95 | .dontupdate: 96 | 97 | 98 | 99 | ;precompute ebx=dx*[videobufferwidth] 100 | ;eax=width of pixel buffer 101 | mov eax,[videobufferwidth] 102 | mul dword [circle_dx] 103 | mov ebx,eax 104 | 105 | ;precompute eax=dy*[videobufferwidth] 106 | mov eax,[videobufferwidth] 107 | mul dword [circle_dy] 108 | 109 | 110 | 111 | ;set 8 pixels, one in each octant 112 | 113 | 114 | 115 | ;[1] set pixel in 1st Octant, theta=0->45 116 | ;edi-dx*[BPSL]+dy, (y,x) 117 | mov edi,esi 118 | sub edi,ebx 119 | add edi,[circle_dy] 120 | mov [Octant1],edi ;save for later circle fill 121 | mov byte [edi],cl 122 | 123 | ;[2] set pixel in 2nd Octant, theta=45->90 124 | ;edi-dy*[BPSL]+dx, (x,y) 125 | mov edi,esi 126 | sub edi,eax 127 | add edi,[circle_dx] 128 | mov [Octant2],edi 129 | mov byte [edi],cl 130 | 131 | ;[3] set pixel in 3rd Octant, theta=90->135 132 | ;edi-dy*[BPSL]-dx, (-x,y) 133 | mov edi,esi 134 | sub edi,eax 135 | sub edi,[circle_dx] 136 | mov [Octant3],edi 137 | mov byte [edi],cl 138 | 139 | ;[4] set pixel in 4th Octant, theta=135->180 140 | ;edi-dx*[BPSL]-dy, (-y,x) 141 | mov edi,esi 142 | sub edi,ebx 143 | sub edi,[circle_dy] 144 | mov [Octant4],edi 145 | mov byte [edi],cl 146 | 147 | ;[5] set pixel in 5th Octant, theta=180->225 148 | ;edi+dx*[BPSL]-dy, (-y,-x) 149 | mov edi,esi 150 | add edi,ebx 151 | sub edi,[circle_dy] 152 | mov [Octant5],edi 153 | mov byte [edi],cl 154 | 155 | ;[6] set pixel in 6th Octant, theta=225->270 156 | ;edi+dy*[BPSL]-dx, (-x,-y) 157 | mov edi,esi 158 | add edi,eax 159 | sub edi,[circle_dx] 160 | mov [Octant6],edi 161 | mov byte [edi],cl 162 | 163 | ;[7] set pixel in 7th Octant, theta=270->325 164 | ;edi+dy*[BPSL]+dx, (x,-y) 165 | mov edi,esi 166 | add edi,eax 167 | add edi,[circle_dx] 168 | mov [Octant7],edi 169 | mov byte [edi],cl 170 | 171 | ;[8] set pixel in 8th Octant, theta=325->360 172 | ;edi+dx*[BPSL]+dy, (y,-x) 173 | mov edi,esi 174 | add edi,ebx 175 | add edi,[circle_dy] 176 | mov [Octant8],edi 177 | mov byte [edi],cl 178 | 179 | 180 | 181 | 182 | ;set pixels in scanlines to fill the circle 183 | cmp dword [ebp+24],0 184 | jz .DoneCircleFill 185 | cld ;increment 186 | 187 | ;Octant[3]->Octant[2] 188 | mov eax,[ebp+8] ;color in al 189 | mov ecx,[Octant2] 190 | sub ecx,[Octant3] ;ecx is number of pixels in scanline to set 191 | mov edi,[Octant3] ;starting address 192 | rep stosb ;al->edi, edi++,ecx-- 193 | 194 | ;Octant[4]->Octant[1] 195 | mov eax,[ebp+8] 196 | mov ecx,[Octant1] 197 | sub ecx,[Octant4] 198 | mov edi,[Octant4] 199 | rep stosb 200 | 201 | ;Octant[5]->Octant[8] 202 | mov eax,[ebp+8] 203 | mov ecx,[Octant8] 204 | sub ecx,[Octant5] 205 | mov edi,[Octant5] 206 | rep stosb 207 | 208 | ;Octant[6]->Octant[7] 209 | mov eax,[ebp+8] 210 | mov ecx,[Octant7] 211 | sub ecx,[Octant6] 212 | mov edi,[Octant6] 213 | rep stosb 214 | 215 | ;must restore the color register for setting border pixels above 216 | mov ecx,[ebp+8] 217 | .DoneCircleFill: 218 | 219 | 220 | 221 | 222 | ;test 4 doneness 223 | mov eax,[circle_dx] 224 | cmp eax,[circle_xmax] 225 | jz .done 226 | inc dword [circle_dx] 227 | jmp .topofCircleLoop 228 | 229 | 230 | .done: 231 | popad 232 | pop ebp 233 | retn 20 234 | 235 | 236 | 237 | 238 | -------------------------------------------------------------------------------- /tlib/clipboard.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/clipboard.s 2 | 3 | 4 | ;userland code needs these functions to copy data to the 5 | ;clipboard and to obtain data from the clipboard 6 | ;the clipboard is 1meg of kernel memory starting at CLIPBOARD 7 | ;the first dword at CLIPBOARD is the qty of bytes 8 | ;the data starts at CLIPBOARD+4 9 | 10 | 11 | 12 | ;*************************************************** 13 | ;copytoclipboard 14 | ;copy data from userland to the clipboard 15 | ;the data must all fit within the clipboard 16 | ;input: 17 | ;push starting address of userland memory [ebp+12] 18 | ;push qty bytes to copy [ebp+8] 19 | ;return: CF is clear on success, set on error 20 | copystr1 db 'copy to clipboard',0 21 | ;************************************************** 22 | 23 | copytoclipboard: 24 | 25 | push ebp 26 | mov ebp,esp 27 | 28 | STDCALL copystr1,dumpstr 29 | 30 | ;test for valid starting address 31 | push dword [ebp+12] 32 | call ValidateUserAddress 33 | jc .done 34 | 35 | ;test for valid ending address 36 | mov eax,[ebp+12] 37 | add eax,[ebp+8] 38 | push eax 39 | call ValidateUserAddress 40 | jc .done 41 | 42 | 43 | ;write the qty of bytes 44 | mov eax,[ebp+8] 45 | mov [CLIPBOARD],eax 46 | 47 | 48 | ;copy the data from userland to clipboard 49 | cld 50 | mov esi,[ebp+12] 51 | lea edi,[CLIPBOARD+4] 52 | mov ecx,[ebp+8] 53 | rep movsb 54 | 55 | clc ;clear on success 56 | 57 | .done: 58 | pop ebp 59 | retn 8 60 | 61 | 62 | 63 | ;*************************************************** 64 | ;copyfromclipboard 65 | ;copy data from the clipboard to userland memory 66 | ;the qty of bytes to copy must already be stored 67 | ;at the first dword of CLIPBOARD 68 | 69 | ;userlands memory received an exact copy of 70 | ;what is in the clipboard so the first dword 71 | ;is qty bytes and then starts the data 72 | 73 | ;input: 74 | ;push destination address of userland memory [ebp+8] 75 | ;return: CF is clear on success, set on error 76 | 77 | copystr2 db 'copy from clipboard',0 78 | ;************************************************** 79 | 80 | copyfromclipboard: 81 | 82 | push ebp 83 | mov ebp,esp 84 | 85 | STDCALL copystr2,dumpstr 86 | 87 | ;test for valid starting address 88 | push dword [ebp+8] 89 | call ValidateUserAddress 90 | jc .done 91 | 92 | ;get the qty of bytes to copy from the clipboard 93 | mov ecx,[CLIPBOARD] 94 | 95 | ;test for valid ending address 96 | mov eax,[ebp+8] 97 | add eax,ecx 98 | push eax 99 | call ValidateUserAddress 100 | jc .done 101 | 102 | 103 | ;copy qty bytes to userland 104 | mov edi,[ebp+8] 105 | mov [edi],ecx 106 | 107 | ;copy data to userland 108 | cld 109 | lea esi,[CLIPBOARD+4] 110 | add edi,4 111 | ;ecx=qty bytes 112 | rep movsb 113 | 114 | clc ;clear on success 115 | 116 | .done: 117 | pop ebp 118 | retn 4 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /tlib/datetime.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/datetime.s 2 | 3 | ;**************************************************************** 4 | ;datetime 5 | ;generates an ascii string of the current date and time 6 | ;relies on bios int 1a,4 for date on startup 7 | ;gets values from RealTimeClock CMOS RAM Bank 0 for time 8 | ;assumes values returned by RTC are BCD 9 | 10 | ;input 11 | ;edi=address of destination buffer 12 | 13 | ;returns 14 | ;ascii string "mm/dd/yy hh:mm" 15 | 16 | ;assumes conversion from BCD to ascii is reqd for the time 17 | ;buffer must be at least 15 bytes long 18 | ;string will be 0 terminated 19 | 20 | ;to write a byte do "out 0x70,Addr" then "out 0x71,byte" 21 | ;to read a byte do "out 0x70,Addr" then "in al,0x71" 22 | 23 | ;to convert a bcd to binary: 24 | ;(LoNibble & 0xf) + (NextNibble>>4 & 0xf)*10 + (NextNibble>>8 & 0xf)*100 ... 25 | ;*************************************************************** 26 | 27 | datetime: 28 | push eax 29 | push ebx 30 | push edx 31 | 32 | 33 | ;month in BCD 34 | ;April will be al=0x04 35 | mov al,[0x510] 36 | mov edx,2 37 | call eax2hex 38 | 39 | mov byte [edi],'/' 40 | inc edi 41 | 42 | ;day in BCD 43 | ;the 11th day of the month will be al=0x11 44 | mov al,[0x511] 45 | mov edx,2 46 | call eax2hex 47 | 48 | mov byte [edi],'/' 49 | inc edi 50 | 51 | ;year in BCD 52 | ;for a year like 2010, al=0x10 53 | ;so the entire string will be "04/11/10" 54 | mov al,[0x512] 55 | mov edx,2 56 | call eax2hex 57 | 58 | mov byte [edi],SPACE 59 | inc edi 60 | 61 | 62 | 63 | ;TIME 64 | 65 | .1: mov al,0xa ;RTC register A 66 | out 0x70,al 67 | in al,0x71 68 | test al,0x80 ;is update in progress 69 | jne .1 70 | 71 | 72 | ;register B 73 | mov al,0xb 74 | out 0x70,al 75 | in al,0x71 76 | 77 | 78 | ;bit1 79 | ;bit=1,zf=0 = 24 hour mode 80 | ;bit=0,zf=1 = 12 hour mode 81 | ;test al,00000010b 82 | 83 | 84 | ;bit2 85 | ;if bit2=0,zf=1 we have BCD endcoding 86 | ;if bit2=1,zf=0 we have binary 87 | ;test al,00000100b 88 | ;for now we just assume BCD 89 | 90 | 91 | ;hours, Address=04 92 | mov al,0x04 93 | out 0x70,al 94 | in al,0x71 95 | 96 | movzx ebx,al 97 | shr ebx,4 98 | add ebx,0x30 99 | mov [edi],bl 100 | inc edi 101 | 102 | movzx ebx,al 103 | and ebx,0xf 104 | add ebx,0x30 105 | mov [edi],bl 106 | inc edi 107 | 108 | mov byte [edi],':' 109 | inc edi 110 | 111 | 112 | 113 | ;minutes, Address=02 114 | mov al,0x02 115 | out 0x70,al 116 | in al,0x71 117 | 118 | movzx ebx,al 119 | shr ebx,4 120 | add ebx,0x30 121 | mov [edi],bl 122 | inc edi 123 | 124 | movzx ebx,al 125 | and ebx,0xf 126 | add ebx,0x30 127 | mov [edi],bl 128 | inc edi 129 | 130 | ;0 terminate 131 | mov byte [edi],0 132 | 133 | ;seconds are at Address=00 (not supported) 134 | 135 | pop edx 136 | pop ebx 137 | pop eax 138 | ret 139 | 140 | 141 | -------------------------------------------------------------------------------- /tlib/dd.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/dd.s 2 | 3 | ;raw byte copy from memory to flash drive 4 | ;similar to "dd" on linux 5 | ;July 2012 moved copy from flash to memory to XXD 6 | ;this is a dangerous function now that we have FAT16 7 | ;I would not use this at all 8 | 9 | 10 | tatOSddstr1: 11 | db 'DD',NL 12 | db 'raw byte copy to your Flash Drive',NL 13 | db 'Warning ! This function does not respect your file system',NL 14 | db 'It will copy bytes to your flash drive wherever you want',NL 15 | db 'Including overwrite of your VBR, FAT and root directory',NL 16 | db 'DD requires an absolute memory address, LBAstart and qtybytes/blocks',NL 17 | db 'F1=Copy data from memory to Flash drive',NL 18 | db 'ESC=quit',0 19 | 20 | tatOSddstr3 db 'Load blocks off PenDrive to STARTOFEXE=0x2000000: LBAstart,qtyblocks',0 21 | tatOSddstr4 db 'Copy Binary Data to PenDrive: Address,QtyBytes,LBAstart',0 22 | tatOSddstr6 db 'LBAstart',0 23 | tatOSddstr7 db 'qty blocks',0 24 | 25 | _ddstor times 20 db 0 26 | 27 | 28 | ddShell: 29 | 30 | ;clear screen 31 | call backbufclear 32 | 33 | ;title message and instructions 34 | STDCALL FONT01,75,100,tatOSddstr1,0xefff,putsml 35 | 36 | call swapbuf 37 | 38 | ;wait for the user to press a function key 39 | call getc 40 | 41 | cmp al,F1 42 | jz .doF1 43 | 44 | ;any other keypress causes quit 45 | jmp .done 46 | 47 | .doF1: 48 | call ddMemory2Flash 49 | .done: 50 | ret 51 | 52 | 53 | 54 | 55 | 56 | 57 | ddMemory2Flash: 58 | 59 | ;prompt user to enter Address,QtyBytes,LBAstart 60 | STDCALL tatOSddstr4,COMPROMPTBUF,comprompt 61 | jnz .done 62 | 63 | ;extract the address of csv's to global memory 64 | push COMPROMPTBUF ;parent string 65 | push COMMA ;seperator 66 | push 3 ;max qty substrings 67 | push _ddstor ;storage for substring address 68 | call splitstr ;returns eax=qty substrings 69 | 70 | cmp eax,3 ;must find 3 substrings 71 | jnz near .error 72 | 73 | 74 | ;substr1 = Address 75 | mov esi,COMPROMPTBUF 76 | call str2eax 77 | jnz .done 78 | mov esi,eax ;esi=address 79 | 80 | ;substr2 = qtyblocks 81 | mov esi,[_ddstor] 82 | call str2eax ;eax=qtybytes user entered 83 | jnz .done 84 | call bytes2blocks 85 | mov ecx,eax ;ecx=qtyblocks 86 | 87 | ;substr3 = LBAstart 88 | mov esi,[_ddstor+4] 89 | call str2eax 90 | jnz .done 91 | 92 | ;copy to pen drive 93 | ;esi=memory address 94 | mov ebx,eax ;LBAstart 95 | ;ecx=qtyblocks 96 | call write10 97 | ;sets ZF on error, no check here 98 | 99 | .error: 100 | .done: 101 | ret 102 | 103 | 104 | -------------------------------------------------------------------------------- /tlib/flood.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/flood.s 2 | 3 | ;********************************************************* 4 | ;floodfill 5 | ;fill a randomly shaped area of pixels 6 | ;with one color 7 | 8 | ;input 9 | ;push starting address of bitmap [ebp+28] 10 | ;push Xseed [ebp+24] 11 | ;push Yseed [ebp+20] 12 | ;push bitmap width [ebp+16] 13 | ;push bitmap height [ebp+12] 14 | ;push color to set [ebp+8] 15 | 16 | ;this function uses the kernel stack 17 | ;we start with a "seed" value, any pixel in the middle to fill 18 | ;we save the color of the "seed" value 19 | ;and push its x,y coordinates on the stack 20 | ;then we enter the loop 21 | ;in the loop we pop off an x,y coordinate 22 | ;we color this pixel with the seed value color 23 | ;next wet examine the 4 neighboring pixels top,bot,left,right 24 | ;we push them on the stack if their color matches the seed 25 | ;continue at top of loop 26 | 27 | ;beware of stack corruption 28 | ;everything you put on the stack must be taken off 29 | 30 | ;beware of stack overflow 31 | ;available stack space as of Nov 2008 32 | ;= esp - (startofApplication + sizeofApplication) 33 | ;= 0x88888-(0x1a000+25600)= 0x68400 = 427k bytes 34 | ;each pixel requires 8 bytes so 53k pixels are allowed 35 | ;so we could fill a region of about 200x250 pixels max 36 | ;since push something on the stack decrements esp 37 | ;closer to our code, we will just limit esp to 0x33333 38 | ;to protect our code 39 | 40 | ;locals 41 | floodstacksize dd 0 42 | floodseedcolor db 0 43 | floodAddressBitmap dd 0 44 | ;******************************************************* 45 | 46 | floodfill: 47 | push ebp 48 | mov ebp,esp 49 | 50 | ;save for later 51 | mov eax,[ebp+28] 52 | mov [floodAddressBitmap],eax 53 | 54 | 55 | ;push our seed on the stack 56 | ;push X 57 | push dword [ebp+24] 58 | ;push Y 59 | push dword [ebp+20] 60 | ;inc floodstacksize 61 | inc dword [floodstacksize] 62 | 63 | 64 | ;save seed color 65 | mov ebx,[ebp+24] 66 | mov eax,[ebp+20] 67 | call getpixelcolor 68 | mov [floodseedcolor],dl 69 | 70 | 71 | floodmainloop: 72 | 73 | ;this is our exit point 74 | ;when there is no more data to pop off stack 75 | ;we quit 76 | cmp dword [floodstacksize],0 77 | jz near .done 78 | 79 | 80 | ;ebx and eax must be preserved thru this main loop !! 81 | 82 | 83 | ;pop Y 84 | pop eax 85 | ;pop X 86 | pop ebx 87 | ;dec qty pixels on stack 88 | dec dword [floodstacksize] 89 | 90 | 91 | ;color this pixel same as our seed 92 | call setpixelcolor 93 | 94 | 95 | ;examine pixel above 96 | ;********************* 97 | ;Y-1 98 | dec eax 99 | call floodprocesspixel 100 | ;reset Y 101 | inc eax 102 | 103 | 104 | ;examine pixel below 105 | ;********************* 106 | ;Y+1 107 | inc eax 108 | call floodprocesspixel 109 | ;reset Y 110 | dec eax 111 | 112 | 113 | ;examine pixel Left 114 | ;********************* 115 | ;X-1 116 | dec ebx 117 | call floodprocesspixel 118 | ;reset X 119 | inc ebx 120 | 121 | 122 | ;examine pixel Right 123 | ;******************** 124 | ;X+1 125 | inc ebx 126 | call floodprocesspixel 127 | ;reset X 128 | dec ebx 129 | 130 | 131 | jmp floodmainloop 132 | ;go back top top and continue 133 | 134 | 135 | .done: 136 | pop ebp 137 | ret 24 138 | 139 | 140 | 141 | 142 | ;************************************** 143 | ;getpixelcolor 144 | ;input 145 | ;ebx=X 146 | ;eax=Y 147 | ;returns 148 | ;color of pixel in dl 149 | ;************************************* 150 | 151 | getpixelcolor: 152 | push eax 153 | push ebx 154 | 155 | mov ecx,[ebp+16] 156 | 157 | push ebx ;x 158 | push eax ;y 159 | push ecx ;bmwidth 160 | call xy2i ;eax=pixel index 161 | 162 | mov esi,[floodAddressBitmap] 163 | mov dl,[eax+esi] 164 | ;return pixel color in dl 165 | 166 | pop ebx 167 | pop eax 168 | ret 169 | 170 | 171 | ;*************************** 172 | ;setpixelcolor 173 | ;sets pixel to our flood color 174 | ;input 175 | ;ebx=X 176 | ;eax=Y 177 | ;no return 178 | ;************************** 179 | 180 | setpixelcolor: 181 | push eax 182 | push ebx 183 | 184 | mov ecx,[ebp+16] 185 | 186 | push ebx ;x 187 | push eax ;y 188 | push ecx ;bmwidth 189 | call xy2i ;eax=pixel index 190 | 191 | mov edx,[ebp+8] ;get color 192 | 193 | mov esi,[floodAddressBitmap] 194 | mov [eax+esi],dl ;set color 195 | 196 | pop ebx 197 | pop eax 198 | ret 199 | 200 | 201 | 202 | ;********************************** 203 | ;floodprocesspixel 204 | ;input 205 | ;ebx=x 206 | ;eax=y 207 | 208 | ;return:none 209 | 210 | ;if pixel x,y is out of range 211 | ;or if pixel is not seed color 212 | ;or if stack if full 213 | ;then this routine does nothing 214 | ;else it pushes x,y on stack 215 | ;and increments count 216 | ;********************************** 217 | 218 | floodprocesspixel: 219 | 220 | ;make sure X value is within range 221 | mov esi,ebx 222 | push 0 223 | push dword [ebp+16] 224 | call checkrange 225 | jnz .done 226 | 227 | ;make sure Y value is within range 228 | mov esi,eax 229 | push 0 230 | push dword [ebp+12] 231 | call checkrange 232 | jnz .done 233 | 234 | ;get pixel color and check if its seed color 235 | call getpixelcolor 236 | cmp dl,[floodseedcolor] 237 | jnz .done 238 | 239 | ;put on stack if we have available size 240 | cmp esp,0x33333 241 | jb .done 242 | 243 | ;now before we push x,y on the stack 244 | ;we must retrieve our return address 245 | ;and then put it on the stack after x,y 246 | pop edx 247 | 248 | ;push X,Y on stack 249 | push ebx 250 | push eax 251 | ;inc floodstacksize 252 | inc dword [floodstacksize] 253 | 254 | ;now put return address on stack 255 | push edx 256 | 257 | .done: 258 | ret 259 | 260 | 261 | -------------------------------------------------------------------------------- /tlib/getc.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/getc.s 2 | 3 | ;functions to act on ps2 or usb keyboard presses 4 | 5 | ;getc, checkc, GetKeyState 6 | 7 | ;see tatOS.inc for some predefined key combinations 8 | ;for example: 9 | ;hold down Ctrl key then press 'x', returns al=0xa1=CUT 10 | ;hold down Ctrl key then press 'c', returns al=0xa2=COPY 11 | ;hold down Ctrl key then press 'v', returns al=0xa3=PASTE 12 | 13 | 14 | ;************************************************************************ 15 | ;getc 16 | ;get a single keypress from 0x504 or 0x50b 17 | ;this function will poll/block until a key on a ps2 or usb keyboard is pressed 18 | 19 | ;this version also handles ListControlKeydown 20 | ;if a list control is being displayed by a kernel or user app 21 | ;the ascii keypress retrieved by getc will be passed on to 22 | ;ListControlKeydown for processing 23 | 24 | ;input:none 25 | ;return: al=ascii char returned 26 | 27 | ; tatOS.inc has some defines like F1,F2,SPACE,TAP,NL,ESCAPE... 28 | ; or 0x31 is for the number 1 ...and so forth 29 | 30 | getcstr1 db '[getc] return value in al',0 31 | ;*********************************************************************** 32 | 33 | getc: 34 | xor eax,eax 35 | 36 | sti ;need ps2 interrupt 37 | 38 | 39 | ;if you have enabled the usb keyboard then we check byte [0x50b] 40 | ;else for ps2 keyboard we check byte [0x504] 41 | cmp dword [have_usb_keyboard],1 42 | jz .dousb 43 | mov ebx,0x504 ;buffer for ps2 keyboard (irq1) 44 | jmp .getc_mainloop 45 | .dousb: 46 | mov ebx,0x50b ;buffer for usb keyboard 47 | 48 | 49 | ;loop until we read a non-zero value 50 | ;all program execution is blocked until we get a non-zero value 51 | 52 | .getc_mainloop: 53 | cmp byte [ebx],0 54 | je .getc_mainloop 55 | 56 | 57 | cli ;disable interrupt 58 | 59 | 60 | ;return the ascii char in al 61 | mov al,[ebx] 62 | 63 | 64 | ;reset for subsequent read operations 65 | mov byte [ebx],0 66 | 67 | 68 | ;if you want to dump every keypress uncomment this line 69 | ;STDCALL getcstr1,2,dumpeax 70 | 71 | 72 | ;if we have a list control, it needs to handle the keypress also 73 | cmp dword [list_HaveList],1 74 | jnz .done 75 | call ListControlKeydown ;al=ascii char 76 | 77 | .done: 78 | ret 79 | 80 | 81 | 82 | 83 | ;*********************************************** 84 | ;checkc 85 | ;same as above except does not block 86 | ;returns immediately if byte [0x504] or [0x50b] = 0 87 | 88 | ;input:none 89 | ;return: al=ascii char 90 | ;zf is set if the keyboard buffer is empty and al=0 91 | ;zf is clear if a key has been pressed and al=ascii char 92 | 93 | checkcstr1 db 'checkc',0 94 | checkcstr2 db 'checkc return value in eax',0 95 | ;*********************************************** 96 | 97 | checkc: 98 | 99 | ;for debug 100 | ;STDCALL checkcstr1,dumpstr 101 | 102 | xor eax,eax ;al=0 103 | 104 | 105 | ;if you have enabled the usb keyboard then we check byte [0x50b] 106 | ;else for ps2 keyboard we check byte [0x504] 107 | cmp dword [have_usb_keyboard],1 108 | jz .dousb 109 | mov ebx,0x504 ;buffer for ps2 keyboard (irq1) 110 | jmp .check_keyboard_buffer 111 | .dousb: 112 | mov ebx,0x50b ;buffer for usb keyboard 113 | 114 | 115 | .check_keyboard_buffer: 116 | cmp byte [ebx],0 117 | jz .done ;zf is set if keypress buffer empty 118 | 119 | ;return the ascii char in al 120 | mov al,[ebx] 121 | 122 | ;reset for subsequent read operations 123 | mov byte [ebx],0 124 | 125 | .done: 126 | 127 | ;for debug if you want to dump every checkc return value uncomment this line 128 | ;STDCALL checkcstr2,2,dumpeax 129 | ret 130 | 131 | 132 | 133 | ;******************************************************* 134 | ;GetKeyState 135 | ;userland function to obtain the state of special keys 136 | ;on the ps2 or usb keyboard 137 | ;input: 138 | ;to obtain state of CTRL key set ebx=0 139 | ;to obtain state of SHIFT key set ebx=1 140 | ;to obtain state of ALT key set ebx=2 141 | ;to obtain state of SPACE key set ebx=3 142 | ;return: 143 | ;on success eax=1 if key is down else 0 if it is up 144 | ;on error eax=0xff 145 | gks_str1 db 'getkeystate return value',0 146 | ;******************************************************* 147 | 148 | GetKeyState: 149 | 150 | cmp ebx,0 151 | jz .doCTRL 152 | cmp ebx,1 153 | jz .doSHIFT 154 | cmp ebx,2 155 | jz .doALT 156 | cmp ebx,3 157 | jz .doSPACE 158 | jmp .error 159 | 160 | .doCTRL: 161 | movzx eax,byte [CTRLKEYSTATE] 162 | jz .done 163 | .doSHIFT: 164 | movzx eax,byte [SHIFTKEYSTATE] 165 | jz .done 166 | .doALT: 167 | movzx eax,byte [ALTKEYSTATE] 168 | jz .done 169 | .doSPACE: 170 | movzx eax,byte [SPACEKEYSTATE] 171 | jz .done 172 | .error: 173 | mov eax,0xff 174 | .done: 175 | ;STDCALL gks_str1,0,dumpeax for debug 176 | ret 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /tlib/getline.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/getline.s 2 | 3 | ;general revision 6/27/12 4 | ;you can now put asm comments on the same line as the code 5 | 6 | ;************************************************ 7 | ;getline 8 | 9 | ;reads an ascii text file 10 | ;lines are terminated by NEWLINE/NL/0xa 11 | ;the file must be terminated with 0 12 | ;this function is customized for the ttasm assembler 13 | 14 | ;copies bytes to a seperate buffer and 0 terminates by the following rules: 15 | ; * if NL terminator is found stop reading and exit 16 | ; * if : colon is read, stop saving bytes but read to end of line 17 | ; this would indicate a code label 18 | ; colon not allowed within ascii string bounded by '' 19 | ; SPACE not allowed on code label line 20 | ; * if ; semicolon is read stop saving bytes but read to end of line (comment) 21 | ; * if 80 chars have been read and not 0 terminator, quit with error 22 | ; * if leading SPACE or TAB, ignore 23 | 24 | ;input 25 | ;esi=address of ascii source 26 | ;edi=address of buffer to copy bytes to 27 | 28 | ;return 29 | ;esi is incremented to the last byte fetched 30 | ;eax=return code: 31 | ; 0=successful copy, found NEWLINE, 0 terminated 32 | ; 1=blank line found 33 | ; 2=error:parse error or buffer full and not 0 terminated 34 | ; 3=found 0 (eof) 35 | ; 5=code_label: (string ends with colon:) 36 | 37 | ;we no longer return 4 comment line, its folded in with blank line 38 | ;this function will now silently eat up comment lines by itself 39 | ;or comments after a line of asm code 40 | 41 | ;locals: 42 | destbuffer dd 0 43 | ReadWithoutSave db 0 44 | FoundCodeLabel db 0 45 | HaveStartChar db 0 46 | HaveString db 0 47 | HaveSpace db 0 48 | glstr1 db 'getline return value',0 49 | ;************************************************ 50 | 51 | getline: 52 | 53 | push ebx 54 | push ecx 55 | push edx 56 | push edi 57 | 58 | cld 59 | 60 | ;save start address of dest buffer 61 | mov [destbuffer],edi 62 | 63 | ;init 64 | mov byte [ReadWithoutSave],0 65 | mov byte [FoundCodeLabel],0 66 | mov byte [HaveStartChar],0 67 | mov byte [HaveString],0 68 | mov byte [HaveSpace],0 69 | 70 | ;max 80 chars read 71 | mov ecx,80 72 | 73 | 74 | 75 | .nextchar: ;top of loop 76 | 77 | lodsb ;al=[esi], esi++ 78 | 79 | ;for each byte read decrement our counter 80 | dec ecx 81 | ;if we got here we fetched 80 char without finding some end of line marker 82 | js near .parserror 83 | 84 | ;now examine the byte 85 | cmp al,EOF 86 | jz near .doEOF 87 | cmp al,NEWLINE 88 | jz near .doNEWLINE 89 | cmp byte [ReadWithoutSave],1 90 | jz near .nextchar 91 | cmp al,COLON 92 | jz near .doColon 93 | cmp al,SEMICOLON 94 | jz near .doReadToEOL 95 | cmp al,SINGLEQUOTE 96 | jz near .doString 97 | cmp al,SPACE 98 | jz near .doSpace 99 | cmp al,TAB 100 | jz near .doTab 101 | 102 | .savebyte: 103 | ;if we got here we have a valid char to save 104 | stosb ;[edi]=al, edi++ 105 | 106 | ;indicate the first valid char of asm code has been found 107 | mov byte [HaveStartChar],1 108 | 109 | jmp .nextchar 110 | ;end of loop 111 | 112 | 113 | 114 | 115 | .doString: 116 | mov byte [HaveString],1 117 | jmp .savebyte 118 | 119 | 120 | .doTab: 121 | .doSpace: 122 | mov byte [HaveSpace],1 123 | cmp byte [HaveStartChar],1 124 | jz .savebyte 125 | jmp .nextchar ;this will eliminate leading space or tab 126 | 127 | 128 | .doColon: 129 | ;if we found a previous SPACE on a line with : this will be treated as error 130 | ;this fixes an error like this jmp MyLabel: which will not assemble to jmp 131 | ;another example that will not be allowed is this 132 | ;db 'line: left click 1st point',0 133 | cmp byte [HaveSpace],1 134 | jz .parserror 135 | ;if we have a previous string marker 0x27 ' this is not a code label 136 | cmp byte [HaveString],1 137 | jz .savebyte 138 | ;otherwise we have a code label 139 | mov byte [FoundCodeLabel],1 140 | 141 | .doReadToEOL: 142 | ;parse the remainder of the source string without saving to dest buffer 143 | mov byte [ReadWithoutSave],1 144 | jmp .nextchar 145 | 146 | 147 | .doNEWLINE: 148 | ;check if this was a code label 149 | cmp byte [FoundCodeLabel],1 150 | jz .codelabel 151 | 152 | ;check for a short line 153 | ;any line of less than 3 chars we will treat like a blank/comment line 154 | mov eax,edi 155 | sub eax,[destbuffer] 156 | sub eax,3 157 | js .blankline 158 | 159 | ;this is an ordinary line of asm code with NL terminator 160 | jmp .success 161 | 162 | 163 | .codelabel: 164 | mov eax,5 165 | jmp .done 166 | 167 | .doEOF: 168 | mov eax,3 ;return found eof 169 | jmp .done 170 | 171 | .parserror: 172 | mov eax,2 ;return error 173 | jmp .done 174 | 175 | .blankline: 176 | mov eax,1 177 | jmp .done 178 | 179 | .success: 180 | mov eax,0 ;return success 181 | 182 | .done: 183 | mov byte [edi],0 ;terminate dest string 184 | ;STDCALL glstr1,0,dumpeax ;for debug only 185 | 186 | pop edi 187 | pop edx 188 | pop ecx 189 | pop ebx 190 | ret 191 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /tlib/is.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/is.s 2 | 3 | ;various functions used in string parsing 4 | 5 | ;isdigit, isascii, ishex, ishexstring, 6 | ;isbinarystring, isupper, islower, isalpha 7 | 8 | 9 | ;**************************************************** 10 | ;isdigit 11 | ;check if value is a valid decimal digit 12 | ;within the range 0x30-0x39 (0-9) 13 | ;April 2009 added check for negative sign - 14 | ;because decimal values may be - 15 | ;note al must contain an ascii character not a number 16 | 17 | ;input 18 | ;al=ascii byte to check 19 | 20 | ;return 21 | ;zf is set on success if byte is in range ascii 0-9 22 | ;or if we have - sign 23 | ;zf is clear on failure 24 | ;***************************************************** 25 | 26 | isdigitB: ;for userland 27 | mov eax,ebx 28 | isdigit: 29 | push ebx 30 | push ecx 31 | 32 | cmp al,0x2d ;check for - 33 | ;zf will be set if we found - 34 | jz .done 35 | cmp al,0x30 ;check for ascii 0 36 | setl bl 37 | cmp al,0x39 ;check for ascii 9 38 | setg cl 39 | 40 | add bl,cl 41 | ;bl will be nonzero and zf clear if out of range 42 | ;bl will be zero and zf set if within the range 0-9 43 | 44 | .done: 45 | pop ecx 46 | pop ebx 47 | ret 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | ;**************************************************** 58 | ;isascii 59 | ;check if byte value is in range 0x20-0x7e 60 | ;this is the range of our font01 61 | ;printable ascii bitmaps 62 | 63 | ;input 64 | ;al=byte to check 65 | 66 | ;return 67 | ;zf is set on success, clear on failure 68 | 69 | ;***************************************************** 70 | 71 | isascii: 72 | push ebx 73 | push ecx 74 | 75 | cmp al,0x20 76 | setl bl ;set bl=1 if condition is true 77 | cmp al,0x7e 78 | setg cl 79 | add bl,cl ;zf=1 if (bl and cl)=0 else zf=0 80 | 81 | pop ecx 82 | pop ebx 83 | ret 84 | 85 | 86 | 87 | ;**************************************************** 88 | ;ishex 89 | ;check a single ascii byte 90 | ;if value is a valid hex digit 91 | ;within the range lower case a-f 92 | ;which corresponds to ascii 0x61-0x66 93 | ;upper case A-F is unsupported 94 | 95 | ;input 96 | ;al=byte to check 97 | 98 | ;return 99 | ;zf is set on success, clear on failure 100 | 101 | ;***************************************************** 102 | 103 | ishex: 104 | push ebx 105 | push ecx 106 | 107 | cmp al,0x61 108 | setl bl ;set bl=1 if condition is true 109 | cmp al,0x66 110 | setg cl 111 | add bl,cl ;zf=1 if (bl and cl)=0 else zf=0 112 | 113 | pop ecx 114 | pop ebx 115 | ret 116 | 117 | 118 | 119 | 120 | ;********************************************* 121 | ;ishexstring 122 | ;for tatos a valid hex string consists of 123 | ;'0x' prefix followed by numbers 0-9 or 124 | ;the letters a-f 125 | ;the string is 0 terminated 126 | ;e.g. '0x1234a8',0 127 | ;upper case is unsupported 128 | ;h suffix is unsupported 129 | ;this function only checks for the '0x' prefix 130 | 131 | ;input 132 | ;esi=address of hex string constant 133 | 134 | ;return 135 | ;zf is set on success, clear on failure 136 | ;********************************************* 137 | 138 | ishexstring: 139 | push ecx 140 | push edx 141 | 142 | cmp byte [esi],'0' 143 | setnz cl 144 | cmp byte [esi+1],'x' 145 | setnz dl 146 | add cl,dl 147 | 148 | pop edx 149 | pop ecx 150 | ret 151 | 152 | 153 | 154 | ;********************************************* 155 | ;isbinarystring 156 | ;for tatos a binary string consists of 157 | ;a series of 1's or 0's followed by 'b' 158 | ;the string is 0 terminated 159 | ;e.g. '110111001b',0 160 | ;this function only checks for the 'b' suffix 161 | 162 | ;input 163 | ;esi=address of bin string constant 164 | 165 | ;return 166 | ;zf is set on success, clear on failure 167 | ;ecx holds address of 'b' char 168 | ;********************************************* 169 | 170 | isbinstring: 171 | push eax 172 | 173 | ;get string length 174 | mov eax,esi 175 | call strlen 176 | 177 | ;check for 'b' at end 178 | lea ecx,[esi+ecx-1] 179 | cmp byte [ecx],'b' 180 | 181 | pop eax 182 | ret 183 | 184 | 185 | 186 | 187 | 188 | ;****************************************************************** 189 | ;untested version of isdigit by bitshifter needs to be verified 190 | ;input: eax=value 191 | ;return:eax=0 if false else 1 if true 192 | ;****************************************************************** 193 | isdigit2: 194 | sub eax,'0' 195 | sub eax,10 196 | sbb eax,eax 197 | neg eax 198 | ret 199 | 200 | 201 | ;****************************************************************** 202 | ;isupper 203 | ;original code by bitshifter is modified to use al register 204 | ;input:al=ascii char value 205 | ;return:al=0 if false else 1 if true 206 | ;****************************************************************** 207 | isupper: 208 | sub al,'A' 209 | sub al,26 210 | sbb al,al 211 | neg al 212 | ret 213 | 214 | ;****************************************************************** 215 | ;islower 216 | ;tests for lower case characters in the range a-z 217 | ;original code by bitshifter is modified to use al register 218 | ;input:al=ascii char value 219 | ;return:al=0 if false else 1 if true 220 | ;****************************************************************** 221 | islower: 222 | sub al,'a' 223 | sub al,26 224 | sbb al,al 225 | neg al 226 | ret 227 | 228 | ;****************************************************************** 229 | ;untested isalpha by bitshifter 230 | ;input:eax=value 231 | ;return:eax=0 if false else 1 if true 232 | ;abused:edx 233 | ;****************************************************************** 234 | isalpha: 235 | mov edx,eax 236 | sub eax,'a' 237 | sub eax,26 238 | sbb eax,eax 239 | sub edx,'A' 240 | sub edx,26 241 | sbb edx,edx 242 | or eax,edx 243 | neg eax 244 | ret 245 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /tlib/memset.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/memset.s 2 | 3 | ;****************************************** 4 | ;memset 5 | ;set all bytes in memory to the same value 6 | 7 | ;input 8 | ;edi = starting address of memory 9 | ;ecx = qty bytes 10 | ; al = byte value to be place in memory 11 | 12 | ;no return value 13 | 14 | ;note nothing is preserved 15 | ;eax,ecx and edi are affected 16 | ;****************************************** 17 | 18 | memset: 19 | cld ;increment 20 | rep stosb ;al->edi do ecx times 21 | ret 22 | 23 | 24 | 25 | ;***************************************** 26 | ;memsetd 27 | ;same as above except works on dwords 28 | 29 | ;input 30 | ;edi = starting address of memory 31 | ;eax = dword value to be placed in memory 32 | ;ecx = qty dwords 33 | ;****************************************** 34 | 35 | memsetd: 36 | cld ;increment 37 | rep stosd ;eax->edi do ecx times 38 | ret 39 | 40 | 41 | 42 | 43 | ;if your looking for memcpy 44 | ;see strcpy and strncpy in string.s 45 | 46 | 47 | -------------------------------------------------------------------------------- /tlib/origin.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/origin.s 2 | 3 | ;******************************************************* 4 | ;origin 5 | ;sets the local origin and y axis orientation 6 | 7 | ;input,push as follows: 8 | ;XOFFSET [ebp+16] 9 | ;YOFFSET [ebp+12] 10 | ;YORIENT [ebp+8] 11 | 12 | ;return:none 13 | 14 | ;YORIENTation is by default set to 1 which means 15 | ;y=0 is along the top of the screen and y=599 16 | ;is at the bottom. If you set YORIENT=-1 then this is 17 | ;reversed and y=0 is at bottom and y=599 is at top. 18 | 19 | ;XOFFSET is from the left edge of the screen 20 | ;YOFFSET is from y=0 21 | 22 | ;after you exit any program or hit Ctrl+Alt+Del 23 | ;the following values are reset to default: 24 | ;XOFFSET=0 25 | ;YOFFSET=0 26 | ;YORIENT=1 27 | 28 | ;XOFFSET, YOFFSET, and YORIENT or global dwords 29 | ;see /doc/memorymap 30 | 31 | ;see also function getpixadd which is affected by 32 | ;all these values 33 | ;******************************************************* 34 | 35 | origin: 36 | push ebp 37 | mov ebp,esp 38 | push eax 39 | push ebx 40 | 41 | mov eax,[ebp+16] 42 | mov ebx,[ebp+12] 43 | mov [XOFFSET],eax 44 | mov [YOFFSET],ebx 45 | 46 | mov eax,[ebp+8] 47 | mov [YORIENT],eax 48 | 49 | pop ebx 50 | pop eax 51 | pop ebp 52 | retn 12 53 | 54 | 55 | -------------------------------------------------------------------------------- /tlib/paging.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/paging.s 2 | 3 | ;code to build page directory entries for 4mb (0x400000 bytes per page) paging 4 | ;elementary identy mapping for now since we currently only support 1 userland process 5 | ;our page table is 1024 directory entries starting at 0x8000 6 | ;we map all pages as present, the first 8 are for kernel, the next 2 for user 7 | ;the remaining pages are for kernel 8 | 9 | ;page 0: 0x00000000->0x00400000 kernel 10 | ;page 1: 0x00400000->0x00800000 kernel 11 | ;page 2: 0x00800000->0x00c00000 kernel 12 | ;page 3: 0x00c00000->0x01000000 kernel 13 | ;page 4: 0x01000000->0x01400000 kernel 14 | ;page 5: 0x01400000->0x01800000 kernel 15 | ;page 6: 0x01800000->0x01c00000 kernel 16 | ;page 7: 0x01c00000->0x02000000 kernel 17 | ;page 8: 0x02000000->0x02400000 userland code and data 18 | ;page 9: 0x02400000->0x02800000 reserved for another future userland process 19 | ;page 10: 0x02800000->0x02c00000 kernel 20 | ;page 11 -> page 1023 is all reserved for the kernel 21 | 22 | 23 | ;in case your app gets a page fault interrupt #14: 24 | ;the ErrorCode is as follows: 25 | ;[7] = page present, access caused by write, processor in user mode 26 | ;[5] = page present, access caused by read, processor in user mode 27 | ;check the dump messages after a ttasm assemble to find the offending 28 | ;instruction with the matching EIP value 29 | 30 | ;if page fault EIP=0, this is most likely caused by an unbalanced userland stack 31 | ;a 'ret' instruction has popped a 0 byte off the stack and attemped to 'jmp 0' 32 | ;and this causes the fault. 33 | 34 | 35 | 36 | ;future: 37 | ;reserve page 10,11 for another userland process 38 | ;this process will have its own page directory entries 39 | ;we map process 2 page 10 to STARTOFEXE same as user process 1 40 | ;and mark process 1 pages 8,9 as not present 41 | ;for our small apps we really dont need to reserve 2 4mb pages for each process 42 | ;one 4mb page is probably sufficient 43 | 44 | 45 | ;the bottom 8 bits are important in the page directory entry 46 | ;0x83 = supervisor, read/write, 4mb, present 47 | ;0x87 = user, read/write, 4mb, present 48 | ;we need read/write for flat binary code and data mixed 49 | ;a couple bits Im not real sure of yet 50 | ;bit3 PWT set to 0 to allow write back caching 51 | ;bit4 PCD set to 0 to allow page or page table to be cached 52 | 53 | ;if you run xxd right after tatOS starts up 54 | ;you will see the processor has modified the first entry at 0x8000 55 | ;so the low byte now reads 0xe3 instead of 0x83 56 | ;the processor sets bit5 accessed and bit6 dirty 57 | 58 | ;note tlibentry.s has a Validate macro and userland addresses 59 | ;that are hardcoded, so if we changing from identity map paging 60 | ;so userland code starting at address 00000000 then we must 61 | ;also make changes to tlibentry.s accordingly tom !!! 62 | 63 | 64 | 65 | ;******************************************** 66 | ;BuildPageDirectory 67 | ;here we write to memory starting at 0x8000 68 | ;our 1024 page directory entries 69 | ;this code is executed in tatOSinit.s 70 | ;first we make 8 entries for kernel 71 | ;the 2 entries for userland 72 | ;then the remaining entries for kernel 73 | ;input:none 74 | ;return:none 75 | ;******************************************** 76 | 77 | BuildPageDirectory: 78 | 79 | cld 80 | 81 | ;prepare for the first 8 pages for kernel/supervisor 82 | ;the PageBaseAddress starts at 0 because we are identity mapping 83 | ;set the low byte to 0x83 for supervisor, read/write, 4mb, present 84 | mov eax,0x83 85 | 86 | ;init the destination for the directory entry 87 | mov edi,0x8000 88 | 89 | ;init the loop counter for 8 kernel entries 90 | mov ecx,8 91 | 92 | 93 | 94 | ;write the 1st 8 kernel page directory entries 95 | ;************************************************ 96 | 97 | .1: 98 | ;now write the 4mb page directory entry to memory 99 | mov [edi],eax 100 | 101 | ;increment the destination memory address 102 | add edi,4 103 | 104 | ;increment the Page Base Address by 4mb 105 | add eax,0x400000 106 | 107 | loop .1 108 | ;done writting the first 8 kernel page entries 109 | 110 | 111 | 112 | 113 | ;now write 2 userland page entries 114 | ;************************************ 115 | 116 | ;set the low byte to 0x87 for user, read/write, 4mb, present 117 | mov al,0x87 118 | 119 | ;write the first userland entry 120 | mov [edi],eax 121 | add edi,4 122 | add eax,0x400000 123 | 124 | ;write the 2nd userland entry 125 | mov [edi],eax 126 | add edi,4 127 | add eax,0x400000 128 | 129 | 130 | 131 | 132 | ;now write the remaining entries up to 4gib 133 | ;******************************************** 134 | 135 | ;change the low byte to 0x83 for kernel 136 | mov al,0x83 137 | 138 | ;8+2+1014=1024 4mb pages 139 | mov ecx,1014 140 | 141 | .2: 142 | ;now write the 4mb page directory entry to memory 143 | mov [edi],eax 144 | 145 | ;increment the destination memory address 146 | add edi,4 147 | 148 | ;increment the Page Base Address by 4mb 149 | add eax,0x400000 150 | 151 | loop .2 152 | 153 | ret 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /tlib/pointer.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/pointer.s 2 | 3 | ;routines to draw a software mouse pointer/cursor 4 | ;apps are responsible for drawing the pointer 5 | ;at the end of their paint routine 6 | ;call crosspointer or arrowpointer 7 | ;dont forget to call swapbuf to make it show up 8 | ;all these pointer routines use MOUSEX,MOUSEY 9 | ;which is maintained by tatOS/usb/mouseinterrupt.s for the usb mouse 10 | 11 | 12 | ;******************************************* 13 | ;crosspointer 14 | ;draw the mouse pointer/cursor 15 | ;its a simple cross 16x16 pixels 16 | ;color RED so its visible on either a 17 | ;WHI or BLA or CYA background 18 | ;the point MOUSEX,MOUSEY 19 | ;is at the intersection 20 | 21 | ;input:none 22 | ;return:none 23 | ;******************************************** 24 | 25 | crosspointer: 26 | 27 | push dword [MOUSEX] 28 | push dword [MOUSEY] 29 | call getpixadd 30 | push edi ;save 31 | 32 | ;horizontal line 33 | sub edi,8 ;backup 8 pixels in the row 34 | mov al,RED ;color 35 | mov ecx,16 ;set 16 pixels 36 | cld ;inc 37 | rep stosb ;al->edi 38 | 39 | ;vertical line 40 | mov ebp,[BPSL] ;ebp=qty bytes to advance to next row 41 | mov ebx,ebp 42 | shl ebx,3 ;ebx = qty bytes to advance 8 rows 43 | pop edi 44 | sub edi,ebx ;edi=address at top of vert line 45 | mov ecx,16 ;qty vert pixels to set 46 | mov al,RED 47 | cld ;inc 48 | .Vline3: 49 | mov [edi],al 50 | add edi,ebp 51 | loop .Vline3 52 | 53 | ret 54 | 55 | 56 | 57 | ;********************************************** 58 | ;arrowpointer 59 | ;this is your standard arrow pointer 60 | ;black border, white interior 61 | ;width=12, height=21 62 | ;the hot spot is the very first byte 63 | ;input: none 64 | ;********************************************** 65 | 66 | arrowpointer: 67 | 68 | push dword [MOUSEX] ;xstart 69 | push dword [MOUSEY] ;ystart 70 | push 12 ;width 71 | push 21 ;height 72 | push _arrowpointerbits 73 | call puttransbits 74 | ret 75 | 76 | 77 | 78 | 79 | _arrowpointerbits: 80 | db 239,255,255,255,255,255,255,255,255,255,255,255 81 | db 239,239,255,255,255,255,255,255,255,255,255,255 82 | db 239,254,239,255,255,255,255,255,255,255,255,255 83 | db 239,254,254,239,255,255,255,255,255,255,255,255 84 | db 239,254,254,254,239,255,255,255,255,255,255,255 85 | db 239,254,254,254,254,239,255,255,255,255,255,255 86 | db 239,254,254,254,254,254,239,255,255,255,255,255 87 | db 239,254,254,254,254,254,254,239,255,255,255,255 88 | db 239,254,254,254,254,254,254,254,239,255,255,255 89 | db 239,254,254,254,254,254,254,254,254,239,255,255 90 | db 239,254,254,254,254,254,254,254,254,254,239,255 91 | db 239,254,254,254,254,254,254,239,239,239,239,239 92 | db 239,254,254,254,239,254,254,239,255,255,255,255 93 | db 239,254,254,239,239,254,254,239,255,255,255,255 94 | db 239,254,239,255,255,239,254,254,239,255,255,255 95 | db 239,239,255,255,255,239,254,254,239,255,255,255 96 | db 239,255,255,255,255,255,239,254,254,239,255,255 97 | db 255,255,255,255,255,255,239,254,254,239,255,255 98 | db 255,255,255,255,255,255,255,239,254,254,239,255 99 | db 255,255,255,255,255,255,255,239,254,254,239,255 100 | db 255,255,255,255,255,255,255,255,239,239,255,255 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /tlib/polar.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/polar.s 2 | 3 | 4 | ;polar2rect, fillsincos, rad2deg, normalizedeg 5 | 6 | 7 | ;********************************************** 8 | ;polar2rect 9 | ;polar to cartesian conversion 10 | ;this function uses the prebuilt SINTABLE & COSTABLE 11 | ;lookup tables are generated by "FillSinCos" below 12 | 13 | ;the angle must be an unsigned integer 0,1,2...359 14 | 15 | ;input 16 | ;push radius,pixels [ebp+12] 17 | ;push theta,degrees (0,1,2...359) [ebp+8] 18 | 19 | ;return 20 | ;ebx=dX=Rcos(theta) 21 | ;eax=dY=Rsin(theta) 22 | 23 | ;ebx and eax are signed integer values 24 | ;ZF is clear on error 25 | ;********************************************** 26 | 27 | polar2rect: 28 | 29 | push ebp 30 | mov ebp,esp 31 | push ecx 32 | push edx 33 | push edi 34 | 35 | 36 | ;ecx=degree=index into dword table 37 | mov ecx,[ebp+8] 38 | 39 | 40 | ;angle must be 0-359 deg 41 | ;because its an index into our lookup tables 42 | cmp ecx,360 43 | jb .setedi 44 | mov eax,ecx 45 | add eax,360 46 | xor edx,edx 47 | mov ebx,360 48 | div ebx 49 | mov ecx,edx 50 | 51 | 52 | .setedi: 53 | ;ebx=radius 54 | mov edi,[ebp+12] 55 | 56 | 57 | ;work on dX 58 | mov eax,[COSTABLE+ecx*4] 59 | imul edi ;eax=R*cos(theta) 60 | 61 | 62 | ;to avoid a costly idiv by 2^16=65536 63 | ;we use Agner Fog's alternative 64 | ;for signed division by 2^N 65 | ;see Agners Pentium Optimization Manual 66 | ;idiv esi ;eax=R*cos(theta)/65536 67 | cdq 68 | shr edx,16 ;shift by 32-N 69 | add eax,edx 70 | sar eax,16 ;shift by N 71 | mov ebx,eax ;ebx=X=R*cos(theta)/65536 72 | 73 | 74 | ;work on dY 75 | mov eax,[SINTABLE+ecx*4] 76 | imul edi 77 | cdq 78 | shr edx,16 ;shift by 32-N 79 | add eax,edx 80 | sar eax,16 ;shift by N 81 | 82 | 83 | ;set zf on success 84 | xor edx,edx 85 | 86 | 87 | .done: 88 | pop edi 89 | pop edx 90 | pop ecx 91 | pop ebp 92 | retn 8 93 | 94 | 95 | 96 | 97 | ;******************************************************** 98 | ;fillsincos 99 | ;we loop 360 times incrementing by 1 deg each time 100 | ;fills dword arrays sintable[] and costable[] 101 | ;each array holds 360 dwords = 1440 bytes 102 | ;each entry is scaled by 2^16 = 65536 to make a signed integer 103 | ;1st entry of cos table: 65536 * cos(0deg) 104 | ;2nd entry of cos table: 65536 * cos(1deg) 105 | ;3rd entry of cos table: 65536 * cos(3deg) 106 | ;and so on ... ditto for sin table 107 | ;so after retrieving a value from the table and doing 108 | ;signed imul by amplitude you should do signed divide by 65536 109 | ;use "sar" arithmetic right shift by 16 instead of the division 110 | ;this function is called on startup in boot2.s 111 | ;see tatOS/doc/memorymap and tatOS/tlib/tatos.inc 112 | ;where we reserve memory for SINTABLE and COSTABLE 113 | 114 | ;local variables 115 | _radsperdeg: 116 | dq 0.01745329 117 | 118 | _multiplier: 119 | dd 65536 120 | ;******************************************************** 121 | 122 | fillsincos: 123 | 124 | mov ecx,360 125 | mov esi,SINTABLE 126 | mov edi,COSTABLE 127 | 128 | ;.01745 is our angle increment 129 | fld qword [_radsperdeg] 130 | ;st0=.01745 131 | 132 | fldz 133 | ;st0=angle_start, st1=.01745 134 | 135 | 136 | .SinCosLoop: 137 | 138 | ;copy st0->st2 139 | fst st2 140 | ;st0=angle, st1=.01745, st2=angle 141 | 142 | fsincos 143 | ;st0=cos(st0), st1=sin(st0), st2=.01745, st3=angle 144 | 145 | fimul dword [_multiplier] 146 | ;st0=65536*cos(st0), st1=sin(st0), st2=.01745, st3=angle 147 | 148 | ;save st0->costable 149 | fistp dword [edi] 150 | ;st1=sin(st0), st2=.01745, st3=angle 151 | 152 | fimul dword [_multiplier] 153 | ;st0=65536*sin(st0), st1=.01745, st2=angle 154 | 155 | ;save st0->sintable 156 | fistp dword [esi] 157 | ;st0=.01745, st1=angle 158 | 159 | 160 | ;inc pointers to sintable and costable 161 | add esi,4 162 | add edi,4 163 | 164 | fxch st1 165 | ;st0=angle, st1=.01756 166 | 167 | fadd st1 168 | ;st0=angle+angleinc, st1=.01745 169 | 170 | loop .SinCosLoop 171 | 172 | ffree st0 173 | ffree st1 174 | 175 | ret 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | ;********************************************** 184 | ;rad2deg 185 | ;converts the qword radian value in st0 186 | ;to degrees in st0 187 | 188 | ;input: 189 | ;st0=angle value in radians 190 | 191 | ;return: 192 | ;st0=angle value in degrees 193 | 194 | ;the function qtod may be used to convert 195 | ;the deg float to int for using the polar 196 | ;lookup tables. The conversion constant is 197 | ;defined in tlib.s 198 | ;********************************************** 199 | 200 | rad2deg: 201 | fmul qword [one_eighty_over_pi] 202 | ret 203 | 204 | 205 | 206 | 207 | ;********************************************** 208 | ;normalizedeg 209 | ;converts a signed integer degree value 210 | ;to an unsigned value in the range of 0-359 211 | 212 | ;input 213 | ;eax=degree value to manipulate 214 | 215 | ;return 216 | ;eax=degree value in range 0-359 217 | ;************************************************ 218 | 219 | normalizedeg: 220 | 221 | push edx 222 | push ebx 223 | 224 | ;we assume the value is bigger than -720 225 | add eax,720 226 | xor edx,edx 227 | mov ebx,360 228 | div ebx 229 | ;value in edx is in range 0-359 230 | mov eax,edx 231 | 232 | pop ebx 233 | pop edx 234 | ret 235 | 236 | 237 | 238 | -------------------------------------------------------------------------------- /tlib/rand.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/rand.s 2 | 3 | ;*************************************************************** 4 | ;rand 5 | ;pseudo random number generator 6 | ;written by Andrew Griffen and Max McGuire 7 | ;taken from John Eckerdahls web set 8 | 9 | ;input 10 | ;if ebx=0 then get a new random number and return dword in eax 11 | ;if ebx!=0 then assign a new value to RANDSEED and exit 12 | 13 | ;return: random DWORD in eax 14 | 15 | ;note RANDSEED is initialize in tatOSinit.s 16 | ;but you may need to assign a new value depending 17 | 18 | ;local 19 | _ranstr1 db 'rand:new RANDSEED',0 20 | _ranstr2 db 'rand:new random number',0 21 | ;*************************************************************** 22 | 23 | rand: 24 | 25 | cmp ebx,0 26 | jz .getrandom 27 | mov [RANDSEED],ebx ;save new RANDSEED 28 | STDCALL _ranstr1,0,dumpebx 29 | jmp .done 30 | 31 | .getrandom: 32 | 33 | mov ebx,[RANDSEED] 34 | mov eax,ebx 35 | shl eax,2 36 | add eax,ebx 37 | xchg al,ah 38 | mov [RANDSEED],eax 39 | 40 | ;with Fern this really fills up the dump and slows down the program 41 | ;STDCALL _ranstr2,0,dumpeax 42 | 43 | .done: 44 | ret 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /tlib/rectangle.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/rectangle.s 2 | 3 | 4 | ;rectangle 5 | ;fillrect 6 | 7 | ;**************************************************************** 8 | ;rectangle 9 | ;draws an unfilled rectangular box, line width = 1 pixel 10 | 11 | ;if YORIENT=1 then x,y is the upper left corner of the rect 12 | ;the rect is drawn to the right and down 13 | 14 | ;if YORIENT=-1 then x,y is the lower left corner of the rect 15 | ;the rect is drawn to the right and up 16 | 17 | ;input 18 | ;push x [ebp+24] 19 | ;push y [ebp+20] 20 | ;push width [ebp+16] 21 | ;push height [ebp+12] 22 | ;push color [ebp+8] 23 | ;**************************************************************** 24 | 25 | rectangle: 26 | 27 | push ebp 28 | mov ebp,esp 29 | pushad 30 | 31 | ;crash protection, width & height must not be neg or 0 32 | cmp dword [ebp+16],0 33 | jle .done 34 | cmp dword [ebp+12],0 35 | jle .done 36 | 37 | ;top 38 | mov ebx,[ebp+24] ;x 39 | mov ecx,[ebp+20] ;y 40 | mov edx,[ebp+16] ;length 41 | mov esi,[ebp+8] ;color 42 | call hline 43 | 44 | ;bottom 45 | mov ebx,[ebp+24] ;x 46 | mov ecx,[ebp+20] 47 | add ecx,[ebp+12] ;y 48 | mov edx,[ebp+16] ;length 49 | mov esi,[ebp+8] ;color 50 | call hline 51 | 52 | ;left side 53 | mov ebx,[ebp+24] ;x 54 | mov ecx,[ebp+20] ;y 55 | mov edx,[ebp+12] ;length 56 | mov esi,[ebp+8] ;color 57 | call vline 58 | 59 | ;right side 60 | mov ebx,[ebp+24] 61 | add ebx,[ebp+16] ;x 62 | mov ecx,[ebp+20] ;y 63 | mov edx,[ebp+12] ;length 64 | mov esi,[ebp+8] ;color 65 | call vline 66 | 67 | .done: 68 | popad 69 | pop ebp 70 | retn 20 71 | 72 | 73 | 74 | 75 | ;*********************************** 76 | ;fillrect 77 | ;draws a filled box 78 | ;input 79 | ;push x upper left [ebp+24] 80 | ;push y [ebp+20] 81 | ;push width [ebp+16] 82 | ;push height [ebp+12] 83 | ;push color [ebp+8] 84 | ;STDCALL x,y,w,y,RED,fillrect 85 | ;********************************** 86 | 87 | fillrect: 88 | 89 | push ebp 90 | mov ebp,esp 91 | pushad 92 | 93 | push dword [ebp+24] 94 | push dword [ebp+20] 95 | call getpixadd 96 | ;edi=address of pixel at upper left corner 97 | 98 | mov edx,[BPSL] ;bytesperscanline 99 | sub edx,[ebp+16] 100 | ;edx now holds qty bytes to advance video buffer to next row 101 | 102 | mov eax,[ebp+8] ;color to al 103 | mov ebx,[ebp+16] ;width 104 | mov ecx,ebx ;needed by stosb 105 | mov esi,[ebp+12] ;height 106 | cld ;inc 107 | 108 | .setpixels: 109 | rep stosb ;al->edi ecx times (set entire row of pixels) 110 | dec esi ;one less row 111 | jz .done 112 | add edi,edx ;increment video buffer to next row 113 | mov ecx,ebx ;rep destroys ecx so restore for next row 114 | jmp .setpixels 115 | 116 | .done: 117 | popad 118 | pop ebp 119 | retn 20 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /tlib/roundmode.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/roundmode.s 2 | 3 | 4 | ;******************************************* 5 | ;roundmode 6 | ;set the fpu rounding mode 7 | 8 | ;input 9 | ;push 0=nearest (default) [ebp+8] 10 | ; 1=down toward - infinity 11 | ; 2=up toward + infinity 12 | ; 3=truncate 13 | 14 | ;return:none 15 | 16 | ;bits 10,11 of the fpu ControlWord control 17 | ;the rounding mode. 18 | 19 | ;this instruction affects the result of frndint 20 | ;which rounds st0 to an integer according to 21 | ;the current rounding mode 22 | 23 | ;e.g. st0=19.876 24 | ;near=11.0, dn=10.0, up=11.0, trun=10.0 25 | ;e.g. st0=10.456 26 | ;near=10.0, dn=10.0, up=11.0, trun=10.0 27 | 28 | ;note a well behaved app should return the 29 | ;rounding mode to "nearest" when done 30 | 31 | ;pow for example requires "truncate" 32 | 33 | ;see "SIMPLY FPU" by "Raymond Filiatreault" 34 | 35 | ;local variable 36 | _roundCW dw 0 37 | ;******************************************* 38 | 39 | roundmode: 40 | 41 | push ebp 42 | mov ebp,esp 43 | push eax 44 | 45 | ;get the current Control Word 46 | fstcw word [_roundCW] 47 | 48 | ;first clear bits 10,11 49 | ;this sets the default rounding mode to "nearest" 50 | and word [_roundCW],0xf3ff 51 | 52 | ;now set bits 10,11 to the selected rounding mode 53 | mov eax,[ebp+8] 54 | shl eax,10 55 | or word [_roundCW],ax 56 | 57 | ;save the Control Word with new rounding mode 58 | fldcw word [_roundCW] 59 | 60 | pop eax 61 | pop ebp 62 | retn 4 63 | 64 | 65 | -------------------------------------------------------------------------------- /tlib/scriptT.bits: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tatimmer/tatOS/7c153b2987a1e7439e853d1b41fa4d1cc3dce6d5/tlib/scriptT.bits -------------------------------------------------------------------------------- /tlib/sort.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/sort.s 2 | 3 | 4 | ;********************************************************** 5 | ;bubble sort 6 | ;This is a bubble sort by Index 7 | 8 | ;input 9 | ;esi=address of Myarray dword elements to sort 10 | ;ecx=qty elements in Myarray 11 | ;return 12 | ;Index array holds the sorted indices of Myarray from min to max 13 | 14 | ;explanation: 15 | ;Myarray contains a collection of dword values to sort 16 | ;this routine does not actually sort Myarray elements 17 | ;instead it fills an Index array and sorts the indexes 18 | ;the "Index" array is the same size as Myarray 19 | ;and immediately follows/appends Myarray 20 | ;the starting address of the Index array is Myarray+n 21 | ;this routine will initially fill "Index" with 0,1,2,3,4... 22 | ;then it will sort the Index array according to the 23 | ;order of elements found in Myarray 24 | ;Index(0) holds the index of the smallest element in Myarray 25 | ;Index(n-1) holds the index of the largest element in Myarray 26 | ;Array and Index are dword arrays 27 | 28 | ;example: 29 | ;Myarray = 9,5,12,2,7,23,13 30 | ;qty elements = 7 31 | ;After bubblesort is done Myarray will look like this: 32 | ;9,5,12,2,7,23,13, 3,1,4,0,2,6,5 33 | ;the last element of Myarray is 13 34 | ;the first element of the Index array is 3 35 | ;"3" is the index of the lowest value in Myarray which is the number 2 36 | ;remember our arrays are 0 based index so Myarray(0)=9, Myarray(1)=5 etc... 37 | ;"1" is the index of the next lowest value in Myarray which is 5 38 | ;"4" is the index of the next lowest value in Myarray which is 7 39 | ;the index of the maximum value in Myarray is found at the end of the Index array 40 | ;the value is 5 and Myarray(5)=23 which is the max value in Myarray 41 | ;get it ? 42 | 43 | ;caution! remember to allocate enough space for Myarray so Index array 44 | ;fits after Myarray, i.e. sizeof(Myarray) must be 2 times the number of dwords 45 | ;in Myarray 46 | 47 | ;****************************************************** 48 | ; Myarray(n) | Index(n) | 49 | ;****************************************************** 50 | ;locals 51 | bubbleNminus1 dd 0 52 | bubblemadeswap dd 0 53 | bubbleMyarray dd 0 ;starting address of Myarray 54 | bubbleIndex dd 0 ;starting address of Index 55 | 56 | 57 | 58 | bubblesort: 59 | pushad 60 | 61 | ;storage 62 | mov [bubbleMyarray],esi 63 | 64 | ;store the starting address of the Index array 65 | lea eax,[esi+ecx*4] 66 | mov [bubbleIndex],eax 67 | 68 | ;fill Index array with 0,1,2,3...n-1 69 | dec ecx ;ecx=n-1 70 | mov [bubbleNminus1],ecx 71 | mov esi,[bubbleIndex] 72 | .fill: 73 | mov [esi+ecx*4],ecx 74 | dec ecx 75 | jns .fill 76 | 77 | .sortfromtop: 78 | ;edx is our index into the Index array (i) 79 | ;max value is n-1 where n=qty elements in the array 80 | xor edx,edx 81 | mov dword [bubblemadeswap],0 ;keep track if we made a swap or not thru the pass 82 | 83 | .get2elements: 84 | mov esi,[bubbleIndex] 85 | mov eax,[esi+edx*4] ;eax=Index(i) 86 | mov ebx,[esi+edx*4+4] ;eax=Index(i+1) 87 | 88 | mov esi,[bubbleMyarray] 89 | mov ecx,[esi+eax*4] ;ecx=Myarray(Index(i)) 90 | mov edi,[esi+ebx*4] ;edx=Myarray(Index(i+1)) 91 | cmp ecx,edi ;make the comparison 92 | jbe .increment 93 | .swap: 94 | mov esi,[bubbleIndex] 95 | mov [esi+edx*4],ebx 96 | mov [esi+edx*4+4],eax 97 | mov dword [bubblemadeswap],1 ;set swap flag 98 | .increment: 99 | inc edx 100 | cmp edx,[bubbleNminus1] 101 | jb .get2elements 102 | 103 | ;check if we did any swapping this pass thru the array 104 | cmp dword [bubblemadeswap],1 105 | jz .sortfromtop ;yes so go back thru the entire array again 106 | 107 | popad 108 | ret 109 | 110 | 111 | -------------------------------------------------------------------------------- /tlib/time.s: -------------------------------------------------------------------------------- 1 | ;tatOS/tlib/time.s 2 | 3 | 4 | ;time related functions: 5 | 6 | ;sleep, clock 7 | ;checktimer, timerstart, timerstop, timerinit 8 | 9 | 10 | ;see /boot/pic.s 11 | ;see irq0 in /boot/gdtidttss.s 12 | ;these functions use the pit 13 | ;which is initialized for about 1000 hits per second 14 | 15 | 16 | ;*********************************************** 17 | ;sleep 18 | ;makes use of pit counter value @ PITCOUNTER 19 | ;to pause execution of time sensitive graphics 20 | ;this is a blocking function 21 | 22 | ;input 23 | ;ebx=amount of milliseconds to pause 24 | 25 | ;set ebx=1000 to pause for one second 26 | ;you can make a simple clock just by displaying 27 | ;a number then sleep(1000) then increment and loop 28 | ;see interrupts.s which programs the PIT to 29 | ;fire appx once every millisecond 30 | ;see also pic.s which must enable the PIT interrupt 31 | 32 | ;warning: dont call this function while interrupts 33 | ;are disabled (cli). It will hang your computer ! 34 | ;because the value of PITCOUNTER never changes. 35 | ;also this function will block keyboard or mouse 36 | ;************************************************ 37 | 38 | sleep: 39 | 40 | ;interrupts MUST be enabled (sti) 41 | ;or we will hang the computer 42 | sti 43 | push eax 44 | 45 | mov eax,[PITCOUNTER] ;get value of pit counter 46 | add eax,ebx ;eax=value of pit counter + amount of delay 47 | 48 | .1: mov ebx,[PITCOUNTER] ;get value of pit counter again 49 | cmp eax,ebx ;are we there yet ? 50 | ja .1 ;no-keep checking 51 | 52 | pop eax 53 | ret 54 | 55 | 56 | 57 | 58 | 59 | ;******************************************************************** 60 | ;checktimer 61 | ;this is a non-blocking alternative to sleep 62 | ;use this function to implement a clock 63 | ;or some other time sensitive action 64 | ;when you also need to be checking for keyboard or mouse activity 65 | ;the kernel will call a user defined function (callback) 66 | ;at regular time intervals you specify 67 | 68 | ;To use this function: 69 | ;1) call timerinit at program startup to set the callbackfunction 70 | ;2) call checktimer right after checkc and usbcheckmouse in your app main loop 71 | ;3) call timerstart or timerstop usually in response to keyboard action 72 | 73 | ;input:none 74 | ;return:none 75 | ;****************************************** 76 | 77 | checktimer: 78 | 79 | ;first make sure we have a valid callback function 80 | cmp dword [TIMERCALLBACK],0 81 | jz .done 82 | 83 | 84 | ;check for stop which means the user does not want a callback yet 85 | cmp dword [TIMERSTART],0 86 | jz .done 87 | 88 | 89 | ;check if value of PITCOUNTER has exceeded CHECKTIMEELAPSED 90 | mov eax,[PITCOUNTER] 91 | cmp eax,[TIMERELAPSED] 92 | jb .done 93 | 94 | 95 | ;call user defined function 96 | call [TIMERCALLBACK] 97 | 98 | 99 | ;reset PITCOUNTER to 0 for next time around app-main-loop 100 | mov dword [PITCOUNTER],0 101 | 102 | 103 | .done: 104 | ret 105 | 106 | 107 | 108 | timerstart: 109 | mov dword [TIMERSTART],1 110 | ret 111 | 112 | timerstop: 113 | mov dword [TIMERSTART],0 114 | ret 115 | 116 | 117 | 118 | ;****************************************************************** 119 | ;timerinit 120 | ;init some values used by checktimer 121 | ;input: 122 | ;ebx=time interval between function calls from kernel, milliseconds 123 | ; to receive a callback function once every second set ebx=1000 124 | ;ecx=name of user defined callback function 125 | ; must be within users page ! 126 | ;return: CF is set if invalid function call else clear if valid 127 | ;****************************************************************** 128 | 129 | timerinit: 130 | 131 | mov [TIMERELAPSED],ebx 132 | mov [TIMERCALLBACK],ecx 133 | mov dword [TIMERSTART],0 134 | 135 | ;check for valid callback function 136 | push ecx 137 | call ValidateUserAddress ;CF is set on invalid address 138 | jnc .done 139 | 140 | .error: 141 | mov dword [TIMERCALLBACK],0 ;this will not be called by kernel 142 | .done: 143 | ret 144 | 145 | 146 | 147 | 148 | 149 | 150 | ;******************************************************** 151 | ;clock 152 | ;function returns a time value in milliseconds 153 | ;to determine elapsed time within your program 154 | ;call this function twice and subtract the two values 155 | ;input:none 156 | ;return:eax=time in milliseconds 157 | ;******************************************************** 158 | 159 | clock: 160 | mov eax,[PITCOUNTER] 161 | ret 162 | 163 | 164 | -------------------------------------------------------------------------------- /usb/README: -------------------------------------------------------------------------------- 1 | README tatOS usb Feb 2016 2 | 3 | This usb driver code was developed from scratch and has evolved over the years. 4 | It is not perfect. No usb analyser has been used to check it. 5 | The flash drive init sequence usually passes but sometimes fails. 6 | Then I just reinit the controller and go thru the flash sequence again. 7 | It will almost always pass the 2nd time. 8 | 9 | Not all flash drives behave the same. Some will go thru the init sequence quickly 10 | the first time without fail, others may stall or slow down at some point. 11 | 12 | There are times when a write10 may fail so I go back and reset the 13 | controller and go thru the flash init sequence again and try the write10 again 14 | and it fails again. Then I just reboot. Sorry thats life. 15 | 16 | 17 | 18 | POLLING 19 | ********** 20 | The usb driver code does not use interrupts, but uses polling. See run.s 21 | We wait/poll for the usb controller to mark the tranfer descriptor as inactive 22 | or failed, before continuing code execution. I have only dabbled into getting 23 | the usb controller to issue a hardware interrupt on successful completion of a TD 24 | but have not been successful. It involves finding the registers that control 25 | legacy support and PIRQD routing. On bootup the bios will enable legacy support 26 | and enable usb keyboard hardware interrupts but route thru irq1. I did not want to 27 | fall back on legacy support. Then there are registers to enable the usb controller to generate interrupts and also an PCI->ISA bridge register to route that interrupt 28 | to whatever irq you choose, and then the usb TD must be generated to issued an 29 | interrupt on completion of the TD. A bit of work must be done here. 30 | 31 | 32 | HUB 33 | **** 34 | As of 2015 there is now code to init an "integrated root hub". This hub is built into 35 | my Acer laptop and it allows a usb 1.0 (low speed device) like a mouse or keyboard 36 | to communicate with an ehci hi speed controller. The use of uhci companion controllers 37 | is apparently obsolete. I have a Lenova desktop with 2 ehci controllers 38 | that also has an integrated root hub (also called "rate matching hub"). 39 | 40 | 41 | KEYBOARD 42 | ********* 43 | As of 2016 we now have usb keyboard code. This keyboard code is identical to the 44 | usb mouse except for the buffer pointers and device address and endpoint numbers. 45 | In fact you can use the mouse init sequence on the keyboard and it will work. 46 | Both the keyboard and mouse are "low speed" HID (human interface device). 47 | So in the interest of time I just copied the mouse code files to keyboard, 48 | changed the address where the descriptors are stored and used unique values for 49 | device address and proper endpoint. Also new queue heads are required in the 50 | frame list in order to conduct seperate interrupt transfers for each device. 51 | Some day I may spend time compacting the code and eliminating duplication but 52 | its not a priority right now. 53 | 54 | 55 | Thats all folks. 56 | Enjoy your usb transactions. 57 | 58 | Tom Timmermann 59 | Janesville WI USA 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /usb/README-Toggle: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/README-Toggle 2 | 3 | March 2015 4 | 5 | data toggles for ehci 6 | 7 | DATA0=0, DATA1=1 8 | 9 | the data toggle can really mess up your usb transactions if not done correctly 10 | run() will give a time out error 11 | 12 | Here are some rules as I see them: 13 | 14 | 1) each endpoint maintains its own toggle which alternates between 0 and 1 with each TD 15 | 16 | 2) on port reset host and device set there toggles to 0 17 | 18 | 3) control transfers (getting device, config, endpint descriptors ...) 19 | * command transport: PID=OUT and toggle=0 20 | * data transport : PID=IN and toggle=1 21 | * status transport : PID=OUT and toggle=1 22 | if there is no data transport (like SetAddress, SetConfiguration) then 23 | * status transport : PID=IN and toggle=1 24 | 25 | we have a seperate queue head for control transfers that is setup 26 | so the controller takes the toggle from the qTD, see initehci.s 27 | 28 | 4) for EHCI bulk transfers which begin with "Inquiry" et all, 29 | we still use toggle values set manually in software and the QH is setup to use 30 | the toggle from the qTD. When we get to Read10 and Write10 we are using 31 | dword [bulktogglein] and dword [bulktoggleout] to manage the toggles 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /usb/baseaddress.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/baseaddress.s 2 | 3 | 4 | ;*************************************************************** 5 | ;uhcibaseaddress 6 | 7 | ;PCI Config: USBBA usb i/o space base address (byte offset 0x20) 8 | ;the USBBA is a dword at Address Offset 20-23h 9 | ;then we extract from this the UHCIBASEADD 10 | ;this is the important one needed for usb transactions 11 | 12 | ;on my CBS homebuilt USBBA=0x7121 13 | ;the UHCIBASEADD is then 0x7120 (USBBA with bit0 cleared) 14 | ;on my Via pci addon card with ehci and (2) uhci companions 15 | ;the UHCIBASEADD of the companions is 0xef20, 0xef40 16 | 17 | ;input: 18 | ;eax=bus:dev:fun number of UHCI usb controller 19 | ;return: 20 | ;the usb controller base address is saved to global [UHCIBASEADD] 21 | 22 | ubastr1 db 'uhcibaseaddress: UHCIBASEADD',0 23 | ;*************************************************************** 24 | 25 | uhcibaseaddress: 26 | pushad 27 | 28 | ;eax=bus:dev:fun number of usb controller 29 | mov ebx,0x20 ;20=address offset for USBBA 30 | call pciReadDword 31 | mov [0x52c],eax ;save USBBA 32 | 33 | ;save the "Index Register Base Address" for usb transactions 34 | ;this is bits15-5 of USBBA with bit0 cleared 35 | ;I guess the bios sets this value but we could change it 36 | and eax,0xfffffffe 37 | mov [UHCIBASEADD],ax 38 | STDCALL ubastr1,1,dumpeax 39 | 40 | popad 41 | ret 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /usb/checkcsw.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/checkCSW.s 2 | 3 | 4 | ;a CSW CommandStatusWrapper is what is returned in the status phase 5 | ;of a scsi bulk transfer, its 13 bytes of goodies 6 | 7 | ;call this function after inquiry, request sense, test unit ready, 8 | ;read10, write10, read capacity 9 | 10 | ;our CSW looks like: 55 53 42 53 DD CC BB AA 00 00 00 00 00 11 | 12 | 13 | ;******************************************** 14 | ;CheckCSWstatus 15 | 16 | ;memory for scsiCSW is reserved in usb.s 17 | 18 | ;check last byte of the CSW (bCSWStatus) 19 | ;00=command passed 20 | ;01=failed 21 | ;02=phase error 22 | ;03,04=Reserved (Obsolete) 23 | ;05-ff=Reserved 24 | 25 | ;input:esi=address of CSW 26 | ; for uhci its scsiCSW 27 | ; for ehci its 0xb70000 28 | 29 | ;return: 30 | ;eax=0 success and eax=1 on failure 31 | ;same as all other usb transactions 32 | ;sets CF if command passed else clears CF on failure 33 | 34 | cswstr1 db 'CSW bCSWStatus = FAIL',0 35 | cswstr2 db 'CSW bCSWStatus = FAIL-PHASE ERROR',0 36 | cswstr3 db 'CSW bCSWStatus = FAIL-Reserved',0 37 | cswstr4 db 'CSW bCSWStatus = Command Passed',0 38 | ;******************************************** 39 | 40 | CheckCSWstatus: 41 | 42 | ;first dump the Command Status Wrapper 43 | STDCALL esi,13,dumpmem 44 | 45 | 46 | ;get the CSW status byte 47 | mov al, [esi+12] 48 | 49 | cmp al,0 50 | jz .commandpassed 51 | cmp al,1 52 | jz .commandfailed 53 | cmp al,2 54 | jz .phaseerror 55 | 56 | 57 | ;al>2 : failed reserved 58 | STDCALL cswstr3,dumpstr 59 | clc 60 | mov eax,1 61 | jmp .done 62 | 63 | .commandpassed: 64 | STDCALL cswstr4,dumpstr 65 | stc 66 | mov eax,0 67 | jmp .done 68 | 69 | .commandfailed: 70 | STDCALL cswstr1,dumpstr 71 | clc 72 | mov eax,1 73 | jmp .done 74 | 75 | .phaseerror: 76 | STDCALL cswstr2,dumpstr 77 | clc 78 | mov eax,1 79 | 80 | .done: 81 | ret 82 | 83 | 84 | 85 | 86 | 87 | 88 | ;this function is currently not used as of Aug 2012 89 | ;but I think it should be 90 | ;**************************************************** 91 | ;CheckCSWSignatureTag 92 | ;check the CSW signature and tag 93 | ;the device should return this 94 | ;as the signature and tag of the CSW 95 | ;expectedCSW (defined in uhci.s) 96 | ;db 0x55,0x53,0x42,0x53,0xdd,0xcc,0xbb,0xaa 97 | ;on a failed transaction you may see something like this 98 | ;db ff ff ff ff ff ff ff ff 99 | ;input 100 | ;none 101 | ;return 102 | ;sets CF on success, clears CF on invalid Signature/Tag 103 | checkcsw db 'USB Status Transport invalid CSW Signature&Tag',0 104 | ;**************************************************** 105 | CheckCSWSignatureTag: 106 | 107 | mov esi,scsiCSW 108 | mov edi,expectedCSW 109 | mov ecx,8 110 | cld 111 | repe cmpsb 112 | je .done 113 | STDCALL checkcsw,dumpstr 114 | 115 | .done: 116 | ret 117 | 118 | 119 | -------------------------------------------------------------------------------- /usb/clearep.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/clearep.s 2 | 3 | 4 | ;code to conduct the Clear Feature ENDPOINT_HALT control transaction 5 | 6 | ;use this for flash drive bulkin or bulkout endpoints only, not control endpoint0 7 | 8 | 9 | ClearFeatureEndpointHaltRequest: 10 | db 0x2 ;bmRequestType=02=endpoint 11 | db 1 ;bRequest=01=CLEAR_FEATURE 12 | dw 0 ;wValue=00=Feature Selector ENDPOINT_HALT 13 | dw 0 ;wIndex = endpoint number 14 | dw 0 ;wLength=0 15 | 16 | 17 | 18 | 19 | cfstr1 db '********** Flash Clear Feature ENDPOINT_HALT COMMAND transport **********',0 20 | cfstr2 db '********** Flash Clear Feature ENDPOINT_HALT STATUS transport **********',0 21 | 22 | 23 | ;******************************************************** 24 | ;ClearFeatureEndpointHalt 25 | 26 | ;input:ax=endpoint number to clear 27 | ;return: eax=0 on success, 1 on error 28 | ;******************************************************** 29 | 30 | ClearFeatureEndpointHalt: 31 | 32 | ;write endpoint # into the request 33 | mov word [ClearFeatureEndpointHaltRequest+4],ax 34 | 35 | 36 | ;Command Transport 37 | ;******************** 38 | STDCALL cfstr1,dumpstr 39 | 40 | ;copy request to data buffer 0xb70000 41 | mov esi,ClearFeatureEndpointHaltRequest 42 | mov edi,0xb70000 43 | mov ecx,8 44 | call strncpy 45 | 46 | ;generate 1 usb Transfer Descriptor 47 | mov eax,8 ;Request is 8 bytes long 48 | mov ebx,2 ;PID = SETUP 49 | mov ecx,0 ;data toggle 50 | call generate_TD 51 | 52 | ;attach TD to queue head and run 53 | mov eax,FLASH_CONTROL_QH_NEXT_TD_PTR 54 | call ehci_run 55 | jnz near .error 56 | 57 | 58 | 59 | 60 | ;Data Transport 61 | ;***************** 62 | ;there is no data transport 63 | 64 | 65 | 66 | ;Status Transport 67 | ;******************* 68 | STDCALL cfstr2,dumpstr 69 | 70 | ;generate 1 usb Transfer Descriptor 71 | mov eax,0 ;qty bytes to transfer 72 | mov ebx,1 ;PID = IN 73 | mov ecx,1 ;data toggle 74 | call generate_TD 75 | 76 | ;attach TD to queue head and run 77 | mov eax,FLASH_CONTROL_QH_NEXT_TD_PTR 78 | call ehci_run 79 | jnz near .error 80 | 81 | 82 | 83 | 84 | .success: 85 | mov eax,0 86 | jmp .done 87 | .error: 88 | mov eax,1 89 | .done: 90 | ret 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /usb/error.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/error.s 2 | 3 | 4 | ;code to check for USBSTS transaction errors 5 | ;the ehci and uhci both have a bit in the status register USBSTS 6 | ;that is set if a transfer descriptor fails. 7 | ;this often happens during initflash 8 | ;the solution I have is to manually reinit the controller and 9 | ;run initflash a second time and then it always succeeds 10 | ;all this code does is check this error bit 11 | 12 | 13 | errorstr db 'USB Error Interrupt-TD has Failed-Reinit controller & Flash',0 14 | 15 | 16 | ;*********************************************************** 17 | ;ehciControllerError 18 | ;input:none 19 | ;return: ZF is set on success, clear on error 20 | ;*********************************************************** 21 | 22 | ehciControllerError: 23 | 24 | ;get the value of USBSTS status register for ehci 25 | mov esi,[EHCIOPERBASE] ;get start of oper reg 26 | mov eax,[esi+4] ;OperationalBase + 4 = USBSTS 27 | mov ebx,eax ;save copy 28 | 29 | ;the Error Interrupt is bit1 of USBSTS 30 | ;this bit is set if a TD has failed, often happens during initflash 31 | shr eax,1 32 | and eax,1 ;1AND1=1, 0AND1=0 33 | jz .done ;ZF is set on success, no TD error 34 | 35 | ;try to clear the error bit in USBSTS, not sure if this works 36 | STDCALL errorstr,putscroll 37 | or ebx,10b ;bit1 is R/WC so to clear it we write a 1 38 | mov [esi],ebx ;save USBSTS back with bit1 cleared 39 | or eax,1 ;clear ZF on error 40 | 41 | .done: 42 | ret 43 | 44 | 45 | 46 | 47 | ;*********************************************************** 48 | ;Aug 2012 I have updated ehciControllerError but not this one 49 | ;uhciControllerError 50 | ;input:none 51 | ;return: ZF is set on success, clear on error 52 | ;*********************************************************** 53 | 54 | uhciControllerError: 55 | 56 | mov dx,[UHCIBASEADD] 57 | add dx,2 58 | in ax,dx ;read in USBSTS 59 | 60 | shr eax,1 61 | and eax,1 62 | 63 | jz .done ;ZF is set on success, no TD error 64 | pushfd ;preserve flags 65 | STDCALL errorstr,putspause 66 | popfd 67 | 68 | .done: 69 | ret 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /usb/hubdesc.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/hubdesc.s 2 | 3 | 4 | ;hubGetHubDescriptor 5 | 6 | ;code to issue the usb HUB Descriptor Request 7 | ;the hub must first be "configured" before issueing this request 8 | 9 | 10 | 11 | 12 | HubDescriptorRequest: 13 | db 0xa0 ;bmRequestType for GetHubDescriptor 14 | db 6 ;bRequest=06=GET_DESCRIPTOR 15 | dw 0x2900 ;wValue=29 for HUB and 00 for index 16 | dw 0 ;wIndex 17 | dw 8 ;wLength=bytes data returned in data phase 18 | 19 | 20 | 21 | hubHDstr1 db '********** hub HUB Descriptor COMMAND Transport **********',0 22 | hubHDstr2 db '********** hub HUB Descriptor DATA Transport **********',0 23 | hubHDstr3 db '********** hub HUB Descriptor STATUS Transport **********',0 24 | hubHDstr4 db 'hub bNbrPorts qty downstream ports',0 25 | 26 | 27 | ;intel ehci with root hub VID=8086h, DID=1e2dh 28 | 29 | ;the first 8 bytes look like this 30 | ;09 29 06 09 00 32 00 00 31 | ;09=bDescLength 32 | ;29=bDescriptorType=HUB descriptor 33 | ;06=bNbrPorts, qty of downstream ports, note my asus laptop has only 3 ehci ports ! 34 | ;00 09=wHubCharacteristics (power switching, over current, TT think time, port indicators) 35 | ;32=bPwrOn2PwrGood 36 | ;00=bHubContrCurrent 37 | ;00=DeviceRemovable 38 | 39 | 40 | ;************************************************************ 41 | ;hubGetHubDescriptor 42 | ;control transfer code for the usb hub 43 | ;for use with ehci controller having root hub only 44 | ;input:none 45 | ;return:none 46 | ;************************************************************ 47 | 48 | GetHubDescriptor: 49 | 50 | 51 | ;Command Transport 52 | ;******************** 53 | STDCALL hubHDstr1,dumpstr 54 | 55 | ;copy request to data buffer 0xb70000 56 | mov esi,HubDescriptorRequest 57 | mov edi,0xb70000 58 | mov ecx,8 59 | call strncpy 60 | 61 | ;generate 1 usb Transfer Descriptor 62 | mov eax,8 ;Device Descriptor Request is 8 bytes long 63 | mov ebx,2 ;PID = SETUP 64 | mov ecx,0 ;data toggle 65 | call generate_TD 66 | 67 | ;attach TD to queue head and run 68 | mov eax,HUB_CONTROL_QH_NEXT_TD_PTR 69 | call ehci_run 70 | jnz near .error 71 | 72 | 73 | 74 | ;Data Transport 75 | ;***************** 76 | STDCALL hubHDstr2,dumpstr 77 | 78 | ;the descriptor length is variable 79 | ;you should request 8 bytes then examine the first byte bDescLength 80 | ;then request bDescLength to get the full descriptor 81 | ;all we are interested in here is the 3rd byte bNbrPorts 82 | 83 | ;generate 1 usb Transfer Descriptor 84 | mov eax,8 ;qty bytes to receive 85 | mov ebx,1 ;PID = IN 86 | mov ecx,1 ;data toggle 87 | call generate_TD 88 | 89 | ;attach TD to queue head and run 90 | mov eax,HUB_CONTROL_QH_NEXT_TD_PTR 91 | call ehci_run 92 | jnz near .error 93 | 94 | 95 | ;copy the Hub Descriptor bytes received to 0x6040 for permanent storage 96 | mov esi,0xb70000 97 | mov edi,0x6040 98 | mov ecx,8 99 | call strncpy 100 | 101 | ;dump the 8 bytes we got 102 | STDCALL 0x6040,8,dumpmem 103 | 104 | ;and dump the bNbrPorts (qty of downstream ports) 105 | mov al,[HUB_BQTYDOWNSTREAMPORTS] 106 | STDCALL hubHDstr4,2,dumpeax 107 | 108 | 109 | 110 | 111 | ;Status Transport 112 | ;******************* 113 | STDCALL hubHDstr3,dumpstr 114 | 115 | ;generate 1 usb Transfer Descriptor 116 | mov eax,0 ;qty bytes to transfer 117 | mov ebx,0 ;PID_OUT 118 | mov ecx,1 ;data toggle 119 | call generate_TD 120 | 121 | ;attach TD to queue head and run 122 | mov eax,HUB_CONTROL_QH_NEXT_TD_PTR 123 | call ehci_run 124 | jnz near .error 125 | 126 | 127 | 128 | 129 | .success: 130 | mov eax,0 131 | jmp .done 132 | .error: 133 | mov eax,1 134 | .done: 135 | ret 136 | 137 | 138 | -------------------------------------------------------------------------------- /usb/info.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/info.s 2 | 3 | 4 | ;getflashinfo 5 | ;gethubinfo 6 | 7 | 8 | ;kernel functions to copy data to userland pages for examination 9 | 10 | 11 | ;***************************************************************** 12 | ;getflashinfo 13 | ;this code copies kernel data that was saved during initflash 14 | ;to userland for examination. /apps/FlashInfo can 15 | ;display this information. We are talking about the flash drive 16 | ;device descriptors, endpoint descriptors, Interface and 17 | ;configuration descriptors, and the results from SCSI 18 | ;read capacity and inquiry 19 | ;input:edi=userland memory address to copy data to 20 | ; this should be in the same users page after user code 21 | ;return:none 22 | ;**************************************************************** 23 | 24 | getflashinfo: 25 | 26 | ;we copy kernel data from 0x5000->0x5224 27 | cld 28 | mov ecx,0x224 ;qty bytes2copy 29 | mov esi,0x5000 30 | ;edi is set by user 31 | rep movsb 32 | 33 | .done: 34 | ret 35 | 36 | 37 | 38 | ;gethubinfo copies the usb hub descriptors saved during inithub.s 39 | ;same inputs and same return 40 | gethubinfo: 41 | 42 | ;we copy kernel data from 0x6000->0x6048 43 | cld 44 | mov ecx,72 ;qty bytes2copy 45 | mov esi,0x6000 46 | ;edi is set by user 47 | rep movsb 48 | 49 | .done: 50 | ret 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /usb/inithub.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/inithub.s 2 | 3 | ;code to communicate with and configure the usb hub 4 | ;hubs can be internal "root" hubs or external devices 5 | ;these typically have 1 upstream port and multiple down stream ports 6 | ;the downstream ports allow you to plug in multiple usb devices 7 | 8 | ;this code was specifically developed on my asus laptop 9 | ;which has 2 ehci usb controllers each with a "root" hub 10 | ;VID=0x8086, DID=0x1e2d and 0x1e26 11 | ;in order to reset a downstream port of a hub 12 | ;you must first configure the device which means collecting and examining 13 | ;the various descriptors, then issue SetAddress and SetConfiguration for the hub 14 | ;then you can apply power to the ports and reset the ports 15 | ;using hub class commands (not ehci register memory maps) 16 | 17 | 18 | ; ------> Keyboard 19 | ; ************ ************** | 20 | ; * ehci * ----> * ROOT HUB * -------------> Flash 21 | ; ************ ************** | 22 | ; ------> Mouse 23 | 24 | 25 | hubstr0 db 'INIT ROOT HUB',0 26 | hubstr1 db 'hub-GetDeviceDescriptor',0 27 | hubstr2 db 'hub-GetConfigDescriptor 9 bytes',0 28 | hubstr3 db 'hub-GetConfigDescriptor full',0 29 | hubstr4 db 'error hub bInterfaceClass is not HUB_CLASSCODE',0 30 | hubstr5 db 'hub IN endpoint #',0 31 | hubstr6 db 'hub-GetHubDescriptor',0 32 | hubstr7 db 'hub-SetAddress',0 33 | hubstr8 db 'inithub-failed usb transaction',0 34 | hubstr9 db 'hub-SetConfiguration',0 35 | hubstr10 db 'hub putting power to all ports',0 36 | hubstr11 db 'success init usb root hub',0 37 | 38 | 39 | 40 | inithub: 41 | 42 | ;this function take no inputs and returns no values 43 | 44 | STDCALL hubstr0,dumpstr 45 | 46 | 47 | ;now you might ask how do we know that we are communicating with the hub ? 48 | ;well the root hub is the first device downstream from ehci 49 | ;we may have multiple things plugged into the downstream ports of the hub 50 | ;but these "things" are not "recognized" by ehci until we do a port reset 51 | ;at the end of initehci with hub we did a port reset of the hub "upstream" port 52 | 53 | 54 | ;hub Device Descriptor 55 | STDCALL hubstr1,putscroll 56 | call HubGetDeviceDescriptor 57 | 58 | 59 | 60 | ;hub Configuration Descriptor 9 bytes 61 | ;first we request the 9 byte Configuration Descriptor 62 | ;this will give us the BNUMINTERFACES and WTOTALLENGTH 63 | STDCALL hubstr2,putscroll 64 | mov edx,9 65 | call hubGetConfigDescriptor 66 | cmp eax,1 ;check for error 67 | jz near .error ;or tom reset upstream port 68 | 69 | 70 | ;hub Configuration Descriptor full 71 | ;now we get the configuration, interface and 72 | ;endpoint descriptors all in one shot 73 | ;the value of HUB_WTOTALLENGTH was determined 74 | ;after we received the 9 byte hub config descriptor 75 | STDCALL hubstr3,putscroll 76 | xor edx,edx 77 | ;note if you request the wrong number of bytes here 78 | ;your machine will triple fault :) 79 | mov dx,[HUB_WTOTALLENGTH] 80 | call hubGetConfigDescriptor 81 | cmp eax,1 ;check for error 82 | jz near .error ;or tom reset upstream port 83 | 84 | 85 | 86 | ;make sure bInterfaceClass is HUB_CLASSCODE 87 | cmp byte [HUB_BINTERFACECLASS],0x09 88 | jnz near .error1 89 | 90 | 91 | ;the first endpoint descriptor starts at 0x6032 92 | ;the bEndpointAddress=0x81 (for asus laptop) field is at 0x6034 93 | ;the 8 indicates IN endpoint, the 1 is the endpoint address 94 | xor eax,eax 95 | mov al,[0x6034] 96 | and al,1 ;mask off the 8 97 | mov [HUBINENDPOINT],al ;save the endpoint address to HUBEPIN (defined in usb.s) 98 | STDCALL hubstr5,2,dumpeax ;dump the endpoint # 99 | ;we need HUBEPIN after the hub is configured 100 | 101 | 102 | ;assign a unique address to the hub 103 | ;HUBADDRESS is defined in usb.s 104 | STDCALL hubstr7,putscroll 105 | STDCALL devstr4,dumpstr ;HUB 106 | 107 | mov eax,HUBADDRESS 108 | mov dword [qh_next_td_ptr], HUB_CONTROL_QH_NEXT_TD_PTR 109 | call SetAddress 110 | 111 | cmp eax,1 ;check for error 112 | jz near .error ;or tom reset upstream port 113 | 114 | 115 | 116 | ;modify QH to include hub address 117 | ;this code similar to initflash.s 118 | mov eax,HUB_CONTROL_QH 119 | mov ecx,0 ;still use endpoint 0 120 | mov ebx,HUBADDRESS 121 | call modify_ehci_qh 122 | 123 | 124 | 125 | ;set hub configuration 126 | STDCALL hubstr9,putscroll 127 | STDCALL devstr4,dumpstr ;HUB 128 | 129 | mov ax,[HUB_BCONFIGVALUE] 130 | mov dword [qh_next_td_ptr], HUB_CONTROL_QH_NEXT_TD_PTR 131 | call SetConfiguration 132 | 133 | cmp eax,1 ;check for error 134 | jz near .error 135 | 136 | 137 | ;at this point the hub is configured but the ports have NO power 138 | 139 | 140 | ;get the HUB descriptor 141 | ;this gives us the number of downstream ports on the device 142 | ;my asus laptop reports 6 ports but there are only 3 external physical 143 | STDCALL hubstr6,putscroll 144 | call GetHubDescriptor 145 | 146 | 147 | ;if you attempt HUbGetPortStatus at this point all you will get is 00 00 00 00 148 | 149 | 150 | ;apply power to all ports 151 | STDCALL hubstr10,putscroll 152 | movzx ecx,byte [HUB_BQTYDOWNSTREAMPORTS] 153 | .1: 154 | mov eax,ecx ;eax=hub port number 155 | call HubPortPower 156 | loop .1 157 | 158 | 159 | 160 | ;done inithub 161 | ;see initdevices with USBCONTROLLERTYPE == 2 for code continuation 162 | 163 | jmp .success 164 | 165 | .error: 166 | STDCALL hubstr8,putscroll 167 | mov eax,1 168 | jmp .done 169 | .error1: 170 | STDCALL hubstr4,putscroll 171 | mov eax,1 172 | jmp .done 173 | .success: 174 | STDCALL hubstr11,putscroll 175 | mov eax,0 176 | .done: 177 | ret 178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /usb/modesense.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/modesense.s 2 | 3 | ;for reference only, not assembled into tatos.img, out of date do not use 2012 4 | 5 | 6 | ;ModeSense 7 | ;this transaction returns 4 bytes of seemingly useless info 8 | ;but both Linux and Windows do this transaction during mounting 9 | ;it seems to be required for some devices to "wake up". 10 | 11 | ;Jan 2009: I have removed this call from mountpd because 12 | ;it caused a Lexar pen drive to barf on data transport 13 | ;my SimpleTech, Burton SledDrive and Toshiba pen drives 14 | ;all enumerate just fine without this command 15 | 16 | ;Sep 2009 the supporting functions have been removed 17 | ;this file is archive only 18 | 19 | 20 | align 0x10 21 | 22 | 23 | ;Command Block Wrapper for SCSI ModeSense(6) (31 bytes) 24 | ModeSenseRequest: 25 | dd 0x43425355 ;dCBWSignature 26 | dd 0xaabbccdd ;dCBWTag (just make it up) 27 | dd 4 ;dCBWDataTransferLength (during tdData) 28 | db 0x80 ;bmCBWFlags (tdData direction 0x80=IN 00=OUT) 29 | db 0 ;bCBWLun 30 | db 6 ;bCBWCBLength, ModeSense6 is a 6 byte command 31 | ;CBWCB (16 bytes) see the SCSI ModeSense(6) Command 32 | db 0x1a ;SCSI operation code for ModeSense(6) 33 | db 0 ;SCSI reserved 34 | db 0x3f ;SCSI page code (3f=return ALL pages) 35 | db 0 ;SCSI Reserved 36 | db 192 ;SCSI allocation length ??? 37 | db 0 ;SCSI Control 38 | times 10 db 0 ;USBmass CBWCB must be 16 bytes long 39 | 40 | 41 | 42 | ;THIS CODE IS NOT UP TO DATE AS OF NOV 2009 AND WILL NOT WORK 43 | ;FOR HISTORICAL REFERENCE ONLY 44 | 45 | ModeSense: 46 | 47 | push mpdstr33 48 | call [PUTSCROLL] 49 | 50 | 51 | push ModeSenseRequest 52 | push 0x5300 ;device returns data transport here 53 | push 4 ;qty bytes returned by device in data transport 54 | call buildSCSItransaction 55 | 56 | mov edi,BULKQUEUEHEAD 57 | call runtransaction 58 | jc .done ;serious error 59 | 60 | call CheckCSWstatus 61 | jc .done ;command passed 62 | 63 | .done: 64 | ret 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /usb/queuehead.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/queuehead.s 2 | 3 | 4 | ;code to modify an ehci queue head to insert the address and endpoint num 5 | 6 | 7 | ;note we are modifying the QH "on the fly" without shutting down the 8 | ;asynch list or first removing the QH from the list 9 | ;see the ehci spec for "doorbell" and "handshake" discussions about this 10 | ;we could have some bad side affects since the ehci maintains a cache 11 | ;for now we have not seen a problem 12 | 13 | 14 | ;************************************************************** 15 | ;modify_ehci_qh 16 | ;the 2nd dword of the ehci QH contains the endpoint and address 17 | ;input: eax=address of queue head to modify 18 | ; ebx=unique usb device address that we assign (see usb.s) 19 | ; ecx=endpoint number (read from 3rd byte of endpoint descriptor) 20 | ;return: 21 | ;************************************************************** 22 | 23 | modify_ehci_qh: 24 | 25 | mov edx,[eax+4] ;read the 2nd dword of QH 26 | or edx,ebx ;set new address 27 | shl ecx,8 ;shift the endpoint # 28 | or edx,ecx ;set new endpoint # 29 | mov [eax+4],edx ;save the QH 2nd dword 30 | 31 | ret 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /usb/saveEP.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/saveepnum.s 2 | 3 | ;****************************************************** 4 | ;SaveEPnum 5 | 6 | ;input 7 | ;al=bEndpointAddress (3rd byte of Endpoint Descriptor) 8 | 9 | ;result 10 | ;extracts the endpoint number from bEndpointAddress 11 | ;and saves to either EPIN or EPOUT as appropriate 12 | ;0x81 indicates an IN endpoint number=1 13 | ;0x02 indicates an OUT endpoint number=2 14 | 15 | saveEPstr1 db 'BULKEPOUT',0 16 | saveEPstr2 db 'BULKEPIN',0 17 | ;****************************************************** 18 | 19 | 20 | 21 | SaveEPnum: 22 | 23 | ;check if bit7 is set indicating IN endpoint 24 | bt eax,7 25 | jc .INendpoint 26 | 27 | ;OUT endpoint 28 | ;************* 29 | and al,0xf ;mask off the low nibble EP number 30 | mov [BULKOUTENDPOINT],al ;save EPOUT 31 | and eax,0xff ;mask off upper bits 32 | STDCALL saveEPstr1,2,dumpeax 33 | jmp .done 34 | 35 | .INendpoint: 36 | and al,0xf 37 | mov [BULKINENDPOINT],al ;save EPIN 38 | and eax,0xff 39 | STDCALL saveEPstr2,2,dumpeax 40 | 41 | .done: 42 | ret 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /usb/showehciroothubports.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/showehciroothubports.s 2 | 3 | 4 | ;code to build list control strings to show the bitfields of the 5 | ;downstream ports of a root hub on my asus laptop 6 | ;we examine dword [HUB_QTYDOWNSTREAMPORTS] saved from the config descriptor 7 | 8 | ;you must first init the ehci and root hub before executing this function 9 | ;strings are written to LISTCTRLBUF and spaced 0x100 bytes apart 10 | 11 | ;note the bits 9,10 for detecting the speed of the device is only relavant 12 | ;if there is in fact a device attached see bit0 13 | 14 | 15 | hpstr0 db 'EHCI ROOT HUB DOWNSTREAM PORT STATUS wPortStatus',0 16 | hpstra db '********** port number for wPortStatus **********',0 17 | hpstr1 db 'current connect status 1=device present on port',0 18 | hpstr2 db 'port enabled/disabled 1=enabled',0 19 | hpstr3 db 'suspend 1=suspended or resuming',0 20 | hpstr4 db 'overcurrent 1=overcurrent condition exists',0 21 | hpstr5 db 'reset 1=reset signalling asserted',0 22 | hpstr6 db 'port power 1=not powered OFF state',0 23 | hpstr7 db 'low speed device attached 0=full or hi speed 1=low speed',0 24 | hpstr8 db 'hi speed device attached 0=full speed 1= hi speed',0 25 | hpstr9 db 'Please wait - building list control strings',0 26 | hpstr10 db 'HUB_BQTYDOWNSTREAMPORTS',0 27 | 28 | 29 | 30 | 31 | showehciroothubports: 32 | 33 | 34 | ;we are going to clear the screen and show the program title immediately 35 | ;because it takes more than 1 second to build and display the list 36 | ;control strings, and we want the user to feel like something is happening 37 | call backbufclear 38 | 39 | ;show the program title 40 | STDCALL FONT01,0,20,hpstr0,0xefff,puts 41 | 42 | ;show the qty of hub down stream ports 43 | movzx eax,byte [HUB_BQTYDOWNSTREAMPORTS] 44 | STDCALL 0,40,0xefff,hpstr10,puteaxstr 45 | 46 | ;message to tell user we are building list control strings 47 | ;this string will get overwritten by the list control 48 | STDCALL FONT01,0,100,hpstr9,0xefff,puts 49 | 50 | ;make it show up 51 | call swapbuf 52 | 53 | 54 | 55 | ;now prepare to build list control strings 56 | 57 | ;edx holds address in memory to store list control string 58 | ;all addresses are spaced out 0x100 59 | ;ecx must be preserved 60 | mov edx,LISTCTRLBUF 61 | 62 | ;loop number 63 | ;ecx= portnum (1,2,3, up to byte [HUB_BQTYDOWNSTREAMPORTS]) 64 | ;ecx must be preserved in this loop 65 | mov ecx,1 66 | 67 | ;copy title string 68 | push hpstr0 69 | push edx 70 | call strcpy2 71 | add edx,0x100 ;string spacing in list control buffer 72 | 73 | 74 | 75 | 76 | .1: ;top of loop 77 | ;9 strings are generated for each hub port 78 | ;this loop actually takes more than 1 second to execute 79 | 80 | ;get status of port 81 | mov eax,ecx ;eax=portnum 1,2,3... 82 | call HubGetPortStatus ;ebx = dword [hubportstatus] 83 | 84 | 85 | ;display a string to identify the port number 86 | push hpstra 87 | mov eax,ecx ;eax=port number 88 | push edx ;destination memory address to write string 89 | call eaxstr 90 | add edx,0x100 91 | 92 | ;Current Connect Status 93 | mov eax,ebx 94 | and eax,1 95 | STDCALL hpstr1,edx,eaxstr 96 | add edx,0x100 97 | 98 | ;Port Enabled/Disabled 99 | mov eax,[hubportstatus] 100 | shr eax,1 101 | and eax,1 102 | STDCALL hpstr2,edx,eaxstr 103 | add edx,0x100 104 | 105 | ;suspend 106 | mov eax,[hubportstatus] 107 | shr eax,2 108 | and eax,1 109 | STDCALL hpstr3,edx,eaxstr 110 | add edx,0x100 111 | 112 | ;over-current 113 | mov eax,[hubportstatus] 114 | shr eax,3 115 | and eax,1 116 | STDCALL hpstr4,edx,eaxstr 117 | add edx,0x100 118 | 119 | ;reset 120 | mov eax,[hubportstatus] 121 | shr eax,4 122 | and eax,1 123 | STDCALL hpstr5,edx,eaxstr 124 | add edx,0x100 125 | 126 | ;port power 127 | mov eax,[hubportstatus] 128 | shr eax,8 129 | and eax,1 130 | STDCALL hpstr6,edx,eaxstr 131 | add edx,0x100 132 | 133 | ;low speed device 134 | mov eax,[hubportstatus] 135 | shr eax,9 136 | and eax,1 137 | STDCALL hpstr7,edx,eaxstr 138 | add edx,0x100 139 | 140 | ;hi speed device 141 | mov eax,[hubportstatus] 142 | shr eax,10 143 | and eax,1 144 | STDCALL hpstr8,edx,eaxstr 145 | add edx,0x100 146 | 147 | 148 | ;go back and build strings for the next port 149 | add ecx,1 150 | cmp cl,[HUB_BQTYDOWNSTREAMPORTS] 151 | jbe .1 152 | 153 | 154 | 155 | ;now setup the list control 156 | ;the qty of strings generated was [HUB_QTYDOWNSTREAMPORTS]*9 + 1 157 | xor edx,edx 158 | mov eax,9 159 | movzx ebx,byte[HUB_BQTYDOWNSTREAMPORTS] 160 | mul ebx ;result is in edx:eax 161 | add eax,1 ;eax=qty strings 162 | mov ebx,100 ;Ylocation of top of listcontrol 163 | call ListControlInit 164 | 165 | 166 | 167 | .appmainloop: 168 | 169 | call ListControlPaint 170 | 171 | STDCALL FONT01,0,20,hpstr0,0xefff,puts 172 | 173 | call swapbuf 174 | call getc ;ListControlKeydown is called within getc 175 | 176 | cmp al,ESCAPE ;to quit 177 | jnz .appmainloop 178 | 179 | ret 180 | 181 | 182 | 183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /usb/status.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/comstat.s 2 | 3 | 4 | ;functions to access the usb command and status registers 5 | ;there are seperate functions for uhci and ehci 6 | 7 | 8 | ;********************************************** 9 | ;uhci_command 10 | ;dump the value of the command register 11 | ;a value of 0x81 is normal after controller reset 12 | 13 | ;input:none 14 | ;return 15 | ;zf set on success, clear on error 16 | 17 | ;local 18 | comregstr1 db 'UHCI USBCMD command register',0 19 | comregstr2 db 'Max Packet',0 20 | comregstr3 db 'CF flag',0 21 | comregstr4 db 'debug',0 22 | comregstr5 db 'global resume',0 23 | comregstr6 db 'global suspend',0 24 | comregstr7 db 'global reset',0 25 | comregstr8 db 'HC reset',0 26 | comregstr9 db 'Run/Stop',0 27 | ;*********************************************** 28 | 29 | uhci_command: 30 | 31 | pushad 32 | 33 | mov dx,[UHCIBASEADD] 34 | in ax,dx 35 | and eax,0xffff 36 | STDCALL comregstr1,0,dumpeax 37 | 38 | %if VERBOSEDUMP 39 | 40 | STDCALL comregstr2, 7,1,dumpbitfield ;MaxPacket 41 | STDCALL comregstr3, 6,1,dumpbitfield ;CF flag 42 | STDCALL comregstr4, 5,1,dumpbitfield ;debug 43 | STDCALL comregstr5, 4,1,dumpbitfield ;global resume 44 | STDCALL comregstr6, 3,1,dumpbitfield ;global suspend 45 | STDCALL comregstr7, 2,1,dumpbitfield ;global reset 46 | STDCALL comregstr8, 1,1,dumpbitfield ;HC reset 47 | STDCALL comregstr9, 0,1,dumpbitfield ;run/stop 48 | 49 | %endif 50 | 51 | .done: 52 | popad 53 | ret 54 | 55 | 56 | 57 | ;********************************************** 58 | ;ehci_command 59 | ;dump the value of the command register 60 | ;input:none 61 | ;return 62 | ;zf set on success, clear on error 63 | ;_ecomregstr1 db 'EHCI USBCMD command register',0 64 | ;*********************************************** 65 | 66 | ;_ehci_command: 67 | 68 | ; pushad 69 | 70 | ; mov esi,[EHCIOPERBASE] ;get start of operational registers 71 | ; mov eax,[esi] ;USBCMD is at opbar+0 72 | ; STDCALL ecomregstr1,0,dumpeax 73 | 74 | ;.done: 75 | ; popad 76 | ; ret 77 | 78 | 79 | 80 | 81 | ;********************************************** 82 | ;uhci_status 83 | ;dump the USBSTS status register 84 | ;this function may be called from the shell 85 | 86 | ;ax=00 is a normal condition 87 | ;ax=0x20 means controller is halted 88 | ;ax=0x10 means controller process error 89 | ;ax=8 means host system error 90 | 91 | ;input:none 92 | ;return:zf set on success, clear on error 93 | 94 | uhcistatstr1 db 'UHCI USBSTS status register',0 95 | uhcistatstr5 db 'Interrupt on Async Advance (0=default)',0 96 | uhcistatstr6 db 'Host System Error',0 97 | uhcistatstr9 db 'USB Error Interrupt',0 98 | uhcistatstr10 db 'USB Interrupt',0 99 | uhcistatstr11 db 'Process Error',0 100 | uhcistatstr12 db 'Resume Detect',0 101 | ;********************************************* 102 | 103 | uhci_status: 104 | 105 | mov dx,[UHCIBASEADD] 106 | add dx,0x02 107 | in ax,dx 108 | and eax,0xffff 109 | mov ebx,eax ;copy 110 | STDCALL uhcistatstr1,0,dumpeax 111 | 112 | STDCALL uhcistatstr5, 5,1,dumpbitfield ;halted 113 | STDCALL uhcistatstr11, 4,1,dumpbitfield ;Process error 114 | STDCALL uhcistatstr6, 3,1,dumpbitfield ;host system error 115 | STDCALL uhcistatstr12, 2,1,dumpbitfield ;resume detect 116 | STDCALL uhcistatstr9, 1,1,dumpbitfield ;Error Interrupt 117 | STDCALL uhcistatstr10, 0,1,dumpbitfield ;Interrupt 118 | 119 | ret 120 | 121 | 122 | 123 | 124 | ;this is just a dummy stub routine 125 | ;uhci_status and ehci_status are pointers to functions called by initflash 126 | ;but ehci_status is actually never used 127 | ;its been replaced by show_ehci_status called from the shell 128 | ;eventually we will obsolete this alltogether 129 | ehci_status: 130 | ret 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /usb/testunit.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/testunit.s 2 | 3 | 4 | ;SCSI TestUnitReady command for usb flash drive 5 | 6 | ;on my pen drive the CSW status is usually 01 fail 7 | ;but if I run the transaction a 2nd time it passes 8 | ;I found a couple other pen drives need RequestSense called 9 | ;after TestUnitReady fails so we now automatically do 10 | ;TestUnitReady->RequestSense->TestUnitReady->RequestSense 11 | 12 | 13 | TestUnitReadyRequest: 14 | dd 0x43425355 ;dCBWSignature 15 | dd 0xaabbccdd ;dCBWTag 16 | dd 0 ;dCBWDataTransferLength 17 | db 0 ;bmCBWFlags 0x80=Device2Host, 00=Host2Device 18 | db 0 ;bCBWLun 19 | db 6 ;bCBWCBLength 20 | ;CBWCB refer to spc2r20.pdf from t10 21 | db 0 ;operation code for TEST UNIT READY 22 | db 0 ;reserved 23 | db 0 ;reserved 24 | db 0 ;reserved 25 | db 0 ;reserved 26 | db 0 ;control ?? whats this 27 | times 10 db 0 ;pad out 28 | 29 | 30 | 31 | %if USBCONTROLLERTYPE == 0 ;uhci 32 | 33 | FlashTUR_structTD_command: 34 | dd TestUnitReadyRequest ;BufferPointer 35 | dd 31 ;all scsi structures are 31 bytes 36 | dd FULLSPEED 37 | dd PID_OUT 38 | dd bulktoggleout ;Address of toggle 39 | dd BULKOUTENDPOINT ;Address of endpoint 40 | dd FLASHDRIVEADDRESS ;device address on bus 41 | 42 | %endif 43 | 44 | 45 | 46 | 47 | ;***************************************************************** 48 | ;TestUnitReady 49 | ;input:eax=value of data toggle for STATUS transport (0 or 1) for ehci 50 | ;return: success eax=0, error eax=1 51 | status_toggle dd 0 52 | ;***************************************************************** 53 | 54 | TestUnitReady: 55 | 56 | ;save for later 57 | mov dword [status_toggle],eax 58 | 59 | 60 | STDCALL devstr1,dumpstr ;FLASH 61 | 62 | 63 | ;Command Transport 64 | ;******************** 65 | STDCALL transtr10a,dumpstr 66 | 67 | %if USBCONTROLLERTYPE == 0 ;uhci 68 | push FlashTUR_structTD_command 69 | call uhci_prepareTDchain 70 | call uhci_runTDchain 71 | jnz .error 72 | %endif 73 | 74 | %if (USBCONTROLLERTYPE == 1 || USBCONTROLLERTYPE == 2 || USBCONTROLLERTYPE == 3) 75 | ;copy request to data buffer 0xb70000 76 | mov esi,TestUnitReadyRequest 77 | mov edi,0xb70000 78 | mov ecx,31 79 | call strncpy 80 | 81 | ;generate 1 usb Transfer Descriptor 82 | mov eax,31 ;all scsi requests are 31 bytes long 83 | mov ebx,0 ;PID = OUT (SETUP was for control xfer only) 84 | mov ecx,1 ;data toggle (Inquiry/ReadCapacity Command OUT was 0 so we use 1) 85 | call generate_TD 86 | 87 | ;attach TD to the proper queue head and run 88 | ;endpoint and address are in the QH 89 | mov eax,FLASH_BULKOUT_QH_NEXT_TD_PTR 90 | call ehci_run 91 | jnz near .error 92 | %endif 93 | 94 | 95 | 96 | 97 | ;Data Transport 98 | ;***************** 99 | ;there is no data transport 100 | 101 | 102 | 103 | ;Status Transport 104 | ;******************* 105 | STDCALL transtr10c,dumpstr 106 | 107 | %if USBCONTROLLERTYPE == 0 ;uhci 108 | push SCSI_structTD_status 109 | call uhci_prepareTDchain 110 | call uhci_runTDchain 111 | jnz near .error 112 | 113 | mov esi,scsiCSW 114 | call CheckCSWstatus 115 | jnc .error 116 | %endif 117 | 118 | %if (USBCONTROLLERTYPE == 1 || USBCONTROLLERTYPE == 2 || USBCONTROLLERTYPE == 3) 119 | ;generate 1 usb Transfer Descriptor 120 | mov eax,13 ;qty bytes to receive 121 | mov ebx,1 ;PID IN 122 | mov ecx,[status_toggle] 123 | call generate_TD 124 | 125 | ;attach TD to queue head and run 126 | mov eax,FLASH_BULKIN_QH_NEXT_TD_PTR 127 | call ehci_run 128 | jnz near .error 129 | 130 | mov esi,0xb70000 131 | call CheckCSWstatus 132 | jnc .error 133 | %endif 134 | 135 | 136 | .success: 137 | mov eax,0 138 | jmp .done 139 | .error: 140 | mov eax,1 141 | .done: 142 | ret 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /usb/usbdump.s: -------------------------------------------------------------------------------- 1 | ;tatOS/usb/usbdump.s 2 | 3 | 4 | ;functions to write to the dump various interesting usb stuff 5 | 6 | 7 | ;dumpehciTDs 8 | ;dumpQH 9 | 10 | 11 | 12 | 13 | ;********************************************************* 14 | ;dumpehciTDs 15 | ;this function dumps a chain of ehci transfer descriptors 16 | ;each ehci TD is 8 dwords in memory plus 4 more dwords for 64 bit addressing 17 | ;TD's are spaced out every 64 bytes 18 | ;use this function after a usb transaction 19 | ;to see how the ehci controller has modified your TDs 20 | ;see /usb/prepareTD-ehci.s for more details 21 | 22 | ;input: none (all TD's are written to fixed memory 0xd60000) 23 | ; global dword [chainqtyTDs] 24 | ;return:none 25 | 26 | ehciTDstr0 db 'dumping ehci chain of qTD after run',0 27 | ehciTDstr1 db 'after run: dword1 next qTD pointer',0 28 | ehciTDstr2 db 'after run: dword2 alternate next qTD pointer',0 29 | ehciTDstr3 db 'after run: dword3 packet header',0 30 | ehciTDstr4 db 'after run: dword4 buffer pointer page0',0 31 | ehciTDstr5 db 'after run: dword5 buffer pointer page1',0 32 | ehciTDstr6 db 'after run: dword6 buffer pointer page2',0 33 | ehciTDstr7 db 'after run: dword7 buffer pointer page3',0 34 | ehciTDstr8 db 'after run: dword8 buffer pointer page4',0 35 | ;********************************************************* 36 | 37 | dumpehciTDs: 38 | 39 | STDCALL ehciTDstr0,dumpstr 40 | 41 | mov ebx,0xd60000 ;load starting address of ehci TD's in memory 42 | 43 | ;[chainqtyTDs] is a global set by prepareTD_ehci.s 44 | ;ecx is our loop counter 45 | mov ecx,[chainqtyTDs] 46 | 47 | .1: 48 | ;dword 1 Next qTD Pointer 49 | ; mov eax,[ebx] 50 | ; STDCALL ehciTDstr1,0,dumpeax 51 | 52 | ;dword 2 Alternate Next qTD Pointer 53 | ; mov eax,[ebx+4] 54 | ; STDCALL ehciTDstr2,0,dumpeax 55 | 56 | ;dword 3 USB Packet Header 57 | mov eax,[ebx+8] 58 | STDCALL ehciTDstr3,0,dumpeax 59 | 60 | ;dword 4 Buffer Pointer page 0 61 | ; mov eax,[ebx+12] 62 | ; STDCALL ehciTDstr4,0,dumpeax 63 | 64 | ;dword 5 Buffer Pointer page 1 65 | ; mov eax,[ebx+16] 66 | ; STDCALL ehciTDstr5,0,dumpeax 67 | 68 | ;dword 6 Buffer Pointer page 2 69 | ; mov eax,[ebx+20] 70 | ; STDCALL ehciTDstr6,0,dumpeax 71 | 72 | ;dword 7 Buffer Pointer page 3 73 | ; mov eax,[ebx+24] 74 | ; STDCALL ehciTDstr7,0,dumpeax 75 | 76 | ;dword 8 Buffer Pointer page 4 77 | ; mov eax,[ebx+28] 78 | ; STDCALL ehciTDstr8,0,dumpeax 79 | 80 | add ebx,64 ;get address of start of next TD 81 | dec ecx ;dec qty of TD's dumped 82 | jnz .1 83 | 84 | ret 85 | 86 | 87 | 88 | ;************************************************ 89 | ;dumpQH 90 | ;dump a queue head 91 | ;each QH is 12 dwords 92 | ;the overlay area starts after the first 3 dwords 93 | ;the ehci may overwrite/modify portions of the overlay 94 | ;input:esi=address of QH 95 | ; valid addresses are: 96 | ; FLASH_CONTROL_QH 97 | ; FLASH_BULKIN_QH 98 | ; FLASH_BULKOUT_QH 99 | ; HUB_CONTROL_QH 100 | ;return:none 101 | 102 | qhstr1 db 'dumping ehci queue head QH',0 103 | qhstr2 db 'QH horizontal link pointer',0 104 | qhstr3 db 'QH endpoint characteristics',0 105 | qhstr4 db 'QH endpoint capabilities',0 106 | qhstr5 db 'QH current qTD pointer',0 107 | qhstr6 db 'QH next qTD pointer',0 108 | qhstr7 db 'QH alternate next qTD pointer',0 109 | qhstr8 db 'QH packet header',0 110 | qhstr9 db 'QH buffer pointer page0',0 111 | qhstr10 db 'QH buffer pointer page1',0 112 | qhstr11 db 'QH buffer pointer page2',0 113 | qhstr12 db 'QH buffer pointer page3',0 114 | qhstr13 db 'QH buffer pointer page4',0 115 | 116 | ;********************************************** 117 | 118 | dumpQH: 119 | 120 | STDCALL qhstr1,dumpstr 121 | 122 | ;QH horizontal link pointer 123 | mov eax,[esi] 124 | STDCALL qhstr2,0,dumpeax 125 | 126 | ;QH endpoint characteristics 127 | mov eax,[esi+4] 128 | STDCALL qhstr3,0,dumpeax 129 | 130 | ;QH endpoint capabilities 131 | mov eax,[esi+8] 132 | STDCALL qhstr4,0,dumpeax 133 | 134 | 135 | ;now starts the QH "Transfer Overlay" area 136 | ;these dwords represent a transaction working space for ehci 137 | 138 | 139 | ;QH Current qTD pointer 140 | mov eax,[esi+12] 141 | STDCALL qhstr5,0,dumpeax 142 | 143 | ;QH next qTD Pointer 144 | mov eax,[esi+16] 145 | STDCALL qhstr6,0,dumpeax 146 | 147 | ;QH alternate next qTD pointer 148 | mov eax,[esi+20] 149 | STDCALL qhstr7,0,dumpeax 150 | 151 | ;QH packet header 152 | mov eax,[esi+24] 153 | STDCALL qhstr8,0,dumpeax 154 | 155 | ;QH buffer pointer page 0, dword8 156 | mov eax,[esi+28] 157 | STDCALL qhstr9,0,dumpeax 158 | 159 | ;QH buffer pointer page 1, dword9 160 | mov eax,[esi+32] 161 | STDCALL qhstr10,0,dumpeax 162 | 163 | ;QH buffer pointer page 2, dword10 164 | mov eax,[esi+36] 165 | STDCALL qhstr11,0,dumpeax 166 | 167 | ;QH buffer pointer page 3, dword11 168 | mov eax,[esi+40] 169 | STDCALL qhstr12,0,dumpeax 170 | 171 | ;QH buffer pointer page 4, dword12 172 | mov eax,[esi+44] 173 | STDCALL qhstr13,0,dumpeax 174 | 175 | ret 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /usb/usberror: -------------------------------------------------------------------------------- 1 | 2 | USBERROR codes: 3 | currently the dword at 0x548 is reserved for this 4 | any usb transaction that generates an error will write 5 | the error code to 0x548 6 | 7 | 8 | 0=no error, success 9 | 1=ReadCommandRegister failed 10 | 2=ReadStatusRegister failed 11 | 3=ReadPort0 failed 12 | 4=runtd packet still active, failed to retire 13 | 5=command transport numbytes transferred failed 14 | 6=data packets still active 15 | 7=status transport numbytes transferred failed 16 | 8=invalid CSW 17 | 18 | The following are the Status codes (2nd dword of td) 19 | The host controller sets these bits on error 20 | see run.s 21 | 9=packet still Active (bit23) 22 | 10=stalled, serious error (bit22) 23 | 11=Data buffer error (bit21) 24 | 12=Babble detected (bit20) 25 | 13=NAK received (bit19) 26 | 14=CRC/TimeOut error (bit18) 27 | 15=Bitstuff error (bit17) 28 | 29 | 30 | 31 | 32 | --------------------------------------------------------------------------------