Advertisement
Guest User

dsbios source code (for sanyo mbc-55x)

a guest
Dec 27th, 2012
493
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ***** CUT HERE ***** BEGIN FILE build.sh
  2.  
  3. #!/bin/bash
  4. nasm -f bin -o dsbios.com dsbios.asm
  5. upx --brute --8086 dsbios.com         #optional
  6.  
  7.  
  8. ***** CUT HERE ***** BEGIN FILE cga.asm
  9.  
  10. ;Halfassed handling of a true hardware CGA card
  11.  
  12. CGA:
  13. .Init:
  14.     ;Input:  CS=BIOS_SEG
  15.     ;Destroys ax, dx, si, di
  16.     mov si,CGA.profile25x80
  17.     call CRTC_LoadProfile.CGA
  18.     xor si,si
  19.     call CRTC_SetDisplayAddress
  20.     mov al,0x2d
  21.     mov dl,0xd8 ;dh already = 0x3
  22.     out dx,al ;set mode
  23.     inc dx
  24.     xor al,al ;set another mode
  25.     out dx,al
  26.     ret
  27.  
  28.  
  29. .modeTable:
  30. ;CRTC mode parameters for CGA
  31.     db      0x38,0x28,0x2D,0x0A,0x1F,6,0x19       ; Mode 0,1: 40x25
  32.     db      0x1C,2,7,6,7
  33.     db      0,0,0,0
  34.  
  35. .profile25x80:
  36.     db      0x71,0x50,0x5A,0x0A,0x1F,6,0x19       ; Mode 2,3: 80x25
  37.     db      0x1C,2,7,6,7
  38.     db      0,0,0,0
  39.  
  40.     db      0x38,0x28,0x2D,0x0A,0x7F,6,0x64       ; Mode 4-6: Graphics
  41.     db      0x70,2,1,6,7
  42.     db      0,0,0,0
  43.  
  44.     ;the fourth mode string is only for MDA, not CGA
  45.     times 16 db 0 ;...so dsBIOS leaves it zero
  46.  
  47. ;video memory page size for those crtc init values
  48. .vidMem:
  49.     dw      0x0800                           ; Regen len, 40 x 25
  50.     dw      0x1000                           ;            80 x 25
  51.     dw      0x4000                           ;            GRAPHIX
  52.     dw      0x4000
  53.  
  54. ;max columns for each mode
  55. .maxCols:
  56.     db      0x28,0x28,0x50,0x50,0x28,0x28,0x50,0x50 ; Maximum columns
  57.  
  58. .modeBytes:
  59.     db      2Ch,28h,2Dh,29h,2Ah,2Eh,1Eh,00h ; Table of mode sets
  60.  
  61. ;TABMUL  db      00h,00h,10h,10h,20h,20h,20h,30h
  62.  
  63. ***** CUT HERE ***** BEGIN FILE crtc.asm
  64.  
  65. ;FIXME:  Assumes BIOS_CODE_SEG = BIOS_DATA_SEG!
  66.  
  67. CRTC_LoadProfile:
  68. .CGA:
  69.     ;  Input:  DS:SI = address of config buffer
  70.                ;(12 bytes) - Config data for CRTC
  71.                ;geometry info is automatically extracted and set up
  72.     ; Output:  SI is incremented by 12
  73.     ;Trashed:  AX, DX, DI
  74.     mov dx,0x3d4 ;CGA address
  75.     mov di,0x3d5 ;CGA data
  76.     mov al,[si+6] ;get rows
  77.     jmp short CRTC_LoadProfile.SetupRowsCols
  78.  
  79. .Sanyo:
  80.     ;  Input:  DS:SI = address of config buffer
  81.                ;(10 bytes) - Config data for CRTC
  82.                ;geometry info is automatically extracted and set up
  83.     ; Output:  SI is incremented by 12
  84.     ;Trashed:  AX, DX, DI
  85.     mov dx,0x30 ;CRTC address port
  86.     mov di,0x32 ;CRTC data port
  87.     mov al,[si+6] ;get # rows*2
  88.     shr ax,1      ;divide by 2 (reg 6 has 4 scanline rows, chars are 8)
  89.  
  90.     ;Routines are chained, DO NOT insert any code here
  91. .SetupRowsCols:
  92.     dec ax        ;subtract 1 (it's zero based)
  93.     mov [BV.ScreenRows],al
  94.  
  95.     ;Routines are chained, DO NOT insert any code here
  96. .SetupCols:
  97.     ;  Input:  DS:SI = address of config buffer
  98.                ;(12 or 10 bytes depending if CGA) - Config data for CRTC
  99.                ;geometry info is automatically extracted and set up
  100.     ;          DX = CRTC Address port
  101.     ;          DI = CRTC Data port
  102.     ; Output:  SI is incremented by 12
  103.     ;Trashed:  AX
  104.     mov al,[si+1] ;get # columns
  105.     cbw
  106.     cs mov [BV.ScreenCols],ax
  107. NoSetup:
  108.     push bx
  109.     cld
  110.     mov al,0
  111. .lp out dx,al   ;write config byte number
  112.     xchg ax,bx
  113.     xchg dx,di
  114.     lodsb
  115.     out dx,al   ;write config byte
  116.     xchg dx,di
  117.     xchg ax,bx
  118.     inc ax
  119.     cmp al,12   ;written 12 bytes?
  120.     jb .lp
  121.     pop bx
  122.     ret
  123.  
  124.  
  125. CRTC_SetDisplayAddress:
  126.     ;  Input:  SI = Display offset
  127.     ;          DX = CRTC Address port
  128.     ;          DI = CRTC Data port
  129.     ;Trashed:  AL
  130.     mov al,13
  131. .do2nd:
  132.     out dx,al
  133.     xchg dx,di
  134.     xchg ax,si
  135.     out dx,al
  136.     xchg ah,al
  137.     xchg ax,si
  138.     xchg dx,di
  139.     dec ax
  140.     jp .do2nd ;going to hell for this one
  141.     ret
  142.  
  143. CRTC_GetDisplayAddress:
  144.     ;  Input:  DX = CRTC Address port
  145.     ;          DI = CRTC Data port
  146.     ; Output:  SI = Display offset
  147.     ;Trashed:  AL
  148.     mov al,13
  149. .do2nd:
  150.     out dx,al
  151.     xchg dx,di
  152.     xchg ax,si
  153.     in al,dx
  154.     xchg ah,al
  155.     xchg ax,si
  156.     xchg dx,di
  157.     dec ax
  158.     jp .do2nd ;window seat please
  159.     ret
  160.  
  161.  
  162. ;Register Index/Register Name
  163. ;  0  Horizontal Total
  164. ;  1  Horizontal Displayed
  165. ;  2  Horizontal Sync Position
  166. ;  3  Horizontal and Vertical Sync Widths
  167. ;     (Hitachi 46505 does not allow setting vertical sync width)
  168. ;  4  Vertical Total
  169. ;  5  Vertical Total Adjust
  170. ;  6  Vertical Displayed
  171. ;  7  Vertical Sync position
  172. ;  8  Interlace and Skew
  173. ;     (Hitachi 46505 does not implement skew)
  174. ;  9  Maximum Raster Address
  175. ;  10  Cursor Start Raster
  176. ;  11  Cursor End Raster
  177. ;  12  Display Start Address (High)
  178. ;  13  Display Start Address (Low)
  179. ;  14  Cursor Address (High)
  180. ;  15  Cursor Address (Low)
  181. ;  16  Light Pen Address (High)
  182. ;  17  Light Pen Address (Low)
  183.  
  184. CRTC:
  185. ;.profile25x72
  186. ;    db 112  ;0  Horizontal Total
  187. ;    db 72   ;1  Horizontal Displayed
  188. ;    db 85   ;2  Horizontal Sync Position
  189. ;    db 0x4a ;3  Horizontal and Vertical Sync Widths
  190. ;    db 65   ;4  Vertical Total
  191. ;    db 0    ;5  Vertical Total Adjust
  192. ;    db 50   ;6  Vertical Displayed
  193. ;    db 56   ;7  Vertical Sync position
  194. ;    db 0    ;8  Interlace and Skew
  195. ;    db 3    ;9  Maximum Raster Address
  196.  
  197. .profile25x80:
  198.     db 112  ;0  Horizontal Total
  199.     db 80   ;1  Horizontal Displayed
  200.     db 88   ;2  Horizontal Sync Position
  201.     db 0x4a ;3  Horizontal and Vertical Sync Widths
  202.     db 65   ;4  Vertical Total
  203.     db 0    ;5  Vertical Total Adjust
  204.     db 50   ;6  Vertical Displayed
  205.     db 56   ;7  Vertical Sync position
  206.     db 0    ;8  Interlace and Skew
  207.     db 3    ;9  Maximum Raster Address
  208.  
  209. .profile6x34: ;Possibly for future use in breakout menu
  210.     db 112  ;0  Horizontal Total
  211.     db 34   ;1  Horizontal Displayed
  212.     db 66   ;2  Horizontal Sync Position
  213.     db 0x4a ;3  Horizontal and Vertical Sync Widths
  214.     db 65   ;4  Vertical Total
  215.     db 0    ;5  Vertical Total Adjust
  216.     db 12   ;6  Vertical Displayed
  217.     db 37   ;7  Vertical Sync position
  218.     db 0    ;8  Interlace and Skew
  219.     db 3    ;9  Maximum Raster Address
  220.  
  221. ;These are the modes that the ROM bootstrap can set
  222.  
  223. ;SW 2 ON
  224. ;65505348690264640003000000000000
  225. ;65=101 0  Horizontal Total
  226. ;50=80  1  Horizontal Displayed
  227. ;53=83  2  Horizontal Sync Position
  228. ;48     3  Horizontal and Vertical Sync Widths
  229. ;69=105 4  Vertical Total
  230. ;02     5  Vertical Total Adjust
  231. ;64=100 6  Vertical Displayed
  232. ;64=100 7  Vertical Sync position
  233. ;00     8  Interlace and Skew
  234. ;03     9  Maximum Raster Address
  235. ;00     10  Cursor Start Raster
  236. ;00     11  Cursor End Raster
  237. ;00     12  Display Start Address (High)
  238. ;00     13  Display Start Address (Low)
  239. ;00     14  Cursor Address (High)
  240. ;00     15  Cursor Address (Low)
  241.  
  242. ;SW 2 OFF
  243. ;7048554A410032380003000000000000
  244. ;70=112  0  Horizontal Total
  245. ;48=72   1  Horizontal Displayed
  246. ;55=85   2  Horizontal Sync Position
  247. ;4a      3  Horizontal and Vertical Sync Widths
  248. ;41=65   4  Vertical Total
  249. ;00      5  Vertical Total Adjust
  250. ;32=50   6  Vertical Displayed
  251. ;38=56   7  Vertical Sync position
  252. ;00      8  Interlace and Skew
  253. ;03      9  Maximum Raster Address
  254. ;00      10  Cursor Start Raster
  255. ;00      11  Cursor End Raster
  256. ;00      12  Display Start Address (High)
  257. ;00      13  Display Start Address (Low)
  258. ;00      14  Cursor Address (High)
  259. ;00      15  Cursor Address (High)
  260.  
  261.  
  262. ***** CUT HERE ***** BEGIN FILE crypto.asm
  263.  
  264. ;cryptographic functions - key entry/generation, block chaining
  265.  
  266. Generate_Subkeys:
  267.     ;DL = drive number
  268.     ;Returns:  BX=Subkey address
  269.     ;Destroys: AX, CX
  270.     mov bx,BV.DSubkeys
  271.     test dl,1
  272.     jnz .drive1
  273.     add bx,240
  274. .drive1:
  275.     push dx
  276.     push bx ;subkeys
  277.     mov ax,BV.EncKey
  278.     push ax ;key
  279.     call rijndael_keygen
  280.     pop ax
  281.     pop bx
  282.     pop dx
  283.     ret
  284.  
  285. Enter_Key:
  286.     ;input:  ds:di = key to be entered
  287.     ;        es=ds
  288.     ;output: carry set if canceled (null entry)
  289.     ;trashed:  ax, bx, cx, si
  290. .beginEntry:
  291.     ;first, clear buffer
  292.     push di ;save buffer location
  293.     mov cx,16 ;16 words
  294.     xor ax,ax
  295.     cld
  296.     rep stosw
  297.     pop di
  298.     mov cl,4
  299. .loopover:
  300.     xor bx,bx ;bx = pointer within the input buffer (32 bytes)
  301.     xor ax,ax
  302.     int 0x16 ;get keypress
  303.     cmp al,13
  304.     je .cancelExit
  305.     jmp short .noread
  306. .charlp:
  307.     xor ax,ax
  308.     int 0x16 ;get keypress
  309. .noread:
  310.     ;check for backspace
  311.     cmp al,8 ;backspace
  312.     je .beginEntry
  313.     cmp al,13 ;enter key
  314.     je .normalExit ;carry will be clear if taken
  315.     xor al,[di+bx]
  316.     rol al,cl
  317.     mov [di+bx],al
  318.     inc bx
  319.     cmp bl,32
  320.     jne .charlp
  321.     jmp short .loopover
  322. .cancelExit:
  323.     stc
  324. .normalExit:
  325.     ret
  326.  
  327. Do_IV:
  328.     ;CH = low eight bits of cylinder number
  329.     ;CL = sector number 1-63 (bits 0-5)
  330.     ;     high two bits of cylinder (bits 6-7, hard disk only)
  331.     ;DH = head number
  332.     ;SI = subkeys
  333.     ;Direction: cleared
  334.     ;Destroyed:  AX
  335.  
  336.     push bx
  337.     push di
  338.     push si ;subkey location for encrypt call
  339.  
  340. ;   generate IV
  341.     mov di,BV.EncIV
  342.     push di ;IV location for encrypt call
  343.     mov ax,cx
  344.     stosw
  345.     mov al,dh
  346.     stosb
  347.     xor ax,ax
  348.     times 6 stosw
  349.     stosb
  350.  
  351. ;   encrypt IV
  352.     ;arguments are already pushed
  353.     call rijndael_encrypt
  354.  
  355. ;   xor IV into first block
  356.     pop si ;IV location
  357.     lea bx,[si+16]
  358.     call mixkey_nosetup  ;; Destroys AX, SI, and DI.
  359.     pop si ;subkeys
  360.     pop di
  361.     pop bx
  362.     ret
  363.  
  364. Encrypt_Sector:
  365.     ;CH = low eight bits of cylinder number
  366.     ;CL = sector number 1-63 (bits 0-5)
  367.     ;     high two bits of cylinder (bits 6-7, hard disk only)
  368.     ;DH = head number
  369.     ;DL = drive number (bit 7 set for hard disk)
  370.     ;DS = BIOS_DATA_SEG
  371.     push es
  372.     push cs
  373.     pop es
  374.     push si
  375.     cmp dl,1
  376.     sbb si,si ;si=0xffff if drive=1, else 0
  377.     and si,240 ;si=240 if drive=1, else 0
  378.     add si,BV.DSubkeys
  379.  
  380.     push bx
  381.     push cx
  382.     push dx
  383.     call Do_IV ;Apply IV
  384.  
  385.     push si
  386.     mov si,BV.SectorBuffer
  387. .nextscr:
  388.     lea bx,[si+16]
  389.     call mixkey_nosetup
  390.     cmp si,BV.SectorBuffer+512-16
  391.     jne .nextscr
  392.  
  393.     mov si,BV.SectorBuffer
  394. .nextblock:
  395.     push si
  396.     call rijndael_decrypt ;encrypt block (using decryption...)
  397.     pop si
  398.  
  399.  
  400.     ;xor block into next block
  401.     ;si has current [source] position in sector
  402.     lea bx,[si+16] ;xor to 16 bytes later
  403.     call mixkey_nosetup ;adds 16 to SI (mix ciphertext)
  404.     cmp si,BV.SectorBuffer+512-16
  405.     jne .nextblock
  406.     push si
  407.     call rijndael_decrypt ;final block
  408.     pop si
  409.     pop si
  410.     pop dx
  411.     pop cx
  412.     pop bx
  413.     pop si
  414.     pop es
  415.     ret
  416.  
  417. Decrypt_Sector:
  418.     ;CH = low eight bits of cylinder number
  419.     ;CL = sector number 1-63 (bits 0-5)
  420.     ;     high two bits of cylinder (bits 6-7, hard disk only)
  421.     ;DH = head number
  422.     ;DL = drive number
  423.     ;DS = BIOS_DATA_SEG
  424.     push es
  425.     push cs
  426.     pop es
  427.     push si
  428.     cmp dl,1
  429.     sbb si,si
  430.     and si,240 ;see Encrypt_Sector for this trick
  431.     add si,BV.DSubkeys
  432.  
  433.     push bx
  434.     push cx
  435.     push dx
  436.     push si
  437.  
  438.     mov si,BV.SectorBuffer+512-16
  439.     push si
  440.     call rijndael_encrypt
  441.     pop si
  442. .nextblock:
  443.     mov bx,si
  444.     sub si,16
  445.     push si
  446.     call mixkey_nosetup
  447.     call rijndael_encrypt ;decrypt block (using encryption...)
  448.     pop si
  449.     cmp si,BV.SectorBuffer
  450.     jne .nextblock
  451.     mov si,BV.SectorBuffer+512-32
  452. .nextscr:
  453.     lea bx,[si+16]
  454.     call mixkey_nosetup
  455.     sub si,32
  456.     cmp si,BV.SectorBuffer-16
  457.     jne .nextscr
  458.     pop si
  459.     pop dx
  460.     pop cx
  461.     push cx
  462.     push dx
  463.     call Do_IV  ;Apply IV
  464.     pop dx
  465.     pop cx
  466.     pop bx
  467.     pop si
  468.     pop es
  469.     ret
  470.  
  471.  
  472. ;Plan:
  473. ;Encryption:
  474. ;   generate IV
  475. ;   encrypt IV
  476. ;   xor IV into first block
  477. ;   encrypt first block
  478. ;   xor first block into 2nd block
  479. ;   encrypt 2nd block...
  480. ;
  481. ;Decryption:
  482. ;   decrypt last block
  483. ;   xor 2nd to last block into last block
  484. ;   decrypt 2nd to last block
  485. ;   ...
  486. ;   decrypt first block
  487. ;   generate IV
  488. ;   encrypt IV
  489. ;   xor IV into first block
  490.  
  491. ***** CUT HERE ***** BEGIN FILE disk.asm
  492.  
  493. ;This file needs a rewrite, but mostly works
  494. ;(some problems switching between disk geometries in freedos)
  495.  
  496. Readsector:
  497.     ;pushing done in function selector
  498.  
  499.     ;INPUT
  500.     ;AH = 02h
  501.     ;AL = number of sectors to read (must be nonzero)
  502.     ;CH = low eight bits of cylinder number
  503.     ;CL = sector number 1-63 (bits 0-5)
  504.     ;     high two bits of cylinder (bits 6-7, hard disk only)
  505.     ;DH = head number
  506.     ;DL = drive number (bit 7 set for hard disk)
  507.     ;ES:BX -> data buffer
  508.     ;-----
  509.     ;during operation:
  510.     ;BH = total sectors
  511.     ;BL = sectors read
  512.     ;ES:BP = data buffer
  513. .rslp   call FDC.SpinSeek
  514.     cli
  515. .rsnsl:
  516.     ;inc bl
  517.     ;cmp bl,bh
  518.     ;je .doOpDoneNE
  519.  
  520.     push cx
  521.     mov di,BV.SectorBuffer
  522.     mov ax,512
  523.     xchg ax,cx ;sector size
  524.     out 0xc,al ;sector number
  525.     mov al,0x80 ;read sector
  526.     call FDC.CmdDelay ;command
  527.     ;retrieve it from the FDC
  528.     jmp short .bytelp
  529. .erchk test al,3
  530.     jz .doOpError
  531. .bytelp:
  532.     in al,8
  533.     test al,2
  534.     jz .erchk
  535.     in al,0xe
  536.     mov [di],al ;store byte from FDC
  537.     inc di
  538.     loop .bytelp
  539.     in al,8
  540.     test al,0x9e
  541.     jnz .doOpError
  542.  
  543.     ;do decryption
  544.     mov di,dx
  545.     and di,1
  546.     test byte [BV.DFlags+di],1
  547.     jz .nodec
  548.     pop cx
  549.     call Decrypt_Sector
  550.     push cx
  551. .nodec:
  552.  
  553.     ;store
  554.     mov di,bp
  555.     mov si,BV.SectorBuffer
  556.     mov cx,256
  557.     rep movsw
  558.     mov bp,di
  559.     pop cx
  560.  
  561.     mov si,dx
  562.     and si,byte 1
  563.     cmp cx,byte 1
  564.     jne .noReadSectorCount
  565.     or dh,dh
  566.     jnz .noReadSectorCount
  567.     mov al,[BV.SectorBuffer+0x18]
  568.     inc al
  569.     mov [BV.SectorsPerTrack+si],al
  570. .noReadSectorCount:
  571.     inc bl
  572.     cmp bl,bh
  573.     je .doOpDoneNE
  574.  
  575.     inc cx ;find next sector
  576.     cmp cl,[BV.SectorsPerTrack+si]
  577.     jb .rsnsl
  578.     mov cl,1
  579.     xor dh,1
  580.     jnz .rslp
  581.     inc ch
  582.     jmp short .rslp
  583.  
  584. .doOpDoneNE:
  585.     jmp INT13.OpDoneNE
  586. .doOpError:
  587.     jmp INT13.OpError
  588.  
  589. Writesector:
  590.     ;pushing done in function selector
  591.  
  592.     ;INPUT
  593.     ;AH = 03h
  594.     ;AL = number of sectors to write (must be nonzero)
  595.     ;CH = low eight bits of cylinder number
  596.     ;CL = sector number 1-63 (bits 0-5)
  597.     ;     high two bits of cylinder (bits 6-7, hard disk only)
  598.     ;DH = head number
  599.     ;DL = drive number (bit 7 set for hard disk)
  600.     ;ES:BX -> data buffer
  601.     ;-----
  602.     ;during operation:
  603.     ;BH = total sectors
  604.     ;BL = sectors read
  605.     ;ES:BP = data buffer
  606. .rslp   call FDC.SpinSeek
  607.     cli
  608. .rsnsl:
  609.     ;inc bl
  610.     ;cmp bl,bh
  611.     ;je Readsector.doOpDoneNE
  612.  
  613.     push cx
  614.     xchg ax,cx
  615.     out 0xc,al ;sector number
  616.  
  617.     ;load from memory to buffer
  618.     push es
  619.     mov ax,es
  620.     mov ds,ax ;ds=source
  621.     mov ax,cs
  622.     mov es,ax ;es=buffer
  623.  
  624.     mov si,bp
  625.     mov di,BV.SectorBuffer
  626.     mov cx,256
  627.     rep movsw
  628.     mov bp,si
  629.  
  630.     mov ax,cs
  631.     mov ds,ax ;restore ds
  632.     pop es
  633.  
  634.     ;do encryption
  635.     mov si,dx
  636.     and si,byte 1
  637.     test byte [BV.DFlags+si],1
  638.     jz .nodec
  639.     pop cx
  640.     call Encrypt_Sector
  641.     push cx
  642. .nodec:
  643.  
  644.     mov si,BV.SectorBuffer
  645.     ;mov cx,512 ;byte counting isn't important when writing
  646.     ;mov al,0xa0 ;write sector
  647.     ;call FDC.CmdDelay ;command
  648.     push bp
  649.     push dx
  650.     mov bp,.bytelp
  651.     mov dx,8
  652.     mov ah,0;2
  653.     lodsb
  654.     mov di,ax
  655.     mov al,0xa0 ;write sector
  656.     push bx
  657.     mov bx,0xf602
  658.     call FDC.CmdDelay ;command
  659.     mov ah,0;xf6
  660.     ;write it to the FDC
  661.  
  662. .startlp:
  663.     in al,dx
  664.     shr al,1
  665.     jnc .wdone ;not busy -> error
  666.     jnz .startlp ;waiting for busy only
  667. .waitdata:
  668.     in al,dx
  669.     test al,bh ;ah=f6 ;ignore CRC error?!?
  670.     jz .waitdata ;wait for data request
  671.     ;jmp short .writeagain
  672.     xchg ax,di
  673.     out 0xe,al
  674.     jmp short .loadnext
  675.  
  676. .bytelp:
  677.     in al,dx
  678.     dec ax
  679.     jz .bytelp
  680.     cmp al,bl
  681.     jne .wdone
  682. .writeagain:
  683.     xchg ax,di
  684.     out 0xe,al
  685. .loadnext:
  686.     lodsb ;get next byte
  687.     xchg di,ax
  688.     in al,dx
  689.     and al,bl ;bl=2
  690.     jnz .writeagain
  691.     jmp bp
  692.  
  693.  
  694. .wdone:
  695.     pop bx
  696.     in al,dx
  697.     or al,al
  698.     ;cmp al,0xff;0x9e
  699.     pop dx
  700.     pop bp
  701.     jnz INT13.OpError
  702.  
  703.     pop cx
  704.  
  705.     inc bl
  706.     cmp bl,bh
  707.     je Readsector.doOpDoneNE
  708.  
  709.     mov si,dx
  710.     and si,1
  711.  
  712.     inc cx ;find next sector
  713.     cmp cl,[BV.SectorsPerTrack+si]
  714.     jb .rsnsl
  715.     mov cl,1
  716.     xor dh,1
  717.     jnz .rslp
  718.     inc ch
  719.     jmp .rslp
  720.  
  721. INT13:
  722. .OpError:
  723.     ;   error exit
  724.     ;xor ah,ah
  725.     ;xor bx,bx
  726.     ;call DisplayNAX
  727.     ;xor ax,ax
  728.     ;int 0x29
  729.     ;xchg ax,cx
  730.     ;call DisplayNAX
  731. ;.self  jmp short .self
  732.     pop cx
  733.     mov ah,4
  734.     ;jmp short INT13.OpDone
  735.     db 0xbb ;ignore next 2 bytes (mov bx,xxxx)
  736. .OpDoneNE:
  737.     mov ah,0
  738. .OpDone:
  739.     mov al,0xd0 ;immediate interrupt
  740.     out 8,al
  741.     mov al,0xd2 ;capture not-ready
  742.     out 8,al
  743.     pop bp
  744.     pop di
  745.     pop si
  746.     pop dx
  747.     pop cx
  748.     pop bx
  749.     or ah,ah ;cmp ah,0
  750.     ;jz .noerr
  751.     jnz .errex
  752.  
  753. .noerr  mov ds,bx
  754.     mov bx,sp
  755.     ss and byte [bx+6],0xfe ;turn carry off
  756.     mov bx,ds
  757. .ex cs and byte [BV.LFlags],0xfb ;unlock
  758.     cs mov [BV.DiskLastStatus],ah
  759.     cs test byte [BV.LFlags],0x20 ;need to run keyclick?
  760.     jz .nokc
  761.     cs and byte [BV.LFlags],0xdf ; no more keyclick
  762.     push ax
  763.     push bx
  764.     call ProcessKeys
  765.     pop bx
  766.     pop ax
  767. .nokc:
  768.     pop ds
  769.     iret
  770.  
  771. .entry:
  772.     push ds
  773.     push cs
  774.     pop ds
  775.     cld
  776.     or byte [BV.LFlags],4 ;lock
  777.     cmp dl,1
  778.     ja .unsupported ;invalid drive
  779.     cmp ah,5
  780.     je .format
  781.     ja .gr5
  782.     cmp ah,1
  783.     jb .noerr ;0 .reset
  784.     je .getstatus ;1
  785.     cmp ah,3
  786.     ja .unsupported; .verify
  787.     push bx
  788.     push cx
  789.     push dx
  790.     push si
  791.     push di
  792.     push bp
  793.     mov bp,bx
  794.     mov bh,al
  795.     mov bl,0
  796.     je Writesector; 3
  797.     jmp Readsector ;2
  798. .gr5:
  799.     cmp ah,8
  800.     je .getparam ;8
  801.     cmp ah,0x15 ;get disk type
  802.     je .disktype
  803.     cmp ah,0x16
  804.     je .diskchg
  805.     ;6, 7 are fixed disk format
  806. .verify:
  807. .format:
  808. .unsupported:
  809.     mov ah,1 ;unsupported
  810. .errex  mov ds,bx
  811.     mov bx,sp
  812.     ss or byte [bx+6],1 ;turn carry on
  813.     mov bx,ds
  814.     jmp short .ex
  815.  
  816. .getparam:
  817.     ;mov ah,7 ;drive param error
  818.     ;test dl,1
  819.     ;ja .errex ;drive out of range
  820.     mov bl,1 ;360KB
  821.     mov cx,40*0x100+9
  822.     mov dx,0x101 ;2 heads, 1 drive
  823.     ;check if we really have 2 drives
  824.     mov ah,[BV.Equipment]
  825.     rcl ah,1
  826.     rcl ah,1
  827.     adc dl,0 ;increment drive count if there are two
  828.     xor ah,ah
  829.  
  830.     ;FIXME need to set drive param table
  831.     jmp .noerr
  832.  
  833. ;.reset
  834. ;   jmp short .noerr
  835.  
  836. .getstatus:
  837.     cs mov ah,[BV.DiskLastStatus]
  838.     or ah,ah
  839.     jz .noerr
  840.     jmp short .errex
  841. .diskchg:
  842.     mov ah,al
  843.     in al,0x1c
  844.     and al,0x3
  845.     sub al,dl
  846.     xchg al,ah ;al becomes unchanged, ah=0 if same drive
  847.     jz .noerr
  848.     mov ah,6
  849.     jmp .errex
  850.  
  851.  
  852. .disktype:
  853.     mov ah,2; 1 ;floppy, changeline support
  854.     jmp .noerr
  855. FDC:
  856. .SpinSeek:
  857.     ;in: dl=drive number, ch=track, dh=head number
  858.     ;    ds=0x40 (BIOS_DATA_SEG)
  859.     ;push ax
  860.     push bx
  861.     mov al,0xd0 ;force interrupt
  862.     out 8,al
  863.     xor bx,bx
  864.  
  865.     ;figure out if the right drive/side was set
  866.     in al,0x1c
  867.     mov ah,al
  868.     and al,7 ;mask off all but the drive/side
  869.     xor al,dl ;dl is desired drive number
  870.     times 2 ror al,1
  871.     xor al,dh ;dh is desired head number
  872.     ;al now has different bits set from drive/side
  873.     jz .ssSameDS
  874.     inc bx ;make sure we exit at an index pulse
  875.     ;inc bx ;and a little more for 10spt
  876. .ssSameDS:
  877.     times 2 rol al,1
  878.     xor al,ah ;this is so fucking genius, it amazes me
  879.     out 0x1c,al ;set desired drive/side
  880.  
  881.     ;is the drive still ready?
  882.     in al,8
  883.     shl al,1
  884.     jnc .ssNoSpinDelay
  885.     mov bl,4 ;the drive wasn't spinning - let's go 3-4 revolutions
  886. .ssNoSpinDelay:
  887.     mov [BV.FloppyIntCount],bl
  888.     or bx,bx ;if bx is non-zero, we must have changed sides/tracks
  889.     mov bl,dl
  890.     lea bx,[bx+BV.DTrack] ;don't touch flags
  891.     ;load track from memory
  892.     mov al,[bx]
  893.     jnz .doSeek
  894.     cmp al,ch ;is the drive on the same track?
  895.     jz .noSeek
  896. .doSeek: ;do seek to track
  897.     out 0xa,al ;set current track
  898.     mov al,ch
  899.     out 0xe,al ;set track number
  900.     mov [bx],al ;update track number
  901.     mov al,0x18 ;seek track, load head
  902.     call .CmdDelay ;command
  903. .ccWait in al,8
  904.     test al,1
  905.     jnz .ccWait
  906.     mov al,0xd4 ;capture index pulse
  907.     ;mov bl,[BV.FloppyIntCount]
  908.     sti ;process interrupts
  909.     out 8,al
  910.  
  911. .ssWait cmp byte [BV.FloppyIntCount],0
  912.     jg .ssWait
  913.     ;cmp bl,4
  914.     ;jb .countSectors
  915. .noSeek pop bx
  916.     ;pop ax
  917.     ret
  918. .CmdDelay:
  919.     out 8,al
  920. .Delay:
  921.     times 4 aam
  922.     ret
  923. .WaitFinished:
  924.     in al,8
  925.     test al,1
  926.     jnz .WaitFinished
  927.     ret
  928.  
  929.  
  930. FloppyDetect:
  931.     ;Strategy:  Step down up to 45 times until TR00 is detected, else give up
  932.     ;           Step up 1 time, verify TR00=0
  933.     ;           Step down 1 time, verify TR00=1
  934.     ;Returns with zero flag set if only one drive is found
  935.     mov cx,45 ; max tracks
  936. .tryAgain:
  937.     mov al,0x68 ;step down, 6ms delay
  938.     call .CWT
  939.     loopz .tryAgain ;loop if no TR00
  940.     jz .done
  941.     mov al,0x4a ;step up, 20ms delay
  942.     call .CWT
  943.     mov al,0x6a ;step down, 20ms delay (0x6a AND 4 is zero for error exit)
  944.     jnz .errdone
  945. .CWT:
  946.     call FDC.CmdDelay
  947.     call FDC.WaitFinished
  948. .errdone:
  949.     test al,4
  950. .done:
  951.     ret
  952.  
  953. FloppyInt:
  954.     ;purpose is to decrement event count if in disk code
  955.     ;otherwise select drive 3 and unload head if no longer ready
  956.     cli
  957.     push ax
  958.     in al,8 ;clear interrupt
  959.     cs test byte [BV.LFlags],4 ;are we in BIOS disk code?
  960.     jz .notdisk
  961.     cs dec byte [BV.FloppyIntCount] ;in disk code
  962.     pop ax
  963.     iret
  964. .notdisk:
  965.     in al,0x1c
  966.     mov ah,al
  967.     or al,7 ;select drive 3 side 1
  968.     xor ah,al
  969.     jz .done ;drive 3 side 1 was already selected
  970.     out 0x1c,al
  971.  
  972.     ;turn off the drive motor
  973.     in al,0xa ;get track
  974.     out 0xe,al ;seek to current track
  975.     mov al,0x10 ;seek and unload head
  976.     out 8,al ;floppy command
  977. .done   pop ax
  978.     iret
  979.  
  980. ***** CUT HERE ***** BEGIN FILE dsbios.asm
  981.  
  982. CPU 186
  983.  
  984. BIOS_DATA_SEG equ 0x40
  985. BIOS_CODE_SEG equ 0x40
  986. VIDEO_SEG equ 0x400
  987.  
  988. Section Loader
  989. LoaderStart:
  990.     call InitCode+LoaderEnd-LoaderStart
  991. LoaderEnd:
  992.  
  993. section BIOS align=1 vstart=0
  994. BV:
  995. .Serial     dw 0
  996.             dw 0
  997.             dw 0
  998.             dw 0
  999. .Parallel   dw 0x1a
  1000.             dw 0
  1001.             dw 0
  1002.             dw 0
  1003. .Equipment  dw 0x4021 ;4061 for 2 floppies; autodetected
  1004.             db 0
  1005. .TotalRAM   dw 768
  1006.             db 0
  1007.             db 0
  1008. .KeyStatus  dw 0 ;shift flags (int16/ah=2) are here (high byte is extended)
  1009.             db 0
  1010. .NextKey    dw .KeyBuffer
  1011. .FirstFreeKey   dw .KeyBuffer
  1012. .KeyBuffer  times 16 dw 0
  1013. .EndKeyBuffer   db 0
  1014.             db 0
  1015.             db 0
  1016. .DiskLastStatus db 0
  1017.             db 0
  1018.             db 0
  1019.             db 0
  1020.             db 0
  1021. .XFCount    db 0
  1022.             db 0
  1023.             db 0
  1024.  
  1025. ;Start mode change clear range
  1026. .CurMode    db 0x2
  1027. .ScreenCols dw 0;80
  1028. .PageSize   dw 0x1000 ;4000
  1029. .PageStart  dw 0
  1030. .CursorPos  times 8 dw 0
  1031. .CEndLine   db 8
  1032. .CStartLine db 7
  1033. .CurPage    db 0
  1034. .CRTCBase   dw 0x3d4
  1035. .CurModeSelect  db 0x2d
  1036. .CurCGAPalette  db 0
  1037. ;End mode change clear range
  1038.             dd 0
  1039.             db 0
  1040. .TimerTicksL    dw 0
  1041. .TimerTicksH    dw 0
  1042. .DaysPassed db 0
  1043. .CtrlBrk    db 0
  1044.             dw 0
  1045.             db 0
  1046.             db 0
  1047.             db 0
  1048.             db 0
  1049.             times 4 db 0
  1050.             times 4 db 0
  1051. .KeyBufferStart dw .KeyBuffer
  1052. .KeyBufferEnd   dw .EndKeyBuffer
  1053. times 0x84-($-$$) db 0
  1054. .ScreenRows db 0;24
  1055. times 0x200-($-$$) db 0
  1056. .XFlags     db 2    ;bit 0=V20 present, 1=CGA present (turned off if not found)
  1057. .LFlags     db 0    ;bit 0=OnboardVid 1=CGA 2=Disk 3=BIOSMenus
  1058.             ;    4=RunTimerTick 5=RunKeyClick 6=RunBIOSMenu
  1059. .FloppyIntCount db 0
  1060. .SectorsPerTrack db 10,10 ;actually SPT+1
  1061. .AuxTickCount   dw 0
  1062. .EncKey   times 32 db 0
  1063.  
  1064. ;DriveData
  1065. .DTrack      db 0,0
  1066. .DFlags      db 0,0 ;bit 0: disk encryption active
  1067. .DSubkeys    times 240*2 db 0 ;240 bytes each
  1068. .CRTC_Profile:
  1069.     dw 0
  1070. .CRTC_DisplayAddress:
  1071.     dw 0
  1072. .LStackStart    dw 0x0200 ;bit to be moved for coprocessor detection
  1073.                 times 47 dw 0
  1074. .LocalStack:
  1075. .EncIV          times 4 dd 0
  1076. .SectorBuffer   times 128 dd 0
  1077.  
  1078. startCode:
  1079.  
  1080. startOnboardv:
  1081. %include "onboardv.asm" ;Onboard Video
  1082. endOnboardv:
  1083. startCga:
  1084. %include "cga.asm"      ;CGA Video
  1085. endCga:
  1086. startDisk:
  1087. %include "disk.asm"     ;Disk Functions
  1088. endDisk:
  1089. startKeyboard:
  1090. %include "keyboard.asm" ;Keyboard API & Interrupt handler
  1091. endKeyboard:
  1092. startMisc:
  1093. %include "misc.asm"     ;Minor interrupt handlers, BIOS display routines
  1094. endMisc:
  1095. startTimer:
  1096. %include "timer.asm"    ;Timer chip support
  1097. endTimer:
  1098. startMenu:
  1099. %include "menu.asm"     ;Breakout menu
  1100. endMenu:
  1101. startCrtc:
  1102. %include "crtc.asm"     ;CRTC configuration routines and screen profiles
  1103. endCrtc:
  1104. startCrypto:
  1105. %include "crypto.asm"   ;Encryption support routines
  1106. endCrypto:
  1107.  
  1108. %define rijndael_empty_data ;tables are generated at boot, saving disk space
  1109. startRijndael:
  1110. %include "rijndael.asm" ;Main Rijndael encryption routines
  1111. endRijndael:
  1112. EndOfResident:
  1113.  
  1114. startInit:
  1115. %include "init.asm" ;HW Init and 3rd stage bootloader code
  1116. endInit:
  1117.  
  1118. InitCode:   ;relocate to 40:0
  1119. cli
  1120. push cs
  1121. pop ds
  1122. mov cx,(InitCode - BV) / 2
  1123. mov ax,BIOS_CODE_SEG
  1124. mov es,ax
  1125. xor di,di
  1126. pop si  ;first byte after call
  1127. cld
  1128. rep movsw ;for great justice
  1129. jmp BIOS_CODE_SEG:BIOSEntry
  1130.  
  1131. %ifdef SizeSummary
  1132.     dw endInit - startInit
  1133.     db "<INIT"
  1134.     dw endOnboardv - startOnboardv
  1135.     db "<ONBOARDV"
  1136.     dw endCga - startCga
  1137.     db "<CGA"
  1138.     dw endDisk - startDisk
  1139.     db "<DISK"
  1140.     dw endKeyboard - startKeyboard
  1141.     db "<KEYBOARD"
  1142.     dw endMisc - startMisc
  1143.     db "<MISC"
  1144.     dw endTimer - startTimer
  1145.     db "<TIMER"
  1146.     dw endMenu - startMenu
  1147.     db "<MENU"
  1148.     dw endCrtc - startCrtc
  1149.     db "<CRTC"
  1150.     dw endCrypto - startCrypto
  1151.     db "<CRYPTO"
  1152.     dw endRijndael - startRijndael
  1153.     db "<RIJNDAEL"
  1154.     dw endRijInit - startRijInit
  1155.     db "<RIJINIT"
  1156.     dw startCode - BV
  1157.     db "<VARS"
  1158. %endif
  1159.  
  1160. ***** CUT HERE ***** BEGIN FILE init.asm
  1161.  
  1162. InitList:
  1163. ;Init interrupt table
  1164.     db 0x8
  1165.     dw NoInterrupt
  1166.     db 0x10
  1167.     dw OnBoardVideo
  1168.     db 0x11
  1169.     dw INT11
  1170.     db 0x12
  1171.     dw INT12
  1172.     db 0x13
  1173.     dw INT13.entry
  1174.     db 0x15
  1175.     dw INT15
  1176.     db 0x16
  1177.     dw INT16.entry
  1178.     db 0x18
  1179.     dw Reboot
  1180.     db 0x19
  1181.     dw Reboot
  1182.     db 0x1a
  1183.     dw INT1A   ;system time api
  1184.     db 0x1d
  1185.     dw CGA.modeTable
  1186.     db 0x29
  1187.     dw INT29
  1188.     db 0xf8    ;Timer0
  1189.     dw Timer0
  1190.     ;db 0xf9    ;Timer1
  1191.     ;dw Timer1
  1192.     ;db 0xfa
  1193.     ;dw
  1194.     db 0xfb ;Keyboard UART
  1195.     dw KeyUART
  1196.     ;db 0xfc
  1197.     ;dw
  1198.     db 0xfd ;Floppy Interrupt
  1199.     dw FloppyInt
  1200.     db 0xfe ;FPU Exception
  1201.     dw FPUInterrupt
  1202.     db 0xff    ;Expansion IRQ
  1203.     dw NoInterrupt
  1204.     db 0 ;end list
  1205. ;#############
  1206. ;Hardware init list
  1207.  
  1208. ;Video page
  1209.     dw 0x1000 ;Video @ 16-32K (VIDEO_SEG)
  1210. ;Floppy seek track 0
  1211.     dw 0x0808 ;no verify
  1212. ;keyboard controller:
  1213.     dw 0x3a00, 0x3a00, 0x3aff, 0x3aff, 0x3a37
  1214. ;       \force state/  \reset/ \mode/  \set command
  1215. ;8259A interrupt controller
  1216.     dw 0x0013, 0x02f8, 0x020f, 0x0296
  1217. ;      \ICW1/  \ICW2/  \ICW4/  \mask/
  1218. ;Timer init data
  1219.     dw 0x2634, 0x20bf, 0x2021 ;channel 0 (clock)
  1220.     dw 0x2674, 0x2200, 0x2200 ;channel 1 (2nd stage clock)
  1221.     dw 0x26b6, 0x245d, 0x2400 ;channel 2 (add-in serial rate)
  1222. ;End hardware init
  1223.     dw 0 ;end list
  1224.  
  1225. Msg: ;IMPORTANT:  DO NOT REORDER FIRST 2 MESSAGES
  1226. .title:
  1227.     db "[dsBIOS] V1.02 - (C)2006 Brad Normand",0xd,0xa
  1228.     db 0xa,0xa
  1229.     db "       Memory:    KB",0xd,0xa
  1230.     db "     CPU Type:",0xd,0xa
  1231.     db "  Coprocessor:",0xd,0xa
  1232.     db "    CGA Video:",0xd,0xa
  1233.     ;db "     Aux Comm:",0xd,0xa
  1234.     db "Floppy Drives:",0
  1235. .i8088:
  1236.     db "i8088",0
  1237. .V20:
  1238.     db "NEC V20",0
  1239. .none:
  1240.     db "None",0
  1241. .detected:
  1242.     db "Detected",0
  1243. .text:
  1244.     db ", text mode initialized",0
  1245. .keyBoot:
  1246.     db 13,10,10,"Booting FreeDOS...",13,10,10,0
  1247. ;MsgReg:    db "LAST     AX-DX                 CS-IP                     ",0
  1248. ;MsgMCE db "Memory corruption detected at: 40:",0
  1249.  
  1250. BIOSEntry:
  1251.     ;switch to our local stack
  1252.     ;ax=0x40 at entry (BIOS_CODE_SEG)
  1253.     ;cl=0x00 at entry
  1254.     ;direction flag must be clear
  1255.     mov ss,ax
  1256.     mov sp,BV.LocalStack-26 ;extra zeros to pop
  1257.     mov ds,ax
  1258.  
  1259.     ;start the math coprocessor initializing if present
  1260.     fninit ;finit can't be used because it will lock if no coprocessor
  1261.  
  1262.     ;prepare interrupt table - each vector points to InterruptCatcher
  1263.     ;                          but with low byte of CS = int#
  1264.     pop di  ;zero from stack
  1265.     pop es  ;zero from stack
  1266.  
  1267.     ;generate int0 offset
  1268.     mov ax,InterruptCatcher-BV & 0xf + ((((InterruptCatcher-BV >> 4) + BIOS_CODE_SEG) & 0xff) << 4)
  1269.     ;generate int0 segment
  1270.     mov dx,((InterruptCatcher-BV >> 4) + BIOS_CODE_SEG) & 0xff00
  1271.  
  1272.     ;cx and direction were cleared in first stage init
  1273.     inc ch
  1274. .nextint:
  1275.     stosw
  1276.     sub ax,0x10 ;update offset
  1277.     jnb .noborrow
  1278.     sub ax,0x1000 ;this adjustment is necessary to ensure the handler is in the segment window
  1279.     add dx,0x100-0x1000 ;0x100 offsets the adjustment, 0x1000 for the wrapover
  1280. .noborrow:
  1281.     xchg ax,dx
  1282.     stosw
  1283.     inc ax ;update segment
  1284.     xchg ax,dx
  1285.  
  1286.     loop .nextint
  1287.  
  1288.  
  1289.     ;direction was also cleared
  1290.     rep stosw
  1291.  
  1292.     fild dword [BV.LStackStart+1] ;load test bit into FPU if present
  1293.  
  1294.     ;set up 25x80
  1295.     mov si,CRTC.profile25x80
  1296.     call CRTC_LoadProfile.Sanyo
  1297.     pop si ;zero from empty stack
  1298.     call CRTC_SetDisplayAddress
  1299.  
  1300.     ;CGA Detection and Initialization
  1301.     call CGA.Init
  1302.     mov dl,0xd4
  1303.     mov si,0x15ea
  1304. .fixCGA:
  1305.     xor byte [BV.XFlags],2
  1306.     call CRTC_SetDisplayAddress
  1307.     call CRTC_GetDisplayAddress
  1308.     sub si,0x15ea
  1309.     jz .fixCGA ;if detected
  1310.  
  1311.     fist dword [BV.LStackStart] ;write test bit back from FPU if present
  1312.  
  1313.     ;next, step through the interrupt list and set them
  1314.     mov si,InitList
  1315. .intlp  lodsb
  1316.     and ax,0xff
  1317.     jz .intdone
  1318.     shl ax,1
  1319.     shl ax,1
  1320.     xchg ax,di
  1321.     movsw
  1322.     mov ax,BIOS_DATA_SEG
  1323.     stosw
  1324.     jmp short .intlp
  1325. .intdone:
  1326.  
  1327.     ;now process hardware init
  1328. .portloop:
  1329.     xor dx,dx
  1330.     lodsw
  1331.     test ax,ax
  1332.     jz .portdone
  1333.     xchg ah,dl
  1334.     out dx,al
  1335.     jmp short .portloop
  1336. .portdone:
  1337.  
  1338.     ;do the title
  1339.     pop ax   ;zero from empty stack
  1340.     int 0x10 ;clear screen
  1341.     ;mov bx,1
  1342.     ;mov si,Msg.title ;SI is already set
  1343.     call DisplayString
  1344.  
  1345.     ;initialize the FDC (track 0 seek already in progress)
  1346.     ;mov byte [BV.DTrack],0  ;already zero!
  1347.  
  1348.     ;determine CPU type
  1349.     mov ax,sp
  1350.     pusha
  1351.     nop
  1352.     cmp ax,sp
  1353.     je .nov20
  1354.     xchg ax,sp
  1355.     or byte [BV.XFlags],1
  1356. .nov20:
  1357.  
  1358.     ;update equipment with coprocessor status
  1359.     mov al,[BV.LStackStart]
  1360.     or [BV.Equipment],al
  1361.  
  1362.     ;count RAM - start at 64KB, test 1KB blocks up to 768KB
  1363.     ;Note:  this checks for presence only - not correct operation!
  1364.     mov ax,0x1000-64
  1365.     mov cx,705  ;test up to 704 additional KB
  1366.     mov di,0x2fd    ;test pattern and address - should catch any missing chip
  1367. .ramclp add ax,64
  1368.     mov es,ax
  1369.     es mov [di],di
  1370.     es cmp [di],di
  1371.     loope .ramclp   ;cx is decremented an extra time
  1372.     ;subtract the nonexistant memory from our total
  1373.     sub word [BV.TotalRAM],cx
  1374.  
  1375.     ;display some info
  1376.     ;mov si,Msg.HW ;SI is already set
  1377.     ;mov bx,3
  1378.     ;mov word [BV.CursorPos],0x300
  1379.     ;call DisplayString
  1380.  
  1381.     mov word [BV.CursorPos],0x30f
  1382.     int 0x12
  1383.     call DisplayNAX
  1384.  
  1385.     mov word [BV.CursorPos],0x40f
  1386.     test byte [BV.XFlags],1
  1387.     ;mov si,Msg.i8088 ;SI is already set
  1388.     jz .i8088
  1389.     mov si,Msg.V20
  1390. .i8088  call DisplayString
  1391.  
  1392.     mov word [BV.CursorPos],0x50f
  1393.     test byte [BV.Equipment],2
  1394.     mov si,Msg.none
  1395.     jz .no8087
  1396.     mov si,Msg.detected
  1397. .no8087 call DisplayString
  1398.  
  1399.     mov word [BV.CursorPos],0x60f
  1400.     mov si,Msg.none
  1401.     test byte [BV.XFlags],2
  1402.     jz .noCGA
  1403.     mov si,Msg.detected
  1404.     call DisplayString
  1405. .noCGA call DisplayString
  1406.  
  1407.     ;generate rijndael tables
  1408. startRijInit:
  1409. %ifdef rijndael_empty_data
  1410.     push cs
  1411.     pop es
  1412.     mov di,isbox ;xtime    ;first, put log in sbox and pwr in isbox ;xtime
  1413.     pop bx  ;zero from empty stack
  1414. ;    push di
  1415.     push di
  1416.     mov al,1
  1417.     mov cx,0xff00
  1418. .tablp  mov bl,al
  1419.     mov [bx+sbox],cl
  1420.     stosb
  1421.     ;call .xtime
  1422.     shl al,1
  1423.     jnc .nxor
  1424.     xor al,0x1b
  1425. .nxor   xor al,bl
  1426.     inc cx
  1427.     jnz .tablp
  1428.     ;now, create the sbox
  1429.     pop bx
  1430.     xor ax,ax
  1431.     mov di,sbox
  1432.     push di
  1433. .sboxl  mov ah,al
  1434.     mov ch,4
  1435. .makes1 rol ah,1
  1436.     xor al,ah
  1437.     dec ch
  1438.     jnz .makes1
  1439.     xor al,0x63
  1440.     stosb
  1441.     mov al,[di]
  1442.     not al
  1443.     xlat
  1444.     loop .sboxl
  1445.     ;now, the inverse sbox
  1446.     xor bx,bx
  1447.     xor ax,ax ;clear al
  1448.     pop si  ;xtime
  1449. .islp   mov bl,[si]
  1450.     inc si
  1451.     mov [bx+isbox],al
  1452.     inc al
  1453.     jnz .islp
  1454. %endif
  1455. endRijInit:
  1456.  
  1457.     ;wait for track seek to complete
  1458.     call FDC.WaitFinished
  1459.     mov al,1 ;2nd drive, side 0
  1460.     out 0x1c,al
  1461.     call FloppyDetect
  1462.     mov al,'1'
  1463.     jz .oneFD
  1464.     or byte [BV.Equipment],0x40 ;turn on 2 drives
  1465.     inc ax ;2
  1466. .oneFD:
  1467.     mov [BV.CursorPos],word 0x70f
  1468.     int 0x29 ;display # drives
  1469.  
  1470.  
  1471.     mov al,0xd2 ;capture ready->not ready
  1472.     out 8,al
  1473.  
  1474.     in al,0x22
  1475.     in al,0x22
  1476.     mov [BV.AuxTickCount],word 0
  1477.     sti ;ready to handle interrupts
  1478.  
  1479.     ;mov word [BV.CursorPos],0x0800
  1480.     mov si,Msg.keyBoot
  1481.     ;pop bx ;zero from stack
  1482.     call DisplayString
  1483. ;    pop ax ;zero from stack
  1484. .bootMenu:
  1485. ;    int 0x16
  1486.  
  1487. .bootFD:
  1488.     mov ax,0x201    ;floppy read one sector
  1489.     mov cx,1    ;track 0 sector 1
  1490.     xor dx,dx   ;head 0 disk 0
  1491.     pop es      ;load seg from empty stack
  1492.     mov bx,0x3ce0   ;load ofs
  1493.     int 0x13    ;read sector
  1494.     ;es mov ax,[0x7dfe]
  1495.     ;xor bx,bx
  1496.     ;call DisplayNAX
  1497.     ;cmp ax,0xaa55
  1498. ;.noboot    jne .noboot
  1499. ;    pop ax ;zero from stack
  1500. ;    int 0x10
  1501.     ;pop es ;zero from stack
  1502.     mov di,0x3d00
  1503.     push di ;boot offset
  1504.     cld
  1505.     mov ch,1 ;actually copies 2 extra bytes
  1506.     mov si,FreeDOSBoot
  1507.     rep movsw
  1508.     mov ds,cx
  1509.     mov si,0x3ceb
  1510.     mov di,0x3d0b
  1511.     mov cl,0xa  ;copy disk info
  1512.     rep movsw   ;es prefix may require interrupts disabled
  1513.     mov dl,0
  1514.     retf ;cs from empty stack
  1515. FreeDOSBoot:
  1516.     incbin "freedos.bs"
  1517.  
  1518. ***** CUT HERE ***** BEGIN FILE keyboard.asm
  1519.  
  1520. INT16:  ;keyboard API
  1521. .getfun:
  1522.     ;jmp short .nofun
  1523. .eshift:
  1524.     ;jmp short .nofun
  1525. .entry:  ;call IntPrint
  1526.     ;call CheckIt
  1527.     push bp
  1528.     push bx
  1529.     mov bp,sp
  1530.     xchg ah,al
  1531.     cmp al,1
  1532.     je .checkkey    ;check for keystroke
  1533.     jb .getkey  ;get keystroke
  1534.     cmp al,3
  1535.     je .shift   ;get shift flags
  1536.     cmp al,5
  1537.     je .store   ;store keystroke
  1538.     cmp al,9
  1539.     je .getfun  ;get keyboard functionality
  1540.     cmp al,0x10
  1541.     je .getkey  ;get enhanced keystroke
  1542.     jb .nofun
  1543.     cmp al,0x12
  1544.     ;je .eshift  ;get extended shift states
  1545.     jb .checkkey    ;check for enhanched
  1546. .nofun  xchg ah,al
  1547. .noex   pop bx
  1548.     pop bp
  1549.     iret
  1550. .getkeyptr:
  1551.     cli ;clear interrupts for this operation
  1552.     cs mov bx,[BV.NextKey]
  1553.     cs cmp [BV.FirstFreeKey],bx
  1554.     ret
  1555. .checkkey:
  1556.     sti ;make sure interrupts were enabled at least for a moment
  1557.     or byte [bp+8],0x40 ;was +4 ;set zero to on ;SS
  1558.     call .getkeyptr
  1559.     je .nocheck
  1560.     cs mov ax,[bx]
  1561.     xchg ah,al
  1562.     xor byte [bp+8],0x40 ;was +4 ;toggle zero ;SS
  1563. .nocheck:
  1564.     jmp short .nofun
  1565. .getkeywaitlp:
  1566.     sti ;interrupts still disabled
  1567.     hlt ;interrupts disabled until halted
  1568. .getkey:
  1569.     call .getkeyptr
  1570.     je .getkeywaitlp  ;loop until we have a keypress
  1571.     cs mov ax,[bx]
  1572.     inc bx
  1573.     inc bx
  1574.     cs cmp [BV.KeyBufferEnd],bx ;do we need to loop over?
  1575.     jne .gnoloop
  1576.     cs mov bx,[BV.KeyBufferStart]
  1577. .gnoloop:
  1578.     cs mov [BV.NextKey],bx
  1579.     jmp short .noex
  1580. .shift:
  1581.     cs mov al,[0]   ;FIXME
  1582.     jmp short .noex
  1583. .store:
  1584.     push ax
  1585.     push ds
  1586.     push cs
  1587.     pop ds
  1588.     cli ;don't want two things updating the buffer at once!
  1589.     mov bx,[BV.FirstFreeKey]
  1590.     mov [bx],cx
  1591.     lea ax,[bx+2]
  1592.     cmp [BV.KeyBufferEnd],ax    ;do we need to loop over?
  1593.     jne .noloop
  1594.     mov ax,[BV.KeyBufferStart]
  1595. .noloop: ;if it was full, we'll pretend it never happened
  1596.     cmp [BV.NextKey],ax
  1597.     je .dropkey
  1598.     mov [BV.FirstFreeKey],ax
  1599. .dropkey:
  1600.     pushf
  1601.     call ProcessKeys ;just in case they sent a special key
  1602.     popf
  1603.     pop ds
  1604.     pop ax
  1605.     mov ah,0    ;can't use xor here
  1606.     jne .bufnotfull
  1607.     inc ah
  1608. .bufnotfull:
  1609.     jmp short .nocheck;.nofun
  1610.  
  1611. KeyUART: ;stack usage: 4+1 words
  1612.     cli
  1613.     push ax
  1614.     push bx
  1615.     push ds
  1616.     in al,0x3a
  1617.     test al,2
  1618.     jz .jiret
  1619.     ;ok, we know we have a key
  1620.     push cs
  1621.     pop ds
  1622.     ;let's get the character and write it to the buffer
  1623.     or al,0xf7  ;turn on all the bits besides parity in the status
  1624.     mov ah,al
  1625.     in al,0x38  ;get data byte
  1626.     mov bx,[BV.FirstFreeKey]
  1627.     mov [bx],ax
  1628.     lea ax,[2+bx]
  1629.     cmp [BV.KeyBufferEnd],ax    ;do we need to loop over?
  1630.     jne .noloop
  1631.     mov ax,[BV.KeyBufferStart]
  1632. .noloop: ;if it was full, we'll pretend it never happened
  1633.     cmp [BV.NextKey],ax
  1634.     je .dropkey
  1635.     mov [BV.FirstFreeKey],ax
  1636. .dropkey:
  1637.     mov al,0x37
  1638.     out 0x3a,al
  1639.     call ProcessKeys
  1640. .jiret  pop ds
  1641.     pop bx
  1642.     pop ax
  1643.     iret
  1644.  
  1645. ProcessKeys:
  1646.     ;destroys ax,bx,ds
  1647.     mov ax,0xfe00
  1648.     mov ds,ax
  1649.     ;do locking checks
  1650.     test byte [BV.LFlags+0x2400],0xe ;is something else in progress?
  1651.     jz .doit
  1652.     or byte [BV.LFlags+0x2400],0x20 ;yes, do it later
  1653.     ret
  1654. .doit:   ;start with the first used key
  1655.     mov bx,[BV.NextKey+0x2400]
  1656. .pkloop: ;retrieve the key to ax
  1657.     cs mov ax,[bx]
  1658.     ror ah,1
  1659.     ror ah,1
  1660.     ror ah,1
  1661.     xor ah,0xfe ;ah is 0 for no ctrl, 1 for ctrl
  1662.     test ah,0xfe
  1663.     jnz .noproc ;key was already processed
  1664.     ;process 'special' keys here, zero ax to clear them from the buffer
  1665.     cmp ax,0x103 ;ctrl break
  1666.     jne .nobreakout
  1667.     xor ax,ax
  1668.     cs mov [bx],ax  ;store key
  1669.     jmp Menu_Breakout
  1670. .nobreakout:
  1671.     shl ax,1
  1672.     xchg ax,bx
  1673.     mov bx,[bx] ;do ROM lookup
  1674.     xchg ax,bx
  1675.     cs mov [bx],ax  ;store key
  1676. .noproc: ;gotta check if we're to the free keys
  1677.     cmp [BV.FirstFreeKey+0x2400],bx
  1678.     je DisplayString.jret  ;yep, get out
  1679.     inc bx
  1680.     inc bx
  1681.     ;do we need to wrap over?
  1682.     cmp [BV.KeyBufferEnd+0x2400],bx
  1683.     jne .pkloop
  1684.     mov bx,[BV.KeyBufferStart+0x2400]
  1685.     jmp short .pkloop
  1686.  
  1687.  
  1688. ***** CUT HERE ***** BEGIN FILE menu.asm
  1689.  
  1690. Menu_Breakout:
  1691.     cld
  1692.     push ax
  1693.     push dx
  1694.     push ds
  1695.     push es
  1696.     mov ax,cs
  1697.     mov ds,ax
  1698.     mov es,ax
  1699. .clearKey:
  1700.     xor ax,ax
  1701.     int 0x16
  1702.     mov ah,1
  1703.     int 0x16
  1704.     jnz .clearKey
  1705.  
  1706.     ;test [BV.LFlags],byte 1
  1707.     ;jz .noVideo
  1708.     ;or [BV.LFlags],byte 0x40 ;request breakout callback upon video completion    mov al,'#'
  1709.     ;int 0x29
  1710.     ;pop es
  1711.     ;pop ds
  1712.     ;pop dx
  1713.     ;pop ax
  1714.     ;ret
  1715. .noVideo:
  1716.  
  1717.     ;or byte [BV.LFlags],8
  1718.     ;mov al,[BV.LFlags]
  1719.     ;and [BV.LFlags],byte 0xbf
  1720.     ;and al,0x40
  1721.     ;int 0x29
  1722. .lp0:
  1723.  
  1724.     call TickBuzzer
  1725. .keyloop:
  1726.     xor ax,ax
  1727.     int 0x16
  1728.     cmp al,'r'
  1729.     jne .noReboot
  1730.     jmp Reboot
  1731. .noReboot:
  1732.     cmp al,'0'
  1733.     jne .no0
  1734.     mov dl,0
  1735.     jmp short .setkey
  1736. .no0:
  1737.     cmp al,'1'
  1738.     jne .no1
  1739.     mov dl,1
  1740.     jmp short .setkey
  1741. .no1:
  1742.     cmp al,'c'
  1743.     jne .noc
  1744.     push si
  1745.     push di
  1746.     call CGA.Init
  1747.     pop di
  1748.     pop si
  1749. .noc:
  1750.  
  1751.     call TickBuzzer
  1752.  
  1753.     ;and byte [BV.LFlags],0xf7
  1754.     pop es
  1755.     pop ds
  1756.     pop dx
  1757.     pop ax
  1758.     ret
  1759.  
  1760. .setkey:
  1761.     push bx
  1762.     push cx
  1763.     push si
  1764.     push di
  1765.     mov di,BV.EncKey
  1766.     call Enter_Key
  1767.     pushf
  1768.     mov bx,dx
  1769.     and bx,1
  1770.     add bx,BV.DFlags
  1771.     ror byte [bx],1
  1772.     popf
  1773.     cmc
  1774.     rcl byte [bx],1
  1775.     call Generate_Subkeys
  1776.     pop di
  1777.     pop si
  1778.     pop cx
  1779.     pop bx
  1780. jmp short .lp0
  1781.  
  1782.  
  1783. Menu_SaveVideo:
  1784. ;save cursor position
  1785. ;save line 1
  1786. ;configure for single line video
  1787.     ;ret
  1788.  
  1789. Menu_RestoreVideo:
  1790. ;restore video settings
  1791. ;restore line 1
  1792. ;restore cursor position
  1793.     ;ret
  1794.  
  1795. ***** CUT HERE ***** BEGIN FILE misc.asm
  1796.  
  1797.  
  1798. ;FIXME:  Assumes BIOS_CS=BIOS_DS and BIOS_CS && 0xFF00=0
  1799.  
  1800. INT8:
  1801.     ;to be done
  1802. INT11:
  1803.     cs mov ax,[BV.Equipment]
  1804.     iret
  1805.  
  1806. INT12:
  1807.     cs mov ax,[BV.TotalRAM]
  1808. NoInterrupt:
  1809.     iret
  1810.  
  1811. Reboot:
  1812.     mov al,0xff
  1813.     out 0x3a,al ;reset keyboard UART for buggy OSes *cough*SANYO*cough*
  1814.     jmp 0xffff:0
  1815.  
  1816. INT15:
  1817.     push bp
  1818.     mov bp,sp
  1819.     or byte [bp+6],1 ;set carry - helps with freedos memory detection
  1820.     pop bp
  1821.     iret
  1822.    ;call IntPrint
  1823. ;   cmp ah,0xc0
  1824. ;   jne NoInterrupt
  1825. ;   push cs
  1826. ;   pop es
  1827. ;   mov bx,.table
  1828. ;   xor ah,ah
  1829. ;   popf ;fixme, this is invalid
  1830. ;   clc
  1831. ;   retf
  1832. ;.table dw .endtable-.starttable
  1833. ;.starttable
  1834. ;   db 0xf7 ;model
  1835. ;   db 0 ;submodel
  1836. ;   db 0 ;BIOS Revision
  1837. ;   db 0
  1838. ;   db 0x84 ;int16/ah=9 supported & non-8042 keyboard
  1839. ;   db 2    ;IML System
  1840. ;   db 8    ;ABIOS not supported
  1841. ;   db 0
  1842. ;   db "dsBIOS",0
  1843. ;.endtable
  1844.  
  1845.  
  1846. INT29:  ;fast console output
  1847.     ;push ax
  1848.     push bx
  1849.     mov bl,7
  1850.     cs mov bh,[BV.CurPage]
  1851.     push si
  1852.     call OnBoardVideo.WrTT
  1853.     pop si
  1854.     pop bx
  1855.     ;pop ax
  1856.     iret
  1857.  
  1858. FPUInterrupt:
  1859.     int 0x75
  1860.     int 0x2
  1861.     iret
  1862.  
  1863. DisplayString:
  1864.     ;ds:si=string, si is incremented to character after null
  1865.     ;bl=attribute
  1866.     ;direction flag must be set as desired, this clears carry
  1867.     push ax
  1868.     push bx
  1869. .lp lodsb
  1870.     or al,al
  1871.     jz .done
  1872.     int 0x29
  1873.     jmp short .lp
  1874. .done:
  1875.     pop bx
  1876.     pop ax
  1877. .jret:
  1878.     ret
  1879.  
  1880. DisplayNAX:
  1881.     push ax
  1882.     push dx
  1883.     push cs ;high byte is zero
  1884. .clp    xor dx,dx
  1885.     cs div word [.base]
  1886.     xchg ax,dx
  1887.     add ax,0xe30
  1888.     push ax
  1889.     xchg ax,dx
  1890.     or ax,ax
  1891.     jnz .clp
  1892. .dlp    pop ax
  1893.     or ah,ah
  1894.     jz .done
  1895.     int 0x29
  1896.     jmp short .dlp
  1897. .done   pop dx
  1898.     pop ax
  1899.     ret
  1900. .base   dw 10
  1901.  
  1902. TickBuzzer:
  1903. .lp:
  1904.     in al,0x3a
  1905.     test al,1
  1906.     jz .lp
  1907.     mov al,0x18
  1908.     out 0x38,al
  1909.     ret
  1910.  
  1911. InterruptCatcher:
  1912.     ;On entry:  low byte of CS=Interrupt number
  1913.     push cs
  1914.     jmp BIOS_CODE_SEG:InterruptCatcher.main
  1915. .main:
  1916.     push bp
  1917.     mov bp,sp
  1918.     push ax
  1919.     push si
  1920.     push ds
  1921.  
  1922.     push cs
  1923.     pop ds
  1924.     cld
  1925.     mov si,.msg
  1926.     call DisplayString
  1927.     mov al,[bp+2]
  1928.     xor ah,ah
  1929.     call DisplayNAX
  1930.     mov al,'/'
  1931.     int 0x29
  1932.     mov ax,[bp-2]
  1933.     call DisplayNAX
  1934.     call DisplayString
  1935.     pop ds
  1936.     pop si
  1937.     pop ax
  1938.     pop bp
  1939.     inc sp ;pop saved cs
  1940.     inc sp
  1941. iret
  1942. .msg:
  1943.     db "[dsBIOS: Unhandled Interrupt: ",0,"]",0
  1944.  
  1945.  
  1946. %ifdef PigsFly
  1947.  
  1948. DrawBox: ;this code is unfinished
  1949.     ;  Input:  AH=upper left row, AL=upper left col
  1950.     ;          BH=#rows (outside dimension, zero is width 1) BL=#cols
  1951.     ;Trashed:  CX, DX
  1952.     ;Internal: DX=current cursor pos
  1953.  
  1954.     ;Draw top line
  1955.     mov dx,al
  1956.  
  1957.     mov al,2 ;set cursor
  1958.     int 0x10
  1959.     mov al,201 ;upper left
  1960.     int 0x29
  1961.  
  1962.     mov cx,bx
  1963.     mov al,205 ;top mid
  1964. .topmid
  1965.     dec cl
  1966.     jz .notopmid
  1967.     int 0x29
  1968.     dec cl
  1969.     jmp short .topmid
  1970. .notopmid
  1971.     mov al,topright
  1972.     int 0x29
  1973.  
  1974.     ;now the middle portion
  1975.  
  1976.     inc
  1977.  
  1978.     ret
  1979.  
  1980. DisplayNAXH: ;Displays AX in hexadecimal
  1981.     push ax
  1982.     push dx
  1983.     push cs ;high byte is zero
  1984.     xor dx,dx
  1985.     cs div word [.base]
  1986.     add dx,0xe30
  1987.     push dx
  1988.     xor dx,dx
  1989.     cs div word [.base]
  1990.     add dx,0xe30
  1991.     push dx
  1992.     xor dx,dx
  1993.     cs div word [.base]
  1994.     add dx,0xe30
  1995.     push dx
  1996.     xor dx,dx
  1997.     cs div word [.base]
  1998.     add dx,0xe30
  1999.     push dx
  2000. .dlp    pop ax
  2001.     or ah,ah
  2002.     jz .done
  2003.     cmp al,0x3a
  2004.     jb .dit
  2005.     add al,7
  2006. .dit    int 0x29
  2007.     jmp short .dlp
  2008. .done   pop dx
  2009.     pop ax
  2010.     ret
  2011. .base   dw 16
  2012.  
  2013. IntPrint: ;meant to be called as first instruction of an interrupt handler
  2014.           ;(prints out registers and waits for a key)
  2015.     push ds
  2016.     push ax
  2017.     push si
  2018.     push cs
  2019.     pop ds
  2020.     push word [BV.CursorPos]
  2021.     mov [BV.CursorPos],word 0x1400
  2022.     mov si,MsgReg
  2023.     call DisplayString
  2024.     mov si,sp
  2025.     ss mov ax,[si+12];10]
  2026.     mov ds,ax
  2027.     ss mov si,[si+10];8]
  2028.     mov ax,[si-2]
  2029.     cs mov [BV.CursorPos],byte 4
  2030.     call DisplayNAXH
  2031.     cs mov [BV.CursorPos],byte 14
  2032.     mov si,sp
  2033.     ss mov ax,[si+4]
  2034.     call DisplayNAXH
  2035.     mov ax,bx
  2036.     call DisplayNAXH
  2037.     mov ax,cx
  2038.     call DisplayNAXH
  2039.     mov ax,dx
  2040.     call DisplayNAXH
  2041.     cs mov [BV.CursorPos],byte 36
  2042.     ss mov ax,[si+12];10]
  2043.     call DisplayNAXH
  2044.     ss mov ax,[si+6]
  2045.     call DisplayNAXH
  2046.     mov ax,es
  2047.     call DisplayNAXH
  2048.     mov ax,ss
  2049.     call DisplayNAXH
  2050.     ss mov ax,[si+10];8]
  2051.     call DisplayNAXH
  2052.     cs pop word [BV.CursorPos]
  2053.     pushf
  2054.     push cs
  2055.     mov ax,.gkret
  2056.     push ax
  2057.     push bp
  2058.     push bx
  2059.     jmp INT16.getkey
  2060. .gkret  pop si
  2061.     pop ax
  2062.     pop ds
  2063.     ret
  2064. %endif
  2065.  
  2066.  
  2067. ***** CUT HERE ***** BEGIN FILE onboardv.asm
  2068.  
  2069. ;BIOS INT10 Driver for the Sanyo MBC-55x Onboard Video
  2070.  
  2071. OnBoardVideo:   ;interrupt handler
  2072.     push si
  2073.     cld
  2074.     mov si,ax
  2075.     mov al,ah
  2076.     test al,0xf0
  2077.     cbw ;clear ah
  2078.     xchg ax,si
  2079.     jnz .OutOfRange
  2080.     shl si,1
  2081.     ;cs or [BV.LFlags],byte 1
  2082.     cli ;reentrant?  hah!
  2083.     cs call [si+.jmptable]
  2084. .OutOfRange:
  2085.     pop si
  2086.     ;cs and [BV.LFlags],byte 0xfe
  2087.     ;cs test [BV.LFlags],byte 0x40
  2088.     ;jnz .DoBIOSMenu
  2089.     iret
  2090. ;.DoBIOSMenu
  2091. ;    push ax
  2092. ;    mov al,'#'
  2093. ;    int 0x29
  2094. ;    pop ax
  2095. ;    call Menu_Breakout
  2096. ;    iret
  2097. .SetGetCursor:
  2098.     ;push bx
  2099.     ;mov bl,bh
  2100.     ;and bx,byte 7   ;pages not implemented in built-in video; always set page 0
  2101.     ;shl bx,1
  2102.     ;lea si,[byte BV.CursorPos+bx]
  2103.     ;pop bx
  2104.     sahf
  2105.     jnc .SetOnly
  2106.     cs mov dx,[BV.CursorPos] ;si
  2107.     cs mov cx,[BV.CEndLine]
  2108.     ret
  2109. .SetOnly:
  2110.     ;hide cursor if drawn!! FIXME
  2111.     ;validate cursor position!! FIXME
  2112.     cs mov [BV.CursorPos],dx ;si for addr
  2113.     ;ret
  2114. .SetPage:
  2115.     ;unimplimented for built-in video
  2116.     ;push di
  2117.     ;push dx
  2118.     ;push ax
  2119.     ;call InitCGA
  2120.     ;pop ax
  2121.     ;pop dx
  2122.     ;pop di
  2123.  
  2124.     ret
  2125. .SetMode:
  2126.     ;hmm... not really sure about this one... let's clear the
  2127.     ;screen and reset the cursor?  The CGA will care more.
  2128.     push es
  2129.     push di
  2130.     push cx
  2131.     ;call InitCGA
  2132.     xor di,di
  2133.     cld
  2134.     mov ax,VIDEO_SEG
  2135.     mov es,ax
  2136.     mov ax,di
  2137.     mov cx,0x2000 ;FIXME for hardware scrolling
  2138.     rep stosw
  2139.     cs mov word [BV.CursorPos],0
  2140.     pop cx
  2141.     pop di
  2142.     pop es
  2143.     mov ax,0030
  2144.     ret
  2145. .RdAttChr:
  2146.     mov ax,0x0320 ;unimplimented for built-in video
  2147. .NoFunction:
  2148.     ;ret
  2149. .SetCursorShape:
  2150.     ;ret
  2151. .ScrollDn:
  2152.     ret
  2153. .ScrollUp:
  2154.     push bx
  2155.     push cx
  2156.     jmp .doscroll ;HACK HACK FIXME FIXME
  2157.     ;ret
  2158. .WrAttChr:
  2159.     push ax
  2160.     push ds
  2161.     push es
  2162.     push di
  2163.     push cx
  2164.     push dx
  2165.     xchg ax,si  ;put ax in si (clears ah unless function > 127)
  2166.     cwd ;clear dx
  2167.     ;calculate dest. location
  2168.     ;xchg bh,bl
  2169.     ;mov di,bx
  2170.     ;xchg bh,bl
  2171.     ;and di,byte 7   ;max 8 pages
  2172.     ;shl di,1
  2173.     ;get the cursor data into ax and di (low=col high=row)
  2174.     cs mov ax,[BV.CursorPos];+di]
  2175.     ;take care of the row offset and swap it into di
  2176.     mov di,ax
  2177.     cs mov al,[BV.ScreenCols]
  2178.     mov dl,al
  2179.     shl dx,1
  2180.     shl dx,1
  2181.     mul ah
  2182.     shl ax,1
  2183.     xchg ax,di
  2184.     ;mask off the row
  2185.     cbw ;xor ah,ah (as long as rows < 128, this is safe)
  2186.     ;each col adds 4 to the offset
  2187.     ;add the col. offset on
  2188.     add di,ax
  2189.     times 2 shl di,1
  2190.     and si,0xff
  2191.     mov ax,VIDEO_SEG
  2192.     mov es,ax
  2193.     mov ah,0xff
  2194.     mov ds,ax
  2195.     times 3 shl si,1
  2196. .repchr movsw
  2197.     movsw
  2198.     add di,dx ;(columns-1) * 4
  2199.     sub di,4
  2200.     movsw
  2201.     lodsw
  2202.     cmp bl,1
  2203.     jne .noul
  2204.     mov ah,0xff
  2205. .noul   stosw
  2206.     sub di,dx ;columns * 4
  2207.     sub si,8
  2208.     loop .repchr
  2209.     pop dx
  2210.     pop cx
  2211.     pop di
  2212.     pop es
  2213.     pop ds
  2214.     pop ax
  2215.     ret
  2216. .WrChr:
  2217.     ;FIXME ideally, we read the old character and preserve the attribute?
  2218.     push bx
  2219.     mov bl,3
  2220.     call .WrAttChr
  2221.     pop bx
  2222.     ;ret
  2223. .WrPixel:
  2224.     ;ret
  2225. .RdPixel:
  2226.     ret
  2227.  
  2228.     ;WrTT starts here
  2229. .doscroll:
  2230.     ;cs mov [BV.CursorPos+si],word 0
  2231.     ;xchg ax,si
  2232.     ;mov ax,1
  2233.     ;mov bh,bl
  2234.     ;xor cx,cx
  2235.     ;cs mov dl,[BV.ScreenCols]
  2236.     ;dec dx
  2237.     ;mov dh,24
  2238.     ;xchg ax,si
  2239. ;.doscrollnocursor
  2240.     ;for now, just scroll up one line and blank last line
  2241.     push ax
  2242.     push ds
  2243.     push es
  2244.     ;bx, cx, and si are already preserved
  2245.     push di
  2246.     ;cld direction already cleared
  2247.     mov ax,VIDEO_SEG
  2248.     mov es,ax
  2249.     mov ds,ax
  2250.     mov al,8
  2251.     cs mov cl,[BV.ScreenCols]
  2252.     mul cl
  2253.     mov si,ax   ;cols*8
  2254.     xor di,di
  2255.     cs mov al,[BV.ScreenRows]
  2256.     mul cl
  2257.     shl ax,1
  2258.     shl ax,1
  2259.     xchg ax,cx;cols*(rows-1)*4
  2260.     rep movsw
  2261.     xchg ax,cx
  2262.     xor ch,ch
  2263.     shl cx,1
  2264.     shl cx,1 ;cols*4
  2265.     ;xor ax,ax ;cleared from last rep movsw
  2266.     rep stosw
  2267.     pop di
  2268.     pop es
  2269.     pop ds
  2270.     pop ax
  2271.     jmp short .done
  2272.  
  2273. .do13   cs mov byte [BV.CursorPos],0 ;+si for cursor pages
  2274.     pop bx
  2275.     ret
  2276. .offS   cs mov byte [BV.CursorPos],0 ;+si
  2277. .do10   cs cmp byte [BV.CursorPos+1],24 ;+si
  2278.     je .doscroll
  2279.     cs inc byte [BV.CursorPos+1] ;+si
  2280.     pop cx
  2281.     pop bx
  2282.     ret
  2283. .doFF:
  2284.     pop bx
  2285.     jmp .SetMode
  2286. .WrTT:
  2287.     push bx
  2288.     ;hide cursor if drawn!! FIXME
  2289.     xchg bh,bl
  2290.     mov si,bx
  2291.     xchg bh,bl
  2292.     and si,7
  2293.     shl si,1
  2294.  
  2295.     cmp al,13   ;cr
  2296.     ja .doNormalCX
  2297.     je .do13
  2298.     cmp al,8    ;backspace
  2299.     je .do8
  2300.     cmp al,12
  2301.     je .doFF
  2302.     push cx ;we need to keep cx at this point
  2303.     cmp al,9
  2304.     je .do9
  2305.     cmp al,10   ;lf
  2306.     je .do10
  2307.     cmp al,7    ;beep
  2308.     jne .doNormal
  2309. .do7    xchg ax,si
  2310.     mov cx,3
  2311. .lp7    call TickBuzzer
  2312.     loop .lp7
  2313.     xchg ax,si
  2314.     jmp short .done
  2315.  
  2316. .doNormalCX:
  2317.     push cx
  2318. .doNormal:
  2319.     mov cx,1
  2320.     push ax
  2321. .doD    push si
  2322.     mov bl,3
  2323.     call .WrAttChr
  2324.     pop si
  2325.     pop ax
  2326.     cs add cx,[BV.CursorPos] ;+si
  2327.     ;check if past end of line
  2328.     cs cmp cl,[BV.ScreenCols]
  2329.     jae .offS
  2330.     cs mov [BV.CursorPos],cl ;normal increment +si
  2331. .done   pop cx
  2332.     pop bx
  2333.     ret
  2334. .do9    xor cx,cx
  2335.     cs mov cl,[BV.CursorPos] ;+si
  2336.     add cl,8
  2337.     and cl,0xf8
  2338.     cs sub cl,[BV.CursorPos] ;+si
  2339.     push ax
  2340.     mov al," "
  2341.     jmp short .doD
  2342. .do8    mov bl,0xff
  2343.     cs add bl,[BV.CursorPos] ;+si
  2344.     jnc .nobs
  2345.     cs mov [BV.CursorPos],bl ;+si
  2346. .nobs   pop bx
  2347.     ret
  2348.  
  2349. .GetState:
  2350.     cs mov ax,[BV.CurMode]
  2351.     cs mov bh,[BV.CurPage]
  2352.     ret
  2353. .jmptable:
  2354.     dw .SetMode
  2355.     dw .SetCursorShape
  2356.     dw .SetGetCursor ;set
  2357.     dw .SetGetCursor ;get
  2358.     dw .NoFunction
  2359.     dw .NoFunction ;.SetPage
  2360.     dw .ScrollUp
  2361.     dw .ScrollDn
  2362.     dw .RdAttChr
  2363.     dw .WrAttChr
  2364.     dw .WrChr
  2365.     dw .NoFunction
  2366.     dw .WrPixel
  2367.     dw .RdPixel
  2368.     dw .WrTT
  2369.     dw .GetState
  2370.  
  2371. ***** CUT HERE ***** BEGIN FILE rijndael.asm
  2372.  
  2373.     ;; Rijndael Encryption Algorithm, in 80186/286 assembler, version 1.2b
  2374.     ;; Copyright (C) 2000 Rafael R. Sevilla
  2375.     ;; (Modified 2005 by Brad Normand for optimization and use in dsBIOS)
  2376.     ;;
  2377.     ;; This library of encryption routines is free software; you can
  2378.     ;; redistribute it and/or modify it under the terms of the GNU Lesser
  2379.     ;; General Public License as published by the Free Software Foundation;
  2380.     ;; either version 2 of the License, or (at your option) any later
  2381.     ;; version.
  2382.     ;;
  2383.     ;; This Rijndael Encryption code is distributed in the hope it will
  2384.     ;; be useful, but WITHOUT ANY WARRANTY; without even the implied
  2385.     ;; warranty of MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE.
  2386.     ;; See the GNU Lesser General Public License for more details.
  2387.     ;;
  2388.     ;; You should have received a copy of the GNU Lesser General Public
  2389.     ;; License along with this Rijndael Encryption code; see the file
  2390.     ;; COPYING.LIB.  If not, write to the Free Software Foundation, Inc.,
  2391.     ;; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  2392.     ;;
  2393.     ;; Note that the only 80186 instructions here are shr/shl instructions
  2394.     ;; with multibit counts, and these only appear in the key expansion
  2395.     ;; function.  (These instructions have been changed to 8086 compatible
  2396.     ;; equivalents -Brad)
  2397.     ;;
  2398.     ;; Heavy restructuring and optimization has been done to increase speed
  2399.     ;; on 8086 type machines - Brad
  2400.     ;;
  2401.     ;; The modification here has incorporated a few changes suggested by
  2402.     ;; Robert G. Durnal (afn21533@afn.org), and a major bugfix in the
  2403.     ;; key generation code.
  2404.     ;;
  2405.     ;; Rijndael was developed by Joan Daemen and Vincent Rijmen
  2406.     ;;
  2407.  
  2408. CPU 186 ;actually 8086, but dsBIOS needs this
  2409.  
  2410. ;SECTION    .data   ;(For the dsBIOS project, CS=DS -Brad)
  2411.  
  2412.     ;; S-box for Rijndael
  2413. sbox:
  2414. %ifdef rijndael_empty_data  ;dsBIOS generates these at boot
  2415.     times 256 db 0
  2416. %else
  2417.     db   99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43
  2418.     db  254, 215, 171, 118, 202, 130, 201, 125, 250,  89,  71, 240
  2419.     db  173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147,  38
  2420.     db   54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21
  2421.     db    4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226
  2422.     db  235,  39, 178, 117,   9, 131,  44,  26,  27, 110,  90, 160
  2423.     db   82,  59, 214, 179,  41, 227,  47, 132,  83, 209,   0, 237
  2424.     db   32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207
  2425.     db  208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127
  2426.     db   80,  60, 159, 168,  81, 163,  64, 143, 146, 157,  56, 245
  2427.     db  188, 182, 218,  33,  16, 255, 243, 210, 205,  12,  19, 236
  2428.     db   95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115
  2429.     db   96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20
  2430.     db  222,  94,  11, 219, 224,  50,  58,  10,  73,   6,  36,  92
  2431.     db  194, 211, 172,  98, 145, 149, 228, 121, 231, 200,  55, 109
  2432.     db  141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8
  2433.     db  186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31
  2434.     db   75, 189, 139, 138, 112,  62, 181, 102,  72,   3, 246,  14
  2435.     db   97,  53,  87, 185, 134, 193,  29, 158, 225, 248, 152,  17
  2436.     db  105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223
  2437.     db  140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15
  2438.     db  176,  84, 187,  22
  2439. %endif
  2440.  
  2441.     ;; Inverse S-box for Rijndael
  2442. isbox:
  2443. %ifdef rijndael_empty_data
  2444.     times 256 db 0
  2445. %else
  2446.     db   82,   9, 106, 213,  48,  54, 165,  56, 191,  64, 163, 158
  2447.     db  129, 243, 215, 251, 124, 227,  57, 130, 155,  47, 255, 135
  2448.     db   52, 142,  67,  68, 196, 222, 233, 203,  84, 123, 148,  50
  2449.     db  166, 194,  35,  61, 238,  76, 149,  11,  66, 250, 195,  78
  2450.     db    8,  46, 161, 102,  40, 217,  36, 178, 118,  91, 162,  73
  2451.     db  109, 139, 209,  37, 114, 248, 246, 100, 134, 104, 152,  22
  2452.     db  212, 164,  92, 204,  93, 101, 182, 146, 108, 112,  72,  80
  2453.     db  253, 237, 185, 218,  94,  21,  70,  87, 167, 141, 157, 132
  2454.     db  144, 216, 171,   0, 140, 188, 211,  10, 247, 228,  88,   5
  2455.     db  184, 179,  69,   6, 208,  44,  30, 143, 202,  63,  15,   2
  2456.     db  193, 175, 189,   3,   1,  19, 138, 107,  58, 145,  17,  65
  2457.     db   79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115
  2458.     db  150, 172, 116,  34, 231, 173,  53, 133, 226, 249,  55, 232
  2459.     db   28, 117, 223, 110,  71, 241,  26, 113,  29,  41, 197, 137
  2460.     db  111, 183,  98,  14, 170,  24, 190,  27, 252,  86,  62,  75
  2461.     db  198, 210, 121,  32, 154, 219, 192, 254, 120, 205,  90, 244
  2462.     db   31, 221, 168,  51, 136,   7, 199,  49, 177,  18,  16,  89
  2463.     db   39, 128, 236,  95,  96,  81, 127, 169,  25, 181,  74,  13
  2464.     db   45, 229, 122, 159, 147, 201, 156, 239, 160, 224,  59,  77
  2465.     db  174,  42, 245, 176, 200, 235, 187,  60, 131,  83, 153,  97
  2466.     db   23,  43,   4, 126, 186, 119, 214,  38, 225, 105,  20,  99
  2467.     db   85,  33,  12, 125
  2468. %endif
  2469.  
  2470. ;SECTION    .text   ;(see note above -Brad)
  2471.  
  2472.     ;; small procedure to mix keys.  CX must point to round key offset.
  2473.     ;; Destroys AX, SI (nosetup adds 16 to SI), and DI.  Clears direction.
  2474. mixkey:
  2475.     cld
  2476.     mov si,[bp+6]   ; base address of round keys
  2477.     add si,cx       ; make si address of current round key
  2478.     mov bx,[bp+4]   ; load cipher state address
  2479. mixkey_nosetup:
  2480.     lodsw           ; load first word BEFORE finding offset
  2481.     sub bx,si       ; bx is the offset between the round key and state
  2482.     %rep 7
  2483.       xor [si+bx],ax
  2484.       lodsw
  2485.     %endrep
  2486.     xor [si+bx],ax
  2487.     ret
  2488.  
  2489. xlat_rotate:
  2490.     ;bx must point to translation table (sbox or isbox)
  2491.     ;if carry=1, rotate to right.  if carry=0, rotate left.
  2492.     ;destroys ax, dx, si, and di
  2493.     mov si,[bp+4]   ; load cipher state address
  2494.     mov di,si
  2495.  
  2496.     ;translate row 0 right away
  2497.     %rep 4
  2498.       lodsb
  2499.       xlatb
  2500.       stosb
  2501.     %endrep
  2502.  
  2503.     jc  .forward
  2504.     std     ;process backward
  2505.     add     si,10 ;position at end of block
  2506.     mov     di,si
  2507. .forward:
  2508.  
  2509.     ;; Rotate (cyclically shift) row 1 by one, row 2 by two and row 3
  2510.     ;; by three.
  2511.  
  2512.     ;load row 1 (or 3 backwards)
  2513.     lodsw
  2514.     xchg    ax,dx
  2515.     lodsw
  2516.     ;translate and rotate right by 1
  2517.     xlatb ;byte 1
  2518.     xchg    ah,al
  2519.     xlatb ;byte 0
  2520.     xchg    dl,al
  2521.     xlatb ;byte 3
  2522.     xchg    dh,al
  2523.     xlatb ;byte 2
  2524.     ;store row 1 back (the loading order has shifted it by 2)
  2525.     stosw
  2526.     xchg    ax,dx
  2527.     stosw
  2528.  
  2529.     ;load row 2
  2530.     lodsw
  2531.     xlatb ;byte 1
  2532.     xchg    ah,al
  2533.     xlatb ;byte 0
  2534.     xchg    ah,al
  2535.     xchg    ax,dx
  2536.     lodsw
  2537.     xlatb ;byte 3
  2538.     xchg    ah,al
  2539.     xlatb ;byte 2
  2540.     xchg    ah,al
  2541.     ;store row 2 back (the loading order has shifted it by 2)
  2542.     stosw
  2543.     xchg    ax,dx
  2544.     stosw
  2545.  
  2546.     ;load row 3 (or 1 backwards) into ax:dx
  2547.     lodsw           ; first half of row
  2548.     xchg    ax,dx       ; lives in DX
  2549.     lodsw           ; second half of row lives in AX
  2550.     ;translate and rotate row 1 left by 1 (right by 3)
  2551.     xlatb ;byte 1
  2552.     xchg    dh,al
  2553.     xlatb ;byte 2
  2554.     xchg    dl,al
  2555.     xlatb ;byte 3
  2556.     xchg    ah,al
  2557.     xlatb ;byte 0
  2558.     ;store row 3 back
  2559.     stosw           ; store first half of row
  2560.     xchg    ax,dx       ; make ax the second
  2561.     stosw           ; store second half of row
  2562.     ;cld        ;mixkey clears direction flag
  2563.     ret
  2564.  
  2565.  
  2566. ;   global  _rijndael_encrypt   ;(don't need globals for dsBIOS -Brad)
  2567. rijndael_encrypt:
  2568.     push    bp
  2569.     mov bp,sp
  2570.     push    si
  2571.     push    di
  2572.     xor cx,cx
  2573.     call    mixkey
  2574.     mov cl,16       ; round key offset (16*round_number)
  2575. .round_top:
  2576.     mov bx,sbox     ; translate using sbox
  2577.     stc         ; rotate right
  2578.     call xlat_rotate    ; translate and rotate
  2579.  
  2580.     cmp cl,224  ;was cx ; are we at round 14 (16*14)?
  2581.     je  .finalize   ; yes, jmp
  2582.     ;; Do the MixColumn transformation.
  2583.     mov di,4        ; column loop counter
  2584.     mov si,[bp+di];di=4 ; load the address of the state
  2585.     ;push    bp
  2586.     push    cx      ; save cx
  2587. .do_mixcolumn:
  2588.     mov cl,[si]     ; zeroth byte of column
  2589.     mov dl,[si+4]   ; first byte of column
  2590.     mov ch,[si+8]   ; second byte of column
  2591.     mov dh,[si+12]  ; third byte of column
  2592.     mov bp,cx       ; save a[j] and a[j+8] to xor with
  2593.     mov ax,cx       ; let ax = tmp,tmp
  2594.     xor ax,dx
  2595.     xor ah,al
  2596.     mov al,ah       ; tmp is set up
  2597.     xor cx,dx       ; xor with a[j+4], a[j+12]
  2598.  
  2599.     shl cl,1        ; xtime a[j] and a[j+8]
  2600.     sbb bl,bl
  2601.     shl ch,1
  2602.     sbb bh,bh
  2603.     and bx,0x1b1b
  2604.     xor cx,bx       ; xtime done
  2605.     xor cx,ax       ; xor with tmp
  2606.  
  2607.     xchg dh,dl  ; byteswap a[j+4], a[j+12] to line up for xor
  2608.     xor dx,bp   ; xor with saved a[j+8], a[j]
  2609.  
  2610.     shl dl,1    ; xtime these two bytes
  2611.     sbb bl,bl
  2612.     shl dh,1
  2613.     sbb bh,bh
  2614.     and bx,0x1b1b
  2615.     xor dx,bx   ; xtime done
  2616.  
  2617.     xor dx,ax   ; xor with tmp
  2618.  
  2619.     xor [si],cl     ; store back to state by xoring with orig
  2620.     xor [si+4],dh
  2621.     xor [si+8],ch
  2622.     xor [si+12],dl
  2623.     inc si      ; point to next column
  2624.     dec di
  2625.     jnz .do_mixcolumn
  2626.     pop cx      ; restore cx
  2627.     ;pop bp
  2628.     mov bp,sp
  2629.     add bp,4
  2630.     call    mixkey      ; mix the key
  2631.     add cx,16  ; increment the loop counter
  2632.     jmp short .round_top
  2633. .finalize:
  2634.     ;; Perform a final key mixing before finishing up
  2635.     call    mixkey
  2636.     pop di
  2637.     pop si
  2638.     pop bp
  2639.     ret
  2640.  
  2641. ;   global  _rijndael_decrypt
  2642. rijndael_decrypt:
  2643.     push    bp
  2644.     mov bp,sp
  2645.     push    si
  2646.     push    di
  2647.     mov cx,224      ; round key offset (14*16)
  2648.     ;; Perform the initial key mixing operation
  2649.     call    mixkey
  2650.     ;; The first round doesn't perform the inverse column mixing.
  2651.     jmp .start_isbox
  2652. .round_top:
  2653.     call    mixkey
  2654.     ;; The inverse column mixing is much more ticklish than the straight
  2655.     ;; mix...
  2656.     mov si,[bp+4]   ; load the address of the state
  2657.     mov ch,4        ; column loop counter
  2658.     ;push    bp
  2659.     mov bp,0x1b1b   ; values for *2 operation
  2660. .do_invmixcolumn:
  2661.     push    cx
  2662.     mov cl,[si]     ; zeroth byte of column
  2663.     mov ch,[si+4]   ; first byte of column
  2664.     mov dl,[si+8]   ; second byte of column
  2665.     mov dh,[si+12]  ; third byte of column
  2666.     ;; Multiply by 0x0e in GF(2^8) (`*' denotes multiplication in GF(2^8))
  2667. .invmix_onecolumn:
  2668.     ;output bytes (low,high):
  2669.     ;ax=x,y di=z,w
  2670.     mov ax,cx ;ax(x,y)=w,x
  2671.     xor ax,dx ;ax(x,y)=w^y,x^z
  2672.  
  2673.     mov di,ax ;di(z,w)=w^y,x^z
  2674.     xor ah,cl ;ah(y)=w^x^z
  2675.     xor al,dh ;al(x)=w^y^z
  2676.     xchg ax,di ;ax=z,w di=x,y
  2677.     xor ah,dl ;ah(w)=x^y^z
  2678.     xor al,ch ;al(z)=w^x^y
  2679.  
  2680.     ;now do *2 to each source byte
  2681.     shl cl,1
  2682.     sbb bl,bl
  2683.     shl ch,1
  2684.     sbb bh,bh
  2685.     and bx,bp;0x1b1b
  2686.     xor cx,bx   ;first 2 done
  2687.     shl dl,1
  2688.     sbb bl,bl
  2689.     shl dh,1
  2690.     sbb bh,bh
  2691.     and bx,bp;0x1b1b
  2692.     xor dx,bx   ;all *2'd
  2693.  
  2694.     ;for this part, w:w,x x:x,y y:y,z z:z,w
  2695.     ;ax=z,w di=x,y
  2696.     xor ax,cx ;ax(z,w)=w,x
  2697.     xor al,dh ;al(z)=w^z
  2698.     xor ah,cl ;ah(w)=w^x
  2699.     xchg ah,al
  2700.     xchg ax,di ;ax=x,y di=w,z
  2701.     xor ax,dx ;ax(x,y)=y,z
  2702.     xor al,ch ;al(x)=x^y
  2703.     xor ah,dl ;ah(y)=y^z
  2704.     xchg ah,al ;ax=y,x di=w,z
  2705.  
  2706.     ;now do *2 to each source byte
  2707.     shl cl,1
  2708.     sbb bl,bl
  2709.     shl ch,1
  2710.     sbb bh,bh
  2711.     and bx,bp;0x1b1b
  2712.     xor cx,bx   ;first 2 done
  2713.     shl dl,1
  2714.     sbb bl,bl
  2715.     shl dh,1
  2716.     sbb bh,bh
  2717.     and bx,bp;0x1b1b
  2718.     xor dx,bx   ;all *2'd
  2719.  
  2720.     ;for this part, w:w,y x:x,z y:w,y z:x,z
  2721.     ;ax=y,x di=w,z
  2722.     xor ax,cx
  2723.     xor ax,dx
  2724.     xor di,cx
  2725.     xor di,dx
  2726.  
  2727.     ;now do *2 to each source byte
  2728.     shl cl,1
  2729.     sbb bl,bl
  2730.     shl ch,1
  2731.     sbb bh,bh
  2732.     and bx,bp;0x1b1b
  2733.     xor cx,bx   ;first 2 done
  2734.     shl dl,1
  2735.     sbb bl,bl
  2736.     shl dh,1
  2737.     sbb bh,bh
  2738.     and bx,bp;0x1b1b
  2739.     xor dx,bx   ;all *2'd
  2740.  
  2741.     xor cx,dx   ;don't care about preserving source bytes anymore
  2742.     xor cl,ch
  2743.     mov ch,cl
  2744.     xor ax,cx
  2745.     xor cx,di   ;(moved to cx)
  2746.  
  2747.     ;ax=y,x cx=w,z
  2748.  
  2749.     mov [si],cl ;save bytes
  2750.     mov [si+4],ah
  2751.     mov [si+8],al
  2752.     mov [si+12],ch
  2753.  
  2754. ;.end_col_invmix:
  2755.     inc si      ; point to next column
  2756.     pop cx
  2757.     dec ch  ;column loop counter (clears carry)
  2758.     ;jnz .do_invmixcolumn
  2759.     jz .start_isbox
  2760.     jmp .do_invmixcolumn
  2761.     ;pop bp      ; restore saved registers
  2762. .start_isbox:
  2763.     mov bp,sp
  2764.     add bp,4
  2765.     mov bx,isbox    ; translate using isbox
  2766.     ;clc            ; rotate to the left (carry was cleared above)
  2767.     call xlat_rotate
  2768.     sub cx,16
  2769.     jz .do_mixkey
  2770.     jmp .round_top
  2771. .do_mixkey:
  2772.     call    mixkey
  2773.     pop di
  2774.     pop si
  2775.     pop bp
  2776.     ret
  2777.  
  2778. ;   global  _rijndael_keygen
  2779. rijndael_keygen:
  2780.     cld
  2781.     push    bp
  2782.     mov     bp,sp
  2783.     push    si
  2784.     push    di
  2785.     ;; Copy the original key data into the W[] array.  This generates
  2786.     ;; the keys used in the first two rounds.
  2787.     mov si,[bp+4]
  2788.     mov di,[bp+6]
  2789.     lea bx,[si+32]
  2790. .copy_again:
  2791.     mov cx,4
  2792. .copy_key:
  2793.     lodsw           ; get two bytes of key information
  2794.     mov [di],al
  2795.     mov [di+4],ah
  2796.     lodsw           ; get another two bytes of key info
  2797.     mov [di+8],al
  2798.     mov [di+12],ah
  2799.     inc di      ; point to next column
  2800.     loop .copy_key      ; (changed this to a loop -Brad)
  2801.     add di,12   ; point di to next block
  2802.     cmp si,bx
  2803.     jne .copy_again
  2804.     mov cl,7        ; key number minus 1 (ch was zeroed above)
  2805.     mov di,1        ; round constant
  2806.     ;mov bx,[bp+6]   ; base address of generated keys
  2807.     mov bx,cx
  2808.     mov si,bx
  2809.     and bl,0xfc     ; clear low four bits(only clears 2 bits? -Brad)
  2810.     shl bx,1        ; (granted these 'clear' the other two... -Brad)
  2811.     shl bx,1
  2812.     and si,3   ; mask low four bits (again, only 2 bits? -Brad)
  2813.     add bx,si
  2814.     add bx,[bp+6]       ; SI points to column to get
  2815. .keygen_loop:
  2816.     mov dl,[bx]
  2817.     mov dh,[bx+4]
  2818.     mov al,[bx+8]
  2819.     mov ah,[bx+12]
  2820.     inc cx
  2821.     ;; Now dl = first byte, dh = second, al = third, ah=fourth
  2822.     test    cl,00000011b    ; is round # div. by 4 or 8?
  2823.     jnz .not_div4   ; no...
  2824.     ;; Apply the S-boxes if round # is divisible by 4 or 8
  2825.     mov bx,sbox     ; load address of S-box for xlat
  2826.     xlatb           ; al = sbox[#3]
  2827.     xchg    ah,al       ; ah = sbox[#3], al=#4
  2828.     xlatb           ; ah=sbox[#3], al=sbox[#4]
  2829.     xchg    ax,dx       ; ah=#2, al=#1, dh=sbox[#3], dl=sbox[#4]
  2830.     xlatb           ; ah=#2, al=sbox[#1]
  2831.     xchg    ah,al       ; ah=sbox[#1], al=#2, dh=sbox[#3], dl=sbox[#4]
  2832.     xlatb           ; al=sbox[#2]
  2833.     ;; Now, ah=sbox[#1], al=sbox[#2], dh=sbox[#3], dl=sbox[#4].
  2834.     ;; Test whether round is divisible by 8.  If so, further transforms
  2835.     ;; are needed.
  2836.     test    cl,00000111b    ; is round # div by 8?
  2837.     jnz .not_div8   ; no...we're done
  2838.     ;; What we want is to rotate the data so that ah=sbox[#2], al=sbox[#3],
  2839.     ;; dh=sbox[#4], and dl=sbox[#1].  This is the cycle (0 1 2 3) which
  2840.     ;; can be turned into the product of transpositions (you by XCHG
  2841.     ;; instructions) (0 3)(0 2)(0 1)
  2842.     xchg    ah,dl       ; (0 3)
  2843.     xchg    ah,dh       ; (0 2)
  2844.     xchg    ah,al       ; (0,1)
  2845.  
  2846.     xchg bx,di  ;get round constant from di
  2847.     xor ah,bl   ;xor with round constant
  2848.     shl bl,1    ;update round constant
  2849.     sbb bh,bh
  2850.     and bh,0x1b
  2851.     xor bl,bh
  2852.     xchg bx,di  ;store next round constant back
  2853. .not_div8:
  2854.     ;; Now we have to rearrange the order of the registers again so that
  2855.     ;; from ah=#1, al=#2, dh=#3, dl=#4 => dl=#1, dh=#2, al=#3, ah=#4, so
  2856.     ;; that the following code gets the registers where they are expected.
  2857.     xchg    ah,dl
  2858.     xchg    al,dh
  2859. .not_div4:
  2860.     ;; When we enter here, dl=first byte, dh=second, al=third, ah=fourth
  2861.     ;; Perform indexing on the address of the previous key again.
  2862.     mov bx,cx
  2863.     mov si,bx
  2864.     and bl,0xfc
  2865.     shl bx,1
  2866.     shl bx,1
  2867.     and si,3
  2868.     add bx,si       ; offset into keys for first byte of old key
  2869.     add bx,[bp+6]   ; add base address of subkeys
  2870.     xor dl,[bx-32]     ; xor with current
  2871.     xor dh,[bx-28]
  2872.     xor al,[bx-24]
  2873.     xor ah,[bx-20]
  2874.  
  2875.     mov [bx],dl
  2876.     mov [bx+4],dh
  2877.     mov [bx+8],al
  2878.     mov [bx+12],ah
  2879.     cmp cx,59      ; last key?
  2880.     jne .keygen_loop
  2881. .done:  pop di
  2882.     pop si
  2883.     pop bp
  2884.     ret
  2885.  
  2886. ***** CUT HERE ***** BEGIN FILE timer.asm
  2887.  
  2888. ;ASSUMES BIOS_CODE_SEG = BIOS_DATA_SEG!!  FIXME
  2889.  
  2890. Timer0:
  2891.     cli
  2892.     push ax
  2893.     push dx
  2894.     push ds
  2895.     push cs
  2896.     pop ds
  2897.     mov dx,[BV.AuxTickCount]
  2898.  
  2899.     ;read timer 1
  2900.     in al,0x22
  2901.     mov ah,al
  2902.     in al,0x22
  2903.     xchg ah,al
  2904.  
  2905.     mov [BV.AuxTickCount],ax
  2906.     sub dx,ax
  2907.     shl dx,1 ;multiply dx by two because sanyo ticks are half as fast as normal IBM
  2908.  
  2909.     ;dx now has the amount of ticks elapsed since last time
  2910.     ;carry has an overflow bit
  2911.     adc word [BV.TimerTicksH],0
  2912.     add word [BV.TimerTicksL],dx
  2913.     adc word [BV.TimerTicksH],0
  2914.     cmp word [BV.TimerTicksH],24 ;check for 24 hours
  2915.     jb .carry2
  2916.     sub word [BV.TimerTicksH],24 ;24 hours
  2917.     inc byte [BV.DaysPassed]
  2918. .carry2:
  2919.     sti
  2920.     ;int 0x1c
  2921.     int 0x8 ;emulate hardware timer interrupt
  2922. .exit:
  2923.     pop ds
  2924.     pop dx
  2925.     pop ax
  2926.     iret
  2927.  
  2928.  
  2929. ;And some time/date API:
  2930. INT1A:
  2931.     cli ;don't want the time changing while we access it!!
  2932.     cmp ah,0x1
  2933.     je .set
  2934.     jnb .exit
  2935.  
  2936. .get: ;Get system time
  2937.     cs mov al,[0x70]
  2938.     cs mov cx,[BV.TimerTicksH];[0x6e]
  2939.     cs mov dx,[BV.TimerTicksL];[0x6c]
  2940.  
  2941. .set: ;Set system time
  2942.     cs mov byte [0x70],0x0 ;clear day counter
  2943.     cs mov [BV.TimerTicksH],cx
  2944.     cs mov [BV.TimerTicksL],dx
  2945. .exit:
  2946.     iret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement