42 classes w/ non-static member functions
38 classes w/ static member functions
33 enhanced fetch_next_byte
31 enhanced peek_next_byte
30 enhanced fetch_next_word

[some of these notes are very old, I need to weed thru them.]

check bx_logical.c: inverting flags with 1 - flag ???

make sure all code which sets EFLAGS fields, set them to either
 0 or 1 but not arbitrary numbers above 1
 * possibly use bitshifts.

is immediate16 in RET signed?

==============================================================

look at case where 2 timers have identical remainder times.  I don't believe
I handle this.

pop/push opcodes manipulate 32bit registers in 16bit mode.  should
only touch 16 bit reg's.

fix macros AX,AL,... to use registers directly instead of going through
  the arrays of pointers to registers.

--- Jan 16 '94
instructions which have 's' bit set need to sign extend 8bit values
to 16 or 32.  Group 1 EvIb & GvEvIb, etc.

look into other instructions which need to sign extend 8 or 16 bit
quantities.

fix all SAR's like SAR_EbCL: don't set OF for variable op2's
* cases found in SAR with Ev comparing shift count which is an 8bit quantity
  to 8, where 16 & 32 should have been used.  Does this carry over to
  other shift instructions?

added IRQ 5 = INT 0Dh handler for hard drive, didn't do anything.

call exit functions for each of the iodev modules upon exit() of
  bochs.  close_harddrive() is called already.

===================================
PCMag Chap 14: Incompatibilities & Bugs

FLAGS image:  image of flags saved on stack by interrupts, exceptions
              and the PUSHF instruction:
  8086: bits 12-15 are always 1.
  286: in real mode, they're always cleared. 
  386: in real mode: bit 15 always 0, 12-14 reflect value last loaded
    into them.
===================================

real mode exceptions: Interrupt 13 for a word operand at offset FFFFh.

macros fetch_next_xyz1() don't look at protected mode, etc.
  need to #ifdef them

need macros for bx_read_virtual_xyz(), bx_write_virtual_xyz()...
  Only useful for 8086

instructions which use registers before success is determined
won't be restartable.  Need to change to temp variables.

could revise main loop in bx_decode.  for i = 0..15 not necessary
for 80286? think 10 is the max len for 286

add checks/bailouts in LOADALL

check out keyboard with CHECKIT

changes to IMUL_ALEb() for OF & CF.  1/15/96
  need to change other variats of IMUL_ ???

make sure index,ti,rpl fields of selector set upon change of
  any descriptor

add BX_HANDLE_EXCEPTION() after all memory references, decodes, etc.

make sure to change flags AFTER final memory reference, in case of
  an exception

real-mode exception: interrupt 13 for word operand at offset FFFF

segment wraparound.  8086 wraps, 80286+ generates int 13 (0Dh)

ROL: flags comments says change O,C, only C changed.

PSEUDO_INT: check for protected mode stuff?

io addresses 00F8H .. 00FFH are dedicated for the 80287

CPL in CS: saw note that it is always in SS, most of time in CS?

any move into SS delays interrupts until after execution next instruction.

take extra test for null selector out of bx_access_virtual().  Added
  code for valid bit, so null test redundant.

check against descriptor being within limits wrong.  doesn't take into
consideration length of descriptor. (index*8 + 7) > limit

fetch_raw_descriptor does limit checks.  can remove redundant checks to
  ldtr & gdtr.

should BX_HANDLE_EXCEPTION() be after real-mode code?

IRET: invalidating code improperly.

fields in cache access are not 1/0 but N/0

check error values in #GP()'s in call_ap

add cache.valid = 1 after load_cs & load_cs_from_gate() calls.

return address CS.rpl should be caller's CPL

all but 2 exceptions are restartable after the condition is removed.
  processor extension segment overrun
  writing into read-only segments with XCHG, ADC, SBB, RCL, RCR

IDT base used in protected mode (usually 0000h)

in iret, should I set dpl of SS along with CS?

passing/pushing of error code to interrupt() & segment_exception() ???

inc SP, dec SP, etc change SP possibly beyond bounds.

