Bubble Dizzy (PC)

Source Code
A big chunk of source code is present in sm.8.


 * sm.8 Codemasters "ABSOLUTELY BRILLIANT" logo.
 * sm.8 Codemasters "ABSOLUTELY BRILLIANT" logo.

video_int      =       int 10h general_int    =       int 21h keyboard_port  =       0060h

right_speed    =       8               ; Speed. "ABSOLUTELY" left_speed     =       -8              ; Speed. "BRILLIANT" centre         =       32              ; Counter

frame_counter: dw      0000h

file_length    =       54273 length2        =       13013 graphics_seg:  dw      0000h gfx_seg2:      dw      0000h pathname:      db      "gfx1.gfx",00h even fontname:      db      "antifont.bin",00h even off_tab:       dw      020h,0ah,00h,020h,4+0*1024,32,32 dw     020h,07h,02h,020h,4+2*1024,32,32 dw     020h,03h,03h,020h,4+3*1024,32,32 dw     020h,00h,04h,020h,4+4*1024,32,32            ; C                dw      037h,06h,01h,020h,4+1*1024,32,32 dw     037h,03h,05h,020h,4+5*1024,32,32 dw     037h,01h,06h,020h,4+6*1024,32,32 dw     037h,00h,07h,020h,4+7*1024,32,32            ; o
 * - Table of co-ords for the CodeMasters bit .....
 * 0 - X position
 * 2 - X shift
 * 4 - Frame no.
 * 6 - Y position
 * 8 - Offset to image
 * a - Width (pixels)
 * c - Height (pixels)
 * c - Height (pixels)

dw     049h,0ah,00h,021h,4+0*1024,32,32 dw     049h,03h,08h,021h,4+8*1024,32,32 dw     049h,01h,09h,021h,4+9*1024,32,32 dw     049h,00h,0ah,021h,4+10*1024,32,32           ; d

dw     05dh,06h,01h,020h,4+1*1024,32,32 dw     05dh,03h,0bh,020h,4+11*1024,32,32 dw     05dh,01h,0ch,020h,4+12*1024,32,32 dw     05dh,00h,0dh,020h,4+13*1024,32,32            ; e1

dw     06fh,06h,01h,020h,4+1*1024,32,32 dw     06fh,06h,0eh,020h,4+14*1024,32,32 dw     06fh,07h,0fh,020h,4+15*1024,32,32 dw     06fh,00h,10h,020h,4+16*1024,32,32            ; m

dw     08bh,06h,01h,020h,4+1*1024,32,32 dw     08bh,03h,11h,020h,4+17*1024,32,32 dw     08bh,01h,12h,020h,4+18*1024,32,32 dw     08bh,00h,13h,020h,4+19*1024,32,32            ; a

dw     09eh,06h,01h,020h,4+1*1024,32,32 dw     09eh,04h,14h,020h,4+20*1024,32,32 dw     09eh,02h,15h,020h,4+21*1024,32,32 dw     09eh,00h,16h,020h,4+22*1024,32,32            ; s1

dw     0aeh,0ah,00h,020h,4+0*1024,32,32 dw     0aeh,03h,17h,020h,4+23*1024,32,32 dw     0aeh,01h,18h,020h,4+24*1024,32,32 dw     0aeh,00h,19h,020h,4+25*1024,32,32            ; t                dw      0bdh,0ah,01h,020h,4+1*1024,32,32 dw     0bdh,03h,0bh,020h,4+11*1024,32,32 dw     0bdh,01h,0ch,020h,4+12*1024,32,32 dw     0bdh,00h,0dh,020h,4+13*1024,32,32            ; e2

dw     0cfh,06h,01h,020h,4+1*1024,32,32 dw     0cfh,04h,1ah,020h,4+26*1024,32,32 dw     0cfh,01h,1bh,020h,4+27*1024,32,32 dw     0cfh,00h,1ch,020h,4+28*1024,32,32            ; r                dw      0e1h,06h,01h,020h,4+1*1024,32,32 dw     0e1h,04h,14h,020h,4+20*1024,32,32 dw     0e1h,02h,15h,020h,4+21*1024,32,32 dw     0e1h,00h,16h,020h,4+22*1024,32,32            ; s

