home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / CEXPRESS.ZIP / TURBOBUG.ASM < prev    next >
Assembly Source File  |  1990-09-16  |  23KB  |  441 lines

  1. cseg      segment
  2.           org  100h
  3.           assume cs:cseg, ds:cseg
  4. buffer    equ  0B000h          ;address of video buffer (presently monochrome)
  5. int_num   equ  80h             ;1st INT of consecutive series of five
  6. begin:    jmp  set_up
  7. tag1      db 'S T A',26,'C K '
  8. tag2      db '  VAR',26
  9. bottom    db '  AX    BX    CX    DX    SI    DI    BP    SP    DS    ES  '
  10. msg       db 'TURBOBUG loaded',0AH,0DH,'$'
  11.  
  12. ;---NOTE: no provision for retrace synchronization -- causes a blizzard on CGA
  13.  
  14. ;---ROUTINE THAT DRAWS THE STACK BEGINS HERE:
  15. stack:    sti                  ;enable interrupts
  16.           pushf                ;save flags
  17.           push ds              ;save all changed registers
  18.           push es              ;
  19.           push di              ;
  20.           push si              ;
  21.           push ax              ;
  22.           push bx              ;
  23.           push cx              ;
  24.           push dx              ;
  25.           push cs              ;to get at variables (above) place
  26.           pop  ds              ;  code segment value in DS
  27.           mov  ax,buffer       ;point ES to video buffer
  28.           mov  es,ax           ;
  29.           cld                  ;set direction flag
  30. ;---DRAW "STACK" LABEL ON TOP LEFT OF SCREEN:
  31.           mov  ah,112          ;use reverse image
  32.           lea  si,tag1         ;point to the data string
  33.           mov  cx,5            ;extends over five rows
  34.           mov  di,0            ;ES:DI points to top left of screen
  35. L1:       lodsb                ;get a character
  36.           stosw                ;write it, with attribute
  37.           lodsb                ;get next character
  38.           stosw                ;write it to the right of the former
  39.           add  di,156          ;point to next row
  40.           loop L1              ;repeat
  41. ;---WRITE OUT THE STACK CONTENTS AND HEX EQUIVALENTS:
  42.           mov  cx,78           ;78 columns available
  43.           mov  di,324          ;point to 3rd col from left on 3rd row
  44.           push bp              ;will use BP as stack pointer
  45.           mov  bp,0FFFFH       ;point to top of stack
  46. L2:       mov  ah,112          ;drawn in reverse image
  47.           mov  al,[bp]         ;get a byte from the stack
  48.           dec  bp              ;point to byte below for next time
  49.           stosw                ;write the byte in reverse image
  50.           sub  ah,ah           ;byte in AL, clear AH
  51.           shl  ax,1            ;move top half of byte into AH
  52.           shl  ax,1            ;
  53.           shl  ax,1            ;
  54.           shl  ax,1            ;
  55.           shr  al,1            ;move bottom half back to bottom of AL
  56.           shr  al,1            ;
  57.           shr  al,1            ;
  58.           shr  al,1            ;
  59.           cmp  al,9            ;low nibble first: is it a numeral?
  60.           jb   L3              ;if so, jump ahead
  61.           add  al,55           ;else is A - F, add 55 to get ASCII code
  62.           jmp  short L4        ;go write it
  63. L3:       add  al,48           ;add 48 to get ASCII code for numeral
  64. L4:       mov  es:[di+318],al  ;write it
  65.           cmp  ah,9            ;high nibble next: is it a numeral?
  66.           jb   L5              ;repeat same process as above
  67.           add  ah,55           ;
  68.           jmp  short L6        ;
  69. L5:       add  ah,48           ;
  70. L6:       mov  es:[di+158],ah  ;
  71.           loop L2              ;
  72.           pop  bp              ;restore BP
  73. ;---PLOT BP POSITION:
  74.           mov  ax,bp           ;BP value to AX
  75.           neg  ax              ;NEG gives distance from top of stack
  76.           mov  bh,0            ;BH=0 flags that no scale drawn to right of BP
  77.           mov  dl,100          ;divide distance by 100
  78.           div  dl              ;
  79.           cmp  al,0            ;less than 100?
  80.           ja   L8              ;if not, no BP label is written
  81.           cmp  ah,78           ;less than or equal to 78? (available space)
  82.           ja   L8              ;if not, no label
  83.           je   L7              ;BP on last col, don't set flag for right scale
  84.           mov  bh,1            ;no jump, flag that chars later drawn to right
  85. ;---WRITE "BP" IF BP IS ON THE SCALE:
  86. L7:       push ax              ;save distance to BP
  87.           shl  ah,1            ;double it to calculate video buffer position
  88.           inc  ah              ;plus two more, since offsets are from BP=0
  89.           inc  ah              ;
  90.           mov  al,ah           ;transfer value to AL
  91.           sub  ah,ah           ;extend through AX
  92.           mov  di,ax           ;add value to buffer pointer
  93.           mov  ah,112          ;use reverse image
  94.           mov  al,'B'          ;prepare to write the 'B'
  95.           stosw                ;write it
  96.           add  di,158          ;shift to character cell below
  97.           mov  al,'P'          ;prepare to write the 'P'
  98.           stosw                ;write it
  99.           pop  ax              ;restore distance to BP
  100. ;---CALCULATE AND WRITE SCALE FROM LEFT UP TO BP:
  101.           sub  cx,cx           ;clear cx for counter
  102.           mov  cl,ah           ;distance to BP
  103.           dec  cl              ;minus 1 = number of chars to write
  104.           mov  ax,cx           ;copy in AX
  105.           push ax              ;use later to calc chars to right
  106.           jmp  short L9        ;go make the division
  107. ;---CASE WHERE BP IS OFF THE SCALE:
  108. L8:       mov  bh,0            ;flag that no chars to right
  109.           mov  cx,78           ;BP off scale, write 78 chars
  110.           mov  al,ah           ;move to AL the distance to BP
  111.           dec  al              ;minus 1 to adjust for offset from 0
  112.           sub  ah,ah           ;extend through AX
  113.           push ax              ;pseudo-PUSH, since other cases use it
  114. ;---WRITE SCALE TO LEFT OF BP:
  115. L9:       mov  di,164          ;pointer to first char
  116.           mov  dl,10           ;will divide by 10 for top line of scale
  117.           div  dl              ;now ten's place in AL, one's place in AH
  118.           add  ah,48           ;add 48 to get the ASCII char equivalent
  119.           inc  ah              ;INC to compensate for first DEC below
  120.           add  al,48           ;add 48 to get ASCII char equivalent
  121. L10:      dec  ah              ;in loop, decrement 1's place digit
  122.           cmp  ah,'0'          ;gotten to 0?
  123.           ja   L12             ;if not, no 10's place printed, jump ahead
  124.           jb   L11             ;if below '0', reset to '9'
  125.           mov  es:[di-160],al  ;1's place is '0', so print 10's place char
  126.           dec  al              ;decrement tens counter
  127.           cmp  al,'0'          ;below '0'yet?
  128.           jae  L12             ;if not, jump ahead
  129.           mov  al,'9'          ;else, reset to '9'
  130.           jmp  short L12       ;jump ahead
  131. L11:      mov  ah,'9'          ;this line used when 1's place is reset
  132. L12:      mov  es:[di],ah      ;print 1's place digit
  133.           inc  di              ;point 2 bytes ahead in the video buffer
  134.           inc  di              ;
  135.           loop L10             ;go do next char(s) of the scale
  136. ;---DRAW SCALE TO RIGHT OF BP (IF REQUIRED):
  137.           pop  ax              ;number chars to left
  138.           cmp  bh,0            ;test flag whether any chars
  139.           je   L16             ;if not, jump ahead and quit
  140.           mov  cx,77           ;max number of chars to draw (78 - 1 for bp)
  141.           sub  cx,ax           ;subtract number chars drawn on left
  142.           add  ax,5            ;adjust for extra chars on left
  143.           shl  ax,1            ;double the number for video buffer position
  144.           mov  di,156          ;start of line position in buffer
  145.           add  di,ax           ;add the offset
  146.           mov  al,'1'          ;start counting from 1
  147.           mov  ah,al           ;ten's place also starts from 1
  148. L13:      mov  es:[di],al      ;loop: write a 1's place character
  149.           inc  di              ;point to next buffer position
  150.           inc  di              ;
  151.           cmp  al,'0'          ;test whether 1's place has gotten to 0
  152.           jne  L14             ;if not, jump ahead
  153.           mov  es:[di-162],ah  ;if so, write a ten's place character
  154.           inc  ah              ;inc ten's place counter
  155. L14:      inc  al              ;inc one's place counter
  156.           cmp  al,':'          ;test if one's place has surpassed '9'
  157.           jb   L15             ;if not, jump ahead
  158.           mov  al,'0'          ;else, reset one's place counter to '0'
  159. L15:      loop L13             ;go write next character(s)
  160. L16:      pop  dx              ;done!
  161.           pop  cx              ;
  162.           pop  bx              ;
  163.           pop  ax              ;
  164.           pop  si              ;
  165.           pop  di              ;
  166.           pop  es              ;
  167.           pop  ds              ;
  168.           popf                 ;restore flags
  169.           iret                 ;return from the DISPLAY STACK interrupt
  170.  
  171. ;-------------------------Display Memory Variable---------------------------
  172.  
  173. ;---ON ENTRY, bx HOLDS OFFSET FROM bp OF VAR ADDRESS ON STACK
  174. ;---THE CALLING CODE MUST SAVE PRIOR CONTENTS OF bx IF THEY ARE REQUIRED
  175. var:      sti                  ;enable hardware interrupts
  176.           pushf                ;save flags
  177.           push ds              ;save all changed registers
  178.           push es              ;
  179.           push ax              ;
  180.           push cx              ;
  181.           push di              ;
  182.           push si              ;
  183.           cld                  ;set direction flag
  184. ;---WRITE THE 'VAR' LABEL:
  185.           push cs              ;set DS to CS value...
  186.           pop  ds              ;...in order to access TAG2
  187.           mov  ax,buffer       ;point ES to monochrome buffer
  188.           mov  es,ax           ;
  189.           mov  di,800          ;point to 6th row of screen
  190.           lea  si,tag2         ;DS:SI points to 'VAR' string
  191.           mov  cx,6            ;these are six characters
  192.           mov  ah,112          ;write them in reverse image
  193. B1:       lodsb                ;get a character
  194.           stosw                ;write it
  195.           loop B1              ;go do next
  196. ;---NOW WRITE OUT THE MEMORY CONTENTS:
  197.           mov  cx,74           ;number of cols available on the line
  198.           add  bx,bp           ;add BP value to the offset from BP
  199.           mov  ax,ss:[bx+2]    ;get segment address of var
  200.           mov  ds,ax           ;place in DS
  201.           mov  si,ss:[bx]      ;place offset of var in SI
  202.           mov  ah,15           ;write in intensified attribute
  203. B2:       lodsb                ;get a char
  204.           stosw                ;write it, setting the new attribute
  205.           loop B2              ;go do next char
  206.           pop  si              ;done!  restore changed registers
  207.           pop  di              ;
  208.           pop  cx              ;
  209.           pop  ax              ;
  210.           pop  es              ;
  211.           pop  ds              ;
  212.           popf                 ;restore flags
  213.           iret                 ;return from the DISPLAY VARIABLE interrupt
  214.  
  215. ;-------------------------Register Display Routine--------------------------
  216.  
  217. ;---THIS PROCEDURE WRITES OUT AX CONTENTS AS CHARS AND IN HEX:
  218. hexwrite  proc near
  219.           push bx              ;save changed registers
  220.           push ds              ;
  221.           push ax              ;point DS to BIOS data area
  222.           mov  ax,40h          ;
  223.           mov  ds,ax           ;
  224.           pop  ax              ;
  225.           mov  bh,4            ;test if ctrl key down
  226.           test ds:[17h],bh     ;
  227.           mov  bx,ax           ;copy input reg in case jump taken
  228.           jnz  C2              ;go make hex write if ctrl down
  229.           cmp  ah,es:[di-156]  ;test if high char is same as before
  230.           jne  C2              ;if not, go write hex equivalent
  231.           cmp  ah,32           ;is it a space char?
  232.           jne  C1              ;if not, will definitely not write in hex, jump
  233.           cmp  es:[di-160],ah  ;if spc, chk line above. Will be 32 if first
  234.           je   C2              ;  call on cleared screen, else FF from scroll
  235. C1:       add  di,4            ;not writing in hex, set buffer pointer ahead
  236.           jmp  short C7        ;jump ahead
  237. ;---WRITE THE HIGH BYTE IN HEX:
  238. C2:       shr  ax,1            ;shift AH halfway down into AL
  239.           shr  ax,1            ;
  240.           shr  ax,1            ;
  241.           shr  ax,1            ;
  242.           shr  al,1            ;shift AL nibble rest of the way down
  243.           shr  al,1            ;
  244.           shr  al,1            ;
  245.           shr  al,1            ;now high nibble in AH, low nibble in AL
  246.           cmp  ah,9            ;is high nibble a numeral?
  247.           ja   C3              ;if not, jump ahead
  248.           add  ah,48           ;add 48 to make ASCII char
  249.           jmp  short C4        ;jump ahead
  250. C3:       add  ah,55           ;A - F, so add 55 to make ASCII char
  251. C4:       cmp  al,9            ;repeat process for low nibble
  252.           ja   C5              ;  (not looped here and elsewhere
  253.           add  al,48           ;                for the sake of speed)
  254.           jmp  short C6        ;
  255. C5:       add  al,55           ;
  256. C6:       mov  es:[di],ah      ;write the high nibble
  257.           inc  di              ;move video buffer pointer to next col
  258.           inc  di              ;
  259.           stosb                ;write the low nibble
  260.           inc  di              ;move pointer to next col
  261. ;---WRITE THE HIGH AND LOW CHARS IN REVERSE IMAGE:
  262. C7:       mov  ah,112          ;code for reverse image
  263.           mov  al,bh           ;get copy of high char
  264.           stosw                ;write it
  265.           mov  al,bl           ;get copy of low char
  266.           stosw                ;write it
  267. ;---WRITE THE LOW BYTE IN HEX:
  268.           mov  bh,4            ;100B tests ctrl key
  269.           test ds:[17h],bh     ;chk BIOS variable whether ctrl key is down
  270.           mov  ah,bl           ;copy of low byte to AH now, before jump taken
  271.           jnz  C9              ;if ctrl down, write the char in hex
  272.           cmp  ah,es:[di-162]  ;test is char is the same as prior one
  273.           jne  C9              ;if not, write it in hex
  274.           cmp  ah,32           ;spc char is special case, since clears screen
  275.           jne  C8              ;if not spc, don't write hex equivalent
  276.           cmp  es:[di-160],ah  ;if a spc, chk if it is one from CLRSCR
  277.           je   C9              ;if so, write out the hex code
  278. C8:       add  di,8            ;don't write hex, adjust buffer pointer
  279.           jmp  short C14       ;finished, go quit routine
  280. C9:       shr  ax,1            ;write out the two hex digits as above
  281.           shr  ax,1            ;
  282.           shr  ax,1            ;
  283.           shr  ax,1            ;
  284.           shr  al,1            ;
  285.           shr  al,1            ;
  286.           shr  al,1            ;
  287.           shr  al,1            ;
  288.           cmp  ah,9            ;
  289.           ja   C10             ;
  290.           add  ah,48           ;
  291.           jmp  short C11       ;
  292. C10:      add  ah,55           ;
  293. C11:      cmp  al,9            ;
  294.           ja   C12             ;
  295.           add  al,48           ;
  296.           jmp  short C13       ;
  297. C12:      add  al,55           ;
  298. C13:      mov  es:[di],ah      ;
  299.           inc  di              ;
  300.           inc  di              ;
  301.           stosb                ;
  302.           add  di,5            ;forward buffer pointer to next register pos
  303. C14:      pop  ds              ;restore changed registers
  304.           pop  bx              ;
  305.           ret                  ;quit
  306. hexwrite  endp
  307.  
  308. ;---THE REGISTER DISPLAY PROCEDURE STARTS HERE:
  309. regs:     sti                  ;enable hardware interrupts
  310.           pushf                ;save flags
  311.           cld                  ;set direction flag
  312.           push ax              ;these three re-restored at end
  313.           push di              ;   since used in writing their own contents
  314.           push es              ;
  315.           push es              ;temporarily save ES and AX
  316.           push ax              ;            while checking Alt key
  317.           mov  ax,40h          ;point ES to BIOS data area
  318.           mov  es,ax           ;
  319.           mov  ah,8            ;see if Alt key is down
  320.           test es:[17h],ah     ;
  321.           pop ax               ;restore ES and AX
  322.           pop es               ;
  323.           jz   D1              ;go ahead if Alt key not down
  324.           jmp  D5              ;else, quit the routine
  325. D1:       push es              ;push altered registers onto stack
  326.           push ds              ;   in the left-right order in which they
  327.           push di              ;   are displayed
  328.           push si              ;
  329.           push cx              ;
  330.           push bx              ;
  331.           push ax              ;
  332.           mov  ax,buffer       ;now point ES to the video buffer
  333.           mov  es,ax           ;
  334.           push cs              ;set DS to CS to get at bottom-of-screen labels
  335.           pop  ds              ;
  336. ;---WRITE LABELS ON BOTTOM OF SCREEN:
  337.           mov  di,3842         ;ES:DI points to buffer position
  338.           lea  si,bottom       ;DS:SI points to data string
  339.           mov  cx,10           ;there are 10 labels
  340.           mov  ah,112          ;will draw in reverse image
  341. D2:       lodsb                ;get a byte
  342.           stosw                ;write it with attribute
  343.           lodsb                ;etc...
  344.           stosw                ;
  345.           lodsb                ;
  346.           stosw                ;
  347.           lodsb                ;
  348.           stosw                ;
  349.           lodsb                ;
  350.           stosw                ;
  351.           lodsb                ;
  352.           stosw                ;
  353.           add  di,4            ;forward pointer to next label
  354.           loop D2              ;go write next label
  355. ;---SCROLL THE 8TH - 24TH ROWS UPWARDS 1 LINE:
  356.           push es              ;set DS to video buffer address
  357.           pop  ds              ;
  358.           mov  di,960          ;di points to start of 7th row
  359.           mov  si,1120         ;si points to start of 8th row
  360.           mov  cx,1360         ;number of chars+attribute to transfer
  361.           rep  movsw           ;make the transfer
  362. ;---CLEAR 24TH ROW:
  363.           mov  cx,80           ;chars to clear
  364.           mov  ax,07FFH        ;use FF as the 'space' char, 7 as the attribute
  365.           mov  di,3680         ;DI points to start of the line
  366.           rep  stosw           ;clear it
  367. ;---DISPLAY THE REGISTERS:
  368.           mov  di,3682         ;point DI to position of first register
  369.           pop  ax              ;momentarily restore AX contents
  370.           call hexwrite        ;write AX
  371.           pop  bx              ;restore BX contents
  372.           mov  ax,bx           ;move copy to AX
  373.           call hexwrite        ;write BX
  374.           pop  cx              ;restore CX contents
  375.           mov  ax,cx           ;move copy to AX
  376.           call hexwrite        ;write CX
  377.           mov  ax,dx           ;DX unchanged, copy to AX
  378.           call hexwrite        ;write DX
  379.           pop  si              ;restore SI contents
  380.           mov  ax,si           ;move copy to AX
  381.           call hexwrite        ;write SI
  382.           pop  ax              ;DI in use, pop contents straight into AX
  383.           call hexwrite        ;write DI
  384.           mov  ax,bp           ;BP unchanged, copy to AX
  385.           call hexwrite        ;write BP
  386.           mov  ax,sp           ;SP unchanged
  387.           call hexwrite        ;write SP
  388.           pop  ds              ;restore DS
  389.           mov  ax,ds           ;move copy to AX
  390.           call hexwrite        ;write DS
  391.           pop  ax              ;ES in use, pop contents straight into AX
  392.           call hexwrite        ;write ES
  393. ;---CHECK SHIFT KEYS:
  394.           mov  ax,40h          ;point ES back to BIOS data area
  395.           mov  es,ax           ;
  396. D3:       mov  ah,8            ;1000B tests Alt key
  397.           test es:[17h],ah     ;is Alt down?
  398.           jnz  D5              ;if so, quit the routine
  399.           mov  ax,0102h        ;1B in AH, 10B in AL
  400.           test es:[17h],ah     ;test right shift
  401.           jnz  D5              ;no delay if right shift down
  402.           test es:[17h],al     ;test left shift
  403.           jz   D3              ;keep looping until shift or Alt key down
  404.           mov  al,es:[6Ch]     ;left shift down, read BIOS time-of-day
  405.           add  al,4            ;wait 4/18ths sec (may change this value)
  406. D4:       cmp  es:[6Ch],al     ;read new time-of-day  -- ready?
  407.           jne  D4              ;keep looping until ready
  408. D5:       pop  es              ;done! restore registers used
  409.           pop  di              ;    to display the register values
  410.           pop  ax              ;
  411.           popf                 ;
  412.           iret                 ;quit
  413.  
  414. ;---------------------DRAW STACK PLUS REGISTERS---------------------------
  415. all:      int  int_num         ;call stack routine
  416.           int  int_num+2       ;call register routine
  417.           iret                 ;done
  418.  
  419. ;--------------------------SETUP CODE-------------------------------------
  420. finish    equ  $               ;mark end of code for int 27h below
  421. set_up:   mov  dx,offset stack ;point DX to start of STACK DISPLAY code
  422.           mov  al,int_num      ;assign it to the base vector
  423.           mov  ah,25h          ;DOS function to set interrupt vector
  424.           int  21h             ;set the vector
  425.           mov  dx,offset var   ;point DX to start of DISPLAY VAR code
  426.           mov  al,int_num+1    ;assign it to the base vector + 1
  427.           int  21h             ;set the vector
  428.           mov  dx,offset regs  ;point DX to start of REGISTER DISPLAY code
  429.           mov  al,int_num+2    ;assign it to the base vector + 2
  430.           int  21h             ;set the vector
  431.           mov  dx,offset all   ;point DX to start of STACK PLUS REGS code
  432.           mov  al,int_num+3    ;assign it to the base vector + 3
  433.           int  21h             ;set the vector
  434.           mov  ah,9            ;DOS function to write string
  435.           lea  dx,msg          ;DS:DX pts to load message
  436.           int  21h             ;write the message
  437.           lea  dx,finish       ;point DX to end of all resident code
  438.           int  27h             ;exit, leaving all resident except setup code
  439. cseg      ends
  440.           end begin
  441.