check code for word_count copying stack-to-stack in call_ap()

make sure int handler codes don't overrun

put check back in bootstrap handler, that ES = 0

inline funcs like stack_has_room

unify fetch_raw_descriptor() & fetch_raw_descriptor2()

comment in memory.c & bios int 15 f87

change STI, retfar +2 to get IF off stack, then retfar +2 for
  certain int handlers

values of INTR INTR_vector after RESET? and switching to protected mode

check for writing to readable only data segment in DS & ES in memory.c?

change:
  SP = ... to bx_cpu.esp =
  IP = ... to bx_cpu.eip =
look for cases when upper bits set in both registers

fixed CF for ROR_eb1 & ROR_ev1 for 16 bit cases
  oops, they were already correct

commented out int15 function C0

fixed CF should be OF in LSL, LAR, VERR, VERW

pop into  SS holds interrupts for until next instruction finishes
  so a MOV SP, value can occur?

lar, lsl, verr, verw: taking out check for descriptor present ?

bios stuff: change unsupported flag 80h to 86?
            change PC model id to something more current?

-lICE in make

check for equality of DS & ES in POST

think about replacing RETfar +2 with IRET after modifying flags on stack.

optim: test using func pointers vs direct function call.  use func ptrs
  for real-mode/protected mode if it makes sense.

changed AAA & AAS

optim: maybe some goto's in decode.c instead of break & continue

lock: #UD

ltr: updated busy bit in descriptor in memory

popf: in real-mode changed to not setting IOPL & NT

memory.c: bomb if access to word at offset=ffff

read_flags(): take out checks

are not calling int15 call in int9 handler for releases

bios.c: bios_config_table: reflects int16&9 calls int15
keyboard.c: calling int15 for each keypress
  should leave CF=0 before int15 call, then set after?

changed OF & CF logic in imul

need to update PIC code for slave PIC, as per  newer master PIC code.

check out timers code

need to set async_event in pic.c upon asserting INTR line if IF set?

subtracted 1k from base memory size in bios.c for extended BIOS data area.

send EOI to slave or master 1st?

added EBDA: delete this?

commented out repne messages in decode.c: should fix rest of cases

masked out all IRQ's except keyboard in iodev/bios.c (for Minix)

am I clearing pending IRQ's after PIC is reprogrammed?

set base memory size to 640k when extended bios data area not used

hardware RESET masks all DMA channels

do I need to use L after long constants on certain machines.

fix CMOS reg 09, 08, 07, etc

hga registers e & f should set cursor locale.

make atomic inp16 & outp16 functions

Intel reserved opcodes (from 386 book: 9-15)
supposedly, these do not generate interrupt 6?
82
d6
f1
0f 07
0f 10
0f 11
0f 12
0f 13
f6 xx
f7 xx
c0 xx
c1 xx
d0 xx
d1 xx
d2 xx
d3 xx

in reset_cpu():
  are the invisible fields in GS, FS, SS set?

bx_write_flags(val16, change_iopl, change_if)
  look at change_if values passed, especially for iret
  use cpl<=IOPL for previous or new values of CPL for iret.
  changed from new to previous value, for IRET outer level

pic.c: allow only IRQ's of higher priority to signal an interrupt.
       previously higher-or-same.

hga.c: add limit check to start_address calculation
       start address needs to be at least 4000bytes = 2000 words
       from BFFFF.

hga.c: cursor_on() called from hga_clear_screen() and hga_refresh_screen()
       cursor_on() accesses BIOS data area which shouldn't occur for non
       DOS OS's.

hga.c: optimize changing of screen offset.  If multiple of line size
       in words, maybe scroll text instead of redisplaying

hga.c: extra hga_update()'s should be deleted.

changed offset to Bit32u in memory.c for bx_access_xyz() functions.
  have to look for cases where previous Bit16s was passed and is
  sign extended, which would be wrong for this case

pentium book: GDTR, IDTR after reset: why does it say
  AR=present, read/write.  Are there such bits?

added bx_async_event=1 after all bx_cpu.inhibit_interrupts=1

look at load_seg_reg() for ES DS ES FS GS in real mode.
  need to set g, d_b, avl fields?

look at use of cs.segment.d_b for default sizes when switching
  from real/protected mode and back.  Is it OK to use this
  in real mode.  Does the d_b remain from protected mode, and
  I should look at real_mode() instead?

look into byte_count overflowing (>16) in decode.c:cpu_loop()

386: in real-address mode, value of 32bit address may not exceed
65535 without causing an exception.  pseudo-protection faults
interrupt 12 or 13 with no error code occur if effective address
generated outside range of 0..FFFF

OF: for shl & other shift operations with count=1

compile time option to disclude PF

fixes for master pic should be done for slave also
  regarding not setting ISR until handshake

optim: use Xor where != used for flags

look for cases of (bx_cpu.eflags.cf?1:0). Can change to just CF.

LMSW: does it get all the new fields?

fetch.h: fetch_next_xyz()
  should convert access_virtual_byte() etc, to access_phy
  also, currently incrementing EIP.  should use IP or EIP accordingly

look for all assignments of bx_cpu.eip or IP or EIP.  Should zero
  out high word for all 16bit uses?

which flags need to be 0/1.  Can CF be the only one?  Could save some
  performance points if so.  NOTE, watch out for changing flags
  which are used to compute other flags within the same instruction

SHR 1: handling of OF different for 8086?


shift operations: should conditionally mask counts to 5 bits only if
  BX_CPU >= 2

put void in () for all inlined instructions

bochs.h: virtual_mode() macro should look for protected mode also.

after segment cache is loaded, set valid bit to 1

setting G, D_B, AVL bits in load_seg_reg(): real mode

when is EIP masked with 0x0000FFFF during computations?
  when operandsize is 16 or when cs.d_b = 0.  Do prefixes
  change this?

the B bit (big bit) fo all data descriptors controls upper address
  range for expand down segments

real mode:
  final effective addresses, regardless of size, must be
    in range 0..FFFF.  Int 0C & 0D exceptions result

real & virtual modes: segment selectors not used, so there is no
  default sizes, thus no way to set default to 32bits.  Must use
  prefixes.

real mode: stack addressing size is 16bits.  In protected, the B bit
 defines default stack addressing size. 0=SP, 1=ESP

in access_virtual_xyz(): should look for paging bit set in real-mode.
  Big Real Mode -or- Real Mode Paging


look for access_physical()'s.  replace with access_virtual()'s ???.

fetch's in fetch.h & debug/db_decode.c should use access_linear instead
of access_physical for paging ?

do stack op's need to use access_virtual()?  maybe access_linear()?

return protected: parameter pop_bytes: pentium manual seems to imply
  this value is number of words for operandsize32?
  also, should pop_bytes be sign extended?

make sure CALL pushes are 32bit even for 16bit quantities. (32bit operandsize)

single shift forms of shift instructions: check OF flag effects

32bit processors: real mode. location and size of interrupt table depend
  on contents of IDTR.  if entry in table beyond IDTR.limit, double
  fault exception is generated.

reset d_b bits upon entering real mode, to simulate lack of ability
  to have 32bit default size?

exception() & interrupt(): effective opsize and addrsize vs.
  interrupt & exceptions.  How do prefixes come into play with
  synchronous vs async events?

look for 32bit_addrsize: should be in very limited places

use of bx_cpu.errno

IDT/TI bits of error code for exceptions

difference in return address for divide error on 8086, than on 286+.
maybe others too...

calls to bx_exception(vector, error, is_INT):
  should use:
    (error & 0xfffc)       /* clear IDT & EXT bits */
      -or-
    (error & 0xfffc) | 2   /* IDT bit set */
  check for "| 2" in bx_interrupt()

check after all bx_read_virtual_xyz() and bx_write_virtual_xyz().
  should be BX_HANDLE_EXCEPTION()

what is effect of software interrupts INT Ib, for vectors <=18?
what about > 18

#ifdef bx_cpu.errno field in cpu_t for BX_CPU < 2

clear high bits of eSP when SP used?

rol, rcl & others: is op2 % opsize done in a separate step,
  does CF get set if (op2 & 0x1f) is not zero, but
  (op2 & opsize) = 0?

shift.c: do instructions fetch op1 if op2=0?

neg: calculating AF?

idiv: remainder & signs

string.c: cmps(w): check with SUB for flags settings and optim's.

look at shutdown_cpu for 286

access to LDTR, with LDTR.valid = 0, cause #GP() fault

bx_exception(a, b, c): typically, b should be &'d with 0xfffc

limit_scaled for non-data segment types

validate_es_gs...: various Intel books have different algorithm
  for determining validity of seg registers.
  286 & 386 list same.  486 & Pentium are same.

  algorithms depend on whether IRET or RET is used:
 
       IRET                      RET
  286: dpl>=cpl or dpl>=rpl      dpl>=cpl or dpl>=rpl
  386: dpl>=cpl or dpl>=rpl      dpl>=cpl or dpl>=rpl
  486: dpl> cpl or dpl< rpl      dpl>=cpl or dpl>=rpl
  586: dpl> cpl or dpl< rpl      dpl>=cpl or dpl>=rpl

stack.c: things which pop() and then can bomb out later, are not
         restartable.  Must delay actual stack change until all
         checks done.

restartability: real mode vs protected mode?

stack.c: pop_es, pop_ds, etc.  should include check for
         32bit opsize, and pop 4 bytes, ignore 2?

can_push()/can_pop(): should have separate routines which
  operate implicitly on SS, another one for alternate stack.
  have to be careful of eSP passed.  should depend upon SS.d_b.

relative offsets to EIP should be added to EIP then
  &= 0x0000ffff, if opsize = 16bits

ENTER: relook at this

should check for valid=1 after all parse_descriptor() calls.

jmp 286 avail TSS. 286 manual says SWITCH_TASKS with nesting.
  others say without?

optim: separate access_virtual out into write_virtual & read_virtual.
       also, make macro's & replace access_virtual_xyz.

mov_espiv: use opsize or stacksize?

logical: AND: delete op1_b15|31 since its set but not used

DELTAs:
  movsx_..
  imul_gvev: ? use of (Bit64u) cast instead of (Bit64s)

parse_descriptor: LDT: is limit only 16bits?

tss386: should have a limit_scaled?

all bx_exception() calls have return after them?

parse_descriptor() calls: should check descriptor.valid
  along with other checks.

iret & others: validate_seg_regs(): maybe there are different
  validations depening upon instruction

iret: outer level.  use CPL before or after iret to pass to
  write_(e)flags()?

interrupt(): what happens with 32bit opsizes, stacks, etc.

make separate task union structure, instead of using gate286
  i.e descriptor.u.task.selector

IRET, etc: use CPL before or after return for changing of IF & IOPL, etc?
  made some mods to iret.

optim: coding of if () else constructs.  Find compile flags & info
  about where to place favored part of code.

SHLD: setting of CF?

shift.c: maybe get rid of if () clauses for 16bit opsize cases,
         when instructions have undefined values for count>opsize
         Also, shouldn't have any if (count>=32) for 32bit opsize cases,
         since count masked to 0..31

shift.c: look at OF settings.

write_eflags: VM, RF, etc.  should have boolean to determine
  if change needed

change pit interval & floppy code back

stack.c: stack_size in real mode: eg. push16() for real mode, uses SP