dw     0f3h,03h,1dh,01ah,30720+0000,64,48 dw     0f3h,03h,1eh,01ah,30720+3072,64,48 dw     0f3h,03h,1fh,01ah,30720+6144,64,48 dw     0f3h,03h,20h,01ah,30720+9216,64,48

code_offset    dw      0000h AbsolX         dw      72 AB_Flag        dw      0000h A_Flag:        db      0 B_Flag:        db      0 LettersX:      dw      0020h   ; X co-ord in pixels LettersY:      dw      00a4h   ; Y co-ord in pixels LettersW:      dw      000bh   ; Width in pixels LettersH:      dw      000dh   ; Height in pixels LettersS:      dw      0000h   ; Segment address of sprite data LettersO:      dw      143*3   ; Offset dw     0000h dw     0000h
 * - Sprite control block for letters for messages .....
 * - Sprite control block for letters for messages .....

sprite_0:      dw      0020h           ; X coord in pixels. sprite_02:     dw      0020h           ; Y coord in pixels. sprite_04:     dw      0020h           ; Width      . sprite_06:     dw      0020h           ; Height     . sprite_08:     dw      0000h           ; Segment of sprite data. dw     0000h           ; Offset         ''. dw     0000h dw     0000h sprite_1:      dw      -208            ; X coord in pixels. ; "ABSOLUTELY" sprite_12:     dw      80             ; Y coord in pixels. sprite_14:     dw      176             ; Width      . sprite_16:     dw      37-1            ; Height     . sprite_18:     dw      0000h           ; Segment of sprite data. dw     43008+4           ; Offset         ''. dw     0000h dw     0000h sprite_2:      dw      368             ; X coord in pixels. ; "BRILLIANT" sprite_22:     dw      120             ; Y coord in pixels. sprite_24:     dw      176             ; Width      . sprite_26:     dw      27-1            ; Height     . sprite_28:     dw      0000h           ; Segment of sprite data. dw     49520+4         ; Offset         ''. dw     0000h dw     0000h sprite_3:      dw      100             ; X coord in pixels. ; Squiggle. sprite_32:     dw      0020h           ; Y coord in pixels. sprite_34:     dw      0020h           ; Width      . sprite_36:     dw      0020h           ; Height     . sprite_38:     dw      0000h           ; Segment of sprite data. dw     0000h           ; Offset         ''. dw     0000h dw     0000h

gfx_lut:       dw      12*0            ; Long line. dw     1024*1          ; Short line. dw     1024*2          ; C                dw      1024*3 dw     1024*4 dw     1024*5          ; o                dw      1024*6 dw     1024*7 dw     1024*8          ; d                dw      1024*9 dw     1024*10 dw     1024*11         ; e                dw      1024*12 dw     1024*13 dw     1024*14         ; m                dw      1024*15 dw     1024*16 dw     1024*17         ; a                dw      1024*18 dw     1024*19 dw     1024*20         ; s                dw      1024*21 dw     1024*22 dw     1024*23         ; t                dw      1024*24 dw     1024*25 dw     1024*26         ; r                dw      1024*27 dw     1024*28 dw     1024*29         ; TM                dw      1024*30         ; CM 1 dw     30720+3072      ; CM 2 dw     30720+6144      ; CM 3 dw     30720+9216      ; CM 4 dw     43008           ; ABSOLUTELY dw     49520           ; BRILLIANT

key_vector_seg: dw     0000h           ; Stores INT 09h seg and adr. key_vector_adr: dw     0000h           ; for return to DOS.

scan_code:     db      00h             ; Scan code of last key even

on             =       00h             ; General ON. off            =       01h             ; General OFF.

screen_address: dw     0a000h          ; Start address of screen. screen_width:  dw      320             ; Screen width in pixels. screen_height: dw      200             ; Screen height in pixels.

video_mode:    db      013h            ; Initial video mode. even

