Advertisement
Kitomas

work for 2025-01-31 (1/4)

Jan 31st, 2025
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 36.99 KB | None | 0 0
  1. /******************************************************************************/
  2. /******************************************************************************/
  3. //"sokoban_and_kit32_2025-01-31\kit32\snake\simple_text_editor.asm":
  4. #include "kit-32.asm"
  5. jmp #init
  6.  
  7. ;r3 = char index
  8. ;r5 = temp indirection buffer
  9. ;other registers are scratch
  10.  
  11.  
  12.  
  13.  
  14.  
  15. init:
  16.   mov.u32  r0,  #0xff000000
  17.   sys           #SYSCALL_SETDRAWCOLOR
  18.   mov.u32  r3, *#text_index
  19.  
  20. loop:
  21.   sys           #SYSCALL_CLEAR
  22.  
  23.   jsr           #get_char
  24.   cmp.u8   r0,  #0
  25.   beq           #.draw_call
  26.  
  27.   ;if key is backspace
  28.   cmp.u8   r0,  #VKEY_BACKSPACE
  29.   bne           #.not_backspace
  30.   jsr           #rem_char
  31.   bra           #.draw_call
  32.   .not_backspace:
  33.  
  34.   ;if key is newline
  35.   cmp.u8   r0,  #VKEY_RETURN
  36.   bne           #.not_newline
  37.   mov.u8   r0,  #"\n" ;convert '\r' to '\n'
  38.   .not_newline:
  39.  
  40.   jsr           #add_char
  41.   .draw_call:
  42.   mov.s32  r0,  #1
  43.   mov.s32  r1,  #1
  44.   jsr           #draw_text
  45.  
  46.   mov.u32  r5,  #text_index
  47.   mov.u32 *r5,  r3
  48.  
  49.   sys           #SYSCALL_PRESENT
  50.   bra           #loop
  51.  
  52.  
  53.  
  54.  
  55.  
  56. ;puts new char for drawing into r0.u8,
  57.  ;or 0 if there's nothing to pull from queue
  58.  
  59. get_char:
  60.  sys           #SYSCALL_GETKEY
  61.  cmp.u32  r0,  #0
  62.  beq           #.e ;skip if null
  63.  bnc           #get_char ;try again on key up
  64.  
  65.  ;try again if the key is just a keymod
  66.   ;(aka, if r0.u8 >= VKEY_LCTRL && r0.u8 <= VKEY_RGUI)
  67.  mov.u16  r4,  r0            ;only observe stuff in vkey mask
  68.  and.u16  r4,  #KE_MASK_VKEY  ;^^
  69.  cmp.u16  r4,  #VKEY_LCTRL
  70.  blt           #.not_a_keymod
  71.  cmp.u16  r4,  #VKEY_RGUI
  72.  ble           #get_char
  73.  .not_a_keymod:
  74.  
  75.  ;check if shift was being held
  76.  mov.u32  r4,  r0
  77.  shr.u32  r4,  #KE_SHIFT_KEYMOD
  78.  and.u16  r4,  #KEYMOD_SHIFT
  79.  bzs           #.e ;if not, exit
  80.  
  81.  
  82.  and.u8   r0,  #0b11011111 ;unset bit 5
  83. .e: rts
  84.  
  85.  
  86.  
  87. ;adds r0.u8 to char buffer, or not if buffer is full
  88.  
  89. add_char:
  90.  cmp.u8   r0,  #0
  91.  beq           #.e ;exit if char is null
  92.  cmp.u32  r3,  #255
  93.  bge           #.e ;exit if char buffer is full
  94.  
  95.  ;construct new char's address before dereferencing it
  96.   mov.u32  r5,  #text_buffer
  97.   add.u32  r5,  r3
  98.   mov.u8  *r5,  r0
  99.  
  100.   inc.u32  r3 ;new char was added; increment accordingly
  101. .e: rts
  102.  
  103.  
  104.  
  105. rem_char:
  106.   cmp.u32  r3,  #0
  107.   beq           #.e ;exit if there are no chars left to remove
  108.   dec.u32  r3
  109. .e: rts
  110.  
  111.  
  112.  
  113. ;r0.s32, r1.s32 = x&y position of text in pixels
  114. ;r3 = the number of chars to draw (0 to skip drawing)
  115.  
  116. draw_text:
  117.   cmp.u32  r3,  #0
  118.   beq           #.e ;exit if there are no chars left to remove
  119.  
  120.   mov.u32  r2,  #text_buffer
  121.   sys           #SYSCALL_DRAWTEXT
  122. .e: rts
  123.  
  124.  
  125.  
  126. #addr 1024*1024*8 ;start of persistent memory
  127. text_index: #res 4
  128. text_buffer: #res 256/******************************************************************************/
  129. /******************************************************************************/
  130. //"sokoban_and_kit32_2025-01-31\kit32\snake\snake.asm":
  131. #include "kit-32.asm"
  132. ;jmp #INIT
  133.  
  134. SCREEN_W   = (256)
  135. SCREEN_H   = (144-8) ; -8 to account for score bar
  136. SCREEN_LEN = (SCREEN_W*SCREEN_H)
  137.  
  138. ;0x24F -> 0x252 = the vkey events, in this order:
  139. DIR_RIGHT = 0
  140. DIR_LEFT  = 1
  141. DIR_DOWN  = 2
  142. DIR_UP    = 3
  143. DIR_DEAD  = 4 ;dead state
  144.  
  145.  
  146.  
  147.  
  148.  
  149. INIT: ;code that executes only once
  150.   ;(nothing currently)
  151. START:
  152.   ;init stack pointer to first byte of persistent memory,
  153.    ;so that it will enter the top of non-persistent memory when pushing
  154.   mov.u32  sp,  #1<<23
  155.  
  156.   ;reset reserved memory
  157.   mov.u32  r0,  #RESERVED_START ;(previously an ext)
  158.   mov.u8   r1,  #0
  159.   mov.u32  r2,  #RESERVED_LEN
  160.   sys           #SYSCALL_MEMSET
  161.  
  162.   ;set background color to a random one
  163.   mov.u32  r0,  #0 ;(previously an ext)
  164.   jfn           #FUN_set_bg
  165.   sys           #SYSCALL_CLEAR
  166.  
  167.   ;set score to -1, so that it rolls over to 0 next call to FUN_create_apple
  168.   mov.u32  r3,  #VAR_score
  169.   dec.u32 *r3 ;(relies on *VAR_score previously being 0)
  170.  
  171.   ;set snake's start and end pointers
  172.  mov.u32  r0,  #ARR_snake_segments ;(previously an ext)
  173.  mov.u32  r4,  #VAR_snake_start    ;(previously an ext)
  174.  mov.u32  r5,  #VAR_snake_end      ;(previously an ext)
  175.  mov.u32 *r4,  r0
  176.  mov.u32 *r5,  r0
  177.  
  178.  ;set snake's position and direction, before adding the first segment
  179.    ;(16-bit is used where possible)
  180.   sys           #SYSCALL_RAND_U16
  181.   mod.u16  r0,  #SCREEN_LEN
  182.   mov.u32  r5,  #VAR_snake_pos ;(previously an ext)
  183.   mov.u16 *r5,  r0
  184.   mov.u16  r1,  r0 ;for the call to FUN_snake_add
  185.    ;
  186.   and.u16  r0,  #3 ;yes, this operates on the value given by the prev. rand.u16
  187.   mov.u32  r4,  #VAR_snake_dir ;(previously an ext)
  188.   mov.u16 *r4,  r0
  189.    ;
  190.   jfn           #FUN_snake_add
  191.  
  192.   ;create first apple
  193.   jfn           #FUN_create_apple
  194.  
  195.  
  196.  
  197. LOOP:
  198.   jfn           #FUN_handle_input
  199.  
  200.  
  201.  
  202.   ;move snake head
  203.   mov.u32  r4, *#VAR_snake_dir
  204.   shl.u16  r4,  #1 ; *= 2
  205.   add.u16  r4,  #.move_lookup
  206.    ;
  207.   mov.u32  r5,  #VAR_snake_pos ;(previously an ext)
  208.   add.s16 *r5, *r4 ;VAR_snake_pos += ARR_move_lookup[VAR_snake_dir]
  209.   cmp.u16 *r5,  #SCREEN_LEN
  210.   blt           #to_absolute(4)
  211.   add.u16 *r5,  #SCREEN_LEN
  212.   mod.u16 *r5,  #SCREEN_LEN
  213.  
  214.  
  215.   ;check to see if snake died
  216.   ;*
  217.   mov.u16  r1, *#VAR_snake_pos
  218.   jfn           #FUN_get_screen_byte
  219.   bzs           #.dont_die
  220.     mov.u32  r0,  #0xFF00007F ;a shade of red
  221.     sys           #SYSCALL_SETDRAWCOLOR
  222.     sys           #SYSCALL_CLEAR
  223.     jfn           #FUN_draw_score
  224.     mov.u16  r1,  #60*3
  225.     jfn           #FUN_wait
  226.     bra           #START
  227.   .dont_die:
  228.   *;
  229.  
  230.   ;add new segment
  231.   mov.u16  r1, *r5
  232.   jfn           #FUN_snake_add
  233.  
  234.  
  235.  
  236.   ;if snake is now touching the apple, increment score and generate a new one.
  237.   ;otherwise, remove the last snake segment
  238.   mov.u32  r4,  #VAR_apple_pos ;(previously an ext)
  239.   cmp.u16 *r4, *r5
  240.   bne           #.not_on_apple
  241.     jfn           #FUN_create_apple
  242.     bra           #.dont_remove_segment
  243.   .not_on_apple:
  244.   jfn             #FUN_snake_rem
  245.   .dont_remove_segment:
  246.  
  247.  
  248.  
  249.   jfn           #FUN_draw_score
  250.   mov.u16  r1,  #2
  251.   jfn           #FUN_wait
  252.  
  253.   bra           #LOOP
  254.  
  255.  
  256.  
  257.  
  258.  
  259. .move_lookup:
  260. ;*right*; #d16 lend16(   1)
  261. ;*left *; #d16 lend16(  -1)
  262. ;*down *; #d16 lend16( 256)
  263. ;*up   *; #d16 lend16(-256)
  264.  
  265.  
  266.  
  267.  
  268.  
  269. ;; add a snake segment to the queue, before painting in that segment
  270. ;;
  271. ;;   params: r1.u16 = the segment to add
  272. ;;  returns: none
  273. ;; clobbers: none
  274. FUN_snake_add:
  275.   ;add segment to the queue
  276.   mov.u32  r4,  #VAR_snake_end ; r4 = &VAR_snake_end
  277.   mov.u32  r5, *r4             ; r5 =  VAR_snake_end
  278.   mov.u16 *r5,  r1             ; *VAR_snake_end = r1
  279.  
  280.   ;snake segment added; set byte to 1 in screen mirror
  281.   mov.u8   r2,  #1
  282.   jfn           #FUN_set_screen_byte ;(r1 = the segment)
  283.  
  284.   ;advance v_snake_end by 2, wrapping at the segment array boundary
  285.   sub.s32 *r4,  #(ARR_snake_segments-2) ;ptr to offset+2
  286.   mod.u32 *r4,  #SCREEN_LEN*2           ; %= size of segments array
  287.   add.u32 *r4,  #ARR_snake_segments     ;new offset back to ptr
  288.  
  289.   ;draw the new segment
  290.   sph.u32  r0
  291.   mov.u32  r0,  #0xFF00FF00 ; a shade of green
  292.   sys           #SYSCALL_SETDRAWCOLOR
  293.   jfn           #FUN_draw_segment ;r1 = the drawn segment
  294.   spl.u32  r0
  295.  
  296.   rfn
  297.  
  298.  
  299.  
  300.  
  301.  
  302. ;; remove a snake segment from the queue,
  303. ;; before painting over that segment
  304. ;;
  305. ;;   params: none
  306. ;;  returns: none
  307. ;; clobbers: none
  308. FUN_snake_rem:
  309.   mov.u32  r4,  #VAR_snake_start ;(previously an ext)
  310.   cmp.u16 *r4, *#VAR_snake_end
  311.   beq           #.e ;no sections to remove; exit early
  312.  
  313.   mov.u32  r5, *r4 ;r5 = *v_snake_start (ptr inside ARR_snake_segments)
  314.   mov.u16  r1, *r5 ;r1 = first segment in queue ;(previously an ext)
  315.   and.u32  r1,  #U16_MAX                         ;^^
  316.  
  317.   ;snake segment removed; set byte to 0 in screen mirror
  318.   mov.u8   r2,  #0
  319.   jfn           #FUN_set_screen_byte ;(r1 = the segment)
  320.  
  321.   ;advance v_snake_start by 2, wrapping at the segment array boundary
  322.   sub.s32 *r4,  #(ARR_snake_segments-2) ;ptr to offset+2
  323.   mod.u32 *r4,  #SCREEN_LEN*2           ; %= size of segments array
  324.   add.u32 *r4,  #ARR_snake_segments     ;new offset back to ptr
  325.  
  326.   ;paint over the segment with the background color
  327.   sph.u32  r0
  328.   jfn           #FUN_get_bg
  329.   jfn           #FUN_draw_segment
  330.   spl.u32  r0
  331.  
  332. .e: rfn
  333.  
  334.  
  335.  
  336.  
  337.  
  338. ;; creates a new apple (will overwrite the previous one)
  339. ;;
  340. ;;   params: none
  341. ;;  returns: none
  342. ;; clobbers: none
  343. FUN_create_apple:
  344.   sph.u32  r0
  345.  
  346.   ;keep rolling for a new spot until one without a snake segment is found
  347.    ;(lazy implementation, but it uses fewer bytes than the non-naive approach)
  348.   .loop:
  349.     sys           #SYSCALL_RAND_U16
  350.     mod.u16  r0,  #SCREEN_LEN ;= a random pixel offset
  351.     mov.u16  r1,  r0
  352.     jfn           #FUN_get_screen_byte
  353.     bzc           #.loop
  354.  
  355.   ;set apple's position to the new value
  356.  mov.u32  r5,  #VAR_apple_pos ;(previously an ext)
  357.  mov.u16 *r5,  r1
  358.  
  359.  ;increment score
  360.  mov.u32  r3,  #VAR_score
  361.  inc.u32 *r3
  362.    
  363.  ;draw the apple
  364.  mov.u32  r0,  #0xFF0000FF ; a shade of red
  365.  sys           #SYSCALL_SETDRAWCOLOR
  366.  jfn           #FUN_draw_segment
  367.  
  368.  spl.u32  r0
  369.  rfn
  370.  
  371.  
  372.  
  373.  
  374.  
  375. ;; sets the byte r1.u16 of ARR_screen_mirror to r2.u8
  376. ;;
  377. ;;   params: r1.u16 = the byte to select
  378. ;;           r2.u8  = the byte's new value
  379. ;;  returns: none
  380. ;; clobbers: none
  381. FUN_set_screen_byte:
  382.   mov.u32  r3,  r1       ;(previously an ext)
  383.   and.u32  r3,  #U16_MAX  ;^^
  384.   mod.u32  r3,  #SCREEN_LEN
  385.   add.u32  r3,  #ARR_screen_mirror
  386.   mov.u8  *r3,  r2
  387.   rfn
  388.  
  389.  
  390.  
  391.  
  392.  
  393. ;; gets the byte r1.u16 from ARR_screen_mirror
  394. ;;
  395. ;;   params: r1.u16 = the byte to select
  396. ;;  returns: r0.u8  = the byte's current value
  397. ;; clobbers: none
  398. ;;
  399. ;;  remarks: the final "mov.u8" instruction will set the zero flag accordingly,
  400. ;;           which means that a branch can be placed right after the jfn call
  401. FUN_get_screen_byte:
  402.  mov.u32  r3,  r1       ;(previously an ext)
  403.  and.u32  r3,  #U16_MAX  ;^^
  404.  mod.u32  r3,  #SCREEN_LEN
  405.  add.u32  r3,  #ARR_screen_mirror
  406.  mov.u8   r0, *r3
  407.  rfn
  408.  
  409.  
  410.  
  411.  
  412.  
  413. ;; set background color, or randomize it if r0 is equal to 0
  414. ;; (will also set the draw color to the new background color!)
  415. ;;
  416. ;;   params: r0.u32 = new color, or 0 for random
  417. ;;  returns: r0.u32 = the new background color
  418. ;; clobbers: none
  419. FUN_set_bg:
  420.  cmp.u32  r0,  #0
  421.  bne #.dont_randomize
  422.    sys           #SYSCALL_RAND_U32
  423.    ior.u32  r0,  #0xFF000000 ;make sure alpha is 255
  424.    ;make sure color intensity isn't too high,
  425.      ;and prevent green from being used too much either
  426.     and.u32  r0,  #0xFF2F0F2F
  427.   .dont_randomize:
  428.  
  429.   ;set background color
  430.   mov.u32  r4,  #VAR_bg_color ;(previously an ext)
  431.   mov.u32 *r4,  r0
  432.   ;(falls through to FUN_get_bg)
  433.  
  434. ;; put background color into r0.u32,
  435. ;; while simultaneously setting the draw color
  436. ;;
  437. ;;   params: none
  438. ;;  returns: r0.u32 = the current background color
  439. ;; clobbers: none
  440. FUN_get_bg:
  441.   mov.u32  r0, *#VAR_bg_color
  442.   sys           #SYSCALL_SETDRAWCOLOR
  443.   rfn
  444.  
  445.  
  446.  
  447.  
  448.  
  449. ;; takes in and acts on user input
  450. ;;
  451. ;;   params: none
  452. ;;  returns: none
  453. ;; clobbers: none
  454. FUN_handle_input:
  455.   sph.u32  r0
  456.  
  457.   mov.u32  r5,  #VAR_snake_dir ;(previously an ext)
  458.   mov.u32  r3, *r5             ;get original state of VAR_snake_dir, into r3
  459.  
  460.   .loop:
  461.   jsr           #SUB_get_vkey_down
  462.   bzs           #.e       ;break loop if key event is null
  463.   cmp.u16 *r5,  #DIR_DEAD
  464.   beq           #.loop    ;if snake is dead, burn events until all are cleared
  465.  
  466.   ;convert an arrow's virtual key code to a snake direction
  467.  sub.u16  r0,  #0x24F ;0x24F = first arrow virtual key code
  468.  cmp.u16  r0,  #4     ;there are 4 arrow keys
  469.  bge           #.loop ;query next event if not an arrow key press
  470.  
  471.  ;query next event if new direction would be the opposite of the old one
  472.   ;(this is to prevent immediately running into the last snake segment)
  473.  mov.u32  r1,  r0 ;no need for an ext, as r0 is guaranteed to be <=U16_MAX
  474.  add.u16  r1,  #.move_conflicts_lookup ;a lookup table is used,
  475.  cmp.u8  *r1, *r5                       ;and each entry is u8
  476.  beq           #.loop
  477.  
  478.  ;set r3 to the new value, before querying another event
  479.  mov.u16  r3,  r0
  480.  bra           #.loop
  481.  
  482. .e:
  483.  ;update v_snake_dir to new value (or the same one if it hasn't changed)
  484.   mov.u16 *r5,  r3
  485.   spl.u32  r0
  486.   rfn
  487.  
  488. .move_conflicts_lookup: ;tiny lookup table :O
  489.   #d8 1 ;opposite of right
  490.   #d8 0 ;opposite of left
  491.   #d8 3 ;opposite of down
  492.   #d8 2 ;opposite of up
  493.  
  494.  
  495.  
  496.  
  497.  
  498. ;; polls for key events until either a non-repeat vkey down event is found,
  499. ;; or if the event queue was cleared before returning anything valid
  500. ;;
  501. ;;   params: none
  502. ;;  returns: r0.u32 = vkey event, or 0 if nothing was found
  503. ;; clobbers: r1.u32
  504. ;;
  505. ;;  remarks: the zero flag will be set at the point of returning,
  506. ;;           so a branch on zero immediately after the jsr is valid
  507. SUB_get_vkey_down:
  508.   sys           #SYSCALL_GETKEY
  509.   cmp.u32  r0,  #0
  510.   beq           #.e                ;break loop if event is null
  511.   bnc           #SUB_get_vkey_down ;try again if event is keyup
  512.  
  513.   mov.u32  r1,  r0
  514.   and.u32  r1,  #1<<KE_SHIFT_REPEAT ;will set zero flag if repeat bit is unset
  515.   bzc           #SUB_get_vkey_down  ;try again if event is a repeat
  516.  
  517.   and.u32  r0,  #KE_MASK_VKEY ;only observe the virtual key code
  518.  
  519. .e: rts
  520.  
  521.  
  522.  
  523.  
  524.  
  525. ;; draws score and the black bar at the bottom
  526. ;;
  527. ;;   params: none
  528. ;;  returns: none
  529. ;; clobbers: none
  530. FUN_draw_score:
  531.   sph.u32  r0
  532.  
  533.   mov.u32  r0,  #0xFF000000
  534.   sys           #SYSCALL_SETDRAWCOLOR
  535.  
  536.   mov.u32  r0,  #0            ;x = 0 ;(previously an ext)
  537.   mov.s32  r1,  #SCREEN_H     ;y = <last play area pixel> + 1
  538.   mov.u32  r2,  #SCREEN_W     ;w
  539.   mov.u32  r3,  #144-SCREEN_H ;h = <total height>-<play area height>
  540.   sys           #SYSCALL_FILLRECT_S32
  541.  
  542.   mov.s32  r2,  #CENTERED_TEXT ;x
  543.   inc.s32  r1                  ;y = <last play area pixel> + 1 + 1
  544.   mov.u32  r3, *#VAR_score     ;n
  545.  
  546.   ;this effectively calls FUN_draw_u32, without pushing r0
  547.   bra           #to_absolute(4)
  548.  
  549. ;; draws r3.u32 at (r2.s32,r1.s32), as text
  550. ;;
  551. ;;   params: r1.s32 = y position
  552. ;;           r2.s32 = x position
  553. ;;           r3.u32 = number to draw
  554. ;;  returns: none
  555. ;; clobbers: none
  556. FUN_draw_u32:
  557.   sph.u32  r0
  558.  
  559.   ;convert number to bcd, into r4
  560.   u2b      r4,  r3
  561.  
  562.   ;preserve x, before setting r2 to last char of ARR_num_str +1
  563.   mov.u32  r0,  r2
  564.   mov.u32  r2,  #ARR_num_str+7 +1
  565.  
  566.   .loop:
  567.     dec.u32  r2 ;will *start* at last char
  568.    
  569.     ;construct digit char from low nybble of r4, into r3
  570.     mov.u8   r3,  r4
  571.     and.u8   r3,  #0b1111
  572.     add.u8   r3,  #"0"
  573.     mov.u8  *r2,  r3 ;write that char to *r2
  574.     shr.u32  r4,  #4 ;go to next nybble in bcd
  575.    
  576.     ;loop will break once r2 == ARR_num_str
  577.     cmp.u32  r2,  #ARR_num_str
  578.     bne #.loop
  579.  
  580.   mov.u32  r3,  #0 ;len = 0 (until null terminator is hit) ;(previously an ext)
  581.   sys           #SYSCALL_DRAWTEXT
  582.  
  583.   spl.u32  r0
  584.   rfn
  585.  
  586.  
  587.  
  588.  
  589.  
  590. ;; draws and waits for r1.u16 frames
  591. ;;
  592. ;;   params: r1.u16 = # of frames to wait
  593. ;;  returns: none
  594. ;; clobbers: none
  595. FUN_wait:
  596.   cmp.u16  r1,  #0
  597.   beq           #.e
  598.  
  599.   .loop:
  600.     sys           #SYSCALL_PRESENT
  601.     dec.u16  r1
  602.     bzc           #.loop
  603.  
  604. .e: rfn
  605.  
  606.  
  607.  
  608.  
  609.  
  610. ;; construct an x & y from a snake segment,
  611. ;; before drawing it as a point
  612. ;;
  613. ;;   params: r1.u16 = segment to draw
  614. ;;  returns: none
  615. ;; clobbers: none
  616. FUN_draw_segment:
  617.   sph.u32  r0
  618.  
  619.   and.u32  r1,  #U16_MAX
  620.  
  621.   ;x
  622.   mov.u32  r0,  r1
  623.   and.u16  r0,  #U8_MAX
  624.  
  625.   ;y
  626.   shr.u16  r1,  #8
  627.   mod.u16  r1,  #SCREEN_H
  628.  
  629.   sys           #SYSCALL_DRAWPOINT_S32
  630.  
  631.   spl.u32  r0
  632.   rfn
  633.  
  634.  
  635.  
  636.  
  637.  
  638. #align 32
  639. RESERVED_START:
  640.  
  641. ARR_num_str       : #res 9
  642. #align 32 ;should make 3 bytes of padding
  643. VAR_score         : #res 4
  644. VAR_bg_color      : #res 4
  645. VAR_apple_pos     : #res 4
  646. VAR_snake_pos     : #res 4
  647. VAR_snake_dir     : #res 4
  648. VAR_snake_start   : #res 4
  649. VAR_snake_end     : #res 4
  650. ARR_screen_mirror : #res SCREEN_LEN   ;1 byte per pixel
  651. ARR_snake_segments: #res SCREEN_LEN*2 ;segment queue, each is 2 bytes
  652.  
  653. RESERVED_END:
  654.  
  655. RESERVED_LEN = RESERVED_END-RESERVED_START/******************************************************************************/
  656. /******************************************************************************/
  657. //"sokoban_and_kit32_2025-01-31\kit32\simulator\src\callbacks.cpp":
  658. #include <include_all.hpp>
  659.  
  660. using namespace kit;
  661.  
  662.  
  663.  
  664.  
  665.  
  666. AudioDevice* audio = nullptr;
  667. bool  audioIsReady = false;
  668.  
  669.  
  670.  
  671.  
  672.  
  673. s32 cb_audio(void* _dst, const AudioDeviceInfo& info){
  674.   if(!audioIsReady) return 0;
  675.  
  676.   Stereo_f32* dst     = (Stereo_f32*)_dst;
  677.   u16         dst_len = info.sampleFrames;
  678.  
  679.   for(u16 i=0; i<dst_len; ++i){
  680.     //clamp the samples so that they aren't out of bounds
  681.     dst[i].l = CLAMP(dst[i].l, -1.0f, 1.0f);
  682.     dst[i].r = CLAMP(dst[i].r, -1.0f, 1.0f);
  683.  
  684.   }
  685.  
  686.   return 0;
  687.  
  688. }
  689. /******************************************************************************/
  690. /******************************************************************************/
  691. //"sokoban_and_kit32_2025-01-31\kit32\simulator\src\kit_32_cpu.cpp":
  692. #include <include_all.hpp>
  693.  
  694. #include <cmath> //for sqrtf, fmodf, and trig functions
  695.  
  696.  
  697. #define STACK_PUSH(_type) \
  698.   *ADDR(_type, regs_sp.u32-=sizeof(_type))
  699.  
  700. #define STACK_PULL(_type) \
  701.   *ADDR(_type, regs_sp.u32); regs_sp.u32 += sizeof(_type)
  702.  
  703. #define STACK_GET(_type, _offset) \
  704.   *ADDR(_type, regs_sp.u32+(_offset))
  705.  
  706.  
  707. #define BITSIZ(_value) (sizeof(_value)*8)
  708.  
  709. #define SHIFTMOD(_value, _shift)  (  (_shift)&(BITSIZ(_value)-1)  )
  710.  
  711. #define GET_MSb(_value) (  1<<(BITSIZ(_value)-1)  )
  712.  
  713. #define SET_FLAGS_ZN(_value) \
  714.   flags_zero     =  (_value)                  == 0; \
  715.   flags_negative = ((_value)&GET_MSb(_value)) != 0
  716.  
  717.  
  718.  
  719.  
  720.  
  721. /* MISC. */
  722.  
  723. #define DO_MOV(_type) { \
  724.   dst->_type = src->_type; \
  725.   SET_FLAGS_ZN(dst->_type); }
  726.  
  727. #define DO_CMP(_type) { \
  728.   flags_less  = dst->_type <  src->_type; \
  729.   flags_equal = dst->_type == src->_type; \
  730.   SET_FLAGS_ZN(dst->_type); }
  731.  
  732. #define DO_JMP(_type) { \
  733.   regs_pc = (u32)(src->_type); } //(z&n are not set here)
  734.  
  735. #define DO_JSR(_type) { \
  736.   STACK_PUSH(u32) = regs_pc; \
  737.   DO_JMP(_type); } //(z&n are not set here)
  738.  
  739. #define DO_SLD(_type) { \
  740.   dst->_type = STACK_GET(_type, src->s16); \
  741.   SET_FLAGS_ZN(dst->_type); }
  742.  
  743. #define DO_SST(_type) { \
  744.   STACK_GET(_type, src->s16) = dst->_type; } //(z&n are not set here)
  745.  
  746. #define DO_SPH(_type) { \
  747.   STACK_PUSH(_type) = src->_type; } //(z&n are not set here)
  748.  
  749. #define DO_SPL(_type) { \
  750.   dst->_type = STACK_PULL(_type); \
  751.   SET_FLAGS_ZN(dst->_type); }
  752.  
  753. /* ARITHMETIC */
  754.  
  755. #define DO_INC(_type) { \
  756.   ++dst->_type; \
  757.   SET_FLAGS_ZN(dst->_type); }
  758.  
  759. #define DO_DEC(_type) { \
  760.   --dst->_type; \
  761.   SET_FLAGS_ZN(dst->_type); }
  762.  
  763. #define DO_ADD(_type) { \
  764.   dst->_type += src->_type; \
  765.   SET_FLAGS_ZN(dst->_type); }
  766.  
  767. #define DO_SUB(_type) { \
  768.   dst->_type -= src->_type; \
  769.   SET_FLAGS_ZN(dst->_type); }
  770.  
  771. #define DO_MUL(_type) { \
  772.   dst->_type *= src->_type; \
  773.   SET_FLAGS_ZN(dst->_type); }
  774.  
  775. #define DO_DIV(_type) { \
  776.   dst->_type /= src->_type; \
  777.   SET_FLAGS_ZN(dst->_type); }
  778.  
  779. #define DO_MOD(_type) { \
  780.   dst->_type %= src->_type; \
  781.   SET_FLAGS_ZN(dst->_type); }
  782.  
  783. #define DO_NEG(_type) { \
  784.   dst->_type = -src->_type; \
  785.   SET_FLAGS_ZN(dst->_type); }
  786.  
  787. /* BITWISE */
  788.  
  789. #define DO_NOT(_type) { \
  790.   dst->_type = ~src->_type; \
  791.   SET_FLAGS_ZN(dst->_type); }
  792.  
  793. #define DO_NND(_type) { \
  794.   dst->_type = ~(dst->_type & src->_type); \
  795.   SET_FLAGS_ZN(dst->_type); }
  796.  
  797. #define DO_AND(_type) { \
  798.   dst->_type &= src->_type; \
  799.   SET_FLAGS_ZN(dst->_type); }
  800.  
  801. #define DO_NOR(_type) { \
  802.   dst->_type = ~(dst->_type | src->_type); \
  803.   SET_FLAGS_ZN(dst->_type); }
  804.  
  805. #define DO_IOR(_type) { \
  806.   dst->_type |= src->_type; \
  807.   SET_FLAGS_ZN(dst->_type); }
  808.  
  809. #define DO_XOR(_type) { \
  810.   dst->_type ^= src->_type; \
  811.   SET_FLAGS_ZN(dst->_type); }
  812.  
  813. #define DO_SHL(_type) { \
  814.   dst->_type = (  dst->_type << SHIFTMOD(dst->_type, src->s16)  ); \
  815.   SET_FLAGS_ZN(dst->_type); }
  816.  
  817. #define DO_SHR(_type) { \
  818.   dst->_type = (  dst->_type >> SHIFTMOD(dst->_type, src->s16)  ); \
  819.   SET_FLAGS_ZN(dst->_type); }
  820.  
  821. #define DO_ROL(_type) { \
  822.   dst->_type = ( \
  823.     (dst->_type << SHIFTMOD(dst->_type, src->s16))  | \
  824.     (dst->_type >> (BITSIZ(dst->_type) - SHIFTMOD(dst->_type, src->s16)))  ); \
  825.   SET_FLAGS_ZN(dst->_type); }
  826.  
  827. #define DO_ROR(_type) { \
  828.   dst->_type = ( \
  829.     (dst->_type >> SHIFTMOD(dst->_type, src->s16))  | \
  830.     (dst->_type << (BITSIZ(dst->_type) - SHIFTMOD(dst->_type, src->s16)))  ); \
  831.   SET_FLAGS_ZN(dst->_type); }
  832.  
  833. #define DO_EXT(_type_from, _type_to) { \
  834.   dst->_type_to = (_type_to)src->_type_from; \
  835.   SET_FLAGS_ZN(dst->_type_to); }
  836.  
  837. /* EXTRA */
  838.  
  839. #define DO_JFN(_type) { \
  840.   regs_sp.u32 -= sizeof(u32)*6; \
  841.   u32* stack   = ADDR(u32, regs_sp.u32); \
  842.   stack[0]     = regs_pc; \
  843.   stack[1]     = regs_gp[5].u32; \
  844.   stack[2]     = regs_gp[4].u32; \
  845.   stack[3]     = regs_gp[3].u32; \
  846.   stack[4]     = regs_gp[2].u32; \
  847.   stack[5]     = regs_gp[1].u32; \
  848.   DO_JMP(_type); } //(z&n are not set here)
  849.  
  850.  
  851.  
  852.  
  853.  
  854. namespace kit {
  855.  
  856.  
  857.  
  858. union bcd {
  859.   u32 v;
  860.   struct { u32 d0:4, d1:4, d2:4, d3:4, d4:4, d5:4, d6:4, d7:4; };
  861.   inline bcd(u32 _v) : v(_v) {}
  862. };
  863.  
  864. static inline u32 to_bcd(u32 value){
  865.   u32 result = 0,  shift  = 0;
  866.  
  867.   value = MIN(value, 99999999);
  868.  
  869.   while(value > 0){
  870.     result |= (value%10)<<shift;
  871.     value /= 10;
  872.     shift += 4;
  873.   }
  874.  
  875.   return result;
  876.  
  877. }
  878.  
  879. static inline u32 from_bcd(bcd value){
  880.   u32 result;
  881.  
  882.   result  = MIN(value.d0,9)/*        1*/;
  883.   result += MIN(value.d1,9) *       10;
  884.   result += MIN(value.d2,9) *      100;
  885.   result += MIN(value.d3,9) *     1000;
  886.   result += MIN(value.d4,9) *    10000;
  887.   result += MIN(value.d5,9) *   100000;
  888.   result += MIN(value.d6,9) *  1000000;
  889.   result += MIN(value.d7,9) * 10000000;
  890.  
  891.   return result;
  892. }
  893.  
  894.  
  895.  
  896.  
  897.  
  898. s32 cpu32::execute(){
  899.   s32 result = EXERES_SUCCESS;
  900.   reg32* src, *dst;
  901.  
  902.   //instructions are supposed to be memory-aligned to 4 bytes
  903.    //(hence the "&(~0b11)"), however that behavior is undefined,
  904.    //and the idiot check isn't strictly necessary.
  905.   //maybe if i actually implement this on an fpga i'll enforce it
  906.   //regs_pc &= ADDRESS_LIMIT&(~0b11);
  907.   ins32 ins = *ADDR(ins32, regs_pc);
  908.   regs_pc += sizeof(ins32);
  909.  
  910.  
  911.  
  912.   //if source is a normal register
  913.   if(ins.src < OPADDR_IMM)
  914.   {
  915.     src = regs + ins.src;
  916.  
  917.   }
  918.   //if ins.src == OPADDR_IMM, src will be set to either &ins.v_u16...
  919.   else if((ins.op_dtype < 2) /*||
  920.           (ins.op_type >= OPTYPE_SHL && ins.op_type <= OPTYPE_ROR)*/)
  921.   {
  922.     src = ADDR(reg32, regs_pc-2);
  923.  
  924.   }
  925.   //...or the next 4 bytes after ins
  926.   else {
  927.     src = ADDR(reg32, regs_pc);
  928.     regs_pc += sizeof(reg32);
  929.  
  930.   }
  931.  
  932.   //if source is indirect, and should be dereferenced as a memory address
  933.    //(dereferencing an immediate value not of type u32 is undefined!)
  934.   if(ins.src_ind) src = ADDR(reg32, src->u32);
  935.  
  936.  
  937.  
  938.   dst = regs + ins.dst;
  939.  
  940.   //if destination is indirect, and should be dereferenced as a memory address
  941.   if(ins.dst_ind) dst = ADDR(reg32, dst->u32);
  942.  
  943.  
  944.  
  945.   switch(ins.op){
  946.     /*************** OPDATA_U8  ****************/
  947.     case OPCODE(U8,BRK): result = EXERES_BRK; break;
  948.     case OPCODE(U8,MOV): DO_MOV(u8); break;
  949.     case OPCODE(U8,CMP): DO_CMP(u8); break;
  950.     case OPCODE(U8,JMP): DO_JMP(u8); break;
  951.     case OPCODE(U8,JSR): DO_JSR(u8); break;
  952.     case OPCODE(U8,SLD): DO_SLD(u8); break;
  953.     case OPCODE(U8,SST): DO_SST(u8); break;
  954.     case OPCODE(U8,SPH): DO_SPH(u8); break;
  955.     case OPCODE(U8,SPL): DO_SPL(u8); break;
  956.     case OPCODE(U8,INC): DO_INC(u8); break;
  957.     case OPCODE(U8,DEC): DO_DEC(u8); break;
  958.     case OPCODE(U8,ADD): DO_ADD(u8); break;
  959.     case OPCODE(U8,SUB): DO_SUB(u8); break;
  960.     case OPCODE(U8,MUL): DO_MUL(u8); break;
  961.     case OPCODE(U8,DIV): DO_DIV(u8); break;
  962.     case OPCODE(U8,MOD): DO_MOD(u8); break;
  963.     case OPCODE(U8,NEG): DO_NEG(u8); break;
  964.     case OPCODE(U8,NOT): DO_NOT(u8); break;
  965.     case OPCODE(U8,NND): DO_NND(u8); break;
  966.     case OPCODE(U8,AND): DO_AND(u8); break;
  967.     case OPCODE(U8,NOR): DO_NOR(u8); break;
  968.     case OPCODE(U8,IOR): DO_IOR(u8); break;
  969.     case OPCODE(U8,XOR): DO_XOR(u8); break;
  970.     case OPCODE(U8,SHL): DO_SHL(u8); break;
  971.     case OPCODE(U8,SHR): DO_SHR(u8); break;
  972.     case OPCODE(U8,ROL): DO_ROL(u8); break;
  973.     case OPCODE(U8,ROR): DO_ROR(u8); break;
  974.     case OPCODE(U8,EXT): DO_EXT(u8, u16); break;
  975.     case OPCODE(U8,JFN): DO_JFN(u8); break;
  976.  
  977.     /*************** OPDATA_S8  ****************/
  978.     case OPCODE(S8,BRK): result = EXERES_BRK; break;
  979.     case OPCODE(S8,MOV): DO_MOV(s8); break;
  980.     case OPCODE(S8,CMP): DO_CMP(s8); break;
  981.     case OPCODE(S8,JMP): DO_JMP(s8); break;
  982.     case OPCODE(S8,JSR): DO_JSR(s8); break;
  983.     case OPCODE(S8,SLD): DO_SLD(s8); break;
  984.     case OPCODE(S8,SST): DO_SST(s8); break;
  985.     case OPCODE(S8,SPH): DO_SPH(s8); break;
  986.     case OPCODE(S8,SPL): DO_SPL(s8); break;
  987.     case OPCODE(S8,INC): DO_INC(s8); break;
  988.     case OPCODE(S8,DEC): DO_DEC(s8); break;
  989.     case OPCODE(S8,ADD): DO_ADD(s8); break;
  990.     case OPCODE(S8,SUB): DO_SUB(s8); break;
  991.     case OPCODE(S8,MUL): DO_MUL(s8); break;
  992.     case OPCODE(S8,DIV): DO_DIV(s8); break;
  993.     case OPCODE(S8,MOD): DO_MOD(s8); break;
  994.     case OPCODE(S8,NEG): DO_NEG(s8); break;
  995.     case OPCODE(S8,NOT): DO_NOT(s8); break;
  996.     case OPCODE(S8,NND): DO_NND(s8); break;
  997.     case OPCODE(S8,AND): DO_AND(s8); break;
  998.     case OPCODE(S8,NOR): DO_NOR(s8); break;
  999.     case OPCODE(S8,IOR): DO_IOR(s8); break;
  1000.     case OPCODE(S8,XOR): DO_XOR(s8); break;
  1001.     case OPCODE(S8,SHL): DO_SHL(s8); break;
  1002.     case OPCODE(S8,SHR): DO_SHR(s8); break;
  1003.     case OPCODE(S8,ROL): DO_ROL(s8); break;
  1004.     case OPCODE(S8,ROR): DO_ROR(s8); break;
  1005.     case OPCODE(S8,EXT): DO_EXT(s8, s16); break;
  1006.     case OPCODE(S8,JFN): DO_JFN(s8); break;
  1007.  
  1008.     /*************** OPDATA_U16 ****************/
  1009.     case OPCODE(U16,BRK): result = EXERES_BRK; break;
  1010.     case OPCODE(U16,MOV): DO_MOV(u16); break;
  1011.     case OPCODE(U16,CMP): DO_CMP(u16); break;
  1012.     case OPCODE(U16,JMP): DO_JMP(u16); break;
  1013.     case OPCODE(U16,JSR): DO_JSR(u16); break;
  1014.     case OPCODE(U16,SLD): DO_SLD(u16); break;
  1015.     case OPCODE(U16,SST): DO_SST(u16); break;
  1016.     case OPCODE(U16,SPH): DO_SPH(u16); break;
  1017.     case OPCODE(U16,SPL): DO_SPL(u16); break;
  1018.     case OPCODE(U16,INC): DO_INC(u16); break;
  1019.     case OPCODE(U16,DEC): DO_DEC(u16); break;
  1020.     case OPCODE(U16,ADD): DO_ADD(u16); break;
  1021.     case OPCODE(U16,SUB): DO_SUB(u16); break;
  1022.     case OPCODE(U16,MUL): DO_MUL(u16); break;
  1023.     case OPCODE(U16,DIV): DO_DIV(u16); break;
  1024.     case OPCODE(U16,MOD): DO_MOD(u16); break;
  1025.     case OPCODE(U16,NEG): DO_NEG(u16); break;
  1026.     case OPCODE(U16,NOT): DO_NOT(u16); break;
  1027.     case OPCODE(U16,NND): DO_NND(u16); break;
  1028.     case OPCODE(U16,AND): DO_AND(u16); break;
  1029.     case OPCODE(U16,NOR): DO_NOR(u16); break;
  1030.     case OPCODE(U16,IOR): DO_IOR(u16); break;
  1031.     case OPCODE(U16,XOR): DO_XOR(u16); break;
  1032.     case OPCODE(U16,SHL): DO_SHL(u16); break;
  1033.     case OPCODE(U16,SHR): DO_SHR(u16); break;
  1034.     case OPCODE(U16,ROL): DO_ROL(u16); break;
  1035.     case OPCODE(U16,ROR): DO_ROR(u16); break;
  1036.     case OPCODE(U16,EXT): DO_EXT(u16, u32); break;
  1037.     case OPCODE(U16,JFN): DO_JFN(u16); break;
  1038.  
  1039.     /*************** OPDATA_S16 ****************/
  1040.     case OPCODE(S16,BRK): result = EXERES_BRK; break;
  1041.     case OPCODE(S16,MOV): DO_MOV(s16); break;
  1042.     case OPCODE(S16,CMP): DO_CMP(s16); break;
  1043.     case OPCODE(S16,JMP): DO_JMP(s16); break;
  1044.     case OPCODE(S16,JSR): DO_JSR(s16); break;
  1045.     case OPCODE(S16,SLD): DO_SLD(s16); break;
  1046.     case OPCODE(S16,SST): DO_SST(s16); break;
  1047.     case OPCODE(S16,SPH): DO_SPH(s16); break;
  1048.     case OPCODE(S16,SPL): DO_SPL(s16); break;
  1049.     case OPCODE(S16,INC): DO_INC(s16); break;
  1050.     case OPCODE(S16,DEC): DO_DEC(s16); break;
  1051.     case OPCODE(S16,ADD): DO_ADD(s16); break;
  1052.     case OPCODE(S16,SUB): DO_SUB(s16); break;
  1053.     case OPCODE(S16,MUL): DO_MUL(s16); break;
  1054.     case OPCODE(S16,DIV): DO_DIV(s16); break;
  1055.     case OPCODE(S16,MOD): DO_MOD(s16); break;
  1056.     case OPCODE(S16,NEG): DO_NEG(s16); break;
  1057.     case OPCODE(S16,NOT): DO_NOT(s16); break;
  1058.     case OPCODE(S16,NND): DO_NND(s16); break;
  1059.     case OPCODE(S16,AND): DO_AND(s16); break;
  1060.     case OPCODE(S16,NOR): DO_NOR(s16); break;
  1061.     case OPCODE(S16,IOR): DO_IOR(s16); break;
  1062.     case OPCODE(S16,XOR): DO_XOR(s16); break;
  1063.     case OPCODE(S16,SHL): DO_SHL(s16); break;
  1064.     case OPCODE(S16,SHR): DO_SHR(s16); break;
  1065.     case OPCODE(S16,ROL): DO_ROL(s16); break;
  1066.     case OPCODE(S16,ROR): DO_ROR(s16); break;
  1067.     case OPCODE(S16,EXT): DO_EXT(s16, s32); break;
  1068.     case OPCODE(S16,JFN): DO_JFN(s16); break;
  1069.  
  1070.     /*************** OPDATA_U32 ****************/
  1071.     case OPCODE(U32,BRK): result = EXERES_BRK; break;
  1072.     case OPCODE(U32,MOV): DO_MOV(u32); break;
  1073.     case OPCODE(U32,CMP): DO_CMP(u32); break;
  1074.     case OPCODE(U32,JMP): DO_JMP(u32); break;
  1075.     case OPCODE(U32,JSR): DO_JSR(u32); break;
  1076.     case OPCODE(U32,SLD): DO_SLD(u32); break;
  1077.     case OPCODE(U32,SST): DO_SST(u32); break;
  1078.     case OPCODE(U32,SPH): DO_SPH(u32); break;
  1079.     case OPCODE(U32,SPL): DO_SPL(u32); break;
  1080.     case OPCODE(U32,INC): DO_INC(u32); break;
  1081.     case OPCODE(U32,DEC): DO_DEC(u32); break;
  1082.     case OPCODE(U32,ADD): DO_ADD(u32); break;
  1083.     case OPCODE(U32,SUB): DO_SUB(u32); break;
  1084.     case OPCODE(U32,MUL): DO_MUL(u32); break;
  1085.     case OPCODE(U32,DIV): DO_DIV(u32); break;
  1086.     case OPCODE(U32,MOD): DO_MOD(u32); break;
  1087.     case OPCODE(U32,NEG): DO_NEG(u32); break;
  1088.     case OPCODE(U32,NOT): DO_NOT(u32); break;
  1089.     case OPCODE(U32,NND): DO_NND(u32); break;
  1090.     case OPCODE(U32,AND): DO_AND(u32); break;
  1091.     case OPCODE(U32,NOR): DO_NOR(u32); break;
  1092.     case OPCODE(U32,IOR): DO_IOR(u32); break;
  1093.     case OPCODE(U32,XOR): DO_XOR(u32); break;
  1094.     case OPCODE(U32,SHL): DO_SHL(u32); break;
  1095.     case OPCODE(U32,SHR): DO_SHR(u32); break;
  1096.     case OPCODE(U32,ROL): DO_ROL(u32); break;
  1097.     case OPCODE(U32,ROR): DO_ROR(u32); break;
  1098.     case OPCODE(U32,EXT): goto _lbl_NOP; //can't extend past 32b
  1099.     case OPCODE(U32,JFN): DO_JFN(u32); break;
  1100.  
  1101.     /*************** OPDATA_S32 ****************/
  1102.     case OPCODE(S32,BRK): result = EXERES_BRK; break;
  1103.     case OPCODE(S32,MOV): DO_MOV(s32); break;
  1104.     case OPCODE(S32,CMP): DO_CMP(s32); break;
  1105.     case OPCODE(S32,JMP): DO_JMP(s32); break;
  1106.     case OPCODE(S32,JSR): DO_JSR(s32); break;
  1107.     case OPCODE(S32,SLD): DO_SLD(s32); break;
  1108.     case OPCODE(S32,SST): DO_SST(s32); break;
  1109.     case OPCODE(S32,SPH): DO_SPH(s32); break;
  1110.     case OPCODE(S32,SPL): DO_SPL(s32); break;
  1111.     case OPCODE(S32,INC): DO_INC(s32); break;
  1112.     case OPCODE(S32,DEC): DO_DEC(s32); break;
  1113.     case OPCODE(S32,ADD): DO_ADD(s32); break;
  1114.     case OPCODE(S32,SUB): DO_SUB(s32); break;
  1115.     case OPCODE(S32,MUL): DO_MUL(s32); break;
  1116.     case OPCODE(S32,DIV): DO_DIV(s32); break;
  1117.     case OPCODE(S32,MOD): DO_MOD(s32); break;
  1118.     case OPCODE(S32,NEG): DO_NEG(s32); break;
  1119.     case OPCODE(S32,NOT): DO_NOT(s32); break;
  1120.     case OPCODE(S32,NND): DO_NND(s32); break;
  1121.     case OPCODE(S32,AND): DO_AND(s32); break;
  1122.     case OPCODE(S32,NOR): DO_NOR(s32); break;
  1123.     case OPCODE(S32,IOR): DO_IOR(s32); break;
  1124.     case OPCODE(S32,XOR): DO_XOR(s32); break;
  1125.     case OPCODE(S32,SHL): DO_SHL(s32); break;
  1126.     case OPCODE(S32,SHR): DO_SHR(s32); break;
  1127.     case OPCODE(S32,ROL): DO_ROL(s32); break;
  1128.     case OPCODE(S32,ROR): DO_ROR(s32); break;
  1129.     case OPCODE(S32,EXT): goto _lbl_NOP; //can't extend past 32b
  1130.     case OPCODE(S32,JFN): DO_JFN(s32); break;
  1131.  
  1132.     /*************** OPDATA_IMP ****************/
  1133.     #define ZN_U32 SET_FLAGS_ZN(dst->u32);
  1134.     #define ZN_S32 SET_FLAGS_ZN(dst->s32);
  1135.     #define ZN_F32 { \
  1136.       flags_zero     = dst->f32 == 0.0f; \
  1137.       flags_negative = dst->f32 <  0.0f; }
  1138.     //(branches have -4 applied to them when src is immediate,
  1139.      //because OPDATA_IMP defaults to 32-bits when using an
  1140.      //immediate value, even though branches only use s16)
  1141.     #define src_imm16  s16 src_s16; { \
  1142.       if(ins.src == OPADDR_IMM){ src_s16 = *(((s16*)src)-1); regs_pc-=4; } \
  1143.       else                     { src_s16 = * ((s16*)src)   ;             } }
  1144.     #define src_imm16_u  u16 src_u16; { \
  1145.       if(ins.src == OPADDR_IMM){ src_u16 = *(((u16*)src)-1); regs_pc-=4; } \
  1146.       else                     { src_u16 = * ((u16*)src)   ;             } }
  1147.     case OPCODE(IMP,NOP): _lbl_NOP: {
  1148. result = EXERES_NOP;
  1149. #ifdef _DEBUG
  1150. kit_LogInfo(
  1151. "\
  1152. r0=0x%08X, r1=0x%08X, r2=0x%08X, r3=0x%08X, r4=0x%08X, r5=0x%08X, sp=0x%08X, flg=0b%08X, pc=0x%08X\
  1153. ",
  1154.   regs[0].u32, regs[1].u32, regs[2].u32, regs[3].u32, regs[4].u32, regs[5].u32, regs_sp.u32, bin_hex(regs_flags.u8), regs_pc
  1155. );
  1156. #endif /* _DEBUG */
  1157.     } break;
  1158.     case OPCODE(IMP,SRT): { dst->f32 = sqrtf(src->f32);          ZN_F32 } break;
  1159.     case OPCODE(IMP,CPU): { src_imm16_u  cpuid(src_u16);                } break;
  1160.     case OPCODE(IMP,SYS): { src_imm16_u  syscall(src_u16);              } break;
  1161.     case OPCODE(IMP,BNC): { src_imm16  if(!flags_negative){ regs_pc += src_s16; } } break;
  1162.     case OPCODE(IMP,BNS): { src_imm16  if( flags_negative){ regs_pc += src_s16; } } break;
  1163.     case OPCODE(IMP,BZC): { src_imm16  if(!flags_zero    ){ regs_pc += src_s16; } } break;
  1164.     case OPCODE(IMP,BZS): { src_imm16  if( flags_zero    ){ regs_pc += src_s16; } } break;
  1165.     case OPCODE(IMP,BLT): { src_imm16  if(CMP_LT){ regs_pc += src_s16; } } break;
  1166.     case OPCODE(IMP,BGT): { src_imm16  if(CMP_GT){ regs_pc += src_s16; } } break;
  1167.     case OPCODE(IMP,BLE): { src_imm16  if(CMP_LE){ regs_pc += src_s16; } } break;
  1168.     case OPCODE(IMP,BGE): { src_imm16  if(CMP_GE){ regs_pc += src_s16; } } break;
  1169.     case OPCODE(IMP,BNE): { src_imm16  if(CMP_NE){ regs_pc += src_s16; } } break;
  1170.     case OPCODE(IMP,BEQ): { src_imm16  if(CMP_EQ){ regs_pc += src_s16; } } break;
  1171.     case OPCODE(IMP,JNC): { if(!flags_negative){ regs_pc = src->u32; }  } break;
  1172.     case OPCODE(IMP,JNS): { if( flags_negative){ regs_pc = src->u32; }  } break;
  1173.     case OPCODE(IMP,JZC): { if(!flags_zero    ){ regs_pc = src->u32; }  } break;
  1174.     case OPCODE(IMP,JZS): { if( flags_zero    ){ regs_pc = src->u32; }  } break;
  1175.     case OPCODE(IMP,JLT): { if(CMP_LT){ regs_pc = src->u32; }           } break;
  1176.     case OPCODE(IMP,JGT): { if(CMP_GT){ regs_pc = src->u32; }           } break;
  1177.     case OPCODE(IMP,JLE): { if(CMP_LE){ regs_pc = src->u32; }           } break;
  1178.     case OPCODE(IMP,JGE): { if(CMP_GE){ regs_pc = src->u32; }           } break;
  1179.     case OPCODE(IMP,JNE): { if(CMP_NE){ regs_pc = src->u32; }           } break;
  1180.     case OPCODE(IMP,JEQ): { if(CMP_EQ){ regs_pc = src->u32; }           } break;
  1181.     case OPCODE(IMP,U2B): { dst->u32 =   to_bcd(src->u32);       ZN_U32 } break;
  1182.     case OPCODE(IMP,B2U): { dst->u32 = from_bcd(src->u32);       ZN_U32 } break;
  1183.     case OPCODE(IMP,I2F): { dst->f32 = (f32)src->s32;            ZN_F32 } break;
  1184.     case OPCODE(IMP,F2I): { dst->s32 = (s32)src->f32;            ZN_S32 } break;
  1185.     case OPCODE(IMP,RTS): { regs_pc  = STACK_PULL(u32);                 } break;
  1186.     case OPCODE(IMP,BRA): { src_imm16  regs_pc += src_s16;              } break;
  1187.     case OPCODE(IMP,RSI): {
  1188.       src_imm16
  1189.       regs_pc = *ADDR(u32, regs_sp.u32);
  1190.       regs_sp.u32 += src_s16;
  1191.     } break;
  1192.     case OPCODE(IMP,RFN): {
  1193.       u32* stack     = ADDR(u32, regs_sp.u32);
  1194.       regs_pc        = stack[0];
  1195.       regs_gp[5].u32 = stack[1];
  1196.       regs_gp[4].u32 = stack[2];
  1197.       regs_gp[3].u32 = stack[3];
  1198.       regs_gp[2].u32 = stack[4];
  1199.       regs_gp[1].u32 = stack[5];
  1200.       regs_sp.u32   += sizeof(u32)*6;
  1201.     } break;
  1202.  
  1203.     /*************** OPDATA_F32 ****************/
  1204.     #undef  SET_FLAGS_ZN
  1205.     #define SET_FLAGS_ZN(_) ZN_F32
  1206.     #define DO_MOD_F32 { dst->f32 = fmodf(dst->f32, src->f32); ZN_F32 }
  1207.     case OPCODE(F32,BRK): result = EXERES_BRK; break;
  1208.     case OPCODE(F32,MOV): DO_MOV(f32); break;
  1209.     case OPCODE(F32,CMP): DO_CMP(f32); break;
  1210.     case OPCODE(F32,JMP): DO_JMP(f32); break;
  1211.     case OPCODE(F32,JSR): DO_JSR(f32); break;
  1212.     case OPCODE(F32,SLD): DO_SLD(f32); break;
  1213.     case OPCODE(F32,SST): DO_SST(f32); break;
  1214.     case OPCODE(F32,SPH): DO_SPH(f32); break;
  1215.     case OPCODE(F32,SPL): DO_SPL(f32); break;
  1216.     case OPCODE(F32,INC): DO_INC(f32); break;
  1217.     case OPCODE(F32,DEC): DO_DEC(f32); break;
  1218.     case OPCODE(F32,ADD): DO_ADD(f32); break;
  1219.     case OPCODE(F32,SUB): DO_SUB(f32); break;
  1220.     case OPCODE(F32,MUL): DO_MUL(f32); break;
  1221.     case OPCODE(F32,DIV): DO_DIV(f32); break;
  1222.     case OPCODE(F32,MOD): DO_MOD_F32 ; break;
  1223.     case OPCODE(F32,NEG): DO_NEG(f32); break;
  1224.     case OPCODE(F32,NOT): ATTR_FALLTHROUGH;
  1225.     case OPCODE(F32,NND): ATTR_FALLTHROUGH;
  1226.     case OPCODE(F32,AND): ATTR_FALLTHROUGH;
  1227.     case OPCODE(F32,NOR): ATTR_FALLTHROUGH;
  1228.     case OPCODE(F32,IOR): ATTR_FALLTHROUGH;
  1229.     case OPCODE(F32,XOR): ATTR_FALLTHROUGH;
  1230.     case OPCODE(F32,SHL): ATTR_FALLTHROUGH;
  1231.     case OPCODE(F32,SHR): ATTR_FALLTHROUGH;
  1232.     case OPCODE(F32,ROL): ATTR_FALLTHROUGH;
  1233.     case OPCODE(F32,ROR): ATTR_FALLTHROUGH;
  1234.     case OPCODE(F32,EXT): goto _lbl_NOP;
  1235.     case OPCODE(F32,JFN): DO_JFN(f32); break;
  1236.  
  1237.     default: result = EXERES_ILLEGAL; break;
  1238.   }
  1239.  
  1240.  
  1241.  
  1242.   return result;
  1243.  
  1244. }
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250. void cpu32::cpuid(u16 type){
  1251.   (void)type; //tbd
  1252.  
  1253. }
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259. }; /* namespace kit */
  1260.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement