dehex.s 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. ; Copyright (C) 2016 Jeremiah Orians
  2. ; This file is part of stage0.
  3. ;
  4. ; stage0 is free software: you can redistribute it and/or modify
  5. ; it under the terms of the GNU General Public License as published by
  6. ; the Free Software Foundation, either version 3 of the License, or
  7. ; (at your option) any later version.
  8. ;
  9. ; stage0 is distributed in the hope that it will be useful,
  10. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ; GNU General Public License for more details.
  13. ;
  14. ; You should have received a copy of the GNU General Public License
  15. ; along with stage0. If not, see <http://www.gnu.org/licenses/>.
  16. :start
  17. FALSE R14 ; R14 will be storing our current address
  18. LOADUI R15 $end ; We will be using R15 for our stack
  19. ;; Main program functionality
  20. ;; Reads in Tape_01 and writes out results to Tape_02
  21. ;; Accepts no arguments and HALTS when done
  22. :main
  23. ;; Prep TAPE_01
  24. LOADUI R0 0x1100
  25. FOPEN_READ
  26. ;; Prep TAPE_02
  27. LOADUI R0 0x1101
  28. FOPEN_WRITE
  29. ;; Perform main loop
  30. :main_0
  31. LOADUI R1 0x1100 ; Read from tape_01
  32. FGETC ; Read a Char
  33. ;; Check for EOF
  34. CMPSKIPI.GE R0 0
  35. JUMP @main_1
  36. ;; Process that byte
  37. CALLI R15 @dehex
  38. ;; Increment address
  39. ADDUI R14 R14 1
  40. ;; Get next byte
  41. JUMP @main_0
  42. :main_1
  43. ;; Close up as we are done
  44. LOADUI R0 0x1100 ; Close TAPE_01
  45. FCLOSE
  46. LOADUI R0 0x1101 ; Close TAPE_02
  47. FCLOSE
  48. HALT
  49. ;; Dehex functionality
  50. ;; Accepts byte in R0
  51. ;; Prints address every 4th byte
  52. ;; Alters R0
  53. ;; Returns to whatever called it
  54. :dehex
  55. PUSHR R1 R15 ; Preserve R1
  56. PUSHR R0 R15 ; Save byte until after address
  57. ANDI R0 R14 3 ; Get mod 4 of address
  58. LOADUI R1 0x1101 ; We want it on TAPE_02
  59. CMPSKIPI.E R0 0 ; if not zero
  60. JUMP @dehex_0 ; Skip placing address
  61. ;; Prepend new line
  62. LOADUI R0 10 ; First print line feed
  63. FPUTC ; Write it
  64. ;; Write out address
  65. COPY R0 R14 ; Prep for call
  66. CALLI R15 @hex32 ; Let it handle the details
  67. ;; Write out : char
  68. LOADUI R0 58 ; Prep
  69. FPUTC ; Write it
  70. ;; Write out tab
  71. LOADUI R0 9 ; Prep
  72. FPUTC ; Write it
  73. :dehex_0
  74. POPR R0 R15 ; Restore byte received
  75. CALLI R15 @hex8 ; Use a subset
  76. LOADUI R0 32 ; Prep for writing space
  77. FPUTC ; Write it
  78. POPR R1 R15 ; Restore R1
  79. RET R15 ; Return to caller
  80. ;; hex32 functionality
  81. ;; Accepts 32bit value in R0
  82. ;; Require R1 to be the device to write the results
  83. ;; Returns to whatever called it
  84. :hex32
  85. PUSHR R0 R15
  86. SR0I R0 16 ; Do high word first
  87. CALLI R15 @hex16
  88. POPR R0 R15
  89. :hex16
  90. PUSHR R0 R15
  91. SR0I R0 8 ; Do high byte first
  92. CALLI R15 @hex8
  93. POPR R0 R15
  94. :hex8
  95. PUSHR R0 R15
  96. SR0I R0 4 ; Do high nybble first
  97. CALLI R15 @hex4
  98. POPR R0 R15
  99. :hex4
  100. ANDI R0 R0 0x000F ; isolate nybble
  101. ADDUI R0 R0 48 ; convert to ascii
  102. CMPSKIPI.LE R0 57 ; If nybble was greater than '9'
  103. ADDUI R0 R0 7 ; Shift it into 'A' range of ascii
  104. FPUTC ; Print char
  105. RET R15 ; Get next nybble or return if done
  106. ;; Where we are putting our stack
  107. :end