palette:       db      000h,000h,000h  ; Background db     0ffh,0ffh,0ffh  ; Letters db     03fh,000h,020h  ; Squiggly db     018h,000h,020h  ;    '' db     028h,028h,028h db     018h,018h,018h db     008h,008h,008h db     000h,000h,000h db     038h,038h,038h  ; "ABSOLUTELY BRILLIANT" - filled db     008h,008h,008h  ; "ABSOLUTELY BRILLIANT" - outline db     028h,028h,028h db     000h,000h,000h db     000h,000h,000h db     000h,000h,000h db     30 DUP (0) db     0fch,0fch,0fch db     0ffh,0ffh,0ffh  ; Sheen bits db     03ch,03ch,03ch db     15 DUP (0) db     03ch,03ch,03ch db     020h,020h,020h db     010h,010h,010h db     663 DUP (0) even SelfCheckV     db      "10",0 even GameV          db      "10",0 even MasterD_T      db      "0706931500",0 even InfoLine       db      "T:v .   A:v .   D:  /  /     :  ",0 even CopyRightMess  db      "(c) Codemasters 1993.",0 even QuitFlag:      dw      0 Clock:         dw      0 NoCard:        dw      0 VerX:          dw      0 VerY:          dw      0 AB_Done:       dw      0 PutFlag:       dw      0 SheenX:        dw      0 SheenY:        dw      0 SheenFlag:     dw      0 SheenDone:     dw      0 SC_LookUp:     db      " ",4,"!",3,"`",4,"ú",6,"$",5,"%",8,"&",9 db     "'",3,"(",4,")",4,"*",5,"+",6,",",3,"-",7 db     ".",3,"/",4,"0",5,"1",5,"2",5,"3",5,"4",6 db     "5",5,"6",5,"7",5,"8",5,"9",5,":",3,";",3 db     "<",5,"=",6,">",5,"?",4,"#",6,"A",8,"B",6 db     "C",7,"D",7,"E",6,"F",6,"G",7,"H",8,"I",4 db     "J",5,"K",7,"L",6,"M",10,"N",8,"O",7,"P",6 db     "Q",7,"R",7,"S",5,"T",6,"U",8,"V",8,"W",12 db     "X",8,"Y",8,"Z",6,"[",4,"\",3,"]",3,"^",5 db     "_",6,"`",3,"a",4,"b",5,"c",4,"d",6,"e",4 db     "f",5,"g",5,"h",6,"i",3,"j",3,"k",6,"l",4 db     "m",9,"n",6,"o",5,"p",5,"q",6,"r",4,"s",4 db     "t",5,"u",6,"v",6,"w",9,"x",6,"y",6,"z",5 db     0ffh,0ffh even main:          push    ds,es           ; Program entry point mov    ds,cs mov    es,cs call   allocate_memory call   Allocate2 cmp    al,00h jnz    >o1 call   load_and_initialise call   Load2
 * - Message bits and pieces .....
 * - Message bits and pieces .....
 * - Variables for the clock waiting system .....
 * - Variables for the clock waiting system .....
 * - Co-ordinate variables for Version bits .....
 * - Co-ordinate variables for Version bits .....
 * - Co-ordinates for the sheen effect .....
 * - Co-ordinates for the sheen effect .....
 * - Proportional font table (Times 13) .....
 * - Proportional font table (Times 13) .....
 * PROGRAM
 * PROGRAM
 * PROGRAM

call   initialise_skeleton_data cmp    w[NoCard],0 je     CarryOn jmp    EndNow

CarryOn:       call    ResetVars call   SetCopyRight call   VersionFind mov    w[SheenX],72 mov    w[SheenY],80

call   action EndNow:        call    deallocate_memory call   DeAllocate2 call   restore_key_vector o1:            pop     es,ds mov    ax,000eh int    10h mov    ah,04ch general_int            ; Return to DOS. ResetVars:     mov     w[code_offset],0 mov    w[AbsolX],0 mov    w[AB_Flag],0 mov    w[QuitFlag],0 mov    w[Clock],0 mov    w[VerX],0 mov    w[VerY],0 mov    w[AB_Done],0 mov    w[SheenX],0 mov    w[SheenY],0 mov    w[SheenFlag],0 mov    w[SheenDone],0 mov    b[A_Flag],0 mov    b[B_Flag],0 mov    w[PutFlag],0 mov    w[AbsolX],72 ret SetCopyRight:  lea     si,CopyRightMess        ; Message - SI                xor     ax,ax xor    bx,bx xor    cx,cx xor    dx,dx SC_Outer:      mov     di,SC_LookUp            ; Lookup table - DI                mov     al,b[si] SC_FindLength: mov     bl,b[di] cmp    al,bl je     SC_FoundOne inc    di                inc     di                cmp     b[di+1],0ffh jne    SC_FindLength jmp    SC_Skip SC_FoundOne:   mov     cl,[di+1] add    dx,cx                   ; DX - length of string SC_Skip:       inc     si                cmp     b[si],0 jne    SC_Outer mov    cx,[screen_width] sub    cx,dx                   ; DX - screen width-string shr    cx,1                    ; For justification
 * - Resets all variables for re-entrant code .....
 * - Resets all variables for re-entrant code .....
 * - Sets up the copyright message in correct position on screen .....
 * Finds length of text to be put to screen
 * Puts text to screen
 * Puts text to screen

mov    w[LettersX],cx mov    w[LettersY],180

lea    si,CopyRightMess        ; Message SC_PrintIt:    xor     ax,ax xor    bx,bx xor    cx,cx SCP_Outer:     xor     dx,dx                   ; Cleared for length mov    di,SC_LookUp            ; Lookup table mov    al,b[si]                ; First message character SCP_FindLength: mov    bl,b[di]                ; First table character cmp    al,bl je     SCP_FoundIt inc    di                inc     di                      ; Next table entry inc    dx                      ; Number of letter cmp    b[di+1],0ffh            ; End of table? jne    SCP_FindLength jmp    SCP_Skip SCP_FoundIt:   mov     cl,b[di+1]                ; Letter length to CL                push    cx,ax                   ; Preserve true letter width mov    w[LettersW],11             ; Put width into sprite block mov    ax,143                  ; Letter size - 143 bytes mul    dx                      ; Get offset mov    dx,ax                   ; in DX                pop     ax,cx mov    LettersO,dx             ; Get offset push   ax,bx,cx,dx,si,di,bp mov    si,LettersX call   print_sprite pop    bp,di,si,dx,cx,bx,ax add    w[LettersX],cx          ; New X position SCP_Skip:      inc     si                mov     al,b[si] cmp    al,0 jne    SC_PrintIt SC_End:        ret VersionFind:   lea     si,InfoLine
 * - Places bits into version string, finds length for justification .....
 * - Places bits into version string, finds length for justification .....

lea    di,SelfCheckV mov    ax,[di] mov    b[si+3],al mov    b[si+5],ah

lea    di,GameV mov    ax,[di] mov    b[si+11],al mov    b[si+13],ah

lea    di,MasterD_T mov    ax,[di] mov    b[si+18],al mov    b[si+19],ah inc    di                inc     di                mov     ax,[di] mov    b[si+21],al mov    b[si+22],ah inc    di                inc     di                mov     ax,[di] mov    b[si+24],al mov    b[si+25],ah inc    di                inc     di                mov     ax,[di] mov    b[si+27],al mov    b[si+28],ah inc    di                inc     di                mov     ax,[di] mov    b[si+30],al mov    b[si+31],ah             ; Stores all bits in message

VF_Length:     lea     si,InfoLine

xor    ax,ax xor    bx,bx xor    cx,cx xor    dx,dx                   ; Work registers

VF_Outer:      mov     di,SC_LookUp mov    al,b[si] VF_FindLength: mov     bl,b[di] cmp    al,bl je     VF_FoundOne inc    di                inc     di                cmp     b[di+1],0ffh jne    VF_FindLength jmp    VF_Skip VF_FoundOne:   mov     cl,[di+1] add    dx,cx                   ; DX - string length VF_Skip:       inc     si                cmp     b[si],0 jne    VF_Outer

mov    cx,[screen_width] sub    cx,dx                   ; Screen width-string width shr    cx,1                    ; Correct start position mov    w[VerX],cx mov    w[VerY],160 ret action: l1:            call    RealTime call   CodeMasters call   AbsolBrill call   Info
 * General routines.
 * - THIS IS THE MAIN PROGRAM LOOP .....
 * - THIS IS THE MAIN PROGRAM LOOP .....
 * - THIS IS THE MAIN PROGRAM LOOP .....
 * - THIS IS THE MAIN PROGRAM LOOP .....
 * mov    cx,0ffffh
 * Waiter:        loop    Waiter

call   TestA cmp    w[AB_Done],0 je     WaitVBL cmp    w[SheenDone],0 jne    WaitVBL call   Sheen call   RemSheen

WaitVBL:       mov     dx,3dah WVBL1:         in      al,dx test   al,8 jne    WVBL1

mov    ax,3 int    33h cmp    bx,0                    ; Mouse pressed? je     A_Test jmp    A_End
 * call   AbsolBrill
 * mov    dx,3dah
 * WVBL2:         in      al,dx
 * test   al,8
 * jne    WVBL2

A_Test:        cmp     w[QuitFlag],0 jne    A_End

jmp    l1 A_End:          ret TestA:         mov     al,[scan_code] cmp    al,01eh+080h jne    TA_NotRelA mov    b[A_Flag],0 TA_NotRelA:    cmp     al,030h+080h jne    TA_NotRelB mov    b[B_Flag],0 TA_NotRelB:    cmp     al,01eh jne    TA_End mov    b[A_Flag],1 TA_End:        cmp     al,030h jne    TA_EndNow mov    b[B_Flag],1 TA_EndNow:     ret RemSheen:      cmp     w[SheenFlag],6 jb     RS_EndNow push   ax,bx,cx,dx,si,di,bp,ds mov    ax,w[SheenX] mov    bx,w[SheenY] sub    ax,32 mov    cx,70 RS_Outer:      push    ax,bx,cx,ds push   ax                mov     ax,320 mul    bx                mov     bx,ax pop    ax                mov     cx,8 mov    ds,[screen_address] mov    si,bx add    si,ax RS_Loop:    ds mov     al,b[si] sub    al,16 ds mov    b[si],al inc    si                loop    RS_Loop pop    ds,cx,bx,ax inc    bx                dec     ax                loop    RS_Outer RS_End:        pop     ds,bp,di,si,dx,cx,bx,ax RS_EndNow:     ret Sheen:         push    ax,bx,cx,dx,si,di,bp,ds mov    ax,w[SheenX] mov    bx,w[SheenY] mov    cx,70 S_Outer:       push    ax,bx,cx,ds             ; Save X,Y,Loop push   ax                      ; Save for MUL mov    ax,320 mul    bx                mov     bx,ax                   ; BX - line offset pop    ax                      ; Restore from MUL mov    cx,8                   ; Bytes to write/2 mov    ds,[screen_address] mov    si,bx                   ; Offset to si                add     si,ax                   ; Add X position S_Loop:     ds mov     al,b[si]                ; Read from screen add    al,16                   ; New value ds mov    b[si],al                ; Write it                inc     si                loop    S_Loop                  ; Do correct amount pop    ds,cx,bx,ax             ; Restore X,Y,Loop inc    bx                      ; Add to Y                dec     ax                      ; Take from X                loop    S_Outer                 ; Do outer loop S_End:         pop     ds,bp,di,si,dx,cx,bx,ax cmp    w[SheenFlag],8 je     S_Continue inc    w[SheenFlag] S_Continue:    add     w[SheenX],8 cmp    w[SheenX],312 jne    S_EndNow mov    w[SheenDone],0ffffh S_EndNow:      ret RealTime:      inc     w[Clock] cmp    w[Clock],(70*10) jne    RT_End mov    w[QuitFlag],0ffffh RT_End:        ret Info:          mov     al,[A_Flag] mov    ah,[B_Flag] add    al,ah cmp    al,2 jne    I_Clear jmp    I_Put I_End:         ret
 * - Test for A key being pressed .....
 * - Test for A key being pressed .....
 * - Remove the previous sheen .....
 * - Remove the previous sheen .....
 * - Do the sheen effect on the Absolutely Brilliant graphics .....
 * - Do the sheen effect on the Absolutely Brilliant graphics .....
 * - Set a clock up .....
 * - Set a clock up .....
 * - Put the information to screen .....
 * - Put the information to screen .....

I_Clear:       push    ax,cx,ds,si mov    w[PutFlag],0 mov    ds,[screen_address] xor    ax,ax mov    cx,(19*320)/2 mov    si,159*320 IC_Loop:    ds mov     [si],ax inc    si,2 loop   IC_Loop pop    si,ds,cx,ax IC_End:        ret

I_Put:         push    ax,bx,cx,dx,si,di,bp mov    w[clock],0

cmp    w[PutFlag],0 jne    IP_End mov    ax,[VerX] mov    bx,[VerY] mov    w[LettersX],ax mov    w[LettersY],bx lea    si,InfoLine IP_PrintIt:    xor     ax,ax xor    bx,bx xor    cx,cx IP_Outer:      xor     dx,dx mov    di,SC_LookUp mov    al,b[si] IP_FindLength: mov     bl,b[di] cmp    al,bl je     IP_FoundIt inc    di                inc     di                inc     dx                cmp     b[di+1],0ffh jne    IP_FindLength jmp    IP_Skip IP_FoundIt:    mov     cl,b[di+1] push   cx,ax mov    w[LettersW],11 mov    ax,143 mul    dx                mov     dx,ax pop    ax,cx mov    LettersO,dx push   ax,bx,cx,dx,si,di,bp mov    si,LettersX call   print_sprite pop    bp,di,si,dx,cx,bx,ax add    w[LettersX],cx IP_Skip:       inc     si                mov     al,b[si] cmp    al,0 jne    IP_PrintIt mov    w[PutFlag],1 IP_End:        pop     bp,di,si,dx,cx,bx,ax ret AbsolBrill:    cmp     w[AB_Done],0 jne    AB_End
 * - Put the Absolutely Brilliant bits to screen .....
 * - Put the Absolutely Brilliant bits to screen .....

mov    si,sprite_1 add    w[si+0],right_speed mov    si,sprite_2 add    w[si+0],left_speed

mov    si,sprite_1 call   print_sprite mov    si,sprite_2 call   print_sprite mov    si,sprite_1 mov    ax,[AbsolX] cmp    ax,w[si+0] jne    AB_End mov    w[AB_Done],0ffh AB_End:        ret CodeMasters:   mov     di,off_tab add    di,code_offset mov    si,sprite_0 mov    ax,[di+0]               ; X 32 justified mov    bx,[di+2]               ; X pixel offset mov    cx,[di+6] mov    w[si+0],ax add    w[si+0],bx              ; Get correct X pos mov    w[si+2],cx              ; Correct Y
 * - Process the CodeMasters data table and put sprites .....
 * - Process the CodeMasters data table and put sprites .....

mov    ax,[di+8] mov    w[si+10],ax             ; Correct offset

mov    ax,[di+10] mov    bx,[di+12] mov    w[si+4],ax mov    w[si+6],bx              ; New width and height

call   print_sprite cmp    [code_offset],47*14 je     CM_Skip                 ; add    [code_offset],14 CM_Skip:       ret load_and_initialise: mov    bx,pathname mov    cx,file_length mov    ax,[graphics_seg] mov    dx,0000h call   general_load
 * - Routine to load in any data needed .....
 * Entry: N/A
 * Exit:  AL - 0 if OK
 * AL - 0ffh if error
 * AL - 0ffh if error

mov    ax,[graphics_seg] mov    [sprite_08],ax mov    [sprite_18],ax mov    [sprite_28],ax mov    [sprite_38],ax ret

Load2:         mov     bx,fontname mov    cx,Length2 mov    ax,[gfx_seg2] mov    dx,0000h call   general_load

mov    ax,[gfx_seg2] mov    [LettersS],ax           ; Store segment addr. in list ret clip_sprite:   cmp     cx,320          ; Return clip width+new X.                jc      >s1 test   cx,08000h jz     >o2 jmp    >s2
 * - Routine to clip the sprites .....
 * - Routine to clip the sprites .....

s1:            mov     ax,320          ; Right clip. sub    ax,cx cmp    bx,ax jc     >o1 mov    bx,ax jmp    >o1 s2:            add     bx,cx           ; Left clip test   bx,08000h jnz    >o2 mov    ax,cx xor    cx,cx neg    ax                      ret o1:            xor     ax,ax ret o2:            xor     bx,bx ret dfloc:         push    ax                                 cs mov     ax,[screen_width] mul    dx                add     ax,cx mov    di,ax pop    ax                ret fblock:        push    si                add     ax,ax           ; Entry : AX=block number add    si,ax           ;         SI=LUT address. cs mov    ax,[si]         ; Exit  : AX=Table adr. pop    si                ret initialise_skeleton_data:                      ; Set palette,reset vars,etc. call   save_key_vector         ; For return to DOS. call   set_key_vector          ; Re-vector keyboard INT 09h. call   set_video_mode          ; Set mode to [VIDEO_MODE]. call   set_palette             ; Set palette to [PALETTE]. ret await_keys_press:                      ; Await any key press. xor    al,al cs mov    [scan_code],al l1:         cs mov     al,[scan_code] cmp    al,00h jz     l1                test    al,080h jnz    await_keys_press ret save_key_vector:                       ; Saves INT 09h vector for mov    al,09h          ; return to DOS. mov    ah,35h push   es                general_int cs mov    [key_vector_seg],es cs mov    [key_vector_adr],bx pop    es                ret set_key_vector:                                ; Set INT 09h vector to new mov    al,09h mov    ah,25h push   ds                mov     dx,keyboard_interrupt mov    ds,cs general_int pop ds                ret restore_key_vector:                            ; Set INT 09h vector to default mov    al,09h                  ; keyboard vector for DOS. mov    ah,25h push   ds             cs mov     dx,[key_vector_adr] cs mov    ds,[key_vector_seg] general_int pop    ds                ret keyboard_interrupt:                            ; GOTO here upon key press int. push   ax                in      al,keyboard_port cs mov    [scan_code],al ki_signal:     mov     al,020h                 ; Signal end of int. out    020h,al pop    ax ki_end:         iret print_sprite:                                  ; Print raster block to screen. ; Entry : SI = sprite control ;              block. push   ds,es mov    ds,cs
 * - Grab screen address (absolute) .....
 * Entry: CX - X, DX - Y
 * Exit:  DI - Screen address
 * Exit:  DI - Screen address
 * - Initialise some data .....
 * - Initialise some data .....
 * KEYBOARD routines.
 * KEYBOARD routines.
 * General VIDEO routines.
 * General VIDEO routines.

mov    cx,[si+0] mov    dx,[si+2] mov    bx,[si+4] call   clip_sprite cmp     bx,0 jz      >o1

call   dfloc           ; di=screen adr. mov    dx,[si+4] mov    cx,[si+6] mov    es,[si+8] mov    si,[si+10] add    si,ax mov    ds,[screen_address] l1:            push    cx,di,si mov    cx,bx shr    cx,1            ;JC l2:         es mov     ax,[si] ds mov    [di],ax inc    di                inc     di                inc     si                inc     si                loop    l2

pop    si,di,cx add    di,320 add    si,dx loop   l1 o1:             pop     es,ds ret

cls:           push    ax,cx,ds,si mov    ds,[screen_address] xor    ax,ax mov    cx,32768 mov    si,0000h l1:         ds mov     [si],ax inc    si,2 loop   l1                pop     si,ds,cx,ax ret set_palette:   push    es                                                mov     es,cs mov    ah,10h mov    al,12h mov    bx,0000h mov    cx,256 mov    dx,palette video_int pop    es                ret set_video_mode:                                ; Set mode to [VIDEO_MODE]. mov    ax,1a00h int    10h cmp    al,1ah jne    SVM_Quit cmp    bl,07h jb     SVM_Quit
 * -Set the colour palette .....
 * -Set the colour palette .....

mov    ah,00h mov    al,[video_mode] video_int ret

SVM_Quit:      mov     w[NoCard],1 ret general_load:                                  ; LOAD any file. ; Entry : CS:BX = Pathname ;      : CX    = File length ;      : AX:DX = Destination. push   ds                push    ax                push    cx                push    dx                      ; Open file.
 * General DISK routines.
 * General DISK routines.

mov    dx,bx mov    ah,03dh mov    al,02h general_int

pop    dx                pop     cx                pop     ds                      ; Read from file. mov    bx,ax push   bx                mov     ah,03fh general_int

pop    bx                mov     ah,03eh                 ; Close file. general_int

pop    ds                ret allocate_memory:                               ; Allocate 64k seg. of memory. mov    ah,048h                 ; Exit : AX=Segment address. mov    bx,4000 general_int jc     >o1 cs mov    [graphics_seg],ax xor    al,al ret o1:            mov     al,0ffh o2:            ret deallocate_memory:                             ; Deallocate 64k seg. of memory. mov    ah,049h push   es                mov     es,[graphics_seg] general_int pop es                ret Allocate2:     mov     ah,048h mov    bx,4000 general_int jc     >o1 cs mov    [gfx_seg2],ax xor    al,al ret o1:            mov     al,0ffh o2:            ret DeAllocate2:   mov     ah,049h push   es                mov     es,[gfx_seg2] general_int pop    es                ret prog_stack     segment word stack dw     400 dup 0000h top_of_stack: code           ends
 * Memory management routines.
 * Memory management routines.
 * - Second allocation of memory .....
 * - Second allocation of memory .....
 * - Stack and segment pieces .....
 * - Stack and segment pieces .....