change bx_printf(1, to bx_panic(
       bx_printf(0, to bx_printf(

change exgx to gxex

look for ^bx_panic("...")
  temporarily panic out some calls for debugging

check that all instructions which can use REP's are coded
  correctly in decode.c

make macro for repeating with and without concern for ZF

for profiling, might want to include a NOP function.

optim: instructions which compute b7,b15,b31 only for purpose
 of computing SF, can use SF = (val >= 0x80, 0x8000, or 0x80000000)

jmp_pro: jump conforming: CPL=?

return: pop_bytes parameter: does it mean words for opsize=32?

iret: use CPL before or after control xfer for setting IF, IOPL fields?

interrupt(): for condition "code seg non-conforming && DPL < CPL"
  use gate CPL or CS descriptor DPL?

protect_ctrl: deal with using limit. change to limit_scaled where needed.

shift.c: shifts with count of 0: is memory accessed for op1, etc?
  if not move "if (op2==0) return" clause up to top.
  right now its mixed.

bound: check out bound condition?

stack.c: push & pop, etc.  even in real mode, should look at
  stack sizes

bios: xms: coded hack for extending limits of ES & DS.

jcxz: I'm assuming it uses addrsize for size of eCX?

keyboard: int15_4f disabled for int9, what about 16?

ctrl_xfer_pro: call_protected: size of eSP & eIP for various cases.

decode: opsize & addrsize prefixes.  Negate themselves or the .d_b bit
  in CS.  matters for duplicate prefixes.

decode: maybe reconstruct decode loop:  search for prefixes, then instructions

ts,em,mp,pe: are they always 0 or 1?

commented out internal keyboard write ACK's for now.

hga_x.c: certain F-keys are mapped for debugging, comment out

8086: wraparound

main.c: strcpy's should be strncpy.  also check #args for all
        .bochsrc directives

enter_real_mode(): do the D_B fields in descriptors get reset
  upon entering real mode, since the default for real mode
  is 16bit?

return_protected(): pop_bytes: always in bytes?
  confusing documentation here.  possibly always in bytes,
  but denotes words for 32bit.

bios.c: skipping int7h for now.

hga_x.c:
  look into:

  /* no sense XFlush'ing if screen needs refresh */
  if (!retval)
    XFlush(display);
  return(retval);

change IO read/writes to pass up to 32bits, and length of IO operation

look at push_16() and push_32() for 16/32bit eSP sizes.

memory.c: make sure that all places where segment registers are loaded,
          the valid bit is cleared if the segment is not valid, since
          I took the checks out of access_virtual. (null selectors, etc)

optim: change parameter types of access_physical, access_linear, etc to
       use unsigned where Bit8u is used.

change bx_access_logical back to bx_access_physical() for LOADALL?
  look for cases where it should be physical access rather.

non-restartability (changes to CF) in bit.c

check for errors and restartability after bx_access_linear() calls.

OCW3 changes to master_pic should be integrated for slave pic

hacks to bomb out if cr0.em==0. remove

turn off f12 debugging.

why didn't GCC know in bit.c:BT_EvGv when I wasn't setting op1_32?

optim: change modulus (%,%=) to (&,&=).  Is this faster?

v8086: make sure VM bit isn't set if PM isn't set.

RF: pushed value & when is it set/cleared?

load_cs: do I need this?
load_ss: ""

look for BX_CPU == xyz

enter_real_mode(): should I set default sizes for all seg's to 16bit?

Alignment Check on 486

286 TSS: task switch loads VM with 0

NT in EFLAGS ignored in v8086 mode.

bx_push_32() & push_16(): should probably look at !real_mode instead of
  protected_mode.

===== Optimizations =====================================================
change 32bit address mode parsing to a switch statement in decode_exgx()

(mostly done) lazy flags processing

(done) change Boolean to be unsigned type instead of Bit8u

maybe pass boolean to BX_SET_FLAGS... macros to determine if should
compute MS bit for op1, op2, result

memory.c: bx-access_physical(): maybe separate out into
  write/read or at least move if (rw==BX_READ) out of loop

(done) use only one flag for rep/repne

use less bits for flag status in lazy_flags, currently 4
possibly merge status and current instruction

separate 16/32 bit decode loops
=========================================================================

XADD: 
OR: change 'sum' to 'result'

bx_hard_drive_io_read_handler
    case 0x1f1: /* hard disk error register */
      if (controller.diag_mode) {
        value8 = controller.diag_byte;
        return(value8);
        controller.diag_mode = 0;
        }
      ...

  return() is before assignment of controller.diag_mode?

options from Linux 2.0.21 compile
  -fomit-frame-pointer
  -fno-strength-reduce
  -malign-loops=2
  -malign-jumps=2
  -malign-functions=2

setfdprm -p /dev/fd0 1680/1440
# Non-standard disk formats:
#		size sec/t hds trk stre gap  rate spec1 fmt_gap

# BEWARE: They're incomplete and possibly incorrect. The only reason why
#         they are in this file is to show how such formats are added.

1440/1200	2880	18   2  80    0 ???? ???? ????	   ???? # ?????
1680/1440	3360	21   2  80    0 0x0C 0x00 0xCF     0x6C # ?????

changed validate_seg_regs()?
removed check in bx_load_cs()
  check out CPL passed to load_cs


pit: added command 0x0d which is an 8254 command.  should
     take this out and ignore 8254 specific commands
     (0x0c .. 0x0f)  Stay with basic 8253.


move BIOS interrupt services to hardcoded locations

-----------------------
virtual_block_write/virtual_block_read:
  won't see bx_cpu.errno, so if there's a problem it'll
  probably repeat.

commented out setting of fields in ES & DS in bios.cc:int15h AH=87h

should I be resetting bx_cpu.cs.cache.u.segment.d_b during real-mode
  loads?

HACKS:
  check in add_ebgb for all zero's, maybe in bogus code
  check in decode.cc for cs.d_b being set.
  check in jmp_ap for particular address

take reset of errno out of cpu_loop.  exception() should handle
  everything

pushing right size 'error_code' in ::interrupt()?

overrides to page protection
  following types of memory accesses are checked as if they are priv 0
  regardless of the CPL: (from Intel Pentium book)
  * access to segment descriptors in GDT, LDT, IDT
  * access to an inner-privilege-level stack during an inter-priv-level
    call or a call to an exception or interrupt handler, when a change
    of priv level occurs

message: translate_linear: dir entry not present

bios.cc: int >= 0x60 & int >= 67
  no '0x' before '67'

add init_cpu to calls made in bx_cpu_c constructor

look at activate_timer for ???

vga.cc: passing of data to bx_X_text_update() needs to
        change.  attribute byte specifies colors which
        select pel_data[]...

vga.cc: last 8 rgb triplets in default_vga_pel_data[] are
        listed as all 0xff's instead of all 0x00's.

clean up .h files for bios/ & iodev/

base_memory_in_k: should be in rombios.bin

parallel: might want to store real port addresses in 0x408..0x40C

========
4/28/97:
========

make sure BIOS is setting byte of word value at 0x410 according with
CMOS reg 0x14


5/13/97:
move save_{cs,ss,eip,esp} into bx_cpu_c???

5/15/97:
maybe have fetch_next_byte variant to return (unsigned int)?

vga mem check in fetch?

finish fetch_next_{word,dword} for both endian types

ROM_lock check for BIG_ENDIAN in memory.cc

7/1/97:
mouse hacks in bios/rombios.c

int74_handler needs to be passed registers like other functions

7/13/97:
  changed panic to printf on iodev/floppy.cc: bad eot
  change back...

00000 .. 9FFFF      (1st 640K)
==============
  000 ..   3FF      interrupt vector table
  400 ..   500      BIOS data area
  500 ..   8ff      DOS ???
 7C00 ..            1st 512 bytes of bootstrap program loaded here
9FC00 ..            Extended BIOS data area

B0000 .. BFFFF      HGA video buffer
C0000 .. C7FFF      VGA BIOS
E0000 .. FFFFF      ROM BIOS

port 0084 should not be in dma.cc

11/26/97:
  do I need to re-walk the page tables when a write is
  attempted to a read-only page?

  error handling in push16 & push32.  Real mode checks
  against eSP vs limit checks.  also specific checks
  for PUSHA for weird odd eSP cases 1,3,...

11/29/97:
  bx_pc_system_c should contain pointer to bx_cpu
  bx_pc_system_c::set_HRQ() has direct use of bx_cpu

11/30/97:
  should put in eip check in prefetch(), and take
  out other checks after decode is unified.
